fix: wayland下最小化魔灯效果显示异常

在应用去驻留在任务栏或者驻留的应用在任务栏坐标有变化时,通过wayland协议去设置最小化窗口的位置

Log: 修复wayland下最小化魔灯效果显示异常的问题
Bug: https://pms.uniontech.com/bug-view-111637.html
Influence: wayland下应用窗口最小化显示效果
Change-Id: I56aef594ff0406f5d0bca42f0a4265ffac6398f4
This commit is contained in:
dengbo 2022-11-22 17:14:29 +08:00 committed by KT-lcz
parent 060da9489c
commit 8c463e7194
7 changed files with 52 additions and 12 deletions

View File

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

View File

@ -16,6 +16,7 @@
#include <QObject>
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();

View File

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

View File

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

View File

@ -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<QWidget *>(parent());
const auto ratio = devicePixelRatioF();
if (item->itemType() == DockItem::App && w->windowHandle() && w->windowHandle()->handle()) {
AppItem * appItem = dynamic_cast<AppItem *>(item);
if (!appItem) {
qWarning() << "invalid item";
return;
}
QList<QVariant> 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);
}
}

View File

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

View File

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