From be89d981d9e3f470277d51b1a38a3bf6b3618e01 Mon Sep 17 00:00:00 2001 From: dengbo Date: Tue, 22 Nov 2022 17:14:29 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20wayland=E4=B8=8B=E6=9C=80=E5=B0=8F?= =?UTF-8?q?=E5=8C=96=E9=AD=94=E7=81=AF=E6=95=88=E6=9E=9C=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在应用去驻留在任务栏或者驻留的应用在任务栏坐标有变化时,通过wayland协议去设置最小化窗口的位置 Log: 修复wayland下最小化魔灯效果显示异常的问题 Bug: https://pms.uniontech.com/bug-view-111637.html Influence: wayland下应用窗口最小化显示效果 Change-Id: I56aef594ff0406f5d0bca42f0a4265ffac6398f4 --- frame/controller/dockitemmanager.cpp | 7 ++++++- frame/controller/dockitemmanager.h | 3 ++- frame/item/appitem.cpp | 20 +++++++++++--------- frame/item/appitem.h | 4 +++- frame/window/mainpanelcontrol.cpp | 28 ++++++++++++++++++++++++++++ frame/window/mainpanelcontrol.h | 1 + frame/window/mainwindow.cpp | 1 + 7 files changed, 52 insertions(+), 12 deletions(-) diff --git a/frame/controller/dockitemmanager.cpp b/frame/controller/dockitemmanager.cpp index ba9bf7e9b..7da638ff2 100644 --- a/frame/controller/dockitemmanager.cpp +++ b/frame/controller/dockitemmanager.cpp @@ -35,7 +35,9 @@ DockItemManager::DockItemManager(QObject *parent) connect(it, &AppItem::requestActivateWindow, m_appInter, &DBusDock::ActivateWindow, Qt::QueuedConnection); connect(it, &AppItem::requestPreviewWindow, m_appInter, &DBusDock::PreviewWindow); connect(it, &AppItem::requestCancelPreview, m_appInter, &DBusDock::CancelPreviewWindow); - + connect(it, &AppItem::requestUpdateItemMinimizedGeometry, this, [=](const QRect r){ + Q_EMIT requestUpdateItemMinimizedGeometry(it, r); + }); connect(this, &DockItemManager::requestUpdateDockItem, it, &AppItem::requestUpdateEntryGeometries); m_itemList.append(it); @@ -194,6 +196,9 @@ void DockItemManager::appItemAdded(const QDBusObjectPath &path, const int index) connect(item, &AppItem::requestActivateWindow, m_appInter, &DBusDock::ActivateWindow, Qt::QueuedConnection); connect(item, &AppItem::requestPreviewWindow, m_appInter, &DBusDock::PreviewWindow); connect(item, &AppItem::requestCancelPreview, m_appInter, &DBusDock::CancelPreviewWindow); + connect(item, &AppItem::requestUpdateItemMinimizedGeometry, this, [=](const QRect r){ + Q_EMIT requestUpdateItemMinimizedGeometry(item, r); + }); connect(this, &DockItemManager::requestUpdateDockItem, item, &AppItem::requestUpdateEntryGeometries); m_itemList.insert(insertIndex, item); diff --git a/frame/controller/dockitemmanager.h b/frame/controller/dockitemmanager.h index 924c0fe5b..926261c56 100644 --- a/frame/controller/dockitemmanager.h +++ b/frame/controller/dockitemmanager.h @@ -16,6 +16,7 @@ #include using DBusDock = com::deepin::dde::daemon::Dock; + /** * @brief The DockItemManager class * 管理类,管理所有的应用数据,插件数据 @@ -39,8 +40,8 @@ signals: void trayVisableCountChanged(const int &count) const; void requestWindowAutoHide(const bool autoHide) const; void requestRefershWindowVisible() const; - void requestUpdateDockItem() const; + void requestUpdateItemMinimizedGeometry(AppItem *item, const QRect) const; public slots: void refreshItemsIcon(); diff --git a/frame/item/appitem.cpp b/frame/item/appitem.cpp index 43db252b8..1b6f7b389 100644 --- a/frame/item/appitem.cpp +++ b/frame/item/appitem.cpp @@ -62,6 +62,7 @@ AppItem::AppItem(const QGSettings *appSettings, const QGSettings *activeAppSetti m_id = m_itemEntryInter->id(); m_active = m_itemEntryInter->isActive(); + m_currentWindowId = m_itemEntryInter->currentWindow(); m_updateIconGeometryTimer->setInterval(500); m_updateIconGeometryTimer->setSingleShot(true); @@ -77,9 +78,8 @@ AppItem::AppItem(const QGSettings *appSettings, const QGSettings *activeAppSetti connect(m_itemEntryInter, &DockEntryInter::WindowInfosChanged, this, &AppItem::updateWindowInfos, Qt::QueuedConnection); connect(m_itemEntryInter, &DockEntryInter::IconChanged, this, &AppItem::refreshIcon); - connect(m_updateIconGeometryTimer, &QTimer::timeout, this, &AppItem::updateWindowIconGeometries, Qt::QueuedConnection); connect(m_retryObtainIconTimer, &QTimer::timeout, this, &AppItem::refreshIcon, Qt::QueuedConnection); - + connect(m_updateIconGeometryTimer, &QTimer::timeout, this, &AppItem::updateWindowIconGeometries, Qt::QueuedConnection); connect(this, &AppItem::requestUpdateEntryGeometries, this, &AppItem::updateWindowIconGeometries); updateWindowInfos(m_itemEntryInter->windowInfos()); @@ -121,12 +121,14 @@ bool AppItem::isValid() const // window behaviors like minimization. void AppItem::updateWindowIconGeometries() { - // wayland没做处理 - if (Utils::IS_WAYLAND_DISPLAY) - return; - const QRect r(mapToGlobal(QPoint(0, 0)), mapToGlobal(QPoint(width(), height()))); + + if (Utils::IS_WAYLAND_DISPLAY){ + Q_EMIT requestUpdateItemMinimizedGeometry(r); + return; + } + if (!QX11Info::connection()) { qWarning() << "QX11Info::connection() is 0x0"; return; @@ -455,9 +457,8 @@ QWidget *AppItem::popupTips() appNameTips.setObjectName(m_itemEntryInter->name()); if (!m_windowInfos.isEmpty()) { - const quint32 currentWindow = m_itemEntryInter->currentWindow(); - Q_ASSERT(m_windowInfos.contains(currentWindow)); - appNameTips.setText(m_windowInfos[currentWindow].title.simplified()); + Q_ASSERT(m_windowInfos.contains(m_currentWindowId)); + appNameTips.setText(m_windowInfos[m_currentWindowId].title.simplified()); } else { appNameTips.setText(m_itemEntryInter->name().simplified()); } @@ -488,6 +489,7 @@ QPoint AppItem::appIconPosition() const void AppItem::updateWindowInfos(const WindowInfoMap &info) { m_windowInfos = info; + m_currentWindowId = info.firstKey(); if (m_appPreviewTips) m_appPreviewTips->setWindowInfos(m_windowInfos, m_itemEntryInter->GetAllowedCloseWindows().value()); m_updateIconGeometryTimer->start(); diff --git a/frame/item/appitem.h b/frame/item/appitem.h index 68d033da1..fe2abb3c2 100644 --- a/frame/item/appitem.h +++ b/frame/item/appitem.h @@ -40,14 +40,15 @@ public: inline ItemType itemType() const override { return App; } QPixmap appIcon(){ return m_appIcon; } virtual QString accessibleName() override; + inline quint32 getAppItemWindowId() const { return m_currentWindowId; } signals: void requestActivateWindow(const WId wid) const; void requestPreviewWindow(const WId wid) const; void requestCancelPreview() const; void dragReady(QWidget *dragWidget); - void requestUpdateEntryGeometries() const; + void requestUpdateItemMinimizedGeometry(const QRect) const; private: void moveEvent(QMoveEvent *e) override; @@ -105,6 +106,7 @@ private: bool m_active; int m_retryTimes; bool m_iconValid; + quint32 m_currentWindowId; quint64 m_lastclickTimes; WindowInfoMap m_windowInfos; diff --git a/frame/window/mainpanelcontrol.cpp b/frame/window/mainpanelcontrol.cpp index 58379f0b4..92187c030 100644 --- a/frame/window/mainpanelcontrol.cpp +++ b/frame/window/mainpanelcontrol.cpp @@ -1211,3 +1211,31 @@ bool MainPanelControl::appIsOnDock(const QString &appDesktop) { return DockItemManager::instance()->appIsOnDock(appDesktop); } + +void MainPanelControl::setKwinAppItemMinimizedGeometry(DockItem *item, const QRect r) +{ + // 只处理wayland窗口 + if (!Utils::IS_WAYLAND_DISPLAY) { + return; + } + + // 对于wayland应用窗口,需要将窗口的位置传递给窗管,用于设置窗口最小化的位置 + auto w = static_cast(parent()); + const auto ratio = devicePixelRatioF(); + if (item->itemType() == DockItem::App && w->windowHandle() && w->windowHandle()->handle()) { + AppItem * appItem = dynamic_cast(item); + if (!appItem) { + qWarning() << "invalid item"; + return; + } + + QList varList = {0, 0, 0, 0, 0}; + varList[0] = appItem->getAppItemWindowId(); + // 此处传给窗管的坐标需要去掉缩放因子,防止最小化窗口位置错误 + varList[1] = (r.x() - w->geometry().x()) * ratio; + varList[2] = (r.y() - w->geometry().y()) * ratio; + varList[3] = r.width(); + varList[4] = r.height(); + QGuiApplication::platformNativeInterface()->setWindowProperty(w->windowHandle()->handle(), "_d_dwayland_dock-appitem-geometry", varList); + } +} diff --git a/frame/window/mainpanelcontrol.h b/frame/window/mainpanelcontrol.h index 5eb5830f0..85c7357ec 100644 --- a/frame/window/mainpanelcontrol.h +++ b/frame/window/mainpanelcontrol.h @@ -37,6 +37,7 @@ public slots: void insertItem(const int index, DockItem *item); void removeItem(DockItem *item); void itemUpdated(DockItem *item); + void setKwinAppItemMinimizedGeometry(DockItem *item, const QRect); signals: void itemMoved(DockItem *sourceItem, DockItem *targetItem); diff --git a/frame/window/mainwindow.cpp b/frame/window/mainwindow.cpp index 2f1564ad2..a25ccbe3f 100644 --- a/frame/window/mainwindow.cpp +++ b/frame/window/mainwindow.cpp @@ -336,6 +336,7 @@ void MainWindow::initConnections() connect(DockItemManager::instance(), &DockItemManager::itemInserted, m_mainPanel, &MainPanelControl::insertItem, Qt::DirectConnection); connect(DockItemManager::instance(), &DockItemManager::itemRemoved, m_mainPanel, &MainPanelControl::removeItem, Qt::DirectConnection); connect(DockItemManager::instance(), &DockItemManager::itemUpdated, m_mainPanel, &MainPanelControl::itemUpdated, Qt::DirectConnection); + connect(DockItemManager::instance(), &DockItemManager::requestUpdateItemMinimizedGeometry, m_mainPanel, &MainPanelControl::setKwinAppItemMinimizedGeometry); connect(DockItemManager::instance(), &DockItemManager::trayVisableCountChanged, this, &MainWindow::resizeDockIcon, Qt::QueuedConnection); connect(DockItemManager::instance(), &DockItemManager::requestWindowAutoHide, m_menuWorker, &MenuWorker::setAutoHide); connect(m_mainPanel, &MainPanelControl::itemMoved, DockItemManager::instance(), &DockItemManager::itemMoved, Qt::DirectConnection);