feat: 鼠标在唤醒区域超过2秒,任务栏才会唤醒

鼠标在其他屏幕的唤醒区域超过2秒,任务栏才会唤醒,防止任务栏频繁切换屏幕

Log: 鼠标在其他屏幕的唤醒区域超过2秒,任务栏才会唤醒
Task: https://pms.uniontech.com/zentao/task-view-33535.html
Change-Id: I58de80b869dbaaf815d5b8b70fa6e80de1ed569e
Reviewed-on: http://gerrit.uniontech.com/c/dde-dock/+/1579
Reviewed-by: <mailman@uniontech.com>
Reviewed-by: fanpengcheng <fanpengcheng@uniontech.com>
Tested-by: <mailman@uniontech.com>
Tested-by: fanpengcheng <fanpengcheng@uniontech.com>
This commit is contained in:
范朋程 2020-08-12 13:57:33 +08:00 committed by fanpengcheng
parent d333bcd545
commit aa389b16cd
2 changed files with 68 additions and 43 deletions

View File

@ -45,6 +45,7 @@ MultiScreenWorker::MultiScreenWorker(QWidget *parent, DWindowManagerHelper *help
, m_displayInter(new DisplayInter("com.deepin.daemon.Display", "/com/deepin/daemon/Display", QDBusConnection::sessionBus(), this))
, m_launcherInter(new DBusLuncher("com.deepin.dde.Launcher", "/com/deepin/dde/Launcher", QDBusConnection::sessionBus()))
, m_monitorUpdateTimer(new QTimer(this))
, m_delayTimer(new QTimer(this))
, m_showAni(new QVariantAnimation(this))
, m_hideAni(new QVariantAnimation(this))
, m_ds(m_displayInter->primary())
@ -113,7 +114,7 @@ QRect MultiScreenWorker::dockRect(const QString &screenName)
return dockRect(screenName, m_position, m_hideMode, m_displayMode);
}
QRect MultiScreenWorker::realDockRect(const QString &screenName, const Position &pos, const HideMode &hideMode, const DisplayMode &displayMode)
QRect MultiScreenWorker::dockRectWithoutScale(const QString &screenName, const Position &pos, const HideMode &hideMode, const DisplayMode &displayMode)
{
if (hideMode == HideMode::KeepShowing)
return getDockShowGeometry(screenName, pos, displayMode, true);
@ -226,9 +227,6 @@ void MultiScreenWorker::onRegionMonitorChanged(int x, int y, const QString &key)
// 过滤重复坐标
static QPoint lastPos(0, 0);
if (lastPos == QPoint(x, y)) {
#ifdef QT_DEBUG
qDebug() << "same point,should return";
#endif
return;
}
lastPos = QPoint(x, y);
@ -239,37 +237,10 @@ void MultiScreenWorker::onRegionMonitorChanged(int x, int y, const QString &key)
// 任务栏显示状态,但需要切换屏幕
if (toScreen != m_ds.current()) {
// 移动Dock至相应屏相应位置
if (m_launcherInter->IsVisible())//启动器显示,则dock不显示
return;
m_delayScreen = toScreen;
// 复制模式.不需要响应切换屏幕
QList<Monitor *> monitorList = validMonitorList(m_monitorInfo);
if (monitorList.size() == 2 && monitorList.first()->rect() == monitorList.last()->rect()) {
#ifdef QT_DEBUG
qDebug() << "copy mode or merge mode";
#endif
parent()->setFixedSize(dockRect(m_ds.current()).size());
parent()->setGeometry(dockRect(m_ds.current()));
return;
}
m_ds.updateDockedScreen(screen->name());
Monitor *currentMonitor = monitorByName(validMonitorList(m_monitorInfo), toScreen);
if (!currentMonitor) {
qDebug() << "cannot find monitor by name: " << toScreen;
return;
}
// 检查边缘是否允许停靠
if (currentMonitor->dockPosition().docked(m_position)) {
if (m_hideMode == HideMode::KeepHidden || m_hideMode == HideMode::SmartHide) {
showAni(m_ds.current());
} else if (m_hideMode == HideMode::KeepShowing) {
changeDockPosition(m_ds.last(), m_ds.current(), m_position, m_position);
}
}
if (!m_delayTimer->isActive())
m_delayTimer->start();
} else {
// 任务栏隐藏状态,但需要显示
if (hideMode() == HideMode::KeepShowing) {
@ -305,6 +276,9 @@ void MultiScreenWorker::onExtralRegionMonitorChanged(int x, int y, const QString
if (m_extralRegisterKey != key)
return;
// 鼠标移动到任务栏界面之外,不再唤起
m_delayTimer->stop();
if (m_hideMode == HideMode::KeepHidden || m_hideMode == HideMode::SmartHide) {
if (!m_launcherInter->IsVisible() && m_autoHide && !m_draging && !m_aniStart) {
if (m_hideMode == HideMode::KeepHidden || (m_hideMode == HideMode::SmartHide && m_hideState == HideState::Hide))
@ -470,6 +444,11 @@ void MultiScreenWorker::updateParentGeometry(const QVariant &value)
updateParentGeometry(value, m_position);
}
void MultiScreenWorker::delayShowDock()
{
emit requestDelayShowDock(m_delayScreen);
}
void MultiScreenWorker::onPositionChanged()
{
const Position position = Dock::Position(m_dockInter->position());
@ -716,7 +695,7 @@ void MultiScreenWorker::onRequestUpdateRegionMonitor()
void MultiScreenWorker::onRequestUpdateFrontendGeometry()
{
const QRect rect = realDockRect(m_ds.current(), m_position, HideMode::KeepShowing, m_displayMode);
const QRect rect = dockRectWithoutScale(m_ds.current(), m_position, HideMode::KeepShowing, m_displayMode);
//!!! 向com.deepin.dde.daemon.Dock的SetFrontendWindowRect接口设置区域时,此区域的高度或宽度不能为0,否则会导致其HideState属性循环切换,造成任务栏循环显示或隐藏
if (rect.width() == 0 || rect.height() == 0)
@ -897,6 +876,41 @@ void MultiScreenWorker::updateMonitorDockedInfo()
}
}
void MultiScreenWorker::onRequestDelayShowDock(const QString &screenName)
{
// 移动Dock至相应屏相应位置
if (m_launcherInter->IsVisible())//启动器显示,则dock不显示
return;
// 复制模式.不需要响应切换屏幕
QList<Monitor *> monitorList = validMonitorList(m_monitorInfo);
if (monitorList.size() == 2 && monitorList.first()->rect() == monitorList.last()->rect()) {
#ifdef QT_DEBUG
qDebug() << "copy mode or merge mode";
#endif
parent()->setFixedSize(dockRect(m_ds.current()).size());
parent()->setGeometry(dockRect(m_ds.current()));
return;
}
m_ds.updateDockedScreen(screenName);
Monitor *currentMonitor = monitorByName(validMonitorList(m_monitorInfo), screenName);
if (!currentMonitor) {
qDebug() << "cannot find monitor by name: " << screenName;
return;
}
// 检查边缘是否允许停靠
if (currentMonitor->dockPosition().docked(m_position)) {
if (m_hideMode == HideMode::KeepHidden || m_hideMode == HideMode::SmartHide) {
showAni(m_ds.current());
} else if (m_hideMode == HideMode::KeepShowing) {
changeDockPosition(m_ds.last(), m_ds.current(), m_position, m_position);
}
}
}
void MultiScreenWorker::initMembers()
{
DockItem::setDockPosition(m_position);
@ -907,6 +921,9 @@ void MultiScreenWorker::initMembers()
m_monitorUpdateTimer->setInterval(10);
m_monitorUpdateTimer->setSingleShot(true);
m_delayTimer->setInterval(2000);
m_delayTimer->setSingleShot(true);
// 设置应用角色为任务栏
m_xcbMisc->set_window_type(xcb_window_t(parent()->winId()), XcbMisc::Dock);
@ -1006,6 +1023,8 @@ void MultiScreenWorker::initConnection()
connect(this, &MultiScreenWorker::requestUpdatePosition, this, &MultiScreenWorker::onRequestUpdatePosition);
connect(this, &MultiScreenWorker::requestNotifyWindowManager, this, &MultiScreenWorker::onRequestNotifyWindowManager);
connect(this, &MultiScreenWorker::requestUpdateMonitorInfo, this, &MultiScreenWorker::onRequestUpdateMonitorInfo);
connect(this, &MultiScreenWorker::requestDelayShowDock, this, &MultiScreenWorker::onRequestDelayShowDock);
// 更新任务栏内容展示
connect(this, &MultiScreenWorker::requestUpdateLayout, this, [ = ] {
parent()->panel()->setFixedSize(dockRect(m_ds.current(), position(), HideMode::KeepShowing, displayMode()).size());
@ -1038,6 +1057,8 @@ void MultiScreenWorker::initConnection()
emit requestNotifyWindowManager();
});
connect(m_delayTimer, &QTimer::timeout, this, &MultiScreenWorker::delayShowDock);
checkDaemonDockService();
}
@ -1316,12 +1337,12 @@ MainWindow *MultiScreenWorker::parent()
return static_cast<MainWindow *>(m_parent);
}
QRect MultiScreenWorker::getDockShowGeometry(const QString &screenName, const Position &pos, const DisplayMode &displaymode, bool real)
QRect MultiScreenWorker::getDockShowGeometry(const QString &screenName, const Position &pos, const DisplayMode &displaymode, bool withoutScale)
{
//!!! 注意,目前双屏情况下缩放保持一致,不会出现两个屏幕的缩放不一致的情况,如果后面出现了,那么这里可能会有问题
const qreal scale = qApp->devicePixelRatio();
QRect rect;
if (real) {//后端真实大小
if (withoutScale) {//后端真实大小
foreach (Monitor *inter, validMonitorList(m_monitorInfo)) {
if (inter->name() == screenName) {
const int dockSize = int(displaymode == DisplayMode::Fashion ? m_dockInter->windowSizeFashion() : m_dockInter->windowSizeEfficient()) * scale;
@ -1397,12 +1418,12 @@ QRect MultiScreenWorker::getDockShowGeometry(const QString &screenName, const Po
return rect;
}
QRect MultiScreenWorker::getDockHideGeometry(const QString &screenName, const Position &pos, const DisplayMode &displaymode, bool real)
QRect MultiScreenWorker::getDockHideGeometry(const QString &screenName, const Position &pos, const DisplayMode &displaymode, bool withoutScale)
{
//!!! 注意,目前双屏情况下缩放保持一致,不会出现两个屏幕的缩放不一致的情况,如果后面出现了,那么这里可能会有问题
const qreal scale = qApp->devicePixelRatio();
QRect rect;
if (real) {//后端真实大小
if (withoutScale) {//后端真实大小
foreach (Monitor *inter, validMonitorList(m_monitorInfo)) {
if (inter->name() == screenName) {
const int margin = (displaymode == DisplayMode::Fashion ? WINDOWMARGIN : 0);

View File

@ -169,7 +169,7 @@ public:
* @param displayMode
* @return
*/
QRect realDockRect(const QString &screenName, const Position &pos, const HideMode &hideMode, const DisplayMode &displayMode);
QRect dockRectWithoutScale(const QString &screenName, const Position &pos, const HideMode &hideMode, const DisplayMode &displayMode);
signals:
void opacityChanged(const quint8 value) const;
@ -183,6 +183,7 @@ signals:
void requestUpdateLayout(); // 界面需要根据任务栏更新布局的方向
void requestUpdateDragArea(); // 更新拖拽区域
void requestUpdateMonitorInfo(); // 屏幕信息发生变化,需要更新任务栏大小,拖拽区域,所在屏幕,监控区域,通知窗管,通知后端,
void requestDelayShowDock(const QString &screenName); // 延时唤醒任务栏
public slots:
void onAutoHideChanged(bool autoHide);
@ -213,6 +214,7 @@ private slots:
void primaryScreenChanged();
void updateParentGeometry(const QVariant &value, const Position &pos);
void updateParentGeometry(const QVariant &value);
void delayShowDock();
// 任务栏属性变化
void onPositionChanged();
@ -235,6 +237,7 @@ private slots:
void onRequestNotifyWindowManager();
void onRequestUpdatePosition(const Position &fromPos, const Position &toPos);
void onRequestUpdateMonitorInfo();
void onRequestDelayShowDock(const QString &screenName);
void updateMonitorDockedInfo();
@ -287,8 +290,8 @@ private:
* @param real ,false为计算,true为不计算(.,)
* @return
*/
QRect getDockShowGeometry(const QString &screenName, const Position &pos, const DisplayMode &displaymode, bool real = false);
QRect getDockHideGeometry(const QString &screenName, const Position &pos, const DisplayMode &displaymode, bool real = false);
QRect getDockShowGeometry(const QString &screenName, const Position &pos, const DisplayMode &displaymode, bool withoutScale = false);
QRect getDockHideGeometry(const QString &screenName, const Position &pos, const DisplayMode &displaymode, bool withoutScale = false);
Monitor *monitorByName(const QList<Monitor *> &list, const QString &screenName);
QScreen *screenByName(const QString &screenName);
@ -317,6 +320,7 @@ private:
// update monitor info
QTimer *m_monitorUpdateTimer;
QTimer *m_delayTimer; // sp3需求,切换屏幕显示延时2秒唤起任务栏
// animation
QVariantAnimation *m_showAni;
@ -340,13 +344,13 @@ private:
int m_screenRawWidth;
QString m_registerKey;
QString m_extralRegisterKey;
QString m_leaveRegisterKey;
bool m_aniStart; // changeDockPosition是否正在运行中
bool m_draging; // 鼠标是否正在调整任务栏的宽度或高度
bool m_autoHide; // 和MenuWorker保持一致,为false时表示菜单已经打开
bool m_btnPress; // 鼠标按下时移动到唤醒区域不应该响应唤醒
QList<MonitRect> m_monitorRectList; // 监听唤起任务栏区域
QList<MonitRect> m_extralRectList; // 任务栏外部区域,随m_monitorRectList一起更新
QString m_delayScreen; // 任务栏将要切换到的屏幕名
/*****************************************************************/
};