Popup menus that are transient for a Plasma panel are now able to grab
the focus on Wayland.
Details
Diff Detail
- Repository
- R108 KWin
- Branch
- cblack/fix-the-menus (branched from master)
- Lint
No Linters Available - Unit
No Unit Test Coverage - Build Status
Buildable 26459 Build 26477: arc lint + arc unit
Not sure if you're asking "why" on a "why is this an issue" or "why is this happening in the first place" so I'll answer both.
Why old behaviour is an issue:
- Normally, menus allow you to interact with them via the keyboard. Menus with panels as a transient parent don't allow you to do this, and the patch fixes that lack of expected behaviour.
Why this happens in the first place:
- Normally, QMenus don't grab keyboard focus themselves, and instead the parent window takes keyboard events and uses it to update the state of the QMenu. Since the Plasmashell panel cannot normally grab keyboard focus, they're unable to use keyboard events to update the state of the QMenu. Fortunately, the QMenu responds fine if you send the keyboard events directly to it, so that's what this patch causes KWin to do.
A QMenu can be backed either by an xdg_toplevel or xdg_popup.
If it's backed by an xdg_toplevel, kwin will activate the menu when it's mapped.
If the QMenu is backed by an xdg_popup, the keyboard focus must be on the topmost grabbing popup. The problem is that popup grabs from the xdg-shell spec aren't implemented in kwayland-server. :/
We probably don't want to work around kwayland-server's incomplete implementation of the xdg-shell protocol in kwin.
Yeah I was asking for the "Why this happens in the first place:".
Unless we are sure what the cause is, we can't be sure of what the correct fix is.
The problem is that popup grabs from the xdg-shell spec aren't implemented in kwayland-server. :/
I don't follow what you're referring to.
We have XdgShellInterface::popupGrabRequested mapped correctly. Tooltips and menus are correctly differentiated.
We don't check the seat and serial properly, but if anything that means we're more likely to acknowledge a grab.
xdgshellclient.cpp | ||
---|---|---|
1015–1021 | Should be just if (m_xdgShellPopup) { return true; } ? |
So from the XDG docs:
During a popup grab, the client owning the grab will receive pointer
and touch events for all their surfaces as normal (similar to an
"owner-events" grab in X11 parlance), while the top most grabbing popup
will always have keyboard focus.
we call a grab, but the knowledge of that is internal to the ShellIntegration based on the window type.
I can't see anything in QWaylandInputDevice::Keyboard that respects that last part.
So this is a Qt bug where it's not requesting keyboard focus or a KWin bug where it's not granting keyboard focus?
It's our bug because popup grabs are implemented partially in kwayland-server.
In order to ensure that the topmost grabbing popup has keyboard focus, we need a mechanism for grabbing input devices in kwayland-server.
So if I wanted to properly fix the issue this patch works around, I would…
- Implement input device grabbing APIs in kwayland-server
- Have KWin use the new APIs introduced in 1 to grant the topmost grabbing popup keyboard focus
Do I have that correct?
I'm not sure about the second one, but yeah I think it's worth to have input grabbing API in kwayland-server. However, I would like to point out that popup grabs != "normal" grabs. It's worth to have a look at weston and other compositors that have already tacked this subtle problem.
Do I have that correct?