xdgshellclient: Allow menus from panels to take focus
AbandonedPublic

Authored by cblack on May 6 2020, 5:21 PM.

Details

Reviewers
zzag
Group Reviewers
KWin
Summary

Popup menus that are transient for a Plasma panel are now able to grab
the focus on Wayland.

Test Plan

Before: right click panel, unable to navigate menu with keyboard.
After: right click panel, able to navigate menu with keyboard.

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
cblack created this revision.May 6 2020, 5:21 PM
Restricted Application added a project: KWin. · View Herald TranscriptMay 6 2020, 5:21 PM
Restricted Application added a subscriber: kwin. · View Herald Transcript
cblack requested review of this revision.May 6 2020, 5:21 PM

Can you expand on why it's broken currently?

cblack added a comment.May 6 2020, 6:23 PM

Can you expand on why it's broken currently?

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.
zzag requested changes to this revision.EditedMay 7 2020, 5:33 AM
zzag added a subscriber: zzag.

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.

https://phabricator.kde.org/T12988

This revision now requires changes to proceed.May 7 2020, 5:33 AM
davidedmundson added a comment.EditedMay 7 2020, 8:41 AM

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.

anthonyfieroni added inline comments.
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.

cblack added a comment.May 7 2020, 2:11 PM
< snip >

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?

zzag added a comment.May 7 2020, 5:25 PM

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.

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.

In order to ensure that the topmost grabbing popup has keyboard focus, we need a mechanism for grabbing input devices in kwayland-server.

cblack added a comment.EditedMay 8 2020, 3:13 PM
In D29486#665820, @zzag wrote:

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.

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.

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…

  1. Implement input device grabbing APIs in kwayland-server
  2. Have KWin use the new APIs introduced in 1 to grant the topmost grabbing popup keyboard focus

Do I have that correct?

zzag added a comment.May 12 2020, 7:32 AM

So if I wanted to properly fix the issue this patch works around, I would…

  1. Implement input device grabbing APIs in kwayland-server
  2. Have KWin use the new APIs introduced in 1 to grant the topmost grabbing popup keyboard focus

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?