dde-dock/frame/util/multiscreenworker.h
donghualin 1691e7188c fix: 任务栏代码结构优化解耦
原来的TrayManagerWindow的类是放到MainPanelWindow类里面作为它的一部分,导致窗管在显示的时候有很多问题
修改方案:
1、将左右侧区域拆分成两个窗体,让它们继承自相同的基类MainWindowBase。
2、左右区域公共的部分,例如圆角、展示区域、动画获取等,都在基类中实现或者通过接口返回
3、增加WindowManager类,管理所有的界面,WindowManager类无需知道具体子类的指针,只需要根据相应的接口来获取即可
4、所有的界面类在main.cpp中创建,调用WindowManager对象设置
5、拆分MultiScreenWorker类,使MultiScreenWorker类只关心任务栏相关的逻辑,无需关心窗体或界面

Log: 优化任务栏的显示问题
Influence: 打开任务栏,观察时尚模式下圆角,左右侧区域中间是否连接在一起等
Bug: https://pms.uniontech.com/bug-view-137267.html
Bug: https://pms.uniontech.com/bug-view-140029.html
Bug: https://pms.uniontech.com/bug-view-134527.html
Bug: https://pms.uniontech.com/bug-view-146743.html
Bug: https://pms.uniontech.com/bug-view-150293.html
Change-Id: I4266f6f8c983f61258b92834d93cdacd0221d7de
2022-08-25 19:31:44 +00:00

224 lines
7.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (C) 2018 ~ 2020 Deepin Technology Co., Ltd.
*
* Author: fanpengcheng <fanpengcheng_cm@deepin.com>
*
* Maintainer: fanpengcheng <fanpengcheng_cm@deepin.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 MULTISCREENWORKER_H
#define MULTISCREENWORKER_H
#include "constants.h"
#include "utils.h"
#include "dockitem.h"
#include "xcb_misc.h"
#include "dbusutil.h"
#include <com_deepin_api_xeventmonitor.h>
#include <com_deepin_dde_launcher.h>
#include <DWindowManagerHelper>
#include <QObject>
#include <QFlag>
#define WINDOWMARGIN ((m_displayMode == Dock::Efficient) ? 0 : 10)
#define ANIMATIONTIME 300
#define FREE_POINT(p) if (p) {\
delete p;\
p = nullptr;\
}\
DGUI_USE_NAMESPACE
/**
* 多屏功能这部分看着很复杂,其实只需要把握住一个核心:及时更新数据!
* 之前测试出的诸多问题都是在切换任务栏位置,切换屏幕,主屏更改,分辨率更改等情况发生后
* 任务栏的鼠标唤醒区域或任务栏的大小没更新或者更新时的大小还是按照原来的屏幕信息计算而来的,
*/
#define DRAG_AREA_SIZE (5)
#define DOCKSPACE (WINDOWMARGIN * 2)
using XEventMonitor = ::com::deepin::api::XEventMonitor;
using DBusLuncher = ::com::deepin::dde::Launcher;
using namespace Dock;
class QVariantAnimation;
class QWidget;
class QTimer;
class MainWindow;
class QGSettings;
class TrayMainWindow;
class MenuWorker;
class MultiScreenWorker : public QObject
{
Q_OBJECT
public:
enum Flag {
Motion = 1 << 0,
Button = 1 << 1,
Key = 1 << 2
};
enum RunState {
ShowAnimationStart = 0x1, // 单次显示动画正在运行状态
HideAnimationStart = 0x2, // 单次隐藏动画正在运行状态
ChangePositionAnimationStart = 0x4, // 任务栏切换位置动画运行状态
AutoHide = 0x8, // 和MenuWorker保持一致,未设置此state时表示菜单已经打开
MousePress = 0x10, // 当前鼠标是否被按下
TouchPress = 0x20, // 当前触摸屏下是否按下
LauncherDisplay = 0x40, // 启动器是否显示
DockIsDraging = 0x80, // 任务栏正在拖拽
// 如果要添加新的状态,可以在上面添加
RunState_Mask = 0xffffffff,
};
typedef QFlags<RunState> RunStates;
explicit MultiScreenWorker(QObject *parent = Q_NULLPTR);
~MultiScreenWorker() override;
DockInter *dockInter() { return m_dockInter; }
void updateDaemonDockSize(const int &dockSize);
inline bool testState(RunState state) { return (m_state & state); }
void setStates(RunStates state, bool on = true);
inline const Position &position() { return m_position; }
inline const DisplayMode &displayMode() { return m_displayMode; }
inline const HideMode &hideMode() { return m_hideMode; }
inline const HideState &hideState() { return m_hideState; }
inline quint8 opacity() { return m_opacity * 255; }
signals:
void opacityChanged(const quint8 value) const;
void displayModeChanged(const Dock::DisplayMode &);
// 更新监视区域
void requestUpdateRegionMonitor(); // 更新监听区域
void requestUpdateFrontendGeometry(); //!!! 给后端的区域不能为是或宽度为0的区域,否则会带来HideState死循环切换的bug
void requestNotifyWindowManager();
void requestUpdatePosition(const Position &fromPos, const Position &toPos);
void requestUpdateMonitorInfo(); // 屏幕信息发生变化,需要更新任务栏大小,拖拽区域,所在屏幕,监控区域,通知窗管,通知后端,
// 用来通知WindowManager的信号
void requestUpdateDockGeometry(const Dock::HideMode &hideMode);
void positionChanged(const Dock::Position &position);
void requestPlayAnimation(const QString &screenName, const Position &position, const Dock::AniAction &animation, bool containMouse = false, bool updatePos = false);
void requestChangeDockPosition(const QString &fromScreen, const QString &toScreen, const Position &fromPos, const Position &toPos);
public slots:
void onAutoHideChanged(const bool autoHide);
void onRequestUpdateRegionMonitor();
#ifndef USE_AM
void handleDbusSignal(QDBusMessage);
#endif
private slots:
// Region Monitor
void onRegionMonitorChanged(int x, int y, const QString &key);
void onExtralRegionMonitorChanged(int x, int y, const QString &key);
void updateDisplay();
void onWindowSizeChanged(uint value);
void onPrimaryScreenChanged();
// 任务栏属性变化
void onPositionChanged(int position);
void onDisplayModeChanged(int displayMode);
void onHideModeChanged(int hideMode);
void onHideStateChanged(int state);
void onOpacityChanged(const double value);
void onRequestUpdatePosition(const Position &fromPos, const Position &toPos);
void onRequestUpdateMonitorInfo();
void onRequestDelayShowDock();
// 触摸手势操作
void onTouchPress(int type, int x, int y, const QString &key);
void onTouchRelease(int type, int x, int y, const QString &key);
void onDelayAutoHideChanged();
private:
// 初始化数据信息
void initMembers();
void initDockMode();
void initConnection();
void initUI();
void initDisplayData();
void reInitDisplayData();
void tryToShowDock(int eventX, int eventY);
void changeDockPosition(QString fromScreen, QString toScreen, const Position &fromPos, const Position &toPos);
void resetDockScreen();
void checkDaemonDockService();
void checkXEventMonitorService();
QString getValidScreen(const Position &pos);
bool isCursorOut(int x, int y);
bool onScreenEdge(const QString &screenName, const QPoint &point);
const QPoint rawXPosition(const QPoint &scaledPos);
static bool isCopyMode();
private:
// monitor screen
XEventMonitor *m_eventInter;
XEventMonitor *m_extralEventInter;
XEventMonitor *m_touchEventInter;
// DBus interface
DockInter *m_dockInter;
DBusLuncher *m_launcherInter;
// update monitor info
QTimer *m_monitorUpdateTimer;
QTimer *m_delayWakeTimer; // sp3需求切换屏幕显示延时默认2秒唤起任务栏
// 任务栏属性
double m_opacity;
Position m_position;
HideMode m_hideMode;
HideState m_hideState;
DisplayMode m_displayMode;
/***************不和其他流程产生交互,尽量不要动这里的变量***************/
QString m_registerKey;
QString m_extralRegisterKey;
QString m_touchRegisterKey; // 触控屏唤起任务栏监控区域key
QPoint m_touchPos; // 触屏按下坐标
QList<MonitRect> m_monitorRectList; // 监听唤起任务栏区域
QList<MonitRect> m_extralRectList; // 任务栏外部区域,随m_monitorRectList一起更新
QList<MonitRect> m_touchRectList; // 监听触屏唤起任务栏区域
QString m_delayScreen; // 任务栏将要切换到的屏幕名
RunStates m_state;
/*****************************************************************/
};
#endif // MULTISCREENWORKER_H