Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Global shortcut portal support #240

Open
rhysperry111 opened this issue Sep 30, 2022 · 15 comments
Open

Global shortcut portal support #240

rhysperry111 opened this issue Sep 30, 2022 · 15 comments
Labels
enhancement New feature or request

Comments

@rhysperry111
Copy link

Currently there is a portal for registering global shortcuts in the works for xdg-desktop-portal v1.16.

I've just created this issue here to:

  • Gather opinions on how this might want to be implemented on the wlroots/sway side of things
  • Track progress of implementation

Since I don't think this is possible with current sway/wlroots, I presume it'd require a fair bit of development in both. Is this something that you think will be supported? The end goal is very similar to what the feature request of forwarding key events in sway would achieve.

Links:

@columbarius
Copy link
Collaborator

This project exists to interact between the portal api and wayland protocols. Unless there is a wayland protocol created (eg. https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/56) providing a comparable feature set this is blocked.

@columbarius columbarius added the enhancement New feature or request label Oct 10, 2022
@LaserEyess
Copy link

Because this is now a portal, I don't think that protocol is ever going to be finished. I am certainly not going to update it in favor of global shortcuts. So, what is the process of getting something in to wlr-protocols?

@vaxerski
Copy link

I don't think there is any. We can try making a PR to wlr-protocols ourselves for a global keybind protocol. I am always open to help with impls (both wlr and xdpw) if anyone's open to the idea.

@columbarius
Copy link
Collaborator

columbarius commented Nov 22, 2022 via email

@Slimemaster0
Copy link

Slimemaster0 commented Jan 13, 2023

How about intercepting the wayland-protocall like this proof-of-consept wayland-keylogger?
https://github.com/Aishou/wayland-keylogger

@PolyMeilex
Copy link

Well assuming the shortcut portal service would have appropriate permissions you could just read input events directly in compositor agnostic fashion and ignore the compositor all together.

@Slimemaster0
Copy link

Maybe we could have a dedicated shortcuts demon that runs as root and send envry keypress to the client (XDPW).

@rhysperry111
Copy link
Author

Not in the scope of this project, but a potential workaround might be a wrapper script that has the ability to send keypresses to a client:
keypress-wrap --id discord --exec /usr/bin/discord

And a script to trigger a keypress send:
bindsym $mod+m exec keypress-send --id discord --key ctrl,shift,m

@navi-desu
Copy link

Maybe we could have a dedicated shortcuts demon that runs as root and send envry keypress to the client (XDPW).

All it's needed for this WM agnostic portal would be access to /dev/input nodes, so a root daemon, or the user adds themselves to the input group, or maybe using the seatd api(? I'm not sure if seatd works like this).

A compositor agnostic portal is an interesting idea IMO.

@jokeyrhyme
Copy link

This project exists to interact between the portal api and wayland protocols.

I'd suggest a clarification on this point: I think this project is a bridge between the portals APIs and the features in wlroots-based compositors that can implement those APIs, not necessarily the broader/upstream wayland protocols and ecosystem

@jokeyrhyme
Copy link

jokeyrhyme commented May 13, 2023

Okay, so, I've read through:

From this, my understanding is that application developers (or developers of the frameworks/libraries used by application developers) need to do explicit work to adopt this:

  • use the portal API to request a GlobalShortcuts session
  • use the portal API to register the keyboard shortcuts they want (along with user-facing text to describe how they'll be used)
  • wait for portal API messages from DBus to know when one of these buttons is pressed and released (a.k.a. Activated and Deactivated), and triggers actions with the application that would normally be triggered by direct keyboard events

My understanding of the sort of work that would likely need to be done here in xdg-desktop-portal-wlr:

  • wlroots-based compositors (e.g. sway/river/hyprland/etc) already allow keys to be bound to certain actions, so x-d-g-wlr should use the same wlroots APIs (during BindShortcuts) to bind the requested GlobalShortcuts
  • however, instead of these keypresses resulting in the usual sort of compositor actions (e.g. change focus, run this user script, etc), they should result in the Activate and Deactivate signals to the app (via DBus)
  • optionally, during BindShortcuts, show the user the GlobalShortcuts request so that they can see which keys will be bound, although this might be out of scope (x-d-g-wlr traditionally outsources UX to other tools like dmenu, etc)
  • optionally, during BindShortcuts, allow the user to re-map the requested bindings to different keys (same UX issue)
  • optionally, during BindShortcuts, allow the user to ignore/block certain requested bindings and to approve other (same UX issue) bindings in the same request
  • maintain internal state (similar to Screencast sessions) for which keyboard events are associated with which GlobalShortcuts sessions
  • optionally, persist approved requests to a cache/config file so that future matching requests don't require human approval

Maybe we could have a dedicated shortcuts demon that runs as root

This is a possible solution, but I don't believe it's necessary, the compositor is already trapping keyboard shortcuts without needing to run as root, the only thing that's different here is the DBus messages

All it's needed for this WM agnostic portal would be access to /dev/input nodes, so a root daemon, or the user adds themselves to the input group, or maybe using the seatd api

Likewise, this shouldn't be necessary

Well assuming the shortcut portal service would have appropriate permissions you could just read input events directly in compositor agnostic fashion and ignore the compositor all together.

My understanding of the GlobalShortcuts portal API, and the way KDE has implemented it, is that applications would not directly receive the keyboard events, they instead receive DBus signal messages

The above is all based on my understanding, however, so of course I could be wrong and I could have misunderstood how this is supposed to work

@columbarius
Copy link
Collaborator

columbarius commented May 14, 2023

Your summary is mostly correct, the main issue is this point:

  • wlroots-based compositors (e.g. sway/river/hyprland/etc) already allow keys to be bound to certain actions, so x-d-g-wlr should use the same wlroots APIs (during BindShortcuts) to bind the requested GlobalShortcuts

There is no wlroots api for this. compositors implement their own custom controls (usually keybinds) via a configuration file (eg. sway) or a program (eg. riverctl).
xdpw is a separate wayland client and is not integrated in any compositor. xdpw only talks to the compositor via wayland protocols. As such we need a protocol to relay portal clients to the compositor. The mapping/decision logic will then again be in the compositor.

To clarify the situation is as follows:
application <---- dbus -----> xdg-desktop-portal <----- dbus -----> xdpw <----- wayland ------> compositor

@jokeyrhyme
Copy link

Okay, read through these and I can see that we're somewhat blocked:

There is another approach that allows for universal coverage of compositors without requiring root:

  • this is too generic for x-d-p-wlr, so likely would be a new x-d-p-??? that only implements GlobalShortcuts
  • x-d-p-??? does all the work outlined in Global shortcut portal support #240 (comment) but relies on user-supplied executables/scripts for the compositor-specific integration
  • for BindShortcut, x-d-p-??? calls a user script with necessary arguments/variables for each requested binding
  • the user script is responsible for calling swaymsg or riverctl to bind the key:
    • really 2 bindings, one for press->Activate and another for release->Deactivate
    • each binding should spawn busctl or dbus-send to send Activate/Deactivate to the application (or perhaps to x-d-p-??? acting as a proxy if it's too dynamic to be hardcoded)
    • e.g.
    #! /usr/bin/env sh
    swaymsg -t bindsym --no-repeat ${GLOBAL_KEY} exec 'busctl call ...'
    swaymsg -t bindsym --no-repeat --release ${GLOBAL_KEY} exec 'busctl call ...'
    
  • there'd need to be another user script responsible for similarly unbinding a given key (e.g. swaymsg -t unbindsym ...)
  • working examples of per-compositor scripts could be provided along with x-d-p-???

The BindShortcut flow:
application <---- dbus -----> xdg-desktop-portal <----- dbus -----> x-d-p-??? -----> user script ------> compositor

The key-press and key-release flow:
compositor ------> sh ------> busctl / dbus-send <----- dbus -----> application
or:
compositor ------> sh ------> busctl / dbus-send <----- dbus -----> x-d-p-??? <----- dbus -----> application

A few downsides though:

  • added latency given that each key-press now flows through at least one more component (and launches at least one more process) on its way to the destination application
  • complexity: it's already tricky for users to get the xdg-desktop-portal constellation working with exactly the correct environment variables and implementations setup, so requiring the user to copy in these scripts isn't going to help
  • both sway and river support separate key-press and key-release bindings, but I'm not sure how common this is, so maybe this would only end up solving the issue for a small number of compositors

@vaxerski
Copy link

vaxerski commented May 14, 2023

There is no good way to achieve this without a wayland protocol.

What you could do is make a daemon like your xdp? and then make a binary that sends a keybind status, e.g. xdp-shortcut name pressed xdp-shortcut name released. (basically like swaymsg but for your daemon)

Not ideal, but it would work.

A proper solution is obviously a wayland protocol, like Hyprland does with hyprland_global_shortcuts_v1 and xdph.

You could either get a protocol of a similiar nature to wayland-protocols, or just adopt the hyprland one in your compositor of choice and use xdph.

@YellowOnion
Copy link

In my uninformed opinion wlroots should just implement hyprland_global_shortcuts_v1 (if an implementation is even required), and either recommend a portal that bridges it, or add it to xdpw, I'm all for not reinventing the wheel if there's already a viable solution available.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

9 participants