feat(frame):dock moves with the mouse to the corresponding screen

多屏扩展模式下桌面-任务栏显示,当鼠标贴近屏幕顶部/底部边缘时,移动任务栏显示到当前屏幕task:18770
This commit is contained in:
zhaolong 2020-05-28 20:45:02 +08:00
parent 526e579016
commit f1ac619557
4 changed files with 173 additions and 110 deletions

View File

@ -4,6 +4,7 @@
* Author: sbw <sbw@sbw.so> * Author: sbw <sbw@sbw.so>
* *
* Maintainer: sbw <sbw@sbw.so> * Maintainer: sbw <sbw@sbw.so>
* zhaolong <zhaolong@uniontech.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -73,6 +74,8 @@ DockSettings::DockSettings(QWidget *parent)
, m_displayInter(new DisplayInter("com.deepin.daemon.Display", "/com/deepin/daemon/Display", QDBusConnection::sessionBus(), this)) , m_displayInter(new DisplayInter("com.deepin.daemon.Display", "/com/deepin/daemon/Display", QDBusConnection::sessionBus(), this))
, m_itemManager(DockItemManager::instance(this)) , m_itemManager(DockItemManager::instance(this))
, m_trashPluginShow(true) , m_trashPluginShow(true)
, m_isMouseMoveCause(false)
, m_mouseCauseDockScreen(nullptr)
{ {
m_settingsMenu.setAccessibleName("settingsmenu"); m_settingsMenu.setAccessibleName("settingsmenu");
checkService(); checkService();
@ -206,24 +209,33 @@ const QRect DockSettings::primaryRect() const
return rect; return rect;
} }
const QRect DockSettings::currentRect() const const QRect DockSettings::currentRect()
{ {
QRect rect; QRect rect;
bool positionAllowed = false; QString currentScrName;
QList<Monitor*> monitors = m_monitors.keys(); if (m_isMouseMoveCause) {
for (Monitor *monitor : monitors) { rect = m_mouseCauseDockScreen->rect();
switch (m_position) { currentScrName = m_mouseCauseDockScreen->name();
case Top: positionAllowed = monitor->dockPosition().topDock; break; } else {
case Right: positionAllowed = monitor->dockPosition().rightDock; break; bool positionAllowed = false;
case Bottom: positionAllowed = monitor->dockPosition().bottomDock; break; QList<Monitor*> monitors = m_monitors.keys();
case Left: positionAllowed = monitor->dockPosition().leftDock; break; for (Monitor *monitor : monitors) {
} switch (m_position) {
if (positionAllowed) { case Top: positionAllowed = monitor->dockPosition().topDock; break;
rect = monitor->rect(); case Right: positionAllowed = monitor->dockPosition().rightDock; break;
if (monitor->isPrimary()) case Bottom: positionAllowed = monitor->dockPosition().bottomDock; break;
break; case Left: positionAllowed = monitor->dockPosition().leftDock; break;
}
if (positionAllowed) {
rect = monitor->rect();
currentScrName = monitor->name();
if (monitor->isPrimary())
break;
}
} }
} }
m_currentScreen = currentScrName;
m_currentRawRect = rect; m_currentRawRect = rect;
qreal scale = qApp->primaryScreen()->devicePixelRatio(); qreal scale = qApp->primaryScreen()->devicePixelRatio();
rect.setWidth(std::round(qreal(rect.width()) / scale)); rect.setWidth(std::round(qreal(rect.width()) / scale));
@ -244,7 +256,7 @@ const QSize DockSettings::panelSize() const
return m_mainWindowSize; return m_mainWindowSize;
} }
const QRect DockSettings::windowRect(const Position position, const bool hide) const const QRect DockSettings::windowRect(const Position position, const bool hide)
{ {
QSize size = m_mainWindowSize; QSize size = m_mainWindowSize;
if (hide) { if (hide) {
@ -357,6 +369,7 @@ void DockSettings::menuActionClicked(QAction *action)
if (action == &m_efficientModeAct) if (action == &m_efficientModeAct)
return m_dockInter->setDisplayMode(Efficient); return m_dockInter->setDisplayMode(Efficient);
m_isMouseMoveCause = false;
calculateMultiScreensPos(); calculateMultiScreensPos();
if (action == &m_topPosAct) if (action == &m_topPosAct)
return m_dockInter->setPosition(Top); return m_dockInter->setPosition(Top);
@ -494,6 +507,18 @@ void DockSettings::updateFrontendGeometry()
resetFrontendGeometry(); resetFrontendGeometry();
} }
void DockSettings::setDockScreen(const QString &scrName)
{
m_isMouseMoveCause = true;
QList<Monitor*> monitors = m_monitors.keys();
for (Monitor *monitor : monitors) {
if (monitor && monitor->name() == scrName) {
m_mouseCauseDockScreen = monitor;
break;
}
}
}
void DockSettings::onOpacityChanged(const double value) void DockSettings::onOpacityChanged(const double value)
{ {
if (m_opacity == value) return; if (m_opacity == value) return;

View File

@ -4,6 +4,7 @@
* Author: sbw <sbw@sbw.so> * Author: sbw <sbw@sbw.so>
* *
* Maintainer: sbw <sbw@sbw.so> * Maintainer: sbw <sbw@sbw.so>
* zhaolong <zhaolong@uniontech.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -56,7 +57,7 @@ public:
inline int narrowTimeout() const { return 100; } inline int narrowTimeout() const { return 100; }
inline bool autoHide() const { return m_autoHide; } inline bool autoHide() const { return m_autoHide; }
const QRect primaryRect() const; const QRect primaryRect() const;
const QRect currentRect() const; const QRect currentRect();
const QList<QRect> monitorsRect() const; const QList<QRect> monitorsRect() const;
inline const QRect primaryRawRect() const { return m_primaryRawRect; } inline const QRect primaryRawRect() const { return m_primaryRawRect; }
inline const QRect currentRawRect() const { return m_currentRawRect; } inline const QRect currentRawRect() const { return m_currentRawRect; }
@ -66,11 +67,14 @@ public:
const int dockMargin() const; const int dockMargin() const;
const QSize panelSize() const; const QSize panelSize() const;
const QRect windowRect(const Position position, const bool hide = false) const; const QRect windowRect(const Position position, const bool hide = false);
qreal dockRatio() const; qreal dockRatio() const;
void showDockSettingsMenu(); void showDockSettingsMenu();
void updateFrontendGeometry(); void updateFrontendGeometry();
void setDockScreen(const QString &scrName);
QString &currentDockScreen() { return m_currentScreen; }
QSize m_mainWindowSize; QSize m_mainWindowSize;
DBusDock *m_dockInter; DBusDock *m_dockInter;
@ -137,7 +141,7 @@ private:
HideState m_hideState; HideState m_hideState;
DisplayMode m_displayMode; DisplayMode m_displayMode;
QRect m_primaryRawRect; QRect m_primaryRawRect;
mutable QRect m_currentRawRect; QRect m_currentRawRect;
QRect m_frontendRect; QRect m_frontendRect;
QMenu m_settingsMenu; QMenu m_settingsMenu;
@ -157,6 +161,9 @@ private:
bool m_trashPluginShow; bool m_trashPluginShow;
QMap<Monitor *, MonitorInter *> m_monitors; QMap<Monitor *, MonitorInter *> m_monitors;
bool m_isMouseMoveCause;
Monitor *m_mouseCauseDockScreen;
QString m_currentScreen;
}; };
#endif // DOCKSETTINGS_H #endif // DOCKSETTINGS_H

View File

@ -4,6 +4,7 @@
* Author: sbw <sbw@sbw.so> * Author: sbw <sbw@sbw.so>
* *
* Maintainer: sbw <sbw@sbw.so> * Maintainer: sbw <sbw@sbw.so>
* zhaolong <zhaolong@uniontech.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -25,6 +26,9 @@
#include "util/utils.h" #include "util/utils.h"
#include "util/docksettings.h" #include "util/docksettings.h"
#include <DStyle>
#include <DPlatformWindowHandle>
#include <QDebug> #include <QDebug>
#include <QEvent> #include <QEvent>
#include <QResizeEvent> #include <QResizeEvent>
@ -32,8 +36,6 @@
#include <QGuiApplication> #include <QGuiApplication>
#include <QX11Info> #include <QX11Info>
#include <qpa/qplatformwindow.h> #include <qpa/qplatformwindow.h>
#include <DStyle>
#include <DPlatformWindowHandle>
#include <X11/X.h> #include <X11/X.h>
#include <X11/Xutil.h> #include <X11/Xutil.h>
@ -127,27 +129,28 @@ const QPoint scaledPos(const QPoint &rawXPos)
} }
MainWindow::MainWindow(QWidget *parent) MainWindow::MainWindow(QWidget *parent)
: DBlurEffectWidget(parent), : DBlurEffectWidget(parent)
m_launched(false), , m_launched(false)
m_mainPanel(new MainPanelControl(this)), , m_mainPanel(new MainPanelControl(this))
m_platformWindowHandle(this), , m_platformWindowHandle(this)
m_wmHelper(DWindowManagerHelper::instance()), , m_wmHelper(DWindowManagerHelper::instance())
m_eventInter(new XEventMonitor("com.deepin.api.XEventMonitor", "/com/deepin/api/XEventMonitor", QDBusConnection::sessionBus())), , m_eventInter(new XEventMonitor("com.deepin.api.XEventMonitor", "/com/deepin/api/XEventMonitor", QDBusConnection::sessionBus()))
m_positionUpdateTimer(new QTimer(this)), , m_positionUpdateTimer(new QTimer(this))
m_expandDelayTimer(new QTimer(this)), , m_expandDelayTimer(new QTimer(this))
m_leaveDelayTimer(new QTimer(this)), , m_leaveDelayTimer(new QTimer(this))
m_shadowMaskOptimizeTimer(new QTimer(this)), , m_shadowMaskOptimizeTimer(new QTimer(this))
m_panelShowAni(new QVariantAnimation(this)), , m_panelShowAni(new QVariantAnimation(this))
m_panelHideAni(new QVariantAnimation(this)), , m_panelHideAni(new QVariantAnimation(this))
m_xcbMisc(XcbMisc::instance()), , m_xcbMisc(XcbMisc::instance())
m_dbusDaemonInterface(QDBusConnection::sessionBus().interface()), , m_dbusDaemonInterface(QDBusConnection::sessionBus().interface())
m_sniWatcher(new StatusNotifierWatcher(SNI_WATCHER_SERVICE, SNI_WATCHER_PATH, QDBusConnection::sessionBus(), this)), , m_sniWatcher(new StatusNotifierWatcher(SNI_WATCHER_SERVICE, SNI_WATCHER_PATH, QDBusConnection::sessionBus(), this))
m_dragWidget(new DragWidget(this)) , m_dragWidget(new DragWidget(this))
, m_mouseCauseDock(false)
{ {
setAccessibleName("mainwindow"); setAccessibleName("mainwindow");
m_mainPanel->setAccessibleName("mainpanel"); m_mainPanel->setAccessibleName("mainpanel");
@ -236,24 +239,26 @@ MainWindow::MainWindow(QWidget *parent)
const QRectF windowRect = m_settings->windowRect(m_curDockPos, false); const QRectF windowRect = m_settings->windowRect(m_curDockPos, false);
const int margin = m_settings->dockMargin(); const int margin = m_settings->dockMargin();
switch (m_curDockPos) { if (!m_mouseCauseDock) {
case Dock::Top: switch (m_curDockPos) {
m_mainPanel->move(0, val - windowRect.height()); case Dock::Top:
QWidget::move(windowRect.left(), windowRect.top() - margin); m_mainPanel->move(0, val - windowRect.height());
break; QWidget::move(windowRect.left(), windowRect.top() - margin);
case Dock::Bottom: break;
m_mainPanel->move(0, 0); case Dock::Bottom:
QWidget::move(windowRect.left(), windowRect.bottom() - val + margin); m_mainPanel->move(0, 0);
break; QWidget::move(windowRect.left(), windowRect.bottom() - val + margin);
case Dock::Left: break;
m_mainPanel->move(val - windowRect.width(), 0); case Dock::Left:
QWidget::move(windowRect.left() - margin, windowRect.top()); m_mainPanel->move(val - windowRect.width(), 0);
break; QWidget::move(windowRect.left() - margin, windowRect.top());
case Dock::Right: break;
m_mainPanel->move(0, 0); case Dock::Right:
QWidget::move(windowRect.right() - val + margin, windowRect.top()); m_mainPanel->move(0, 0);
break; QWidget::move(windowRect.right() - val + margin, windowRect.top());
default: break; break;
default: break;
}
} }
if (m_curDockPos == Dock::Top || m_curDockPos == Dock::Bottom) { if (m_curDockPos == Dock::Top || m_curDockPos == Dock::Bottom) {
@ -276,6 +281,7 @@ MainWindow::MainWindow(QWidget *parent)
}); });
connect(m_panelHideAni, &QVariantAnimation::finished, [ this ]() { connect(m_panelHideAni, &QVariantAnimation::finished, [ this ]() {
m_mouseCauseDock = false;
m_curDockPos = m_newDockPos; m_curDockPos = m_newDockPos;
const QRect windowRect = m_settings->windowRect(m_curDockPos, true); const QRect windowRect = m_settings->windowRect(m_curDockPos, true);
@ -1034,74 +1040,97 @@ void MainWindow::themeTypeChanged(DGuiApplicationHelper::ColorType themeType)
void MainWindow::onRegionMonitorChanged(int x, int y, const QString &key) void MainWindow::onRegionMonitorChanged(int x, int y, const QString &key)
{ {
// if (m_registerKey != key) if (m_registerKey != key)
// return;
if (m_settings->hideMode() == KeepShowing)
return; return;
if (!isVisible()) QScreen *screen = Utils::screenAtByScaled(QPoint(x, y));
setVisible(true);
// QScreen *screen = Utils::screenAtByScaled(QPoint(x, y)); if (screen->name() == m_settings->currentDockScreen()) {
if (m_settings->hideMode() == KeepShowing)
return;
if (!isVisible())
setVisible(true);
} else {
// 移动Dock至相应屏相应位置
m_mouseCauseDock = true;
m_settings->setDockScreen(screen->name());
positionChanged(m_curDockPos, m_curDockPos);
}
} }
void MainWindow::updateRegionMonitorWatch() void MainWindow::updateRegionMonitorWatch()
{ {
if (m_settings->hideMode() == KeepShowing) if (!m_registerKey.isEmpty()) {
return; m_eventInter->UnregisterArea(m_registerKey);
m_registerKey.clear();
// if (!m_registerKey.isEmpty()) { }
// m_eventInter->UnregisterArea(m_registerKey);
// m_registerKey.clear();
// }
const int flags = Motion | Button | Key; const int flags = Motion | Button | Key;
// QList<QRect> screensRect = m_settings->monitorsRect();
// QList<QRect> monitorAreas; QList<QRect> screensRect = m_settings->monitorsRect();
int val = 2; QList<MonitRect> monitorAreas;
const int margin = m_settings->dockMargin();
const qreal scale = devicePixelRatioF();
int val = 3;
int x, y, w, h; int x, y, w, h;
// if (screensRect.size()) { auto func = [&](MonitRect &monitRect){
switch (m_curDockPos) { monitRect.x1 = int(x * scale);
case Dock::Top: { monitRect.y1 = int(y * scale);
m_eventInter->RegisterArea(margin, 0, m_settings->currentRect().width() - margin * 2, val, flags); monitRect.x2 = int((x + w) * scale);
// for (QRect rect : screensRect) { monitRect.y2 = int((y + h) * scale);
// monitorAreas << QRect(rect.x() + margin, rect.y(), rect.width() - margin * 2, val); monitorAreas << monitRect;
// } };
}
break;
case Dock::Bottom: {
m_eventInter->RegisterArea(margin, m_settings->currentRect().height() - val, m_settings->currentRect().width() - margin * 2, val, flags);
// for (QRect rect : screensRect) {
// monitorAreas << QRect(rect.x() + margin, rect.y() + rect.height() - val, rect.width() - margin * 2, val);
// }
}
break;
case Dock::Left: {
m_eventInter->RegisterArea(0, margin, val, m_settings->currentRect().height() - margin * 2, flags);
// for (QRect rect : screensRect) {
// monitorAreas << QRect(rect.x(), rect.y() + margin, val, rect.height() - margin * 2);
// }
}
break;
case Dock::Right: {
m_eventInter->RegisterArea(m_settings->currentRect().width() - val, margin, val, m_settings->currentRect().height() - margin * 2, flags);
// for (QRect rect : screensRect) {
// monitorAreas << QRect(rect.x() + rect.width() - val, rect.y() + margin, val, rect.height() - margin * 2);
// }
}
break;
}
// m_registerKey = m_eventInter->RegisterAreas(monitorAreas , flags);
// } else {
// m_registerKey = m_eventInter->RegisterFullScreen();
// }
// if (!m_regionMonitor->registered()) { if (screensRect.size()) {
// m_regionMonitor->registerRegion(); MonitRect monitRect;
// } switch (m_curDockPos) {
case Dock::Top: {
for (QRect rect : screensRect) {
x = rect.x();
y = rect.y();
w = rect.width();
h = val;
func(monitRect);
}
}
break;
case Dock::Bottom: {
for (QRect rect : screensRect) {
x = rect.x();
y = rect.y() + rect.height() - val;
w = rect.width();
h = val;
func(monitRect);
}
}
break;
case Dock::Left: {
for (QRect rect : screensRect) {
x = rect.x();
y = rect.y();
w = val;
h = rect.height();
func(monitRect);
}
}
break;
case Dock::Right: {
for (QRect rect : screensRect) {
x = rect.x() + rect.width() - val;
y = rect.y();
w = val;
h = rect.height();
func(monitRect);
}
}
break;
}
m_registerKey = m_eventInter->RegisterAreas(monitorAreas , flags);
} else {
m_registerKey = m_eventInter->RegisterFullScreen();
}
} }

View File

@ -4,6 +4,7 @@
* Author: sbw <sbw@sbw.so> * Author: sbw <sbw@sbw.so>
* *
* Maintainer: sbw <sbw@sbw.so> * Maintainer: sbw <sbw@sbw.so>
* zhaolong <zhaolong@uniontech.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -144,6 +145,7 @@ private:
DragWidget *m_dragWidget; DragWidget *m_dragWidget;
Position m_curDockPos; Position m_curDockPos;
Position m_newDockPos; Position m_newDockPos;
bool m_mouseCauseDock;
}; };
#endif // MAINWINDOW_H #endif // MAINWINDOW_H