Merge branch 'fix/window-geometry' into 'master'

Persist window size across restarts

See merge request marcoa/a-la-karte!3
This commit is contained in:
Marco Allegretti 2026-02-03 11:25:41 +00:00
commit ecb7eb66d6
3 changed files with 159 additions and 0 deletions

View file

@ -279,6 +279,74 @@ void Config::setTheme(const QString &theme)
} }
} }
int Config::windowWidth() const
{
return m_windowWidth;
}
void Config::setWindowWidth(int width)
{
width = qBound(0, width, 10000);
if (m_windowWidth != width) {
m_windowWidth = width;
save();
Q_EMIT windowWidthChanged();
}
}
int Config::windowHeight() const
{
return m_windowHeight;
}
void Config::setWindowHeight(int height)
{
height = qBound(0, height, 10000);
if (m_windowHeight != height) {
m_windowHeight = height;
save();
Q_EMIT windowHeightChanged();
}
}
bool Config::windowMaximized() const
{
return m_windowMaximized;
}
void Config::setWindowMaximized(bool maximized)
{
if (m_windowMaximized != maximized) {
m_windowMaximized = maximized;
save();
Q_EMIT windowMaximizedChanged();
}
}
void Config::setWindowSize(int width, int height)
{
width = qBound(0, width, 10000);
height = qBound(0, height, 10000);
const bool widthChanged = m_windowWidth != width;
const bool heightChanged = m_windowHeight != height;
if (!widthChanged && !heightChanged) {
return;
}
m_windowWidth = width;
m_windowHeight = height;
save();
if (widthChanged) {
Q_EMIT windowWidthChanged();
}
if (heightChanged) {
Q_EMIT windowHeightChanged();
}
}
void Config::save() void Config::save()
{ {
const auto config = KSharedConfig::openConfig(QStringLiteral("alakarterc")); const auto config = KSharedConfig::openConfig(QStringLiteral("alakarterc"));
@ -308,6 +376,11 @@ void Config::save()
behaviorGroup.writeEntry(QStringLiteral("exitAfterLaunch"), m_exitAfterLaunch); behaviorGroup.writeEntry(QStringLiteral("exitAfterLaunch"), m_exitAfterLaunch);
behaviorGroup.writeEntry(QStringLiteral("coverLaunchesGame"), m_coverLaunchesGame); behaviorGroup.writeEntry(QStringLiteral("coverLaunchesGame"), m_coverLaunchesGame);
KConfigGroup windowGroup(config, QStringLiteral("Window"));
windowGroup.writeEntry(QStringLiteral("width"), m_windowWidth);
windowGroup.writeEntry(QStringLiteral("height"), m_windowHeight);
windowGroup.writeEntry(QStringLiteral("maximized"), m_windowMaximized);
config->sync(); config->sync();
} }
@ -339,6 +412,11 @@ void Config::load()
m_animatedCovers = behaviorGroup.readEntry(QStringLiteral("animatedCovers"), false); m_animatedCovers = behaviorGroup.readEntry(QStringLiteral("animatedCovers"), false);
m_exitAfterLaunch = behaviorGroup.readEntry(QStringLiteral("exitAfterLaunch"), false); m_exitAfterLaunch = behaviorGroup.readEntry(QStringLiteral("exitAfterLaunch"), false);
m_coverLaunchesGame = behaviorGroup.readEntry(QStringLiteral("coverLaunchesGame"), false); m_coverLaunchesGame = behaviorGroup.readEntry(QStringLiteral("coverLaunchesGame"), false);
const KConfigGroup windowGroup(config, QStringLiteral("Window"));
m_windowWidth = windowGroup.readEntry(QStringLiteral("width"), 0);
m_windowHeight = windowGroup.readEntry(QStringLiteral("height"), 0);
m_windowMaximized = windowGroup.readEntry(QStringLiteral("maximized"), false);
} }
void Config::resetToDefaults() void Config::resetToDefaults()
@ -363,6 +441,10 @@ void Config::resetToDefaults()
m_animatedCovers = false; m_animatedCovers = false;
m_theme.clear(); m_theme.clear();
m_windowWidth = 0;
m_windowHeight = 0;
m_windowMaximized = false;
save(); save();
Q_EMIT viewModeChanged(); Q_EMIT viewModeChanged();
@ -384,4 +466,7 @@ void Config::resetToDefaults()
Q_EMIT highQualityImagesChanged(); Q_EMIT highQualityImagesChanged();
Q_EMIT animatedCoversChanged(); Q_EMIT animatedCoversChanged();
Q_EMIT themeChanged(); Q_EMIT themeChanged();
Q_EMIT windowWidthChanged();
Q_EMIT windowHeightChanged();
Q_EMIT windowMaximizedChanged();
} }

View file

@ -30,6 +30,9 @@ class Config : public QObject
Q_PROPERTY(bool animatedCovers READ animatedCovers WRITE setAnimatedCovers NOTIFY animatedCoversChanged) Q_PROPERTY(bool animatedCovers READ animatedCovers WRITE setAnimatedCovers NOTIFY animatedCoversChanged)
Q_PROPERTY(bool coverLaunchesGame READ coverLaunchesGame WRITE setCoverLaunchesGame NOTIFY coverLaunchesGameChanged) Q_PROPERTY(bool coverLaunchesGame READ coverLaunchesGame WRITE setCoverLaunchesGame NOTIFY coverLaunchesGameChanged)
Q_PROPERTY(QString theme READ theme WRITE setTheme NOTIFY themeChanged) Q_PROPERTY(QString theme READ theme WRITE setTheme NOTIFY themeChanged)
Q_PROPERTY(int windowWidth READ windowWidth WRITE setWindowWidth NOTIFY windowWidthChanged)
Q_PROPERTY(int windowHeight READ windowHeight WRITE setWindowHeight NOTIFY windowHeightChanged)
Q_PROPERTY(bool windowMaximized READ windowMaximized WRITE setWindowMaximized NOTIFY windowMaximizedChanged)
public: public:
enum ViewMode { enum ViewMode {
@ -105,10 +108,21 @@ public:
QString theme() const; QString theme() const;
void setTheme(const QString &theme); void setTheme(const QString &theme);
int windowWidth() const;
void setWindowWidth(int width);
int windowHeight() const;
void setWindowHeight(int height);
bool windowMaximized() const;
void setWindowMaximized(bool maximized);
Q_INVOKABLE void save(); Q_INVOKABLE void save();
Q_INVOKABLE void load(); Q_INVOKABLE void load();
Q_INVOKABLE void resetToDefaults(); Q_INVOKABLE void resetToDefaults();
Q_INVOKABLE void setWindowSize(int width, int height);
Q_SIGNALS: Q_SIGNALS:
void viewModeChanged(); void viewModeChanged();
void uiModeChanged(); void uiModeChanged();
@ -129,6 +143,9 @@ Q_SIGNALS:
void animatedCoversChanged(); void animatedCoversChanged();
void coverLaunchesGameChanged(); void coverLaunchesGameChanged();
void themeChanged(); void themeChanged();
void windowWidthChanged();
void windowHeightChanged();
void windowMaximizedChanged();
private: private:
ViewMode m_viewMode = GridView; ViewMode m_viewMode = GridView;
@ -150,4 +167,8 @@ private:
bool m_highQualityImages = true; bool m_highQualityImages = true;
bool m_animatedCovers = false; bool m_animatedCovers = false;
QString m_theme; QString m_theme;
int m_windowWidth = 0;
int m_windowHeight = 0;
bool m_windowMaximized = false;
}; };

View file

@ -4,6 +4,7 @@
import QtQuick import QtQuick
import QtQuick.Controls as QQC2 import QtQuick.Controls as QQC2
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Window
import org.kde.kirigami as Kirigami import org.kde.kirigami as Kirigami
import org.kde.kirigamiaddons.formcard as FormCard import org.kde.kirigamiaddons.formcard as FormCard
import org.kde.alakarte import org.kde.alakarte
@ -18,6 +19,45 @@ Kirigami.ApplicationWindow {
width: Kirigami.Units.gridUnit * 55 width: Kirigami.Units.gridUnit * 55
height: Kirigami.Units.gridUnit * 40 height: Kirigami.Units.gridUnit * 40
property bool windowGeometryRestored: false
Timer {
id: windowGeometrySaveTimer
interval: 400
repeat: false
onTriggered: {
if (!root.windowGeometryRestored) return
if (root.isMobile) return
if (root.visibility === Window.Maximized || root.visibility === Window.FullScreen) return
App.config.setWindowSize(root.width, root.height)
}
}
onWidthChanged: {
if (!root.windowGeometryRestored) return
if (root.isMobile) return
windowGeometrySaveTimer.restart()
}
onHeightChanged: {
if (!root.windowGeometryRestored) return
if (root.isMobile) return
windowGeometrySaveTimer.restart()
}
onVisibilityChanged: {
if (!root.windowGeometryRestored) return
if (root.isMobile) return
App.config.windowMaximized = root.visibility === Window.Maximized
}
onClosing: function(close) {
if (root.isMobile) return
App.config.windowMaximized = root.visibility === Window.Maximized
if (root.visibility !== Window.Maximized && root.visibility !== Window.FullScreen) {
App.config.setWindowSize(root.width, root.height)
}
}
property var selectedGame: null property var selectedGame: null
property var pendingRemoveGame: null property var pendingRemoveGame: null
property string currentSource: "all" property string currentSource: "all"
@ -1980,6 +2020,19 @@ Kirigami.ApplicationWindow {
} }
Component.onCompleted: { Component.onCompleted: {
if (!root.isMobile) {
const savedW = App.config.windowWidth
const savedH = App.config.windowHeight
if (savedW > 0) root.width = Math.max(root.minimumWidth, savedW)
if (savedH > 0) root.height = Math.max(root.minimumHeight, savedH)
root.windowGeometryRestored = true
if (App.config.windowMaximized) {
root.showMaximized()
}
} else {
root.windowGeometryRestored = true
}
if (App.gameModel.count === 0) { if (App.gameModel.count === 0) {
importSheet.open() importSheet.open()
} }