fix: 修复任务栏显示问题

修复任务栏显示问题

Log:
Task: https://pms.uniontech.com/task-view-135223.html
Influence: 无
Change-Id: I08494c28a2cf8594c4d8b2db0b6cdb5a5049f3eb
This commit is contained in:
weizhixiang 2022-05-24 21:49:47 +08:00
parent 38cf02a51f
commit fa3a508644
17 changed files with 323 additions and 134 deletions

View File

@ -23,7 +23,7 @@
#include "macro.h" #include "macro.h"
#include "dstring.h" #include "dstring.h"
#include<sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include <cstring> #include <cstring>

View File

@ -168,6 +168,16 @@ void XCBUtils::setActiveWindow(XWindow xid)
xcb_ewmh_set_active_window(&m_ewmh, m_screenNum, 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<XWindow> XCBUtils::getClientList() std::list<XWindow> XCBUtils::getClientList()
{ {
std::list<XWindow> ret; std::list<XWindow> ret;
@ -217,8 +227,13 @@ std::vector<XCBAtom> XCBUtils::getWMWindoType(XWindow xid)
std::vector<XCBAtom> ret; std::vector<XCBAtom> ret;
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_window_type(&m_ewmh, xid); 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 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; std::cout << xid << " getWMWindoType error" << std::endl;
}
return ret; return ret;
} }
@ -424,6 +439,8 @@ WMClass XCBUtils::getWMClass(XWindow xid)
WMClass ret; WMClass ret;
xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_class(m_connect, xid); xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_class(m_connect, xid);
xcb_icccm_get_wm_class_reply_t reply; 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 (!xcb_icccm_get_wm_class_reply(m_connect, cookie, &reply, nullptr)) {
if (reply.class_name) if (reply.class_name)
ret.className.assign(reply.class_name); ret.className.assign(reply.class_name);

View File

@ -138,6 +138,12 @@ public:
// 设置活动窗口 _NET_ACTIVE_WINDOW // 设置活动窗口 _NET_ACTIVE_WINDOW
void setActiveWindow(XWindow xid); void setActiveWindow(XWindow xid);
// 改变活动窗口
void changeActiveWindow(XWindow newActiveXid);
// 重新排列窗口
void restackWindow(XWindow xid);
// 获取窗口列表 _NET_CLIENT_LIST // 获取窗口列表 _NET_CLIENT_LIST
std::list<XWindow> getClientList(); std::list<XWindow> getClientList();

View File

@ -33,7 +33,10 @@ AppMenu::AppMenu()
} }
// 增加菜单选项 /**
* @brief AppMenu::appendItem
* @param item
*/
void AppMenu::appendItem(AppMenuItem item) void AppMenu::appendItem(AppMenuItem item)
{ {
if (!item.text.isEmpty()) { 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) void AppMenu::handleAction(uint32_t timestamp, QString itemId)
{ {
for (auto &item : items) { for (auto &item : items) {

View File

@ -100,4 +100,5 @@ const int MotifFunctionMaximize = 16;
const int MotifFunctionClose = 32; const int MotifFunctionClose = 32;
const QString ddeLauncherWMClass = "dde-launcher"; const QString ddeLauncherWMClass = "dde-launcher";
#endif // COMMON_H #endif // COMMON_H

View File

@ -82,17 +82,17 @@ QString DBusHandler::getCurrentWM()
return wmSwitcher->CurrentWM().value(); return wmSwitcher->CurrentWM().value();
} }
// TODO 扩展ApplicationManager Run接口允许带参数启动应用暂时调用StartManager接口 // TODO 扩展ApplicationManager Launch接口允许带参数启动应用暂时调用StartManager接口
void DBusHandler::launchApp(uint32_t timestamp, QStringList files) void DBusHandler::launchApp(QString desktopFile, uint32_t timestamp, QStringList files)
{ {
QDBusInterface interface = QDBusInterface("com.deepin.StartManager", "/com/deepin/StartManager", "com.deepin.StartManager"); QDBusInterface interface = QDBusInterface("com.deepin.daemon.Display", "/com/deepin/StartManager", "com.deepin.StartManager");
interface.call("LaunchApp", files, timestamp); 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"); QDBusInterface interface = QDBusInterface("com.deepin.daemon.Display", "/com/deepin/StartManager", "com.deepin.StartManager");
interface.call("LaunchAppAction", file, section, timestamp); interface.call("LaunchAppAction", desktopFile, action, timestamp);
} }
void DBusHandler::markAppLaunched(const QString &filePath) void DBusHandler::markAppLaunched(const QString &filePath)

View File

@ -56,8 +56,8 @@ public:
QString getCurrentWM(); QString getCurrentWM();
/************************* StartManager ***************************/ /************************* StartManager ***************************/
void launchApp(uint32_t timestamp, QStringList files); void launchApp(QString desktopFile, uint32_t timestamp, QStringList files);
void launchAppAction(uint32_t timestamp, QString file, QString section); void launchAppAction(QString desktopFile, QString action, uint32_t timestamp);
/************************* AlRecorder1 ***************************/ /************************* AlRecorder1 ***************************/
void markAppLaunched(const QString &filePath); void markAppLaunched(const QString &filePath);

View File

@ -21,7 +21,6 @@
#include "dock.h" #include "dock.h"
#include "windowidentify.h" #include "windowidentify.h"
#include "common.h"
#include "windowinfok.h" #include "windowinfok.h"
#include "xcbutils.h" #include "xcbutils.h"
#include "dbushandler.h" #include "dbushandler.h"
@ -248,7 +247,7 @@ void Dock::undockEntry(Entry *entry)
*/ */
QString Dock::allocEntryId() 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(); 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 * @brief Dock::getActiveWindow
* @return * @return
@ -380,6 +392,14 @@ WindowInfoBase *Dock::getActiveWindow()
return ret; return ret;
} }
void Dock::doActiveWindow(XWindow xid)
{
XCB->changeActiveWindow(xid);
QTimer::singleShot(0, [&] {
XCB->restackWindow(xid);
});
}
/** /**
* @brief Dock::getClientList client列表 * @brief Dock::getClientList client列表
* @return * @return
@ -586,7 +606,7 @@ void Dock::smartHideModeTimerExpired()
{ {
HideState state = shouldHideOnSmartHideMode() ? HideState::Hide : HideState::Show; HideState state = shouldHideOnSmartHideMode() ? HideState::Hide : HideState::Show;
qInfo() << "smartHideModeTimerExpired, is Hide? " << int(state); 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 * @param xid
* @return * @return
*
* 1 desktop
* 2 0
* 3
* 4 rect存在重叠区域
*/ */
bool Dock::isWindowDockOverlapX(XWindow xid) 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环境下判断活动窗口和任务栏区域是否重叠 * @brief Dock::hasInterSectionK Wayland环境下判断活动窗口和任务栏区域是否重叠
* @param windowRect rect * @param windowRect
* @param dockRect rect * @param dockRect
* @return * @return
*/ */
bool Dock::hasInterSectionK(const Rect &windowRect, QRect dockRect) bool Dock::hasInterSectionK(const Rect &windowRect, QRect dockRect)
@ -878,24 +948,21 @@ void Dock::updateHideState(bool delay)
{ {
if (ddeLauncherVisible) { if (ddeLauncherVisible) {
qInfo() << "updateHideState: dde launcher is visible, show dock"; qInfo() << "updateHideState: dde launcher is visible, show dock";
setPropHideMode(HideState::Show); setPropHideState(HideState::Show);
} }
HideMode mode = SETTING->getHideMode(); HideMode mode = SETTING->getHideMode();
switch (mode) { switch (mode) {
case HideMode::KeepShowing: case HideMode::KeepShowing:
setPropHideMode(HideState::Show); setPropHideState(HideState::Show);
break; break;
case HideMode::KeepHidden: case HideMode::KeepHidden:
setPropHideMode(HideState::Hide); setPropHideState(HideState::Hide);
break; break;
case HideMode::SmartHide: case HideMode::SmartHide:
qInfo() << "reset smart hide mode timer " << delay; qInfo() << "reset smart hide mode timer " << delay;
smartHideTimer->start(delay ? smartHideTimerDelay : 0); smartHideTimer->start(delay ? smartHideTimerDelay : 0);
break; break;
case HideMode::Unknown:
setPropHideMode(HideState::Unknown);
break;
} }
} }
@ -903,7 +970,7 @@ void Dock::updateHideState(bool delay)
* @brief Dock::setPropHideMode * @brief Dock::setPropHideMode
* @param state * @param state
*/ */
void Dock::setPropHideMode(HideState state) void Dock::setPropHideState(HideState state)
{ {
if (state == HideState::Unknown) { if (state == HideState::Unknown) {
qInfo() << "setPropHideState: unknown mode"; qInfo() << "setPropHideState: unknown mode";
@ -964,7 +1031,8 @@ void Dock::attachOrDetachWindow(WindowInfoBase *info)
*/ */
void Dock::attachWindow(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) { if (entry) {
// entry existed // entry existed
entry->attachWindow(info); entry->attachWindow(info);
@ -997,9 +1065,9 @@ void Dock::detachWindow(WindowInfoBase *info)
* @param timestamp * @param timestamp
* @param files * @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 file
* @param section * @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); return waylandManager->unRegisterWindow(objPath);
} }
/**
* @brief Dock::isShowingDesktop
* @return
*/
bool Dock::isShowingDesktop()
{
return dbusHandler->wlShowingDesktop();
}
/** /**
* @brief Dock::identifyWindow * @brief Dock::identifyWindow
* @param winInfo * @param winInfo
@ -1312,7 +1389,7 @@ void Dock::setHideMode(HideMode mode)
* @brief Dock::getHideState * @brief Dock::getHideState
* @return * @return
*/ */
Dock::HideState Dock::getHideState() HideState Dock::getHideState()
{ {
return hideState; return hideState;
} }
@ -1321,7 +1398,7 @@ Dock::HideState Dock::getHideState()
* @brief Dock::setHideState * @brief Dock::setHideState
* @param state * @param state
*/ */
void Dock::setHideState(Dock::HideState state) void Dock::setHideState(HideState state)
{ {
hideState = state; hideState = state;
} }

View File

@ -38,18 +38,17 @@ class X11Manager;
class WindowInfoK; class WindowInfoK;
class WindowInfoX; class WindowInfoX;
enum class HideState
{
Unknown,
Show,
Hide,
};
// 任务栏 // 任务栏
class Dock : public SynModule class Dock : public SynModule
{ {
Q_OBJECT Q_OBJECT
enum class HideState
{
Unknown,
Show,
Hide,
};
public: public:
explicit Dock(QObject *parent = nullptr); explicit Dock(QObject *parent = nullptr);
~Dock(); ~Dock();
@ -61,12 +60,12 @@ public:
void setDdeLauncherVisible(bool visible); void setDdeLauncherVisible(bool visible);
QString getWMName(); QString getWMName();
void setWMName(QString name); void setWMName(QString name);
void setPropHideMode(HideState state); void setPropHideState(HideState state);
void attachOrDetachWindow(WindowInfoBase *info); void attachOrDetachWindow(WindowInfoBase *info);
void attachWindow(WindowInfoBase *info); void attachWindow(WindowInfoBase *info);
void detachWindow(WindowInfoBase *info); void detachWindow(WindowInfoBase *info);
void launchApp(uint32_t timestamp, QStringList files); void launchApp(const QString desktopFile, uint32_t timestamp, QStringList files);
void launchAppAction(uint32_t timestamp, QString file, QString section); void launchAppAction(const QString desktopFile, QString action, uint32_t timestamp);
bool is3DWM(); bool is3DWM();
bool isWaylandEnv(); bool isWaylandEnv();
WindowInfoK *handleActiveWindowChangedK(uint activeWin); WindowInfoK *handleActiveWindowChangedK(uint activeWin);
@ -79,6 +78,7 @@ public:
void registerWindowWayland(const QString &objPath); void registerWindowWayland(const QString &objPath);
void unRegisterWindowWayland(const QString &objPath); void unRegisterWindowWayland(const QString &objPath);
bool isShowingDesktop();
AppInfo *identifyWindow(WindowInfoBase *winInfo, QString &innerId); AppInfo *identifyWindow(WindowInfoBase *winInfo, QString &innerId);
void markAppLaunched(AppInfo *appInfo); void markAppLaunched(AppInfo *appInfo);
@ -123,7 +123,9 @@ public:
void presentWindows(QList<uint> windows); void presentWindows(QList<uint> windows);
HideMode getDockHideMode(); HideMode getDockHideMode();
bool isActiveWindow(const WindowInfoBase *win);
WindowInfoBase *getActiveWindow(); WindowInfoBase *getActiveWindow();
void doActiveWindow(XWindow xid);
QList<XWindow> getClientList(); QList<XWindow> getClientList();
void closeWindow(XWindow windowId); void closeWindow(XWindow windowId);
@ -162,6 +164,7 @@ private:
WindowInfoX *findWindowByXidX(XWindow xid); WindowInfoX *findWindowByXidX(XWindow xid);
WindowInfoK *findWindowByXidK(XWindow xid); WindowInfoK *findWindowByXidK(XWindow xid);
bool isWindowDockOverlapX(XWindow xid); bool isWindowDockOverlapX(XWindow xid);
bool hasInterSectionX(const Geometry &windowRect, QRect dockRect);
bool isWindowDockOverlapK(WindowInfoBase *info); bool isWindowDockOverlapK(WindowInfoBase *info);
bool hasInterSectionK(const Rect &windowRect, QRect dockRect); bool hasInterSectionK(const Rect &windowRect, QRect dockRect);
Entry *getDockedEntryByDesktopFile(const QString &desktopFile); Entry *getDockedEntryByDesktopFile(const QString &desktopFile);
@ -187,5 +190,4 @@ private:
QMutex windowOperateMutex; // 窗口合并或拆分锁 QMutex windowOperateMutex; // 窗口合并或拆分锁
}; };
#endif // DOCK_H #endif // DOCK_H

View File

@ -59,13 +59,13 @@ void DockSettings::init()
HideMode DockSettings::getHideMode() HideMode DockSettings::getHideMode()
{ {
HideMode ret = HideMode::Unknown; HideMode ret = HideMode::KeepShowing;
if (dockSettings) { if (dockSettings) {
QString mode = dockSettings->value(keyHideMode).toString(); QString mode = dockSettings->value(keyHideMode).toString();
HideModeHandler handler(mode); HideModeHandler handler(mode);
ret = handler.toEnum(); return handler.toEnum();
} }
return ret; return HideMode::KeepShowing;
} }
void DockSettings::setHideMode(HideMode mode) void DockSettings::setHideMode(HideMode mode)
@ -77,25 +77,25 @@ void DockSettings::setHideMode(HideMode mode)
DisplayMode DockSettings::getDisplayMode() DisplayMode DockSettings::getDisplayMode()
{ {
DisplayMode ret = DisplayMode::Unknown; DisplayMode ret = DisplayMode::Efficient;
if (dockSettings) { if (dockSettings) {
QString mode = dockSettings->value(keyDisplayMode).toString(); QString mode = dockSettings->value(keyDisplayMode).toString();
DisplayModeHandler handler(mode); DisplayModeHandler handler(mode);
ret = handler.toEnum(); return handler.toEnum();
} }
return ret; return DisplayMode::Efficient;
} }
void DockSettings::setDisplayMode(DisplayMode mode) void DockSettings::setDisplayMode(DisplayMode mode)
{ {
if (dockSettings) { if (dockSettings) {
dockSettings->setValue(keyHideMode, DisplayModeHandler(mode).toString()); dockSettings->setValue(keyDisplayMode, DisplayModeHandler(mode).toString());
} }
} }
PositionMode DockSettings::getPositionMode() PositionMode DockSettings::getPositionMode()
{ {
PositionMode ret = PositionMode::Unknown; PositionMode ret = PositionMode::Bottom;
if (dockSettings) { if (dockSettings) {
QString mode = dockSettings->value(keyPosition).toString(); QString mode = dockSettings->value(keyPosition).toString();
PositionModeHandler handler(mode); PositionModeHandler handler(mode);
@ -113,7 +113,7 @@ void DockSettings::setPositionMode(PositionMode mode)
ForceQuitAppMode DockSettings::getForceQuitAppMode() ForceQuitAppMode DockSettings::getForceQuitAppMode()
{ {
ForceQuitAppMode ret = ForceQuitAppMode::Unknown; ForceQuitAppMode ret = ForceQuitAppMode::Enabled;
if (dockSettings) { if (dockSettings) {
QString mode = dockSettings->value(keyForceQuitApp).toString(); QString mode = dockSettings->value(keyForceQuitApp).toString();
ForceQuitAppModeHandler handler(mode); ForceQuitAppModeHandler handler(mode);

View File

@ -31,7 +31,6 @@ enum class HideMode {
KeepShowing, KeepShowing,
KeepHidden, KeepHidden,
SmartHide, SmartHide,
Unknown,
}; };
class HideModeHandler { class HideModeHandler {
@ -40,7 +39,7 @@ class HideModeHandler {
public: public:
HideModeHandler(HideMode mode) : modeEnum(mode), modeStr("") {} 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) { bool equal(HideModeHandler hideMode) {
return toString() == hideMode.toString() || toEnum() == hideMode.toEnum(); return toString() == hideMode.toString() || toEnum() == hideMode.toEnum();
@ -54,21 +53,16 @@ public:
return "keep-hidden"; return "keep-hidden";
case HideMode::SmartHide: case HideMode::SmartHide:
return "smart-hide"; return "smart-hide";
case HideMode::Unknown:
default:
return "unknown";
} }
} }
HideMode toEnum() { HideMode toEnum() {
if (modeStr == "keep-showing") if (modeStr == "keep-hidden")
return HideMode::KeepHidden; return HideMode::KeepHidden;
else if (modeStr == "keep-hidden") if (modeStr == "smart-hide")
return HideMode::KeepHidden;
else if (modeStr == "smart-hide")
return HideMode::SmartHide; return HideMode::SmartHide;
else
return HideMode::Unknown; return HideMode::KeepShowing;
} }
}; };
@ -76,7 +70,6 @@ public:
enum class DisplayMode { enum class DisplayMode {
Fashion, Fashion,
Efficient, Efficient,
Unknown,
}; };
class DisplayModeHandler { class DisplayModeHandler {
@ -85,7 +78,7 @@ class DisplayModeHandler {
public: public:
DisplayModeHandler(DisplayMode mode) : modeEnum(mode), modeStr("") {} 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) { bool equal(DisplayModeHandler displayMode) {
return toString() == displayMode.toString() || toEnum() == displayMode.toEnum(); return toString() == displayMode.toString() || toEnum() == displayMode.toEnum();
@ -97,29 +90,23 @@ public:
return "fashion"; return "fashion";
case DisplayMode::Efficient: case DisplayMode::Efficient:
return "efficient"; return "efficient";
case DisplayMode::Unknown:
default:
return "unknown";
} }
} }
DisplayMode toEnum() { DisplayMode toEnum() {
if (modeStr == "fashion") if (modeStr == "fashion")
return DisplayMode::Fashion; return DisplayMode::Fashion;
else if (modeStr == "efficient")
return DisplayMode::Efficient; return DisplayMode::Efficient;
else
return DisplayMode::Unknown;
} }
}; };
// 显示位置 // 显示位置
enum class PositionMode { enum class PositionMode {
TOP, TOP, // 上
Right, Right, // 右
Bottom, Bottom, // 下
Left, Left, // 左
Unknown,
}; };
class PositionModeHandler { class PositionModeHandler {
@ -128,7 +115,7 @@ class PositionModeHandler {
public: public:
PositionModeHandler(PositionMode mode) : modeEnum(mode), modeStr("") {} 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) { bool equal(PositionModeHandler displayMode) {
return toString() == displayMode.toString() || toEnum() == displayMode.toEnum(); return toString() == displayMode.toString() || toEnum() == displayMode.toEnum();
@ -140,27 +127,22 @@ public:
return "top"; return "top";
case PositionMode::Right: case PositionMode::Right:
return "right"; return "right";
case PositionMode::Bottom:
return "bottom";
case PositionMode::Left: case PositionMode::Left:
return "left"; return "left";
case PositionMode::Unknown: case PositionMode::Bottom:
default: return "bottom";
return "unknown";
} }
} }
PositionMode toEnum() { PositionMode toEnum() {
if (modeStr == "top") if (modeStr == "top")
return PositionMode::TOP; return PositionMode::TOP;
else if (modeStr == "right") if (modeStr == "right")
return PositionMode::Right; return PositionMode::Right;
else if (modeStr == "bottom") if (modeStr == "bottom")
return PositionMode::Bottom; return PositionMode::Bottom;
else if (modeStr == "left") if (modeStr == "left")
return PositionMode::Left; return PositionMode::Left;
else
return PositionMode::Unknown;
} }
}; };
@ -169,7 +151,6 @@ enum class ForceQuitAppMode {
Enabled, // 开启 Enabled, // 开启
Disabled, // 关闭 Disabled, // 关闭
Deactivated, // 置灰 Deactivated, // 置灰
Unknown
}; };
class ForceQuitAppModeHandler { class ForceQuitAppModeHandler {
@ -178,7 +159,7 @@ class ForceQuitAppModeHandler {
public: public:
ForceQuitAppModeHandler(ForceQuitAppMode mode) : modeEnum(mode), modeStr("") {} 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) { bool equal(ForceQuitAppModeHandler displayMode) {
return toString() == displayMode.toString() || toEnum() == displayMode.toEnum(); return toString() == displayMode.toString() || toEnum() == displayMode.toEnum();
@ -192,21 +173,16 @@ public:
return "disabled"; return "disabled";
case ForceQuitAppMode::Deactivated: case ForceQuitAppMode::Deactivated:
return "deactivated"; return "deactivated";
case ForceQuitAppMode::Unknown:
default:
return "unknown";
} }
} }
ForceQuitAppMode toEnum() { ForceQuitAppMode toEnum() {
if (modeStr == "enabled") if (modeStr == "disabled")
return ForceQuitAppMode::Enabled;
else if (modeStr == "disabled")
return ForceQuitAppMode::Disabled; return ForceQuitAppMode::Disabled;
else if (modeStr == "deactivated") else if (modeStr == "deactivated")
return ForceQuitAppMode::Deactivated; return ForceQuitAppMode::Deactivated;
else
return ForceQuitAppMode::Unknown; return ForceQuitAppMode::Enabled;
} }
}; };

View File

@ -23,11 +23,14 @@
#include "dock.h" #include "dock.h"
#include "processinfo.h" #include "processinfo.h"
#include "dbusadaptorentry.h" #include "dbusadaptorentry.h"
#include "xcbutils.h"
#include <QDebug> #include <QDebug>
#include <QDBusInterface> #include <QDBusInterface>
#include<signal.h> #include <signal.h>
#define XCB XCBUtils::instance()
Entry::Entry(Dock *_dock, AppInfo *_app, QString _innerId, QObject *parent) Entry::Entry(Dock *_dock, AppInfo *_app, QString _innerId, QObject *parent)
: QObject(parent) : QObject(parent)
@ -115,12 +118,14 @@ QString Entry::getIcon()
if (app) { if (app) {
icon = app->getIcon(); icon = app->getIcon();
if (icon.size() > 0) if (icon.size() > 0)
return ret; return icon;
} }
ret = current->getIcon(); return current->getIcon();
} else if (app) { }
if (app) {
// no window // no window
ret = app->getIcon(); return app->getIcon();
} }
return ret; return ret;
@ -366,21 +371,41 @@ WindowInfoBase *Entry::getCurrentWindowInfo()
return current; 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 Entry::getExec(bool oneLine)
{ {
QString ret;
if (!current) if (!current)
return ret; return "";
ProcessInfo *process = current->getProcess(); ProcessInfo *process = current->getProcess();
if (process) { if (process) {
if (oneLine) if (oneLine)
ret = process->getOneCommandLine().c_str(); return process->getOneCommandLine().c_str();
else else
ret = process->getShellScriptLines().c_str(); return process->getShellScriptLines().c_str();
} }
return ret; return "";
} }
bool Entry::hasWindow() bool Entry::hasWindow()
@ -466,7 +491,7 @@ bool Entry::attachWindow(WindowInfoBase *info)
void Entry::launchApp(uint32_t timestamp) void Entry::launchApp(uint32_t timestamp)
{ {
dock->launchApp(timestamp, QStringList() << app->getFileName()); dock->launchApp(app->getFileName(), timestamp, QStringList());
} }
bool Entry::containsWindow(XWindow xid) 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) 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) void Entry::newInstance(uint32_t timestamp)
{ {
QStringList files; QStringList files;
dock->launchApp(timestamp, files); dock->launchApp(app->getFileName(), timestamp, files);
} }
// 检查应用窗口分离、合并状态 // 检查应用窗口分离、合并状态
@ -561,9 +586,79 @@ void Entry::presentWindows()
dock->presentWindows(windows); dock->presentWindows(windows);
} }
/**
* @brief Entry::active
* @param timestamp
*/
void Entry::active(uint32_t 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() XWindow Entry::getCurrentWindow()
@ -622,9 +717,9 @@ QVector<AppMenuItem> Entry::getMenuItemDesktopActions()
return ret; return ret;
for (auto action : app->getActions()) { for (auto action : app->getActions()) {
AppMenuAction fn = [&](uint32_t timestamp) { AppMenuAction fn = [=](uint32_t timestamp) {
qInfo() << "do MenuItem: " << action.name.c_str(); 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; AppMenuItem item;

View File

@ -73,6 +73,7 @@ public:
void setPropCurrentWindow(XWindow value); void setPropCurrentWindow(XWindow value);
void setCurrentWindowInfo(WindowInfoBase *windowInfo); void setCurrentWindowInfo(WindowInfoBase *windowInfo);
WindowInfoBase *getCurrentWindowInfo(); WindowInfoBase *getCurrentWindowInfo();
WindowInfoBase *findNextLeader();
QString getExec(bool oneLine); QString getExec(bool oneLine);
bool hasWindow(); bool hasWindow();
void updateWindowInfos(); void updateWindowInfos();

View File

@ -103,23 +103,21 @@ WindowIdentify::WindowIdentify(Dock *_dock, QObject *parent)
AppInfo *WindowIdentify::identifyWindow(WindowInfoBase *winInfo, QString &innerId) AppInfo *WindowIdentify::identifyWindow(WindowInfoBase *winInfo, QString &innerId)
{ {
AppInfo *ret = nullptr; if (!winInfo)
//qInfo() << "identifyWindow: window id " << winInfo->getXid() << " innerId " << winInfo->getInnerId(); return nullptr;
if (winInfo->getWindowType() == "X11")
ret = identifyWindowX11(static_cast<WindowInfoX *>(winInfo), innerId);
else if (winInfo->getWindowType() == "Wayland")
ret = identifyWindowWayland(static_cast<WindowInfoK *>(winInfo), innerId);
return ret; qInfo() << "identifyWindow: window id " << winInfo->getXid() << " innerId " << winInfo->getInnerId();
if (winInfo->getWindowType() == "X11")
return identifyWindowX11(static_cast<WindowInfoX *>(winInfo), innerId);
if (winInfo->getWindowType() == "Wayland")
return identifyWindowWayland(static_cast<WindowInfoK *>(winInfo), innerId);
return nullptr;
} }
AppInfo *WindowIdentify::identifyWindowX11(WindowInfoX *winInfo, QString &innerId) AppInfo *WindowIdentify::identifyWindowX11(WindowInfoX *winInfo, QString &innerId)
{ {
AppInfo *appInfo = nullptr; AppInfo *appInfo = nullptr;
if (winInfo->getInnerId() == "") {
qInfo() << "identify WindowX11: innerId is empty";
return appInfo;
}
for (auto iter = identifyWindowFuns.begin(); iter != identifyWindowFuns.end(); iter++) { for (auto iter = identifyWindowFuns.begin(); iter != identifyWindowFuns.end(); iter++) {
QString name = iter.key(); QString name = iter.key();

View File

@ -28,6 +28,7 @@
#include <QDebug> #include <QDebug>
#include <QCryptographicHash> #include <QCryptographicHash>
#include <QTimer>
#define XCB XCBUtils::instance() #define XCB XCBUtils::instance()
@ -67,9 +68,9 @@ bool WindowInfoX::shouldSkip()
if (atom == XCB->getAtom("_NET_WM_WINDOW_TYPE_UTILITY") if (atom == XCB->getAtom("_NET_WM_WINDOW_TYPE_UTILITY")
|| atom == XCB->getAtom("_NET_WM_WINDOW_TYPE_COMBO") || 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_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_DROPDOWN_MENU")
|| atom == XCB->getAtom("_NET_WM_WINDOW_TYPE_MENU") || atom == XCB->getAtom("_NET_WM_WINDOW_TYPE_MENU")
|| atom == XCB->getAtom("_NET_WM_WINDOW_TYPE_NOTIFICATION") || atom == XCB->getAtom("_NET_WM_WINDOW_TYPE_NOTIFICATION")
@ -93,7 +94,10 @@ QString WindowInfoX::getIcon()
void WindowInfoX::activate() void WindowInfoX::activate()
{ {
XCB->setActiveWindow(xid); XCB->changeActiveWindow(xid);
QTimer::singleShot(0, [&] {
XCB->restackWindow(xid);
});
} }
void WindowInfoX::minimize() void WindowInfoX::minimize()
@ -340,6 +344,9 @@ void WindowInfoX::updateHasWmTransientFor()
hasWMTransientFor = true; hasWMTransientFor = true;
} }
/**
* @brief WindowInfoX::update
*/
void WindowInfoX::update() void WindowInfoX::update()
{ {
updateWmClass(); updateWmClass();

View File

@ -283,12 +283,13 @@ void X11Manager::handleMapNotifyEvent(XWindow xid)
if (!winInfo) if (!winInfo)
return; return;
QTimer::singleShot(2 * 1000, this, [&] { // TODO QTimer不能在非主线程执行使用单独线程开发定时器处理非主线程类似定时任务
//QTimer::singleShot(2 * 1000, this, [=] {
qInfo() << "handleMapNotifyEvent: pass 2s, now call idnetifyWindow, windowId=" << winInfo->getXid(); qInfo() << "handleMapNotifyEvent: pass 2s, now call idnetifyWindow, windowId=" << winInfo->getXid();
QString innerId; QString innerId;
AppInfo *appInfo = dock->identifyWindow(winInfo, innerId); AppInfo *appInfo = dock->identifyWindow(winInfo, innerId);
dock->markAppLaunched(appInfo); dock->markAppLaunched(appInfo);
}); //});
} }
// config changed event 检测窗口大小调整和重绘应用 // config changed event 检测窗口大小调整和重绘应用

View File

@ -49,7 +49,7 @@ void DBusAdaptorLauncher::setFullscreen(bool value)
bool DBusAdaptorLauncher::AddAutostart(const QString &desktopFile) 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<bool> reply = interface.call("AddAutostart", desktopFile); QDBusReply<bool> reply = interface.call("AddAutostart", desktopFile);
return reply.isValid() ? reply.value() : false; return reply.isValid() ? reply.value() : false;
} }
@ -87,14 +87,14 @@ bool DBusAdaptorLauncher::IsItemOnDesktop(const QString &id)
bool DBusAdaptorLauncher::LaunchWithTimestamp(const QString &desktopFile, int time) 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<bool> reply = interface.call("LaunchWithTimestamp", desktopFile, time); QDBusReply<bool> reply = interface.call("LaunchWithTimestamp", desktopFile, time);
return reply.isValid() ? reply.value() : false; return reply.isValid() ? reply.value() : false;
} }
bool DBusAdaptorLauncher::RemoveAutostart(const QString &desktopFile) 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<bool> reply = interface.call("RemoveAutostart", desktopFile); QDBusReply<bool> reply = interface.call("RemoveAutostart", desktopFile);
return reply.isValid() ? reply.value() : false; return reply.isValid() ? reply.value() : false;
} }