refactor: 去除对后端Display服务的依赖

后端服务数据变化有快有慢,可能导致任务栏不正确时间进行响应,从而导致显示异常,对应的单元测试代码已添加

Log: 重构显示逻辑,保障任务栏显示正常
Change-Id: I62f06c133945a625c2c2ec2b2e21809be27543b6
This commit is contained in:
Fan PengCheng 2021-04-12 16:53:03 +08:00
parent 3aa4308644
commit 1e3d90f62b
14 changed files with 694 additions and 774 deletions

View File

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

View File

@ -39,6 +39,7 @@ target_include_directories(${BIN_NAME} PUBLIC
accessible
controller
dbus
display
item
item/components
util

View 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();
}
}

View 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

View File

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

View File

@ -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
View 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 &) {}
};

View File

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

View File

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

View File

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

View File

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

View 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");
}