GNOME Bugzilla – Bug 786021
Fix synthetic event window
Last modified: 2017-10-04 13:51:51 UTC
Created attachment 357217 [details] [review] fix When a client is passively grabbing keys or mouse clicks that it does not need, it sends them up for other clients to process (this sets the `send_event` flag inside `XEvent`). Often in this situation, the event contains the wrong window (either root, for global keybindings, or the original client itself). This means that Metacity will attempt to process the event for the wrong window. This is not an issue for global bindings within Metacity, as the focused/current window does not matter. However, for shortcuts that operate directly on specific windows, the events gets lost. This change addresses this issue by determining which is the currently-focused (for key grabs), or under-the-pointer (for button grabs), window, regardless of which client forwarded the event.
(In reply to Victor Kareh from comment #0) > Created attachment 357217 [details] [review] [review] > fix > > When a client is passively grabbing keys or mouse clicks that it does not > need, it sends them up for other clients to process (this sets the > `send_event` flag inside `XEvent`). Example with some real apps? Client that grabs keys and/or mouse clicks. What are other clients? > Often in this situation, the event contains the wrong window (either root, > for global keybindings, or the original client itself). This means that > Metacity will attempt to process the event for the wrong window. How it can be wrong window? If event was generated for x window why metacity should process this event for some random y window? > This is not an issue for global bindings within Metacity, as the > focused/current window does not matter. However, for shortcuts that operate > directly on specific windows, the events gets lost. > > This change addresses this issue by determining which is the > currently-focused (for key grabs), or under-the-pointer (for button grabs), > window, regardless of which client forwarded the event. With forwarded event you mean XSendEvent?
(In reply to Alberts Muktupāvels from comment #1) > (In reply to Victor Kareh from comment #0) > > Created attachment 357217 [details] [review] [review] [review] > > fix > > > > When a client is passively grabbing keys or mouse clicks that it does not > > need, it sends them up for other clients to process (this sets the > > `send_event` flag inside `XEvent`). > > Example with some real apps? Client that grabs keys and/or mouse clicks. > What are other clients? > > > Often in this situation, the event contains the wrong window (either root, > > for global keybindings, or the original client itself). This means that > > Metacity will attempt to process the event for the wrong window. > > How it can be wrong window? If event was generated for x window why metacity > should process this event for some random y window? > > > This is not an issue for global bindings within Metacity, as the > > focused/current window does not matter. However, for shortcuts that operate > > directly on specific windows, the events gets lost. > > > > This change addresses this issue by determining which is the > > currently-focused (for key grabs), or under-the-pointer (for button grabs), > > window, regardless of which client forwarded the event. > > With forwarded event you mean XSendEvent? Hi Alberts, An example would be the Ubuntu MATE heads-up-display (HUD). It triggers on pressing, then releasing, `Alt_L`, with no other key in between. Since `Alt` is also used as a modifier (for example, `Alt+Tab` for switching windows or `Alt+F10` for maximizing windows, it calls `XSendEvent` if another key is pressed after `Alt` (but before it's released). Since the HUD doesn't have a window before being triggered, it uses a passive grab on the root window (which is common for global keybindings). So if I have another window focused (for example, the Terminal) when I press Alt, then I press F10, the F10 press (with the Alt modifier) is sent with XSendEvent, but since the window with the grab was root, the terminal doesn't get the event and it's just lost. That's where this patch comes into play: Since the event was intended for the Terminal (in our example), but the event was hijacked by the root window grab, metacity can determine which window was in focus when this happened, and thus trigger the event on the correct window. A similar example for mouse clicks would be using `Alt+RightClick` to resize a window, or `Alt+LeftClick` to move a window.
(In reply to Victor Kareh from comment #2) > (In reply to Alberts Muktupāvels from comment #1) > > (In reply to Victor Kareh from comment #0) > > > Created attachment 357217 [details] [review] [review] [review] [review] > > > fix > > > > > > When a client is passively grabbing keys or mouse clicks that it does not > > > need, it sends them up for other clients to process (this sets the > > > `send_event` flag inside `XEvent`). > > > > Example with some real apps? Client that grabs keys and/or mouse clicks. > > What are other clients? > > > > > Often in this situation, the event contains the wrong window (either root, > > > for global keybindings, or the original client itself). This means that > > > Metacity will attempt to process the event for the wrong window. > > > > How it can be wrong window? If event was generated for x window why metacity > > should process this event for some random y window? > > > > > This is not an issue for global bindings within Metacity, as the > > > focused/current window does not matter. However, for shortcuts that operate > > > directly on specific windows, the events gets lost. > > > > > > This change addresses this issue by determining which is the > > > currently-focused (for key grabs), or under-the-pointer (for button grabs), > > > window, regardless of which client forwarded the event. > > > > With forwarded event you mean XSendEvent? > > Hi Alberts, > > An example would be the Ubuntu MATE heads-up-display (HUD). It triggers on > pressing, then releasing, `Alt_L`, with no other key in between. This is one app, do you have other examples? Can you provide small app that could be used to reproduce this bug / problem? > Since `Alt` is also used as a modifier (for example, `Alt+Tab` for switching > windows or `Alt+F10` for maximizing windows, it calls `XSendEvent` if > another key is pressed after `Alt` (but before it's released). What calls XSendEvent? Metacity or mate-hud? Quick look at mate-hud shows that it is calling send_event. > Since the HUD doesn't have a window before being triggered, it uses a > passive grab on the root window (which is common for global keybindings). So > if I have another window focused (for example, the Terminal) when I press > Alt, then I press F10, the F10 press (with the Alt modifier) is sent with > XSendEvent, but since the window with the grab was root, the terminal > doesn't get the event and it's just lost. Hmm, why do you think that it is bug in metacity and not in mate-hud? MATE Hud sends that event to root window. Why metacity should process it for terminal window? Also what possible regressions and/or side effects this could introduce? Maybe that event was not meant to reach and/or be used by that window... > That's where this patch comes into play: Since the event was intended for > the Terminal (in our example), but the event was hijacked by the root window > grab, metacity can determine which window was in focus when this happened, > and thus trigger the event on the correct window. In our example, but what if event was not intended for Terminal? Event was hijacked by mate-hud, why this is metacity problem? How that works in other window manager? Mutter, Compiz? Are they also searching for window under mouse and/or window with input focus? > A similar example for mouse clicks would be using `Alt+RightClick` to resize > a window, or `Alt+LeftClick` to move a window. https://tronche.com/gui/x/xlib/event-handling/XSendEvent.html "Specifies the window the event is to be sent to, or PointerWindow, or InputFocus." Instead of sending event to root window send it to: - InputFocus, probably same you try to do in keybindings.c - PointerWindow, probably same you try to do in display.c Have you tried and it does not work? Are there some specification that requires mate-hud to send event to root window? Or anything else that could show that mate-hud does right thing and real problem really is in metacity.
You are processing events in mate-hud, does not it include correct window? event = self.display.next_event() event.window = ??? In your example Alt+F10 from Terminal. Should not event.window be Terminal window? If so why send it to root window if you can send it to correct window?
Created attachment 360683 [details] test app to send Alt+F10 to root window Should I close this or you still think that this is bug in metacity? Check test app - it sends Alt+F10 to root window. Alt+F10 is used as keybinding to maximize / unmaximize window... So what should happen? Nothing, right? Event is sent to root window and there is probably nothing that is interested in that event. What happens after your patch? Suddenly my gnome-terminal is maximized...
I guess I don't see this as a bug as much as a feature request. In your example, I would expect an app simulating an Alt+F10 to actually maximize the focused window. It would allow global keybindings (which live in the root window anyway, from what I've seen) to allow acting on behalf of other non-root windows (like the HUD in my example) Unless there's another way of doing this which I don't know about (which is entirely possible - I'm not that well versed in how to use X yet). Try as I might, I haven't been able to do this from the HUD. The event just gets ignored.
(In reply to Victor Kareh from comment #2) > An example would be the Ubuntu MATE heads-up-display (HUD). It triggers on > pressing, then releasing, `Alt_L`, with no other key in between. Ok, I have mate-hud, commit c289927f205fe211d2b4c8f5f546d57d41f5c0f6 / Release 17.10.8 with GSettings part removed... > Since `Alt` is also used as a modifier (for example, `Alt+Tab` for switching > windows or `Alt+F10` for maximizing windows, it calls `XSendEvent` if > another key is pressed after `Alt` (but before it's released). > > Since the HUD doesn't have a window before being triggered, it uses a > passive grab on the root window (which is common for global keybindings). So > if I have another window focused (for example, the Terminal) when I press > Alt, then I press F10, the F10 press (with the Alt modifier) is sent with > XSendEvent, but since the window with the grab was root, the terminal > doesn't get the event and it's just lost. I can not reproduce this... I start mate-hud and get "INFO:root:Press Alt_L to handle keybinding". In gnome-terminal I get (after relase) "INFO:root:Unable to register with com.canonical.AppMenu.Registrar.", but LibreOffice shows that HUD. Both gnome-terminal and LibreOffice maximize/unmaximize when I press alt+f10. Also alt+tab works just fine. > That's where this patch comes into play: Since the event was intended for > the Terminal (in our example), but the event was hijacked by the root window > grab, metacity can determine which window was in focus when this happened, > and thus trigger the event on the correct window. > > A similar example for mouse clicks would be using `Alt+RightClick` to resize > a window, or `Alt+LeftClick` to move a window. (In reply to Victor Kareh from comment #6) > I guess I don't see this as a bug as much as a feature request. In your > example, I would expect an app simulating an Alt+F10 to actually maximize > the focused window. It would allow global keybindings (which live in the > root window anyway, from what I've seen) to allow acting on behalf of other > non-root windows (like the HUD in my example) > > Unless there's another way of doing this which I don't know about (which is > entirely possible - I'm not that well versed in how to use X yet). Try as I > might, I haven't been able to do this from the HUD. The event just gets > ignored. Maybe you can provide minimal app that shows your problem?
Huh! Well, that's good news then! Hopefully this patch is unnecessary :P What about Alt+Mouse (to move and resize) - do those work for you without this patch while HUD is running? (you might need to change `/org/gnome/desktop/wm/preferences/mouse-button-modifier` to `<Alt>`)
(In reply to Victor Kareh from comment #8) > Huh! Well, that's good news then! Hopefully this patch is unnecessary :P https://github.com/ubuntu-mate/mate-hud/pull/11/commits/139d24ec7ef7a5cd1bca2237aca3e34173caa831 With this applied it does not work, it requires to press f10 twice to maximize... > What about Alt+Mouse (to move and resize) - do those work for you without > this patch while HUD is running? (you might need to change > `/org/gnome/desktop/wm/preferences/mouse-button-modifier` to `<Alt>`) Did not try.
Ah, yeah that patch to mate-hud was done to prevent the keys being sent twice for some reason. It was causing all sorts of strange issues when Alt+Tabbing.
Still was able to get it to work without changes in Metacity or in other words - you have bug / problem in mate-hud. Short debugging showed that received event has: event.window - xroot window id, not interesting event.child - frame window id So all you need to do is create new event and send it to correct window: ev = protocol.event.KeyPress(window=event.child, child=0, time=event.time, ...) self.display.send_event(event.child, ev, ...)
Comment on attachment 357217 [details] [review] fix Your problem can be fixed in mate-hud. Also I still think that your proposed fix is not correct.
Thanks for the explanation and the sample code - it helps! I'll try to get it working on mate-hud without this patch