diff options
author | Nate Graham <nate@kde.org> | 2020-07-29 21:22:22 -0600 |
---|---|---|
committer | Nate Graham <nate@kde.org> | 2020-08-02 08:52:41 -0600 |
commit | 1434257972de28f183e701cb7da3bd333fa71f3c (patch) | |
tree | 8ed00a476e0bf1222f4c8d008ce22763f9f99bb3 /src/gui/kwindowconfig.cpp | |
parent | 3e5e2ea59ea66ffaa5eff81a6f220c8469f19733 (diff) | |
download | kconfig-1434257972de28f183e701cb7da3bd333fa71f3c.tar.gz kconfig-1434257972de28f183e701cb7da3bd333fa71f3c.tar.bz2 |
Add functions to save and restore window positions on non-Wayland platforms
These functions allow an application to save and restore the positions
of its windows. Positions are stored on a per-screen-arrangement basis.
For example with a single screen connected, the config file would have
entries like this in it:
eDP-1 XPosition=140
eDP-1 YPosition=340
When a second screen is connected, the following gets saved:
eDP-1 HDMI-1 XPosition=3878
eDP-1 HDMI-1 YPosition=29
This ensures that each separate screen arrangement can have its own
saved window position, which is handy for the use case where you have a
laptop that you plug into an external screen some of the time. It also
allows the position to get restored to the correct screen when there are
multiple screens.
This is a necessary first step to getting KDE apps to save their window
positions on X11 The next step would be calling the new functions from
KXMLGui and Kirigami apps, and then porting all apps that manually invoke
KWindowConfig::saveWindowSize() and KWindowConfig::restoreWindowSize()
to also invoke KWindowConfig::saveWindowPosition() and
KWindowConfig::restoreWindowPosition() in the same places.
The functions only work on X11 or other non-Wayland platforms. On
Wayland, the compositor has sole dominion over window positioning so a
compositor-specific solution much be adopted instead, such as
https://bugs.kde.org/show_bug.cgi?id=15329.
CCBUG: 415150
Diffstat (limited to 'src/gui/kwindowconfig.cpp')
-rw-r--r-- | src/gui/kwindowconfig.cpp | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/src/gui/kwindowconfig.cpp b/src/gui/kwindowconfig.cpp index 2f787a2f..07f1a307 100644 --- a/src/gui/kwindowconfig.cpp +++ b/src/gui/kwindowconfig.cpp @@ -7,6 +7,7 @@ #include "kwindowconfig.h" +#include <QGuiApplication> #include <QScreen> #include <QWindow> @@ -71,3 +72,60 @@ void KWindowConfig::restoreWindowSize(QWindow *window, const KConfigGroup &confi window->setWindowState(Qt::WindowMaximized); } } + +void KWindowConfig::saveWindowPosition(const QWindow *window, KConfigGroup &config, KConfigGroup::WriteConfigFlags options) +{ + // On Wayland, the compositor is solely responsible for window positioning, + // So this needs to be a no-op + if (!window || QGuiApplication::platformName() == QStringLiteral("wayland")) { + return; + } + + // Prepend the names of all connected screens so that we save the position + // on a per-screen-arrangement basis, since people often like to have + // windows positioned differently depending on their screen arrangements + QStringList names; + const auto screens = QGuiApplication::screens(); + names.reserve(screens.length()); + for (auto screen : screens) { + names << screen->name(); + } + const QString allScreens = names.join(QStringLiteral(" ")); + config.writeEntry(allScreens + QStringLiteral(" XPosition"), window->x(), options); + config.writeEntry(allScreens + QStringLiteral(" YPosition"), window->y(), options); +} + +void KWindowConfig::restoreWindowPosition(QWindow *window, const KConfigGroup &config) +{ + // On Wayland, the compositor is solely responsible for window positioning, + // So this needs to be a no-op + if (!window || QGuiApplication::platformName() == QStringLiteral("wayland")) { + return; + } + + const QRect desk = window->screen()->geometry(); + const bool isMaximized = config.readEntry(QStringLiteral("Window-Maximized %1x%2").arg(desk.height()).arg(desk.width()), false); + + // Don't need to restore position if the window was maximized + if (isMaximized) { + window->setWindowState(Qt::WindowMaximized); + return; + } + + QStringList names; + const auto screens = QGuiApplication::screens(); + names.reserve(screens.length()); + for (auto screen : screens) { + names << screen->name(); + } + const QString allScreens = names.join(QStringLiteral(" ")); + const int xPos = config.readEntry(allScreens + QStringLiteral(" XPosition"), -1); + const int yPos = config.readEntry(allScreens + QStringLiteral(" YPosition"), -1); + + if (xPos == -1 || yPos == -1) { + return; + } + + window->setX(xPos); + window->setY(yPos); +} |