Skip to content

fix(seat): clear keyboard focus before desktop surface transfer in onShowDesktop - #1364

Closed
deepin-wm wants to merge 1 commit into
linuxdeepin:masterfrom
deepin-wm:agent/developer/6294f7ed6b90
Closed

fix(seat): clear keyboard focus before desktop surface transfer in onShowDesktop#1364
deepin-wm wants to merge 1 commit into
linuxdeepin:masterfrom
deepin-wm:agent/developer/6294f7ed6b90

Conversation

@deepin-wm

@deepin-wm deepin-wm commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

修复:Super+D 显示桌面时 popup 窗口焦点未清除

问题

当桌面只有 popup 窗口(无普通窗口)时,按 Super+D 进入显示桌面状态,概率性需要按 2 次 Super+D 才能退出 popup;而当桌面有普通窗口时,按一次 Super+D popup 窗口就会失焦退出。

根因

onShowDesktop() 调用 dismissPopups() 结束了 popup 的 keyboard grab,但没有清除 SeatSurfaceManager 中的 m_keyboardFocusSurface(仍指向 popup surface)。随后 requestKeyboardFocus(desktopSurface) 调用 setKeyboardFocusSurface(desktopSurface, ...) 时,由于 popup 的 keyboardFocusPriority() 为 0,而桌面背景 layer surface(KeyboardInteractivity::None)的优先级为 -1,触发优先级检查 0 > -1,焦点转移被拒绝。popup 仍持有键盘焦点,导致需要第二次按 Super+D 才能退出。

修复方案

src/seat/helper.cpponShowDesktop() 中,dismissPopups() 之后、requestKeyboardFocus(desktopSurface) 之前,显式调用 setKeyboardFocusSurface(nullptr, Qt::OtherFocusReason) 清除键盘焦点。由于 setKeyboardFocusSurface 中的优先级检查仅在 oldSurface && surface 都非空时执行,传 nullptr 可绕过该检查,使后续对桌面 surface 的焦点请求成功。

改动

             seatContainer->dismissPopups();
+            // Clear keyboard focus from the dismissed popup so the subsequent
+            // focus request to the desktop surface is not blocked by the
+            // keyboardFocusPriority check (popup priority 0 > desktop priority -1).
+            seatContainer->setKeyboardFocusSurface(nullptr, Qt::OtherFocusReason);
             requestKeyboardFocus(desktopSurface, Qt::OtherFocusReason, seat);

Multica Issue

WM-366

Summary by Sourcery

Bug Fixes:

  • Ensure popup surfaces are explicitly closed when showing the desktop, preventing them from remaining visible and requiring a second Super+D to dismiss them.

@deepin-ci-robot

Copy link
Copy Markdown

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: deepin-wm

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@sourcery-ai

sourcery-ai Bot commented Sep 1, 2026

Copy link
Copy Markdown
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Updates onShowDesktop to fully close popup surfaces and clear stale keyboard focus before requesting focus for the desktop surface, preventing popup focus or visibility from requiring a second Super+D.

Sequence diagram for clearing popups and transferring desktop focus

sequenceDiagram
    participant Helper
    participant PopupContainer
    participant PopupSurface
    participant SeatContainer
    participant DesktopSurface

    Helper->>PopupContainer: surfaces()
    loop each XdgPopup
        Helper->>PopupSurface: type()
        Helper->>PopupSurface: close()
    end
    Helper->>SeatContainer: dismissPopups()
    Helper->>SeatContainer: setKeyboardFocusSurface(null, Qt.OtherFocusReason)
    Helper->>DesktopSurface: requestKeyboardFocus(desktopSurface, Qt.OtherFocusReason, seat)
Loading

File-Level Changes

Change Details Files
Explicitly close popup surfaces when entering the show-desktop state.
  • Snapshot popup surfaces from the popup container.
  • Close surfaces whose type is XdgPopup before processing seat focus changes.
src/seat/helper.cpp
Clear stale keyboard focus before transferring focus to the desktop surface.
  • After dismissing popups, set the seat keyboard focus surface to null.
  • Allow the subsequent desktop focus request to bypass the keyboard-focus priority check.
src/seat/helper.cpp

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

dismissPopups() only ends the keyboard grab and sends popup_done, but
does not destroy the popup surfaces themselves. When the desktop has
only popup windows (no normal windows), the popups remain visible after
the first Super+D, requiring a second press to dismiss them.

Fix: explicitly close all XdgPopup surfaces in the popup container before
transferring keyboard focus to the desktop surface in onShowDesktop().
@deepin-wm
deepin-wm force-pushed the agent/developer/6294f7ed6b90 branch from 733e054 to 8e8fd6f Compare September 1, 2026 13:35
@deepin-wm
deepin-wm marked this pull request as ready for review September 1, 2026 13:35

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@zccrs
zccrs marked this pull request as draft September 2, 2026 05:06
@Groveer

Groveer commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

#1376 这个提交解决该问题

@Groveer Groveer closed this Sep 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants