-
-
Notifications
You must be signed in to change notification settings - Fork 150
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
implement keyboard-shortcuts-inhibit
and wlr-virtual-pointer
#630
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Smithay docs refer to a nonexistent function so i had to check 2-year-old git blames to find out what replaced it. We just ignore the axis source if it's done before an arbitrary other thing??
I haven't looked in detail but if it involves axis v120 events then yeah it's like this pretty much because of legacy, v120 events replaced the old ones: https://wayland.freedesktop.org/libinput/doc/latest/wheel-api.html
src/input/mod.rs
Outdated
@@ -2221,6 +2247,18 @@ fn should_intercept_key( | |||
} | |||
} | |||
|
|||
if is_inhibiting_shortcuts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a feeling that this should interact in a more complex manner with the match
below because starting to inhibit while some modifier is held (and in suppressed_keys
) then releasing the modifier will currently leave it in suppressed_keys
, which does not seem right.
This behavior should also be tested in the unit tests below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've since updated the handling in a way that i think works with supressed_keys
properly (and i've commented the behaviour), but to be honest, thinking about the order of events kinda makes my head hurt and i'm dreading writing the requested tests. I'm also not entirely confident that my intuition of how it should behave exactly aligns with what you think it should do? Do you wanna take a shot at writing tests for this? 🥺👉👈
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems fine to me. For the tests, just add a few cases with the shortcuts inhibited = true. For pressing and releasing allow-inhibit, !allow-inhibit, which also check suppress keys. Basically check that a shortcut that would return Intercept() returns instead Forward if inhibited = true. And maybe also something which first does a press with inhibited = true, then release with inhibited = false in case that logic would change later.
keyboard-shortcuts-inhibit
and wlr-virtual-pointer
bfd9d78
to
62982c4
Compare
I've implemented the I've also made sure you can't bind
The uhh... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like someone to verify that this is how the Axis* events are suppposed to work. Basically if we get more than one timestamp in a single frame, all but the first are ignored. And... AxisDiscrete overrides the values set by Axis? It feels very dirty, but judging by the AxisFrame struct in Smithay, it feels like the protocol should not really be allowing any of these requests to be sent twice in one frame. It feels very jank, and i know little about how axis events actually work, i just plugged together the parts of Smithay that "looked" about right to me.
The uhh... AxisSource request is optional (i think?) but PointerAxisEvent::source() does not allow a None value, so this is definitely wrong. The AxisFrame struct cannot be constructed without a timestamp, so for the AxisSource event, which doesn't include a timestamp, it's just dropped because no AxisFrame can be started; a different Axis* event must be sent first for the AxisSource to amend it.
Yeah idk tbh, I would just test with several wlr-virtual-pointer clients to see that they work. And if there's something weird, check in WAYLAND_DEBUG=1 what events they send.
(btw, what wlr-virtual-pointer clients are there apart from lan-mouse? I'll need a few to test this I guess)
resources/default-config.kdl
Outdated
// | ||
// The allow-inhibiting=false property can be applied to other binds as well, | ||
// which ensures niri always processes them, even when an inhibitor is active. | ||
Mod+Shift+Escape allow-inhibiting=false { toggle-keyboard-shortcuts-inhibit; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should bind this to Mod+Escape
by default because Super+Escape is the default in GNOME: https://gitlab.gnome.org/GNOME/mutter/-/blob/d7d92c68bd5c76525752feab65c44b3157deb7f1/data/org.gnome.mutter.wayland.gschema.xml.in#L58-61
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reasoning for not doing this is so:
The primary release mechanism should be implemented in the client. It will know best what keys are in use and easily accessible. In many cases, we'd expect the client to release on Super+Escape
(because inhibiting shortcuts means you're free to use Super
for whatever binds, and Super+Escape
is unlikely to mean anything else), but if it does mean something else then the client knows best what is an appropriate release shortcut.
The reason why i chose Mod+Shift+Escape
is because that's the shortcut to open Task Manager on Windows; so it already has the connotation of "An app is misbehaving!! Help me, operating system!" in some users' minds (including my own).
The difference is, however, ultimately arbitrary. So if you disagree with the above, i'll change it to Mod+Escape
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In many cases, we'd expect the client to release on Super+Escape (because inhibiting shortcuts means you're free to use Super for whatever binds, and Super+Escape is unlikely to mean anything else), but if it does mean something else then the client knows best what is an appropriate release shortcut.
Well, my thinking is, if Super+Escape is the default on GNOME, then client devs might decide not to do anything on Super+Escape client-side and generally expect it to already work, and definitely not bind it to something other important (considering GNOME is by and large the "default desktop", and any client testing likely occurs on GNOME).
The reason why i chose Mod+Shift+Escape is because that's the shortcut to open Task Manager on Windows
Oh? I always used Ctrl+Shift+Escape (and Ctrl-Alt-Delete before that started bringing up the menu).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh? I always used Ctrl+Shift+Escape
actually that sounds about right. i may have misremembered and just Made Up This Shortcut (by changing the first modifier in the sequence)
then yeah, let's make it parity with GNOME. i'm still happy with that 'cause i can just use the one i prefer in my config :3
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mod+Shift+Escape allow-inhibiting=false { toggle-keyboard-shortcuts-inhibit; } | |
Mod+Escape allow-inhibiting=false { toggle-keyboard-shortcuts-inhibit; } |
so yeah
Mod+T allow-when-locked=true { spawn "alacritty"; } | ||
Mod+Q { close-window; } | ||
Mod+Shift+H { focus-monitor-left; } | ||
Mod+Ctrl+Shift+L { move-window-to-monitor-right; } | ||
Mod+Comma { consume-window-into-column; } | ||
Mod+1 { focus-workspace 1; } | ||
Mod+Shift+1 { focus-workspace "workspace-1"; } | ||
Mod+Shift+E { quit skip-confirmation=true; } | ||
Mod+Shift+E allow-inhibiting=false { quit skip-confirmation=true; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if allow-inhibiting=false
is a bit hard to wrap one's head around? Maybe something along prevent-inhibiting=true
would be better, human config file reading and writing wise?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i don't feel like that change is an improvement, because prevent-inhibiting=true
is a double negative. but also, i agree with your concern, and i think it's slightly confusing because allow-inhibiting=false
is also a double negative, because the value it will be set to is false.
is there a way to name it that isn't a double negative? always-available=true
, but more descriptive? borrow an idiom from CSS and call it important=true
? maybe with the exclamation point to drive home the correlation? !important=true
. though it reads as "not".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm, difficult question indeed. I like the word "inhibit" being there because it's the technical term for this (unless it isn't always? do some apps re-phrase it?).
If we drop inhibit, maybe something like "always-accessible" is better than "always-available"? That's kind of still not very descriptive, while it does control a very specific thing, so it would be good if it were descriptive...
src/input/mod.rs
Outdated
@@ -2221,6 +2247,18 @@ fn should_intercept_key( | |||
} | |||
} | |||
|
|||
if is_inhibiting_shortcuts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems fine to me. For the tests, just add a few cases with the shortcuts inhibited = true. For pressing and releasing allow-inhibit, !allow-inhibit, which also check suppress keys. Basically check that a shortcut that would return Intercept() returns instead Forward if inhibited = true. And maybe also something which first does a press with inhibited = true, then release with inhibited = false in case that logic would change later.
just about any KVM or RDP software. Something like deskflow or input leap should do the same thing as lan-mouse. I also noticed that WayVNC works just fine with niri as of this PR, as it has several capture protocols including Most of these should probably also be using keyboard shortcuts inhibit? Unsure. I know |
62982c4
to
234b6b5
Compare
Hi, I was trying to setup wayvnc and having some issues with wlr-virtual-pointer. Has this issue been resolved in niri-0.1.9-1. If yes, how can I set it up? |
wlr-virtual-pointer is part of this PR. It is not yet merged |
Note that Currently, i'm fairly busy with a bunch of exams and other assignments at school, which is why i haven't been very actively working on this PR (and others) for some time. I'll get to it sometime, and also improve the virtual keyboard situation such that WayVNC will work properly, as i do actually also wish to use WayVNC eventually. I have no ETA on when all of this will be finished; it's a fairly broad scope of work requiring changes in Smithay's input backend and not just niri. If you don't find the lack of keyboard shortcuts to be problematic, and still wish to use WayVNC and want to do it right now, you can just run this PR as-is, before it's merged. Its not necessarily up-to-date with the most recent version of niri, so you'd be "downgrading" slightly (not by much). I am running a branch based on this PR live on my machines and it works fine. |
33cdeac
to
e5298b7
Compare
by the way: i didn't realize this was an issue that existed but it should definitely be linked to this PR. current status: i have a lot of stuff in my backlog, including a lot of schoolwork. i'll get back to this (and my other PRs) eventually but right now it's not my top priority the keyboard shortcuts inhibition part is actually stable and worked well last i recall, so like, if you want it right now just go merge it manually. i guess i could open another PR to separate these, because i think that one requires less work to "finish" and actually be good to merge. |
d19f77f
to
2febcdc
Compare
Okay, so respecting the I've implemented this in the commit titled "add InputBackend extensions; use Device::output() for absolute pos events". This is the latest commit. Virtual Pointer absolute motion when provided with an output should now work, and actually give output-relative coordinates. I've also hooked up the touch and tablet positions to this function, falling back to the previous behaviour when it returns |
4b29f6d
to
9e8a5de
Compare
9e8a5de
to
f337a27
Compare
I am very excited for this. |
Remind me, what is left to do here? (Apart from the whole "virtual keyboard doesn't do compositor shortcuts" which is not really related to these code changes.) Just review and merge? |
uihhh yeah, just review i guess. everything works i think. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some minor things left, otherwise looks good.
resources/default-config.kdl
Outdated
// | ||
// The allow-inhibiting=false property can be applied to other binds as well, | ||
// which ensures niri always processes them, even when an inhibitor is active. | ||
Mod+Shift+Escape allow-inhibiting=false { toggle-keyboard-shortcuts-inhibit; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mod+Shift+Escape allow-inhibiting=false { toggle-keyboard-shortcuts-inhibit; } | |
Mod+Escape allow-inhibiting=false { toggle-keyboard-shortcuts-inhibit; } |
so yeah
4189442
to
5440002
Compare
5440002
to
d8876d4
Compare
I added a few tests for inhibited shortcuts. Manually tested inhibiting with SDL3 test clients, seems to work fine. However, I noticed that pointer input in winit is vertically inverted. What's up with that, does it work on your machine? |
d8876d4
to
9fa7423
Compare
(resolved on Matrix, up to my push just now; but summarizing here for future reference) No, this didn't work on my machine. I don't know how i missed that. It's because returning the |
9fa7423
to
a8d273d
Compare
Let's assume this works fine now, and i'll also pretend i didn't see how you added that new State parameter. Still, please re-test with lan-mouse (ideally with transformed outputs too) |
Thanks! |
hey there was already a comment about that in the previous commit, that we'd need it to implement per-device config (e.g. multiple touch screens, or multiple tablets mapped to different outputs). this is just preparing for that inevitability, at least |
I've tested it now with lan-mouse, and it seems to still be fully functional! both i did notice, however, that disabling the keyboard shortcuts inhibitor is not very helpful against lan-mouse because, you see, lan-mouse still has keyboard focus, and if i open a fuzzel, i can't type into it; those keypresses go to my other machine. so best i can do is like, exit niri or switch VTs (though the latter doesn't require the inhibitor anyways). I guess that is basically a of course, virtual keyboard still can't do compositor binds, but that's like, super not our fault, and not related to this PR. but this is the main thing limiting the usability of |
Alright, thanks for testing |
My motivation for this is the use of KVM switching software, in particular i noticed that
lan-mouse
requires them (hence my branch name).Two things need to be done:
ChangeVt
binds ever.You can try the functionality of both of these protocols using
lan-mouse --test-emulation
(will cause the pointer to move in a lemniscate) orlan-mouse --test-capture
(WARNING: YOUR FOCUS WILL BE UNRECOVERABLE FROM WITHIN NIRI. useCtrl+Alt+F2
and thenpkill -f test-capture
to recover. theCtrl+Alt+{F1..F12}
binds are theChangeVt
binds i've mentioned already)Another thing i've noticed is that virtual-keyboard inputs aren't ever handled by the compositor (i.e.
Super+Left
is passed to whatever client, instead of focusing the column to the left)? This is irrelevant to this PR, but something i noticed while using lan-mouse. This is probably a Smithay issue? Since it's uhh mostly implemented in Smithay.