From fa3a508644480a5a0cb8de20b489fcae043af04e Mon Sep 17 00:00:00 2001 From: weizhixiang Date: Tue, 24 May 2022 21:49:47 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E6=A0=8F=E6=98=BE=E7=A4=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复任务栏显示问题 Log: Task: https://pms.uniontech.com/task-view-135223.html Influence: 无 Change-Id: I08494c28a2cf8594c4d8b2db0b6cdb5a5049f3eb --- src/lib/dfile.cpp | 2 +- src/lib/xcbutils.cpp | 19 ++- src/lib/xcbutils.h | 6 + src/modules/dock/appmenu.cpp | 10 +- src/modules/dock/common.h | 1 + src/modules/dock/dbushandler.cpp | 14 +-- src/modules/dock/dbushandler.h | 4 +- src/modules/dock/dock.cpp | 119 ++++++++++++++---- src/modules/dock/dock.h | 26 ++-- src/modules/dock/docksettings.cpp | 18 +-- src/modules/dock/docksettings.h | 68 ++++------ src/modules/dock/entry.cpp | 125 ++++++++++++++++--- src/modules/dock/entry.h | 1 + src/modules/dock/windowidentify.cpp | 20 ++- src/modules/dock/windowinfox.cpp | 13 +- src/modules/dock/x11manager.cpp | 5 +- src/modules/launcher/dbusadaptorlauncher.cpp | 6 +- 17 files changed, 323 insertions(+), 134 deletions(-) diff --git a/src/lib/dfile.cpp b/src/lib/dfile.cpp index baec4d4..71d9228 100644 --- a/src/lib/dfile.cpp +++ b/src/lib/dfile.cpp @@ -23,7 +23,7 @@ #include "macro.h" #include "dstring.h" -#include +#include #include #include diff --git a/src/lib/xcbutils.cpp b/src/lib/xcbutils.cpp index cdd2f95..76ab665 100644 --- a/src/lib/xcbutils.cpp +++ b/src/lib/xcbutils.cpp @@ -168,6 +168,16 @@ void XCBUtils::setActiveWindow(XWindow xid) xcb_ewmh_set_active_window(&m_ewmh, m_screenNum, xid); } +void XCBUtils::changeActiveWindow(XWindow newActiveXid) +{ + xcb_ewmh_request_change_active_window(&m_ewmh, m_screenNum, newActiveXid, XCB_EWMH_CLIENT_SOURCE_TYPE_OTHER, 0, 0); +} + +void XCBUtils::restackWindow(XWindow xid) +{ + xcb_ewmh_request_restack_window(&m_ewmh, m_screenNum, xid, 0, XCB_STACK_MODE_ABOVE); +} + std::list XCBUtils::getClientList() { std::list ret; @@ -217,8 +227,13 @@ std::vector XCBUtils::getWMWindoType(XWindow xid) std::vector ret; xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_window_type(&m_ewmh, xid); xcb_ewmh_get_atoms_reply_t reply; // a list of Atom - if (!xcb_ewmh_get_wm_window_type_reply(&m_ewmh, cookie, &reply, nullptr)) + if (xcb_ewmh_get_wm_window_type_reply(&m_ewmh, cookie, &reply, nullptr)) { + for (uint32_t i = 0; i < reply.atoms_len; i++) { + ret.push_back(reply.atoms[i]); + } + } else { std::cout << xid << " getWMWindoType error" << std::endl; + } return ret; } @@ -424,6 +439,8 @@ WMClass XCBUtils::getWMClass(XWindow xid) WMClass ret; xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_class(m_connect, xid); xcb_icccm_get_wm_class_reply_t reply; + reply.instance_name = nullptr; + reply.class_name = nullptr; if (!xcb_icccm_get_wm_class_reply(m_connect, cookie, &reply, nullptr)) { if (reply.class_name) ret.className.assign(reply.class_name); diff --git a/src/lib/xcbutils.h b/src/lib/xcbutils.h index baf564c..71e2a4e 100644 --- a/src/lib/xcbutils.h +++ b/src/lib/xcbutils.h @@ -138,6 +138,12 @@ public: // 设置活动窗口 _NET_ACTIVE_WINDOW void setActiveWindow(XWindow xid); + // 改变活动窗口 + void changeActiveWindow(XWindow newActiveXid); + + // 重新排列窗口 + void restackWindow(XWindow xid); + // 获取窗口列表 _NET_CLIENT_LIST std::list getClientList(); diff --git a/src/modules/dock/appmenu.cpp b/src/modules/dock/appmenu.cpp index 31a9403..1bdd377 100644 --- a/src/modules/dock/appmenu.cpp +++ b/src/modules/dock/appmenu.cpp @@ -33,7 +33,10 @@ AppMenu::AppMenu() } -// 增加菜单选项 +/** + * @brief AppMenu::appendItem 增加菜单选项 + * @param item + */ void AppMenu::appendItem(AppMenuItem item) { if (!item.text.isEmpty()) { @@ -42,6 +45,11 @@ void AppMenu::appendItem(AppMenuItem item) } } +/** + * @brief AppMenu::handleAction 响应应用菜单项 + * @param timestamp + * @param itemId + */ void AppMenu::handleAction(uint32_t timestamp, QString itemId) { for (auto &item : items) { diff --git a/src/modules/dock/common.h b/src/modules/dock/common.h index 6d31ccf..9df0899 100644 --- a/src/modules/dock/common.h +++ b/src/modules/dock/common.h @@ -100,4 +100,5 @@ const int MotifFunctionMaximize = 16; const int MotifFunctionClose = 32; const QString ddeLauncherWMClass = "dde-launcher"; + #endif // COMMON_H diff --git a/src/modules/dock/dbushandler.cpp b/src/modules/dock/dbushandler.cpp index 56a37a6..5c0cbb4 100644 --- a/src/modules/dock/dbushandler.cpp +++ b/src/modules/dock/dbushandler.cpp @@ -82,17 +82,17 @@ QString DBusHandler::getCurrentWM() return wmSwitcher->CurrentWM().value(); } -// TODO 扩展ApplicationManager Run接口,允许带参数启动应用,暂时调用StartManager接口 -void DBusHandler::launchApp(uint32_t timestamp, QStringList files) +// TODO 扩展ApplicationManager Launch接口,允许带参数启动应用,暂时调用StartManager接口 +void DBusHandler::launchApp(QString desktopFile, uint32_t timestamp, QStringList files) { - QDBusInterface interface = QDBusInterface("com.deepin.StartManager", "/com/deepin/StartManager", "com.deepin.StartManager"); - interface.call("LaunchApp", files, timestamp); + QDBusInterface interface = QDBusInterface("com.deepin.daemon.Display", "/com/deepin/StartManager", "com.deepin.StartManager"); + interface.call("LaunchApp", desktopFile, timestamp, files); } -void DBusHandler::launchAppAction(uint32_t timestamp, QString file, QString section) +void DBusHandler::launchAppAction(QString desktopFile, QString action, uint32_t timestamp) { - QDBusInterface interface = QDBusInterface("com.deepin.StartManager", "/com/deepin/StartManager", "com.deepin.StartManager"); - interface.call("LaunchAppAction", file, section, timestamp); + QDBusInterface interface = QDBusInterface("com.deepin.daemon.Display", "/com/deepin/StartManager", "com.deepin.StartManager"); + interface.call("LaunchAppAction", desktopFile, action, timestamp); } void DBusHandler::markAppLaunched(const QString &filePath) diff --git a/src/modules/dock/dbushandler.h b/src/modules/dock/dbushandler.h index 5264739..28e7321 100644 --- a/src/modules/dock/dbushandler.h +++ b/src/modules/dock/dbushandler.h @@ -56,8 +56,8 @@ public: QString getCurrentWM(); /************************* StartManager ***************************/ - void launchApp(uint32_t timestamp, QStringList files); - void launchAppAction(uint32_t timestamp, QString file, QString section); + void launchApp(QString desktopFile, uint32_t timestamp, QStringList files); + void launchAppAction(QString desktopFile, QString action, uint32_t timestamp); /************************* AlRecorder1 ***************************/ void markAppLaunched(const QString &filePath); diff --git a/src/modules/dock/dock.cpp b/src/modules/dock/dock.cpp index 751ca07..9c5c41c 100644 --- a/src/modules/dock/dock.cpp +++ b/src/modules/dock/dock.cpp @@ -21,7 +21,6 @@ #include "dock.h" #include "windowidentify.h" -#include "common.h" #include "windowinfok.h" #include "xcbutils.h" #include "dbushandler.h" @@ -248,7 +247,7 @@ void Dock::undockEntry(Entry *entry) */ QString Dock::allocEntryId() { - return QString("e%1T%2").arg(++entriesSum).arg(QString::number(QDateTime::currentMSecsSinceEpoch(), 16)); + return QString("e%1T%2").arg(++entriesSum).arg(QString::number(QDateTime::currentSecsSinceEpoch(), 16)); } /** @@ -365,6 +364,19 @@ HideMode Dock::getDockHideMode() return SETTING->getHideMode(); } +/** + * @brief Dock::isActiveWindow 判断是否为活动窗口 + * @param win + * @return + */ +bool Dock::isActiveWindow(const WindowInfoBase *win) +{ + if (!win) + return false; + + return win == getActiveWindow(); +} + /** * @brief Dock::getActiveWindow 获取当前活跃窗口 * @return @@ -380,6 +392,14 @@ WindowInfoBase *Dock::getActiveWindow() return ret; } +void Dock::doActiveWindow(XWindow xid) +{ + XCB->changeActiveWindow(xid); + QTimer::singleShot(0, [&] { + XCB->restackWindow(xid); + }); +} + /** * @brief Dock::getClientList 获取窗口client列表 * @return @@ -586,7 +606,7 @@ void Dock::smartHideModeTimerExpired() { HideState state = shouldHideOnSmartHideMode() ? HideState::Hide : HideState::Show; qInfo() << "smartHideModeTimerExpired, is Hide? " << int(state); - setPropHideMode(state); + setPropHideState(state); } /** @@ -700,13 +720,63 @@ WindowInfoK *Dock::findWindowByXidK(XWindow xid) } /** - * @brief Dock::isWindowDockOverlapX 判断X环境下窗口和任务栏是否重叠 TODO + * @brief Dock::isWindowDockOverlapX 判断X环境下窗口和任务栏是否重叠 * @param xid * @return + * 计算重叠条件: + * 1 窗口类型非桌面desktop + * 2 窗口透明度非0 + * 3 窗口显示在当前工作区域 + * 4 窗口和任务栏rect存在重叠区域 */ bool Dock::isWindowDockOverlapX(XWindow xid) { - return false; + // 检查窗口类型 + auto desktopType = XCB->getAtom("_NET_WM_WINDOW_TYPE_DESKTOP"); + for (auto ty : XCB->getWMWindoType(xid)) { + if (ty == desktopType) { + // 不处理桌面窗口属性 + return false; + } + } + + // TODO 检查窗口透明度 + // 检查窗口是否显示 + auto wmHiddenType = XCB->getAtom("_NET_WM_STATE_HIDDEN"); + for (auto ty : XCB->getWMState(xid)) { + if (ty == wmHiddenType) { + // 不处理隐藏的窗口属性 + return false; + } + } + + // 检查窗口是否在当前工作区 + uint32_t wmDesktop = XCB->getWMDesktop(xid); + uint32_t currentDesktop = XCB->getCurrentWMDesktop(); + if (wmDesktop != currentDesktop) { + qInfo() << "isWindowDockOverlapX: wmDesktop:" << wmDesktop << " is not equal to currentDesktop:" << currentDesktop; + return false; + } + + // 检查窗口和任务栏窗口是否存在重叠 + auto winRect = XCB->getWindowGeometry(xid); + return hasInterSectionX(winRect, frontendWindowRect); +} + +/** + * @brief Dock::hasInterSectionX 检查窗口重叠区域 + * @param windowRect 活动窗口 + * @param dockRect 任务栏窗口 + * @return + */ +bool Dock::hasInterSectionX(const Geometry &windowRect, QRect dockRect) +{ + int ltX = MAX(windowRect.x, dockRect.x()); + int ltY = MAX(windowRect.y, dockRect.y()); + int rbX = MIN(windowRect.x + windowRect.width, dockRect.x() + dockRect.width()); + int rbY = MIN(windowRect.y + windowRect.height, dockRect.y() + dockRect.height()); + + return (ltX < rbX) && (ltY < rbY); } /** @@ -741,8 +811,8 @@ bool Dock::isWindowDockOverlapK(WindowInfoBase *info) /** * @brief Dock::hasInterSectionK Wayland环境下判断活动窗口和任务栏区域是否重叠 - * @param windowRect 活动窗口rect - * @param dockRect 任务栏窗口rect + * @param windowRect 活动窗口 + * @param dockRect 任务栏窗口 * @return */ bool Dock::hasInterSectionK(const Rect &windowRect, QRect dockRect) @@ -878,24 +948,21 @@ void Dock::updateHideState(bool delay) { if (ddeLauncherVisible) { qInfo() << "updateHideState: dde launcher is visible, show dock"; - setPropHideMode(HideState::Show); + setPropHideState(HideState::Show); } HideMode mode = SETTING->getHideMode(); switch (mode) { case HideMode::KeepShowing: - setPropHideMode(HideState::Show); + setPropHideState(HideState::Show); break; case HideMode::KeepHidden: - setPropHideMode(HideState::Hide); + setPropHideState(HideState::Hide); break; case HideMode::SmartHide: qInfo() << "reset smart hide mode timer " << delay; smartHideTimer->start(delay ? smartHideTimerDelay : 0); break; - case HideMode::Unknown: - setPropHideMode(HideState::Unknown); - break; } } @@ -903,7 +970,7 @@ void Dock::updateHideState(bool delay) * @brief Dock::setPropHideMode 设置隐藏属性 * @param state */ -void Dock::setPropHideMode(HideState state) +void Dock::setPropHideState(HideState state) { if (state == HideState::Unknown) { qInfo() << "setPropHideState: unknown mode"; @@ -964,7 +1031,8 @@ void Dock::attachOrDetachWindow(WindowInfoBase *info) */ void Dock::attachWindow(WindowInfoBase *info) { - Entry *entry = entries->getByInnerId(info->getEntryInnerId()); // entries中存在innerid为空的entry, 导致后续新应用通过innerid获取应用一直能获取到 + // TODO: entries中存在innerid为空的entry, 导致后续新应用通过innerid获取应用一直能获取到 + Entry *entry = entries->getByInnerId(info->getEntryInnerId()); if (entry) { // entry existed entry->attachWindow(info); @@ -997,9 +1065,9 @@ void Dock::detachWindow(WindowInfoBase *info) * @param timestamp 时间 * @param files 应用打开文件 */ -void Dock::launchApp(uint32_t timestamp, QStringList files) +void Dock::launchApp(const QString desktopFile, uint32_t timestamp, QStringList files) { - dbusHandler->launchApp(timestamp, files); + dbusHandler->launchApp(desktopFile, timestamp, files); } /** @@ -1008,9 +1076,9 @@ void Dock::launchApp(uint32_t timestamp, QStringList files) * @param file * @param section */ -void Dock::launchAppAction(uint32_t timestamp, QString file, QString section) +void Dock::launchAppAction(const QString desktopFile, QString action, uint32_t timestamp) { - dbusHandler->launchAppAction(timestamp, file, section); + dbusHandler->launchAppAction(desktopFile, action, timestamp); } /** @@ -1147,6 +1215,15 @@ void Dock::unRegisterWindowWayland(const QString &objPath) return waylandManager->unRegisterWindow(objPath); } +/** + * @brief Dock::isShowingDesktop + * @return + */ +bool Dock::isShowingDesktop() +{ + return dbusHandler->wlShowingDesktop(); +} + /** * @brief Dock::identifyWindow 识别窗口 * @param winInfo @@ -1312,7 +1389,7 @@ void Dock::setHideMode(HideMode mode) * @brief Dock::getHideState 获取隐藏状态 * @return */ -Dock::HideState Dock::getHideState() +HideState Dock::getHideState() { return hideState; } @@ -1321,7 +1398,7 @@ Dock::HideState Dock::getHideState() * @brief Dock::setHideState 设置任务栏隐藏状态 * @param state */ -void Dock::setHideState(Dock::HideState state) +void Dock::setHideState(HideState state) { hideState = state; } diff --git a/src/modules/dock/dock.h b/src/modules/dock/dock.h index 64aede5..f271cfa 100644 --- a/src/modules/dock/dock.h +++ b/src/modules/dock/dock.h @@ -38,18 +38,17 @@ class X11Manager; class WindowInfoK; class WindowInfoX; +enum class HideState +{ + Unknown, + Show, + Hide, +}; + // 任务栏 class Dock : public SynModule { Q_OBJECT - - enum class HideState - { - Unknown, - Show, - Hide, - }; - public: explicit Dock(QObject *parent = nullptr); ~Dock(); @@ -61,12 +60,12 @@ public: void setDdeLauncherVisible(bool visible); QString getWMName(); void setWMName(QString name); - void setPropHideMode(HideState state); + void setPropHideState(HideState state); void attachOrDetachWindow(WindowInfoBase *info); void attachWindow(WindowInfoBase *info); void detachWindow(WindowInfoBase *info); - void launchApp(uint32_t timestamp, QStringList files); - void launchAppAction(uint32_t timestamp, QString file, QString section); + void launchApp(const QString desktopFile, uint32_t timestamp, QStringList files); + void launchAppAction(const QString desktopFile, QString action, uint32_t timestamp); bool is3DWM(); bool isWaylandEnv(); WindowInfoK *handleActiveWindowChangedK(uint activeWin); @@ -79,6 +78,7 @@ public: void registerWindowWayland(const QString &objPath); void unRegisterWindowWayland(const QString &objPath); + bool isShowingDesktop(); AppInfo *identifyWindow(WindowInfoBase *winInfo, QString &innerId); void markAppLaunched(AppInfo *appInfo); @@ -123,7 +123,9 @@ public: void presentWindows(QList windows); HideMode getDockHideMode(); + bool isActiveWindow(const WindowInfoBase *win); WindowInfoBase *getActiveWindow(); + void doActiveWindow(XWindow xid); QList getClientList(); void closeWindow(XWindow windowId); @@ -162,6 +164,7 @@ private: WindowInfoX *findWindowByXidX(XWindow xid); WindowInfoK *findWindowByXidK(XWindow xid); bool isWindowDockOverlapX(XWindow xid); + bool hasInterSectionX(const Geometry &windowRect, QRect dockRect); bool isWindowDockOverlapK(WindowInfoBase *info); bool hasInterSectionK(const Rect &windowRect, QRect dockRect); Entry *getDockedEntryByDesktopFile(const QString &desktopFile); @@ -187,5 +190,4 @@ private: QMutex windowOperateMutex; // 窗口合并或拆分锁 }; - #endif // DOCK_H diff --git a/src/modules/dock/docksettings.cpp b/src/modules/dock/docksettings.cpp index 9947708..63f64ed 100644 --- a/src/modules/dock/docksettings.cpp +++ b/src/modules/dock/docksettings.cpp @@ -59,13 +59,13 @@ void DockSettings::init() HideMode DockSettings::getHideMode() { - HideMode ret = HideMode::Unknown; + HideMode ret = HideMode::KeepShowing; if (dockSettings) { QString mode = dockSettings->value(keyHideMode).toString(); HideModeHandler handler(mode); - ret = handler.toEnum(); + return handler.toEnum(); } - return ret; + return HideMode::KeepShowing; } void DockSettings::setHideMode(HideMode mode) @@ -77,25 +77,25 @@ void DockSettings::setHideMode(HideMode mode) DisplayMode DockSettings::getDisplayMode() { - DisplayMode ret = DisplayMode::Unknown; + DisplayMode ret = DisplayMode::Efficient; if (dockSettings) { QString mode = dockSettings->value(keyDisplayMode).toString(); DisplayModeHandler handler(mode); - ret = handler.toEnum(); + return handler.toEnum(); } - return ret; + return DisplayMode::Efficient; } void DockSettings::setDisplayMode(DisplayMode mode) { if (dockSettings) { - dockSettings->setValue(keyHideMode, DisplayModeHandler(mode).toString()); + dockSettings->setValue(keyDisplayMode, DisplayModeHandler(mode).toString()); } } PositionMode DockSettings::getPositionMode() { - PositionMode ret = PositionMode::Unknown; + PositionMode ret = PositionMode::Bottom; if (dockSettings) { QString mode = dockSettings->value(keyPosition).toString(); PositionModeHandler handler(mode); @@ -113,7 +113,7 @@ void DockSettings::setPositionMode(PositionMode mode) ForceQuitAppMode DockSettings::getForceQuitAppMode() { - ForceQuitAppMode ret = ForceQuitAppMode::Unknown; + ForceQuitAppMode ret = ForceQuitAppMode::Enabled; if (dockSettings) { QString mode = dockSettings->value(keyForceQuitApp).toString(); ForceQuitAppModeHandler handler(mode); diff --git a/src/modules/dock/docksettings.h b/src/modules/dock/docksettings.h index 1fddc25..12a55b6 100644 --- a/src/modules/dock/docksettings.h +++ b/src/modules/dock/docksettings.h @@ -31,7 +31,6 @@ enum class HideMode { KeepShowing, KeepHidden, SmartHide, - Unknown, }; class HideModeHandler { @@ -40,7 +39,7 @@ class HideModeHandler { public: HideModeHandler(HideMode mode) : modeEnum(mode), modeStr("") {} - HideModeHandler(QString mode) : modeEnum(HideMode::Unknown), modeStr(mode) {} + HideModeHandler(QString mode) : modeEnum(HideMode::KeepShowing), modeStr(mode) {} bool equal(HideModeHandler hideMode) { return toString() == hideMode.toString() || toEnum() == hideMode.toEnum(); @@ -54,21 +53,16 @@ public: return "keep-hidden"; case HideMode::SmartHide: return "smart-hide"; - case HideMode::Unknown: - default: - return "unknown"; } } HideMode toEnum() { - if (modeStr == "keep-showing") + if (modeStr == "keep-hidden") return HideMode::KeepHidden; - else if (modeStr == "keep-hidden") - return HideMode::KeepHidden; - else if (modeStr == "smart-hide") + if (modeStr == "smart-hide") return HideMode::SmartHide; - else - return HideMode::Unknown; + + return HideMode::KeepShowing; } }; @@ -76,7 +70,6 @@ public: enum class DisplayMode { Fashion, Efficient, - Unknown, }; class DisplayModeHandler { @@ -85,7 +78,7 @@ class DisplayModeHandler { public: DisplayModeHandler(DisplayMode mode) : modeEnum(mode), modeStr("") {} - DisplayModeHandler(QString mode) : modeEnum(DisplayMode::Unknown), modeStr(mode) {} + DisplayModeHandler(QString mode) : modeEnum(DisplayMode::Efficient), modeStr(mode) {} bool equal(DisplayModeHandler displayMode) { return toString() == displayMode.toString() || toEnum() == displayMode.toEnum(); @@ -97,29 +90,23 @@ public: return "fashion"; case DisplayMode::Efficient: return "efficient"; - case DisplayMode::Unknown: - default: - return "unknown"; } } DisplayMode toEnum() { if (modeStr == "fashion") return DisplayMode::Fashion; - else if (modeStr == "efficient") - return DisplayMode::Efficient; - else - return DisplayMode::Unknown; + + return DisplayMode::Efficient; } }; // 显示位置 enum class PositionMode { - TOP, - Right, - Bottom, - Left, - Unknown, + TOP, // 上 + Right, // 右 + Bottom, // 下 + Left, // 左 }; class PositionModeHandler { @@ -128,7 +115,7 @@ class PositionModeHandler { public: PositionModeHandler(PositionMode mode) : modeEnum(mode), modeStr("") {} - PositionModeHandler(QString mode) : modeEnum(PositionMode::Unknown), modeStr(mode) {} + PositionModeHandler(QString mode) : modeEnum(PositionMode::Bottom), modeStr(mode) {} bool equal(PositionModeHandler displayMode) { return toString() == displayMode.toString() || toEnum() == displayMode.toEnum(); @@ -140,27 +127,22 @@ public: return "top"; case PositionMode::Right: return "right"; - case PositionMode::Bottom: - return "bottom"; case PositionMode::Left: return "left"; - case PositionMode::Unknown: - default: - return "unknown"; + case PositionMode::Bottom: + return "bottom"; } } PositionMode toEnum() { if (modeStr == "top") return PositionMode::TOP; - else if (modeStr == "right") + if (modeStr == "right") return PositionMode::Right; - else if (modeStr == "bottom") + if (modeStr == "bottom") return PositionMode::Bottom; - else if (modeStr == "left") + if (modeStr == "left") return PositionMode::Left; - else - return PositionMode::Unknown; } }; @@ -169,7 +151,6 @@ enum class ForceQuitAppMode { Enabled, // 开启 Disabled, // 关闭 Deactivated, // 置灰 - Unknown }; class ForceQuitAppModeHandler { @@ -178,7 +159,7 @@ class ForceQuitAppModeHandler { public: ForceQuitAppModeHandler(ForceQuitAppMode mode) : modeEnum(mode), modeStr("") {} - ForceQuitAppModeHandler(QString mode) : modeEnum(ForceQuitAppMode::Unknown), modeStr(mode) {} + ForceQuitAppModeHandler(QString mode) : modeEnum(ForceQuitAppMode::Enabled), modeStr(mode) {} bool equal(ForceQuitAppModeHandler displayMode) { return toString() == displayMode.toString() || toEnum() == displayMode.toEnum(); @@ -192,21 +173,16 @@ public: return "disabled"; case ForceQuitAppMode::Deactivated: return "deactivated"; - case ForceQuitAppMode::Unknown: - default: - return "unknown"; } } ForceQuitAppMode toEnum() { - if (modeStr == "enabled") - return ForceQuitAppMode::Enabled; - else if (modeStr == "disabled") + if (modeStr == "disabled") return ForceQuitAppMode::Disabled; else if (modeStr == "deactivated") return ForceQuitAppMode::Deactivated; - else - return ForceQuitAppMode::Unknown; + + return ForceQuitAppMode::Enabled; } }; diff --git a/src/modules/dock/entry.cpp b/src/modules/dock/entry.cpp index 1d215e9..b9e6c04 100644 --- a/src/modules/dock/entry.cpp +++ b/src/modules/dock/entry.cpp @@ -23,11 +23,14 @@ #include "dock.h" #include "processinfo.h" #include "dbusadaptorentry.h" +#include "xcbutils.h" #include #include -#include +#include + +#define XCB XCBUtils::instance() Entry::Entry(Dock *_dock, AppInfo *_app, QString _innerId, QObject *parent) : QObject(parent) @@ -115,12 +118,14 @@ QString Entry::getIcon() if (app) { icon = app->getIcon(); if (icon.size() > 0) - return ret; + return icon; } - ret = current->getIcon(); - } else if (app) { + return current->getIcon(); + } + + if (app) { // no window - ret = app->getIcon(); + return app->getIcon(); } return ret; @@ -366,21 +371,41 @@ WindowInfoBase *Entry::getCurrentWindowInfo() return current; } +/** + * @brief Entry::findNextLeader + * @return + */ +WindowInfoBase *Entry::findNextLeader() +{ + auto xids = windowInfos.keys(); + qSort(xids); + XWindow curWinId = current->getXid(); + int index = xids.indexOf(curWinId); + if (index < 0) + return nullptr; + + // 如果当前窗口是最大, 返回xids[0], 否则返回xids[index + 1] + int nextIndex = 0; + if (index < xids.size() - 1) + nextIndex = index + 1; + + return windowInfos[xids[nextIndex]]; +} + QString Entry::getExec(bool oneLine) { - QString ret; if (!current) - return ret; + return ""; ProcessInfo *process = current->getProcess(); if (process) { if (oneLine) - ret = process->getOneCommandLine().c_str(); + return process->getOneCommandLine().c_str(); else - ret = process->getShellScriptLines().c_str(); + return process->getShellScriptLines().c_str(); } - return ret; + return ""; } bool Entry::hasWindow() @@ -466,7 +491,7 @@ bool Entry::attachWindow(WindowInfoBase *info) void Entry::launchApp(uint32_t timestamp) { - dock->launchApp(timestamp, QStringList() << app->getFileName()); + dock->launchApp(app->getFileName(), timestamp, QStringList()); } bool Entry::containsWindow(XWindow xid) @@ -499,7 +524,7 @@ void Entry::handleMenuItem(uint32_t timestamp, QString itemId) // 处理拖拽事件 void Entry::handleDragDrop(uint32_t timestamp, QStringList files) { - dock->launchApp(timestamp, files); + dock->launchApp(app->getFileName(), timestamp, files); } // 驻留 @@ -519,7 +544,7 @@ void Entry::requestUndock() void Entry::newInstance(uint32_t timestamp) { QStringList files; - dock->launchApp(timestamp, files); + dock->launchApp(app->getFileName(), timestamp, files); } // 检查应用窗口分离、合并状态 @@ -561,9 +586,79 @@ void Entry::presentWindows() dock->presentWindows(windows); } +/** + * @brief Entry::active 激活窗口 + * @param timestamp + */ void Entry::active(uint32_t timestamp) { + if (dock->getHideMode() == HideMode::SmartHide) { + dock->setPropHideState(HideState::Show); + dock->updateHideState(true); + } + // 无窗口则直接启动 + if (!hasWindow()) { + launchApp(timestamp); + return; + } + + if (!current) { + qWarning() << "active: current window is nullptr"; + return; + } + + WindowInfoBase *winInfo = current; + if (dock->isWaylandEnv()) { + // wayland环境 + if (!dock->isActiveWindow(winInfo)) { + winInfo->activate(); + } else { + bool showing = dock->isShowingDesktop(); + if (showing || winInfo->isMinimized()) { + winInfo->activate(); + } else { + if (windowInfos.size() == 1) { + winInfo->minimize(); + } else { + WindowInfoBase *nextWin = findNextLeader(); + if (nextWin) { + nextWin->activate(); + } + } + } + } + } else { + // X11环境 + XWindow xid = winInfo->getXid(); + WindowInfoBase *activeWin = dock->getActiveWindow(); + if (xid != activeWin->getXid()) { + dock->doActiveWindow(xid); + } else { + bool found = false; + bool hiddenAtom = XCB->getAtom("_NET_WM_STATE_HIDDEN"); + for (auto state : XCB->getWMState(xid)) { + if (hiddenAtom == state) { + found = true; + break; + } + } + + if (found) { + // 激活隐藏窗口 + dock->doActiveWindow(xid); + } else { + if (windowInfos.size() == 1) { + XCB->minimizeWindow(xid); + } else if (dock->getActiveWindow()->getXid() == xid) { + WindowInfoBase *nextWin = findNextLeader(); + if (nextWin) { + nextWin->activate(); + } + } + } + } + } } XWindow Entry::getCurrentWindow() @@ -622,9 +717,9 @@ QVector Entry::getMenuItemDesktopActions() return ret; for (auto action : app->getActions()) { - AppMenuAction fn = [&](uint32_t timestamp) { + AppMenuAction fn = [=](uint32_t timestamp) { qInfo() << "do MenuItem: " << action.name.c_str(); - dock->launchAppAction(timestamp, app->getFileName(), action.section.c_str()); + dock->launchAppAction(app->getFileName(), action.section.c_str(), timestamp); }; AppMenuItem item; diff --git a/src/modules/dock/entry.h b/src/modules/dock/entry.h index b903802..b4af5f4 100644 --- a/src/modules/dock/entry.h +++ b/src/modules/dock/entry.h @@ -73,6 +73,7 @@ public: void setPropCurrentWindow(XWindow value); void setCurrentWindowInfo(WindowInfoBase *windowInfo); WindowInfoBase *getCurrentWindowInfo(); + WindowInfoBase *findNextLeader(); QString getExec(bool oneLine); bool hasWindow(); void updateWindowInfos(); diff --git a/src/modules/dock/windowidentify.cpp b/src/modules/dock/windowidentify.cpp index 69ae2ce..bc5bfc1 100644 --- a/src/modules/dock/windowidentify.cpp +++ b/src/modules/dock/windowidentify.cpp @@ -103,23 +103,21 @@ WindowIdentify::WindowIdentify(Dock *_dock, QObject *parent) AppInfo *WindowIdentify::identifyWindow(WindowInfoBase *winInfo, QString &innerId) { - AppInfo *ret = nullptr; - //qInfo() << "identifyWindow: window id " << winInfo->getXid() << " innerId " << winInfo->getInnerId(); - if (winInfo->getWindowType() == "X11") - ret = identifyWindowX11(static_cast(winInfo), innerId); - else if (winInfo->getWindowType() == "Wayland") - ret = identifyWindowWayland(static_cast(winInfo), innerId); + if (!winInfo) + return nullptr; - return ret; + qInfo() << "identifyWindow: window id " << winInfo->getXid() << " innerId " << winInfo->getInnerId(); + if (winInfo->getWindowType() == "X11") + return identifyWindowX11(static_cast(winInfo), innerId); + if (winInfo->getWindowType() == "Wayland") + return identifyWindowWayland(static_cast(winInfo), innerId); + + return nullptr; } AppInfo *WindowIdentify::identifyWindowX11(WindowInfoX *winInfo, QString &innerId) { AppInfo *appInfo = nullptr; - if (winInfo->getInnerId() == "") { - qInfo() << "identify WindowX11: innerId is empty"; - return appInfo; - } for (auto iter = identifyWindowFuns.begin(); iter != identifyWindowFuns.end(); iter++) { QString name = iter.key(); diff --git a/src/modules/dock/windowinfox.cpp b/src/modules/dock/windowinfox.cpp index bcba801..1346804 100644 --- a/src/modules/dock/windowinfox.cpp +++ b/src/modules/dock/windowinfox.cpp @@ -28,6 +28,7 @@ #include #include +#include #define XCB XCBUtils::instance() @@ -67,9 +68,9 @@ bool WindowInfoX::shouldSkip() if (atom == XCB->getAtom("_NET_WM_WINDOW_TYPE_UTILITY") || atom == XCB->getAtom("_NET_WM_WINDOW_TYPE_COMBO") - || atom == XCB->getAtom("_NET_WM_WINDOW_TYPE_DESKTOP") + || atom == XCB->getAtom("_NET_WM_WINDOW_TYPE_DESKTOP") // 桌面属性窗口 || atom == XCB->getAtom("_NET_WM_WINDOW_TYPE_DND") - || atom == XCB->getAtom("_NET_WM_WINDOW_TYPE_DOCK") + || atom == XCB->getAtom("_NET_WM_WINDOW_TYPE_DOCK") // 任务栏属性窗口 || atom == XCB->getAtom("_NET_WM_WINDOW_TYPE_DROPDOWN_MENU") || atom == XCB->getAtom("_NET_WM_WINDOW_TYPE_MENU") || atom == XCB->getAtom("_NET_WM_WINDOW_TYPE_NOTIFICATION") @@ -93,7 +94,10 @@ QString WindowInfoX::getIcon() void WindowInfoX::activate() { - XCB->setActiveWindow(xid); + XCB->changeActiveWindow(xid); + QTimer::singleShot(0, [&] { + XCB->restackWindow(xid); + }); } void WindowInfoX::minimize() @@ -340,6 +344,9 @@ void WindowInfoX::updateHasWmTransientFor() hasWMTransientFor = true; } +/** + * @brief WindowInfoX::update 更新窗口信息(仅仅执行一次) + */ void WindowInfoX::update() { updateWmClass(); diff --git a/src/modules/dock/x11manager.cpp b/src/modules/dock/x11manager.cpp index 92b0f2b..8ed9698 100644 --- a/src/modules/dock/x11manager.cpp +++ b/src/modules/dock/x11manager.cpp @@ -283,12 +283,13 @@ void X11Manager::handleMapNotifyEvent(XWindow xid) if (!winInfo) return; - QTimer::singleShot(2 * 1000, this, [&] { + // TODO QTimer不能在非主线程执行,使用单独线程开发定时器处理非主线程类似定时任务 + //QTimer::singleShot(2 * 1000, this, [=] { qInfo() << "handleMapNotifyEvent: pass 2s, now call idnetifyWindow, windowId=" << winInfo->getXid(); QString innerId; AppInfo *appInfo = dock->identifyWindow(winInfo, innerId); dock->markAppLaunched(appInfo); - }); + //}); } // config changed event 检测窗口大小调整和重绘应用 diff --git a/src/modules/launcher/dbusadaptorlauncher.cpp b/src/modules/launcher/dbusadaptorlauncher.cpp index 9f1d56b..d8efd2c 100644 --- a/src/modules/launcher/dbusadaptorlauncher.cpp +++ b/src/modules/launcher/dbusadaptorlauncher.cpp @@ -49,7 +49,7 @@ void DBusAdaptorLauncher::setFullscreen(bool value) bool DBusAdaptorLauncher::AddAutostart(const QString &desktopFile) { - QDBusInterface interface = QDBusInterface("com.deepin.SessionManager", "/com/deepin/StartManager", "com.deepin.StartManager"); + QDBusInterface interface = QDBusInterface("com.deepin.daemon.Display", "/com/deepin/StartManager", "com.deepin.StartManager"); QDBusReply reply = interface.call("AddAutostart", desktopFile); return reply.isValid() ? reply.value() : false; } @@ -87,14 +87,14 @@ bool DBusAdaptorLauncher::IsItemOnDesktop(const QString &id) bool DBusAdaptorLauncher::LaunchWithTimestamp(const QString &desktopFile, int time) { - QDBusInterface interface = QDBusInterface("com.deepin.SessionManager", "/com/deepin/StartManager", "com.deepin.StartManager"); + QDBusInterface interface = QDBusInterface("com.deepin.daemon.Display", "/com/deepin/StartManager", "com.deepin.StartManager"); QDBusReply reply = interface.call("LaunchWithTimestamp", desktopFile, time); return reply.isValid() ? reply.value() : false; } bool DBusAdaptorLauncher::RemoveAutostart(const QString &desktopFile) { - QDBusInterface interface = QDBusInterface("com.deepin.SessionManager", "/com/deepin/StartManager", "com.deepin.StartManager"); + QDBusInterface interface = QDBusInterface("com.deepin.daemon.Display", "/com/deepin/StartManager", "com.deepin.StartManager"); QDBusReply reply = interface.call("RemoveAutostart", desktopFile); return reply.isValid() ? reply.value() : false; }