Skip to content

Conversation

@BLumia
Copy link
Member

@BLumia BLumia commented Dec 25, 2025

支持在 wayland 环境下为 Xembed 支持注册 selectionowner 并暴露相关托盘到 dbus 接口上。

Summary by Sourcery

Add a Wayland-capable XEmbed tray selection manager and expose embedded tray icons over a new DBus TrayManager1 interface.

New Features:

  • Introduce FdoSelectionManager to own the FDO/XEmbed system tray selection and manage tray icons via XDamage events.
  • Expose embedded X11 tray icons through a new org.deepin.dde.TrayManager1 DBus interface with registration, change notifications, and metadata access.
  • Automatically register the FDO selection manager when running on non-X11 platforms where an X display is available.

Enhancements:

  • Refine the application-tray plugin build configuration to explicitly list tray sources, generate a DBus adaptor, and link against KF6WindowSystem.
  • Update the project DTL version to 2.0.99 and extend X11 dependencies to include xcb-damage for tray damage tracking.

Build:

  • Link application-tray plugin against KF6::WindowSystem and add xcb-damage to the X11 pkg-config modules.
  • Generate the TrayManager1 DBus adaptor source from the org.deepin.dde.TrayManager1.xml definition and include it in the tray plugin build.

@BLumia BLumia requested a review from tsic404 December 25, 2025 09:20
@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: BLumia

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 Dec 25, 2025

Reviewer's Guide

Implements a Wayland-compatible XEmbed system tray selection manager by introducing FdoSelectionManager and TrayManager1 DBus service, wiring them into TrayPlugin when not on X11, and updating build configuration and dependencies accordingly.

Sequence diagram for XEmbed tray icon docking via FdoSelectionManager and TrayManager1

sequenceDiagram
    autonumber
    participant TrayPlugin
    participant FdoSelectionManager
    participant KSelectionOwner
    participant X11Server
    participant TrayManager1
    participant DBusSession as DBusSessionBus
    participant ClientTrayApp as XEmbedClient

    TrayPlugin->>TrayPlugin: constructor
    TrayPlugin->>TrayPlugin: registerDBusMetaTypes
    TrayPlugin->>FdoSelectionManager: new FdoSelectionManager(this) when not X11 and XAvaliable

    activate FdoSelectionManager
    FdoSelectionManager->>KSelectionOwner: new KSelectionOwner(_NET_SYSTEM_TRAY,...)
    FdoSelectionManager->>FdoSelectionManager: QTimer singleShot init

    FdoSelectionManager->>X11Server: xcb_damage_query_version
    FdoSelectionManager->>QGuiApplication: installNativeEventFilter
    FdoSelectionManager->>KSelectionOwner: claim(false)

    KSelectionOwner-->>FdoSelectionManager: claimedOwnership()
    FdoSelectionManager->>FdoSelectionManager: onClaimedOwnership
    FdoSelectionManager->>FdoSelectionManager: initTrayManager
    FdoSelectionManager->>TrayManager1: new TrayManager1(this)
    FdoSelectionManager->>DBusSession: registerObject /org/deepin/dde/TrayManager1
    FdoSelectionManager->>DBusSession: registerService org.deepin.dde.TrayManager1

    FdoSelectionManager->>X11Server: setSystemTrayVisual property

    XEmbedClient->>X11Server: send _NET_SYSTEM_TRAY_OPCODE DOCK(winId)
    X11Server-->>FdoSelectionManager: XCB_CLIENT_MESSAGE via nativeEventFilter

    FdoSelectionManager->>FdoSelectionManager: dock(winId)
    FdoSelectionManager->>FdoSelectionManager: addDamageWatch(winId)
    FdoSelectionManager->>TrayManager1: registerIcon(winId)

    TrayManager1-->>DBusSession: signal Added(winId)
    DBusSession-->>Clients: TrayManager1 Added(winId)
Loading

Class diagram for new Wayland tray selection manager integration

classDiagram
    direction LR

    class TrayPlugin {
        +TrayPlugin(QObject *parent)
        +~TrayPlugin()
        -QHash~QString, QWidget*~ m_widget
        -QHash~QString, QWidget*~ m_tooltip
        -PluginProxyInterface* m_proyInter
        -FdoSelectionManager* m_selectionManager
    }

    class FdoSelectionManager {
        +FdoSelectionManager(QObject *parent)
        +~FdoSelectionManager()
        +bool nativeEventFilter(QByteArray eventType, void* message, qintptr* result)
        -void init()
        -bool addDamageWatch(xcb_window_t client)
        -void dock(xcb_window_t embed_win)
        -void undock(xcb_window_t client)
        -void setSystemTrayVisual()
        -void initTrayManager()
        -void onClaimedOwnership()
        -void onFailedToClaimOwnership()
        -void onLostOwnership()
        -TrayManager1* m_trayManager
        -uint8_t m_damageEventBase
        -QHash~xcb_window_t, u_int32_t~ m_damageWatches
        -KSelectionOwner* m_selectionOwner
    }

    class TrayManager1 {
        +TrayManager1(QObject *parent)
        +~TrayManager1()
        +void registerIcon(xcb_window_t win)
        +void unregisterIcon(xcb_window_t win)
        +void notifyIconChanged(xcb_window_t win)
        +TrayList trayIcons() const
        +bool haveIcon(xcb_window_t win) const
        +bool Manage()
        +QString GetName(uint32_t win)
        +void EnableNotification(uint32_t win, bool enabled)
        +signal void Added(uint32_t id)
        +signal void Removed(uint32_t id)
        +signal void Changed(uint32_t id)
        +signal void Inited()
        -TrayManager1Adaptor* m_adaptor
        -QHash~xcb_window_t, bool~ m_icons
    }

    class TrayManager1Adaptor {
        <<qt_dbus_adaptor>>
    }

    class KSelectionOwner {
    }

    class Util {
        +static Util* instance()
        +xcb_connection_t* getX11Connection()
        +xcb_window_t getRootWindow()
        +xcb_atom_t getAtomFromDisplay(const char* name)
        +xcb_atom_t getAtomByName(const char* name)
    }

    class UniqueCPointer~T~ {
        -CDeleter m_deleter
    }

    class CDeleter {
        +void operator()(T* ptr)
    }

    TrayPlugin --> FdoSelectionManager : owns
    FdoSelectionManager --> TrayManager1 : creates and owns
    FdoSelectionManager --> KSelectionOwner : owns
    FdoSelectionManager --> Util : uses
    FdoSelectionManager --> UniqueCPointer : uses
    TrayManager1 --> TrayManager1Adaptor : owns
    UniqueCPointer --|> std_unique_ptr
    CDeleter --> UniqueCPointer : deleter type
Loading

File-Level Changes

Change Details Files
Wire new FdoSelectionManager into the tray plugin lifecycle to manage XEmbed tray icons when running under non-X11 platforms.
  • Include fdoselectionmanager header and KF6 KWindowSystem in trayplugin.cpp.
  • Instantiate FdoSelectionManager in TrayPlugin constructor when not on X11 but X11 connection is available.
  • Store the FdoSelectionManager instance as a member pointer in TrayPlugin with forward declaration in the header.
plugins/application-tray/trayplugin.cpp
plugins/application-tray/trayplugin.h
Add FdoSelectionManager implementation to own the X11 system tray selection, watch damage events, and forward tray icon lifecycle to TrayManager1 over DBus.
  • Create FdoSelectionManager class that owns a KSelectionOwner for _NET_SYSTEM_TRAY and claims the selection on startup.
  • Install a native XCB event filter to handle system tray client messages, destroy and damage notifications, and call dock/undock or notifyIconChanged accordingly.
  • Integrate XDamage to watch tray window updates and track damage handles in an internal hash map.
  • Set the _NET_SYSTEM_TRAY_VISUAL property on the selection owner window based on a suitable visual from the root screen.
  • Initialize and export a TrayManager1 instance on the session bus at /org/deepin/dde/TrayManager1 with service org.deepin.dde.TrayManager1 when ownership is claimed.
plugins/application-tray/fdoselectionmanager.h
plugins/application-tray/fdoselectionmanager.cpp
plugins/application-tray/c_ptr.h
Introduce TrayManager1 DBus manager for tray icons to expose XEmbed tray state and basic operations.
  • Define TrayManager1 class with a TrayIcons DBus property, Added/Removed/Changed/Inited signals, and DBus methods Manage, GetName, and EnableNotification.
  • Track tray icons in an internal QHash keyed by X11 window ID, with a boolean to control change notifications.
  • Emit DBus signals when icons are registered, unregistered, or changed, and provide helpers to query icon presence and list.
plugins/application-tray/traymanager1.h
plugins/application-tray/traymanager1.cpp
Adjust CMake build configuration to explicitly list tray sources, generate DBus adaptor code for TrayManager1, and add new dependencies.
  • Replace globbing of tray sources with an explicit TRAY_SOURCES list including new FdoSelectionManager, TrayManager1, support headers, and existing tray components.
  • Invoke qt_add_dbus_adaptor to generate the TrayManager1 DBus adaptor from the org.deepin.dde.TrayManager1.xml interface.
  • Add KF6WindowSystem as a required package and link dependency, and extend X11 pkg-config modules to include xcb-damage.
  • Bump DTL_VERSION from 1.99.0 to 2.0.99 in the top-level CMakeLists.txt.
plugins/application-tray/CMakeLists.txt
CMakeLists.txt

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 5 issues, and left some high level feedback:

  • In FdoSelectionManager::undock(), the early return condition uses if (m_trayManager->haveIcon(winId)) { return; }, which looks inverted compared to dock(); this prevents unregistering existing icons and likely should be if (!m_trayManager->haveIcon(winId)) { return; }.
  • In fdoselectionmanager.h the hash is declared as QHash<xcb_window_t, u_int32_t> m_damageWatches; – consider using the standard uint32_t type for consistency with the rest of the xcb-related code and platform headers.
  • FdoSelectionManager::init and ownership handlers call qApp->exit(-1) on failures; since this code runs inside a plugin, it may be safer to signal the error back to the host instead of terminating the entire application.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In FdoSelectionManager::undock(), the early return condition uses `if (m_trayManager->haveIcon(winId)) { return; }`, which looks inverted compared to dock(); this prevents unregistering existing icons and likely should be `if (!m_trayManager->haveIcon(winId)) { return; }`.
- In fdoselectionmanager.h the hash is declared as `QHash<xcb_window_t, u_int32_t> m_damageWatches;` – consider using the standard `uint32_t` type for consistency with the rest of the xcb-related code and platform headers.
- FdoSelectionManager::init and ownership handlers call `qApp->exit(-1)` on failures; since this code runs inside a plugin, it may be safer to signal the error back to the host instead of terminating the entire application.

## Individual Comments

### Comment 1
<location> `plugins/application-tray/fdoselectionmanager.cpp:44-47` </location>
<code_context>
+    QTimer::singleShot(0, this, &FdoSelectionManager::init);
+}
+
+FdoSelectionManager::~FdoSelectionManager()
+{
+    qCDebug(SELECTIONMGR) << "closing";
+    m_selectionOwner->release();
+}
+
</code_context>

<issue_to_address>
**issue (bug_risk):** Native event filter is never removed in the destructor.

Since the constructor installs this as a native event filter via `qApp->installNativeEventFilter(this)`, the destructor should also call `qApp->removeNativeEventFilter(this)` before releasing state to avoid dangling event filter callbacks into a destroyed object.
</issue_to_address>

### Comment 2
<location> `plugins/application-tray/fdoselectionmanager.cpp:154-163` </location>
<code_context>
+    return false;
+}
+
+void FdoSelectionManager::dock(xcb_window_t winId)
+{
+    Q_CHECK_PTR(m_trayManager);
+    qCDebug(SELECTIONMGR) << "trying to dock window " << winId;
+
+    if (m_trayManager->haveIcon(winId)) {
+        return;
+    }
+
+    if (addDamageWatch(winId)) {
+        // Register with TrayManager1 if available
+        m_trayManager->registerIcon(winId);
+    }
+}
</code_context>

<issue_to_address>
**issue (bug_risk):** Potential race/use-before-init of m_trayManager in dock/undock paths.

`dock`/`undock` dereference `m_trayManager` unconditionally, but it’s only created in `initTrayManager()` (from `onClaimedOwnership()`). A tray client message can arrive before `claimedOwnership`, so `dock()` may run with `m_trayManager == nullptr`, tripping `Q_CHECK_PTR` in debug or causing UB in release. Please either ensure `m_trayManager` is constructed earlier (e.g. in `init()`) or skip/defer handling until it is initialized.
</issue_to_address>

### Comment 3
<location> `plugins/application-tray/fdoselectionmanager.cpp:169-178` </location>
<code_context>
+    }
+}
+
+void FdoSelectionManager::undock(xcb_window_t winId)
+{
+    Q_CHECK_PTR(m_trayManager);
+    qCDebug(SELECTIONMGR) << "trying to undock window " << winId;
+
+    if (m_trayManager->haveIcon(winId)) {
+        return;
+    }
+    
+    // Unregister from TrayManager1 if available
+    m_trayManager->unregisterIcon(winId);
+    
+    // m_proxies[winId]->deleteLater();
+    // m_proxies.remove(winId);
+}
+
</code_context>

<issue_to_address>
**issue (bug_risk):** Undock logic returns early when an icon exists, preventing proper unregister.

```cpp
if (m_trayManager->haveIcon(winId)) {
    return;
}
// ...
m_trayManager->unregisterIcon(winId);
```

This condition looks reversed: when the icon exists we return and never call `unregisterIcon`, so the icon is never removed. I think this should be:

```cpp
if (!m_trayManager->haveIcon(winId)) {
    return;
}

m_trayManager->unregisterIcon(winId);
```
</issue_to_address>

### Comment 4
<location> `plugins/application-tray/fdoselectionmanager.h:49` </location>
<code_context>
+
+    uint8_t m_damageEventBase;
+
+    QHash<xcb_window_t, u_int32_t> m_damageWatches;
+    // QHash<xcb_window_t, TrayManagerProxy *> m_proxies;
+    KSelectionOwner *m_selectionOwner;
</code_context>

<issue_to_address>
**suggestion:** Use of non‑standard `u_int32_t` type for damage IDs.

`m_damageWatches` is declared as `QHash<xcb_window_t, u_int32_t>`. `u_int32_t` is a non‑standard extension and may not exist on all platforms/compilers. Please switch to a portable type such as `uint32_t` from `<cstdint>` or, if it better reflects the intent, an appropriate XCB damage type like `xcb_damage_direct_t`/`xcb_damage_damage_t`.

Suggested implementation:

```c
    QHash<xcb_window_t, uint32_t> m_damageWatches;

```

To ensure `uint32_t` is available in this header on all platforms, add `#include <cstdint>` (or `<stdint.h>`) in the include section of `fdoselectionmanager.h` if it is not already indirectly included. Place it alongside the other standard-library includes.
</issue_to_address>

### Comment 5
<location> `plugins/application-tray/CMakeLists.txt:11-12` </location>
<code_context>
 find_package(PkgConfig REQUIRED)
 find_package(Qt${QT_VERSION_MAJOR} ${REQUIRED_QT_VERSION} REQUIRED Core Gui Widgets DBus)
 find_package(Dtk${DTK_VERSION_MAJOR} REQUIRED Core Gui Widget)
+find_package(KF6WindowSystem 6.6 REQUIRED) # for x11 tray section owner

-pkg_check_modules(X11 REQUIRED IMPORTED_TARGET x11 xcb xcb-image xcb-composite xcb-xfixes xcb-util xcb-shape xtst xcb-xtest xcb-res xcb-ewmh)
</code_context>

<issue_to_address>
**suggestion (typo):** Typo and capitalization in inline comment: use "X11 tray selection owner".

In `# for x11 tray section owner`, "section" should be "selection" (per the X11 "selection owner" concept), and "x11" should be capitalized to "X11": `# for X11 tray selection owner`.

```suggestion
find_package(Dtk${DTK_VERSION_MAJOR} REQUIRED Core Gui Widget)
find_package(KF6WindowSystem 6.6 REQUIRED) # for X11 tray selection owner
```
</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.

Comment on lines +44 to +47
FdoSelectionManager::~FdoSelectionManager()
{
qCDebug(SELECTIONMGR) << "closing";
m_selectionOwner->release();
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): Native event filter is never removed in the destructor.

Since the constructor installs this as a native event filter via qApp->installNativeEventFilter(this), the destructor should also call qApp->removeNativeEventFilter(this) before releasing state to avoid dangling event filter callbacks into a destroyed object.

Comment on lines +154 to +167
void FdoSelectionManager::dock(xcb_window_t winId)
{
Q_CHECK_PTR(m_trayManager);
qCDebug(SELECTIONMGR) << "trying to dock window " << winId;

if (m_trayManager->haveIcon(winId)) {
return;
}

if (addDamageWatch(winId)) {
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): Potential race/use-before-init of m_trayManager in dock/undock paths.

dock/undock dereference m_trayManager unconditionally, but it’s only created in initTrayManager() (from onClaimedOwnership()). A tray client message can arrive before claimedOwnership, so dock() may run with m_trayManager == nullptr, tripping Q_CHECK_PTR in debug or causing UB in release. Please either ensure m_trayManager is constructed earlier (e.g. in init()) or skip/defer handling until it is initialized.

Comment on lines +169 to +182
void FdoSelectionManager::undock(xcb_window_t winId)
{
Q_CHECK_PTR(m_trayManager);
qCDebug(SELECTIONMGR) << "trying to undock window " << winId;

if (m_trayManager->haveIcon(winId)) {
return;
}

// Unregister from TrayManager1 if available
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): Undock logic returns early when an icon exists, preventing proper unregister.

if (m_trayManager->haveIcon(winId)) {
    return;
}
// ...
m_trayManager->unregisterIcon(winId);

This condition looks reversed: when the icon exists we return and never call unregisterIcon, so the icon is never removed. I think this should be:

if (!m_trayManager->haveIcon(winId)) {
    return;
}

m_trayManager->unregisterIcon(winId);


uint8_t m_damageEventBase;

QHash<xcb_window_t, u_int32_t> m_damageWatches;
Copy link

Choose a reason for hiding this comment

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

suggestion: Use of non‑standard u_int32_t type for damage IDs.

m_damageWatches is declared as QHash<xcb_window_t, u_int32_t>. u_int32_t is a non‑standard extension and may not exist on all platforms/compilers. Please switch to a portable type such as uint32_t from <cstdint> or, if it better reflects the intent, an appropriate XCB damage type like xcb_damage_direct_t/xcb_damage_damage_t.

Suggested implementation:

    QHash<xcb_window_t, uint32_t> m_damageWatches;

To ensure uint32_t is available in this header on all platforms, add #include <cstdint> (or <stdint.h>) in the include section of fdoselectionmanager.h if it is not already indirectly included. Place it alongside the other standard-library includes.

Comment on lines 11 to 12
find_package(Dtk${DTK_VERSION_MAJOR} REQUIRED Core Gui Widget)
find_package(KF6WindowSystem 6.6 REQUIRED) # for x11 tray section owner
Copy link

Choose a reason for hiding this comment

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

suggestion (typo): Typo and capitalization in inline comment: use "X11 tray selection owner".

In # for x11 tray section owner, "section" should be "selection" (per the X11 "selection owner" concept), and "x11" should be capitalized to "X11": # for X11 tray selection owner.

Suggested change
find_package(Dtk${DTK_VERSION_MAJOR} REQUIRED Core Gui Widget)
find_package(KF6WindowSystem 6.6 REQUIRED) # for x11 tray section owner
find_package(Dtk${DTK_VERSION_MAJOR} REQUIRED Core Gui Widget)
find_package(KF6WindowSystem 6.6 REQUIRED) # for X11 tray selection owner

void FdoSelectionManager::onLostOwnership()
{
qCWarning(SELECTIONMGR) << "lost ownership of Systray Manager";
qApp->exit(-1);
Copy link
Contributor

Choose a reason for hiding this comment

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

selection 并非独占。

Copy link
Member Author

Choose a reason for hiding this comment

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

已修改为强制claim,保留了此信号的日志输出以防万一。退出行为已删除

{
// Create and register the TrayManager1 DBus interface
if (!m_trayManager) {
m_trayManager = new TrayManager1(this);
Copy link
Contributor

Choose a reason for hiding this comment

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

Manage() 调用对接到 claim(true)

Copy link
Member Author

Choose a reason for hiding this comment

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

done

registerDBusToolTipMetaType();
registerDBusImageListMetaType();

if (!KWindowSystem::isPlatformX11() && UTIL->isXAvaliable()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

不能用 qpa,使用 XDG_SESSION_TYPE 判断

Copy link
Member Author

Choose a reason for hiding this comment

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

done

QHash<QString, QWidget*> m_widget;
QHash<QString, QWidget*> m_tooltip;
PluginProxyInterface *m_proyInter;
FdoSelectionManager *m_selectionManager = nullptr;
Copy link
Contributor

Choose a reason for hiding this comment

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

FdoSelectionManager 属于 Xembed 的实现,不应该在 TrayPlugin 这个抽象类上。

Copy link
Member Author

Choose a reason for hiding this comment

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

done

@deepin-bot
Copy link

deepin-bot bot commented Dec 25, 2025

TAG Bot

New tag: 2.0.20
DISTRIBUTION: unstable
Suggest: synchronizing this PR through rebase #407

xcb_damage_query_version_unchecked(c, XCB_DAMAGE_MAJOR_VERSION, XCB_DAMAGE_MINOR_VERSION);
} else {
// no XDamage means
qCCritical(SELECTIONMGR) << "could not load damage extension.";
Copy link
Member Author

Choose a reason for hiding this comment

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

这里该退出么?

Copy link
Contributor

Choose a reason for hiding this comment

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

走到这了,那就是 X server 缺少必要的扩展。业务逻辑依赖这些扩展,可以退出。

Copy link
Member Author

Choose a reason for hiding this comment

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

done

{
qApp->installNativeEventFilter(this);

m_trayManager->Manage();
Copy link
Contributor

Choose a reason for hiding this comment

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

Dbus 的注册是下面执行的,那么此处的调用是不是应该延后?

Copy link
Member Author

Choose a reason for hiding this comment

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

done

xcb_damage_query_version_unchecked(c, XCB_DAMAGE_MAJOR_VERSION, XCB_DAMAGE_MINOR_VERSION);
} else {
// no XDamage means
qCCritical(SELECTIONMGR) << "could not load damage extension.";
Copy link
Contributor

Choose a reason for hiding this comment

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

走到这了,那就是 X server 缺少必要的扩展。业务逻辑依赖这些扩展,可以退出。

@BLumia BLumia force-pushed the xembed-tray branch 2 times, most recently from 1ea5c5e to c259057 Compare December 26, 2025 08:11
return true;
}

QString TrayManager1::GetName(uint32_t win)
Copy link
Contributor

Choose a reason for hiding this comment

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

这个是什么?下面的 connection 可以拿到吗?以及使用 KWindownInfo 可以起到预期效果吗?

支持在 wayland 环境下为 Xembed 支持注册 selectionowner 并暴露相关
托盘到 dbus 接口上。

Log:
@deepin-ci-robot
Copy link

deepin pr auto review

我来对这个diff进行代码审查。这个diff主要涉及dde-tray-loader项目的更新,包括版本升级、许可证添加、依赖更新以及新的FDO系统托盘选择管理器的实现。

  1. 版本和依赖更新
  • CMakeLists.txt中DTL_VERSION从1.99.0升级到2.0.99,这是一个主版本升级,需要确保向后兼容性
  • 添加了libkf6windowsystem-dev依赖,这是KDE Frameworks 6的一部分,用于窗口系统集成
  • 新增了LGPL-2.1-or-later许可证文件,这表明部分代码使用了LGPL许可证
  1. FDO系统托盘选择管理器实现
    新增了fdoselectionmanager.cpp/h文件,实现了Freedesktop.org标准的系统托盘选择管理器。主要关注点:

安全性:

  • 使用了RAII模式的UniqueCPointer来管理XCB资源,避免内存泄漏
  • 对X11窗口操作进行了错误检查
  • 使用了Qt的信号槽机制确保线程安全

性能:

  • 使用XCB Damage扩展来监控窗口变化,比轮询更高效
  • 使用哈希表(m_damageWatches)来快速查找和管理窗口

代码质量:

  • 良好的日志记录机制,使用Q_LOGGING_CATEGORY
  • 清晰的代码结构和注释
  • 遵循Qt的编码规范
  1. TrayManager1实现
    新增了traymanager1.cpp/h文件,实现了DBus接口:

安全性:

  • 对窗口ID进行了有效性检查
  • 使用Qt的DBus框架确保通信安全

性能:

  • 使用QHash存储托盘图标信息,提供O(1)的查找性能
  • 使用信号机制通知变化,避免轮询

代码质量:

  • 清晰的接口文档
  • 完整的错误处理
  • 遵循Qt的编码规范
  1. 其他改进
  • xembedprotocolhandler中添加了对Wayland的支持
  • 改进了CMakeLists.txt的构建配置

建议改进:

  1. 在FdoSelectionManager::addDamageWatch中,可以考虑添加对damage事件数量的限制,防止过多的damage事件影响性能
  2. TrayManager1中的m_icons哈希表使用了bool值,可以考虑使用枚举类型来提高代码可读性
  3. 可以考虑添加更多的单元测试来确保新功能的正确性
  4. 在处理X11事件时,可以考虑添加事件队列管理,防止事件积压

总体来说,这个更新实现了Freedesktop.org标准的系统托盘支持,提高了兼容性,代码质量良好,安全性考虑周到,性能优化合理。建议在合并前进行充分的测试,特别是在不同桌面环境下的兼容性测试。

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