diff --git a/frame/util/multiscreenworker.cpp b/frame/util/multiscreenworker.cpp index 43651ff9f..3c779bec6 100644 --- a/frame/util/multiscreenworker.cpp +++ b/frame/util/multiscreenworker.cpp @@ -124,8 +124,8 @@ QRect MultiScreenWorker::dockRect(const QString &screenName, const Position &pos { if (hideMode == HideMode::KeepShowing || (hideMode == HideMode::SmartHide && m_hideState == HideState::Show)) return getDockShowGeometry(screenName, pos, displayMode); - else - return getDockHideGeometry(screenName, pos, displayMode); + + return getDockHideGeometry(screenName, pos, displayMode); } /** @@ -236,7 +236,18 @@ void MultiScreenWorker::onExtralRegionMonitorChanged(int x, int y, const QString void MultiScreenWorker::showAniFinished() { - const QRect rect = dockRect(m_ds.current(), m_position, HideMode::KeepShowing, m_displayMode); + QRect rect = dockRect(m_ds.current(), m_position, HideMode::KeepShowing, m_displayMode); + if (m_displayMode == Dock::DisplayMode::Fashion + && (m_position == Dock::Position::Top || m_position == Dock::Position::Bottom)) { + // 特效模式下且在上下位置,需要先设置高度,因为trayManager + // 里面需要根据顶层窗口的高度来设置显示一行还是两行, + // 此时trayManager的长度就会发送变化,返回的建议值才是正确的尺寸值 + parent()->setFixedHeight(rect.height()); + // 调用更新布局接口来调整trayManager窗口的尺寸 + parent()->panel()->updatePluginsLayout(); + // 重新获取窗口尺寸 + rect = dockRect(m_ds.current(), m_position, HideMode::KeepShowing, m_displayMode); + } parent()->setFixedSize(rect.size()); parent()->setGeometry(rect); @@ -883,6 +894,19 @@ void MultiScreenWorker::onRequestDelayShowDock() } } +void MultiScreenWorker::onChildSizeChanged() +{ + // 如果当前为隐藏,则无需再次设置其尺寸 + if (parent()->height() == 0) + return; + + QSize dockSize = dockRect(m_ds.current(), position(), HideMode::KeepShowing, displayMode()).size(); + parent()->setFixedSize(dockSize); + parent()->panel()->setFixedSize(dockSize); + parent()->panel()->move(0, 0); + parent()->panel()->update(); +} + MainWindow *MultiScreenWorker::parent() { return static_cast(m_parent); @@ -892,6 +916,7 @@ void MultiScreenWorker::initMembers() { m_monitorUpdateTimer->setInterval(100); m_monitorUpdateTimer->setSingleShot(true); + parent()->panel()->setDockScreen(&m_ds); m_delayWakeTimer->setSingleShot(true); @@ -907,7 +932,7 @@ void MultiScreenWorker::initConnection() connect(qApp, &QApplication::primaryScreenChanged, this, &MultiScreenWorker::primaryScreenChanged); connect(DIS_INS, &DisplayManager::primaryScreenChanged, this, &MultiScreenWorker::primaryScreenChanged); connect(DIS_INS, &DisplayManager::screenInfoChanged, this, &MultiScreenWorker::requestUpdateMonitorInfo); - connect(parent()->panel(), &MainPanelControl::sizeChanged, this, [ this ] { resetDockScreen(); }); + connect(parent()->panel(), &MainPanelControl::sizeChanged, this, &MultiScreenWorker::onChildSizeChanged); connect(m_launcherInter, static_cast(&DBusLuncher::VisibleChanged), this, [ = ](bool value) { setStates(LauncherDisplay, value); }); @@ -1508,38 +1533,38 @@ QRect MultiScreenWorker::getDockShowGeometry(const QString &screenName, const Po QRect screenRect = s->handle()->geometry(); switch (pos) { - case Position::Top: - parent()->panel()->setScreenSize(static_cast(screenRect.width())); - - rect.setX((static_cast(screenRect.width() / ratio) - parent()->panel()->suitableSize(ratio).width()) / 2); + case Position::Top: { + QSize panelSize = parent()->panel()->suitableSize(screenRect.width(), ratio); + rect.setX((static_cast(screenRect.width() / ratio) - panelSize.width()) / 2); rect.setY(static_cast((screenRect.y() + margin) / ratio)); - rect.setWidth(parent()->panel()->suitableSize(ratio).width()); + rect.setWidth(panelSize.width()); rect.setHeight(dockSize); + } break; - case Position::Bottom: + case Position::Bottom: { // 先用设置屏幕尺寸,理论上不应该在此处设置,因为这是在一个get方法里面,后续改成直接获取,在其他地方设置 - parent()->panel()->setScreenSize(static_cast(screenRect.width())); - - rect.setX((static_cast(screenRect.width() / ratio) - parent()->panel()->suitableSize(ratio).width()) / 2); + QSize panelSize = parent()->panel()->suitableSize(screenRect.width(), ratio); + rect.setX((static_cast(screenRect.width() / ratio) - panelSize.width()) / 2); rect.setY(static_cast(screenRect.y() + screenRect.height() / ratio - margin - dockSize)); - rect.setWidth(parent()->panel()->suitableSize(ratio).width()); + rect.setWidth(panelSize.width()); rect.setHeight(dockSize); + } break; - case Position::Left: - parent()->panel()->setScreenSize(static_cast(screenRect.height())); - + case Position::Left: { + QSize panelSize = parent()->panel()->suitableSize(screenRect.height(), ratio); rect.setX(static_cast(screenRect.x() + margin)); - rect.setY((static_cast(screenRect.height() / ratio) - parent()->panel()->suitableSize(ratio).height()) / 2); + rect.setY((static_cast(screenRect.height() / ratio) - panelSize.height()) / 2); rect.setWidth(dockSize); - rect.setHeight(parent()->panel()->suitableSize(ratio).height()); + rect.setHeight(panelSize.height()); + } break; - case Position::Right: - parent()->panel()->setScreenSize(static_cast(screenRect.height())); - + case Position::Right: { + QSize panelSize = parent()->panel()->suitableSize(screenRect.height(), ratio); rect.setX(static_cast(screenRect.x() + screenRect.width() / ratio - margin - dockSize)); - rect.setY((static_cast(screenRect.height() / ratio) - parent()->panel()->suitableSize(ratio).height()) / 2); + rect.setY((static_cast(screenRect.height() / ratio) - panelSize.height()) / 2); rect.setWidth(dockSize); - rect.setHeight(parent()->panel()->suitableSize(ratio).height()); + rect.setHeight(panelSize.height()); + } break; } } @@ -1568,29 +1593,36 @@ QRect MultiScreenWorker::getDockHideGeometry(const QString &screenName, const Po QRect screenRect = s->handle()->geometry(); switch (pos) { - case Position::Top: - rect.setX(static_cast(screenRect.x() + margin)); + case Position::Top: { + QSize panelSize = parent()->panel()->suitableSize(screenRect.width(), ratio); + rect.setX(static_cast((screenRect.width() / ratio - panelSize.width()) / 2)); rect.setY(static_cast(screenRect.y() + margin)); - rect.setWidth(static_cast(screenRect.width() / ratio - 2 * margin)); + rect.setWidth(panelSize.width()); rect.setHeight(0); + } break; - case Position::Bottom: - rect.setX(static_cast(screenRect.x() + margin)); + case Position::Bottom: { + QSize panelSize = parent()->panel()->suitableSize(screenRect.width(), ratio); + rect.setX(static_cast((screenRect.width() / ratio - panelSize.width()) / 2)); rect.setY(static_cast(screenRect.y() + screenRect.height() / ratio - margin)); - rect.setWidth(static_cast(screenRect.width() / ratio - 2 * margin)); + rect.setWidth(panelSize.width()); rect.setHeight(0); + } break; - case Position::Left: + case Position::Left: { + QSize panelSize = parent()->panel()->suitableSize(screenRect.height(), ratio); rect.setX(static_cast(screenRect.x() + margin)); - rect.setY(static_cast(screenRect.y() + margin)); + rect.setY(static_cast(static_cast((screenRect.height() / ratio - panelSize.height()) / 2))); rect.setWidth(0); - rect.setHeight(static_cast(screenRect.height() / ratio - 2 * margin)); + rect.setHeight(panelSize.height()); + } break; case Position::Right: + QSize panelSize = parent()->panel()->suitableSize(screenRect.height(), ratio); rect.setX(static_cast(screenRect.x() + screenRect.width() / ratio - margin)); - rect.setY(static_cast(screenRect.y() + margin)); + rect.setY(static_cast(static_cast((screenRect.height() / ratio - panelSize.height()) / 2))); rect.setWidth(0); - rect.setHeight(static_cast(screenRect.height() / ratio - 2 * margin)); + rect.setHeight(panelSize.height()); break; } } diff --git a/frame/util/multiscreenworker.h b/frame/util/multiscreenworker.h index abebf10b4..719e29e44 100644 --- a/frame/util/multiscreenworker.h +++ b/frame/util/multiscreenworker.h @@ -211,6 +211,9 @@ private slots: void onDelayAutoHideChanged(); + // 子部件尺寸发生变化 + void onChildSizeChanged(); + private: MainWindow *parent(); // 初始化数据信息 diff --git a/frame/window/mainpanelcontrol.cpp b/frame/window/mainpanelcontrol.cpp index 116f1cad4..b37c61b9b 100755 --- a/frame/window/mainpanelcontrol.cpp +++ b/frame/window/mainpanelcontrol.cpp @@ -32,6 +32,8 @@ #include "desktop_widget.h" #include "imageutil.h" #include "traymanagerwindow.h" +#include "multiscreenworker.h" +#include "displaymanager.h" #include #include @@ -90,8 +92,8 @@ MainPanelControl::MainPanelControl(QWidget *parent) , m_appDragWidget(nullptr) , m_dislayMode(Efficient) , m_tray(nullptr) - , m_screenSize(-1) , m_trashItem(nullptr) + , m_dockScreen(nullptr) { initUI(); updateMainPanelLayout(); @@ -992,6 +994,12 @@ void MainPanelControl::updatePluginsLayout() } } } + m_trayManagerWidget->updateLayout(); +} + +void MainPanelControl::setDockScreen(DockScreen *dockScreen) +{ + m_dockScreen = dockScreen; } QPainterPath MainPanelControl::areaPath() @@ -1015,14 +1023,9 @@ QPainterPath MainPanelControl::areaPath() return path; } -void MainPanelControl::setScreenSize(int size) +QSize MainPanelControl::suitableSize(int screenSize, double deviceRatio) const { - m_screenSize = size; -} - -QSize MainPanelControl::suitableSize(double deviceRatio) -{ - if (m_screenSize <= 0) + if (screenSize <= 0) return QSize(-1, -1); double ratio = deviceRatio; @@ -1032,22 +1035,23 @@ QSize MainPanelControl::suitableSize(double deviceRatio) if (m_dislayMode == DisplayMode::Efficient) { // 如果是高效模式 if (m_position == Position::Top || m_position == Position::Bottom) - return QSize(static_cast(m_screenSize / ratio), height()); + return QSize(static_cast(screenSize / ratio), height()); - return QSize(width(), static_cast(m_screenSize / ratio)); + return QSize(width(), static_cast(screenSize / ratio)); } + QSize traySuitableSize = m_trayManagerWidget->suitableSize(); // 如果是特效模式 - int totalLength = static_cast(m_screenSize / ratio); + int totalLength = static_cast(screenSize / ratio); // 减去右侧托盘和快捷设置还有插件区域的尺寸 - totalLength -= (((m_position == Position::Top || m_position == Position::Bottom) ? m_trayManagerWidget->width() : m_trayManagerWidget->height()) / ratio); + totalLength -= (((m_position == Position::Top || m_position == Position::Bottom) ? traySuitableSize.width() : traySuitableSize.height()) / ratio); // 需要参与计算的图标的总数 int iconCount = m_fixedAreaLayout->count() + m_appAreaSonLayout->count(); if (iconCount <= 0) { if (m_position == Position::Top || m_position == Position::Bottom) - return QSize((static_cast((m_trayManagerWidget->width() + 20) / ratio)), height()); + return QSize((static_cast((traySuitableSize.width() + 20) / ratio)), height()); - return QSize(width(), static_cast((m_trayManagerWidget->height() + 20) / ratio)); + return QSize(width(), static_cast((traySuitableSize.height() + 20) / ratio)); } int yu = (totalLength % iconCount); @@ -1056,13 +1060,13 @@ QSize MainPanelControl::suitableSize(double deviceRatio) if (m_position == Position::Top || m_position == Position::Bottom) { iconSize = iconSize < height() ? iconSize : height(); - return QSize(iconSize * iconCount + static_cast((m_fixedSpliter->width() + m_trayManagerWidget->width() + 20) / ratio), + return QSize(iconSize * iconCount + static_cast((m_fixedSpliter->width() + traySuitableSize.width() + 20) / ratio), static_cast(height() / ratio)); } iconSize = iconSize < width() ? iconSize : width(); - return QSize(width(), iconSize * iconCount + static_cast((m_fixedSpliter->height() + m_trayManagerWidget->height() + 20) / ratio)); + return QSize(width(), iconSize * iconCount + static_cast((m_fixedSpliter->height() + traySuitableSize.height() + 20) / ratio)); } void MainPanelControl::itemUpdated(DockItem *item) @@ -1090,6 +1094,24 @@ void MainPanelControl::paintEvent(QPaintEvent *event) painter.fillRect(m_traySpliter->geometry(), color); } +// 获取当前屏幕的高或者宽(任务栏上下的时候获取宽,左右获取高) +int MainPanelControl::getScreenSize() const +{ + QScreen *currentScreen = qApp->primaryScreen(); + if (m_dockScreen) { + DisplayManager *displayManager = DisplayManager::instance(); + QScreen *screen = displayManager->screen(m_dockScreen->current()); + if (screen) + currentScreen = screen; + } + + QRect screenRect = currentScreen->handle()->geometry(); + if (m_position == Dock::Position::Top || m_position == Dock::Position::Bottom) + return screenRect.width(); + + return screenRect.height(); +} + /**重新计算任务栏上应用图标、插件图标的大小,并设置 * @brief MainPanelControl::resizeDockIcon */ @@ -1100,7 +1122,7 @@ void MainPanelControl::resizeDockIcon() int iconCount = 0; // 总宽度 if (m_dislayMode == DisplayMode::Fashion) { - int totalLength = m_screenSize; + int totalLength = getScreenSize(); // 减去右侧托盘和插件区域的宽度 totalLength -= ((m_position == Position::Top) || (m_position == Position::Bottom)) ? m_trayManagerWidget->width() : m_trayManagerWidget->height(); @@ -1322,13 +1344,22 @@ void MainPanelControl::calcuDockIconSize(int w, int h, int traySize) */ void MainPanelControl::resizeDesktopWidget() { - QSize suitableSize = m_trayManagerWidget->suitableSize(); if (m_position == Position::Right || m_position == Position::Left) { m_desktopWidget->setFixedSize(QWIDGETSIZE_MAX, DESKTOP_SIZE); - m_trayManagerWidget->setFixedSize(QWIDGETSIZE_MAX, suitableSize.height()); + m_trayManagerWidget->setFixedWidth(QWIDGETSIZE_MAX); + m_trayManagerWidget->updateLayout(); + QSize suitableSize = m_trayManagerWidget->suitableSize(); + m_trayManagerWidget->setFixedHeight(suitableSize.height()); } else { m_desktopWidget->setFixedSize(DESKTOP_SIZE, QWIDGETSIZE_MAX); - m_trayManagerWidget->setFixedSize(suitableSize.width(), QWIDGETSIZE_MAX); + // 在调整尺寸过程中,先设置高度,然后更新布局,因为更新布局的时候,里面的 + // Layout需要根据高度来调整布局的部件间距和边距,此时返回的尺寸会有所变化 + // 等布局更新后,再获取返回的尺寸来设置右侧的宽度 + // 如果是左右位置,原理一样 + m_trayManagerWidget->setFixedHeight(QWIDGETSIZE_MAX); + m_trayManagerWidget->updateLayout(); + QSize suitableSize = m_trayManagerWidget->suitableSize(); + m_trayManagerWidget->setFixedWidth(suitableSize.width()); } if (DisplayMode::Fashion == m_dislayMode) diff --git a/frame/window/mainpanelcontrol.h b/frame/window/mainpanelcontrol.h index e2cffe906..3e06cb6dc 100755 --- a/frame/window/mainpanelcontrol.h +++ b/frame/window/mainpanelcontrol.h @@ -39,6 +39,7 @@ class PlaceholderItem; class AppDragWidget; class DesktopWidget; class TrayManagerWindow; +class DockScreen; class MainPanelControl : public QWidget { @@ -50,9 +51,10 @@ public: void setDisplayMode(DisplayMode dislayMode); void resizeDockIcon(); void updatePluginsLayout(); + + void setDockScreen(DockScreen *dockScreen); QPainterPath areaPath(); - void setScreenSize(int size); - QSize suitableSize(double deviceRatio); + QSize suitableSize(int screenSize, double deviceRatio) const; public slots: void insertItem(const int index, DockItem *item); @@ -80,6 +82,7 @@ private: void removeTrayAreaItem(QWidget *wdg); void addPluginAreaItem(int index, QWidget *wdg); void removePluginAreaItem(QWidget *wdg); + int getScreenSize() const; // 拖拽相关 void startDrag(DockItem *); @@ -129,9 +132,9 @@ private: QPoint m_mousePressPos; TrayPluginItem *m_tray; int m_dragIndex = -1; // 记录应用区域被拖拽图标的位置 - int m_screenSize; PluginsItem *m_trashItem; // 垃圾箱插件(需要特殊处理一下) + DockScreen *m_dockScreen; }; #endif // MAINPANELCONTROL_H diff --git a/frame/window/systempluginwindow.cpp b/frame/window/systempluginwindow.cpp index 80c951032..e9bfcf30d 100644 --- a/frame/window/systempluginwindow.cpp +++ b/frame/window/systempluginwindow.cpp @@ -100,12 +100,6 @@ QSize SystemPluginWindow::suitableSize() return QSize(QWIDGETSIZE_MAX, itemHeight); } -void SystemPluginWindow::resizeEvent(QResizeEvent *event) -{ - QWidget::resizeEvent(event); - Q_EMIT sizeChanged(); -} - void SystemPluginWindow::initUi() { m_mainLayout->setContentsMargins(0, 0, 0, 0); diff --git a/frame/window/systempluginwindow.h b/frame/window/systempluginwindow.h index 31642cde8..2c7314337 100644 --- a/frame/window/systempluginwindow.h +++ b/frame/window/systempluginwindow.h @@ -47,9 +47,6 @@ public: Q_SIGNALS: void sizeChanged(); -protected: - void resizeEvent(QResizeEvent *event) override; - private: void initUi(); diff --git a/frame/window/traymanagerwindow.cpp b/frame/window/traymanagerwindow.cpp index b8cc261ba..095660452 100644 --- a/frame/window/traymanagerwindow.cpp +++ b/frame/window/traymanagerwindow.cpp @@ -76,6 +76,22 @@ TrayManagerWindow::~TrayManagerWindow() { } +void TrayManagerWindow::updateLayout() +{ + bool showSingle = true; + if (m_postion == Dock::Position::Top || m_postion == Dock::Position::Bottom) + showSingle = (topLevelWidget()->height() <= CRITLCALHEIGHT); + + if (showSingle) + resetSingleDirection(); + else + resetMultiDirection(); + + resetChildWidgetSize(); + // 当尺寸发生变化的时候,通知托盘区域刷新尺寸,让托盘图标始终保持居中显示 + Q_EMIT m_delegate->sizeHintChanged(m_model->index(0, 0)); +} + void TrayManagerWindow::setPositon(Dock::Position position) { if (m_postion == position) @@ -169,7 +185,7 @@ void TrayManagerWindow::resizeEvent(QResizeEvent *event) { Q_UNUSED(event); - resetDirection(); + updateLayout(); } void TrayManagerWindow::initUi() @@ -277,28 +293,7 @@ void TrayManagerWindow::initConnection() m_trayView->installEventFilter(this); m_quickIconWidget->installEventFilter(this); installEventFilter(this); - QMetaObject::invokeMethod(this, &TrayManagerWindow::resetDirection, Qt::QueuedConnection); -} - -void TrayManagerWindow::resetDirection() -{ - if (showSingleRow()) - resetSingleDirection(); - else - resetMultiDirection(); - - resetChildWidgetSize(); - // 当尺寸发生变化的时候,通知托盘区域刷新尺寸,让托盘图标始终保持居中显示 - Q_EMIT m_delegate->sizeHintChanged(m_model->index(0, 0)); - Q_EMIT sizeChanged(); -} - -bool TrayManagerWindow::showSingleRow() -{ - if (m_postion == Dock::Position::Top || m_postion == Dock::Position::Bottom) - return topLevelWidget()->height() <= CRITLCALHEIGHT; - - return true; + QMetaObject::invokeMethod(this, &TrayManagerWindow::sizeChanged, Qt::QueuedConnection); } void TrayManagerWindow::resetChildWidgetSize() diff --git a/frame/window/traymanagerwindow.h b/frame/window/traymanagerwindow.h index 0b30a6289..554acd4f7 100644 --- a/frame/window/traymanagerwindow.h +++ b/frame/window/traymanagerwindow.h @@ -51,6 +51,8 @@ class TrayManagerWindow : public QWidget public: explicit TrayManagerWindow(QWidget *parent = nullptr); ~TrayManagerWindow() override; + + void updateLayout(); void setPositon(Dock::Position position); QSize suitableSize(); @@ -69,13 +71,11 @@ private: void initUi(); void initConnection(); - void resetDirection(); void resetChildWidgetSize(); void resetMultiDirection(); void resetSingleDirection(); QColor maskColor(uint8_t alpha) const; - bool showSingleRow(); int appDatetimeSize(); QPainterPath roundedPaths();