From d126c75df51dd03fd65efbc5402fd307dcfc97c6 Mon Sep 17 00:00:00 2001 From: Clement Lefebvre Date: Wed, 19 Aug 2026 15:10:45 +0200 Subject: [PATCH 01/21] 7.1.5 --- debian/changelog | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/debian/changelog b/debian/changelog index 39d9521e..1a0170dd 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,46 @@ +mintupdate (7.1.5) alfa; urgency=medium + + [ Clement Lefebvre ] + * polkit: Allow remote upgrades + * Remove kernel window (moved to mintsysadm) + * Remove kernel cleanup + * Remove obsolete settings + * Remove kernel metapackage handling + * man: Remove obsolete info + + [ Michael Webster ] + * mintUpdate.py: Fix auto-refresh loop race condition. + * .github/workflows: Add generate-test-packages trigger. + * flatpak-update-worker.py: Revert changes accidentally sucked up in previous commit. + * .github: Add stale workflow. + * mintUpdate.py: Simplify auto-refresh loop and refresh coordination. + * Classes.py: Some cleanup, use os.makedirs() instead of os.system. + * information window: Allow copying the logfile path. + * Add queue_refresh for off-main callers, catch refresh() exceptions so the refresh loop doesn't break. + * Move APT install work to checkAPT.py + * Move preferences to its own file. + * Give the apt install a timeout, fix GLib/Gio.Unix deprecations. + * Allow multiple selection in the treeview. + * Rename checkAPT.py to aptUpdater.py, remove unused checkWarnings. + * Use python-xapp for network proxy settings. + * Take initial queue_refresh(False) out of the APT monitor and call it explicitly at startup. + * Use upower for battery detection. + * automatic updates: Move flatpak/cinnamon automation into the main process, instead of running once at startup. + * Move _idle, _async to util module. + * Move the inhibitor into utils, clean up some imports. + * aptUpdater: clean up some confusion when calling find_changes(). + * mintUpdate.py: Just use XApp.StatusIcon instead of a wrapper. + * main.ui: Use GtkButtons instead of GtkToolButtons for the top row controls. + * mintUpdate.py: Fix tray re-activation in Wayland. + + [ hduelme ] + * remove unused update description formatting (#1032) + + [ SAY-5 ] + * checkAPT: handle packages without a candidate version + + -- Clement Lefebvre Wed, 19 Aug 2026 15:10:30 +0200 + mintupdate (7.1.4) zena; urgency=medium * l10n: Update translations From 4944a8f2bd70cda28760222430dfad6e8c8458cc Mon Sep 17 00:00:00 2001 From: Danilo Rezende <50598421+returnDanilo@users.noreply.github.com> Date: Wed, 19 Aug 2026 12:21:59 -0300 Subject: [PATCH 02/21] minor github issue template edit (#1071) --- .github/ISSUE_TEMPLATE/bug_report.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 79d91f31..80103bc3 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -13,7 +13,7 @@ A clear and concise description of what the bug is. **Screenshots** If applicable, add screenshots to help explain your problem, you can just drag & drop them here. -**To Reproduce** +**Steps to reproduce** Steps to reproduce the behavior: 1. Go to '...' 2. Click on '....' @@ -41,4 +41,4 @@ If you are reporting a crash, please run `mintupdate` from a terminal window, re Add any other context about the problem you think might be relevant. **Locale:** -If the problem is with text not getting displayed correctly, paste the output of the terminal command `locale`. \ No newline at end of file +If the problem is with text not getting displayed correctly, paste the output of the terminal command `locale`. From 1cea35d9259a7ce9f3296731e404b84c7e575be0 Mon Sep 17 00:00:00 2001 From: Michael Webster Date: Thu, 20 Aug 2026 10:00:35 -0400 Subject: [PATCH 03/21] mintUpdate.py: Fix interactive-search positioning in Wayland sessions. This is a known issue with popup positioning, unlikely to be fixed. see: https://gitlab.gnome.org/GNOME/gtk/-/work_items/2794 --- usr/lib/linuxmint/mintUpdate/mintUpdate.py | 41 +++++++++++++++++++++- usr/lib/linuxmint/mintUpdate/util.py | 6 +++- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/usr/lib/linuxmint/mintUpdate/mintUpdate.py b/usr/lib/linuxmint/mintUpdate/mintUpdate.py index 3656670e..45694ec4 100755 --- a/usr/lib/linuxmint/mintUpdate/mintUpdate.py +++ b/usr/lib/linuxmint/mintUpdate/mintUpdate.py @@ -33,7 +33,7 @@ from preferences import PreferencesWindow from Classes import MainloopTimer, PRIORITY_UPDATES, UpdateTracker -from util import on_battery, _idle, _async, Inhibitor +from util import on_battery, get_session_type, _idle, _async, Inhibitor settings = Gio.Settings(schema_id="com.linuxmint.updates") @@ -104,6 +104,43 @@ def name_search_func(model, column, key, iter): return key.lower() not in name.lower() # False is a match +def search_position_func(treeview, search_window, user_data=None): + """Place the interactive-search entry below the treeview's bottom-right corner. + + Installed on Wayland only, replacing a GTK default that additionally clamps + the entry to the monitor workarea. That clamp mixes two coordinate spaces: + here gdk_window_get_origin() is window-local (a toplevel reports 0,0) while + gdk_monitor_get_workarea() is in global compositor coordinates. + + ref: https://gitlab.gnome.org/GNOME/gtk/-/work_items/2794 + """ + tree_window = treeview.get_window() + if tree_window is None: + return + + search_window.realize() + + tree_x, tree_y = tree_window.get_origin()[1:] + requisition = search_window.get_preferred_size()[0] + + parent_window = treeview.get_toplevel().get_window() + parent_x, parent_y = parent_window.get_origin()[1:] + + anchor_rect = Gdk.Rectangle() + anchor_rect.x = tree_x + tree_window.get_width() - requisition.width - parent_x + anchor_rect.y = tree_y + tree_window.get_height() - parent_y + anchor_rect.width = 1 + anchor_rect.height = 1 + + search_window.get_window().move_to_rect(anchor_rect, + Gdk.Gravity.NORTH_WEST, + Gdk.Gravity.NORTH_WEST, + Gdk.AnchorHints.FLIP_Y | + Gdk.AnchorHints.SLIDE_X | + Gdk.AnchorHints.SLIDE_Y, + 0, 0) + + class APTCacheMonitor(): """ Monitors package cache and dpkg status and runs the refresh thread() on change """ @@ -256,6 +293,8 @@ def __init__(self): self.treeview.set_tooltip_column(UPDATE_TOOLTIP) self.treeview.set_search_equal_func(name_search_func) + if get_session_type() == "wayland": + self.treeview.set_search_position_func(search_position_func) self.treeview.append_column(column_type) self.treeview.append_column(self.column_upgrade) self.treeview.append_column(column_name) diff --git a/usr/lib/linuxmint/mintUpdate/util.py b/usr/lib/linuxmint/mintUpdate/util.py index 6cb95214..e3bbdb79 100644 --- a/usr/lib/linuxmint/mintUpdate/util.py +++ b/usr/lib/linuxmint/mintUpdate/util.py @@ -22,6 +22,10 @@ def wrapper(*args): return wrapper +def get_session_type(): + return os.environ.get("XDG_SESSION_TYPE", "x11") + + def on_battery(): # Query UPower over the system D-Bus. Works for both root (system services) # and user contexts; UPower's default policy allows property reads from any uid. @@ -69,7 +73,7 @@ def _get_info(self, reason): flags = 1 | 4 xid = 0 - if self.window is not None and os.environ.get("XDG_SESSION_TYPE", "x11") == "x11": + if self.window is not None and get_session_type() == "x11": try: xid = self.window.get_window().get_xid() except Exception: From a6a9f5767905b8fc94923d0b4ca0538a93309a90 Mon Sep 17 00:00:00 2001 From: Michael Webster Date: Sat, 12 Sep 2026 09:29:53 -0400 Subject: [PATCH 04/21] mintUpdate.py: Improve startup, process singleton behavior. - Use Gio.Application to enforce uniqueness. - Don't re-launch when displaying updates from a notification. - Use os.execv() to restart mintupdate after self-updates. Fixes #997. --- usr/lib/linuxmint/mintUpdate/mintUpdate.py | 46 +++++++++++----------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/usr/lib/linuxmint/mintUpdate/mintUpdate.py b/usr/lib/linuxmint/mintUpdate/mintUpdate.py index 45694ec4..e8846b1f 100755 --- a/usr/lib/linuxmint/mintUpdate/mintUpdate.py +++ b/usr/lib/linuxmint/mintUpdate/mintUpdate.py @@ -58,14 +58,6 @@ CINNAMON_SUPPORT = cinnamon_support FLATPAK_SUPPORT = flatpak_support -try: - os.system("killall -q mintUpdate") -except Exception as e: - print (e) - print(sys.exc_info()[0]) - -setproctitle.setproctitle("mintUpdate") - # i18n APP = 'mintupdate' LOCALE_DIR = "/usr/share/locale" @@ -188,9 +180,23 @@ def update_cachetime(self): self.cachetime = os.path.getmtime(self.pkgcache) self.statustime = os.path.getmtime(self.dpkgstatus) -class MintUpdate(): +class MintUpdate(Gio.Application): def __init__(self): + Gio.Application.__init__(self, application_id="com.linuxmint.mintupdate", + flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE) + + def do_command_line(self, command_line): + if "show" in command_line.get_arguments()[1:]: + self.show_window() + return 0 + + def do_startup(self): + Gio.Application.do_startup(self) + # Transitional: kill instances from before single-instance support. + os.system("killall -q mintUpdate") + setproctitle.setproctitle("mintUpdate") + self.information_window_showing = False self.history_window_showing = False self.preferences_window = None @@ -356,7 +362,7 @@ def __init__(self): menu.append(menuItem4) image = Gtk.Image.new_from_icon_name("xsi-exit-symbolic", Gtk.IconSize.MENU) menuItem = Gtk.ImageMenuItem(label=_("Quit"), image=image) - menuItem.connect('activate', self.quit) + menuItem.connect('activate', self.on_quit) menu.append(menuItem) menu.show_all() @@ -377,7 +383,7 @@ def __init__(self): fileSubmenu.append(Gtk.SeparatorMenuItem()) image = Gtk.Image.new_from_icon_name("xsi-exit-symbolic", Gtk.IconSize.MENU) quitMenuItem = Gtk.ImageMenuItem(label=_("Quit"), image=image) - quitMenuItem.connect('activate', self.quit) + quitMenuItem.connect('activate', self.on_quit) key, mod = Gtk.accelerator_parse("Q") quitMenuItem.add_accelerator("activate", accel_group, key, mod, Gtk.AccelFlags.VISIBLE) fileSubmenu.append(quitMenuItem) @@ -518,11 +524,6 @@ def __init__(self): self.ui_vbox.show_all() - if len(sys.argv) > 1: - showWindow = sys.argv[1] - if showWindow == "show": - self.show_window() - self.apt_updater = aptUpdater.AptUpdater(self.ui_window) if CINNAMON_SUPPORT: @@ -549,7 +550,7 @@ def __init__(self): self.start_auto_refresh() self.start_session_updates() - Gtk.main() + self.hold() except Exception as e: print (e) @@ -738,7 +739,7 @@ def show_tracker_notification(self, num_software, num_security): def on_notification_action(self, notification, action_name, data): if action_name == "show_updates": - os.system("/usr/lib/linuxmint/mintUpdate/mintUpdate.py show &") + self.show_window() elif action_name == "enable_automatic_updates": self.open_preferences(None, show_automation=True) @@ -1388,7 +1389,7 @@ def on_statusicon_activated(self, icon, button, time): if button == Gdk.BUTTON_PRIMARY: self.tray_activate(time) - def quit(self, widget, data = None): + def on_quit(self, widget, data = None): if self.ui_window: self.hide_window() try: @@ -1670,7 +1671,7 @@ def _on_preferences_destroyed(self, window): def restart_app(self): self.logger.write("Restarting update manager...") - os.system("/usr/lib/linuxmint/mintUpdate/mintUpdate.py show &") + os.execv(sys.executable, [sys.executable, os.path.abspath(__file__), "show"]) ######### REFRESH THREAD ########## @@ -2244,8 +2245,7 @@ def _do_install(self): self.hide_window() if [pkg for pkg in PRIORITY_UPDATES if pkg in self.packages]: - # Skip _post_install_cleanup — restart_app spawns a new - # instance that will take over. + # Skip _post_install_cleanup, restart_app replaces this process. self.inhibitor.uninhibit() self.logger.write("Mintupdate was updated, restarting it...") self.logger.close() @@ -2297,4 +2297,4 @@ def _post_install_cleanup(self, refresh_needed): except Exception as e: print("Network proxy support unavailable: %s" % str(e), file=sys.stderr) - MintUpdate() + MintUpdate().run(sys.argv) From b4c586f9839d2943944390f4117a10acd4ba865a Mon Sep 17 00:00:00 2001 From: Clement Lefebvre Date: Tue, 13 Oct 2026 15:12:38 +0100 Subject: [PATCH 05/21] 7.1.6 --- debian/changelog | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/debian/changelog b/debian/changelog index 1a0170dd..d8f89084 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,14 @@ +mintupdate (7.1.6) adrien; urgency=medium + + [ Danilo Rezende ] + * minor github issue template edit (#1071) + + [ Michael Webster ] + * mintUpdate.py: Fix interactive-search positioning in Wayland sessions. + * mintUpdate.py: Improve startup, process singleton behavior. + + -- Clement Lefebvre Tue, 13 Oct 2026 15:12:32 +0100 + mintupdate (7.1.5) alfa; urgency=medium [ Clement Lefebvre ] From e9a398c566233917e94de4a431315e1d88697fc4 Mon Sep 17 00:00:00 2001 From: Michael Webster Date: Tue, 20 Oct 2026 15:52:19 -0400 Subject: [PATCH 06/21] mintUpdate.py: Add set_prgname() Replaces #1044 --- usr/lib/linuxmint/mintUpdate/mintUpdate.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/usr/lib/linuxmint/mintUpdate/mintUpdate.py b/usr/lib/linuxmint/mintUpdate/mintUpdate.py index e8846b1f..56a2400c 100755 --- a/usr/lib/linuxmint/mintUpdate/mintUpdate.py +++ b/usr/lib/linuxmint/mintUpdate/mintUpdate.py @@ -5,6 +5,10 @@ import os import sys import gi + +from gi.repository import GLib +GLib.set_prgname("mintupdate") + import time import gettext import io @@ -25,7 +29,7 @@ gi.require_version('Gtk', '3.0') gi.require_version('Notify', '0.7') -from gi.repository import Gtk, Gdk, Gio, GLib, GObject, Notify, Pango +from gi.repository import Gtk, Gdk, Gio, GObject, Notify, Pango from xapp.GSettingsWidgets import * # local imports From ceed0fcdd51592ac374f0e1991f69ce92beb9ccc Mon Sep 17 00:00:00 2001 From: Michael Webster Date: Mon, 26 Oct 2026 13:10:52 -0400 Subject: [PATCH 07/21] Fix test script minutupdate no longer always kills its previous self at startup. --- test | 1 + 1 file changed, 1 insertion(+) diff --git a/test b/test index 14feb9b7..6a4eeb19 100755 --- a/test +++ b/test @@ -6,4 +6,5 @@ sudo cp -R lib/* /lib/ sudo cp -R usr / sudo glib-compile-schemas /usr/share/glib-2.0/schemas sudo gtk-update-icon-cache /usr/share/icons/hicolor +killall mintUpdate mintupdate From d02958b067e91b811df386d0f28ca0a314343583 Mon Sep 17 00:00:00 2001 From: Michael Webster Date: Mon, 26 Oct 2026 13:12:10 -0400 Subject: [PATCH 08/21] Fix flatpak errors being lost or hanging the update process. - flatpak-update-worker: Don't quit before mintcommon's error dialog is shown. Show a dialog for errors that occur before the transaction is ready. - flatpakUpdater: Reset the error before each check/update. - Pass any flatpak check error into show_update_in_UI so the statusbar text can show the error. Fixes: #1082, #1050 Ref: #1103 --- .../mintUpdate/flatpak-update-worker.py | 41 +++++++++++++-- .../linuxmint/mintUpdate/flatpakUpdater.py | 51 +++++++++++-------- usr/lib/linuxmint/mintUpdate/mintUpdate.py | 18 +++---- 3 files changed, 77 insertions(+), 33 deletions(-) diff --git a/usr/lib/linuxmint/mintUpdate/flatpak-update-worker.py b/usr/lib/linuxmint/mintUpdate/flatpak-update-worker.py index 39530be5..a7b8468f 100755 --- a/usr/lib/linuxmint/mintUpdate/flatpak-update-worker.py +++ b/usr/lib/linuxmint/mintUpdate/flatpak-update-worker.py @@ -21,6 +21,7 @@ from mintcommon.installer import installer from mintcommon.installer import _flatpak +from mintcommon.installer import dialogs from Classes import FlatpakUpdate @@ -62,6 +63,7 @@ def __init__(self): self.installer = installer.Installer(installer.PKG_TYPE_FLATPAK) self.fp_sys = _flatpak.get_fp_sys() self.task = None + self.error = None self.cancellable = Gio.Cancellable() @@ -123,6 +125,10 @@ def _fetch_task_ready(self, task): debug("task object:", task, "transaction:", task.transaction) self.task = task + if self.error is not None: + task.cancel() + return + self.error = task.error_message if self.error is None and task.transaction is not None: @@ -138,6 +144,12 @@ def _fetch_task_ready(self, task): def _fetch_updates_error(self, task): warn("fetch error", task.error_message) + if self.error is not None: + return + + self.error = task.error_message + self.send_to_updater(f"error:{self.error}") + self.quit() def _process_fetch_task(self, task): trans = task.transaction @@ -252,25 +264,46 @@ def prepare_start_updates(self, updates): def _start_task_ready(self, task): self.task = task + if self.error is not None: + task.cancel() + return + self.send_to_updater("ready") self.stdin.read_bytes_async(4096, GLib.PRIORITY_DEFAULT, None, self.message_from_updater) def _start_updates_error(self, task): warn("start updates error", task.error_message) - self.send_to_updater(f"error:{task.error_message}") + # mintcommon only shows its own error dialog once the transaction is running. + self.finish_with_error(task.error_message, show_dialog=True) def start_updates(self): self.installer.execute_task(self.task) def _execute_finished(self, task): - self.error = task.error_message + self.write_to_log(task) if task.error_message is not None: - self.send_to_updater(f"error:{task.error_message}") + self.finish_with_error(task.error_message) else: self.send_to_updater("done") - self.write_to_log(task) + self.quit() + + def finish_with_error(self, message, show_dialog=False): + if self.error is not None: + return + + self.error = message + if show_dialog: + dialogs.show_error(message) + + # Error dialogs are queued at PRIORITY_DEFAULT_IDLE - reporting at a lower priority ensures + # the dialog is up before mintupdate is told (it waits for us to exit) and we quit. + GLib.idle_add(self._report_error_and_quit, priority=GLib.PRIORITY_DEFAULT_IDLE + 1) + + def _report_error_and_quit(self): + self.send_to_updater(f"error:{self.error}") self.quit() + return GLib.SOURCE_REMOVE def write_to_log(self, task): try: diff --git a/usr/lib/linuxmint/mintUpdate/flatpakUpdater.py b/usr/lib/linuxmint/mintUpdate/flatpakUpdater.py index 594d1c2a..a66526c2 100644 --- a/usr/lib/linuxmint/mintUpdate/flatpakUpdater.py +++ b/usr/lib/linuxmint/mintUpdate/flatpakUpdater.py @@ -26,6 +26,7 @@ class FlatpakUpdater(): def __init__(self): self.task = None + self.proc = None self.updates = [] self.error = None @@ -40,6 +41,7 @@ def refresh(self): def fetch_updates(self): self.updates = [] + self.error = None output = None try: @@ -74,44 +76,53 @@ def fetch_updates(self): print("Flatpak: done generating updates") def prepare_start_updates(self, updates): + self.error = None argv = [UPDATE_WORKER_PATH, "--update-packages"] + [update.ref.format_ref() for update in updates] try: self.proc = subprocess.Popen(argv, stdin=subprocess.PIPE, stdout=subprocess.PIPE, encoding="utf-8") except Exception as e: - print("Flatpak: Could not start worker: %s" % str(e)) - return False + self.error = str(e) + print("Flatpak: Could not start worker: %s" % self.error) + return self.out_pipe = self.proc.stdout self.in_pipe = self.proc.stdin try: - res = self.out_pipe.readline() - if res: - answer = res.strip("\n") - if answer == "ready": - return - else: - raise Exception("Unexpected response from worker - expected 'ready', got '%s'" % answer) + answer = self.out_pipe.readline().strip("\n") + if answer == "ready": + return + if answer.startswith("error:"): + self.error = answer[6:] + else: + self.error = "Unexpected response from worker - expected 'ready', got '%s'" % answer except Exception as e: - print("Flatpak: Could not set up to install updates: %s", str(e)) - self.terminate_helper() + self.error = str(e) + + print("Flatpak: Could not set up to install updates: %s" % self.error) + self.terminate_helper() def perform_updates(self): + if self.proc is None: + return + try: self.in_pipe.write("start") self.in_pipe.flush() - res = self.out_pipe.readline() - if res: - answer = res.strip("\n") - if answer == "done": - print("Flatpaks: updates complete") - elif answer.startswith("error:"): - self.error = answer[6:] - print("Flatpaks: error performing updates: %s" % self.error) + answer = self.out_pipe.readline().strip("\n") + if answer == "done": + print("Flatpaks: updates complete") + elif answer.startswith("error:"): + self.error = answer[6:] + else: + self.error = "Unexpected response from worker - expected 'done', got '%s'" % answer except Exception as e: - print("Flatpak: Could not perform updates: %s", str(e)) + self.error = str(e) + + if self.error is not None: + print("Flatpak: Could not perform updates: %s" % self.error) self.terminate_helper() diff --git a/usr/lib/linuxmint/mintUpdate/mintUpdate.py b/usr/lib/linuxmint/mintUpdate/mintUpdate.py index 56a2400c..9685e1d9 100755 --- a/usr/lib/linuxmint/mintUpdate/mintUpdate.py +++ b/usr/lib/linuxmint/mintUpdate/mintUpdate.py @@ -666,8 +666,8 @@ def show_error(self, error_msg): @_idle - def show_updates_in_UI(self, num_visible, num_software, num_security, download_size, is_self_update, model_items): - status_string = "" + def show_updates_in_UI(self, num_visible, num_software, num_security, download_size, is_self_update, model_items, flatpak_error=None): + status_string = flatpak_error or "" if num_visible > 0: self.logger.write("Found %d software updates" % num_visible) @@ -681,7 +681,7 @@ def show_updates_in_UI(self, num_visible, num_software, num_security, download_s details = ", ".join(details) self.ui_label_self_update_details.set_text(details) else: - status_string = gettext.ngettext("%(selected)d update selected (%(size)s)", + status_string = flatpak_error or gettext.ngettext("%(selected)d update selected (%(size)s)", "%(selected)d updates selected (%(size)s)", num_visible) % \ {'selected':num_visible, 'size':size_to_string(download_size)} self.ui_clear_button.set_sensitive(True) @@ -697,7 +697,7 @@ def show_updates_in_UI(self, num_visible, num_software, num_security, download_s self.ui_stack.set_visible_child_name("success_page") if not self.reboot_required: - self.set_status("", _("Your system is up to date"), "mintupdate-up-to-date-symbolic", + self.set_status(status_string, _("Your system is up to date"), "mintupdate-up-to-date-symbolic", not self.settings.get_boolean("hide-systray")) if self.reboot_required: @@ -2114,13 +2114,13 @@ def refresh_updates(self): num_visible += 1 download_size += update.size - # Updates found, update status message - self.show_updates_in_UI(num_visible, num_software, num_security, download_size, is_self_update, model_items) - + flatpak_error = None if FLATPAK_SUPPORT and self.flatpak_updater.error is not None and not is_self_update: self.logger.write("Could not check for flatpak updates: %s" % self.flatpak_updater.error) - msg = _("Error checking for flatpak updates: %s") % self.flatpak_updater.error - self.set_status_message(msg) + flatpak_error = _("Error checking for flatpak updates: %s") % self.flatpak_updater.error + + # Updates found, update status message + self.show_updates_in_UI(num_visible, num_software, num_security, download_size, is_self_update, model_items, flatpak_error) # Check whether to display the mirror infobar self.mirror_check() From 15e45f3a91b9cc32bd86830d9f914aab6e019d64 Mon Sep 17 00:00:00 2001 From: Pedro Barbosa <156959341+Amadeus-22@users.noreply.github.com> Date: Tue, 27 Oct 2026 11:41:11 -0300 Subject: [PATCH 09/21] rel_upgrade_root: Import syslog (#1099) on_removals_finished logs with syslog.syslog() when update-grub fails, but the module never imports syslog. If update-grub is missing or raises, the handler itself fails with NameError, so Gtk.main_quit() and sys.exit(0) are not reached and the upgrade process never exits. --- usr/lib/linuxmint/mintUpdate/rel_upgrade_root.py | 1 + 1 file changed, 1 insertion(+) diff --git a/usr/lib/linuxmint/mintUpdate/rel_upgrade_root.py b/usr/lib/linuxmint/mintUpdate/rel_upgrade_root.py index 92b996ea..ec0926ef 100755 --- a/usr/lib/linuxmint/mintUpdate/rel_upgrade_root.py +++ b/usr/lib/linuxmint/mintUpdate/rel_upgrade_root.py @@ -7,6 +7,7 @@ import os import subprocess import sys +import syslog gi.require_version('Gtk', '3.0') from gi.repository import Gtk From 23d9513bb949f7ddb6a116ce33a225fe98fe3393 Mon Sep 17 00:00:00 2001 From: Michael Webster Date: Fri, 30 Oct 2026 13:26:54 -0400 Subject: [PATCH 10/21] rel_upgrade_root: Stop the upgrade when a step fails or is cancelled. The finished callback was called with any exit state, and the next step ran regardless, so a failed or cancelled package install could be followed by the additions, removals and update-grub. Quit with an error status instead. A cancelled confirmation dialog also left the script hanging, as no cancelled callback was set. --- .../linuxmint/mintUpdate/rel_upgrade_root.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/usr/lib/linuxmint/mintUpdate/rel_upgrade_root.py b/usr/lib/linuxmint/mintUpdate/rel_upgrade_root.py index ec0926ef..92ab1a85 100755 --- a/usr/lib/linuxmint/mintUpdate/rel_upgrade_root.py +++ b/usr/lib/linuxmint/mintUpdate/rel_upgrade_root.py @@ -1,6 +1,7 @@ #!/usr/bin/python3 import apt +import aptkit.enums import aptkit.simpleclient import gettext import gi @@ -44,6 +45,7 @@ class Upgrader(): def __init__(self): self.refresh_done = False self.client = aptkit.simpleclient.SimpleAPTClient() + self.client.set_cancelled_callback(lambda: self.quit(1)) self.additions = file_to_list(f"/usr/share/mint-upgrade-info/{codename}/additions") self.removals = file_to_list(f"/usr/share/mint-upgrade-info/{codename}/removals") self.blacklist = file_to_list(f"/usr/share/mint-upgrade-info/{codename}/blacklist") @@ -86,7 +88,17 @@ def on_cache_updated(self, transaction=None, exit_state=None): else: self.on_install_finished() + def quit(self, status): + Gtk.main_quit() + sys.exit(status) + + def quit_if_failed(self, exit_state): + if exit_state is not None and exit_state != aptkit.enums.EXIT_SUCCESS: + syslog.syslog("Upgrade step failed: %s" % exit_state) + self.quit(1) + def on_install_finished(self, transaction=None, exit_state=None): + self.quit_if_failed(exit_state) # STEP 4: ADD PACKAGES if len(self.additions) > 0: self.client.set_finished_callback(self.on_additions_finished) @@ -95,6 +107,7 @@ def on_install_finished(self, transaction=None, exit_state=None): self.on_additions_finished() def on_additions_finished(self, transaction=None, exit_state=None): + self.quit_if_failed(exit_state) # STEP 5: REMOVE PACKAGES removals = [] cache = apt.Cache() @@ -109,6 +122,7 @@ def on_additions_finished(self, transaction=None, exit_state=None): self.on_removals_finished() def on_removals_finished(self, transaction=None, exit_state=None): + self.quit_if_failed(exit_state) # STEP 6: UPDATE GRUB try: subprocess.run(["update-grub"]) @@ -116,8 +130,7 @@ def on_removals_finished(self, transaction=None, exit_state=None): subprocess.run(["/usr/share/ubuntu-system-adjustments/systemd/adjust-grub-title"]) except Exception as detail: syslog.syslog("Couldn't update grub: %s" % detail) - Gtk.main_quit() - sys.exit(0) + self.quit(0) if __name__ == "__main__": upgrader =Upgrader() From 3799cc79ebbadd8ae1e97b7397fead89de64f3e4 Mon Sep 17 00:00:00 2001 From: Michael Webster Date: Sat, 31 Oct 2026 10:46:23 -0400 Subject: [PATCH 11/21] mintUpdate.py: Fix infobar handling when there are multiple issues Since cb43dd9e0d07ae64c only a single infobar can be shown at any time. This causes an issue if the default mirror is in use, the user has never dismissed it, and performs a driver/kernel update - the 'reboot needed' infobar only shows briefly during the post-update view refresh (a few seconds), and is then replaced by the mirror infobar. Clear the infobar holder only once during refresh(), not before a new infobar is added. --- usr/lib/linuxmint/mintUpdate/mintUpdate.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/usr/lib/linuxmint/mintUpdate/mintUpdate.py b/usr/lib/linuxmint/mintUpdate/mintUpdate.py index 9685e1d9..4ce20c0b 100755 --- a/usr/lib/linuxmint/mintUpdate/mintUpdate.py +++ b/usr/lib/linuxmint/mintUpdate/mintUpdate.py @@ -655,9 +655,11 @@ def show_infobar(self, title, msg, msg_type, icon, callback, ok_label=None): infobar.add_button(ok_label, Gtk.ResponseType.OK) infobar.connect("response", callback) infobar.show_all() + self.ui_infobar.pack_start(infobar, True, True, 0) + + def clear_infobars(self): for child in self.ui_infobar.get_children(): child.destroy() - self.ui_infobar.pack_start(infobar, True, True, 0) @_idle def show_error(self, error_msg): @@ -1860,6 +1862,7 @@ def refresh(self, refresh_cache): self.inhibitor.inhibit("Checking for updates") self.cache_monitor.pause() + self.clear_infobars() if self.reboot_required: #Updated UI text from 'Reboot' to 'Restart' for consistency with Cinnamon. #Internal variables (like reboot_required) left unchanged for compatibility. From 82c61f0b098f169693d2e98da254a0d40ec7712e Mon Sep 17 00:00:00 2001 From: Michael Webster Date: Sat, 31 Oct 2026 13:15:06 -0400 Subject: [PATCH 12/21] rel_upgrade_root.py: Abort if cache update fails --- usr/lib/linuxmint/mintUpdate/rel_upgrade_root.py | 1 + 1 file changed, 1 insertion(+) diff --git a/usr/lib/linuxmint/mintUpdate/rel_upgrade_root.py b/usr/lib/linuxmint/mintUpdate/rel_upgrade_root.py index 92ab1a85..d9aa8735 100755 --- a/usr/lib/linuxmint/mintUpdate/rel_upgrade_root.py +++ b/usr/lib/linuxmint/mintUpdate/rel_upgrade_root.py @@ -64,6 +64,7 @@ def update_cache(self): self.client.update_cache() def on_cache_updated(self, transaction=None, exit_state=None): + self.quit_if_failed(exit_state) # STEP 3: INSTALL MINT UPDATES cache = apt.Cache() cache.open(None) From 19bca4c0d04da882ff44ddf2e46fc572211f6da4 Mon Sep 17 00:00:00 2001 From: LB Date: Tue, 3 Nov 2026 14:11:14 -0500 Subject: [PATCH 13/21] Pass the exported blacklist to mintupdate-automation on stdin (#1096) * Pass the exported blacklist to mintupdate-automation on stdin Exporting the blacklist wrote it to /tmp/mintUpdate/blacklist, then mintupdate-automation read that path as root after pkexec authentication. Another local user can replace the file (or plant a symlink) while the authentication dialog is open, so root appended arbitrary lines or the contents of any file, e.g. /etc/shadow, to world-readable /etc/mintupdate.blacklist. Pipe the blacklist to the helper on stdin instead. * Remove accidentally committed .pyc file --------- Co-authored-by: lbellows <19894143+lbellows@users.noreply.github.com> --- usr/bin/mintupdate-automation | 15 ++++++++------- usr/lib/linuxmint/mintUpdate/preferences.py | 7 ++----- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/usr/bin/mintupdate-automation b/usr/bin/mintupdate-automation index d9a7cb31..75809885 100755 --- a/usr/bin/mintupdate-automation +++ b/usr/bin/mintupdate-automation @@ -55,14 +55,15 @@ def do_disable(_automation_id): print("%s %s removed." % (name, filename)) def add_user_blacklist(outfile): - import tempfile + # The user's blacklist arrives on stdin. Never read it from a shared + # location such as /tmp: another user could swap the file for a symlink + # while the authentication dialog is open. + if sys.stdin is None or sys.stdin.isatty(): + return try: - infile = os.path.join(tempfile.gettempdir(), "mintUpdate/blacklist") - with open(infile, "r") as export: - with open(outfile, "a") as f: - for line in export: - f.write(line) - os.remove(infile) + with open(outfile, "a") as f: + for line in sys.stdin: + f.write(line) print("User blacklist exported.") except: pass diff --git a/usr/lib/linuxmint/mintUpdate/preferences.py b/usr/lib/linuxmint/mintUpdate/preferences.py index 9f96a550..4c64da5d 100644 --- a/usr/lib/linuxmint/mintUpdate/preferences.py +++ b/usr/lib/linuxmint/mintUpdate/preferences.py @@ -5,7 +5,6 @@ import json import os import subprocess -import tempfile import gi gi.require_version('Gtk', '3.0') @@ -215,11 +214,9 @@ def _build_automation(self, builder): section.add_row(switch) def _export_blacklist(self, widget): - filename = os.path.join(tempfile.gettempdir(), "mintUpdate/blacklist") blacklist = self.settings.get_strv("blacklisted-packages") - with open(filename, "w") as f: - f.write("\n".join(blacklist) + "\n") - subprocess.run(["pkexec", "/usr/bin/mintupdate-automation", "blacklist", "enable"]) + subprocess.run(["pkexec", "/usr/bin/mintupdate-automation", "blacklist", "enable"], + input="\n".join(blacklist) + "\n", text=True) def _set_auto_upgrade(self, widget, param): self._toggle_automation(widget, "upgrade") From 2b1bd03e4d90b4b0f0a76929c50a7e195351b3f6 Mon Sep 17 00:00:00 2001 From: Michael Webster Date: Tue, 3 Nov 2026 14:38:13 -0500 Subject: [PATCH 14/21] mintUpdate.py: Don't store the window's maximized size Closes #1057 Ref: #1104 --- usr/lib/linuxmint/mintUpdate/mintUpdate.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/usr/lib/linuxmint/mintUpdate/mintUpdate.py b/usr/lib/linuxmint/mintUpdate/mintUpdate.py index 4ce20c0b..7dc22a2e 100755 --- a/usr/lib/linuxmint/mintUpdate/mintUpdate.py +++ b/usr/lib/linuxmint/mintUpdate/mintUpdate.py @@ -752,12 +752,12 @@ def on_notification_action(self, notification, action_name, data): ######### WINDOW/STATUSICON ########## def close_window(self, window, event): - self.save_window_size() self.hide_window(window) return True @_idle def hide_window(self, widget=None): + self.save_window_size() self.ui_window.hide() self.hidden = True @@ -799,8 +799,10 @@ def set_refresh_mode(self, enabled): def save_window_size(self): - self.settings.set_int('window-width', self.ui_window.get_size()[0]) - self.settings.set_int('window-height', self.ui_window.get_size()[1]) + if self.ui_window.get_visible() and not self.ui_window.is_maximized(): + width, height = self.ui_window.get_size() + self.settings.set_int('window-width', width) + self.settings.set_int('window-height', height) self.settings.set_int('window-pane-position', self.ui_paned.get_position()) ######### MENU/TOOLBAR FUNCTIONS ######### @@ -1386,7 +1388,6 @@ def add_to_ignore_list(self, widget, source_packages, versioned): def tray_activate(self, time=0): if self.ui_window.is_active(): - self.save_window_size() self.hide_window() else: self.show_window(time) @@ -1397,11 +1398,11 @@ def on_statusicon_activated(self, icon, button, time): def on_quit(self, widget, data = None): if self.ui_window: + self.save_window_size() self.hide_window() try: self.logger.write("Exiting - requested by user") self.logger.close() - self.save_window_size() except: pass # cause log might already been closed # Whatever works best heh :) From 174bf63552a8d1a4391f9d6d4ec1e0fdcf216a32 Mon Sep 17 00:00:00 2001 From: Michael Webster Date: Wed, 4 Nov 2026 12:15:15 -0500 Subject: [PATCH 15/21] system_automatic_upgrades.py: Allow auto-update while on sufficient battery ref: #1021 --- .../mintUpdate/system_automatic_upgrades.py | 20 ++++++--- usr/lib/linuxmint/mintUpdate/util.py | 42 +++++++++++++------ 2 files changed, 44 insertions(+), 18 deletions(-) diff --git a/usr/lib/linuxmint/mintUpdate/system_automatic_upgrades.py b/usr/lib/linuxmint/mintUpdate/system_automatic_upgrades.py index 886409d0..9a37a861 100755 --- a/usr/lib/linuxmint/mintUpdate/system_automatic_upgrades.py +++ b/usr/lib/linuxmint/mintUpdate/system_automatic_upgrades.py @@ -6,20 +6,30 @@ import time sys.path.insert(0, "/usr/lib/linuxmint/mintUpdate") -from util import on_battery +from util import on_battery, get_battery_percentage + +MIN_BATTERY_PERCENTAGE = 75 if not os.path.exists("/var/lib/linuxmint/mintupdate-automatic-upgrades-enabled"): exit(0) optionsfile = "/etc/mintupdate-automatic-upgrades.conf" logfile = "/var/log/mintupdate.log" -log = open(logfile, "a") +log = open(logfile, "a", buffering=1) log.write("\n-- Automatic Upgrade starting %s:\n" % time.strftime('%a %d %b %Y %H:%M:%S %Z')) -log.flush() pkla_source = "/usr/share/linuxmint/mintupdate/automation/99-mintupdate-temporary.pkla" pkla_target = "/etc/polkit-1/localauthority/90-mandatory.d/99-mintupdate-temporary.pkla" -if not on_battery(): + +can_upgrade = True +if on_battery(): + battery_percentage = get_battery_percentage() + if battery_percentage is not None and battery_percentage >= MIN_BATTERY_PERCENTAGE: + log.write("-- On battery power (%d%%), proceeding.\n" % battery_percentage) + else: + can_upgrade = False + +if can_upgrade: try: # Put shutdown and reboot blocker into place os.symlink(pkla_source, pkla_target) @@ -56,5 +66,5 @@ log.write("-- Automatic Upgrade completed\n") else: - log.write("-- Power supply not connected, abort automatic update.\n") + log.write("-- Power supply not connected and battery below %d%%, abort automatic update.\n" % MIN_BATTERY_PERCENTAGE) log.close() diff --git a/usr/lib/linuxmint/mintUpdate/util.py b/usr/lib/linuxmint/mintUpdate/util.py index e3bbdb79..adf18102 100644 --- a/usr/lib/linuxmint/mintUpdate/util.py +++ b/usr/lib/linuxmint/mintUpdate/util.py @@ -26,26 +26,42 @@ def get_session_type(): return os.environ.get("XDG_SESSION_TYPE", "x11") +def _get_upower_property(path, iface, name): + # UPower's default policy allows property reads from any uid, so this works + # for both root (system services) and user contexts. + bus = Gio.bus_get_sync(Gio.BusType.SYSTEM, None) + ret = bus.call_sync( + "org.freedesktop.UPower", path, + "org.freedesktop.DBus.Properties", "Get", + GLib.Variant("(ss)", (iface, name)), + GLib.VariantType("(v)"), + Gio.DBusCallFlags.NONE, 2000, None) + return ret.unpack()[0] + + def on_battery(): - # Query UPower over the system D-Bus. Works for both root (system services) - # and user contexts; UPower's default policy allows property reads from any uid. # Returns False if UPower is unavailable (fail open — assume AC connected). try: - bus = Gio.bus_get_sync(Gio.BusType.SYSTEM, None) - proxy = Gio.DBusProxy.new_sync( - bus, Gio.DBusProxyFlags.NONE, None, - "org.freedesktop.UPower", - "/org/freedesktop/UPower", - "org.freedesktop.UPower", - None) - prop = proxy.get_cached_property("OnBattery") - if prop is None: - return False - return prop.unpack() + return bool(_get_upower_property("/org/freedesktop/UPower", + "org.freedesktop.UPower", + "OnBattery")) except GLib.Error: return False +def get_battery_percentage(): + # UPower's DisplayDevice aggregates all system batteries, excluding peripherals. + # Returns None if there's no battery or UPower is unavailable. + path = "/org/freedesktop/UPower/devices/DisplayDevice" + iface = "org.freedesktop.UPower.Device" + try: + if not _get_upower_property(path, iface, "IsPresent"): + return None + return _get_upower_property(path, iface, "Percentage") + except GLib.Error: + return None + + class Inhibitor: def __init__(self, logger=None, window=None): self.logger = logger From e4355c8766c9ba01798204850b0ca5a7cfe7febf Mon Sep 17 00:00:00 2001 From: Pedro Barbosa <156959341+Amadeus-22@users.noreply.github.com> Date: Wed, 4 Nov 2026 14:41:35 -0300 Subject: [PATCH 16/21] Blacklist: Match the source version stored by "Ignore the current update" (#1112) "Ignore the current update for this package" stores source=source_version (since 7a79b61a), but the update list and mintupdate-cli compared that version with a binary version. Where the two differ (epochs such as bsdutils 1:2.39.3-9ubuntu6.6, -signed packages such as grub2-signed 1.202.5 / grub-efi-amd64-signed 1.202.5+2.12-1ubuntu7.3, binNMUs) the update was not ignored, or only partly ignored: for util-linux only bsdutils stayed in the list. Move the matching rule to one is_blacklisted() helper in aptUpdater.py that accepts the source version as well as the binary version, so versions typed in the preferences keep working, and use it from mintupdate-cli instead of its own copy. mintupdate-cli now checks every package of an update and skips the whole update when one matches. Add tests/test_blacklist.py, run with /usr/bin/python3 -m unittest discover -s tests Co-authored-by: Claude Opus 5.5 --- tests/test_blacklist.py | 139 ++++++++++++++++++ usr/lib/linuxmint/mintUpdate/aptUpdater.py | 30 ++-- .../linuxmint/mintUpdate/mintupdate-cli.py | 17 +-- 3 files changed, 160 insertions(+), 26 deletions(-) create mode 100644 tests/test_blacklist.py diff --git a/tests/test_blacklist.py b/tests/test_blacklist.py new file mode 100644 index 00000000..fb299b51 --- /dev/null +++ b/tests/test_blacklist.py @@ -0,0 +1,139 @@ +#!/usr/bin/python3 + +# Blacklist matching in the update list (AptUpdater) and in mintupdate-cli. +# Run with: /usr/bin/python3 -m unittest discover -s tests +# Nothing is read from APT or dconf: packages are stubs and GSettings uses +# the memory backend. + +import contextlib +import io +import os +import runpy +import sys +import unittest +from types import SimpleNamespace +from unittest import mock + +os.environ["GSETTINGS_BACKEND"] = "memory" +myPath = os.path.dirname(os.path.abspath(__file__)) +libPath = os.path.join(myPath, "..", "usr", "lib", "linuxmint", "mintUpdate") +sys.path.insert(0, libPath) + +import aptUpdater +from aptUpdater import AptUpdater + +def make_package(name, source_name, source_version, version, old_version): + candidate = SimpleNamespace(source_name=source_name, source_version=source_version, + version=version, size=1, raw_description="", description="", + origins=[], section="admin") + return SimpleNamespace(name=name, candidate=candidate, is_installed=True, + installed=SimpleNamespace(version=old_version)) + +# bsdutils has an epoch, the other util-linux binaries don't +UTIL_LINUX = [ + make_package("util-linux", "util-linux", "2.39.3-9ubuntu6.6", "2.39.3-9ubuntu6.6", "2.39.3-9ubuntu6"), + make_package("mount", "util-linux", "2.39.3-9ubuntu6.6", "2.39.3-9ubuntu6.6", "2.39.3-9ubuntu6"), + make_package("bsdutils", "util-linux", "2.39.3-9ubuntu6.6", "1:2.39.3-9ubuntu6.6", "1:2.39.3-9ubuntu6"), +] +# -signed source packages have their own version, unrelated to the binary one +GRUB_SIGNED = [ + make_package("grub-efi-amd64-signed", "grub2-signed", "1.202.5", "1.202.5+2.12-1ubuntu7.3", "1.202+2.12-1ubuntu7"), +] +PACKAGES = UTIL_LINUX + GRUB_SIGNED + +class FakeSettings(): + + def __init__(self, blacklist): + self.blacklist = blacklist + + def get_strv(self, key): + return list(self.blacklist) + +class FakeAptUpdater(AptUpdater): + # Real AptUpdater.add_update() on stub packages, with an empty GUI blacklist + # unless one is given + + gui_blacklist = [] + + def __init__(self, ui_window=None): + super().__init__(ui_window) + self.settings = FakeSettings(self.gui_blacklist) + + def load_cache(self): + self.cache = {package.name: package for package in PACKAGES} + + def find_changes(self): + self.updates = {} + for package in PACKAGES: + self.add_update(package) + +def listed_updates(gui_blacklist): + FakeAptUpdater.gui_blacklist = gui_blacklist + updater = FakeAptUpdater() + updater.load_cache() + updater.find_changes() + return {source_name: sorted(update.package_names) for source_name, update in updater.updates.items()} + +def run_cli(*args): + # Runs mintupdate-cli.py as a script, on the stub packages, without /etc/mintupdate.blacklist + real_exists = os.path.exists + def exists(path): + return False if path == "/etc/mintupdate.blacklist" else real_exists(path) + FakeAptUpdater.gui_blacklist = [] + output = io.StringIO() + with mock.patch.object(aptUpdater, "AptUpdater", FakeAptUpdater), \ + mock.patch("os.path.exists", exists), \ + mock.patch.object(sys, "argv", ["mintupdate-cli"] + list(args)), \ + contextlib.redirect_stdout(output): + runpy.run_path(os.path.join(libPath, "mintupdate-cli.py"), run_name="__main__") + return [line.split()[1] for line in output.getvalue().splitlines()] + +class TestUpdateList(unittest.TestCase): + + def test_nothing_ignored(self): + self.assertEqual(listed_updates([]), { + "util-linux": ["bsdutils", "mount", "util-linux"], + "grub2-signed": ["grub-efi-amd64-signed"], + }) + + def test_ignore_current_update_epoch(self): + # "Ignore the current update" stores source=source_version + self.assertNotIn("util-linux", listed_updates(["util-linux=2.39.3-9ubuntu6.6"])) + + def test_ignore_current_update_signed(self): + self.assertNotIn("grub2-signed", listed_updates(["grub2-signed=1.202.5"])) + + def test_ignore_binary_version(self): + # A version typed in the preferences, as shown in the update list + self.assertNotIn("grub2-signed", listed_updates(["grub2-signed=1.202.5+2.12-1ubuntu7.3"])) + + def test_ignore_all_versions_pattern(self): + self.assertNotIn("grub2-signed", listed_updates(["grub2-*"])) + + def test_other_version_not_ignored(self): + self.assertEqual(listed_updates(["util-linux=2.39.3-9ubuntu6", "grub2-signed=1.202"]), + listed_updates([])) + +class TestCli(unittest.TestCase): + + def test_nothing_ignored(self): + self.assertEqual(run_cli("list"), ["grub2-signed", "util-linux"]) + + def test_ignore_current_update_epoch(self): + self.assertEqual(run_cli("list", "-i", "util-linux=2.39.3-9ubuntu6.6"), ["grub2-signed"]) + + def test_ignore_current_update_signed(self): + self.assertEqual(run_cli("list", "-i", "grub2-signed=1.202.5"), ["util-linux"]) + + def test_ignore_binary_version(self): + self.assertEqual(run_cli("list", "-i", "grub2-signed=1.202.5+2.12-1ubuntu7.3"), ["util-linux"]) + + def test_ignore_all_versions_pattern(self): + self.assertEqual(run_cli("list", "-i", "grub2-*,util-*"), []) + + def test_other_version_not_ignored(self): + self.assertEqual(run_cli("list", "-i", "util-linux=2.39.3-9ubuntu6,grub2-signed=1.202"), + ["grub2-signed", "util-linux"]) + +if __name__ == "__main__": + unittest.main() diff --git a/usr/lib/linuxmint/mintUpdate/aptUpdater.py b/usr/lib/linuxmint/mintUpdate/aptUpdater.py index 22de03aa..c89e6996 100755 --- a/usr/lib/linuxmint/mintUpdate/aptUpdater.py +++ b/usr/lib/linuxmint/mintUpdate/aptUpdater.py @@ -33,6 +33,23 @@ # packages which description is incorrect in Ubuntu (usually those which were replaced by snap dependencies) NON_TRANSLATED_PKGS = ["firefox", "thunderbird"] +def is_blacklisted(blacklist, candidate): + # Blacklist entries are "source" or "source=version", where source can be + # a pattern. "Ignore the current update" stores the source version, while + # a version typed in the preferences is usually the binary version shown + # in the update list. Both are accepted: they differ for epochs, -signed + # packages and binNMUs. + for blacklist_entry in blacklist: + if "=" in blacklist_entry: + (bl_pkg, bl_ver) = blacklist_entry.split("=", 1) + else: + bl_pkg = blacklist_entry + bl_ver = None + if fnmatch.fnmatch(candidate.source_name, bl_pkg) and \ + (not bl_ver or bl_ver in (candidate.source_version, candidate.version)): + return True + return False + class AptUpdater(): def __init__(self, ui_window=None): @@ -250,17 +267,6 @@ def find_changes(self): if (pkg.marked_upgrade or pkg.marked_downgrade): self.add_update(pkg) - def is_blacklisted(self, source_name, version): - for blacklist in self.settings.get_strv("blacklisted-packages"): - if "=" in blacklist: - (bl_pkg, bl_ver) = blacklist.split("=", 1) - else: - bl_pkg = blacklist - bl_ver = None - if fnmatch.fnmatch(source_name, bl_pkg) and (not bl_ver or bl_ver == version): - return True - return False - def get_kernel_version_from_meta_package(self, pkg): for dependency in pkg.dependencies: if not dependency.target_versions or dependency.rawtype != "Depends": @@ -300,7 +306,7 @@ def add_update(self, package, kernel_update=False, test_version=None): source_name = package.candidate.source_name # ignore packages blacklisted by the user - if self.is_blacklisted(package.candidate.source_name, package.candidate.version): + if is_blacklisted(self.settings.get_strv("blacklisted-packages"), package.candidate): return if source_name in PRIORITY_UPDATES: diff --git a/usr/lib/linuxmint/mintUpdate/mintupdate-cli.py b/usr/lib/linuxmint/mintUpdate/mintupdate-cli.py index 38ba0d90..c06805ca 100755 --- a/usr/lib/linuxmint/mintUpdate/mintupdate-cli.py +++ b/usr/lib/linuxmint/mintUpdate/mintupdate-cli.py @@ -1,28 +1,16 @@ #!/usr/bin/python3 import argparse -import fnmatch import os import subprocess import sys import traceback -from aptUpdater import AptUpdater +from aptUpdater import AptUpdater, is_blacklisted from Classes import PRIORITY_UPDATES if __name__ == "__main__": - def is_blacklisted(blacklisted_packages, source_name, version): - for blacklist in blacklisted_packages: - if "=" in blacklist: - (bl_pkg, bl_ver) = blacklist.split("=", 1) - else: - bl_pkg = blacklist - bl_ver = None - if fnmatch.fnmatch(source_name, bl_pkg) and (not bl_ver or bl_ver == version): - return True - return False - parser = argparse.ArgumentParser(prog="mintupdate-cli") parser.add_argument("command", help="command to run (possible commands are: list, upgrade)") @@ -65,7 +53,8 @@ def is_blacklisted(blacklisted_packages, source_name, version): continue elif args.only_security and update.type != "security": continue - elif is_blacklisted(blacklisted, update.real_source_name, update.new_version): + elif any(is_blacklisted(blacklisted, check.cache[name].candidate) for name in update.package_names): + # skip the whole update, not just the matching packages continue else: updates.append(update) From fd3779e140b85850ec48293680f8cafc7f85dd78 Mon Sep 17 00:00:00 2001 From: Clement Lefebvre Date: Thu, 12 Nov 2026 11:55:18 +0000 Subject: [PATCH 17/21] l10n: Update POT --- mintupdate.pot | 716 +++++++++++++++++++------------------------------ 1 file changed, 280 insertions(+), 436 deletions(-) diff --git a/mintupdate.pot b/mintupdate.pot index ca97920a..2a9d5549 100644 --- a/mintupdate.pot +++ b/mintupdate.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-12-11 14:38+0000\n" +"POT-Creation-Date: 2026-11-12 11:46+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -18,16 +18,16 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" -#: usr/lib/linuxmint/mintUpdate/checkAPT.py:247 +#: usr/lib/linuxmint/mintUpdate/aptUpdater.py:351 #, python-format msgid "Linux kernel %s" msgstr "" -#: usr/lib/linuxmint/mintUpdate/checkAPT.py:248 +#: usr/lib/linuxmint/mintUpdate/aptUpdater.py:352 msgid "The Linux kernel." msgstr "" -#: usr/lib/linuxmint/mintUpdate/checkAPT.py:249 +#: usr/lib/linuxmint/mintUpdate/aptUpdater.py:353 msgid "" "The Linux Kernel is responsible for hardware and drivers support. Note that " "this update will not remove your existing kernel. You will still be able to " @@ -39,702 +39,623 @@ msgid "" "to remove the new one first." msgstr "" -#: usr/lib/linuxmint/mintUpdate/Classes.py:429 +#: usr/lib/linuxmint/mintUpdate/Classes.py:390 msgid "Installing" msgstr "" -#: usr/lib/linuxmint/mintUpdate/Classes.py:475 +#: usr/lib/linuxmint/mintUpdate/Classes.py:436 msgid "A Flatpak runtime package" msgstr "" -#: usr/lib/linuxmint/mintUpdate/flatpak-update-worker.py:34 -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1650 +#: usr/lib/linuxmint/mintUpdate/flatpak-update-worker.py:37 +#: usr/lib/linuxmint/mintUpdate/preferences.py:159 msgid "Flatpak updates" msgstr "" -#: usr/lib/linuxmint/mintUpdate/kernelwindow.py:48 -#: usr/lib/linuxmint/mintUpdate/kernelwindow.py:138 -msgid "Remove" -msgstr "" - -#: usr/lib/linuxmint/mintUpdate/kernelwindow.py:50 -#: usr/lib/linuxmint/mintUpdate/kernelwindow.py:144 -msgid "Install" -msgstr "" - -#: usr/lib/linuxmint/mintUpdate/kernelwindow.py:139 -msgid "Queue Removal" -msgstr "" - -#: usr/lib/linuxmint/mintUpdate/kernelwindow.py:141 -msgid "This kernel cannot be removed because it is currently in use." -msgstr "" - -#: usr/lib/linuxmint/mintUpdate/kernelwindow.py:145 -msgid "Queue Installation" -msgstr "" - -#: usr/lib/linuxmint/mintUpdate/kernelwindow.py:147 -msgid "This kernel is not installable." -msgstr "" - -#: usr/lib/linuxmint/mintUpdate/kernelwindow.py:164 -#, python-format -msgid "Are you sure you want to remove the %s kernel?" -msgstr "" - -#: usr/lib/linuxmint/mintUpdate/kernelwindow.py:166 -#, python-format -msgid "Are you sure you want to install the %s kernel?" -msgstr "" - -#: usr/lib/linuxmint/mintUpdate/kernelwindow.py:213 -msgid "Remove Kernels" -msgstr "" - -#: usr/lib/linuxmint/mintUpdate/kernelwindow.py:214 -msgid "Perform Queued Actions" -msgstr "" - -#: usr/lib/linuxmint/mintUpdate/kernelwindow.py:290 -msgid "Active" -msgstr "" - -#: usr/lib/linuxmint/mintUpdate/kernelwindow.py:293 -msgid "Installed" -msgstr "" - -#: usr/lib/linuxmint/mintUpdate/kernelwindow.py:380 -msgid "Supported until" -msgstr "" - -#: usr/lib/linuxmint/mintUpdate/kernelwindow.py:383 -msgid "Superseded" -msgstr "" - -#: usr/lib/linuxmint/mintUpdate/kernelwindow.py:385 -msgid "End of Life" -msgstr "" - -#: usr/lib/linuxmint/mintUpdate/kernelwindow.py:387 -msgid "Unsupported" -msgstr "" - -#: usr/lib/linuxmint/mintUpdate/kernelwindow.py:416 -msgid "You are currently using the following kernel:" -msgstr "" - -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:83 -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:221 -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:594 -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1462 -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2461 generate_desktop_files:25 -#: usr/bin/mintupdate-launcher:23 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:74 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:251 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:621 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1611 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2157 generate_desktop_files:25 msgid "Update Manager" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:94 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:86 msgid "B" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:94 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:86 msgid "KB" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:94 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:86 msgid "MB" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:94 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:86 msgid "GB" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:244 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:274 msgid "Upgrade" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:249 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:279 msgid "Name" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:253 -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:429 -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1328 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:283 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:461 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1477 msgid "Old Version" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:257 -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:435 -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1331 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:287 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:467 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1480 msgid "New Version" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:261 -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:447 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:291 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:479 msgid "Size" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:265 -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:417 -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1322 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:295 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:449 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1471 msgid "Type" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:269 -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:441 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:299 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:473 msgid "Origin" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:322 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:356 #: usr/share/linuxmint/mintupdate/main.ui.h:3 #: usr/share/linuxmint/mintupdate/shortcuts.ui.h:3 msgid "Refresh" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:326 -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:410 -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1284 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:360 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:442 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1428 #: usr/share/linuxmint/mintupdate/main.ui.h:20 msgid "Information" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:330 #: usr/lib/linuxmint/mintUpdate/mintUpdate.py:364 -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1525 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:399 +#: usr/lib/linuxmint/mintUpdate/preferences.py:33 msgid "Preferences" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:334 -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:354 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:368 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:389 msgid "Quit" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:343 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:378 msgid "_File" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:347 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:382 msgid "Close window" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:360 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:395 msgid "_Edit" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:369 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:404 msgid "System Snapshots" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:374 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:409 msgid "Software Sources" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:396 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:431 #, python-format msgid "Upgrade to %s" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:400 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:435 msgid "_View" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:404 -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1310 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:439 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1459 msgid "History of Updates" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:407 -msgid "Linux Kernels" -msgstr "" - -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:413 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:445 msgid "Visible Columns" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:423 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:455 msgid "Package" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:455 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:487 msgid "Show Descriptions" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:472 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:495 msgid "_Help" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:477 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:500 msgid "Welcome Screen" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:482 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:505 msgid "Keyboard Shortcuts" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:486 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:509 msgid "Contents" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:492 -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1460 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:515 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1609 msgid "About" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:592 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:619 msgid "Cannot Proceed" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:593 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:620 msgid "" "Another process is currently using the package management system. Please " "wait for it to finish and then try again." msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:601 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:628 #: usr/share/linuxmint/mintupdate/main.ui.h:15 msgid "OK" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:625 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:652 msgid "Yes" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:626 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:653 msgid "No" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:657 -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:798 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:686 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:828 #, python-format msgid "%(selected)d update selected (%(size)s)" msgid_plural "%(selected)d updates selected (%(size)s)" msgstr[0] "" msgstr[1] "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:664 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:693 #, python-format msgid "%d update available" msgid_plural "%d updates available" msgstr[0] "" msgstr[1] "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:673 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:702 #: usr/share/linuxmint/mintupdate/main.ui.h:19 msgid "Your system is up to date" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:677 -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2098 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:706 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1870 msgid "Restart required" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:699 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:728 #, python-format msgid "%d security update" msgid_plural "%d security updates" msgstr[0] "" msgstr[1] "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:700 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:729 #, python-format msgid "%d software update" msgid_plural "%d software updates" msgstr[0] "" msgstr[1] "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:706 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:735 msgid "Apply them to keep your operating system safe and up to date." msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:710 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:739 msgid "Updates are available" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:713 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:742 msgid "View updates" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:714 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:743 msgid "Enable automatic updates" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:795 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:825 msgid "No updates selected" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:865 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:891 #: usr/share/linuxmint/mintupdate/main.ui.h:5 msgid "Welcome to the Update Manager" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:898 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:983 msgid "Most recent change" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:907 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:992 #, python-format msgid "Website: %s" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1033 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1114 msgid "Downloading changelog..." msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1045 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1116 msgid "No changelog available" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1196 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1288 msgid "Total size: <" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1201 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1293 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1323 msgid "Total size:" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1204 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1296 msgid "This update affects the following installed package:" msgid_plural "This update affects the following installed packages:" msgstr[0] "" msgstr[1] "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1218 -msgid "Ignore the current update for this package" +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1306 +msgid "Select a single update to view its description and changelog." msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1221 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1318 +msgid "The selected updates affect the following installed package:" +msgid_plural "The selected updates affect the following installed packages:" +msgstr[0] "" +msgstr[1] "" + +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1359 +msgid "Ignore the current update for this package" +msgid_plural "Ignore the current updates for these packages" +msgstr[0] "" +msgstr[1] "" + +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1363 msgid "Ignore all future updates for this package" -msgstr "" +msgid_plural "Ignore all future updates for these packages" +msgstr[0] "" +msgstr[1] "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1319 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1468 msgid "Date" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1325 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1474 msgid "Update" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1370 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1519 msgid "package" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1545 -msgid "Options" -msgstr "" - -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1546 -#: usr/share/linuxmint/mintupdate/main.ui.h:21 -msgid "Packages" -msgstr "" - -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1547 -msgid "Automation" +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1749 +msgid "Do you want to switch to a local mirror?" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1553 -msgid "Interface" +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1750 +msgid "Local mirrors are usually faster than packages.linuxmint.com." msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1554 -msgid "Hide the update manager after applying updates" +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1761 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1771 +msgid "Please switch to another mirror" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1555 -msgid "Only show a tray icon when updates are available or in case of errors" +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1762 +#, python-format +msgid "%s is unreachable." msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1557 -msgid "Auto-refresh" -msgstr "" +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1772 +#, python-format +msgid "The last update on %(mirror)s was %(days)d day ago." +msgid_plural "The last update on %(mirror)s was %(days)d days ago." +msgstr[0] "" +msgstr[1] "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1558 -msgid "Refresh the list of updates automatically" +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1862 +msgid "Checking for updates" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1570 -msgid "days" +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1871 +msgid "" +"You have installed updates that require a restart to take effect. Please " +"restart your system as soon as possible." msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1571 -msgid "hours" +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1875 +msgid "Restart" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1572 -msgid "minutes" +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1959 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1967 +msgid "Your APT configuration is corrupt." msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1573 -msgid "First, refresh the list of updates after:" +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1960 +msgid "" +"Do not install or update anything - doing so could break your operating " +"system!" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1577 -msgid "Then, refresh the list of updates every:" +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1961 +msgid "" +"To switch to a different Linux Mint mirror and solve this problem, click OK." msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1620 -msgid "" -"Note: The list only gets refreshed while the Update Manager window is closed " -"(in system tray mode)." +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1963 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1964 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1987 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1988 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1996 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1997 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2137 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2138 +#: usr/share/linuxmint/mintupdate/main.ui.h:16 +msgid "Could not refresh the list of updates" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1624 -msgid "Notifications" +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1966 +msgid "Please switch to another Linux Mint mirror" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1630 -msgid "Only show notifications for security and kernel updates" +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1985 +msgid "Run 'apt update' in a terminal window to address this" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1632 -msgid "" -"Show a notification if an update has been available for (in logged-in days):" +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2034 +msgid "Security update" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1634 -msgid "Show a notification if an update is older than (in days):" +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2038 +msgid "Kernel update" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1636 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2042 msgid "" -"Don't show notifications if an update was applied in the last (in days):" +"Unstable software. Only apply this update to help developers beta-test new " +"software." msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1645 -msgid "Update types" +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2046 +msgid "Software update" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1645 -msgid "In addition to system packages, check for:" +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2049 +msgid "3rd-party update" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1648 -msgid "Cinnamon spice updates" +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2073 +msgid "Flatpak application" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1658 -msgid "Ignored Updates" +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2075 +msgid "Flatpak runtime" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1681 -msgid "Package Updates" +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2098 +msgid "Cinnamon applet" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1681 -msgid "Performed as root on a daily basis" +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2100 +msgid "Cinnamon desklet" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1682 -msgid "Apply updates automatically" +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2105 +msgid "Nemo action" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1686 -msgid "Export blacklist to /etc/mintupdate.blacklist" +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2107 +msgid "Cinnamon theme" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1690 -msgid "Click this button to make automatic updates use your current blacklist." +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2109 +msgid "Cinnamon extension" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1695 -msgid "Update Cinnamon spices automatically" +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2124 +#, python-format +msgid "Error checking for flatpak updates: %s" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1698 -msgid "Update Flatpaks automatically" +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2227 +msgid "Installing updates" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1701 -msgid "Other Updates" +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2241 +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2242 +msgid "Could not install the security updates" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1701 -msgid "Performed when you log in" +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2271 +msgid "Updating Cinnamon Spices" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1704 -msgid "Automatic Maintenance" +#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2284 +msgid "Could not update Cinnamon Spices" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1704 -msgid "Performed as root on a weekly basis" +#: usr/lib/linuxmint/mintUpdate/preferences.py:51 +msgid "Options" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1705 -msgid "Remove obsolete kernels and dependencies" +#: usr/lib/linuxmint/mintUpdate/preferences.py:52 +#: usr/share/linuxmint/mintupdate/main.ui.h:21 +msgid "Packages" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1709 -msgid "" -"This option always leaves at least one older kernel installed and never " -"removes manually installed kernels." +#: usr/lib/linuxmint/mintUpdate/preferences.py:53 +msgid "Automation" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1764 -msgid "" -"Please specify the source package name of the update to ignore (wildcards " -"are supported) and optionally the version:" +#: usr/lib/linuxmint/mintUpdate/preferences.py:69 +msgid "Interface" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1765 -msgid "Ignore an Update" +#: usr/lib/linuxmint/mintUpdate/preferences.py:70 +msgid "Hide the update manager after applying updates" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1773 -msgid "Name:" +#: usr/lib/linuxmint/mintUpdate/preferences.py:72 +msgid "Only show a tray icon when updates are available or in case of errors" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1775 -msgid "Version:" +#: usr/lib/linuxmint/mintUpdate/preferences.py:75 +msgid "Auto-refresh" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1777 -msgid "(optional)" +#: usr/lib/linuxmint/mintUpdate/preferences.py:76 +msgid "Refresh the list of updates automatically" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1984 -msgid "Do you want to switch to a local mirror?" +#: usr/lib/linuxmint/mintUpdate/preferences.py:88 +msgid "days" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1985 -msgid "Local mirrors are usually faster than packages.linuxmint.com." +#: usr/lib/linuxmint/mintUpdate/preferences.py:89 +msgid "hours" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1996 -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2006 -msgid "Please switch to another mirror" +#: usr/lib/linuxmint/mintUpdate/preferences.py:90 +msgid "minutes" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:1997 -#, python-format -msgid "%s is unreachable." +#: usr/lib/linuxmint/mintUpdate/preferences.py:91 +msgid "First, refresh the list of updates after:" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2007 -#, python-format -msgid "The last update on %(mirror)s was %(days)d day ago." -msgid_plural "The last update on %(mirror)s was %(days)d days ago." -msgstr[0] "" -msgstr[1] "" - -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2091 -msgid "Checking for updates" +#: usr/lib/linuxmint/mintUpdate/preferences.py:95 +msgid "Then, refresh the list of updates every:" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2099 +#: usr/lib/linuxmint/mintUpdate/preferences.py:106 msgid "" -"You have installed updates that require a restart to take effect. Please " -"restart your system as soon as possible." -msgstr "" - -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2103 -msgid "Restart" +"Note: The list only gets refreshed while the Update Manager window is closed " +"(in system tray mode)." msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2259 -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2267 -msgid "Your APT configuration is corrupt." +#: usr/lib/linuxmint/mintUpdate/preferences.py:110 +msgid "Notifications" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2260 -msgid "" -"Do not install or update anything - doing so could break your operating " -"system!" +#: usr/lib/linuxmint/mintUpdate/preferences.py:116 +msgid "Only show notifications for security and kernel updates" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2261 +#: usr/lib/linuxmint/mintUpdate/preferences.py:119 msgid "" -"To switch to a different Linux Mint mirror and solve this problem, click OK." +"Show a notification if an update has been available for (in logged-in days):" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2263 -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2264 -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2290 -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2291 -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2301 -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2302 -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2441 -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2442 -#: usr/share/linuxmint/mintupdate/main.ui.h:16 -msgid "Could not refresh the list of updates" +#: usr/lib/linuxmint/mintUpdate/preferences.py:122 +msgid "Show a notification if an update is older than (in days):" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2266 -msgid "Please switch to another Linux Mint mirror" +#: usr/lib/linuxmint/mintUpdate/preferences.py:125 +msgid "" +"Don't show notifications if an update was applied in the last (in days):" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2288 -msgid "Run 'apt update' in a terminal window to address this" +#: usr/lib/linuxmint/mintUpdate/preferences.py:154 +msgid "Update types" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2338 -msgid "Security update" +#: usr/lib/linuxmint/mintUpdate/preferences.py:154 +msgid "In addition to system packages, check for:" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2342 -msgid "Kernel update" +#: usr/lib/linuxmint/mintUpdate/preferences.py:156 +msgid "Cinnamon spice updates" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2346 -msgid "" -"Unstable software. Only apply this update to help developers beta-test new " -"software." +#: usr/lib/linuxmint/mintUpdate/preferences.py:168 +msgid "Ignored Updates" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2350 -msgid "Software update" +#: usr/lib/linuxmint/mintUpdate/preferences.py:191 +msgid "Package Updates" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2353 -msgid "3rd-party update" +#: usr/lib/linuxmint/mintUpdate/preferences.py:191 +msgid "Performed as root on a daily basis" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2377 -msgid "Flatpak application" +#: usr/lib/linuxmint/mintUpdate/preferences.py:192 +msgid "Apply updates automatically" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2379 -msgid "Flatpak runtime" +#: usr/lib/linuxmint/mintUpdate/preferences.py:196 +msgid "Export blacklist to /etc/mintupdate.blacklist" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2402 -msgid "Cinnamon applet" +#: usr/lib/linuxmint/mintUpdate/preferences.py:200 +msgid "Click this button to make automatic updates use your current blacklist." msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2404 -msgid "Cinnamon desklet" +#: usr/lib/linuxmint/mintUpdate/preferences.py:206 +msgid "Update Cinnamon spices automatically" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2409 -msgid "Nemo action" +#: usr/lib/linuxmint/mintUpdate/preferences.py:209 +msgid "Update Flatpaks automatically" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2411 -msgid "Cinnamon theme" +#: usr/lib/linuxmint/mintUpdate/preferences.py:212 +msgid "Other Updates" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2413 -msgid "Cinnamon extension" +#: usr/lib/linuxmint/mintUpdate/preferences.py:212 +msgid "Performed when you log in" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2430 -#, python-format -msgid "Error checking for flatpak updates: %s" +#: usr/lib/linuxmint/mintUpdate/preferences.py:251 +msgid "" +"Please specify the source package name of the update to ignore (wildcards " +"are supported) and optionally the version:" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2497 -msgid "Could not install the security updates" +#: usr/lib/linuxmint/mintUpdate/preferences.py:252 +msgid "Ignore an Update" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2520 -msgid "Updating Cinnamon Spices" +#: usr/lib/linuxmint/mintUpdate/preferences.py:260 +msgid "Name:" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2533 -msgid "Could not update Cinnamon Spices" +#: usr/lib/linuxmint/mintUpdate/preferences.py:262 +msgid "Version:" msgstr "" -#: usr/lib/linuxmint/mintUpdate/mintUpdate.py:2608 -msgid "Installing updates" +#: usr/lib/linuxmint/mintUpdate/preferences.py:264 +msgid "(optional)" msgstr "" #: usr/lib/linuxmint/mintUpdate/rel_upgrade.py:22 @@ -847,21 +768,20 @@ msgid "" "for all changes to take effect." msgstr "" -#: generate_desktop_files:26 -msgid "Show and install available updates" -msgstr "" - -#: usr/bin/mintupdate-launcher:57 +#: usr/lib/linuxmint/mintUpdate/session_automatic_upgrades.py:42 msgid "The following spices were automatically updated:" msgstr "" -#: usr/bin/mintupdate-launcher:66 +#: usr/lib/linuxmint/mintUpdate/session_automatic_upgrades.py:57 msgid "Cinnamon was restarted" msgstr "" +#: generate_desktop_files:26 +msgid "Show and install available updates" +msgstr "" + #: usr/share/linuxmint/mintupdate/history.ui.h:1 #: usr/share/linuxmint/mintupdate/information.ui.h:3 -#: usr/share/linuxmint/mintupdate/kernels.ui.h:5 #: usr/share/linuxmint/mintupdate/shortcuts.ui.h:2 msgid "Close" msgstr "" @@ -874,86 +794,6 @@ msgstr "" msgid "Log file:" msgstr "" -#: usr/share/linuxmint/mintupdate/kernels.ui.h:1 -msgid "Kernels" -msgstr "" - -#: usr/share/linuxmint/mintupdate/kernels.ui.h:2 -msgid "Kernel flavor:" -msgstr "" - -#: usr/share/linuxmint/mintupdate/kernels.ui.h:3 -msgid "Perform Queued Actions..." -msgstr "" - -#: usr/share/linuxmint/mintupdate/kernels.ui.h:4 -msgid "Remove Kernels..." -msgstr "" - -#: usr/share/linuxmint/mintupdate/kernels.ui.h:6 -msgid "Warning!" -msgstr "" - -#: usr/share/linuxmint/mintupdate/kernels.ui.h:7 -msgid "Proceed with caution" -msgstr "" - -#: usr/share/linuxmint/mintupdate/kernels.ui.h:8 -msgid "" -"Installing a new kernel can sometimes cause problems, especially if you're " -"using proprietary drivers." -msgstr "" - -#: usr/share/linuxmint/mintupdate/kernels.ui.h:9 -msgid "These issues include:" -msgstr "" - -#: usr/share/linuxmint/mintupdate/kernels.ui.h:10 -msgid "" -"- No wifi (or ethernet)\n" -"- No video acceleration\n" -"- Black screen on startup\n" -"- Random system freeze" -msgstr "" - -#: usr/share/linuxmint/mintupdate/kernels.ui.h:14 -msgid "If you face any of these issues, don't panic:" -msgstr "" - -#: usr/share/linuxmint/mintupdate/kernels.ui.h:15 -msgid "" -"- Reboot.\n" -"- Press and hold the Shift key to show the boot menu.\n" -"- In the boot menu, select the line which starts with 'Advanced options'.\n" -"- Select an older kernel.\n" -"- After the computer boots with the older kernel, uninstall the new one." -msgstr "" - -#: usr/share/linuxmint/mintupdate/kernels.ui.h:20 -msgid "Do not show this message again" -msgstr "" - -#: usr/share/linuxmint/mintupdate/kernels.ui.h:21 -#: usr/share/linuxmint/mintupdate/main.ui.h:14 -msgid "Help" -msgstr "" - -#: usr/share/linuxmint/mintupdate/kernels.ui.h:22 -msgid "Continue" -msgstr "" - -#: usr/share/linuxmint/mintupdate/kernels.ui.h:23 -msgid "Cancel" -msgstr "" - -#: usr/share/linuxmint/mintupdate/kernels.ui.h:24 -msgid "Apply" -msgstr "" - -#: usr/share/linuxmint/mintupdate/kernels.ui.h:25 -msgid "Please confirm the following actions:" -msgstr "" - #: usr/share/linuxmint/mintupdate/main.ui.h:1 #: usr/share/linuxmint/mintupdate/shortcuts.ui.h:6 msgid "Clear" @@ -1008,6 +848,10 @@ msgid "" "back in time and recover from any potential regression." msgstr "" +#: usr/share/linuxmint/mintupdate/main.ui.h:14 +msgid "Help" +msgstr "" + #: usr/share/linuxmint/mintupdate/main.ui.h:17 msgid "A new version of the Update Manager is available" msgstr "" From 4ead00f3197bbf527fdf9e768768095b6ed4209e Mon Sep 17 00:00:00 2001 From: Clement Lefebvre Date: Thu, 12 Nov 2026 11:55:27 +0000 Subject: [PATCH 18/21] 7.1.7 --- debian/changelog | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/debian/changelog b/debian/changelog index d8f89084..c2322c29 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,27 @@ +mintupdate (7.1.7) adrien; urgency=medium + + [ Michael Webster ] + * mintUpdate.py: Add set_prgname() + * Fix test script + * Fix flatpak errors being lost or hanging the update process. + * rel_upgrade_root: Stop the upgrade when a step fails or is cancelled. + * mintUpdate.py: Fix infobar handling when there are multiple issues + * rel_upgrade_root.py: Abort if cache update fails + * mintUpdate.py: Don't store the window's maximized size + * system_automatic_upgrades.py: Allow auto-update while on sufficient battery + + [ Pedro Barbosa ] + * rel_upgrade_root: Import syslog (#1099) + * Blacklist: Match the source version stored by "Ignore the current update" (#1112) + + [ LB ] + * Pass the exported blacklist to mintupdate-automation on stdin (#1096) + + [ Clement Lefebvre ] + * l10n: Update POT + + -- Clement Lefebvre Thu, 12 Nov 2026 11:55:21 +0000 + mintupdate (7.1.6) adrien; urgency=medium [ Danilo Rezende ] From a8415fe5e658e262f9ce2c8082b0f3373797f3cc Mon Sep 17 00:00:00 2001 From: Clement Lefebvre Date: Sat, 14 Nov 2026 10:20:59 +0000 Subject: [PATCH 19/21] mirror_check: Support DEB822 format --- usr/lib/linuxmint/mintUpdate/mintUpdate.py | 38 +++++++++++++++++----- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/usr/lib/linuxmint/mintUpdate/mintUpdate.py b/usr/lib/linuxmint/mintUpdate/mintUpdate.py index 7dc22a2e..94cbf3e3 100755 --- a/usr/lib/linuxmint/mintUpdate/mintUpdate.py +++ b/usr/lib/linuxmint/mintUpdate/mintUpdate.py @@ -1731,16 +1731,36 @@ def mirror_check(self): infobar_message_type = Gtk.MessageType.WARNING infobar_callback = self._on_infobar_mintsources_response try: - if os.path.exists("/usr/bin/mintsources") and os.path.exists("/etc/apt/sources.list.d/official-package-repositories.list"): + if os.path.exists("/usr/bin/mintsources"): mirror_url = None - with open("/etc/apt/sources.list.d/official-package-repositories.list", 'r') as sources_file: - for line in sources_file: - line = line.strip() - if line.startswith("deb ") and "main upstream import" in line: - mirror_url = line.split()[1] - if mirror_url.endswith("/"): - mirror_url = mirror_url[:-1] - break + deb822_sources_path = "/etc/apt/sources.list.d/official-package-repositories.sources" + legacy_sources_path = "/etc/apt/sources.list.d/official-package-repositories.list" + if os.path.exists(deb822_sources_path): + uris = None + with open(deb822_sources_path, 'r') as sources_file: + for line in sources_file: + line = line.strip() + # DEB822 field names are case-insensitive + lowercase_line = line.lower() + if not line: + uris = None + elif lowercase_line.startswith("uris:"): + uris = line.split()[1] + elif lowercase_line.startswith("components:") and "main upstream import" in lowercase_line and uris: + mirror_url = uris + break + elif os.path.exists(legacy_sources_path): + with open(legacy_sources_path, 'r') as sources_file: + for line in sources_file: + line = line.strip() + if line.startswith("deb ") and "main upstream import" in line: + mirror_url = line.split()[1] + break + else: + # No official sources file! + pass + if mirror_url is not None: + mirror_url = mirror_url.rstrip("/") if mirror_url is None or not mirror_url.startswith("http"): # The Mint mirror being used either cannot be found or is not an HTTP(s) mirror pass From bd6e0865b2a7d9ca9af8012bf9547884d21f7c0a Mon Sep 17 00:00:00 2001 From: Clement Lefebvre Date: Sat, 14 Nov 2026 10:21:30 +0000 Subject: [PATCH 20/21] rel_upgrade: Support DEB822 format --- usr/lib/linuxmint/mintUpdate/rel_upgrade_root.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/usr/lib/linuxmint/mintUpdate/rel_upgrade_root.py b/usr/lib/linuxmint/mintUpdate/rel_upgrade_root.py index d9aa8735..9b3eaf93 100755 --- a/usr/lib/linuxmint/mintUpdate/rel_upgrade_root.py +++ b/usr/lib/linuxmint/mintUpdate/rel_upgrade_root.py @@ -24,7 +24,11 @@ sys.exit(1) codename = sys.argv[1] -sources_list = f"/usr/share/mint-upgrade-info/{codename}/official-package-repositories.list" +sources_ext = "sources" +sources_list = f"/usr/share/mint-upgrade-info/{codename}/official-package-repositories.sources" +if not os.path.exists(sources_list): + sources_ext = "list" + sources_list = f"/usr/share/mint-upgrade-info/{codename}/official-package-repositories.list" if not os.path.exists(sources_list): print("Unrecognized release: %s" % codename) sys.exit(1) @@ -55,9 +59,11 @@ def run(self): def update_cache(self): # STEP 1: UPDATE APT SOURCES - if os.path.exists("/etc/apt/sources.list.d/official-source-repositories.list"): - subprocess.run(["rm", "-f", "/etc/apt/sources.list.d/official-source-repositories.list"]) - subprocess.run(["cp", sources_list, "/etc/apt/sources.list.d/official-package-repositories.list"]) + # Remove the files of both formats, so we never end up with the same repositories defined twice + for filename in ["official-source-repositories.list", "official-source-repositories.sources", + "official-package-repositories.list", "official-package-repositories.sources"]: + subprocess.run(["rm", "-f", f"/etc/apt/sources.list.d/{filename}"]) + subprocess.run(["cp", sources_list, f"/etc/apt/sources.list.d/official-package-repositories.{sources_ext}"]) # STEP 2: UPDATE APT CACHE self.client.set_finished_callback(self.on_cache_updated) From c523dff8ac65422302a714500ce2fca7708635fb Mon Sep 17 00:00:00 2001 From: Clement Lefebvre Date: Sat, 14 Nov 2026 10:51:08 +0000 Subject: [PATCH 21/21] 7.1.8 --- debian/changelog | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/debian/changelog b/debian/changelog index c2322c29..ffa11f2d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +mintupdate (7.1.8) adrien; urgency=medium + + * mirror_check: Support DEB822 format + * rel_upgrade: Support DEB822 format + + -- Clement Lefebvre Sat, 14 Nov 2026 10:51:01 +0000 + mintupdate (7.1.7) adrien; urgency=medium [ Michael Webster ]