From f687d4aea62b1a05fa0407340cbf9989c796d2b1 Mon Sep 17 00:00:00 2001 From: luhongxu Date: Mon, 12 Oct 2026 16:38:43 +0800 Subject: [PATCH] feat: adapt to treeland-region-watch-unstable-v1 protocol MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Add treeland-region-watch-unstable-v1.xml to CMakeLists.txt and lock TreelandProtocols to 0.7.0 2. Replace TreeLandWindowOverlapChecker with TreeLandRegionWatchManager and TreeLandRegionWatch 3. Extract shared ensureRegionWatch lambda to deduplicate region watch setup logic 4. Migrate anchor enums from treeland_window_overlap_checker to treeland_region_watch_v1 5. Replace update() with set_region() and add output_removed event handler 6. Rename updateOverlapCheckerPos to updateRegionWatchPos for consistency Influence: 1. Test dock smart-hide behavior with windows overlapping the dock area 2. Verify dock visibility when windows enter and leave the dock region 3. Test dock position changes (top, bottom, left, right) trigger correct region watch updates 4. Verify output_removed event correctly resets overlap state when display is disconnected feat: 适配 treeland-region-watch-unstable-v1 协议 1. 在 CMakeLists.txt 中新增 treeland-region-watch-unstable-v1.xml 并锁定 TreelandProtocols 至 0.7.0 2. 将 TreeLandWindowOverlapChecker 替换为 TreeLandRegionWatchManager 和 TreeLandRegionWatch 3. 提取共享的 ensureRegionWatch lambda 去重区域监听初始化逻辑 4. 将 anchor 枚举从 treeland_window_overlap_checker 迁移至 treeland_region_watch_v1 5. 将 update() 替换为 set_region() 并新增 output_removed 事件处理 6. 将 updateOverlapCheckerPos 重命名为 updateRegionWatchPos 以保持一致性 Influence: 1. 测试任务栏智能隐藏模式下窗口遮挡时的行为 2. 验证窗口进入和离开任务栏区域时任务栏可见性变化 3. 测试任务栏位置切换(上、下、左、右)时区域监听正确更新 4. 验证显示器断开时 output_removed 事件正确重置遮挡状态 --- panels/dock/CMakeLists.txt | 3 +- panels/dock/waylanddockhelper.cpp | 75 ++++++++++++++++++------------- panels/dock/waylanddockhelper.h | 31 +++++++++---- 3 files changed, 68 insertions(+), 41 deletions(-) diff --git a/panels/dock/CMakeLists.txt b/panels/dock/CMakeLists.txt index 505876102..58deda7db 100644 --- a/panels/dock/CMakeLists.txt +++ b/panels/dock/CMakeLists.txt @@ -9,7 +9,7 @@ configure_file(environments.h.in environments.h @ONLY) find_package(PkgConfig REQUIRED) find_package(Qt${QT_VERSION_MAJOR} ${REQUIRED_QT_VERSION} COMPONENTS Core DBus Gui Qml WaylandCompositor Widgets WaylandClient) find_package(DdeTrayLoader REQUIRED) -find_package(TreelandProtocols 0.6.0 REQUIRED) +find_package(TreelandProtocols 0.7.0 REQUIRED) pkg_check_modules(WaylandClient REQUIRED IMPORTED_TARGET wayland-client) file( @@ -63,6 +63,7 @@ qt_generate_wayland_protocol_client_sources(dockpanel ${TREELAND_PROTOCOLS_DATA_DIR}/treeland-wallpaper-color-v1.xml ${TREELAND_PROTOCOLS_DATA_DIR}/treeland-dde-shell-v1.xml ${TREELAND_PROTOCOLS_DATA_DIR}/treeland-xwindow-control-unstable-v1.xml + ${TREELAND_PROTOCOLS_DATA_DIR}/treeland-region-watch-unstable-v1.xml ) target_link_libraries(dockpanel PRIVATE diff --git a/panels/dock/waylanddockhelper.cpp b/panels/dock/waylanddockhelper.cpp index 0938abce7..ce7f37c86 100644 --- a/panels/dock/waylanddockhelper.cpp +++ b/panels/dock/waylanddockhelper.cpp @@ -12,6 +12,8 @@ #include "qwayland-treeland-xwindow-control-unstable-v1.h" #include "wayland-treeland-dde-shell-v1-client-protocol.h" #include "wayland-treeland-xwindow-control-unstable-v1-client-protocol.h" +#include "qwayland-treeland-region-watch-unstable-v1.h" +#include "wayland-treeland-region-watch-unstable-v1-client-protocol.h" #include #include @@ -26,6 +28,7 @@ WaylandDockHelper::WaylandDockHelper(DockPanel *panel) { m_ddeShellManager.reset(new TreeLandDDEShellManager()); m_xwindowControl.reset(new TreeLandXWindowControl()); + m_regionWatchManager.reset(new TreeLandRegionWatchManager()); DS_NAMESPACE::DAppletBridge bridge("org.deepin.ds.dock.taskmanager"); if (auto applet = bridge.applet()) { connect(applet, SIGNAL(windowFullscreenChanged(bool)), this, SLOT(setCurrentActiveWindowFullscreened(bool))); @@ -40,33 +43,26 @@ WaylandDockHelper::WaylandDockHelper(DockPanel *panel) } - connect(m_panel, &DockPanel::positionChanged, this, &WaylandDockHelper::updateOverlapCheckerPos); - connect(m_panel, &DockPanel::dockSizeChanged, this, &WaylandDockHelper::updateOverlapCheckerPos); - connect(m_panel, &DockPanel::rootObjectChanged, this, &WaylandDockHelper::updateOverlapCheckerPos); + connect(m_panel, &DockPanel::positionChanged, this, &WaylandDockHelper::updateRegionWatchPos); + connect(m_panel, &DockPanel::dockSizeChanged, this, &WaylandDockHelper::updateRegionWatchPos); + connect(m_panel, &DockPanel::rootObjectChanged, this, &WaylandDockHelper::updateRegionWatchPos); - connect(m_ddeShellManager.get(), &TreeLandDDEShellManager::activeChanged, this, [this]() { - if (m_panel->hideMode() == HideMode::SmartHide && m_ddeShellManager->isActive()) { - m_overlapChecker.reset(new TreeLandWindowOverlapChecker(this, m_ddeShellManager->get_window_overlap_checker())); - updateOverlapCheckerPos(); + auto ensureRegionWatch = [this]() { + if (m_panel->hideMode() == HideMode::SmartHide && m_regionWatchManager->isActive()) { + m_regionWatch.reset(new TreeLandRegionWatch(this, m_regionWatchManager->get_region_watch())); + updateRegionWatchPos(); } else { - m_overlapChecker.reset(nullptr); + m_regionWatch.reset(nullptr); } - }); - - connect(m_panel, &DockPanel::hideModeChanged, this, [this](HideMode mode) { - if (mode == HideMode::SmartHide && m_ddeShellManager->isActive()) { - m_overlapChecker.reset(new TreeLandWindowOverlapChecker(this, m_ddeShellManager->get_window_overlap_checker())); - updateOverlapCheckerPos(); - } else { - m_overlapChecker.reset(nullptr); - } - }); + }; + connect(m_regionWatchManager.get(), &TreeLandRegionWatchManager::activeChanged, this, ensureRegionWatch); + connect(m_panel, &DockPanel::hideModeChanged, this, ensureRegionWatch); } -void WaylandDockHelper::updateOverlapCheckerPos() +void WaylandDockHelper::updateRegionWatchPos() { - if (!m_overlapChecker) + if (!m_regionWatch) return; if (!m_panel->rootObject()) @@ -79,20 +75,20 @@ void WaylandDockHelper::updateOverlapCheckerPos() uint32_t anchor = 0; switch (m_panel->position()) { case Top: - anchor = QtWayland::treeland_window_overlap_checker::anchor_top; + anchor = QtWayland::treeland_region_watch_v1::anchor_top; break; case Bottom: - anchor = QtWayland::treeland_window_overlap_checker::anchor_bottom; + anchor = QtWayland::treeland_region_watch_v1::anchor_bottom; break; case Left: - anchor = QtWayland::treeland_window_overlap_checker::anchor_left; + anchor = QtWayland::treeland_region_watch_v1::anchor_left; break; case Right: - anchor = QtWayland::treeland_window_overlap_checker::anchor_right; + anchor = QtWayland::treeland_region_watch_v1::anchor_right; break; } - m_overlapChecker->update(m_panel->dockSize(), m_panel->dockSize(), anchor, waylandScreen->output()); + m_regionWatch->set_region(m_panel->dockSize(), m_panel->dockSize(), anchor, waylandScreen->output()); } DockWakeUpArea *WaylandDockHelper::createArea(QScreen *screen) @@ -256,26 +252,43 @@ struct ::wl_callback *TreeLandXWindowControl::setXWindowPositionRelative(uint32_ return QtWayland::treeland_xwindow_control_v1::set_xwindow_position_relative(wid, anchor, wl_fixed_from_double(dx), wl_fixed_from_double(dy)); } -TreeLandWindowOverlapChecker::TreeLandWindowOverlapChecker(WaylandDockHelper *helper, struct ::treeland_window_overlap_checker *checker) - : QWaylandClientExtensionTemplate(treeland_dde_shell_manager_v1_interface.version) +TreeLandRegionWatchManager::TreeLandRegionWatchManager() + : QWaylandClientExtensionTemplate(treeland_region_watch_manager_v1_interface.version) +{ +} + +TreeLandRegionWatchManager::~TreeLandRegionWatchManager() +{ + if (isInitialized()) + destroy(); +} + +TreeLandRegionWatch::TreeLandRegionWatch(WaylandDockHelper *helper, struct ::treeland_region_watch_v1 *watcher) + : QWaylandClientExtensionTemplate(treeland_region_watch_v1_interface.version) , m_helper(helper) { setParent(helper); - init(checker); + init(watcher); } -TreeLandWindowOverlapChecker::~TreeLandWindowOverlapChecker() +TreeLandRegionWatch::~TreeLandRegionWatch() { destroy(); } -void TreeLandWindowOverlapChecker::treeland_window_overlap_checker_enter() +void TreeLandRegionWatch::treeland_region_watch_v1_enter() { m_helper->m_isWindowOverlap = true; Q_EMIT m_helper->isWindowOverlapChanged(m_helper->m_isWindowOverlap); } -void TreeLandWindowOverlapChecker::treeland_window_overlap_checker_leave() +void TreeLandRegionWatch::treeland_region_watch_v1_leave() +{ + m_helper->m_isWindowOverlap = false; + Q_EMIT m_helper->isWindowOverlapChanged(m_helper->m_isWindowOverlap); +} + +void TreeLandRegionWatch::treeland_region_watch_v1_output_removed() { m_helper->m_isWindowOverlap = false; Q_EMIT m_helper->isWindowOverlapChanged(m_helper->m_isWindowOverlap); diff --git a/panels/dock/waylanddockhelper.h b/panels/dock/waylanddockhelper.h index c341fcdb9..592cec8ad 100644 --- a/panels/dock/waylanddockhelper.h +++ b/panels/dock/waylanddockhelper.h @@ -10,6 +10,7 @@ #include "qwayland-treeland-dde-shell-v1.h" #include "qwayland-treeland-wallpaper-color-v1.h" #include "qwayland-treeland-xwindow-control-unstable-v1.h" +#include "qwayland-treeland-region-watch-unstable-v1.h" #include #include @@ -21,7 +22,8 @@ class WallpaperColorManager; class TreeLandDockTriggerArea; class TreeLandDDEShellManager; class TreeLandXWindowControl; -class TreeLandWindowOverlapChecker; +class TreeLandRegionWatchManager; +class TreeLandRegionWatch; class WaylandDockHelper : public DockHelper { @@ -52,16 +54,17 @@ protected Q_SLOTS: void setCurrentActiveWindowFullscreened(bool); private: - void updateOverlapCheckerPos(); + void updateRegionWatchPos(); void initWallpaperColorManager(); private: - friend class TreeLandWindowOverlapChecker; + friend class TreeLandRegionWatch; bool m_isWindowOverlap; bool m_isCurrentActiveWindowFullscreened; DockPanel *m_panel; QScopedPointer m_wallpaperColorManager; - QScopedPointer m_overlapChecker; + QScopedPointer m_regionWatch; + QScopedPointer m_regionWatchManager; QScopedPointer m_ddeShellManager; QScopedPointer m_xwindowControl; struct ::wl_surface *m_dockWlSurface = nullptr; // Dock's wl_surface for XEmbed positioning @@ -103,17 +106,27 @@ class TreeLandXWindowControl : public QWaylandClientExtensionTemplate, public QtWayland::treeland_window_overlap_checker +class TreeLandRegionWatchManager : public QWaylandClientExtensionTemplate, public QtWayland::treeland_region_watch_manager_v1 { Q_OBJECT public: - TreeLandWindowOverlapChecker(WaylandDockHelper *helper, struct ::treeland_window_overlap_checker *); - ~TreeLandWindowOverlapChecker(); + explicit TreeLandRegionWatchManager(); + ~TreeLandRegionWatchManager() override; +}; + +class TreeLandRegionWatch : public QWaylandClientExtensionTemplate, public QtWayland::treeland_region_watch_v1 +{ + Q_OBJECT + +public: + TreeLandRegionWatch(WaylandDockHelper *helper, struct ::treeland_region_watch_v1 *); + ~TreeLandRegionWatch(); protected: - void treeland_window_overlap_checker_enter() override; - void treeland_window_overlap_checker_leave() override; + void treeland_region_watch_v1_enter() override; + void treeland_region_watch_v1_leave() override; + void treeland_region_watch_v1_output_removed() override; private: WaylandDockHelper *m_helper;