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 "dstring.h"
#include<sys/stat.h>
#include <sys/stat.h>
#include <unistd.h>
#include <cstring>

View File

@ -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<XWindow> XCBUtils::getClientList()
{
std::list<XWindow> ret;
@ -217,8 +227,13 @@ std::vector<XCBAtom> XCBUtils::getWMWindoType(XWindow xid)
std::vector<XCBAtom> 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);

View File

@ -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<XWindow> getClientList();

View File

@ -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) {

View File

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

View File

@ -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)

View File

@ -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);

View File

@ -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;
}

View File

@ -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<uint> windows);
HideMode getDockHideMode();
bool isActiveWindow(const WindowInfoBase *win);
WindowInfoBase *getActiveWindow();
void doActiveWindow(XWindow xid);
QList<XWindow> 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

View File

@ -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);

View File

@ -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;
}
};

View File

@ -23,11 +23,14 @@
#include "dock.h"
#include "processinfo.h"
#include "dbusadaptorentry.h"
#include "xcbutils.h"
#include <QDebug>
#include <QDBusInterface>
#include<signal.h>
#include <signal.h>
#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<AppMenuItem> 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;

View File

@ -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();

View File

@ -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<WindowInfoX *>(winInfo), innerId);
else if (winInfo->getWindowType() == "Wayland")
ret = identifyWindowWayland(static_cast<WindowInfoK *>(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<WindowInfoX *>(winInfo), innerId);
if (winInfo->getWindowType() == "Wayland")
return identifyWindowWayland(static_cast<WindowInfoK *>(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();

View File

@ -28,6 +28,7 @@
#include <QDebug>
#include <QCryptographicHash>
#include <QTimer>
#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();

View File

@ -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 检测窗口大小调整和重绘应用

View File

@ -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<bool> 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<bool> 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<bool> reply = interface.call("RemoveAutostart", desktopFile);
return reply.isValid() ? reply.value() : false;
}