Skip to content
Open
37 changes: 37 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions changelogs/24.04
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Pop!_OS 24.04 includes the COSMIC desktop environment. COSMIC offers better performance, productivity, and in-depth personalization to empower a wide variety of use cases. <a href="https://system76.com/cosmic">Learn more.</a>

When you upgrade:
* GNOME desktop will be replaced by the new COSMIC desktop.
* New system applications will be installed: COSMIC Files, COSMIC Settings, COSMIC Store, COSMIC Terminal, COSMIC Text Editor.
* Applications pinned tot he dock will need to be pinned again.
* PPAs will be removed for increased upgrade reliability.
* Applications installed from PPAs or local DEB files will need to be reinstalled.
* COSMIC offers all new user settings and customizations.
1 change: 1 addition & 0 deletions daemon/src/changelogs.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::cmp::Ordering;

pub const CHANGELOGS: &[(&str, &str)] = &[
("24.04", include_str!("../../changelogs/24.04")),
("22.04", include_str!("../../changelogs/22.04")),
("21.10", include_str!("../../changelogs/21.10")),
("21.04", include_str!("../../changelogs/21.04")),
Expand Down
18 changes: 9 additions & 9 deletions daemon/src/release/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ const HIRSUTE: &str = "21.04";
const IMPISH: &str = "21.10";
const JAMMY: &str = "22.04";
const NOBLE: &str = "24.04";
const UNKNOWN: &str = "26.04";
const RESOLUTE: &str = "26.04";

pub fn release_str(major: u8, minor: u8) -> &'static str {
match (major, minor) {
Expand All @@ -112,7 +112,7 @@ pub fn release_str(major: u8, minor: u8) -> &'static str {
(21, 10) => IMPISH,
(22, 4) => JAMMY,
(24, 4) => NOBLE,
(26, 4) => UNKNOWN,
(26, 4) => RESOLUTE,
_ => panic!("this version of pop-upgrade is not supported on this release"),
}
}
Expand All @@ -133,20 +133,20 @@ async fn next_<Check: Fn(String) -> Status, Status: Future<Output = BuildStatus>
};

// Only permits an upgrade if the development flag is passed
let development_enabled = |is_lts: bool, current: &'static str, next: &'static str| async move {
let build =
if development { release_check(next.into()).await } else { BuildStatus::Blacklisted };
ReleaseStatus { current, next, build, is_lts }
};
// let development_enabled = |is_lts: bool, current: &'static str, next: &'static str| async move {
// let build =
// if development { release_check(next.into()).await } else { BuildStatus::Blacklisted };
// ReleaseStatus { current, next, build, is_lts }
// };

match (current.major, current.minor) {
(18, 4) => available(true, BIONIC, FOCAL).await,
(20, 4) => available(true, FOCAL, JAMMY).await,
(20, 10) => available(false, GROOVY, HIRSUTE).await,
(21, 4) => available(false, HIRSUTE, IMPISH).await,
(21, 10) => available(false, IMPISH, JAMMY).await,
(22, 4) => development_enabled(true, JAMMY, NOBLE).await,
(24, 4) => blocked(true, NOBLE, UNKNOWN).await,
(22, 4) => available(true, JAMMY, NOBLE).await,
(24, 4) => blocked(true, NOBLE, RESOLUTE).await,
_ => panic!("this version of pop-upgrade is not supported on this release"),
}
}
5 changes: 5 additions & 0 deletions daemon/src/ubuntu_version/codename.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub enum Codename {
Impish,
Jammy,
Noble,
Resolute,
}

impl Codename {
Expand Down Expand Up @@ -49,6 +50,7 @@ impl Codename {
Codename::Impish => (2021, 10, 14),
Codename::Jammy => (2022, 4, 21),
Codename::Noble => (2024, 4, 13),
Codename::Resolute => (2026, 4, 23),
}
}

Expand All @@ -66,6 +68,7 @@ impl Codename {
Codename::Impish => 1_634_191_200,
Codename::Jammy => 1_650_492_000,
Codename::Noble => 1_712_959_200,
Codename::Resolute => 1_776_895_200
}
}
}
Expand All @@ -89,6 +92,7 @@ impl FromStr for Codename {
"impish" => Codename::Impish,
"jammy" => Codename::Jammy,
"noble" => Codename::Noble,
"resolute" => Codename::Resolute,
_ => return Err(CodenameParseError::NotFound),
};

Expand All @@ -109,6 +113,7 @@ impl From<Codename> for &'static str {
Codename::Impish => "impish",
Codename::Jammy => "jammy",
Codename::Noble => "noble",
Codename::Resolute => "resolute",
}
}
}
1 change: 1 addition & 0 deletions daemon/src/ubuntu_version/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ impl From<Codename> for Version {
Codename::Impish => (21, 10),
Codename::Jammy => (22, 4),
Codename::Noble => (24, 4),
Codename::Resolute => (26, 4),
};

Version { major, minor, patch: 0 }
Expand Down
1 change: 1 addition & 0 deletions gtk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ upower_dbus = "=0.1.0"
uzers = "0.12.1"
yansi = "1.0.1"
gtk-sys = "0.15.3"
open = "5.3.3"

[build-dependencies]
pkg-config = "0.3.32"
131 changes: 72 additions & 59 deletions gtk/src/events/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,14 @@ pub enum Event {
}

pub struct EventWidgets {
pub button_sg: gtk::SizeGroup,
pub container: gtk::Box,
pub dismisser: gtk::ListBoxRow,
pub stack: gtk::Stack,
pub button_sg: gtk::SizeGroup,
pub container: gtk::Box,
pub dismisser: gtk::ListBoxRow,
pub stack: gtk::Stack,
pub loading_label: gtk::Label,

pub recovery: UpgradeSection,
pub upgrade: UpgradeSection,
pub upgrade: UpgradeSection,
}

impl EventWidgets {
Expand Down Expand Up @@ -154,6 +154,7 @@ pub async fn on_event(widgets: &mut EventWidgets, state: &mut State, event: UiEv
InitiatedEvent::Download(version) => {
widgets.upgrade.options[0]
.label(&fl!("download-os", version = (&*version)))
.sublabel(None)
.reset_progress()
.show_progress();

Expand Down Expand Up @@ -185,7 +186,22 @@ pub async fn on_event(widgets: &mut EventWidgets, state: &mut State, event: UiEv
UiEvent::Upgrade(event) => match event {
OsUpgradeEvent::Cancelled => cancelled_upgrade(state, widgets),

OsUpgradeEvent::Dialog => release_upgrade_dialog(state, widgets),
OsUpgradeEvent::Dialog => {
let dialog = UpgradeDialog::new(&state.upgrading_from, &state.upgrading_to, false);

let answer = dialog.run();
dialog.close();
if gtk::ResponseType::Accept == answer {
let _ = state.sender.send(BackgroundEvent::Finalize);
} else {
// Send upgrading event to prevent closing
(state.callback_event.borrow())(Event::Upgrading);
widgets.upgrade.options[0]
.button_class(&gtk::STYLE_CLASS_SUGGESTED_ACTION)
.label(&fl!("upgrade-canceling"));
let _ = state.sender.send(BackgroundEvent::Reset);
}
}

OsUpgradeEvent::Dismissed(dismissed) => {
info!("{} release", if dismissed { "dismissed" } else { "un-dismissed" });
Expand All @@ -207,7 +223,7 @@ pub async fn on_event(widgets: &mut EventWidgets, state: &mut State, event: UiEv

OsUpgradeEvent::Notification => (state.callback_ready.borrow())(),

OsUpgradeEvent::Upgrade => upgrade_clicked(state, widgets),
OsUpgradeEvent::Upgrade => release_upgrade_dialog(state, widgets),
},

UiEvent::Updating => {
Expand Down Expand Up @@ -317,19 +333,23 @@ fn connect_refresh(state: &State, widgets: &EventWidgets) {
fn connect_upgrade(state: &mut State, widgets: &EventWidgets, is_lts: bool, reboot_ready: bool) {
let notice = match EolDate::fetch() {
Ok(eol) => {
let (y, m, d) = eol.ymd;
match eol.status() {
EolStatus::Exceeded => Some(fl!(
"eol-exceeded",
current = fomat!((eol.version)),
next = fomat!((eol.version.next_release()))
)),
EolStatus::Imminent => Some(fl!(
"eol-imminent",
current = fomat!((eol.version)),
date = fomat!((Utc.ymd(y as i32, m, d).format("%B %-d, %Y")))
)),
EolStatus::Ok => None,
if eol.version.major == 24 && eol.version.minor == 4 {
let (y, m, d) = eol.ymd;
match eol.status() {
EolStatus::Exceeded => Some(fl!(
"eol-exceeded",
current = fomat!((eol.version)),
next = fomat!((eol.version.next_release()))
)),
EolStatus::Imminent => Some(fl!(
"eol-imminent",
current = fomat!((eol.version)),
date = fomat!((Utc.ymd(y as i32, m, d).format("%B %-d, %Y")))
)),
EolStatus::Ok => None,
}
} else {
Some(fl!("upgrade-cosmic"))
}
}
Err(why) => {
Expand Down Expand Up @@ -381,11 +401,11 @@ fn download_action(sender: sync::Weak<flume::Sender<UiEvent>>) -> (String, Box<d
}
});

(fl!("button-download"), action)
(fl!("button-upgrade"), action)
}

/// Notify that OS release updates have been downloaded, and are ready to commence.
fn download_complete(state: &mut State, widgets: &EventWidgets) {
fn download_complete(state: &mut State, widgets: &mut EventWidgets) {
state.upgrade_downloaded = true;

let description = fl!("notification-description", version = (&*state.upgrading_to));
Expand All @@ -400,9 +420,12 @@ fn download_complete(state: &mut State, widgets: &EventWidgets) {
(state.callback_event.borrow())(Event::UpgradeReady);

widgets.upgrade.options[0]
.button_class(&gtk::STYLE_CLASS_DESTRUCTIVE_ACTION)
.show_button()
.button_label(&fl!("button-upgrade"))
.label(&fl!("download-os-complete", version = (&*state.upgrading_to)));
.label(&fl!("download-os-complete", version = (&*state.upgrading_to)))
.sublabel(None)
.button_signal(Some(upgrade_action(state.gui_sender.clone())));
}

use once_cell::sync::Lazy;
Expand Down Expand Up @@ -473,17 +496,32 @@ fn is_dismissed(next: &str) -> bool {

/// When the user selects to commence an upgrade, a dialog is shown to confirm.
fn release_upgrade_dialog(state: &mut State, widgets: &EventWidgets) {
let dialog = UpgradeDialog::new(&state.upgrading_from, &state.upgrading_to);

let answer = dialog.run();
dialog.close();
if gtk::ResponseType::Accept == answer {
let _ = state.sender.send(BackgroundEvent::Finalize);
} else {
// Send upgrading event to prevent closing
if let Some(info) = state.upgrade_version.clone() {
(state.callback_event.borrow())(Event::Upgrading);
widgets.upgrade.options[0].label(&fl!("upgrade-canceling"));
let _ = state.sender.send(BackgroundEvent::Reset);

widgets.upgrade.options[0].label(&fl!("upgrade-preparing")).show_progress();

widgets.recovery.options[RECOVERY_PARTITION].sensitive(false);
widgets.recovery.options[REFRESH_OS].sensitive(false);

if let Some(dismisser) = state.dismisser.take() {
unsafe {
dismisser.destroy();
}
}

let dialog = UpgradeDialog::new(&state.upgrading_from, &state.upgrading_to, true);

let answer = dialog.run();
dialog.close();
if gtk::ResponseType::Accept == answer {
let _ = state.sender.send(BackgroundEvent::DownloadUpgrade(info));
} else {
// Send upgrading event to prevent closing
(state.callback_event.borrow())(Event::Upgrading);
widgets.upgrade.options[0].label(&fl!("upgrade-canceling"));
let _ = state.sender.send(BackgroundEvent::Reset);
}
}
}

Expand Down Expand Up @@ -587,32 +625,7 @@ fn upgrade_action(sender: sync::Weak<flume::Sender<UiEvent>>) -> (String, Box<dy
}
});

(fl!("button-upgrade"), action)
}

/// Triggers on clicking the upgrade button
fn upgrade_clicked(state: &mut State, widgets: &EventWidgets) {
if state.upgrade_downloaded {
release_upgrade_dialog(state, widgets);
return;
}

if let Some(info) = state.upgrade_version.clone() {
(state.callback_event.borrow())(Event::Upgrading);

widgets.upgrade.options[0].label(&fl!("upgrade-preparing")).show_progress();

widgets.recovery.options[RECOVERY_PARTITION].sensitive(false);
widgets.recovery.options[REFRESH_OS].sensitive(false);

if let Some(dismisser) = state.dismisser.take() {
unsafe {
dismisser.destroy();
}
}

let _ = state.sender.send(BackgroundEvent::DownloadUpgrade(info));
}
(fl!("button-perform-upgrade"), action)
}

mod recovery {
Expand Down
Loading