Skip to content

feat: make splash screens visible and closable via foreign-toplevel#745

Open
wineee wants to merge 1 commit intolinuxdeepin:masterfrom
wineee:titlebar
Open

feat: make splash screens visible and closable via foreign-toplevel#745
wineee wants to merge 1 commit intolinuxdeepin:masterfrom
wineee:titlebar

Conversation

@wineee
Copy link
Member

@wineee wineee commented Feb 12, 2026

protocol

Added foreign-toplevel protocol integration for splash screens to make them visible and manageable in the dock. Splash screens now appear in the dock with proper identification and can be closed directly from the dock. When a splash screen is closed before the actual application window appears, the matching application window will be automatically closed to maintain consistency.

Key changes:

  1. Register splash screens with foreign-toplevel protocol to appear in dock
  2. Implement splash screen closure handling via dock requests
  3. Track closed splash appIds to close matching application windows
  4. Move foreign-toplevel management from Helper to ShellHandler for better integration
  5. Add proper splash screen identification and state management

Log: Splash screens now appear in dock and can be closed via dock interface

Influence:

  1. Test splash screen visibility in dock for various applications
  2. Verify splash screen closure from dock works correctly
  3. Test that closing splash screen prevents matching application window from opening
  4. Verify normal window behavior remains unchanged after splash integration
  5. Check that skipDockPreView property still works correctly for all surface types
  6. Test application launch with and without splash screen closure

feat: 使闪屏通过foreign-toplevel协议在dock栏可见可关闭

为闪屏添加foreign-toplevel协议集成,使其在dock栏中可见并可管理。闪屏现在
会出现在dock栏中并带有适当标识,可以直接从dock栏关闭。如果在实际应用程序
窗口出现之前关闭闪屏,匹配的应用程序窗口将自动关闭以保持一致性。

主要更改:

  1. 将闪屏注册到foreign-toplevel协议以在dock栏显示
  2. 实现通过dock请求处理闪屏关闭功能
  3. 跟踪已关闭闪屏的appId以关闭匹配的应用程序窗口
  4. 将foreign-toplevel管理从Helper移动到ShellHandler以实现更好集成
  5. 添加适当的闪屏标识和状态管理

Log: 闪屏现在可在dock栏显示并可通过dock界面关闭

Influence:

  1. 测试各种应用程序的闪屏在dock栏中的可见性
  2. 验证从dock栏关闭闪屏功能正常工作
  3. 测试关闭闪屏后是否阻止匹配应用程序窗口打开
  4. 验证闪屏集成后正常窗口行为保持不变
  5. 检查skipDockPreView属性对所有表面类型是否仍正常工作
  6. 测试在有和没有关闭闪屏的情况下应用程序启动行为

Summary by Sourcery

Integrate splash screens with the foreign-toplevel protocol so they appear and can be managed from the dock, and ensure subsequent app windows respect splash-close actions.

New Features:

  • Expose splash screen surfaces to the foreign-toplevel protocol so they can be shown and controlled in the dock.
  • Allow dock-initiated close requests to close both normal toplevel windows and splash screens via a unified SurfaceWrapper close API.

Bug Fixes:

  • Prevent application windows from remaining open when their corresponding splash screen was closed from the dock by tracking closed splash appIds and closing matching toplevels on creation.

Enhancements:

  • Move Treeland foreign-toplevel management from Helper into ShellHandler and centralize registration of surfaces with dynamic handling of skipDockPreView.
  • Extend ForeignToplevelV1 to support splash screen lifecycle, including identifiers, titles, state initialization, and safety checks when removing surfaces.
  • Ensure SurfaceWrapper consistently updates skipDockPreView on teardown to keep dock state in sync.

protocol

Added foreign-toplevel protocol integration for splash screens to make
them visible and manageable in the dock. Splash screens now appear in
the dock with proper identification and can be closed directly from
the dock. When a splash screen is closed before the actual application
window appears, the matching application window will be automatically
closed to maintain consistency.

Key changes:
1. Register splash screens with foreign-toplevel protocol to appear
in dock
2. Implement splash screen closure handling via dock requests
3. Track closed splash appIds to close matching application windows
4. Move foreign-toplevel management from Helper to ShellHandler for
better integration
5. Add proper splash screen identification and state management

Log: Splash screens now appear in dock and can be closed via dock
interface

Influence:
1. Test splash screen visibility in dock for various applications
2. Verify splash screen closure from dock works correctly
3. Test that closing splash screen prevents matching application window
from opening
4. Verify normal window behavior remains unchanged after splash
integration
5. Check that skipDockPreView property still works correctly for all
surface types
6. Test application launch with and without splash screen closure

feat: 使闪屏通过foreign-toplevel协议在dock栏可见可关闭

为闪屏添加foreign-toplevel协议集成,使其在dock栏中可见并可管理。闪屏现在
会出现在dock栏中并带有适当标识,可以直接从dock栏关闭。如果在实际应用程序
窗口出现之前关闭闪屏,匹配的应用程序窗口将自动关闭以保持一致性。

主要更改:
1. 将闪屏注册到foreign-toplevel协议以在dock栏显示
2. 实现通过dock请求处理闪屏关闭功能
3. 跟踪已关闭闪屏的appId以关闭匹配的应用程序窗口
4. 将foreign-toplevel管理从Helper移动到ShellHandler以实现更好集成
5. 添加适当的闪屏标识和状态管理

Log: 闪屏现在可在dock栏显示并可通过dock界面关闭

Influence:
1. 测试各种应用程序的闪屏在dock栏中的可见性
2. 验证从dock栏关闭闪屏功能正常工作
3. 测试关闭闪屏后是否阻止匹配应用程序窗口打开
4. 验证闪屏集成后正常窗口行为保持不变
5. 检查skipDockPreView属性对所有表面类型是否仍正常工作
6. 测试在有和没有关闭闪屏的情况下应用程序启动行为
@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: wineee

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
Copy link

sourcery-ai bot commented Feb 12, 2026

Reviewer's Guide

Integrates splash screens with the Treeland foreign-toplevel protocol by moving Treeland-specific toplevel registration into ShellHandler, adding proper splash identification and close handling, and tracking closed splash appIds so that subsequent real windows are auto-closed, while ensuring skipDockPreView still governs dock visibility for all surface types.

Sequence diagram for dock-driven splash close and auto-closing real window

sequenceDiagram
    actor User
    participant DockUI
    participant ForeignToplevelV1
    participant ToplevelHandle as treeland_foreign_toplevel_handle_v1
    participant ShellHandler
    participant SplashWrapper as SurfaceWrapper_splash
    participant AppResolver as AppIdResolver
    participant RealSurface as WXdgToplevelSurface

    User->>DockUI: Click close on splash icon
    DockUI->>ToplevelHandle: requestClose
    ToplevelHandle->>SplashWrapper: close()
    SplashWrapper->>SplashWrapper: emit requestCloseSplash
    SplashWrapper-->>ShellHandler: requestCloseSplash()

    ShellHandler->>ShellHandler: m_closedSplashAppIds.insert(appId)
    ShellHandler->>ShellHandler: m_prelaunchWrappers.removeOne(SplashWrapper)
    ShellHandler->>ShellHandler: m_rootSurfaceContainer->destroyForSurface(SplashWrapper)

    note over RealSurface,AppResolver: Later, real app window appears

    RealSurface-->>ShellHandler: onXdgToplevelSurfaceAdded(RealSurface)
    ShellHandler->>AppResolver: resolveAppId(pidfd)
    AppResolver-->>ShellHandler: resolved appId
    ShellHandler->>ShellHandler: ensureXdgWrapper(RealSurface, appId)

    alt appId in m_closedSplashAppIds
        ShellHandler->>ShellHandler: m_closedSplashAppIds.remove(appId)
        ShellHandler->>RealSurface: close()
    else appId not in m_closedSplashAppIds
        ShellHandler->>ShellHandler: create normal wrapper
        ShellHandler->>ForeignToplevelV1: addSurface(wrapper)
    end
Loading

Class diagram for updated ShellHandler, SurfaceWrapper and ForeignToplevelV1

classDiagram
    class ShellHandler {
        - RootSurfaceContainer* m_rootSurfaceContainer
        - LayerSurfaceContainer* m_backgroundContainer
        - LayerSurfaceContainer* m_bottomContainer
        - Workspace* m_workspace
        - SurfaceContainer* m_normalContainer
        - SurfaceContainer* m_popupContainer
        - WindowConfigStore* m_windowConfigStore
        - QList~SurfaceWrapper*~ m_prelaunchWrappers
        - QSet~QString~ m_pendingPrelaunchAppIds
        - QSet~QString~ m_closedSplashAppIds
        - QList~WToplevelSurface*~ m_pendingAppIdResolveToplevels
        - ForeignToplevelV1* m_treelandForeignToplevel
        + ShellHandler(RootSurfaceContainer* rootContainer, WServer* server)
        + Workspace* workspace()
        + void createPrelaunchSplash(QString appId, QString iconName, QString title)
        + void onXdgToplevelSurfaceAdded(WXdgToplevelSurface* surface)
        + void onXWaylandSurfaceAdded(WXWaylandSurface* surface)
        - void ensureXdgWrapper(WXdgToplevelSurface* surface, QString targetAppId)
        - void ensureXwaylandWrapper(WXWaylandSurface* surface, QString targetAppId)
        - void setupSurfaceActiveWatcher(SurfaceWrapper* wrapper)
        - void registerSurfaceToForeignToplevel(SurfaceWrapper* wrapper)
    }

    class ForeignToplevelV1 {
        - treeland_foreign_toplevel_manager_v1* m_manager
        - map~SurfaceWrapper*, treeland_foreign_toplevel_handle_v1*~ m_surfaces
        + wl_global* global() const
        + void addSurface(SurfaceWrapper* wrapper)
        + void removeSurface(SurfaceWrapper* wrapper)
        - void initializeToplevelHandle(SurfaceWrapper* wrapper, treeland_foreign_toplevel_handle_v1* handle)
    }

    class SurfaceWrapper {
        <<QQuickItem>>
        + Type: XdgToplevel, XWayland, SplashScreen, Other
        - Type m_type
        - bool m_skipDockPreView
        - WToplevelSurface* m_shellSurface
        - QString m_appId
        + ~SurfaceWrapper()
        + Type type() const
        + QString appId() const
        + bool skipDockPreView() const
        + void setSkipDockPreView(bool skip)
        + void close()
        + void markWrapperToRemoved()
        + void requestCloseSplash()
        + void skipDockPreViewChanged()
        + Q_SIGNAL void aboutToBeInvalidated()
        + Q_SIGNAL void surfaceItemCreated()
        + Q_SIGNAL void requestCloseSplash()
    }

    class Helper {
        - RootSurfaceContainer* m_rootSurfaceContainer
        - ShellHandler* m_shellHandler
        - WServer* m_server
        - WForeignToplevel* m_foreignToplevel
        - WExtForeignToplevelListV1* m_extForeignToplevelListV1
        + Helper(QObject* parent)
        - void init(Treeland* treeland)
        - void onSurfaceWrapperAdded(SurfaceWrapper* wrapper)
        - void onSurfaceWrapperAboutToRemove(SurfaceWrapper* wrapper)
    }

    class DockPreview {
        + void close()
    }

    ShellHandler --> RootSurfaceContainer : uses
    ShellHandler --> ForeignToplevelV1 : owns m_treelandForeignToplevel
    ShellHandler --> SurfaceWrapper : manages wrappers
    ShellHandler --> WServer : constructed with

    ForeignToplevelV1 --> SurfaceWrapper : manages via addSurface/removeSurface

    Helper --> ShellHandler : creates and connects
    Helper --> WServer : uses
    Helper --> DockPreview : controls via dock requests

    SurfaceWrapper ..> DockPreview : represented in dock via ForeignToplevelV1
Loading

File-Level Changes

Change Details Files
Wire ForeignToplevelV1 management into ShellHandler and register all eligible surfaces (including splash) there instead of in Helper.
  • Change ShellHandler constructor to accept WServer, attach ForeignToplevelV1 there, and expose it as a member used for QML registration and dock preview signals.
  • Add registerSurfaceToForeignToplevel helper that adds/removes SurfaceWrapper instances to the Treeland foreign toplevel manager based on skipDockPreView and listens to skipDockPreViewChanged.
  • Remove Treeland foreign-toplevel attachment and per-wrapper registration/unregistration from Helper, and update signal connections to use ShellHandler’s ForeignToplevelV1 instance.
src/core/shellhandler.cpp
src/core/shellhandler.h
src/seat/helper.cpp
src/seat/helper.h
Make splash screens visible and closable via the Treeland foreign-toplevel protocol, and ensure closing a splash inhibits the matching real window.
  • When creating prelaunch splash wrappers, register them with the foreign-toplevel manager and connect a new requestCloseSplash signal to mark the appId as having a closed splash and destroy the splash wrapper.
  • Introduce m_closedSplashAppIds in ShellHandler and extend XDG/XWayland toplevel creation paths to resolve appIds even when only closed-splash entries exist.
  • In ensureXdgWrapper and ensureXwaylandWrapper, immediately close any new window whose resolved appId matches an appId in m_closedSplashAppIds, removing it from the set.
  • Extend SurfaceWrapper with a close() method that either emits requestCloseSplash for splash surfaces or calls the underlying shell surface close for normal windows.
src/core/shellhandler.cpp
src/core/shellhandler.h
src/surface/surfacewrapper.cpp
src/surface/surfacewrapper.h
Enhance ForeignToplevelV1 to properly represent splash and normal windows, support dock-initiated close for splash, and refactor initialization logic.
  • Relax addSurface precondition so it can accept splash surfaces, and create a per-wrapper handle with a simple numeric identifier and logging.
  • For splash-type wrappers, set basic state (title, appId, non-minimized, non-fullscreen, inactive), hook requestClose to SurfaceWrapper::close, and defer full initialization until surfaceItemCreated.
  • Refactor common handle setup into initializeToplevelHandle, which configures title, appId, state, and all signal wiring for XdgToplevel/XWayland, and remove the old direct requestClose-to-shell-surface connection.
  • Improve logging and safety in removeSurface with extra diagnostics when called on an unknown wrapper.
src/modules/foreign-toplevel/foreigntoplevelmanagerv1.cpp
src/modules/foreign-toplevel/foreigntoplevelmanagerv1.h
Tighten SurfaceWrapper dock-preview lifecycle and semantics so non-toplevels cannot be exposed in dock, and ensure cleanup on destruction/removal.
  • On SurfaceWrapper destruction and in markWrapperToRemoved, force skipDockPreView to true if it was false, ensuring foreign-toplevel and dock preview cleanup happens before the wrapper disappears.
  • Adjust setSkipDockPreView so that only XdgToplevel/XWayland surfaces may set skipDockPreView=false, while still allowing any type to set it to true, and update warnings accordingly.
  • Add requestCloseSplash signal to SurfaceWrapper and wire it into ShellHandler’s splash-close handling via the new close() method.
src/surface/surfacewrapper.cpp
src/surface/surfacewrapper.h

Possibly linked issues

  • #TODO: splash screen: PR implements dock visibility and close control for splash screens, addressing the issue’s taskbar/dock closure TODO.

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

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 2 issues, and left some high level feedback:

  • The new SurfaceWrapper::requestCloseSplash is declared as a slot but used as a signal (e.g. connect(wrapper, &SurfaceWrapper::requestCloseSplash, ...) and Q_EMIT requestCloseSplash()), which will not compile with the new connect syntax; move it to the signals section instead of public Q_SLOTS.
  • In ForeignToplevelV1::addSurface, the set_identifier now uses a static int counter instead of something tied to the underlying surface/handle; consider whether this needs to be stable/unique across the compositor lifetime and make the identifier generation more robust (and thread‑safe) if clients rely on it.
  • The m_closedSplashAppIds set is only pruned when a matching window appears; if an app never creates a window after its splash is closed, the appId will remain in the set indefinitely—consider adding a timeout or cleanup path to avoid unbounded growth over long sessions.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new `SurfaceWrapper::requestCloseSplash` is declared as a slot but used as a signal (e.g. `connect(wrapper, &SurfaceWrapper::requestCloseSplash, ...)` and `Q_EMIT requestCloseSplash()`), which will not compile with the new connect syntax; move it to the `signals` section instead of `public Q_SLOTS`.
- In `ForeignToplevelV1::addSurface`, the `set_identifier` now uses a `static int counter` instead of something tied to the underlying surface/handle; consider whether this needs to be stable/unique across the compositor lifetime and make the identifier generation more robust (and thread‑safe) if clients rely on it.
- The `m_closedSplashAppIds` set is only pruned when a matching window appears; if an app never creates a window after its splash is closed, the appId will remain in the set indefinitely—consider adding a timeout or cleanup path to avoid unbounded growth over long sessions.

## Individual Comments

### Comment 1
<location> `src/surface/surfacewrapper.h:330` </location>
<code_context>
     void showOnAllWorkspaceChanged();
     void requestActive();
     void requestInactive();
+    void requestCloseSplash();
     void skipSwitcherChanged();
     void skipDockPreViewChanged();
</code_context>

<issue_to_address>
**issue (bug_risk):** requestCloseSplash should be declared as a signal, not a slot, to match its usage.

`requestCloseSplash` is currently under `public Q_SLOTS`, but in `surfacewrapper.cpp` you use `Q_EMIT requestCloseSplash();` and in `ShellHandler::createPrelaunchSplash` you connect with `&SurfaceWrapper::requestCloseSplash` as if it were a signal. Because it’s not declared under `signals:`, there will be no meta-object entry, so this pointer-to-member connection will fail at runtime (usually with `QObject::connect: No such signal ...`) and the handler won’t be invoked. Please move `requestCloseSplash` to the `signals:` section (or add one) and keep the implementation the same.
</issue_to_address>

### Comment 2
<location> `src/core/shellhandler.h:137` </location>
<code_context>
     WAYLIB_SERVER_NAMESPACE::WLayerShell *m_layerShell = nullptr;
     WAYLIB_SERVER_NAMESPACE::WInputMethodHelper *m_inputMethodHelper = nullptr;
     QList<WAYLIB_SERVER_NAMESPACE::WXWayland *> m_xwaylands;
+    ForeignToplevelV1 *m_treelandForeignToplevel = nullptr;

     QPointer<RootSurfaceContainer> m_rootSurfaceContainer;
</code_context>

<issue_to_address>
**issue (bug_risk):** m_treelandForeignToplevel is used from Helper but declared private, which will not compile.

In `Helper::init` you connect directly to `m_shellHandler->m_treelandForeignToplevel`, but this member is private in `ShellHandler` and `Helper` is not a friend, so this will not compile. Please either add a public accessor (e.g. `ForeignToplevelV1 *treelandForeignToplevel() const`) or route these connections via `ShellHandler` signals instead of accessing its internals directly.
</issue_to_address>

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.

void showOnAllWorkspaceChanged();
void requestActive();
void requestInactive();
void requestCloseSplash();
Copy link

Choose a reason for hiding this comment

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

issue (bug_risk): requestCloseSplash should be declared as a signal, not a slot, to match its usage.

requestCloseSplash is currently under public Q_SLOTS, but in surfacewrapper.cpp you use Q_EMIT requestCloseSplash(); and in ShellHandler::createPrelaunchSplash you connect with &SurfaceWrapper::requestCloseSplash as if it were a signal. Because it’s not declared under signals:, there will be no meta-object entry, so this pointer-to-member connection will fail at runtime (usually with QObject::connect: No such signal ...) and the handler won’t be invoked. Please move requestCloseSplash to the signals: section (or add one) and keep the implementation the same.

WAYLIB_SERVER_NAMESPACE::WLayerShell *m_layerShell = nullptr;
WAYLIB_SERVER_NAMESPACE::WInputMethodHelper *m_inputMethodHelper = nullptr;
QList<WAYLIB_SERVER_NAMESPACE::WXWayland *> m_xwaylands;
ForeignToplevelV1 *m_treelandForeignToplevel = nullptr;
Copy link

Choose a reason for hiding this comment

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

issue (bug_risk): m_treelandForeignToplevel is used from Helper but declared private, which will not compile.

In Helper::init you connect directly to m_shellHandler->m_treelandForeignToplevel, but this member is private in ShellHandler and Helper is not a friend, so this will not compile. Please either add a public accessor (e.g. ForeignToplevelV1 *treelandForeignToplevel() const) or route these connections via ShellHandler signals instead of accessing its internals directly.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR integrates prelaunch splash screens into Treeland’s ForeignToplevelV1 (dock/preview) so they appear in the dock and can be closed from it, and moves Treeland foreign-toplevel registration responsibilities from Helper into ShellHandler for tighter lifecycle integration.

Changes:

  • Register splash SurfaceWrapper instances with ForeignToplevelV1, including basic metadata and close handling.
  • Centralize Treeland foreign-toplevel surface registration in ShellHandler, including reacting to skipDockPreView changes.
  • Track appIds for splash screens closed from the dock and close the matching real toplevel when it appears.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
src/surface/surfacewrapper.h Adds a unified close() API and a splash-close request signal hook.
src/surface/surfacewrapper.cpp Implements SurfaceWrapper::close() and adjusts skipDockPreView teardown behavior and validation.
src/seat/helper.h Removes stored Treeland foreign-toplevel manager pointer from Helper.
src/seat/helper.cpp Constructs ShellHandler with WServer and reroutes dock-preview connections to the manager owned by ShellHandler.
src/modules/foreign-toplevel/foreigntoplevelmanagerv1.h Extracts toplevel-handle initialization into a helper method.
src/modules/foreign-toplevel/foreigntoplevelmanagerv1.cpp Extends Treeland foreign-toplevel handling for splash screens and refactors handle initialization.
src/core/shellhandler.h Stores Treeland foreign-toplevel manager and adds tracking for dock-closed splash appIds.
src/core/shellhandler.cpp Registers wrappers (including splash) with Treeland foreign-toplevel and enforces “closed splash cancels real window” behavior.

(中文)
本 PR 将预启动闪屏接入 Treeland 的 ForeignToplevelV1(dock/preview 协议)以便在 dock 中可见并可关闭,并将 Treeland foreign-toplevel 的管理从 Helper 迁移到 ShellHandler,以获得更一致的生命周期与状态联动。

主要改动:

  • 将闪屏 SurfaceWrapper 注册到 ForeignToplevelV1,并支持从 dock 发起关闭。
  • ShellHandler 中集中处理 Treeland foreign-toplevel 的注册/反注册(随 skipDockPreView 动态变化)。
  • 记录从 dock 关闭的闪屏 appId,并在真实窗口出现时自动关闭匹配窗口。

connect(handle, &treeland_foreign_toplevel_handle_v1::requestClose, surface, [surface] {
surface->close();
});
connect(handle,
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

treeland_foreign_toplevel_handle_v1::requestClose is only connected for splash wrappers; for normal XdgToplevel/XWayland handles there is no close handler anymore, so dock-initiated close requests won’t close the window. Please connect requestClose to the unified SurfaceWrapper::close() (or directly to shellSurface()->close()) during normal handle initialization.

treeland_foreign_toplevel_handle_v1::requestClose 目前只对闪屏 wrapper 做了连接;对普通 XdgToplevel/XWayland handle 已没有关闭处理,导致 dock 发起的关闭请求无法关闭窗口。请在普通窗口 handle 初始化时将 requestClose 连接到统一的 SurfaceWrapper::close()(或直接连接到 shellSurface()->close())。

Suggested change
connect(handle,
connect(handle,
&treeland_foreign_toplevel_handle_v1::requestClose,
wrapper,
[wrapper]() {
wrapper->close();
});
connect(handle,

Copilot uses AI. Check for mistakes.
Comment on lines +96 to 98
qInfo() << "Register surface to ForeignToplevelV1, appId=" << wrapper->appId()
<< wrapper->type() << wrapper->skipDockPreView();

Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

This file uses qInfo() for the new register/unregister logs, which bypasses the project’s categorized logging (see docs/logging-guidelines.md). Please switch these to qCInfo(treelandProtocol) (or another appropriate Treeland category) so log filtering works consistently.

这里新增的注册/反注册日志使用了 qInfo(),会绕过项目的分类日志规范(见 docs/logging-guidelines.md)。建议改为 qCInfo(treelandProtocol)(或其它合适的 Treeland category),以便统一过滤与排查。

Copilot uses AI. Check for mistakes.
Comment on lines +61 to +65
static int counter = 1;
handle->set_identifier(
// *reinterpret_cast<const uint32_t *>(surface->surface()->handle()->handle()));
//*reinterpret_cast<const uint32_t *>(wrapper));
counter++);
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

The set_identifier block contains commented-out pointer/reinterpret_cast experiments and uses a function-local static int counter. Please remove the commented code and consider using an explicit uint32_t monotonic member (or another clearly documented identifier source) to keep this maintainable.

set_identifier 这段还保留了注释掉的指针/reinterpret_cast 试验代码,并且用函数内的 static int counter 生成 id。建议删除这些注释代码,并考虑改为显式的 uint32_t 单调递增成员变量(或其它有明确来源/文档的标识符方案),以提升可维护性。

Copilot uses AI. Check for mistakes.
qCWarning(treelandSurface) << "Only xdgtoplevel and x11 surface can `setSkipDockPreView`";
if (!skip && (m_type != Type::XdgToplevel && m_type != Type::XWayland)) {
qCWarning(treelandSurface)
<< "Only xdgtoplevel, x11 surface or can `setSkipDockPreView` to false";
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

The warning string here is grammatically incorrect and misleading ("or can ... to false"). Please reword it to clearly state that only XdgToplevel/XWayland can set skipDockPreView to false.

这里的 warning 文案语法不通且容易误解("or can ... to false")。建议改成更清晰的表述:只有 XdgToplevel/XWayland 才允许把 skipDockPreView 设置为 false

Suggested change
<< "Only xdgtoplevel, x11 surface or can `setSkipDockPreView` to false";
<< "Only XdgToplevel or XWayland surfaces are allowed to set `skipDockPreView` to false. "
<< "仅允许 XdgToplevel/XWayland 将 `skipDockPreView` 设置为 false。";

Copilot uses AI. Check for mistakes.
Comment on lines +254 to +256
qInfo() << "Unregister surface from ForeignToplevelV1, appId=" << wrapper->appId()
<< wrapper->type() << wrapper->skipDockPreView();

Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

This unregister log also uses qInfo() instead of categorized logging. Please use qCInfo(treelandProtocol) (or a more specific category) to follow docs/logging-guidelines.md.

这条反注册日志同样使用了 qInfo() 而不是分类日志。请改用 qCInfo(treelandProtocol)(或更具体的 category),以符合 docs/logging-guidelines.md

Copilot uses AI. Check for mistakes.
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.

2 participants