Skip to content

fix: use Cmd+Shift+Q for Quit Completely, fix app menu quit handler#3810

Merged
yujonglee merged 7 commits intomainfrom
devin/1770695769-quit-completely-cmd-shift-q
Feb 10, 2026
Merged

fix: use Cmd+Shift+Q for Quit Completely, fix app menu quit handler#3810
yujonglee merged 7 commits intomainfrom
devin/1770695769-quit-completely-cmd-shift-q

Conversation

@devin-ai-integration
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot commented Feb 10, 2026

Summary

Fixes two issues with "Quit Completely" after PR #3696:

  1. Misleading shortcut label: Both the app icon menu and tray icon menu showed ⌘Q for "Quit Completely", but ⌘Q is intercepted by the Swift overlay (press to close / hold to quit). Changed the accelerator to ⌘⇧Q.

  2. App icon menu "Quit Completely" didn't actually quit: Clicking "Quit Completely" in the app icon menu was intercepted by ExitRequested and just hid the dock — it never called TrayQuit::handle because only the tray icon had an on_menu_event handler. Replaced the tray-level handler with a single app-level on_menu_event on AppHandle so both app menu and tray menu clicks route through HyprMenuItem::handle.

  3. Restored window closing in ExitRequested: Brought back the window.close() loop that was removed in Replace Cmd+Q hide behavior with hold-to-quit overlay #3696, so intercepted exit requests also close all windows before hiding the dock icon.

  4. Swift interceptor now intercepts ⌘⇧Q directly: handleKeyDown consumes ⌘⇧Q and calls performQuit() immediately, preventing macOS from triggering its built-in "Log Out" system dialog. The ⌘⇧Q menu accelerator label remains as a visual hint only — the actual keyboard shortcut is handled entirely in Swift.

  5. Refactored Swift QuitInterceptor: Removed Event enum and transition() dispatch in favor of direct onCmdQPressed()/onKeyReleased() methods. Consolidated four timer functions into generic scheduleTimer/cancelTimer helpers. Extracted makeLabel to reduce duplication in view construction. Net -24 lines.

Review & Testing Checklist for Human

⚠️ All Swift/macOS changes were developed on Linux and have NOT been tested on macOS. End-to-end testing on a Mac is essential before merging.

  • Two different quit code paths: ⌘⇧Q (keyboard) triggers Swift's performQuit()rustSetForceQuit()NSApplication.shared.terminate(nil). Clicking "Quit Completely" (menu) triggers Rust's TrayQuit::handle()kill_processes_by_matcher()set_force_quit()app.exit(0). Verify both paths clean up properly (kill child processes, save state, etc.). Notably, the Swift keyboard path does not call kill_processes_by_matcher() — confirm this is acceptable or if it needs to be added.
  • Verify ⌘⇧Q is intercepted before macOS Log Out dialog: addLocalMonitorForEvents only sees events delivered to the app. If macOS intercepts ⌘⇧Q at the system level first, the Swift interceptor won't help. Test that pressing ⌘⇧Q quits the app without showing the macOS "Log Out" dialog.
  • Test on macOS end-to-end:
    • Press ⌘Q → overlay should appear ("Press ⌘Q to Close" / "Hold ⌘Q to Quit")
    • Press ⌘⇧Q → app should quit immediately (no Log Out dialog)
    • Click "Quit Completely" in app icon menu → should quit
    • Click "Quit Completely" in tray icon menu → should quit
    • Click other tray items (Open, Start) → should still work
  • Verify Swift refactor preserves behavior: The state machine logic was restructured but should be equivalent. The dismiss timer callback now has an explicit self.state == .awaiting guard — verify the overlay still auto-dismisses after 1.5s if you press ⌘Q once and release.
  • Verify app-level on_menu_event receives tray menu events: The tray-level on_menu_event was removed entirely. Confirm tray menu items still work via the app-level handler.

Notes

Co-Authored-By: yujonglee <yujonglee.dev@gmail.com>
@netlify
Copy link

netlify bot commented Feb 10, 2026

Deploy Preview for hyprnote-storybook canceled.

Name Link
🔨 Latest commit 5a25f73
🔍 Latest deploy log https://app.netlify.com/projects/hyprnote-storybook/deploys/698abbb7432c780008bcb208

@netlify
Copy link

netlify bot commented Feb 10, 2026

Deploy Preview for hyprnote canceled.

Name Link
🔨 Latest commit 5a25f73
🔍 Latest deploy log https://app.netlify.com/projects/hyprnote/deploys/698abbb75ef1370007e47b13

@devin-ai-integration
Copy link
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR that start with 'DevinAI' or '@devin'.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

Copy link
Contributor Author

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

View 5 additional findings in Devin Review.

Open in Devin Review

devin-ai-integration bot and others added 3 commits February 10, 2026 04:18
Co-Authored-By: yujonglee <yujonglee.dev@gmail.com>
…date timers, extract makeLabel

Co-Authored-By: yujonglee <yujonglee.dev@gmail.com>
Co-Authored-By: yujonglee <yujonglee.dev@gmail.com>
Copy link
Contributor Author

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 new potential issue.

View 7 additional findings in Devin Review.

Open in Devin Review

devin-ai-integration bot and others added 3 commits February 10, 2026 04:43
…d gesture

Co-Authored-By: yujonglee <yujonglee.dev@gmail.com>
Co-Authored-By: yujonglee <yujonglee.dev@gmail.com>
@yujonglee yujonglee merged commit 22d677d into main Feb 10, 2026
15 of 17 checks passed
@yujonglee yujonglee deleted the devin/1770695769-quit-completely-cmd-shift-q branch February 10, 2026 05:02
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.

1 participant