Skip to content

Wayland support#162

Open
Adamskye wants to merge 32 commits intotauri-apps:devfrom
Adamskye:wayland_support
Open

Wayland support#162
Adamskye wants to merge 32 commits intotauri-apps:devfrom
Adamskye:wayland_support

Conversation

@Adamskye
Copy link

@Adamskye Adamskye commented Sep 14, 2025

This PR adds support for creating global hotkeys on Wayland, using the XDG GlobalShortcuts portal. Closes #28.

The portal API works very differently to how this crate otherwise works. For instance, the application will specify some actions (with descriptions and a preferred trigger for each) and the hotkeys are configured externally.

I initially attempted to completely overhaul the API so that handling hotkeys on Wayland and non-Wayland systems is done with the same set of functions. However, this involved creating lots of breaking changes, and the developer would have needed to write extra Wayland-specific UI code anyway.

Thus, I made all Wayland-related API separate. There is GlobalHotKeyManager::wl_register_all() for handling hotkeys on Wayland, along with a small Wayland module for other Wayland-specific things. This PR shouldn't introduce any breaking changes, though note that I haven't yet tested this outside of Linux/Wayland, except that the tao example compiles on Windows.

The Wayland module comes with documentation.

I have tested this on KDE Plasma 6.4.4 and GNOME 48.5.

Supports:

  • Registering hotkey actions.
  • Unregistering hotkey actions.
  • Listing registered hotkeys.
  • Listening to changes in hotkeys.
  • Setting the app id (for non-sandboxed applications).

Does not support:

  • Specifying a parent window ID (isn't mandatory, could be added later).

@waxzce
Copy link

waxzce commented Sep 16, 2025

The CI breaks seems to be a rustc version, not your code, but maybe need a better rust version definition or in the docker

@Adamskye
Copy link
Author

The CI breaks seems to be a rustc version, not your code, but maybe need a better rust version definition or in the docker

Yeah, it's that and some clippy warnings. I upgraded the rustc version because of the ashpd crate iirc.

@SergioRibera
Copy link
Contributor

Hey @Adamskye do you need help fixing the workflows?

@Adamskye
Copy link
Author

Adamskye commented Nov 6, 2025

Hey @Adamskye do you need help fixing the workflows?

I don't have a Windows PC to test on currently so I would greatly appreciate that. Thank you.

@coral
Copy link

coral commented Nov 20, 2025

@Adamskye if you add me as a collaborator i can help you fix the windows build issue on this branch

@Adamskye
Copy link
Author

@Adamskye if you add me as a collaborator i can help you fix the windows build issue on this branch

Done.

…on windows is not thread safe, thus the example breaks when you compile it on windows, it only affects wayland regardless
@coral
Copy link

coral commented Nov 20, 2025

@Adamskye Ok it builds fine now.

The issue was doctest breaking on the example in wayland.rs, as the underlying windows HWND isn't thread safe, rust correctly refused to build that example on windows. Scoped it to only build on linux which resolves.

@Adamskye
Copy link
Author

@Adamskye Ok it builds fine now.

The issue was doctest breaking on the example in wayland.rs, as the underlying windows HWND isn't thread safe, rust correctly refused to build that example on windows. Scoped it to only build on linux which resolves.

Thank you very much.

@SergioRibera
Copy link
Contributor

@waxzce @FabianLars can you review this PR? I think it's ready 😅

@FabianLars
Copy link
Member

Would be appreciated if some of you can test it as well and share your feedback :) Not sure when i can test Linux stuff again tbh

@Adamskye
Copy link
Author

Rebinding hotkeys doesn't work properly in GNOME 48 currently, but it does work in GNOME 49. I backported the fixes into GNOME 48, so it should work properly in a future bugfix update (so people using Debian, for instance, should get fully working global shortcuts soon). The backports were merged recently, though they weren't included in 48.7, which was just released, so I'd expect them to be included in 48.8 in early January.

Worth noting in case anyone tests this on GNOME 48.

@coral
Copy link

coral commented Nov 25, 2025

I tried it on Fedora 43 and it worked!

@nglmercer
Copy link

Build and test works for me (on Windows 10).
imagen

@jkoking
Copy link

jkoking commented Dec 5, 2025

@waxzce @FabianLars
Tested on:

  • kde plasma: latest
  • gnome: latest
  • Windows 11: 24H2

Works great!
https://github.com/jkoking/hotkey-test

@coral
Copy link

coral commented Dec 19, 2025

@waxzce @FabianLars Seems tested by a few now, would appreciate a merge!

@Salman-Sali
Copy link

I am on Ubuntu 25.10, GNOME 49.
cargo test is passing.

However I tried to swap out the implementations in plugins-workspace and try out in my project, it does not work. But maybe my implementation is wrong.

This is the my swapped out code from plugin-workspace/plugins/global-shortcut/src/lib.rs

impl<R: Runtime> GlobalShortcut<R> {
    fn register_internal(...)(
        ...
        run_main_thread!(self.app, self.manager, |m| m.0.wl_register_all("com.myapp.app", &[WlNewHotKeyAction::new(1156747, "description", Some(shortcut))]))?;
        ...
    }

    fn register_multiple_internal(...){
        ...
        run_main_thread!(self.app, self.manager, |m| m.0.wl_register_all("com.myapp.app", &[WlNewHotKeyAction::new(1156747, "description", Some(shortcut))]))?;
       ...
    }
}

impl<R: Runtime> Builder<R> {
    pub fn with_handler(...){
        PluginBuilder::new("global-shortcut")
           ....
            .setup(move |app, _api| {
               ....
                for shortcut in shortcuts {
                    manager.wl_register_all("com.myapp.app", &[WlNewHotKeyAction::new(1156747, "description", Some(shortcut))])?;
                   ....
                }
                ....
            })
            .build()
    }
}

"com.myapp.app" is the "identifier" from tauri.conf.json
id i gave 1156747, because i don't know what it should be.

@Adamskye
Copy link
Author

I am on Ubuntu 25.10, GNOME 49. cargo test is passing.

However I tried to swap out the implementations in plugins-workspace and try out in my project, it does not work. But maybe my implementation is wrong.

This is the my swapped out code from plugin-workspace/plugins/global-shortcut/src/lib.rs

impl<R: Runtime> GlobalShortcut<R> {
    fn register_internal(...)(
        ...
        run_main_thread!(self.app, self.manager, |m| m.0.wl_register_all("com.myapp.app", &[WlNewHotKeyAction::new(1156747, "description", Some(shortcut))]))?;
        ...
    }

    fn register_multiple_internal(...){
        ...
        run_main_thread!(self.app, self.manager, |m| m.0.wl_register_all("com.myapp.app", &[WlNewHotKeyAction::new(1156747, "description", Some(shortcut))]))?;
       ...
    }
}

impl<R: Runtime> Builder<R> {
    pub fn with_handler(...){
        PluginBuilder::new("global-shortcut")
           ....
            .setup(move |app, _api| {
               ....
                for shortcut in shortcuts {
                    manager.wl_register_all("com.myapp.app", &[WlNewHotKeyAction::new(1156747, "description", Some(shortcut))])?;
                   ....
                }
                ....
            })
            .build()
    }
}

"com.myapp.app" is the "identifier" from tauri.conf.json id i gave 1156747, because i don't know what it should be.

I've had a look at your snippet.
Firstly, the id uniquely identifies a shortcut, so it should be different for each one. It doesn't otherwise matter what id you choose for each one.
Secondly, you should register all shortcuts in a single call to wl_register_all because the user may be shown a dialog box for each one otherwise. So basically, you'd map the shortcuts array to an array of WlNewHotKeyActions first, and then call wl_register_all.

@Adamskye
Copy link
Author

I've created a demo application that uses this PR here. I successfully tested it under Wayland (GNOME 49 and KDE Plasma 6.5), under X11 (LXQt), and also within a Flatpak sandbox. The hotkey code is in this file.

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.

Global Shortcut support on Wayland

8 participants