From 06c7ebee9b636f856dac488c211aa4b593253409 Mon Sep 17 00:00:00 2001 From: Nicholas Yoder Date: Fri, 27 Dec 2024 20:15:16 -0500 Subject: [PATCH] Improve multi monitor support --- desktop/desktop-app/desktop.cpp | 25 +++++++++++++++++++------ desktop/desktop-app/desktop.h | 5 +++-- docs/changelog.md | 1 + library/miscutills/miscutills.cpp | 13 +++++++++++++ library/miscutills/miscutills.h | 14 ++++++++++++++ panel/panel-app/geometrymanager.cpp | 10 +++++----- panel/panel-library/popup.h | 16 ++++++++-------- 7 files changed, 63 insertions(+), 21 deletions(-) diff --git a/desktop/desktop-app/desktop.cpp b/desktop/desktop-app/desktop.cpp index d3d124c..e3d2922 100755 --- a/desktop/desktop-app/desktop.cpp +++ b/desktop/desktop-app/desktop.cpp @@ -1,7 +1,7 @@ /* BEGIN_COMMON_COPYRIGHT_HEADER * (c)LGPL3+ * - * Copyright: 2021 Nicholas Yoder + * Copyright: 2021-2024 Nicholas Yoder * * This program or library is free software; you can redistribute it * and/or modify it under the terms of the GNU Lesser General Public @@ -44,7 +44,11 @@ void desktop::setupPlug(){ QDBusConnection::sessionBus().registerObject("/org/forest/desktop", this, QDBusConnection::ExportScriptableSlots); - connect(qApp->primaryScreen(), &QScreen::geometryChanged, this, &desktop::handleAvailableGeoChange); + RunOnce* runner = new RunOnce(2000); + connect(qApp, &QGuiApplication::screenAdded, runner, &RunOnce::try_activate); + connect(qApp, &QGuiApplication::screenRemoved, runner, &RunOnce::try_activate); + connect(qApp->primaryScreen(), &QScreen::geometryChanged, runner, &RunOnce::try_activate); + connect(runner, &RunOnce::activated, this, &desktop::handleScreenChange); } //called by dbus to load new wallpaper @@ -57,14 +61,15 @@ void desktop::reloadwallpaper(){ } void desktop::loadwallpaperwidgets(){ + screen_geos.clear(); foreach (QScreen *screen, qApp->screens()){ + screen_geos.append(screen->geometry()); wallpaperwidget *wallwidget = new wallpaperwidget(GS::WALLPAPER, GS::IMAGE_MODE); wallwidgetlist << wallwidget; wallwidget->setGeometry(screen->geometry()); wallwidget->setFixedSize(screen->size()); if (screen == qApp->primaryScreen()){ - qDebug() << "got primary screen" << screen->size() << getusabledesktopspace(); iwidget = new iconswidget(screen->size(), getusabledesktopspace()); QVBoxLayout *vlayout = new QVBoxLayout; vlayout->setMargin(0); @@ -206,10 +211,18 @@ QRect desktop::getusabledesktopspace(){ return QRect(iconmargin, iconmargin, qApp->primaryScreen()->size().width() - (iconmargin*2), qApp->primaryScreen()->size().height() - (iconmargin*2)); } -void desktop::handleAvailableGeoChange(QRect geo){ - Q_UNUSED(geo); +void desktop::handleScreenChange(){ + // Check if anything actually changed and skip reloading if not + if(qApp->screens().length() == screen_geos.length()){ + bool skip = true; + foreach (QScreen *screen, qApp->screens()){ + if (!screen_geos.contains(screen->geometry())){ + skip = false; + } + } - qDebug() << "geo change"; + if(skip) return; + } foreach(wallpaperwidget *ww, wallwidgetlist){ ww->close(); diff --git a/desktop/desktop-app/desktop.h b/desktop/desktop-app/desktop.h index 8ae85c6..af3ad0f 100755 --- a/desktop/desktop-app/desktop.h +++ b/desktop/desktop-app/desktop.h @@ -1,7 +1,7 @@ /* BEGIN_COMMON_COPYRIGHT_HEADER * (c)LGPL3+ * - * Copyright: 2021 Nicholas Yoder + * Copyright: 2021-2024 Nicholas Yoder * * This program or library is free software; you can redistribute it * and/or modify it under the terms of the GNU Lesser General Public @@ -75,7 +75,7 @@ private slots: void loadicon(QString file); void saveiconlocations(QHash poshash); QRect getusabledesktopspace(); - void handleAvailableGeoChange(QRect geo); + void handleScreenChange(); void handleiconactivated(QString iconID){fmutils::openfile(iconID);} void paste2desktop(){fmutils::pastefromclipboard(QDir::homePath() + "/Desktop");} @@ -102,6 +102,7 @@ private slots: bool shiftdown = false; bool updatepaused = false; + QList screen_geos; QList wallwidgetlist; iconswidget *iwidget; QSettings *settings = new QSettings("Forest", "Forest"); diff --git a/docs/changelog.md b/docs/changelog.md index e812162..8abd608 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -3,6 +3,7 @@ Changelog ============ * UNRELEASED + - Improve multi monitor support - Implement base themes with functional light/dark variations of Circle and Rounded themes - Fix random pixels in tray icons diff --git a/library/miscutills/miscutills.cpp b/library/miscutills/miscutills.cpp index 7cecf38..e1ba2e2 100644 --- a/library/miscutills/miscutills.cpp +++ b/library/miscutills/miscutills.cpp @@ -116,3 +116,16 @@ QString miscutills::pad_with_zeros(int number){ else if (number < 1000) return "0" + QString::number(number); else return QString::number(number); } + + +RunOnce::RunOnce(int delay){ + run_delay = delay; +} + +void RunOnce::try_activate(){ + if(timer && timer->isActive()){timer->stop(); delete timer;} + timer = new QTimer(); + connect(timer, &QTimer::timeout, this, &RunOnce::activated); + timer->setSingleShot(true); + timer->start(run_delay); +} diff --git a/library/miscutills/miscutills.h b/library/miscutills/miscutills.h index f3ae3da..1262c3f 100644 --- a/library/miscutills/miscutills.h +++ b/library/miscutills/miscutills.h @@ -2,6 +2,7 @@ #define MISCUTILLS_H #include +#include enum WALLPAPER_MODE { Fill, Fit, Stretch, Tile, Center}; @@ -27,4 +28,17 @@ class miscutills static QString pad_with_zeros(int number); }; +class RunOnce: public QObject { + Q_OBJECT +public: + RunOnce(int delay = 200); +signals: + void activated(); +public slots: + void try_activate(); +private: + int run_delay; + QTimer *timer = nullptr; +}; + #endif // MISCUTILLS_H diff --git a/panel/panel-app/geometrymanager.cpp b/panel/panel-app/geometrymanager.cpp index c6519e5..36266a8 100644 --- a/panel/panel-app/geometrymanager.cpp +++ b/panel/panel-app/geometrymanager.cpp @@ -58,10 +58,10 @@ void GeometryManager::update_geometry(){ if(fixed_panel_size == 0) fixed_panel_size = panel_widget->sizeHint().height(); - QSize scsize = qApp->primaryScreen()->size(); + QRect sc_geo = qApp->primaryScreen()->geometry(); if (panel_position == "top"){ - panel_widget->move(0,0); - panel_widget->setFixedSize(scsize.width(), fixed_panel_size); + panel_widget->move(sc_geo.left(), 0); + panel_widget->setFixedSize(sc_geo.width(), fixed_panel_size); if(reserve_screen_space) Xcbutills::setPartialStrut(panel_widget->winId(),0,0,panel_widget->height(),0,0,0,0,0,panel_widget->geometry().left(),panel_widget->geometry().right(),0,0); else @@ -75,8 +75,8 @@ void GeometryManager::update_geometry(){ panel_widget->setFixedSize(fixed_panel_size, scsize.height()); //Xcbutills::setPartialStrut(winId(),0,height(),0,0,0,0,geometry().top(),geometry().bottom(),0,0,0,0);*/ } else{//bottom - panel_widget->move(0,scsize.height() - fixed_panel_size); - panel_widget->setFixedSize(scsize.width(), fixed_panel_size); + panel_widget->move(sc_geo.left(), sc_geo.height() - fixed_panel_size); + panel_widget->setFixedSize(sc_geo.width(), fixed_panel_size); if(reserve_screen_space) Xcbutills::setPartialStrut(panel_widget->winId(),0,0,0,panel_widget->height(),0,0,0,0,0,0,panel_widget->geometry().left(),panel_widget->geometry().right()); else diff --git a/panel/panel-library/popup.h b/panel/panel-library/popup.h index 1cb778c..d3f8764 100644 --- a/panel/panel-library/popup.h +++ b/panel/panel-library/popup.h @@ -1,7 +1,7 @@ /* BEGIN_COMMON_COPYRIGHT_HEADER * (c)LGPL3+ * - * Copyright: 2021 Nicholas Yoder + * Copyright: 2021-2024 Nicholas Yoder * * This program or library is free software; you can redistribute it * and/or modify it under the terms of the GNU Lesser General Public @@ -97,15 +97,15 @@ public slots: else if (panelpos == "left") popupRect.moveTo(QPoint(panelRect.width(), launcherRect.x() + edgeoffset));*/ - QSize screensize(qApp->desktop()->screenGeometry(launcherwidget).size()); + QRect screen_geo(qApp->desktop()->screenGeometry(launcherwidget)); QPoint newpos(popupRect.topLeft()); - if (popupRect.x() + popupRect.width() > screensize.width()) - newpos.setX(screensize.width() - popupRect.width()); - if (popupRect.y() + popupRect.height() > screensize.height()) - newpos.setY(screensize.height() - popupRect.height()); - if (popupRect.x() < 0) - newpos.setX(0); + if (popupRect.x() + popupRect.width() > screen_geo.right()) + newpos.setX(screen_geo.right() - popupRect.width()); + if (popupRect.y() + popupRect.height() > screen_geo.height()) + newpos.setY(screen_geo.height() - popupRect.height()); + if (popupRect.x() < screen_geo.left()) + newpos.setX(screen_geo.left()); if (popupRect.y() < 0) newpos.setY(0);