tauri-apps / tauri

Build smaller, faster, and more secure desktop and mobile applications with a web frontend.
https://tauri.app
Apache License 2.0
85.38k stars 2.58k forks source link

[feat] [macOS] App focus gain/loss handlers #11670

Open stijnfrishert opened 1 week ago

stijnfrishert commented 1 week ago

Describe the problem

I am building a shortcut system for my desktop app, for triggering actions using hotkeys that aren't in any menu. From what I understand, there are two ways to go about this currently:

  1. Register keydown js listeners in the webview
  2. Register global key listeners on the Rust side using something like rdev.

Both solutions expose a problem on macOS: An application can have focus without having any windows open. For example: without any windows open, I would still like to be able to listen for Command + N, to open a new window.

  1. For JS, I'm registering key listeners directly on the window, but there's no way of listening to non-window key pressed afaik.
  2. For Rust, I can register global OS shortcuts (using rdev), but I would need to unregister these if the app loses focus. On macOS, this is not the same as checking if any window has focus.

In lieu of an actual key event handler solution on the Rust side (one that uses the app event loop itself), I'm inclined to go for solution 2, but I would need to know if my app has focus or not.

Describe the solution you'd like

Ideally, we could install an app focus loss/gain handler on the App builder, something along these lines:

tauri::Builder::default()
    .on_app_focus_gain(|app|{ }))
    .on_app_focus_loss(|app|{ }))
    .run()

These lambda's would directly map to NSApplicationDelegate::applicationDidBecomeActive() and its counterpart.

Alternatives considered

In this particular case I can put Command + N in my main application menu, and it will get triggered, but that is a happy coincidence. This isn't always the case.

Additional context

amrbashir commented 1 week ago

seems like your problem may just be solved by our global shortcut plugin, https://tauri.app/plugin/global-shortcut/

stijnfrishert commented 1 week ago

@amrbashir it is not, because global shortcut takes control over a shortcut for the entire system.

That means that if I register Cmd + S in my app, hitting that combination in any other app also results in my Tauri app triggering. Global-shortcut is something I would use for the Play Media or Fast Forward buttons, because you want your app to react even if it doesn't have focus.

In fact, the way to work around this is to register global shortcuts when your app gains focus, and unregistering them when your app loses focus. That is exactly what this feature request is about, but I think the bigger discussion's already happening in the other issue.


I would like to point out though, that getting a notification for when your app gains or loses focus (especially for mac users) is useful outside of hotkey management. I can imagine you might want to put your app in a low-battery mode, stop listening to hardware or sockets, or forego other intensive work when your app isn't in focus.

amrbashir commented 3 days ago

I see, this is more of a macOS specific as other OSes doesn't have similar behavior.