fix: restore focus after showing desktop - #1271
Conversation
Reviewer's guide (collapsed on small PRs)Reviewer's GuideThe PR updates the show-desktop handling so that keyboard focus is explicitly moved to the desktop layer when entering show-desktop mode and restored to the previously active normal surface when exiting, using a QPointer to safely track the previously focused surface. Sequence diagram for updated show-desktop focus handlingsequenceDiagram
actor User
participant Helper
participant BackgroundContainer as BackgroundContainer
participant SurfaceWrapper_desktop as SurfaceWrapper_desktop
User->>Helper: onShowDesktop(Show)
Helper->>Helper: activatedSurface()
Helper->>BackgroundContainer: surfaces()
loop find desktop surface
Helper->>SurfaceWrapper_desktop: requestKeyboardFocus(SurfaceWrapper_desktop)
end
alt [layer-shell windows depend on focus loss]
note over Helper,SurfaceWrapper_desktop: Layer-shell window exits on focus loss
end
User->>Helper: onShowDesktop(Normal)
Helper->>Helper: activateSurface(m_showDesktopFocusSurface)
Helper->>Helper: m_showDesktopFocusSurface = nullptr
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Pull request overview
EN: This PR improves Treeland’s show-desktop focus behavior (seat/input layer) so that entering show-desktop moves keyboard focus to the desktop layer, and exiting show-desktop restores activation/keyboard focus to the previously active normal surface per seat.
ZH: 该 PR 改进 Treeland 的“显示桌面”焦点逻辑(seat/input 层),进入显示桌面时将键盘焦点移动到 desktop 图层,退出显示桌面时按 seat 恢复到此前激活的普通窗口,并保证依赖失焦退出的 layer-shell 窗口能正确退出。
Changes / 变更:
- EN: Save per-seat previously activated surface via
QPointerand restore it when leaving show-desktop.
ZH:使用QPointer按 seat 保存此前激活窗口,并在退出显示桌面时恢复。 - EN: On entering show-desktop, attempt to focus the desktop background layer-surface (
dde-shell/desktop).
ZH:进入显示桌面时尝试将键盘焦点切到 desktop 背景图层窗口(dde-shell/desktop)。 - EN: Ensure clicking/activating a window while in show-desktop restores other seats’ previous focus state.
ZH:在显示桌面状态下激活窗口时,恢复其它 seat 的此前焦点状态。
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/seat/helper.h | Adds QPointer include, declares focus-restore helper, stores per-seat saved focus surfaces. |
| src/seat/helper.cpp | Implements show-desktop focus handoff to desktop layer and per-seat focus restoration logic. |
Suppressed comments (1)
src/seat/helper.cpp:1504
- EN:
restoreShowDesktopFocusSurfaces()can callactivateSurface(saved, ..., seat)even if this seat has noSeatSurfaceManager.activateSurface()may end up callingrequestKeyboardFocus(), which asserts on a missing seat container; add a guard to avoid crashes when seats are in transition.
ZH:restoreShowDesktopFocusSurfaces()在 seat 没有对应SeatSurfaceManager时仍可能调用activateSurface(saved, ..., seat);而activateSurface()进一步可能调用requestKeyboardFocus(),该函数会对缺失的 seat container 断言,seat 处于增删/切换过程中可能导致崩溃。建议加保护判断。
for (auto *seat : seats) {
if (seat == exceptSeat)
continue;
auto it = m_showDesktopFocusSurfaces.find(seat);
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
TAG Bot New tag: 0.8.18 |
f711787 to
51fbba2
Compare
Why: showing the desktop (Super+D) did not move keyboard focus, so layer-shell windows that close on focus loss (e.g. dde-shell popups, tooltips) never exited. Also, focus was never restored to the previously active window when leaving show-desktop mode. 1. On entering show-desktop, dismiss any popup keyboard grab and move keyboard focus to the desktop layer surface for every seat; drop focus when no desktop surface exists, so focus-loss layer-shell windows exit. 2. On exit, restore keyboard focus to each seat's activated surface via the shared restoreShowDesktopFocus(). It is reached from three triggers: the protocol desktop-state change (onShowDesktop), click-activation of a window (setActivatedSurface), and shortcut/forced-activation exits (restoreFromShowDesktop). 3. Skip seats that are still in transition (hotplug) instead of asserting on a missing seat container. 4. While showing the desktop, do not yank keyboard focus back to the (hidden) activated surface when its focus capability changes or when a popup keyboard grab ends. Log: 显示桌面时键盘焦点正确转移到桌面层,退出时恢复之前的激活窗口。 Influence: 1. 在依赖失焦退出的图层窗口显示时触发 Super+D。 2. 确认该图层窗口退出,且 desktop 获得键盘焦点。 3. 再次触发 Super+D,确认焦点恢复到此前的普通窗口。 fix: 显示桌面后恢复窗口焦点 1. 显示桌面时关闭弹窗键盘抓取,将键盘焦点转移到 desktop 图层窗口。 2. 退出显示桌面时,将键盘焦点恢复到各 seat 的激活窗口。 3. 跳过热插拔切换中的 seat,避免断言。 PMS: BUG-372393 Signed-off-by: groveer <guoyao@uniontech.com>
Why: two popup focus problems. 1. Clicking outside a popup did not always dismiss it. wlroots' xdg popup grab only auto-dismisses when the clicked surface cannot receive the event (pointer focus cleared, serial == 0), i.e. clicks on other clients. Clicks on the popup client's own toplevel were delivered normally and the popup stayed open. End the grab explicitly on a mouse press that is not on an xdg popup surface, per xdg-shell semantics. 2. onKeyboardGrabBegin cast grab->data (a wlr_xdg_popup_grab*) to wlr_drag* and read grab_type from it. The first member of wlr_xdg_popup_grab is a wl_client* pointer, not an enum, so this is undefined behavior and could misclassify a popup grab as a drag, leaving m_hasPopupGrab false and breaking outside-click dismissal. seat->drag is set only AFTER keyboard_grab_begin fires (wlr_seat_start_drag), so drags cannot be detected there; exclude them at dismissal time instead. 1. Dismiss the popup keyboard grab in beforeDisposeEvent on a MouseButtonPress outside any xdg popup surface. 2. Never dismiss during an active DnD drag (seat->drag non-null): a drag also installs a keyboard grab, and ending it would break the drag. 3. Remove the undefined-behavior grab_type cast in onKeyboardGrabBegin. Log: 点击弹出窗口外部可以关闭弹出窗口;移除 DnD 抓取检测的未定义行为。 Influence: 1. 打开一个弹出窗口(如右键菜单)。 2. 点击该弹出窗口所属应用自身的窗口,确认弹出窗口关闭。 3. 点击其他应用的窗口,确认弹出窗口同样关闭且点击正常传递。 4. 拖拽文件时确认拖拽流程不受影响。
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: Groveer, wineee The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
Log: Layer-shell windows that close on focus loss now exit when showing desktop.
Influence:
fix: 显示桌面后恢复窗口焦点
Log: 显示桌面时,依赖失焦退出的图层窗口会正常退出。
Influence:
PMS: BUG-372393
Summary by Sourcery
Improve show-desktop behavior by moving focus to the desktop layer and restoring the previous window focus when exiting show-desktop mode.
Bug Fixes:
Enhancements: