mirror of
https://github.com/linuxdeepin/dde-dock.git
synced 2025-06-02 15:45:21 +00:00
refactor: 去除对后端Display服务的依赖
后端服务数据变化有快有慢,可能导致任务栏不正确时间进行响应,从而导致显示异常,对应的单元测试代码已添加 Log: 重构显示逻辑,保障任务栏显示正常 Change-Id: I62f06c133945a625c2c2ec2b2e21809be27543b6
This commit is contained in:
parent
3aa4308644
commit
1e3d90f62b
@ -55,6 +55,7 @@ include_directories(
|
||||
frame/controller
|
||||
frame/dbus
|
||||
frame/dbus/sni
|
||||
frame/display
|
||||
frame/item
|
||||
frame/item/components
|
||||
frame/item/resources
|
||||
@ -68,6 +69,7 @@ aux_source_directory(frame/accessible ACCESSIBLE)
|
||||
aux_source_directory(frame/controller CONTROLLER)
|
||||
aux_source_directory(frame/dbus DBUS)
|
||||
aux_source_directory(frame/dbus/sni SNI)
|
||||
aux_source_directory(frame/display DISPLAY)
|
||||
aux_source_directory(frame/item ITEM)
|
||||
aux_source_directory(frame/item/components COMPONENTS)
|
||||
aux_source_directory(frame/item/resources RESOURCES)
|
||||
@ -80,6 +82,7 @@ file(GLOB SRC_PATH
|
||||
${CONTROLLER}
|
||||
${DBUS}
|
||||
${SNI}
|
||||
${DISPLAY}
|
||||
${ITEM}
|
||||
${COMPONENTS}
|
||||
${UTIL}
|
||||
|
@ -39,6 +39,7 @@ target_include_directories(${BIN_NAME} PUBLIC
|
||||
accessible
|
||||
controller
|
||||
dbus
|
||||
display
|
||||
item
|
||||
item/components
|
||||
util
|
||||
|
307
frame/display/displaymanager.cpp
Normal file
307
frame/display/displaymanager.cpp
Normal file
@ -0,0 +1,307 @@
|
||||
/*
|
||||
* Copyright (C) 2018 ~ 2028 Uniontech Technology Co., Ltd.
|
||||
*
|
||||
* Author: fanpengcheng <fanpengcheng@uniontech.com>
|
||||
*
|
||||
* Maintainer: fanpengcheng <fanpengcheng@uniontech.com>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "displaymanager.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <QScreen>
|
||||
#include <QApplication>
|
||||
#include <QDBusConnection>
|
||||
#include <QDesktopWidget>
|
||||
|
||||
DisplayManager::DisplayManager(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_display(new DisplayInter("com.deepin.daemon.Display", "/com/deepin/daemon/Display", QDBusConnection::sessionBus(), this))
|
||||
, m_delayTimer(new QTimer(this))
|
||||
, m_gsettings(Utils::SettingsPtr("com.deepin.dde.dock.mainwindow", "/com/deepin/dde/dock/mainwindow/", this))
|
||||
, m_onlyInPrimary(Utils::SettingValue("com.deepin.dde.dock.mainwindow", "/com/deepin/dde/dock/mainwindow/", "onlyShowPrimary", false).toBool())
|
||||
{
|
||||
connect(qApp, &QApplication::primaryScreenChanged, this, &DisplayManager::primaryScreenChanged);
|
||||
connect(QApplication::desktop(), &QDesktopWidget::screenCountChanged, this, &DisplayManager::screenCountChanged);
|
||||
connect(m_delayTimer, &QTimer::timeout, this, [ = ] {
|
||||
updateScreenDockInfo();
|
||||
|
||||
#ifdef QT_DEBUG
|
||||
qInfo() << m_screenPositionMap;
|
||||
#endif
|
||||
|
||||
Q_EMIT screenInfoChanged();
|
||||
});
|
||||
if (m_gsettings)
|
||||
connect(m_gsettings, &QGSettings::changed, this, &DisplayManager::onGSettingsChanged);
|
||||
|
||||
m_delayTimer->setInterval(10);
|
||||
m_delayTimer->setSingleShot(true);
|
||||
|
||||
screenCountChanged();
|
||||
updateScreenDockInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DisplayManager::screens
|
||||
* @return 返回当前可用的QScreen指针列表
|
||||
*/
|
||||
QList<QScreen *> DisplayManager::screens() const
|
||||
{
|
||||
return m_screens;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DisplayManager::screen
|
||||
* @param screenName
|
||||
* @return 根据screenName参数找到对应的QScreen指针返回,否则返回nullptr
|
||||
*/
|
||||
QScreen *DisplayManager::screen(const QString &screenName) const
|
||||
{
|
||||
for (auto s : m_screens) {
|
||||
if (s->name() == screenName)
|
||||
return s;
|
||||
}
|
||||
|
||||
qWarning() << "Screen: " << screenName << " can`t be found!";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DisplayManager::primary
|
||||
* @return 主屏幕名称
|
||||
*/
|
||||
QString DisplayManager::primary() const
|
||||
{
|
||||
return qApp->primaryScreen() ? qApp->primaryScreen()->name() : QString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Display::screenWidth
|
||||
* @return 所有屏幕逻辑宽度之和
|
||||
*/
|
||||
int DisplayManager::screenRawWidth() const
|
||||
{
|
||||
int width = 0;
|
||||
for (auto s : m_screens) {
|
||||
width = qMax(width, s->geometry().x() + int(s->geometry().width() * s->devicePixelRatio()));
|
||||
}
|
||||
|
||||
return width;
|
||||
}
|
||||
/**
|
||||
* @brief Display::screenHeight
|
||||
* @return 所有屏幕逻辑高度之和
|
||||
*/
|
||||
|
||||
int DisplayManager::screenRawHeight() const
|
||||
{
|
||||
int height = 0;
|
||||
for (auto s : m_screens) {
|
||||
height = qMax(height, s->geometry().y() + int(s->geometry().height() * s->devicePixelRatio()));
|
||||
}
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DisplayManager::canDock
|
||||
* @param s QScreen指针
|
||||
* @param pos 任务栏位置(上下左右)
|
||||
* @return 判断当前s屏幕上pos位置任务栏位置是否允许停靠
|
||||
*/
|
||||
bool DisplayManager::canDock(QScreen *s, Position pos) const
|
||||
{
|
||||
return s ? m_screenPositionMap[s].value(pos) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DisplayManager::updateScreenDockInfo
|
||||
* 更新屏幕停靠信息
|
||||
*/
|
||||
void DisplayManager::updateScreenDockInfo()
|
||||
{
|
||||
// TODO 目前仅仅支持双屏,如果超过双屏,会出现异常,这里可以考虑做成通用的处理规则
|
||||
|
||||
// 先清除原先的数据,然后再更新
|
||||
m_screenPositionMap.clear();
|
||||
|
||||
if (m_screens.isEmpty())
|
||||
return;
|
||||
|
||||
// reset map
|
||||
for (auto s : m_screens) {
|
||||
QMap <Position, bool> map;
|
||||
map.insert(Position::Top, true);
|
||||
map.insert(Position::Bottom, true);
|
||||
map.insert(Position::Left, true);
|
||||
map.insert(Position::Right, true);
|
||||
m_screenPositionMap.insert(s, map);
|
||||
}
|
||||
|
||||
// 仅显示在主屏时的处理
|
||||
if (m_onlyInPrimary) {
|
||||
for (auto s : m_screens) {
|
||||
if (s != qApp->primaryScreen()) {
|
||||
QMap <Position, bool> map;
|
||||
map.insert(Position::Top, false);
|
||||
map.insert(Position::Bottom, false);
|
||||
map.insert(Position::Left, false);
|
||||
map.insert(Position::Right, false);
|
||||
m_screenPositionMap.insert(s, map);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_screens.size() == 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 最多支持双屏,这里只计算双屏,单屏默认四边均可停靠任务栏
|
||||
if (m_screens.size() == 2) {
|
||||
QRect s0 = m_screens.at(0)->geometry();
|
||||
s0.setSize(s0.size() * m_screens.at(0)->devicePixelRatio());
|
||||
QRect s1 = m_screens.at(1)->geometry();
|
||||
s1.setSize(s1.size() * m_screens.at(1)->devicePixelRatio());
|
||||
|
||||
qInfo() << "monitor info changed" << m_screens.at(0)->name() << s0 << m_screens.at(1)->name() << s1;
|
||||
|
||||
int s0top = s0.y();
|
||||
int s0bottom = s0.y() + s0.height();
|
||||
int s0left = s0.x();
|
||||
int s0Right = s0.x() + s0.width();
|
||||
|
||||
int s1top = s1.y();
|
||||
int s1bottom = s1.y() + s1.height();
|
||||
int s1left = s1.x();
|
||||
int s1Right = s1.x() + s1.width();
|
||||
|
||||
QPoint s0topLeft = QPoint(s0.x(), s0.y());
|
||||
QPoint s0topRight = QPoint(s0.x()+ s0.width(), s0.y());
|
||||
QPoint s0bottomRight = QPoint(s0.x()+ s0.width(), s0.y() + s0.height());
|
||||
QPoint s0bottomLeft = QPoint(s0.x(), s0.y() + s0.height());
|
||||
|
||||
QPoint s1topLeft = QPoint(s1.x(), s1.y());
|
||||
QPoint s1topRight = QPoint(s1.x() + s1.width(), s1.y());
|
||||
QPoint s1bottomRight = QPoint(s1.x() + s1.width(), s1.y() + s1.height());
|
||||
QPoint s1bottomLeft = QPoint(s1.x(), s1.y() + s1.height());
|
||||
|
||||
// 对角拼接,重置,默认均可停靠
|
||||
if (s0bottomRight == s1topLeft
|
||||
|| s0topRight == s1bottomRight) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 左右拼接,s0左,s1右
|
||||
if (s0Right == s1left
|
||||
&& (s0topRight == s1topLeft || s0bottomRight == s1bottomLeft)) {
|
||||
m_screenPositionMap[m_screens.at(0)].insert(Position::Right, false);
|
||||
m_screenPositionMap[m_screens.at(1)].insert(Position::Left, false);
|
||||
return;
|
||||
}
|
||||
|
||||
// 左右拼接,s0右,s1左
|
||||
if (s0left== s1Right
|
||||
&& (s0topRight == s1topRight || s0bottomLeft == s1bottomRight)) {
|
||||
m_screenPositionMap[m_screens.at(0)].insert(Position::Left, false);
|
||||
m_screenPositionMap[m_screens.at(1)].insert(Position::Right, false);
|
||||
return;
|
||||
}
|
||||
|
||||
// 上下拼接,s0上,s1下
|
||||
if (s0bottom == s1top
|
||||
&& (s0bottomLeft == s1topLeft || s0bottomRight == s1topRight)) {
|
||||
m_screenPositionMap[m_screens.at(0)].insert(Position::Bottom, false);
|
||||
m_screenPositionMap[m_screens.at(1)].insert(Position::Top, false);
|
||||
return;
|
||||
}
|
||||
|
||||
// 上下拼接,s0下,s1上
|
||||
if (s0top == s1bottom
|
||||
&& (s0topLeft == s1bottomLeft || s0topRight == s1bottomRight)) {
|
||||
m_screenPositionMap[m_screens.at(0)].insert(Position::Top, false);
|
||||
m_screenPositionMap[m_screens.at(1)].insert(Position::Bottom, false);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 目前不支持链接超过两个以上的显示器
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DisplayManager::screenCountChanged
|
||||
* 屏幕数量发生变化时,此函数应被调用,更新屏幕相关信息
|
||||
* @note 除初始化时需要手动调用一次外,其他时间会自动被调用
|
||||
*/
|
||||
void DisplayManager::screenCountChanged()
|
||||
{
|
||||
// 找到过期的screen指针
|
||||
QList<QScreen *> to_remove_list;
|
||||
for (auto s : m_screens) {
|
||||
if (!qApp->screens().contains(s))
|
||||
to_remove_list.append(s);
|
||||
}
|
||||
|
||||
// 找出新增的screen指针
|
||||
QList<QScreen *> to_add_list;
|
||||
for (auto s : qApp->screens()) {
|
||||
if (!m_screens.contains(s)) {
|
||||
to_add_list.append(s);
|
||||
}
|
||||
}
|
||||
|
||||
// 取消关联
|
||||
for (auto s : to_remove_list) {
|
||||
disconnect(s);
|
||||
m_screens.removeOne(s);
|
||||
}
|
||||
|
||||
// 创建关联
|
||||
for (auto s : to_add_list) {
|
||||
s->setOrientationUpdateMask(Qt::PrimaryOrientation
|
||||
| Qt::LandscapeOrientation
|
||||
| Qt::PortraitOrientation
|
||||
| Qt::InvertedLandscapeOrientation
|
||||
| Qt::InvertedPortraitOrientation);
|
||||
|
||||
connect(s, &QScreen::geometryChanged, m_delayTimer, static_cast<void (QTimer::*)()>(&QTimer::start));
|
||||
connect(s, &QScreen::primaryOrientationChanged, m_delayTimer, static_cast<void (QTimer::*)()>(&QTimer::start));
|
||||
connect(s, &QScreen::orientationChanged, m_delayTimer, static_cast<void (QTimer::*)()>(&QTimer::start));
|
||||
|
||||
m_screens.append(s);
|
||||
}
|
||||
|
||||
// 屏幕数量发生变化,应该刷新一下任务栏的显示
|
||||
m_delayTimer->start();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DisplayManager::onGSettingsChanged
|
||||
* @param key
|
||||
* 监听onlyShowPrimary配置的变化,此时有变化时应该刷新一下任务栏的显示信息
|
||||
*/
|
||||
void DisplayManager::onGSettingsChanged(const QString &key)
|
||||
{
|
||||
if (key == "onlyShowPrimary") {
|
||||
m_onlyInPrimary = Utils::SettingValue("com.deepin.dde.dock.mainwindow", "/com/deepin/dde/dock/mainwindow/", "onlyShowPrimary", false).toBool();
|
||||
|
||||
updateScreenDockInfo();
|
||||
|
||||
m_delayTimer->start();
|
||||
}
|
||||
}
|
75
frame/display/displaymanager.h
Normal file
75
frame/display/displaymanager.h
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2018 ~ 2028 Uniontech Technology Co., Ltd.
|
||||
*
|
||||
* Author: fanpengcheng <fanpengcheng@uniontech.com>
|
||||
*
|
||||
* Maintainer: fanpengcheng <fanpengcheng@uniontech.com>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DISPLAYMANAGER_H
|
||||
#define DISPLAYMANAGER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "singleton.h"
|
||||
#include "constants.h"
|
||||
|
||||
#include <com_deepin_dde_daemon_dock.h>
|
||||
#include <com_deepin_daemon_display.h>
|
||||
#include <com_deepin_daemon_display_monitor.h>
|
||||
|
||||
using DisplayInter = com::deepin::daemon::Display;
|
||||
using namespace Dock;
|
||||
|
||||
class QScreen;
|
||||
class QTimer;
|
||||
class QGSettings;
|
||||
class DisplayManager: public QObject, public Singleton<DisplayManager>
|
||||
{
|
||||
Q_OBJECT
|
||||
friend class Singleton<DisplayManager>;
|
||||
|
||||
public:
|
||||
explicit DisplayManager(QObject *parent = Q_NULLPTR);
|
||||
|
||||
QList<QScreen *> screens() const;
|
||||
QScreen *screen(const QString &screenName) const;
|
||||
QString primary() const;
|
||||
int screenRawWidth() const;
|
||||
int screenRawHeight() const;
|
||||
bool canDock(QScreen *s, Position pos) const;
|
||||
|
||||
private:
|
||||
void updateScreenDockInfo();
|
||||
|
||||
private Q_SLOTS:
|
||||
void screenCountChanged();
|
||||
void onGSettingsChanged(const QString &key);
|
||||
|
||||
Q_SIGNALS:
|
||||
void primaryScreenChanged();
|
||||
void screenInfoChanged(); // 屏幕信息发生变化,需要调整任务栏显示,只需要这一个信号,其他的都不要,简化流程
|
||||
|
||||
private:
|
||||
DisplayInter *m_display;
|
||||
QTimer *m_delayTimer;
|
||||
QList <QScreen *> m_screens;
|
||||
QMap <QScreen *, QMap <Position, bool>> m_screenPositionMap;
|
||||
const QGSettings *m_gsettings; // 多屏配置控制
|
||||
bool m_onlyInPrimary;
|
||||
};
|
||||
|
||||
#endif // DISPLAYMANAGER_H
|
@ -139,7 +139,7 @@ void PreviewContainer::adjustSize()
|
||||
|
||||
if (composite) {
|
||||
// 3D
|
||||
const QRect r = qApp->primaryScreen()->geometry();
|
||||
const QRect r = qApp->primaryScreen() ? qApp->primaryScreen()->geometry() : QRect();
|
||||
const int padding = 20;
|
||||
|
||||
const bool horizontal = m_windowListLayout->direction() == QBoxLayout::LeftToRight;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -64,108 +64,6 @@ class QTimer;
|
||||
class MainWindow;
|
||||
class QGSettings;
|
||||
|
||||
/**
|
||||
* @brief The MonitorInfo class
|
||||
* 保存显示器信息
|
||||
*/
|
||||
class MonitorInfo : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MonitorInfo() {}
|
||||
|
||||
/**
|
||||
* @brief data
|
||||
* @return 所有的显示器信息
|
||||
*/
|
||||
inline QMap<Monitor *, MonitorInter *> data() {return m_monitorInfo;}
|
||||
|
||||
/**
|
||||
* @brief validMonitor
|
||||
* @return 返回一个列表,包含所有可用的显示器
|
||||
*/
|
||||
const QList<Monitor *> validMonitor()
|
||||
{
|
||||
QList<Monitor *> list;
|
||||
QMapIterator<Monitor *, MonitorInter *>it(m_monitorInfo);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
// 仅显示在主屏的情况下,可用屏幕信息只提供主屏幕(m_primary有可能不是主屏幕的名字,数据还没来得及切换过来)
|
||||
// 问题场景:连接双屏,设置任务栏仅显示在主屏(gsettings),然后拔掉主屏幕显示器,任务栏崩溃
|
||||
if (it.key()->enable()) {
|
||||
if (m_showInPrimary) {
|
||||
if (it.key()->name() == m_primary) {
|
||||
list.clear();
|
||||
list.append(it.key());
|
||||
return list;
|
||||
}
|
||||
|
||||
if (!list.isEmpty()) {
|
||||
list.removeAt(0);
|
||||
list.push_front(it.key());
|
||||
} else
|
||||
list << it.key();
|
||||
} else
|
||||
list << it.key();
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
/**
|
||||
* @brief insert 插入新的屏幕信息
|
||||
* @param mon 插入的屏幕信息
|
||||
* @param monInter 插入的屏幕对应的dbus指针
|
||||
*/
|
||||
void insert(Monitor *mon, MonitorInter *monInter)
|
||||
{
|
||||
m_monitorInfo.insert(mon, monInter);
|
||||
|
||||
Q_EMIT monitorChanged();
|
||||
}
|
||||
/**
|
||||
* @brief remove 删除显示其信息
|
||||
* @param mon 待删除的数据
|
||||
*/
|
||||
void remove(Monitor *mon)
|
||||
{
|
||||
m_monitorInfo.value(mon)->deleteLater();
|
||||
m_monitorInfo.remove(mon);
|
||||
mon->deleteLater();
|
||||
|
||||
Q_EMIT monitorChanged();
|
||||
}
|
||||
/**
|
||||
* @brief setShowInPrimary 设置仅显示在主屏
|
||||
* @param showIn
|
||||
*/
|
||||
void setShowInPrimary(const bool &showIn)
|
||||
{
|
||||
if (m_showInPrimary != showIn)
|
||||
m_showInPrimary = showIn;
|
||||
}
|
||||
/**
|
||||
* @brief setPrimary 记录一下主屏信息
|
||||
* @param primary
|
||||
*/
|
||||
void setPrimary(const QString &primary)
|
||||
{
|
||||
if (m_primary != primary)
|
||||
m_primary = primary;
|
||||
}
|
||||
|
||||
signals:
|
||||
/**
|
||||
* @brief monitorChanged 显示器信息发生变化
|
||||
*/
|
||||
void monitorChanged();
|
||||
|
||||
private:
|
||||
QMap<Monitor *, MonitorInter *> m_monitorInfo;
|
||||
QString m_primary;
|
||||
bool m_showInPrimary = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The DockScreen class
|
||||
* 保存任务栏的屏幕信息
|
||||
@ -258,7 +156,7 @@ signals:
|
||||
public slots:
|
||||
void onAutoHideChanged(bool autoHide);
|
||||
void updateDaemonDockSize(int dockSize);
|
||||
void onDragStateChanged(bool draging);
|
||||
void onRequestUpdateRegionMonitor();
|
||||
void handleDbusSignal(QDBusMessage);
|
||||
|
||||
private slots:
|
||||
@ -266,11 +164,6 @@ private slots:
|
||||
void onRegionMonitorChanged(int x, int y, const QString &key);
|
||||
void onExtralRegionMonitorChanged(int x, int y, const QString &key);
|
||||
|
||||
// Display Monitor
|
||||
void onMonitorListChanged(const QList<QDBusObjectPath> &mons);
|
||||
void monitorAdded(const QString &path);
|
||||
void monitorRemoved(const QString &path);
|
||||
|
||||
// Animation
|
||||
void showAniFinished();
|
||||
void hideAniFinished();
|
||||
@ -288,8 +181,6 @@ private slots:
|
||||
void onHideStateChanged();
|
||||
void onOpacityChanged(const double value);
|
||||
|
||||
void onRequestUpdateRegionMonitor();
|
||||
|
||||
// 通知后端任务栏所在位置
|
||||
void onRequestUpdateFrontendGeometry();
|
||||
|
||||
@ -298,26 +189,13 @@ private slots:
|
||||
void onRequestUpdateMonitorInfo();
|
||||
void onRequestDelayShowDock(const QString &screenName);
|
||||
|
||||
void updateMonitorDockedInfo();
|
||||
/**
|
||||
* @brief updatePrimaryDisplayRotation
|
||||
* 更新主屏幕的方向
|
||||
*/
|
||||
void updatePrimaryDisplayRotation();
|
||||
|
||||
void onTouchPress(int type, int x, int y, const QString &key);
|
||||
void onTouchRelease(int type, int x, int y, const QString &key);
|
||||
|
||||
// gsetting配置改变响应槽
|
||||
void onGSettingsChange(const QString &changeKey);
|
||||
|
||||
Monitor *waitAndGetScreen(const QString& screenName);
|
||||
|
||||
private:
|
||||
MainWindow *parent();
|
||||
// 初始化数据信息
|
||||
void initMembers();
|
||||
void initGSettingConfig();
|
||||
void initDBus();
|
||||
void initConnection();
|
||||
void initUI();
|
||||
@ -335,20 +213,14 @@ private:
|
||||
void resetDockScreen();
|
||||
|
||||
void checkDaemonDockService();
|
||||
void checkDaemonDisplayService();
|
||||
void checkXEventMonitorService();
|
||||
|
||||
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);
|
||||
bool onScreenEdge(const QString &screenName, const QPoint &point);
|
||||
bool onScreenEdge(const QPoint &point);
|
||||
bool contains(const MonitRect &rect, const QPoint &pos);
|
||||
bool contains(const QList<MonitRect> &rectList, const QPoint &pos);
|
||||
const QPoint rawXPosition(const QPoint &scaledPos);
|
||||
void updateScreenSize();
|
||||
|
||||
private:
|
||||
QWidget *m_parent;
|
||||
@ -361,17 +233,13 @@ private:
|
||||
|
||||
// DBus interface
|
||||
DBusDock *m_dockInter;
|
||||
DisplayInter *m_displayInter;
|
||||
DBusLuncher *m_launcherInter;
|
||||
|
||||
// update monitor info
|
||||
QTimer *m_monitorUpdateTimer;
|
||||
QTimer *m_delayWakeTimer; // sp3需求,切换屏幕显示延时,默认2秒唤起任务栏
|
||||
|
||||
const QGSettings *m_gsettings; // 多屏配置控制
|
||||
|
||||
DockScreen m_ds; // 屏幕名称信息
|
||||
MonitorInfo m_mtrInfo; // 显示器信息
|
||||
|
||||
// 任务栏属性
|
||||
double m_opacity;
|
||||
@ -380,19 +248,13 @@ private:
|
||||
HideState m_hideState;
|
||||
DisplayMode m_displayMode;
|
||||
|
||||
int m_monitorRotation; //当前屏幕的方向
|
||||
RotationList m_rotations; // 当前屏幕的所有方向,逆时针旋转(向下,向右,向上,向左)
|
||||
|
||||
/***************不和其他流程产生交互,尽量不要动这里的变量***************/
|
||||
int m_screenRawHeight;
|
||||
int m_screenRawWidth;
|
||||
QString m_registerKey;
|
||||
QString m_extralRegisterKey;
|
||||
QString m_touchRegisterKey; // 触控屏唤起任务栏监控区域key
|
||||
bool m_showAniStart; // 动画显示过程正在执行标志
|
||||
bool m_hideAniStart; // 动画隐藏过程正在执行标志
|
||||
bool m_aniStart; // changeDockPosition是否正在运行中
|
||||
bool m_draging; // 鼠标是否正在调整任务栏的宽度或高度
|
||||
bool m_autoHide; // 和MenuWorker保持一致,为false时表示菜单已经打开
|
||||
bool m_btnPress; // 鼠标按下时移动到唤醒区域不应该响应唤醒
|
||||
bool m_touchPress; // 触屏按下
|
||||
|
31
frame/util/singleton.h
Normal file
31
frame/util/singleton.h
Normal file
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Copyright (C) 2016 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
#include <memory>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <class T>
|
||||
class Singleton
|
||||
{
|
||||
public:
|
||||
static inline T *instance() {
|
||||
static T* _instance = new T;
|
||||
return _instance;
|
||||
}
|
||||
|
||||
protected:
|
||||
Singleton(void) {}
|
||||
~Singleton(void) {}
|
||||
Singleton(const Singleton &) {}
|
||||
Singleton &operator= (const Singleton &) {}
|
||||
};
|
||||
|
||||
|
@ -52,6 +52,8 @@
|
||||
#define MAINWINDOW_MIN_SIZE (40)
|
||||
#define DRAG_AREA_SIZE (5)
|
||||
|
||||
#define DRAG_STATE_PROP "DRAG_STATE"
|
||||
|
||||
using org::kde::StatusNotifierWatcher;
|
||||
using DBusDock = com::deepin::dde::daemon::Dock;
|
||||
|
||||
@ -88,6 +90,7 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
, m_sniWatcher(new StatusNotifierWatcher(SNI_WATCHER_SERVICE, SNI_WATCHER_PATH, QDBusConnection::sessionBus(), this))
|
||||
, m_dragWidget(new DragWidget(this))
|
||||
, m_launched(false)
|
||||
, m_updateDragAreaTimer(new QTimer(this))
|
||||
{
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
setAttribute(Qt::WA_X11DoNotAcceptFocus);
|
||||
@ -115,6 +118,7 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
|
||||
m_mainPanel->setDisplayMode(m_multiScreenWorker->displayMode());
|
||||
|
||||
initMember();
|
||||
initSNIHost();
|
||||
initComponents();
|
||||
initConnections();
|
||||
@ -241,10 +245,16 @@ void MainWindow::mouseMoveEvent(QMouseEvent *e)
|
||||
void MainWindow::moveEvent(QMoveEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
|
||||
if (!qApp->property(DRAG_STATE_PROP).toBool())
|
||||
m_updateDragAreaTimer->start();
|
||||
}
|
||||
|
||||
void MainWindow::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
if (!qApp->property(DRAG_STATE_PROP).toBool())
|
||||
m_updateDragAreaTimer->start();
|
||||
|
||||
// 任务栏大小、位置、模式改变都会触发resize,发射大小改变信号,供依赖项目更新位置
|
||||
Q_EMIT panelGeometryChanged();
|
||||
|
||||
@ -259,6 +269,12 @@ void MainWindow::dragEnterEvent(QDragEnterEvent *e)
|
||||
QWidget::dragEnterEvent(e);
|
||||
}
|
||||
|
||||
void MainWindow::initMember()
|
||||
{
|
||||
m_updateDragAreaTimer->setInterval(100);
|
||||
m_updateDragAreaTimer->setSingleShot(true);
|
||||
}
|
||||
|
||||
void MainWindow::initSNIHost()
|
||||
{
|
||||
// registor dock as SNI Host on dbus
|
||||
@ -310,11 +326,17 @@ void MainWindow::initConnections()
|
||||
connect(m_mainPanel, &MainPanelControl::itemMoved, DockItemManager::instance(), &DockItemManager::itemMoved, Qt::DirectConnection);
|
||||
connect(m_mainPanel, &MainPanelControl::itemAdded, DockItemManager::instance(), &DockItemManager::itemAdded, Qt::DirectConnection);
|
||||
|
||||
connect(m_dragWidget, &DragWidget::dragPointOffset, m_multiScreenWorker, [ = ] {m_multiScreenWorker->onDragStateChanged(true);});
|
||||
connect(m_dragWidget, &DragWidget::dragFinished, m_multiScreenWorker, [ = ] {m_multiScreenWorker->onDragStateChanged(false);});
|
||||
// -拖拽任务栏改变高度或宽度-------------------------------------------------------------------------------
|
||||
connect(m_updateDragAreaTimer, &QTimer::timeout, this, &MainWindow::resetDragWindow);
|
||||
connect(m_updateDragAreaTimer, &QTimer::timeout, m_multiScreenWorker, &MultiScreenWorker::onRequestUpdateRegionMonitor);
|
||||
|
||||
|
||||
connect(m_dragWidget, &DragWidget::dragPointOffset, this, [ = ] { qApp->setProperty(DRAG_STATE_PROP, true); });
|
||||
connect(m_dragWidget, &DragWidget::dragFinished, this, [ = ] { qApp->setProperty(DRAG_STATE_PROP, false); });
|
||||
|
||||
connect(m_dragWidget, &DragWidget::dragPointOffset, this, &MainWindow::onMainWindowSizeChanged);
|
||||
connect(m_dragWidget, &DragWidget::dragFinished, this, &MainWindow::onDragFinished);
|
||||
connect(m_dragWidget, &DragWidget::dragFinished, this, &MainWindow::resetDragWindow); // 更新拖拽区域
|
||||
// ----------------------------------------------------------------------------------------------------
|
||||
|
||||
connect(DGuiApplicationHelper::instance(), &DGuiApplicationHelper::themeTypeChanged, this, &MainWindow::themeTypeChanged);
|
||||
|
||||
@ -325,9 +347,6 @@ void MainWindow::initConnections()
|
||||
|
||||
connect(m_multiScreenWorker, &MultiScreenWorker::requestUpdateDockEntry, DockItemManager::instance(), &DockItemManager::requestUpdateDockItem);
|
||||
|
||||
// 更新拖拽区域
|
||||
connect(m_multiScreenWorker, &MultiScreenWorker::requestUpdateDragArea, this, &MainWindow::resetDragWindow);
|
||||
|
||||
// 响应后端触控屏拖拽任务栏高度长按信号
|
||||
connect(TouchSignalManager::instance(), &TouchSignalManager::middleTouchPress, this, &MainWindow::touchRequestResizeDock);
|
||||
connect(TouchSignalManager::instance(), &TouchSignalManager::touchMove, m_dragWidget, [ this ]() {
|
||||
@ -463,28 +482,28 @@ void MainWindow::onMainWindowSizeChanged(QPoint offset)
|
||||
newRect.setWidth(rect.width());
|
||||
newRect.setHeight(qBound(MAINWINDOW_MIN_SIZE, rect.height() + offset.y(), MAINWINDOW_MAX_SIZE));
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case Bottom: {
|
||||
newRect.setX(rect.x());
|
||||
newRect.setY(rect.y() + rect.height() - qBound(MAINWINDOW_MIN_SIZE, rect.height() - offset.y(), MAINWINDOW_MAX_SIZE));
|
||||
newRect.setWidth(rect.width());
|
||||
newRect.setHeight(qBound(MAINWINDOW_MIN_SIZE, rect.height() - offset.y(), MAINWINDOW_MAX_SIZE));
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case Left: {
|
||||
newRect.setX(rect.x());
|
||||
newRect.setY(rect.y());
|
||||
newRect.setWidth(qBound(MAINWINDOW_MIN_SIZE, rect.width() + offset.x(), MAINWINDOW_MAX_SIZE));
|
||||
newRect.setHeight(rect.height());
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case Right: {
|
||||
newRect.setX(rect.x() + rect.width() - qBound(MAINWINDOW_MIN_SIZE, rect.width() - offset.x(), MAINWINDOW_MAX_SIZE));
|
||||
newRect.setY(rect.y());
|
||||
newRect.setWidth(qBound(MAINWINDOW_MIN_SIZE, rect.width() - offset.x(), MAINWINDOW_MAX_SIZE));
|
||||
newRect.setHeight(rect.height());
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
// 更新界面大小
|
||||
@ -493,12 +512,6 @@ void MainWindow::onMainWindowSizeChanged(QPoint offset)
|
||||
move(newRect.topLeft());
|
||||
}
|
||||
|
||||
void MainWindow::onDragFinished()
|
||||
{
|
||||
qDebug() << "drag finished";
|
||||
resetDragWindow();
|
||||
}
|
||||
|
||||
void MainWindow::themeTypeChanged(DGuiApplicationHelper::ColorType themeType)
|
||||
{
|
||||
if (m_wmHelper->hasComposite()) {
|
||||
@ -569,19 +582,19 @@ void MainWindow::sendNotifications()
|
||||
hints["x-deepin-action-reload"] = QString("dbus-send,--session,--dest=com.deepin.dde.Dock,--print-reply,/com/deepin/dde/Dock,com.deepin.dde.Dock.ReloadPlugins");
|
||||
QTimer::singleShot(0, this, [=] {
|
||||
DDBusSender()
|
||||
.service("com.deepin.dde.Notification")
|
||||
.path("/com/deepin/dde/Notification")
|
||||
.interface("com.deepin.dde.Notification")
|
||||
.method(QString("Notify"))
|
||||
.arg(QString("dde-control-center")) // appname
|
||||
.arg(static_cast<uint>(0)) // id
|
||||
.arg(QString("preferences-system")) // icon
|
||||
.arg(QString(tr("Dock - Safe Mode"))) // summary
|
||||
.arg(QString(tr("The Dock is in safe mode, please exit to show it properly"))) // content
|
||||
.arg(actionButton) // actions
|
||||
.arg(hints) // hints
|
||||
.arg(15000) // timeout
|
||||
.call();
|
||||
.service("com.deepin.dde.Notification")
|
||||
.path("/com/deepin/dde/Notification")
|
||||
.interface("com.deepin.dde.Notification")
|
||||
.method(QString("Notify"))
|
||||
.arg(QString("dde-control-center")) // appname
|
||||
.arg(static_cast<uint>(0)) // id
|
||||
.arg(QString("preferences-system")) // icon
|
||||
.arg(QString(tr("Dock - Safe Mode"))) // summary
|
||||
.arg(QString(tr("The Dock is in safe mode, please exit to show it properly"))) // content
|
||||
.arg(actionButton) // actions
|
||||
.arg(hints) // hints
|
||||
.arg(15000) // timeout
|
||||
.call();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -145,6 +145,7 @@ private:
|
||||
void moveEvent(QMoveEvent *event) override;
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
void initMember();
|
||||
void initSNIHost();
|
||||
void initComponents();
|
||||
void initConnections();
|
||||
@ -156,7 +157,7 @@ signals:
|
||||
void panelGeometryChanged();
|
||||
|
||||
public slots:
|
||||
void resetDragWindow();
|
||||
void resetDragWindow(); // 任务栏调整高度或宽度后需调用此函数
|
||||
|
||||
private slots:
|
||||
void compositeChanged();
|
||||
@ -164,7 +165,6 @@ private slots:
|
||||
|
||||
void onDbusNameOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner);
|
||||
void onMainWindowSizeChanged(QPoint offset);
|
||||
void onDragFinished();
|
||||
void themeTypeChanged(DGuiApplicationHelper::ColorType themeType);
|
||||
void touchRequestResizeDock();
|
||||
|
||||
@ -184,6 +184,8 @@ private:
|
||||
bool m_launched;
|
||||
QString m_registerKey;
|
||||
QStringList m_registerKeys;
|
||||
|
||||
QTimer *m_updateDragAreaTimer;
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
@ -6,7 +6,7 @@ lcov -c -i -d ./ -o init.info
|
||||
./dde_dock_unit_test
|
||||
lcov -c -d ./ -o cover.info
|
||||
lcov -a init.info -a cover.info -o total.info
|
||||
lcov --remove total.info '*/usr/include/*' '*/usr/lib/*' '*/usr/lib64/*' '*/usr/local/include/*' '*/usr/local/lib/*' '*/usr/local/lib64/*' '*/third/*' 'testa.cpp' '*/unittest/dde_dock_unit_test_autogen/*' '*/dde-dock/frame/dbus/*' '*/dde-dock/interfaces/*' '*/dde-dock/unittest/*' -o final.info
|
||||
lcov --remove total.info '*/usr/include/*' '*/usr/lib/*' '*/usr/lib64/*' '*/usr/local/include/*' '*/usr/local/lib/*' '*/usr/local/lib64/*' '*/third/*' '*/tests/dde_dock_unit_test_autogen/*' '*/dde-dock/frame/dbus/*' '*/dde-dock/interfaces/*' '*/dde-dock/tests/*' -o final.info
|
||||
|
||||
# 生成报告
|
||||
genhtml -o cover_report --legend --title "lcov" --prefix=./ final.info
|
||||
|
@ -56,7 +56,7 @@ static QMap<QString, QMap<quint32, int>> AppWinidSuffixMap;
|
||||
|
||||
const QPoint rawXPosition(const QPoint &scaledPos)
|
||||
{
|
||||
QRect g = qApp->primaryScreen()->geometry();
|
||||
QRect g = qApp->primaryScreen() ? qApp->primaryScreen()->geometry() : QRect();
|
||||
for (auto *screen : qApp->screens())
|
||||
{
|
||||
const QRect &sg = screen->geometry();
|
||||
|
60
tests/display/ut_displaymanager.cpp
Normal file
60
tests/display/ut_displaymanager.cpp
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2018 ~ 2028 Uniontech Technology Co., Ltd.
|
||||
*
|
||||
* Author: fanpengcheng <fanpengcheng@uniontech.com>
|
||||
*
|
||||
* Maintainer: fanpengcheng <fanpengcheng@uniontech.com>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <QObject>
|
||||
#include <QThread>
|
||||
#include <QTest>
|
||||
#include <QScreen>
|
||||
#include <QSignalSpy>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#define private public
|
||||
#include "displaymanager.h"
|
||||
#undef private
|
||||
|
||||
using namespace ::testing;
|
||||
|
||||
class Test_DisplayManager : public ::testing::Test
|
||||
{
|
||||
};
|
||||
|
||||
TEST_F(Test_DisplayManager, method_test)
|
||||
{
|
||||
ASSERT_EQ(DisplayManager::instance()->screens().count(), qApp->screens().count());
|
||||
|
||||
for (auto s : qApp->screens()) {
|
||||
ASSERT_TRUE(DisplayManager::instance()->screen(s->name()));
|
||||
}
|
||||
|
||||
ASSERT_FALSE(DisplayManager::instance()->screen("testname"));
|
||||
|
||||
ASSERT_EQ(DisplayManager::instance()->primary(), qApp->primaryScreen() ? qApp->primaryScreen()->name() : QString());
|
||||
|
||||
// 第一次启动的时候,默认发出一次信号
|
||||
QSignalSpy spy(DisplayManager::instance(), &DisplayManager::screenInfoChanged);
|
||||
QTest::qWait(100);
|
||||
ASSERT_EQ(spy.count(), 1);
|
||||
}
|
||||
|
||||
TEST_F(Test_DisplayManager, coverage_test) // 提高覆盖率,还没想好怎么做这种
|
||||
{
|
||||
DisplayManager::instance()->onGSettingsChanged("onlyShowPrimary");
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user