mirror of
https://github.com/linuxdeepin/dde-dock.git
synced 2025-06-02 15:45:21 +00:00
feat: 增加窗口多开的功能
增加窗口多开的窗口类,用于绘制应用图标和打开窗口的图标,根据实际情况让其显示到正确的位置 Log: 增加窗口多开的功能 Influence: 控制中心开启多开窗口显示,观察应用打开的窗口是否在对应的位置显示 Task: https://pms.uniontech.com/task-view-170977.html Change-Id: I96371b1304f5373f17dad95893ee656056e5f457
This commit is contained in:
parent
90a076a043
commit
56c3019a5c
@ -25,6 +25,7 @@
|
||||
#include "pluginsitem.h"
|
||||
#include "traypluginitem.h"
|
||||
#include "utils.h"
|
||||
#include "appmultiitem.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QGSettings>
|
||||
@ -47,16 +48,23 @@ DockItemManager::DockItemManager(QObject *parent)
|
||||
|
||||
// 应用区域
|
||||
for (auto entry : m_appInter->entries()) {
|
||||
AppItem *it = new AppItem(m_appSettings, m_activeSettings, m_dockedSettings, entry);
|
||||
AppItem *it = new AppItem(m_appInter, m_appSettings, m_activeSettings, m_dockedSettings, entry);
|
||||
manageItem(it);
|
||||
|
||||
connect(it, &AppItem::requestActivateWindow, m_appInter, &DockInter::ActivateWindow, Qt::QueuedConnection);
|
||||
connect(it, &AppItem::requestPreviewWindow, m_appInter, &DockInter::PreviewWindow);
|
||||
connect(it, &AppItem::requestCancelPreview, m_appInter, &DockInter::CancelPreviewWindow);
|
||||
|
||||
#ifdef USE_AM
|
||||
connect(it, &AppItem::windowCountChanged, this, &DockItemManager::onAppWindowCountChanged);
|
||||
#endif
|
||||
|
||||
connect(this, &DockItemManager::requestUpdateDockItem, it, &AppItem::requestUpdateEntryGeometries);
|
||||
|
||||
m_itemList.append(it);
|
||||
#ifdef USE_AM
|
||||
updateMultiItems(it);
|
||||
#endif
|
||||
}
|
||||
|
||||
// 托盘区域和插件区域 由DockPluginsController获取
|
||||
@ -65,6 +73,9 @@ DockItemManager::DockItemManager(QObject *parent)
|
||||
connect(m_appInter, &DockInter::EntryAdded, this, &DockItemManager::appItemAdded);
|
||||
connect(m_appInter, &DockInter::EntryRemoved, this, static_cast<void (DockItemManager::*)(const QString &)>(&DockItemManager::appItemRemoved), Qt::QueuedConnection);
|
||||
connect(m_appInter, &DockInter::ServiceRestarted, this, &DockItemManager::reloadAppItems);
|
||||
#ifdef USE_AM
|
||||
connect(m_appInter, &DockInter::ShowMultiWindowChanged, this, &DockItemManager::onShowMultiWindowChanged);
|
||||
#endif
|
||||
|
||||
// 插件信号
|
||||
connect(m_pluginsInter, &DockPluginsController::pluginItemInserted, this, &DockItemManager::pluginItemInserted, Qt::QueuedConnection);
|
||||
@ -194,7 +205,7 @@ void DockItemManager::appItemAdded(const QDBusObjectPath &path, const int index)
|
||||
++insertIndex;
|
||||
}
|
||||
|
||||
AppItem *item = new AppItem(m_appSettings, m_activeSettings, m_dockedSettings, path);
|
||||
AppItem *item = new AppItem(m_appInter, m_appSettings, m_activeSettings, m_dockedSettings, path);
|
||||
|
||||
if (m_appIDist.contains(item->appId())) {
|
||||
delete item;
|
||||
@ -206,17 +217,24 @@ void DockItemManager::appItemAdded(const QDBusObjectPath &path, const int index)
|
||||
connect(item, &AppItem::requestActivateWindow, m_appInter, &DockInter::ActivateWindow, Qt::QueuedConnection);
|
||||
connect(item, &AppItem::requestPreviewWindow, m_appInter, &DockInter::PreviewWindow);
|
||||
connect(item, &AppItem::requestCancelPreview, m_appInter, &DockInter::CancelPreviewWindow);
|
||||
#ifdef USE_AM
|
||||
connect(item, &AppItem::windowCountChanged, this, &DockItemManager::onAppWindowCountChanged);
|
||||
#endif
|
||||
connect(this, &DockItemManager::requestUpdateDockItem, item, &AppItem::requestUpdateEntryGeometries);
|
||||
|
||||
m_itemList.insert(insertIndex, item);
|
||||
m_appIDist.append(item->appId());
|
||||
|
||||
if (index != -1) {
|
||||
emit itemInserted(insertIndex - 1, item);
|
||||
return;
|
||||
}
|
||||
int itemIndex = insertIndex;
|
||||
if (index != -1)
|
||||
itemIndex = insertIndex - 1;
|
||||
|
||||
emit itemInserted(insertIndex, item);
|
||||
// 插入dockItem
|
||||
emit itemInserted(itemIndex, item);
|
||||
#ifdef USE_AM
|
||||
// 向后插入多开窗口
|
||||
updateMultiItems(item, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
void DockItemManager::appItemRemoved(const QString &appId)
|
||||
@ -299,9 +317,7 @@ void DockItemManager::pluginItemInserted(PluginsItem *item)
|
||||
|
||||
m_itemList.insert(insertIndex, item);
|
||||
if(pluginType == DockItem::FixedPlugin)
|
||||
{
|
||||
insertIndex ++;
|
||||
}
|
||||
|
||||
if (!Utils::SettingValue(QString("com.deepin.dde.dock.module.") + item->pluginName(), QByteArray(), "enable", true).toBool())
|
||||
item->setVisible(false);
|
||||
@ -345,3 +361,115 @@ void DockItemManager::onPluginLoadFinished()
|
||||
updatePluginsItemOrderKey();
|
||||
m_loadFinished = true;
|
||||
}
|
||||
|
||||
#ifdef USE_AM
|
||||
void DockItemManager::onAppWindowCountChanged()
|
||||
{
|
||||
AppItem *appItem = static_cast<AppItem *>(sender());
|
||||
updateMultiItems(appItem, true);
|
||||
}
|
||||
|
||||
void DockItemManager::updateMultiItems(AppItem *appItem, bool emitSignal)
|
||||
{
|
||||
// 如果系统设置不开启应用多窗口拆分,则无需之后的操作
|
||||
if (!m_appInter->showMultiWindow())
|
||||
return;
|
||||
|
||||
// 如果开启了多窗口拆分,则同步窗口和多窗口应用的信息
|
||||
const WindowInfoMap &windowInfoMap = appItem->windowsMap();
|
||||
QList<AppMultiItem *> removeItems;
|
||||
// 同步当前已经存在的多开窗口的列表,删除不存在的多开窗口
|
||||
for (int i = 0; i < m_itemList.size(); i++) {
|
||||
QPointer<DockItem> dockItem = m_itemList[i];
|
||||
AppMultiItem *multiItem = qobject_cast<AppMultiItem *>(dockItem.data());
|
||||
if (!multiItem || multiItem->appItem() != appItem)
|
||||
continue;
|
||||
|
||||
// 如果查找到的当前的应用的窗口不需要移除,则继续下一个循环
|
||||
if (!needRemoveMultiWindow(multiItem))
|
||||
continue;
|
||||
|
||||
removeItems << multiItem;
|
||||
}
|
||||
// 从itemList中移除多开窗口
|
||||
for (AppMultiItem *dockItem : removeItems)
|
||||
m_itemList.removeOne(dockItem);
|
||||
if (emitSignal) {
|
||||
// 移除发送每个多开窗口的移除信号
|
||||
for (AppMultiItem *dockItem : removeItems)
|
||||
Q_EMIT itemRemoved(dockItem);
|
||||
}
|
||||
qDeleteAll(removeItems);
|
||||
|
||||
// 遍历当前APP打开的所有窗口的列表,如果不存在多开窗口的应用,则新增,同时发送信号
|
||||
for (auto it = windowInfoMap.begin(); it != windowInfoMap.end(); it++) {
|
||||
if (multiWindowExist(it.key()))
|
||||
continue;
|
||||
|
||||
const WindowInfo &windowInfo = it.value();
|
||||
// 如果不存在这个窗口对应的多开窗口,则新建一个窗口,同时发送窗口新增的信号
|
||||
AppMultiItem *multiItem = new AppMultiItem(appItem, it.key(), windowInfo);
|
||||
m_itemList << multiItem;
|
||||
if (emitSignal)
|
||||
Q_EMIT itemInserted(-1, multiItem);
|
||||
}
|
||||
}
|
||||
|
||||
// 检查对应的窗口是否存在多开窗口
|
||||
bool DockItemManager::multiWindowExist(quint32 winId) const
|
||||
{
|
||||
for (QPointer<DockItem> dockItem : m_itemList) {
|
||||
AppMultiItem *multiItem = qobject_cast<AppMultiItem *>(dockItem.data());
|
||||
if (!multiItem)
|
||||
continue;
|
||||
|
||||
if (multiItem->winId() == winId)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查当前多开窗口是否需要移除
|
||||
// 如果当前多开窗口图标对应的窗口在这个窗口所属的APP中所有打开窗口中不存在,那么则认为该多窗口已经被关闭
|
||||
bool DockItemManager::needRemoveMultiWindow(AppMultiItem *multiItem) const
|
||||
{
|
||||
// 查找多分窗口对应的窗口在应用所有的打开的窗口中是否存在,只要它对应的窗口存在,就无需删除
|
||||
// 只要不存在,就需要删除
|
||||
AppItem *appItem = multiItem->appItem();
|
||||
const WindowInfoMap &windowInfoMap = appItem->windowsMap();
|
||||
for (auto it = windowInfoMap.begin(); it != windowInfoMap.end(); it++) {
|
||||
if (it.key() == multiItem->winId())
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DockItemManager::onShowMultiWindowChanged()
|
||||
{
|
||||
if (m_appInter->showMultiWindow()) {
|
||||
// 如果当前设置支持窗口多开,那么就依次对每个APPItem加载多开窗口
|
||||
for (const QPointer<DockItem> &dockItem : m_itemList) {
|
||||
if (dockItem->itemType() != DockItem::ItemType::App)
|
||||
continue;
|
||||
|
||||
updateMultiItems(static_cast<AppItem *>(dockItem.data()), true);
|
||||
}
|
||||
} else {
|
||||
// 如果当前设置不支持窗口多开,则删除所有的多开窗口
|
||||
QList<DockItem *> multiWindows;
|
||||
for (const QPointer<DockItem> &dockItem : m_itemList) {
|
||||
if (dockItem->itemType() != DockItem::AppMultiWindow)
|
||||
continue;
|
||||
|
||||
multiWindows << dockItem.data();
|
||||
}
|
||||
for (DockItem *multiItem : multiWindows) {
|
||||
m_itemList.removeOne(multiItem);
|
||||
Q_EMIT itemRemoved(multiItem);
|
||||
multiItem->deleteLater();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class AppMultiItem;
|
||||
/**
|
||||
* @brief The DockItemManager class
|
||||
* 管理类,管理所有的应用数据,插件数据
|
||||
@ -64,6 +65,11 @@ public slots:
|
||||
private Q_SLOTS:
|
||||
void onPluginLoadFinished();
|
||||
|
||||
#ifdef USE_AM
|
||||
void onAppWindowCountChanged();
|
||||
void onShowMultiWindowChanged();
|
||||
#endif
|
||||
|
||||
private:
|
||||
explicit DockItemManager(QObject *parent = nullptr);
|
||||
void appItemAdded(const QDBusObjectPath &path, const int index);
|
||||
@ -75,6 +81,12 @@ private:
|
||||
void reloadAppItems();
|
||||
void manageItem(DockItem *item);
|
||||
|
||||
#ifdef USE_AM
|
||||
void updateMultiItems(AppItem *appItem, bool emitSignal = false);
|
||||
bool multiWindowExist(quint32 winId) const;
|
||||
bool needRemoveMultiWindow(AppMultiItem *multiItem) const;
|
||||
#endif
|
||||
|
||||
private:
|
||||
DockInter *m_appInter;
|
||||
DockPluginsController *m_pluginsInter;
|
||||
|
154
frame/controller/multiwindowhelper.cpp
Normal file
154
frame/controller/multiwindowhelper.cpp
Normal file
@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* Maintainer: donghualin <donghualin@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 "multiwindowhelper.h"
|
||||
#include "appmultiitem.h"
|
||||
#include "appitem.h"
|
||||
|
||||
MultiWindowHelper::MultiWindowHelper(QWidget *appWidget, QWidget *multiWindowWidget, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_appWidget(appWidget)
|
||||
, m_multiWindowWidget(multiWindowWidget)
|
||||
, m_displayMode(Dock::DisplayMode::Efficient)
|
||||
{
|
||||
m_appWidget->installEventFilter(this);
|
||||
m_multiWindowWidget->installEventFilter(this);
|
||||
}
|
||||
|
||||
void MultiWindowHelper::setDisplayMode(Dock::DisplayMode displayMode)
|
||||
{
|
||||
if (m_displayMode == displayMode)
|
||||
return;
|
||||
|
||||
m_displayMode = displayMode;
|
||||
resetMultiItemPosition();
|
||||
}
|
||||
|
||||
void MultiWindowHelper::addMultiWindow(int, AppMultiItem *item)
|
||||
{
|
||||
int index = itemIndex(item);
|
||||
if (m_displayMode == Dock::DisplayMode::Efficient) {
|
||||
// 将多开窗口项目插入到对应的APP的后面
|
||||
insertChildWidget(m_appWidget, index, item);
|
||||
} else {
|
||||
// 将多开窗口插入到工具区域的前面
|
||||
insertChildWidget(m_multiWindowWidget, index, item);
|
||||
}
|
||||
}
|
||||
|
||||
void MultiWindowHelper::removeMultiWindow(AppMultiItem *item)
|
||||
{
|
||||
if (m_appWidget->children().contains(item))
|
||||
m_appWidget->layout()->removeWidget(item);
|
||||
else
|
||||
m_multiWindowWidget->layout()->removeWidget(item);
|
||||
}
|
||||
|
||||
bool MultiWindowHelper::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
if (watched == m_appWidget || watched == m_multiWindowWidget) {
|
||||
switch(event->type()) {
|
||||
case QEvent::ChildAdded:
|
||||
case QEvent::ChildRemoved: {
|
||||
/* 这里用异步的方式,因为收到QEvent::ChildAdded信号的时候,
|
||||
此时应用还没有插入到Widget中,收到QEvent::ChildRemoved信号的时候,
|
||||
此时应用还未从任务栏上移除,通过异步的方式保证同步新增或移除成功后才执行,这样更新的界面才是最准确的
|
||||
*/
|
||||
QMetaObject::invokeMethod(this, &MultiWindowHelper::requestUpdate, Qt::QueuedConnection);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return QObject::eventFilter(watched, event);
|
||||
}
|
||||
|
||||
int MultiWindowHelper::itemIndex(AppMultiItem *item)
|
||||
{
|
||||
if (m_displayMode != Dock::DisplayMode::Efficient)
|
||||
return -1;
|
||||
|
||||
// 高效模式,查找对应的应用或者这个应用所有的子窗口所在的位置,然后插入到最大的值的后面
|
||||
int lastIndex = -1;
|
||||
for (int i = 0; i < m_appWidget->layout()->count(); i++) {
|
||||
DockItem *dockItem = qobject_cast<DockItem *>(m_appWidget->layout()->itemAt(i)->widget());
|
||||
if (!dockItem)
|
||||
continue;
|
||||
|
||||
if (dockItem != item->appItem()) {
|
||||
AppMultiItem *multiItem = qobject_cast<AppMultiItem *>(dockItem);
|
||||
if (!multiItem || multiItem->appItem() != item->appItem())
|
||||
continue;
|
||||
}
|
||||
|
||||
lastIndex = i;
|
||||
}
|
||||
|
||||
if (lastIndex >= 0)
|
||||
return ++lastIndex;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void MultiWindowHelper::insertChildWidget(QWidget *parentWidget, int index, AppMultiItem *item)
|
||||
{
|
||||
QBoxLayout *layout = static_cast<QBoxLayout *>(parentWidget->layout());
|
||||
if (index >= 0)
|
||||
layout->insertWidget(index, item);
|
||||
else
|
||||
layout->addWidget(item);
|
||||
}
|
||||
|
||||
void MultiWindowHelper::resetMultiItemPosition()
|
||||
{
|
||||
QWidget *fromWidget = nullptr;
|
||||
QWidget *toWidget = nullptr;
|
||||
|
||||
if (m_displayMode == Dock::DisplayMode::Efficient) {
|
||||
// 从时尚模式变换为高效模式
|
||||
fromWidget = m_multiWindowWidget;
|
||||
toWidget = m_appWidget;
|
||||
} else {
|
||||
// 从高效模式变换到时尚模式
|
||||
fromWidget = m_appWidget;
|
||||
toWidget = m_multiWindowWidget;
|
||||
}
|
||||
|
||||
QList<AppMultiItem *> moveWidgetItem;
|
||||
for (int i = 0; i < fromWidget->layout()->count(); i++) {
|
||||
AppMultiItem *multiItem = qobject_cast<AppMultiItem *>(fromWidget->layout()->itemAt(i)->widget());
|
||||
if (!multiItem)
|
||||
continue;
|
||||
|
||||
moveWidgetItem << multiItem;
|
||||
}
|
||||
|
||||
QBoxLayout *toLayout = static_cast<QBoxLayout *>(toWidget->layout());
|
||||
for (AppMultiItem *item : moveWidgetItem) {
|
||||
fromWidget->layout()->removeWidget(item);
|
||||
int index = itemIndex(item);
|
||||
if (index >= 0)
|
||||
toLayout->insertWidget(index, item);
|
||||
else
|
||||
toLayout->addWidget(item);
|
||||
}
|
||||
}
|
58
frame/controller/multiwindowhelper.h
Normal file
58
frame/controller/multiwindowhelper.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* Maintainer: donghualin <donghualin@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 MULTIWINDOWHELPER_H
|
||||
#define MULTIWINDOWHELPER_H
|
||||
|
||||
#include "constants.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class AppMultiItem;
|
||||
|
||||
class MultiWindowHelper : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MultiWindowHelper(QWidget *appWidget, QWidget *multiWindowWidget, QObject *parent = nullptr);
|
||||
|
||||
void setDisplayMode(Dock::DisplayMode displayMode);
|
||||
void addMultiWindow(int, AppMultiItem *item);
|
||||
void removeMultiWindow(AppMultiItem *item);
|
||||
|
||||
Q_SIGNALS:
|
||||
void requestUpdate();
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *watched, QEvent *event) override;
|
||||
|
||||
private:
|
||||
int itemIndex(AppMultiItem *item);
|
||||
void insertChildWidget(QWidget *parentWidget, int index, AppMultiItem *item);
|
||||
void resetMultiItemPosition();
|
||||
|
||||
private:
|
||||
QWidget *m_appWidget;
|
||||
QWidget *m_multiWindowWidget;
|
||||
Dock::DisplayMode m_displayMode;
|
||||
};
|
||||
|
||||
#endif // MULTIWINDOWHELPER_H
|
@ -328,6 +328,11 @@ bool Dde_Dock::showRecent() const
|
||||
return qvariant_cast<bool>(property("ShowRecent"));
|
||||
}
|
||||
|
||||
bool Dde_Dock::showMultiWindow() const
|
||||
{
|
||||
return qvariant_cast<bool>(property("ShowMultiWindow"));
|
||||
}
|
||||
|
||||
QDBusPendingReply<> Dde_Dock::ActivateWindow(uint in0)
|
||||
{
|
||||
return m_wm->ActivateWindow(in0);
|
||||
|
@ -128,6 +128,9 @@ public:
|
||||
Q_PROPERTY(bool ShowRecent READ showRecent NOTIFY showRecentChanged)
|
||||
bool showRecent() const;
|
||||
|
||||
Q_PROPERTY(bool ShowMultiWindow READ showMultiWindow NOTIFY ShowMultiWindowChanged)
|
||||
bool showMultiWindow() const;
|
||||
|
||||
public Q_SLOTS: // METHODS
|
||||
QDBusPendingReply<> ActivateWindow(uint in0);
|
||||
|
||||
@ -326,6 +329,7 @@ Q_SIGNALS: // SIGNALS
|
||||
void WindowSizeEfficientChanged(uint value) const;
|
||||
void WindowSizeFashionChanged(uint value) const;
|
||||
void showRecentChanged(bool) const;
|
||||
void ShowMultiWindowChanged(bool) const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void CallQueued(const QString &callName, const QList<QVariant> &args);
|
||||
|
@ -145,6 +145,13 @@ public Q_SLOTS: // METHODS
|
||||
return asyncCallWithArgumentList(QStringLiteral("ForceQuit"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> ActiveWindow(quint32 in0)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << in0;
|
||||
return asyncCallWithArgumentList(QStringLiteral("ActiveWindow"), argumentList);
|
||||
}
|
||||
|
||||
inline void ForceQuitQueued()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
|
@ -50,7 +50,7 @@ DCORE_USE_NAMESPACE
|
||||
|
||||
QPoint AppItem::MousePressPos;
|
||||
|
||||
AppItem::AppItem(const QGSettings *appSettings, const QGSettings *activeAppSettings, const QGSettings *dockedAppSettings, const QDBusObjectPath &entry, QWidget *parent)
|
||||
AppItem::AppItem(DockInter *dockInter, const QGSettings *appSettings, const QGSettings *activeAppSettings, const QGSettings *dockedAppSettings, const QDBusObjectPath &entry, QWidget *parent)
|
||||
: DockItem(parent)
|
||||
, m_appSettings(appSettings)
|
||||
, m_activeAppSettings(activeAppSettings)
|
||||
@ -72,6 +72,7 @@ AppItem::AppItem(const QGSettings *appSettings, const QGSettings *activeAppSetti
|
||||
, m_themeType(DGuiApplicationHelper::instance()->themeType())
|
||||
, m_createMSecs(QDateTime::currentMSecsSinceEpoch())
|
||||
, m_screenSpliter(ScreenSpliterFactory::createScreenSpliter(this, m_itemEntryInter))
|
||||
, m_dockInter(dockInter)
|
||||
{
|
||||
QHBoxLayout *centralLayout = new QHBoxLayout;
|
||||
centralLayout->setMargin(0);
|
||||
@ -135,6 +136,11 @@ const QString AppItem::appId() const
|
||||
return m_id;
|
||||
}
|
||||
|
||||
QString AppItem::name() const
|
||||
{
|
||||
return m_itemEntryInter->name();
|
||||
}
|
||||
|
||||
bool AppItem::isValid() const
|
||||
{
|
||||
return m_itemEntryInter->isValid() && !m_itemEntryInter->id().isEmpty();
|
||||
@ -216,8 +222,14 @@ int AppItem::mode() const
|
||||
{
|
||||
return m_itemEntryInter->mode();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
DockEntryInter *AppItem::itemEntryInter() const
|
||||
{
|
||||
return m_itemEntryInter;
|
||||
}
|
||||
|
||||
QString AppItem::accessibleName()
|
||||
{
|
||||
return m_itemEntryInter->name();
|
||||
@ -243,6 +255,11 @@ void AppItem::updateMSecs()
|
||||
m_createMSecs = QDateTime::currentMSecsSinceEpoch();
|
||||
}
|
||||
|
||||
const WindowInfoMap &AppItem::windowsMap() const
|
||||
{
|
||||
return m_windowInfos;
|
||||
}
|
||||
|
||||
void AppItem::moveEvent(QMoveEvent *e)
|
||||
{
|
||||
DockItem::moveEvent(e);
|
||||
@ -281,14 +298,26 @@ void AppItem::paintEvent(QPaintEvent *e)
|
||||
QPainterPath path;
|
||||
path.addRoundedRect(backgroundRect, 8, 8);
|
||||
|
||||
if (m_active) {
|
||||
painter.fillPath(path, QColor(0, 0, 0, 255 * 0.8));
|
||||
} else if (!m_windowInfos.isEmpty()) {
|
||||
if (hasAttention())
|
||||
painter.fillPath(path, QColor(241, 138, 46, 255 * .8));
|
||||
else
|
||||
painter.fillPath(path, QColor(0, 0, 0, 255 * 0.3));
|
||||
// 在没有开启窗口多开的情况下,显示背景色
|
||||
#ifdef USE_AM
|
||||
if (!m_dockInter->showMultiWindow()) {
|
||||
#endif
|
||||
if (m_active) {
|
||||
QColor color = Qt::black;
|
||||
color.setAlpha(255 * 0.8);
|
||||
painter.fillPath(path, color);
|
||||
} else if (!m_windowInfos.isEmpty()) {
|
||||
if (hasAttention()) {
|
||||
painter.fillPath(path, QColor(241, 138, 46, 255 * .8));
|
||||
} else {
|
||||
QColor color = Qt::black;
|
||||
color.setAlpha(255 * 0.3);
|
||||
painter.fillPath(path, color);
|
||||
}
|
||||
}
|
||||
#ifdef USE_AM
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
if (!m_windowInfos.isEmpty()) {
|
||||
QPoint p;
|
||||
@ -381,12 +410,21 @@ void AppItem::mouseReleaseEvent(QMouseEvent *e)
|
||||
qDebug() << "app item clicked, name:" << m_itemEntryInter->name()
|
||||
<< "id:" << m_itemEntryInter->id() << "my-id:" << m_id << "icon:" << m_itemEntryInter->icon();
|
||||
|
||||
m_itemEntryInter->Activate(QX11Info::getTimestamp());
|
||||
|
||||
// play launch effect
|
||||
if (m_windowInfos.isEmpty() && DGuiApplicationHelper::isSpecialEffectsEnvironment())
|
||||
playSwingEffect();
|
||||
#ifdef USE_AM
|
||||
if (m_dockInter->showMultiWindow()) {
|
||||
// 如果开启了多窗口显示,则直接新建一个窗口
|
||||
m_itemEntryInter->NewInstance(QX11Info::getTimestamp());
|
||||
} else {
|
||||
#endif
|
||||
// 如果没有开启新窗口显示,则
|
||||
m_itemEntryInter->Activate(QX11Info::getTimestamp());
|
||||
// play launch effect
|
||||
if (m_windowInfos.isEmpty() && DGuiApplicationHelper::isSpecialEffectsEnvironment())
|
||||
playSwingEffect();
|
||||
}
|
||||
#ifdef USE_AM
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void AppItem::mousePressEvent(QMouseEvent *e)
|
||||
@ -640,6 +678,9 @@ void AppItem::updateWindowInfos(const WindowInfoMap &info)
|
||||
}
|
||||
|
||||
update();
|
||||
|
||||
// 通知外面窗体数量发生变化,需要更新多开窗口的信息
|
||||
Q_EMIT windowCountChanged();
|
||||
}
|
||||
|
||||
void AppItem::refreshIcon()
|
||||
|
@ -43,11 +43,12 @@ class AppItem : public DockItem
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AppItem(const QGSettings *appSettings, const QGSettings *activeAppSettings, const QGSettings *dockedAppSettings, const QDBusObjectPath &entry, QWidget *parent = nullptr);
|
||||
explicit AppItem(DockInter *dockInter, const QGSettings *appSettings, const QGSettings *activeAppSettings, const QGSettings *dockedAppSettings, const QDBusObjectPath &entry, QWidget *parent = nullptr);
|
||||
~AppItem() override;
|
||||
|
||||
void checkEntry() override;
|
||||
const QString appId() const;
|
||||
QString name() const;
|
||||
bool isValid() const;
|
||||
void updateWindowIconGeometries();
|
||||
void undock();
|
||||
@ -61,6 +62,7 @@ public:
|
||||
#ifdef USE_AM
|
||||
int mode() const;
|
||||
#endif
|
||||
DockEntryInter *itemEntryInter() const;
|
||||
inline ItemType itemType() const override { return App; }
|
||||
QPixmap appIcon(){ return m_appIcon; }
|
||||
virtual QString accessibleName() override;
|
||||
@ -68,6 +70,7 @@ public:
|
||||
bool isDocked() const;
|
||||
qint64 appOpenMSecs() const;
|
||||
void updateMSecs();
|
||||
const WindowInfoMap &windowsMap() const;
|
||||
|
||||
signals:
|
||||
void requestActivateWindow(const WId wid) const;
|
||||
@ -76,6 +79,7 @@ signals:
|
||||
void dragReady(QWidget *dragWidget);
|
||||
|
||||
void requestUpdateEntryGeometries() const;
|
||||
void windowCountChanged() const;
|
||||
#ifdef USE_AM
|
||||
void modeChanged(int) const;
|
||||
#else
|
||||
@ -161,6 +165,7 @@ private:
|
||||
static QPoint MousePressPos;
|
||||
|
||||
ScreenSpliter *m_screenSpliter;
|
||||
DockInter *m_dockInter;
|
||||
};
|
||||
|
||||
#endif // APPITEM_H
|
||||
|
286
frame/item/appmultiitem.cpp
Normal file
286
frame/item/appmultiitem.cpp
Normal file
@ -0,0 +1,286 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* Maintainer: donghualin <donghualin@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 "appitem.h"
|
||||
#include "appmultiitem.h"
|
||||
#include "imageutil.h"
|
||||
#include "themeappicon.h"
|
||||
|
||||
#include <QBitmap>
|
||||
#include <QMenu>
|
||||
#include <QPixmap>
|
||||
#include <QX11Info>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <sys/shm.h>
|
||||
|
||||
struct SHMInfo {
|
||||
long shmid;
|
||||
long width;
|
||||
long height;
|
||||
long bytesPerLine;
|
||||
long format;
|
||||
|
||||
struct Rect {
|
||||
long x;
|
||||
long y;
|
||||
long width;
|
||||
long height;
|
||||
} rect;
|
||||
};
|
||||
|
||||
AppMultiItem::AppMultiItem(AppItem *appItem, WId winId, const WindowInfo &windowInfo, QWidget *parent)
|
||||
: DockItem(parent)
|
||||
, m_appItem(appItem)
|
||||
, m_windowInfo(windowInfo)
|
||||
, m_entryInter(appItem->itemEntryInter())
|
||||
, m_winId(winId)
|
||||
, m_menu(new QMenu(this))
|
||||
{
|
||||
initMenu();
|
||||
initConnection();
|
||||
}
|
||||
|
||||
AppMultiItem::~AppMultiItem()
|
||||
{
|
||||
}
|
||||
|
||||
QSize AppMultiItem::suitableSize(int size) const
|
||||
{
|
||||
return QSize(size, size);
|
||||
}
|
||||
|
||||
AppItem *AppMultiItem::appItem() const
|
||||
{
|
||||
return m_appItem;
|
||||
}
|
||||
|
||||
quint32 AppMultiItem::winId() const
|
||||
{
|
||||
return m_winId;
|
||||
}
|
||||
|
||||
const WindowInfo &AppMultiItem::windowInfo() const
|
||||
{
|
||||
return m_windowInfo;
|
||||
}
|
||||
|
||||
DockItem::ItemType AppMultiItem::itemType() const
|
||||
{
|
||||
return DockItem::AppMultiWindow;
|
||||
}
|
||||
|
||||
bool AppMultiItem::isKWinAvailable() const
|
||||
{
|
||||
if (QDBusConnection::sessionBus().interface()->isServiceRegistered(QStringLiteral("org.kde.KWin"))) {
|
||||
QDBusInterface interface(QStringLiteral("org.kde.KWin"), QStringLiteral("/Effects"), QStringLiteral("org.kde.kwin.Effects"));
|
||||
QDBusReply<bool> reply = interface.call(QStringLiteral("isEffectLoaded"), "screenshot");
|
||||
|
||||
return reply.value();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QImage AppMultiItem::snapImage() const
|
||||
{
|
||||
// 优先使用窗管进行窗口截图
|
||||
if (isKWinAvailable()) {
|
||||
QDBusInterface interface(QStringLiteral("org.kde.KWin"), QStringLiteral("/Screenshot"), QStringLiteral("org.kde.kwin.Screenshot"));
|
||||
|
||||
QList<QVariant> args;
|
||||
args << QVariant::fromValue(m_winId);
|
||||
args << QVariant::fromValue(quint32(width() - 20));
|
||||
args << QVariant::fromValue(quint32(height() - 20));
|
||||
|
||||
QImage image;
|
||||
QDBusReply<QString> reply = interface.callWithArgumentList(QDBus::Block, QStringLiteral("screenshotForWindowExtend"), args);
|
||||
if(reply.isValid()){
|
||||
const QString tmpFile = reply.value();
|
||||
if (QFile::exists(tmpFile)) {
|
||||
image.load(tmpFile);
|
||||
qDebug() << "reply: " << tmpFile;
|
||||
QFile::remove(tmpFile);
|
||||
} else {
|
||||
qDebug() << "get current workspace bckground error, file does not exist : " << tmpFile;
|
||||
}
|
||||
} else {
|
||||
qDebug() << "get current workspace bckground error: "<< reply.error().message();
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
// get window image from shm(only for deepin app)
|
||||
SHMInfo *info = getImageDSHM();
|
||||
QImage image;
|
||||
uchar *image_data = 0;
|
||||
if (info) {
|
||||
qDebug() << "get Image from dxcbplugin SHM...";
|
||||
image_data = (uchar *)shmat(info->shmid, 0, 0);
|
||||
if ((qint64)image_data != -1)
|
||||
return QImage(image_data, info->width, info->height, info->bytesPerLine, (QImage::Format)info->format);
|
||||
|
||||
qDebug() << "invalid pointer of shm!";
|
||||
image_data = nullptr;
|
||||
}
|
||||
|
||||
QImage qimage;
|
||||
XImage *ximage;
|
||||
if (!image_data || qimage.isNull()) {
|
||||
ximage = getImageXlib();
|
||||
if (!ximage)
|
||||
return QImage();
|
||||
|
||||
qimage = QImage((const uchar *)(ximage->data), ximage->width, ximage->height, ximage->bytes_per_line, QImage::Format_RGB32);
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
SHMInfo *AppMultiItem::getImageDSHM() const
|
||||
{
|
||||
const auto display = Utils::IS_WAYLAND_DISPLAY ? XOpenDisplay(nullptr) : QX11Info::display();
|
||||
if (!display) {
|
||||
qWarning() << "Error: get display failed!";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Atom atom_prop = XInternAtom(display, "_DEEPIN_DXCB_SHM_INFO", true);
|
||||
if (!atom_prop) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Atom actual_type_return_deepin_shm;
|
||||
int actual_format_return_deepin_shm;
|
||||
unsigned long nitems_return_deepin_shm;
|
||||
unsigned long bytes_after_return_deepin_shm;
|
||||
unsigned char *prop_return_deepin_shm;
|
||||
|
||||
XGetWindowProperty(display, m_winId, atom_prop, 0, 32 * 9, false, AnyPropertyType,
|
||||
&actual_type_return_deepin_shm, &actual_format_return_deepin_shm, &nitems_return_deepin_shm,
|
||||
&bytes_after_return_deepin_shm, &prop_return_deepin_shm);
|
||||
|
||||
return reinterpret_cast<SHMInfo *>(prop_return_deepin_shm);
|
||||
}
|
||||
|
||||
XImage *AppMultiItem::getImageXlib() const
|
||||
{
|
||||
const auto display = Utils::IS_WAYLAND_DISPLAY ? XOpenDisplay(nullptr) : QX11Info::display();
|
||||
if (!display) {
|
||||
qWarning() << "Error: get display failed!";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Window unused_window;
|
||||
int unused_int;
|
||||
unsigned unused_uint, w, h;
|
||||
XGetGeometry(display, m_winId, &unused_window, &unused_int, &unused_int, &w, &h, &unused_uint, &unused_uint);
|
||||
return XGetImage(display, m_winId, 0, 0, w, h, AllPlanes, ZPixmap);
|
||||
}
|
||||
|
||||
void AppMultiItem::initMenu()
|
||||
{
|
||||
QAction *actionOpen = new QAction(m_menu);
|
||||
actionOpen->setText(tr("Open"));
|
||||
connect(actionOpen, &QAction::triggered, this, &AppMultiItem::onOpen);
|
||||
m_menu->addAction(actionOpen);
|
||||
}
|
||||
|
||||
void AppMultiItem::initConnection()
|
||||
{
|
||||
connect(m_entryInter, &DockEntryInter::CurrentWindowChanged, this, &AppMultiItem::onCurrentWindowChanged);
|
||||
}
|
||||
|
||||
void AppMultiItem::onOpen()
|
||||
{
|
||||
#ifdef USE_AM
|
||||
m_entryInter->ActiveWindow(m_winId);
|
||||
#endif
|
||||
}
|
||||
|
||||
void AppMultiItem::onCurrentWindowChanged(uint32_t value)
|
||||
{
|
||||
if (value != m_winId)
|
||||
return;
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void AppMultiItem::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter painter(this);
|
||||
painter.setRenderHint(QPainter::Antialiasing, true);
|
||||
painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
|
||||
|
||||
if (m_snapImage.isNull()) {
|
||||
m_snapImage = snapImage();
|
||||
}
|
||||
|
||||
DStyleHelper dstyle(style());
|
||||
const int radius = dstyle.pixelMetric(DStyle::PM_FrameRadius);
|
||||
QRect itemRect = rect();
|
||||
itemRect.marginsRemoved(QMargins(6, 6, 6, 6));
|
||||
QPixmap pixmapWindowIcon = QPixmap::fromImage(m_snapImage);
|
||||
QPainterPath path;
|
||||
path.addRoundedRect(rect(), radius, radius);
|
||||
painter.fillPath(path, Qt::transparent);
|
||||
|
||||
if (m_entryInter->currentWindow() == m_winId) {
|
||||
QColor backColor = Qt::black;
|
||||
backColor.setAlpha(255 * 0.8);
|
||||
painter.fillPath(path, backColor);
|
||||
}
|
||||
|
||||
itemRect = m_snapImage.rect();
|
||||
int itemWidth = itemRect.width();
|
||||
int itemHeight = itemRect.height();
|
||||
int x = (rect().width() - itemWidth) / 2;
|
||||
int y = (rect().height() - itemHeight) / 2;
|
||||
painter.drawPixmap(QRect(x, y, itemWidth, itemHeight), pixmapWindowIcon);
|
||||
|
||||
QPixmap pixmapAppIcon;
|
||||
ThemeAppIcon::getIcon(pixmapAppIcon, m_entryInter->icon(), qMin(width(), height()) * 0.8);
|
||||
if (!pixmapAppIcon.isNull()) {
|
||||
// 绘制下方的图标,下方的小图标大约为应用图标的三分之一的大小
|
||||
//pixmap = pixmap.scaled(pixmap.width() * 0.3, pixmap.height() * 0.3);
|
||||
QRect rectIcon = rect();
|
||||
int iconWidth = rectIcon.width() * 0.3;
|
||||
int iconHeight = rectIcon.height() * 0.3;
|
||||
rectIcon.setX((rect().width() - iconWidth) * 0.5);
|
||||
rectIcon.setY(rect().height() - iconHeight);
|
||||
rectIcon.setWidth(iconWidth);
|
||||
rectIcon.setHeight(iconHeight);
|
||||
painter.drawPixmap(rectIcon, pixmapAppIcon);
|
||||
}
|
||||
}
|
||||
|
||||
void AppMultiItem::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
#ifdef USE_AM
|
||||
m_entryInter->ActiveWindow(m_winId);
|
||||
#endif
|
||||
} else {
|
||||
QPoint currentPoint = QCursor::pos();
|
||||
m_menu->exec(currentPoint);
|
||||
}
|
||||
}
|
74
frame/item/appmultiitem.h
Normal file
74
frame/item/appmultiitem.h
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* Maintainer: donghualin <donghualin@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 APPMULTIITEM_H
|
||||
#define APPMULTIITEM_H
|
||||
|
||||
#include "dockitem.h"
|
||||
#include "dbusutil.h"
|
||||
|
||||
struct SHMInfo;
|
||||
struct _XImage;
|
||||
typedef _XImage XImage;
|
||||
class AppItem;
|
||||
|
||||
class AppMultiItem : public DockItem
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
friend class AppItem;
|
||||
|
||||
public:
|
||||
AppMultiItem(AppItem *appItem, WId winId, const WindowInfo &windowInfo, QWidget *parent = Q_NULLPTR);
|
||||
~AppMultiItem() override;
|
||||
|
||||
QSize suitableSize(int size) const;
|
||||
AppItem *appItem() const;
|
||||
quint32 winId() const;
|
||||
const WindowInfo &windowInfo() const;
|
||||
|
||||
ItemType itemType() const override;
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *) override;
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
|
||||
private:
|
||||
bool isKWinAvailable() const;
|
||||
QImage snapImage() const;
|
||||
SHMInfo *getImageDSHM() const;
|
||||
XImage *getImageXlib() const;
|
||||
void initMenu();
|
||||
void initConnection();
|
||||
|
||||
private Q_SLOTS:
|
||||
void onOpen();
|
||||
void onCurrentWindowChanged(uint32_t value);
|
||||
|
||||
private:
|
||||
AppItem *m_appItem;
|
||||
WindowInfo m_windowInfo;
|
||||
DockEntryInter *m_entryInter;
|
||||
QImage m_snapImage;
|
||||
WId m_winId;
|
||||
QMenu *m_menu;
|
||||
};
|
||||
|
||||
#endif // APPMULTIITEM_H
|
@ -48,7 +48,8 @@ public:
|
||||
Placeholder,
|
||||
TrayPlugin, // 托盘插件
|
||||
QuickSettingPlugin, // 快捷设置区域插件
|
||||
StretchPlugin // 时尚模式下的固定在最右侧的插件,例如开关机插件
|
||||
StretchPlugin, // 时尚模式下的固定在最右侧的插件,例如开关机插件
|
||||
AppMultiWindow // APP的多开应用的窗口
|
||||
};
|
||||
|
||||
public:
|
||||
|
@ -36,6 +36,10 @@
|
||||
#include "displaymanager.h"
|
||||
#include "recentapphelper.h"
|
||||
#include "toolapphelper.h"
|
||||
#include "multiwindowhelper.h"
|
||||
#include "mainwindow.h"
|
||||
#include "appmultiitem.h"
|
||||
#include "multiwindowhelper.h"
|
||||
|
||||
#include <QDrag>
|
||||
#include <QTimer>
|
||||
@ -89,7 +93,11 @@ MainPanelControl::MainPanelControl(QWidget *parent)
|
||||
, m_recentLayout(new QBoxLayout(QBoxLayout::LeftToRight, this))
|
||||
, m_recentSpliter(new QLabel(this))
|
||||
, m_toolAreaWidget(new QWidget(this))
|
||||
, m_toolLayout(new QBoxLayout(QBoxLayout::LeftToRight, m_toolAreaWidget))
|
||||
, m_toolAreaLayout(new QBoxLayout(QBoxLayout::LeftToRight, m_toolAreaWidget))
|
||||
, m_multiWindowWidget(new QWidget(m_toolAreaWidget))
|
||||
, m_multiWindowLayout(new QBoxLayout(QBoxLayout::LeftToRight, m_multiWindowWidget))
|
||||
, m_toolSonAreaWidget(new QWidget(m_toolAreaWidget))
|
||||
, m_toolSonLayout(new QBoxLayout(QBoxLayout::LeftToRight, m_toolSonAreaWidget))
|
||||
, m_trayManagerWidget(new TrayManagerWindow(this))
|
||||
, m_pluginLayout(new QBoxLayout(QBoxLayout::LeftToRight, this))
|
||||
, m_desktopWidget(new DesktopWidget(this))
|
||||
@ -102,6 +110,7 @@ MainPanelControl::MainPanelControl(QWidget *parent)
|
||||
, m_dockInter(new DockInter(dockServiceName(), dockServicePath(), QDBusConnection::sessionBus(), this))
|
||||
, m_recentHelper(new RecentAppHelper(m_appAreaSonWidget, m_recentAreaWidget, m_dockInter, this))
|
||||
, m_toolHelper(new ToolAppHelper(m_pluginAreaWidget, m_toolAreaWidget, this))
|
||||
, m_multiHelper(new MultiWindowHelper(m_appAreaSonWidget, m_multiWindowWidget, this))
|
||||
{
|
||||
initUI();
|
||||
initConnection();
|
||||
@ -158,12 +167,27 @@ void MainPanelControl::initUI()
|
||||
m_mainPanelLayout->addWidget(m_recentSpliter);
|
||||
|
||||
/* 工具应用 */
|
||||
m_toolAreaWidget->setObjectName("toolarea");
|
||||
m_toolAreaWidget->setAccessibleName("toolarea");
|
||||
m_toolAreaWidget->setLayout(m_toolLayout);
|
||||
m_toolLayout->setSpacing(0);
|
||||
m_toolLayout->setContentsMargins(0, 0, 0, 0);
|
||||
// 包含窗口多开和工具组合
|
||||
m_toolAreaWidget->setObjectName("toolArea");
|
||||
m_toolAreaWidget->setAccessibleName("toolArea");
|
||||
m_toolAreaWidget->setLayout(m_toolAreaLayout);
|
||||
m_toolAreaLayout->setContentsMargins(0, 0, 0, 0);
|
||||
m_toolAreaLayout->setSpacing(0);
|
||||
m_mainPanelLayout->addWidget(m_toolAreaWidget);
|
||||
// 多开窗口区域
|
||||
m_multiWindowWidget->setObjectName("multiWindow");
|
||||
m_multiWindowWidget->setAccessibleName("multiWindow");
|
||||
m_multiWindowWidget->setLayout(m_multiWindowLayout);
|
||||
m_multiWindowLayout->setContentsMargins(0, 2, 0, 2);
|
||||
m_multiWindowLayout->setSpacing(0);
|
||||
m_toolAreaLayout->addWidget(m_multiWindowWidget);
|
||||
// 工具应用区域-包含打开窗口区域和回收站区域
|
||||
m_toolSonAreaWidget->setObjectName("toolsonarea");
|
||||
m_toolSonAreaWidget->setAccessibleName("toolsonarea");
|
||||
m_toolSonAreaWidget->setLayout(m_toolSonLayout);
|
||||
m_toolSonLayout->setSpacing(0);
|
||||
m_toolSonLayout->setContentsMargins(0, 0, 0, 0);
|
||||
m_toolAreaLayout->addWidget(m_toolSonAreaWidget);
|
||||
|
||||
/* 托盘区域 */
|
||||
m_trayAreaWidget->setObjectName("trayarea");
|
||||
@ -206,6 +230,7 @@ void MainPanelControl::initConnection()
|
||||
connect(m_recentHelper, &RecentAppHelper::dockAppVisibleChanged, this, &MainPanelControl::onDockAppVisibleChanged);
|
||||
connect(m_toolHelper, &ToolAppHelper::requestUpdate, this, &MainPanelControl::requestUpdate);
|
||||
connect(m_toolHelper, &ToolAppHelper::toolVisibleChanged, this, &MainPanelControl::onToolVisibleChanged);
|
||||
connect(m_multiHelper, &MultiWindowHelper::requestUpdate, this, &MainPanelControl::requestUpdate);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -220,6 +245,7 @@ void MainPanelControl::setDisplayMode(DisplayMode dislayMode)
|
||||
m_displayMode = dislayMode;
|
||||
m_recentHelper->setDisplayMode(dislayMode);
|
||||
m_toolHelper->setDisplayMode(dislayMode);
|
||||
m_multiHelper->setDisplayMode(dislayMode);
|
||||
updateDisplayMode();
|
||||
}
|
||||
|
||||
@ -244,6 +270,7 @@ void MainPanelControl::updateMainPanelLayout()
|
||||
m_recentLayout->setDirection(QBoxLayout::LeftToRight);
|
||||
m_trayAreaLayout->setContentsMargins(0, 10, 0, 10);
|
||||
m_pluginLayout->setContentsMargins(10, 0, 10, 0);
|
||||
m_multiWindowLayout->setContentsMargins(0, 2, 0, 2);
|
||||
break;
|
||||
case Position::Right:
|
||||
case Position::Left:
|
||||
@ -260,6 +287,7 @@ void MainPanelControl::updateMainPanelLayout()
|
||||
m_recentLayout->setDirection(QBoxLayout::TopToBottom);
|
||||
m_trayAreaLayout->setContentsMargins(10, 0, 10, 0);
|
||||
m_pluginLayout->setContentsMargins(0, 10, 0, 10);
|
||||
m_multiWindowLayout->setContentsMargins(2, 0, 2, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -379,12 +407,12 @@ void MainPanelControl::updateAppAreaSonWidgetSize()
|
||||
m_appAreaSonWidget->setMaximumHeight(height());
|
||||
m_appAreaSonWidget->setMaximumWidth(m_appAreaWidget->width());
|
||||
m_recentAreaWidget->setFixedHeight(height());
|
||||
m_toolAreaWidget->setFixedHeight(height());
|
||||
//m_toolAreaWidget->setFixedHeight(height());
|
||||
} else {
|
||||
m_appAreaSonWidget->setMaximumWidth(width());
|
||||
m_appAreaSonWidget->setMaximumHeight(m_appAreaWidget->height());
|
||||
m_recentAreaWidget->setFixedWidth(width());
|
||||
m_toolAreaWidget->setFixedWidth(width());
|
||||
//m_toolAreaWidget->setFixedWidth(width());
|
||||
}
|
||||
|
||||
m_appAreaSonWidget->adjustSize();
|
||||
@ -434,10 +462,13 @@ void MainPanelControl::insertItem(int index, DockItem *item)
|
||||
addTrayAreaItem(index, item);
|
||||
break;
|
||||
case DockItem::Plugins:
|
||||
//addPluginAreaItem(index, item);
|
||||
m_toolHelper->addPluginItem(index, item);
|
||||
break;
|
||||
default: break;
|
||||
case DockItem::AppMultiWindow:
|
||||
m_multiHelper->addMultiWindow(index, static_cast<AppMultiItem *>(item));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// 同removeItem处 注意:不能屏蔽此接口,否则会造成插件插入时无法显示
|
||||
@ -469,7 +500,11 @@ void MainPanelControl::removeItem(DockItem *item)
|
||||
case DockItem::Plugins:
|
||||
m_toolHelper->removePluginItem(item);
|
||||
break;
|
||||
default: break;
|
||||
case DockItem::AppMultiWindow:
|
||||
m_multiHelper->removeMultiWindow(static_cast<AppMultiItem *>(item));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
item->removeEventFilter(this);
|
||||
@ -954,7 +989,7 @@ void MainPanelControl::updateModeChange()
|
||||
m_trayAreaWidget->setVisible(m_displayMode == DisplayMode::Efficient);
|
||||
m_traySpliter->setVisible(m_displayMode == DisplayMode::Efficient);
|
||||
m_pluginAreaWidget->setVisible(m_displayMode == DisplayMode::Efficient);
|
||||
m_trayManagerWidget->setVisible(m_displayMode != DisplayMode::Efficient);
|
||||
m_toolAreaWidget->setVisible(m_displayMode == DisplayMode::Fashion);
|
||||
onRecentVisibleChanged(m_recentHelper->recentIsVisible());
|
||||
onDockAppVisibleChanged(m_recentHelper->dockAppIsVisible());
|
||||
onToolVisibleChanged(m_toolHelper->toolIsVisible());
|
||||
@ -969,20 +1004,11 @@ void MainPanelControl::moveAppSonWidget()
|
||||
{
|
||||
QRect rect(QPoint(0, 0), m_appAreaSonWidget->size());
|
||||
if (DisplayMode::Efficient == m_displayMode) {
|
||||
switch (m_position) {
|
||||
case Top:
|
||||
case Bottom :
|
||||
rect.moveTo(m_appAreaWidget->pos());
|
||||
break;
|
||||
case Right:
|
||||
case Left:
|
||||
rect.moveTo(m_appAreaWidget->pos());
|
||||
break;
|
||||
}
|
||||
rect.moveTo(m_appAreaWidget->pos());
|
||||
} else {
|
||||
switch (m_position) {
|
||||
case Top:
|
||||
case Bottom :
|
||||
case Bottom:
|
||||
rect.moveCenter(this->rect().center());
|
||||
if (rect.right() > m_appAreaWidget->geometry().right()) {
|
||||
rect.moveRight(m_appAreaWidget->geometry().right());
|
||||
@ -1041,7 +1067,7 @@ QPainterPath MainPanelControl::areaPath()
|
||||
if (m_recentLayout->count() > 0)
|
||||
leftWidth += m_recentAreaWidget->width();
|
||||
|
||||
if (m_toolLayout->count() > 0)
|
||||
if (m_toolAreaLayout->count() > 0)
|
||||
leftWidth += m_toolAreaWidget->width();
|
||||
|
||||
int roundHeight = height();
|
||||
@ -1053,7 +1079,7 @@ QPainterPath MainPanelControl::areaPath()
|
||||
if (m_recentLayout->count() > 0)
|
||||
topHeight += m_recentAreaWidget->height();
|
||||
|
||||
if (m_toolLayout->count() > 0)
|
||||
if (m_toolAreaLayout->count() > 0)
|
||||
topHeight += m_toolAreaWidget->height();
|
||||
|
||||
path.addRoundedRect(QRect(0, 0, roundWidth, topHeight), radius, radius);
|
||||
@ -1086,7 +1112,7 @@ QSize MainPanelControl::suitableSize(int screenSize, double deviceRatio) const
|
||||
// 减去右侧托盘和快捷设置还有插件区域的尺寸
|
||||
totalLength -= (((m_position == Position::Top || m_position == Position::Bottom) ? traySuitableSize.width() : traySuitableSize.height()) / ratio);
|
||||
// 需要参与计算的图标的总数
|
||||
int iconCount = m_fixedAreaLayout->count() + m_appAreaSonLayout->count() + m_recentLayout->count() + m_toolLayout->count();
|
||||
int iconCount = m_fixedAreaLayout->count() + m_appAreaSonLayout->count() + m_recentLayout->count() + m_toolAreaLayout->count();
|
||||
if (iconCount <= 0) {
|
||||
if (m_position == Position::Top || m_position == Position::Bottom)
|
||||
return QSize((static_cast<int>((traySuitableSize.width() + 20) / ratio)), height());
|
||||
@ -1195,7 +1221,12 @@ void MainPanelControl::resizeDockIcon()
|
||||
// 减去右侧托盘和插件区域的宽度
|
||||
totalLength -= ((m_position == Position::Top) || (m_position == Position::Bottom)) ? trayManagerSize.width() : trayManagerSize.height();
|
||||
|
||||
iconCount = m_fixedAreaLayout->count() + m_appAreaSonLayout->count() + m_recentLayout->count();
|
||||
iconCount = m_fixedAreaLayout->count() + m_appAreaSonLayout->count();
|
||||
if (m_recentAreaWidget->isVisible())
|
||||
iconCount += m_recentLayout->count();
|
||||
|
||||
if (m_toolAreaWidget->isVisible())
|
||||
iconCount += m_toolSonLayout->count();
|
||||
|
||||
if (iconCount <= 0)
|
||||
return;
|
||||
@ -1333,11 +1364,11 @@ void MainPanelControl::calcuDockIconSize(int w, int h, int traySize)
|
||||
m_recentSpliter->setFixedSize(int(h * 0.6), SPLITER_SIZE);
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_appAreaSonLayout->count(); ++i)
|
||||
m_appAreaSonLayout->itemAt(i)->widget()->setFixedSize(appItemSize, appItemSize);
|
||||
|
||||
// 时尚模式下判断是否需要显示最近打开的应用区域
|
||||
if (m_displayMode == Dock::DisplayMode::Fashion) {
|
||||
for (int i = 0; i < m_appAreaSonLayout->count(); ++i)
|
||||
m_appAreaSonLayout->itemAt(i)->widget()->setFixedSize(appItemSize, appItemSize);
|
||||
|
||||
if (m_recentLayout->count() > 0) {
|
||||
for (int i = 0; i < m_recentLayout->count(); ++i)
|
||||
m_recentLayout->itemAt(i)->widget()->setFixedSize(appItemSize, appItemSize);
|
||||
@ -1349,14 +1380,61 @@ void MainPanelControl::calcuDockIconSize(int w, int h, int traySize)
|
||||
m_recentAreaWidget->setFixedHeight(appItemSize * m_recentLayout->count());
|
||||
}
|
||||
|
||||
if (m_toolLayout->count() > 0) {
|
||||
for (int i = 0; i < m_toolLayout->count(); i++)
|
||||
m_toolLayout->itemAt(i)->widget()->setFixedSize(appItemSize, appItemSize);
|
||||
if (m_multiWindowLayout->count() > 0) {
|
||||
QList<QSize> multiSizes;
|
||||
for (int i = 0; i < m_multiWindowLayout->count(); i++) {
|
||||
// 因为多开窗口的长宽会不一样,因此,需要将当前的尺寸传入
|
||||
// 由它自己来计算自己的长宽尺寸
|
||||
AppMultiItem *appMultiItem = qobject_cast<AppMultiItem *>(m_multiWindowLayout->itemAt(i)->widget());
|
||||
if (!appMultiItem)
|
||||
continue;
|
||||
|
||||
if (m_position == Dock::Position::Top || m_position == Dock::Position::Bottom)
|
||||
m_toolAreaWidget->setFixedWidth(appItemSize * m_toolLayout->count());
|
||||
else
|
||||
m_toolAreaWidget->setFixedHeight(appItemSize * m_toolLayout->count());
|
||||
QSize size = appMultiItem->suitableSize(appItemSize);
|
||||
appMultiItem->setFixedSize(size);
|
||||
multiSizes << size;
|
||||
}
|
||||
// 计算多开窗口的尺寸
|
||||
int totalSize = 0;
|
||||
if (m_position == Dock::Position::Top || m_position == Dock::Position::Bottom) {
|
||||
for (QSize size : multiSizes)
|
||||
totalSize += size.width();
|
||||
|
||||
m_multiWindowWidget->setFixedSize(totalSize, appItemSize);
|
||||
} else {
|
||||
for (QSize size : multiSizes)
|
||||
totalSize += size.height();
|
||||
|
||||
m_multiWindowWidget->setFixedSize(appItemSize, totalSize);
|
||||
}
|
||||
} else {
|
||||
m_multiWindowWidget->setFixedSize(0, 0);
|
||||
}
|
||||
if (m_toolSonLayout->count() > 0) {
|
||||
for (int i = 0; i < m_toolSonLayout->count(); i++)
|
||||
m_toolSonLayout->itemAt(i)->widget()->setFixedSize(appItemSize, appItemSize);
|
||||
|
||||
if (m_position == Dock::Position::Top || m_position == Dock::Position::Bottom) {
|
||||
m_toolSonAreaWidget->setFixedWidth(appItemSize * m_toolSonLayout->count());
|
||||
} else {
|
||||
m_toolSonAreaWidget->setFixedHeight(appItemSize * m_toolSonLayout->count());
|
||||
}
|
||||
}
|
||||
|
||||
if (m_position == Dock::Position::Top || m_position == Dock::Position::Bottom)
|
||||
m_toolAreaWidget->setFixedWidth(m_multiWindowWidget->width() + m_toolSonAreaWidget->width());
|
||||
else
|
||||
m_toolAreaWidget->setFixedHeight(m_multiWindowWidget->height() + m_toolSonAreaWidget->height());
|
||||
} else {
|
||||
for (int i = 0; i < m_appAreaSonLayout->count(); ++i) {
|
||||
DockItem *dockItem = qobject_cast<DockItem *>(m_appAreaSonLayout->itemAt(i)->widget());
|
||||
if (!dockItem)
|
||||
continue;
|
||||
if (dockItem->itemType() == DockItem::ItemType::AppMultiWindow) {
|
||||
AppMultiItem *appMultiItem = qobject_cast<AppMultiItem *>(dockItem);
|
||||
dockItem->setFixedSize(appMultiItem->suitableSize(appItemSize));
|
||||
} else {
|
||||
dockItem->setFixedSize(appItemSize, appItemSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,6 +43,7 @@ class TrayManagerWindow;
|
||||
class DockScreen;
|
||||
class RecentAppHelper;
|
||||
class ToolAppHelper;
|
||||
class MultiWindowHelper;
|
||||
|
||||
class MainPanelControl : public QWidget
|
||||
{
|
||||
@ -132,8 +133,12 @@ private:
|
||||
QWidget *m_recentAreaWidget; // 最近打开应用
|
||||
QBoxLayout *m_recentLayout;
|
||||
QLabel *m_recentSpliter; // 最近打开应用区域分割线
|
||||
QWidget *m_toolAreaWidget; // 工具区域
|
||||
QBoxLayout *m_toolLayout; // 工具区域布局
|
||||
QWidget *m_toolAreaWidget; // 工具区域,用来存放多开窗口和回收站等
|
||||
QBoxLayout *m_toolAreaLayout; // 工具区域的布局
|
||||
QWidget *m_multiWindowWidget; // 多开窗口区域,用来存放多开窗口
|
||||
QBoxLayout *m_multiWindowLayout;// 用来存放多开窗口的布局
|
||||
QWidget *m_toolSonAreaWidget; // 工具区域,用来存放回收站等工具
|
||||
QBoxLayout *m_toolSonLayout; // 工具区域布局
|
||||
|
||||
TrayManagerWindow *m_trayManagerWidget;
|
||||
QBoxLayout *m_pluginLayout; // 插件区域布局
|
||||
@ -152,6 +157,7 @@ private:
|
||||
DockInter *m_dockInter;
|
||||
RecentAppHelper *m_recentHelper;
|
||||
ToolAppHelper *m_toolHelper;
|
||||
MultiWindowHelper *m_multiHelper;
|
||||
};
|
||||
|
||||
#endif // MAINPANELCONTROL_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user