aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNate Graham <nate@kde.org>2020-07-29 21:22:22 -0600
committerNate Graham <nate@kde.org>2020-08-02 08:52:41 -0600
commit1434257972de28f183e701cb7da3bd333fa71f3c (patch)
tree8ed00a476e0bf1222f4c8d008ce22763f9f99bb3 /src
parent3e5e2ea59ea66ffaa5eff81a6f220c8469f19733 (diff)
downloadkconfig-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')
-rw-r--r--src/gui/kwindowconfig.cpp58
-rw-r--r--src/gui/kwindowconfig.h27
2 files changed, 85 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);
+}
diff --git a/src/gui/kwindowconfig.h b/src/gui/kwindowconfig.h
index ad03f3ef..04af27d1 100644
--- a/src/gui/kwindowconfig.h
+++ b/src/gui/kwindowconfig.h
@@ -55,6 +55,33 @@ KCONFIGGUI_EXPORT void saveWindowSize(const QWindow *window, KConfigGroup &confi
* @since 5.0.
*/
KCONFIGGUI_EXPORT void restoreWindowSize(QWindow *window, const KConfigGroup &config);
+
+/**
+ * Saves the window's position either to the global or application config file.
+ * This function has no effect on Wayland, where the compositor is responsible
+ * for window positioning.
+ *
+ * @note the group must be set before calling
+ *
+ * @param window The window whose position to save.
+ * @param config The config group to read from.
+ * @param options passed to KConfigGroup::writeEntry()
+ * @since 5.74
+ */
+KCONFIGGUI_EXPORT void saveWindowPosition(const QWindow *window, KConfigGroup &config, KConfigGroup::WriteConfigFlags options = KConfigGroup::Normal);
+
+/**
+ * Restores the window's position from the configuration.
+ * This function has no effect on Wayland, where the compositor is responsible
+ * for window positioning.
+ *
+ * @note the group must be set before calling
+ *
+ * @param window The window whose position to restore.
+ * @param config The config group to read from.
+ * @since 5.74
+ */
+KCONFIGGUI_EXPORT void restoreWindowPosition(QWindow *window, const KConfigGroup &config);
}
#endif // KWINDOWCONFIG_H