dde-dock/frame/util/multiscreenworker.h

439 lines
15 KiB
C
Raw Normal View History

/*
* Copyright (C) 2018 ~ 2028 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 "monitor.h"
#include "utils.h"
#include "item/dockitem.h"
#include "xcb/xcb_misc.h"
#include <com_deepin_dde_daemon_dock.h>
#include <com_deepin_daemon_display.h>
#include <com_deepin_daemon_display_monitor.h>
#include <com_deepin_api_xeventmonitor.h>
#include <com_deepin_dde_launcher.h>
#include <DWindowManagerHelper>
#include <QObject>
#define WINDOWMARGIN ((m_displayMode == Dock::Efficient) ? 0 : 10)
#define ANIMATIONTIME 300
DGUI_USE_NAMESPACE
/**
*
*
*
*/
using DBusDock = com::deepin::dde::daemon::Dock;
using DisplayInter = com::deepin::daemon::Display;
using MonitorInter = com::deepin::daemon::display::Monitor;
using XEventMonitor = ::com::deepin::api::XEventMonitor;
using DBusLuncher = ::com::deepin::dde::Launcher;
using namespace Dock;
class QVariantAnimation;
class QWidget;
class QTimer;
class MainWindow;
/**
* @brief The MonitorInfo class
*
*/
class MonitorInfo : public QObject
{
Q_OBJECT
public:
explicit MonitorInfo() {}
/**
* @brief data
* @return
*/
inline const 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();
if (it.key()->enable())
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();
}
signals:
/**
* @brief monitorChanged
*/
void monitorChanged();
private:
QMap<Monitor *, MonitorInter *> m_monitorInfo;
};
/**
* @brief The DockScreen class
*
*/
class DockScreen
{
public:
explicit DockScreen(const QString &current, const QString &last, const QString &primary)
: m_currentScreen(current)
, m_lastScreen(last)
, m_primary(primary)
{}
explicit DockScreen(const QString &primary)
: m_currentScreen(primary)
, m_lastScreen(primary)
, m_primary(primary)
{}
inline const QString &current() {return m_currentScreen;}
inline const QString &last() {return m_lastScreen;}
inline const QString &primary() {return m_primary;}
void updateDockedScreen(const QString &screenName)
{
m_lastScreen = m_currentScreen;
m_currentScreen = screenName;
}
void updatePrimary(const QString &primary)
{
m_primary = primary;
}
private:
QString m_currentScreen;
QString m_lastScreen;
QString m_primary;
};
class MultiScreenWorker : public QObject
{
Q_OBJECT
public:
enum Flag {
Motion = 1 << 0,
Button = 1 << 1,
Key = 1 << 2
};
MultiScreenWorker(QWidget *parent, DWindowManagerHelper *helper);
~MultiScreenWorker();
void initShow();
DBusDock *dockInter() {return m_dockInter;}
/**
* @brief lastScreen
* @return
*/
inline const QString &lastScreen() {return m_ds.last();/*return m_lastScreen;*/}
/**
* @brief deskScreen
* @return .
*/
inline const QString &deskScreen() {return m_ds.current();/*return m_currentScreen;*/}
/**
* @brief position
* @return ()
*/
inline const Position &position() {return m_position;}
/**
* @brief displayMode
* @return (,)
*/
inline const DisplayMode &displayMode() {return m_displayMode;}
/**
* @brief hideMode
* @return (,,)
*/
inline const HideMode &hideMode() {return m_hideMode;}
/**
* @brief hideState
* @return (1,2,)
*/
inline const HideState &hideState() {return m_hideState;}
/**
* @brief opacity
* @return
*/
inline quint8 opacity() {return m_opacity * 255;}
/**
* @brief dockRect
* @param screenName
* @param pos
* @param hideMode
* @param displayMode
* @return
*/
QRect dockRect(const QString &screenName, const Position &pos, const HideMode &hideMode, const DisplayMode &displayMode);
/**
* @brief dockRect
* @param screenName
* @return
*/
QRect dockRect(const QString &screenName);
/**
* @brief realDockRect ()
* @param screenName
* @param pos
* @param hideMode
* @param displayMode
* @return
*/
QRect dockRectWithoutScale(const QString &screenName, const Position &pos, const HideMode &hideMode, const DisplayMode &displayMode);
signals:
void opacityChanged(const quint8 value) const;
void displayModeChanegd();
// 更新监视区域
void requestUpdateRegionMonitor(); // 更新监听区域
void requestUpdateFrontendGeometry(); //!!! 给后端的区域不能为是或宽度为0的区域,否则会带来HideState死循环切换的bug
void requestNotifyWindowManager();
void requestUpdatePosition(const Position &fromPos, const Position &toPos);
void requestUpdateLayout(); // 界面需要根据任务栏更新布局的方向
void requestUpdateDragArea(); // 更新拖拽区域
void requestUpdateMonitorInfo(); // 屏幕信息发生变化,需要更新任务栏大小,拖拽区域,所在屏幕,监控区域,通知窗管,通知后端,
void requestDelayShowDock(const QString &screenName); // 延时唤醒任务栏
public slots:
void onAutoHideChanged(bool autoHide);
/**
* @brief updateDaemonDockSize
* @param dockSize qt获取的使
*/
void updateDaemonDockSize(int dockSize);
void onDragStateChanged(bool draging);
void handleDbusSignal(QDBusMessage);
private slots:
// Region Monitor
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();
void onWindowSizeChanged(uint value);
void primaryScreenChanged();
void updateParentGeometry(const QVariant &value, const Position &pos);
void updateParentGeometry(const QVariant &value);
void delayShowDock();
// 任务栏属性变化
void onPositionChanged();
void onDisplayModeChanged();
void onHideModeChanged();
void onHideStateChanged();
void onOpacityChanged(const double value);
/**
* @brief onRequestUpdateRegionMonitor
* :,,,
*
* ''
*/
void onRequestUpdateRegionMonitor();
// 通知后端任务栏所在位置
void onRequestUpdateFrontendGeometry();
void onRequestNotifyWindowManager();
void onRequestUpdatePosition(const Position &fromPos, const Position &toPos);
void onRequestUpdateMonitorInfo();
void onRequestDelayShowDock(const QString &screenName);
void updateMonitorDockedInfo();
void onTouchPress(int type, int x, int y, const QString &key);
void onTouchRelease(int type, int x, int y, const QString &key);
private:
// 初始化数据信息
void initMembers();
void initConnection();
void initUI();
/**
* @brief showAni
* @param screen
*/
void showAni(const QString &screen);
/**
* @brief tryToShowDock xEvent监控区域信号的xy坐标处理任务栏唤醒显示
* @param eventX x坐标
* @param eventY y坐标
*/
void tryToShowDock(int eventX, int eventY);
/**
* @brief hideAni
* @param screen
*/
void hideAni(const QString &screen);
/**
* @brief changeDockPosition
* @param lastScreen
* @param deskScreen
* @param fromPos
* @param toPos
*/
void changeDockPosition(QString lastScreen, QString deskScreen, const Position &fromPos, const Position &toPos);
/**
* @brief updateDockScreenName ,,
* @param screenName
*/
void updateDockScreenName(const QString &screenName);
/**
* @brief getValidScreen 使
* @return
*/
QString getValidScreen(const Position &pos);
/**
* @brief autosetDockScreen
*/
void autosetDockScreen();
void checkDaemonDockService();
MainWindow *parent();
/**
* @brief getDockShowGeometry
* @param screenName
* @param pos
* @param displaymode
* @param real ,false为计算,true为不计算(.,)
* @return
*/
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);
qreal scaleByName(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);
const QPoint scaledPos(const QPoint &rawXPos);
private:
QWidget *m_parent;
DWindowManagerHelper *m_wmHelper;
// monitor screen
XEventMonitor *m_eventInter;
XEventMonitor *m_extralEventInter;
XEventMonitor *m_touchEventInter;
// DBus interface
DBusDock *m_dockInter;
DisplayInter *m_displayInter;
DBusLuncher *m_launcherInter;
// update monitor info
QTimer *m_monitorUpdateTimer;
QTimer *m_delayTimer; // sp3需求,切换屏幕显示延时2秒唤起任务栏
// animation
QVariantAnimation *m_showAni;
QVariantAnimation *m_hideAni;
// 屏幕名称信息
DockScreen m_ds;
// 显示器信息
MonitorInfo m_mtrInfo;
// 任务栏属性
double m_opacity;
Position m_position;
HideMode m_hideMode;
HideState m_hideState;
DisplayMode m_displayMode;
/***************不和其他流程产生交互,尽量不要动这里的变量***************/
int m_screenRawHeight;
int m_screenRawWidth;
QString m_registerKey;
QString m_extralRegisterKey;
QString m_touchRegisterKey; // 触控屏唤起任务栏监控区域key
bool m_aniStart; // changeDockPosition是否正在运行中
bool m_draging; // 鼠标是否正在调整任务栏的宽度或高度
bool m_autoHide; // 和MenuWorker保持一致,为false时表示菜单已经打开
bool m_btnPress; // 鼠标按下时移动到唤醒区域不应该响应唤醒
bool m_touchPress; // 触屏按下
QPoint m_touchPos; // 触屏按下坐标
QList<MonitRect> m_monitorRectList; // 监听唤起任务栏区域
QList<MonitRect> m_extralRectList; // 任务栏外部区域,随m_monitorRectList一起更新
QList<MonitRect> m_touchRectList; // 监听触屏唤起任务栏区域
QString m_delayScreen; // 任务栏将要切换到的屏幕名
/*****************************************************************/
};
#endif // MULTISCREENWORKER_H