From 2850efdfa4a40b4878b026719fb39b9cca5bcc98 Mon Sep 17 00:00:00 2001 From: Ferran Date: Mon, 31 Aug 2026 10:41:10 +0200 Subject: [PATCH 1/3] Fix autofind to list profiles from every detected browser Automatic Discover picked whichever browser pack happened to appear first in enum declaration order and silently filtered the profile dropdown to that one browser only. On a machine with Firefox Snap and Waterfox both installed, this hid every Waterfox profile even though detection had already found them. - PackSelector now clears its package to None on Auto instead of leaving a stale filter in place. - Page passes no filter to the profile dropdown while autofinding, and syncs the backend's data-path to whichever browser owns the actively selected profile so status stays accurate across restarts. - Profile.display_name now includes the owning pack name so profiles with identical names across browsers (e.g. two "default-release") stay distinguishable in the dropdown. - Mentions Waterfox and CachyOS Browser in the metainfo description, which had fallen out of sync with the supported pack list. --- data/dev.qwery.AddWater.metainfo.xml.in | 2 +- src/gui/pack_selector.py | 5 ++-- src/page.py | 33 ++++++++++++++++++++++--- src/profile.py | 2 ++ 4 files changed, 36 insertions(+), 6 deletions(-) diff --git a/data/dev.qwery.AddWater.metainfo.xml.in b/data/dev.qwery.AddWater.metainfo.xml.in index 948a26e..4a8ba7d 100644 --- a/data/dev.qwery.AddWater.metainfo.xml.in +++ b/data/dev.qwery.AddWater.metainfo.xml.in @@ -18,7 +18,7 @@
  • Use an OLED-friendly pitch black for the interface
  • Customize Tab Bar position, position of controls, alignment, and more
  • Hide redundant microphone, webcam, screen share indicators
  • -
  • Supports Flatpak, Snap, Librewolf, and Floorp variants of Firefox
  • +
  • Supports Flatpak, Snap, Librewolf, Floorp, Waterfox, and CachyOS Browser variants of Firefox
  • *The Firefox GNOME Theme itself is independently developed and maintained by Rafael Mardojai CM.

    The Firefox browser is not included and must be downloaded separately. This project is not affiliated or endorsed by the Mozilla Foundation. Firefox is a trademark of the Mozilla Foundation in the U.S. and other countries.

    diff --git a/src/gui/pack_selector.py b/src/gui/pack_selector.py index 20ed281..c62b87b 100644 --- a/src/gui/pack_selector.py +++ b/src/gui/pack_selector.py @@ -19,7 +19,7 @@ import logging -from typing import Callable, Optional +from typing import Optional from gi.repository import Adw, Gio, GObject, Gtk @@ -38,7 +38,7 @@ class PackSelector(Adw.ComboRow): str_model: Gtk.StringList = Gtk.Template.Child() backend = None - package: FirefoxPack + package: Optional[FirefoxPack] = None inner_valid_path: bool autofind_paths: bool = GObject.Property(type=bool, default=True, flags=GObject.ParamFlags.READWRITE) @@ -71,6 +71,7 @@ def set_package(self): if selected_index == AUTO: self.autofind_paths = True + self.package = None log.info("Autofind paths enabled") self.valid_path = True self.emit("package-changed") diff --git a/src/page.py b/src/page.py index fe6ab73..54f5954 100644 --- a/src/page.py +++ b/src/page.py @@ -27,6 +27,7 @@ from packaging.version import Version from addwater import info +from addwater.backend import InterfaceMisuseError from addwater.profile import Profile from addwater.gui import ProfileSelector, PackSelector from addwater.apps.firefox import FirefoxPack @@ -184,11 +185,18 @@ def init_gui(self, options): pack = self.backend.get_package() self.package_combobox.setup_list(pack, self.backend) + + autofind_paths = self.settings.get_boolean("autofind-paths") + filter_pack = None if autofind_paths else pack self.profile_combobox.setup_list( self.backend.get_profiles(), self.settings.get_string("profile-selected"), - pack, + filter_pack, + ) + self.profile_combobox.connect( + "notify::selected-item", self.profile_changed_cb ) + self.profile_changed_cb() def bind_settings(self): # Primary Options @@ -227,8 +235,27 @@ def init_actions(self): self.package_combobox.connect("package-changed", self.package_changed_cb) def package_changed_cb(self, pack_selector): - if (pack := pack_selector.package): - self.profile_combobox.update_package_filter(pack) + self.profile_combobox.update_package_filter(pack_selector.package) + + def profile_changed_cb(self, *_args): + """Keep 'data-path' truthful to the currently selected profile while autofinding. + + The package selector is only a UI filter; it isn't the source of truth for + installation. When autofind is on, whichever browser owns the selected profile + should be reflected back into the backend so status queries (get_package) and + the persisted 'data-path' GSetting stay accurate across restarts. + """ + if not self.package_combobox.autofind_paths: + return + + profile = self.profile_combobox.get_selected_item() + if not profile: + return + + try: + self.backend.set_package(profile.package) + except InterfaceMisuseError as err: + log.error(f"Could not sync package to selected profile: {err}") def update_version_title(self): v = self.backend.get_update_version() diff --git a/src/profile.py b/src/profile.py index 967bcd9..910d83d 100644 --- a/src/profile.py +++ b/src/profile.py @@ -49,6 +49,8 @@ def __init__(self, name, id, path, favorite, package): @GObject.Property(type=str) def display_name(self) -> str: out = self.name + if self.package: + out += f" ({self.package.pack_name})" if self.favorite: out += " (Preferred)" From 8007ac2631acf4d47d58345d14ff515aae699215 Mon Sep 17 00:00:00 2001 From: Ferran Date: Mon, 31 Aug 2026 11:10:50 +0200 Subject: [PATCH 2/3] Drop data-path autofind sync to avoid a repeat-install loop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Real-device testing surfaced that syncing the backend's data-path to the actively selected profile on every selection change, combined with GTK's incremental filter/sort model settling, caused the theme to get reinstalled into multiple different profiles/browsers within seconds of a single launch — confirmed via traceback instrumentation, absent entirely on the unmodified code. Installation was never routed through the package/data-path anyway; Backend.begin_install always operates on the selected Profile's own path. Keeping data-path in sync with the UI selection was a status- display nicety, not something the fix needs, so drop it and keep only the verified change: not filtering the profile list while autofinding. --- src/page.py | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/src/page.py b/src/page.py index 54f5954..59edc63 100644 --- a/src/page.py +++ b/src/page.py @@ -27,7 +27,6 @@ from packaging.version import Version from addwater import info -from addwater.backend import InterfaceMisuseError from addwater.profile import Profile from addwater.gui import ProfileSelector, PackSelector from addwater.apps.firefox import FirefoxPack @@ -193,10 +192,6 @@ def init_gui(self, options): self.settings.get_string("profile-selected"), filter_pack, ) - self.profile_combobox.connect( - "notify::selected-item", self.profile_changed_cb - ) - self.profile_changed_cb() def bind_settings(self): # Primary Options @@ -237,26 +232,6 @@ def init_actions(self): def package_changed_cb(self, pack_selector): self.profile_combobox.update_package_filter(pack_selector.package) - def profile_changed_cb(self, *_args): - """Keep 'data-path' truthful to the currently selected profile while autofinding. - - The package selector is only a UI filter; it isn't the source of truth for - installation. When autofind is on, whichever browser owns the selected profile - should be reflected back into the backend so status queries (get_package) and - the persisted 'data-path' GSetting stay accurate across restarts. - """ - if not self.package_combobox.autofind_paths: - return - - profile = self.profile_combobox.get_selected_item() - if not profile: - return - - try: - self.backend.set_package(profile.package) - except InterfaceMisuseError as err: - log.error(f"Could not sync package to selected profile: {err}") - def update_version_title(self): v = self.backend.get_update_version() version_str = parse_version_str(v) From d96159a1c08542141eb53eb0fd611972c30aa6fe Mon Sep 17 00:00:00 2001 From: Ferran Date: Mon, 31 Aug 2026 11:31:49 +0200 Subject: [PATCH 3/3] Ignore Claude Code local config (CLAUDE.md, .claude/) These are local assistant instructions/state for this working copy, not part of the upstream project. --- .gitignore | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index b32162f..74f106b 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,11 @@ pylint-results.txt .pytest_cache tests/__pycache__ subprojects/libportal -.wraplock \ No newline at end of file +.wraplock +# hyperresearch (per-project research vault) +.hyperresearch/ +research/temp/ +research/index/ +# Claude Code local config/instructions, not part of upstream project +CLAUDE.md +.claude/