From db2c83f08043ee69141459144c744a2972f3615a Mon Sep 17 00:00:00 2001 From: Bob Date: Tue, 8 Sep 2026 17:25:48 +0000 Subject: [PATCH 1/2] build(deps): bump aw-qt and aw-tauri for profile-aware autostart aw-qt 1337c9a -> e285e77: feat(autostart): preserve named profile at login (#133) plus fix(config): isolated-root config.toml (#132) aw-tauri 20a4f40 -> 924150c: feat(autostart): isolate named profile entries (#253) Dependabot's gitsubmodule cadence is monthly, so without this the next release would not carry named-profile login commands. Git-Session-Id: 1ee8 --- aw-qt | 2 +- aw-tauri | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/aw-qt b/aw-qt index 1337c9a9b..e285e77e3 160000 --- a/aw-qt +++ b/aw-qt @@ -1 +1 @@ -Subproject commit 1337c9a9b7d284f254118ffb9c149d12e5ca36c4 +Subproject commit e285e77e3d106215a968e87ea5a33923db6dba32 diff --git a/aw-tauri b/aw-tauri index 20a4f4083..924150c59 160000 --- a/aw-tauri +++ b/aw-tauri @@ -1 +1 @@ -Subproject commit 20a4f408390e1ee6332df4d572f43b38201a877b +Subproject commit 924150c5923bdf1d35a83f4ef3fa23be6f2924a6 From 3e5f7d7152a3408cfad181280e77e6981ed37f68 Mon Sep 17 00:00:00 2001 From: Bob Date: Tue, 8 Sep 2026 17:48:25 +0000 Subject: [PATCH 2/2] fix(research): keep edition autostart distinct from named profiles aw-qt#133 / aw-tauri#253 give named profiles their own login entries. The research edition is profile=research, so the old patcher targets missed the new Linux path and would have collided with a standard `--profile research` login item. Override edition identities explicitly: - Qt Linux: activitywatch-research.desktop - Qt macOS: net.activitywatch.ActivityWatch-research - Tauri: aw-tauri-{BUILD_PROFILE}-edition Git-Session-Id: 1ee8 --- scripts/patch_research_edition_profile.py | 89 ++++++++----------- .../test_patch_research_edition_profile.py | 40 +++++---- 2 files changed, 60 insertions(+), 69 deletions(-) diff --git a/scripts/patch_research_edition_profile.py b/scripts/patch_research_edition_profile.py index a53d607c2..cb38bf51c 100644 --- a/scripts/patch_research_edition_profile.py +++ b/scripts/patch_research_edition_profile.py @@ -548,6 +548,13 @@ def _python_profile_patches(path: str) -> List[Patch]: # names are independent of the installer's: without this the two editions # overwrite each other's login item / Startup shortcut / autostart .desktop even # though every other identity is already split. +# +# aw-qt#133 made those names profile-aware (`aw-qt-research.desktop`, +# `net.activitywatch.aw-qt-research`, `ActivityWatch (research)`). The research +# edition *is* profile=research, so the suffix alone collides with a standard +# build launched as `--profile research`. Override the written identities to +# edition-specific names; leave DESKTOP_FILENAME / LAUNCH_AGENT_LABEL as the +# shipped-resource / base strings. AUTOSTART_PATCHES_QT: List[Patch] = [ Patch( @@ -558,16 +565,18 @@ def _python_profile_patches(path: str) -> List[Patch]: ), Patch( "aw-qt/aw_qt/autostart.py", - " return _linux_autostart_dir() / DESKTOP_FILENAME\n", + ' return _linux_autostart_dir() / f"{stem}{_profile_suffix()}{extension}"\n', f' return _linux_autostart_dir() / "{LINUX_DESKTOP_FILENAME}"\n', "Linux autostart entry filename (DESKTOP_FILENAME still names the " - "shipped resource we copy from)", + "shipped resource we copy from; do not use aw-qt-research.desktop — " + "that is the standard build's named-profile entry)", ), Patch( "aw-qt/aw_qt/autostart.py", - 'LAUNCH_AGENT_LABEL = "net.activitywatch.aw-qt"\n', - f'LAUNCH_AGENT_LABEL = "{LAUNCH_AGENT_LABEL}"\n', - "macOS LaunchAgent label and plist filename", + ' return f"{LAUNCH_AGENT_LABEL}{_profile_suffix()}"\n', + f' return "{BUNDLE_ID}"\n', + "macOS LaunchAgent label (bundle id, not net.activitywatch.aw-qt-research, " + "which is the standard build's named-profile label)", ), Patch( "aw-qt/aw_qt/autostart.py", @@ -579,13 +588,10 @@ def _python_profile_patches(path: str) -> List[Patch]: # --- first-run autostart identity (Tauri) -------------------------------------- -# tauri_plugin_autostart derives its OS entry name from productName by default. -# Standard and research Tauri builds share productName="aw-tauri", so their -# autostart entries (Windows registry Run key, Linux ~/.config/autostart/ file) -# overwrite each other. Give the research build a distinct name by switching to -# the Builder API and setting app_name when BUILD_PROFILE is not the default. -# macOS uses different OS mechanisms (AppleScript vs LaunchAgent) so it doesn't -# collide, but the macos_launcher selection is included for completeness. +# aw-tauri#253 already gives named profiles a distinct plugin app name +# (`aw-tauri-research`). The research edition *is* profile=research, so that +# name collides with a standard build launched as `--profile research`. Override +# with an edition-specific `aw-tauri-{BUILD_PROFILE}-edition` identity. # # This patch applies after PROFILE_PATCHES_TAURI, so BUILD_PROFILE and # DEFAULT_PROFILE are both defined in the compiled profile module by the time @@ -594,47 +600,26 @@ def _python_profile_patches(path: str) -> List[Patch]: AUTOSTART_PATCHES_TAURI: List[Patch] = [ Patch( "aw-tauri/src-tauri/src/lib.rs", - " .plugin(tauri_plugin_autostart::init(\n" - " // AppleScript login items silently drop extra arguments; LaunchAgent\n" - " // writes a plist with ProgramArguments so --profile survives relogin.\n" - " if profile::is_default(&cli_args.profile) {\n" - " MacosLauncher::AppleScript\n" - " } else {\n" - " MacosLauncher::LaunchAgent\n" - " },\n" - " if profile::is_default(&cli_args.profile) {\n" - " Some(vec![])\n" - " } else {\n" - " Some(vec![\"--profile\", cli_args.profile.as_str()])\n" - " },\n" - " ))\n", - " .plugin({\n" - " // AppleScript login items silently drop extra arguments; LaunchAgent\n" - " // writes a plist with ProgramArguments so --profile survives relogin.\n" - " // Non-default BUILD_PROFILE means a research-edition binary: give it a\n" - " // distinct autostart entry name so editions don't overwrite each other.\n" - " let is_default_profile = profile::is_default(&cli_args.profile);\n" - " let args: Vec<&str> = if is_default_profile {\n" - " vec![]\n" - " } else {\n" - " vec![\"--profile\", cli_args.profile.as_str()]\n" - " };\n" - " #[allow(unused_mut)]\n" - " let mut b = tauri_plugin_autostart::Builder::new().args(args);\n" - " if profile::BUILD_PROFILE != profile::DEFAULT_PROFILE {\n" - " b = b.app_name(format!(\"aw-tauri-{}\", profile::BUILD_PROFILE));\n" + " if let Some(app_name) = profile::autostart_app_name(&cli_args.profile) {\n" + " builder = builder\n" + " .app_name(app_name)\n" + " .args([\"--profile\", cli_args.profile.as_str()]);\n" + " }\n", + " if let Some(app_name) = profile::autostart_app_name(&cli_args.profile) {\n" + " builder = builder\n" + " .app_name(app_name)\n" + " .args([\"--profile\", cli_args.profile.as_str()]);\n" " }\n" - " #[cfg(target_os = \"macos\")]\n" - " {\n" - " b = b.macos_launcher(if is_default_profile {\n" - " MacosLauncher::AppleScript\n" - " } else {\n" - " MacosLauncher::LaunchAgent\n" - " });\n" - " }\n" - " b.build()\n" - " })\n", - "tauri autostart: Builder with distinct app_name for research edition", + " // Non-default BUILD_PROFILE is a research-edition binary: do not\n" + " // reuse the named-profile identity (`aw-tauri-research`), which a\n" + " // standard `--profile research` login item already owns.\n" + " if profile::BUILD_PROFILE != profile::DEFAULT_PROFILE {\n" + " builder = builder.app_name(format!(\n" + " \"aw-tauri-{}-edition\",\n" + " profile::BUILD_PROFILE\n" + " ));\n" + " }\n", + "tauri autostart: edition-specific app_name so research != named profile", ), ] diff --git a/scripts/tests/test_patch_research_edition_profile.py b/scripts/tests/test_patch_research_edition_profile.py index 9e5bac3d2..9a9a19761 100644 --- a/scripts/tests/test_patch_research_edition_profile.py +++ b/scripts/tests/test_patch_research_edition_profile.py @@ -436,21 +436,26 @@ def test_first_run_autostart_identity_is_distinct_on_every_platform(tmp_path: Pa # Linux: the written filename changes; the *shipped resource* name does not # (the patched build still reads resources/aw-qt.desktop out of the bundle). + # Must not be aw-qt-research.desktop — that is the standard named-profile entry. assert f'_linux_autostart_dir() / "{patcher.LINUX_DESKTOP_FILENAME}"' in after + assert "aw-qt-research.desktop" not in after assert 'DESKTOP_FILENAME = "aw-qt.desktop"' in after - # macOS: LAUNCH_AGENT_FILENAME is derived, so the plist follows the label. - assert f'LAUNCH_AGENT_LABEL = "{patcher.LAUNCH_AGENT_LABEL}"' in after - assert 'LAUNCH_AGENT_LABEL = "net.activitywatch.aw-qt"\n' not in after + # macOS: plist path follows _macos_launch_agent_label(), which would otherwise + # become net.activitywatch.aw-qt-research and collide with --profile research. + assert f'return "{patcher.BUNDLE_ID}"' in after + assert 'return f"{LAUNCH_AGENT_LABEL}{_profile_suffix()}"' not in after + assert f'return "{patcher.LAUNCH_AGENT_LABEL}"' not in after # Windows: both the Run value name and the Startup .lnk derive from APP_NAME. + # Named-profile suffixing then yields "ActivityWatch Research (research)". assert f'APP_NAME = "{patcher.BUNDLE_NAME}"' in after assert 'APP_NAME = "ActivityWatch"\n' not in after - # Guard the derivations the assertions above rely on: if upstream stops - # deriving these, the research build silently keeps a colliding name. + # Guard the runtime identity sources: if upstream stops suffixing these, the + # research overrides above would be patching dead code. for derived in ( - 'LAUNCH_AGENT_FILENAME = f"{LAUNCH_AGENT_LABEL}.plist"', - "WINDOWS_RUN_VALUE_NAME = APP_NAME", - 'WINDOWS_STARTUP_SHORTCUT_NAME = f"{APP_NAME}.lnk"', + 'return _linux_autostart_dir() / f"{stem}{_profile_suffix()}{extension}"', + 'return f"{LAUNCH_AGENT_LABEL}{_profile_suffix()}"', + 'return APP_NAME if not suffix else f"{APP_NAME} ({_profile()})"', ): assert derived in before, f"upstream no longer derives: {derived}" @@ -487,23 +492,24 @@ def test_tauri_autostart_uses_distinct_app_name_for_research_build(tmp_path: Pat ) assert f'pub const BUILD_PROFILE: &str = "{patcher.RESEARCH_PROFILE}";' in after_profile - # --- half 2: AUTOSTART_PATCHES_TAURI replaces init() with Builder + app_name --- + # --- half 2: AUTOSTART_PATCHES_TAURI overrides named-profile app_name --- lib_rs_rel = "aw-tauri/src-tauri/src/lib.rs" lib_rs_src = _repo_root() / lib_rs_rel if not lib_rs_src.is_file(): pytest.skip(f"{lib_rs_rel} not present") before_lib = lib_rs_src.read_text(encoding="utf-8") - # Standard source uses init(), not Builder - assert "tauri_plugin_autostart::init(" in before_lib - assert "tauri_plugin_autostart::Builder::new()" not in before_lib + # Standard source already uses Builder + named-profile identities. + assert "tauri_plugin_autostart::Builder::new()" in before_lib + assert "profile::autostart_app_name" in before_lib + assert "BUILD_PROFILE" not in before_lib after_lib = _patch_real_file( tmp_path, lib_rs_rel, patcher.AUTOSTART_PATCHES_TAURI, ) - # Research build uses Builder with conditional app_name - assert "tauri_plugin_autostart::Builder::new().args(args)" in after_lib + # Research build keeps named-profile wiring, then overrides the OS identity + # so it does not collide with a standard `--profile research` login item. + assert "profile::autostart_app_name" in after_lib assert "profile::BUILD_PROFILE != profile::DEFAULT_PROFILE" in after_lib - assert 'b.app_name(format!("aw-tauri-{}", profile::BUILD_PROFILE))' in after_lib - # Standard autostart call is gone - assert "tauri_plugin_autostart::init(" not in after_lib + assert '"aw-tauri-{}-edition"' in after_lib + assert 'format!("aw-tauri-{}", profile::BUILD_PROFILE)' not in after_lib