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:36 +00:00
commit ff9348d994
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()
{
const auto config = KSharedConfig::openConfig(QStringLiteral("alakarterc"));
@ -308,6 +376,11 @@ void Config::save()
behaviorGroup.writeEntry(QStringLiteral("exitAfterLaunch"), m_exitAfterLaunch);
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();
}
@ -339,6 +412,11 @@ void Config::load()
m_animatedCovers = behaviorGroup.readEntry(QStringLiteral("animatedCovers"), false);
m_exitAfterLaunch = behaviorGroup.readEntry(QStringLiteral("exitAfterLaunch"), 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()
@ -363,6 +441,10 @@ void Config::resetToDefaults()
m_animatedCovers = false;
m_theme.clear();
m_windowWidth = 0;
m_windowHeight = 0;
m_windowMaximized = false;
save();
Q_EMIT viewModeChanged();
@ -384,4 +466,7 @@ void Config::resetToDefaults()
Q_EMIT highQualityImagesChanged();
Q_EMIT animatedCoversChanged();
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 coverLaunchesGame READ coverLaunchesGame WRITE setCoverLaunchesGame NOTIFY coverLaunchesGameChanged)
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:
enum ViewMode {
@ -105,10 +108,21 @@ public:
QString theme() const;
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 load();
Q_INVOKABLE void resetToDefaults();
Q_INVOKABLE void setWindowSize(int width, int height);
Q_SIGNALS:
void viewModeChanged();
void uiModeChanged();
@ -129,6 +143,9 @@ Q_SIGNALS:
void animatedCoversChanged();
void coverLaunchesGameChanged();
void themeChanged();
void windowWidthChanged();
void windowHeightChanged();
void windowMaximizedChanged();
private:
ViewMode m_viewMode = GridView;
@ -150,4 +167,8 @@ private:
bool m_highQualityImages = true;
bool m_animatedCovers = false;
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.Controls as QQC2
import QtQuick.Layouts
import QtQuick.Window
import org.kde.kirigami as Kirigami
import org.kde.kirigamiaddons.formcard as FormCard
import org.kde.alakarte
@ -18,6 +19,45 @@ Kirigami.ApplicationWindow {
width: Kirigami.Units.gridUnit * 55
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 pendingRemoveGame: null
property string currentSource: "all"
@ -1980,6 +2020,19 @@ Kirigami.ApplicationWindow {
}
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) {
importSheet.open()
}