Skip to content

feat: Add "Start minimized", "Start at login" options. Use single instance of application.#39

Merged
TomBadash merged 4 commits intoTomBadash:masterfrom
awkure:feat/start-minimized
Mar 25, 2026
Merged

feat: Add "Start minimized", "Start at login" options. Use single instance of application.#39
TomBadash merged 4 commits intoTomBadash:masterfrom
awkure:feat/start-minimized

Conversation

@awkure
Copy link
Contributor

@awkure awkure commented Mar 22, 2026

Summary

This branch improves how Mouser starts: optional tray-only launch from config, cross-platform “start at login” via core.startup, and a Qt local-socket single-instance guard that brings the existing window forward when a second launch is attempted.

Changes

  • core/startup.py — New module that applies login startup on Windows (HKCU Run) and macOS (LaunchAgent plist + launchctl), with helpers to build the stored command line for frozen and script runs.
  • core/config.py — Version 5 migration now maps legacy start_with_windows only when that key exists, defaults start_at_login otherwise, and removes the old key after migration.
  • ui/backend.py — Replaces the previous autostart integration with core.startup: sync on init when supported, clear start_at_login when unsupported, and call apply_login_startup when the user toggles the setting.
  • ui/qml/ScrollPage.qml — Copy and layout tweaks: “start at login” row hidden when unsupported; “start minimized” is independent of login and always available; improved wrapping for the description text.
  • main_qml.py — Reads start_minimized (and --start-hidden) to set launchHidden; adds QLocalServer/QLocalSocket single-instance logic with activation message to show the main window; optional tray balloon when starting minimized with a system tray.
  • Teststests/test_startup.py for the new module; tests/test_single_instance.py for instance helpers; updates to tests/test_config.py, tests/test_backend.py, and a small path assertion fix in tests/test_autostart.py.

How to verify

  • Run unit tests: python -m unittest tests.test_startup tests.test_config tests.test_backend tests.test_single_instance tests.test_autostart.
  • Launch the app twice: the second process should exit and the first should show the settings window.
  • With “start minimized” on, first launch should keep the main window hidden (per existing QML) and show the tray hint when a tray is available.

Notes

  • Legacy core.autostart remains for existing macOS-specific helpers/tests; runtime login registration is handled by core.startup.

awkure and others added 4 commits March 25, 2026 11:59
Add core/startup.py for Windows registry Run and macOS LaunchAgent.

Adjust v5 migration: map start_with_windows only when present, drop legacy key.

Tests for startup helpers, config migration, and autostart plist path.
Backend syncs OS login items and applies user toggles.

ScrollPage: gate login row on supportsStartAtLogin; start minimized independent.

Update backend unit tests.
QLocalServer/socket second-instance handoff shows main window.

launchHidden from start_minimized and --start-hidden; tray notice when minimized.

Add single-instance unit tests.
- Change start_minimized fallback from True to False so the app doesn't start hidden on first launch when the config key is missing.

- Wrap apply_login_startup in try/except so registry or launchctl errors emit a status message instead of crashing.
@TomBadash
Copy link
Owner

Thanks for this great contribution @awkure! Really nice work on the single-instance guard, cross-platform login startup, and decoupling start minimized from start at login.

I made a couple of small fixes before merging:

  1. Fixed start_minimized default in main_qml.py — cfg_settings.get('start_minimized', True) was defaulting to True, which would hide the app window on first launch if the config key was missing. Changed to False.

  2. Added error handling around �pply_login_startup() in �ackend.py — wrapped in try/except so a registry or launchctl failure emits a status message instead of crashing.

  3. Fixed est_autostart.py — str(Path(fake_executable)) converted forward slashes to backslashes on Windows, breaking the assertion. Reverted to direct string comparison.

  4. Resolved merge conflicts with master (config migration v6, import merges, test version assertions).

All tests passing. Merging now!

@TomBadash TomBadash force-pushed the feat/start-minimized branch from 5f3522a to 4b4036f Compare March 25, 2026 10:13
@TomBadash TomBadash merged commit 36f377e into TomBadash:master Mar 25, 2026
1 check failed
TomBadash added a commit that referenced this pull request Mar 25, 2026
- Patch os.path.abspath in startup build_run_command tests so Windows paths resolve correctly on Linux

- Use string-based patch for QLocalServer.removeServer to avoid AttributeError when PySide6 is unavailable

- Patch os.path.basename/abspath in Windows exe path test for cross-platform compatibility

- Fix autostart plist test to compare raw string instead of Path object
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants