[lightsoff/arnaudb/save-state: 5/5] Save window state on exit.




commit c559140dd85591537e55ee0cf896870c81693ab9
Author: Arnaud Bonatti <arnaud bonatti gmail com>
Date:   Wed Oct 28 17:24:03 2020 +0100

    Save window state on exit.

 data/lightsoff.ui                    |   2 +-
 data/org.gnome.LightsOff.gschema.xml |  24 ++++++++
 src/lightsoff-window.vala            |   4 +-
 src/managed-window.vala              | 110 +++++++++++++++++++++++++++++++++++
 src/meson.build                      |   1 +
 5 files changed, 139 insertions(+), 2 deletions(-)
---
diff --git a/data/lightsoff.ui b/data/lightsoff.ui
index db244ce..5088238 100644
--- a/data/lightsoff.ui
+++ b/data/lightsoff.ui
@@ -2,7 +2,7 @@
 <!-- Generated with glade 3.22.1 -->
 <interface>
   <requires lib="gtk+" version="3.12"/>
-  <template class="LightsoffWindow" parent="GtkApplicationWindow">
+  <template class="LightsoffWindow" parent="ManagedWindow">
     <property name="can_focus">False</property>
     <child type="titlebar">
       <object class="GtkHeaderBar" id="headerbar">
diff --git a/data/org.gnome.LightsOff.gschema.xml b/data/org.gnome.LightsOff.gschema.xml
index c33dd44..2f08fd5 100644
--- a/data/org.gnome.LightsOff.gschema.xml
+++ b/data/org.gnome.LightsOff.gschema.xml
@@ -9,4 +9,28 @@
       <description>The users’s most recent level.</description>
     </key>
   </schema>
+
+  <schema id="org.gnome.LightsOff.Lib" gettext-domain="lightsoff">
+    <key name="window-width" type="i">
+      <default>1</default>
+      <!-- Translators: summary of a settings key, see 'dconf-editor /org/gnome/LightsOff/window-width' -->
+      <summary>The width of the window</summary>
+      <!-- Translators: description of a settings key, see 'dconf-editor /org/gnome/LightsOff/window-width' 
-->
+      <description>The width of the main window in pixels.</description>
+    </key>
+    <key name="window-height" type="i">
+      <default>1</default>
+      <!-- Translators: summary of a settings key, see 'dconf-editor /org/gnome/LightsOff/window-height' -->
+      <summary>The height of the window</summary>
+      <!-- Translators: description of a settings key, see 'dconf-editor /org/gnome/LightsOff/window-height' 
-->
+      <description>The height of the main window in pixels.</description>
+    </key>
+    <key name="window-is-maximized" type="b">
+      <default>false</default>
+      <!-- Translators: summary of a settings key, see 'dconf-editor 
/org/gnome/LightsOff/window-is-maximized' -->
+      <summary>A flag to enable maximized mode</summary>
+      <!-- Translators: description of a settings key, see 'dconf-editor 
/org/gnome/LightsOff/window-is-maximized' -->
+      <description>If “true”, the main window starts in maximized mode.</description>
+    </key>
+  </schema>
 </schemalist>
diff --git a/src/lightsoff-window.vala b/src/lightsoff-window.vala
index 408bc7d..31a74cf 100644
--- a/src/lightsoff-window.vala
+++ b/src/lightsoff-window.vala
@@ -13,7 +13,7 @@
 using Gtk;
 
 [GtkTemplate (ui = "/org/gnome/LightsOff/ui/lightsoff.ui")]
-private class LightsoffWindow : ApplicationWindow
+private class LightsoffWindow : ManagedWindow
 {
     [GtkChild] private HeaderBar headerbar;
     [GtkChild] private MenuButton menu_button;
@@ -60,6 +60,8 @@ private class LightsoffWindow : ApplicationWindow
 
     internal LightsoffWindow ()
     {
+        Object (schema_path: "/org/gnome/LightsOff/");
+
         settings = new GLib.Settings ("org.gnome.LightsOff");
 
         var menu_builder = new Gtk.Builder.from_resource ("/org/gnome/LightsOff/gtk/menus.ui");
diff --git a/src/managed-window.vala b/src/managed-window.vala
new file mode 100644
index 0000000..2aad64a
--- /dev/null
+++ b/src/managed-window.vala
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2020 Arnaud Bonatti
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 2 of the License, or (at your option) any later
+ * version. See http://www.gnu.org/copyleft/gpl.html the full text of the
+ * license.
+ */
+
+using Gtk;
+
+private class ManagedWindow : ApplicationWindow
+{
+    private int window_width = 0;
+    private int window_height = 0;
+    private bool window_is_maximized = false;
+    private bool window_is_fullscreen = false;
+    private bool window_is_tiled = false;
+
+    construct
+    {
+        connect_callbacks ();
+        load_window_state ();
+    }
+
+    /*\
+    * * callbacks
+    \*/
+
+    private inline void connect_collback ()
+    {
+        window_state_event.connect (on_window_state_event);
+        size_allocate.connect (on_size_allocate);
+        destroy.connect (on_destroy);
+    }
+
+    private const Gdk.WindowState tiled_state = Gdk.WindowState.TILED
+                                              | Gdk.WindowState.TOP_TILED
+                                              | Gdk.WindowState.BOTTOM_TILED
+                                              | Gdk.WindowState.LEFT_TILED
+                                              | Gdk.WindowState.RIGHT_TILED;
+    private inline bool on_window_state_event (Widget widget, Gdk.EventWindowState event)
+    {
+        if ((event.changed_mask & Gdk.WindowState.MAXIMIZED) != 0)
+            window_is_maximized = (event.new_window_state & Gdk.WindowState.MAXIMIZED) != 0;
+
+        /* fullscreen: saved as maximized */
+        if ((event.changed_mask & Gdk.WindowState.FULLSCREEN) != 0)
+            window_is_fullscreen = (event.new_window_state & Gdk.WindowState.FULLSCREEN) != 0;
+
+        /* tiled: not saved, but should not change saved window size */
+        if ((event.changed_mask & tiled_state) != 0)
+            window_is_tiled = (event.new_window_state & tiled_state) != 0;
+
+        return false;
+    }
+
+    private inline void on_size_allocate (Allocation allocation)
+    {
+        if (window_is_maximized || window_is_tiled || window_is_fullscreen)
+            return;
+        int? _window_width = null;
+        int? _window_height = null;
+        get_size (out _window_width, out _window_height);
+        if (_window_width == null || _window_height == null)
+            return;
+        window_width = (!) _window_width;
+        window_height = (!) _window_height;
+    }
+
+    private inline void on_destroy ()
+    {
+        save_window_state ();
+        base.destroy ();
+    }
+
+    /*\
+    * * manage window state
+    \*/
+
+    [CCode (notify = false)] public string schema_path
+    {
+        protected construct
+        {
+            string? _value = value;
+            if (_value == null)
+                assert_not_reached ();
+
+            settings = new GLib.Settings.with_path ("org.gnome.LightsOff.Lib", value);
+        }
+    }
+    private GLib.Settings settings;
+
+    private inline void load_window_state ()   // called on construct
+    {
+        if (settings.get_boolean ("window-is-maximized"))
+            maximize ();
+        set_default_size (settings.get_int ("window-width"), settings.get_int ("window-height"));
+    }
+
+    private inline void save_window_state ()   // called on destroy
+    {
+        settings.delay ();
+        settings.set_int ("window-width", window_width);
+        settings.set_int ("window-height", window_height);
+        settings.set_boolean ("window-is-maximized", window_is_maximized || window_is_fullscreen);
+        settings.apply ();
+    }
+}
diff --git a/src/meson.build b/src/meson.build
index 913fd7f..7b2a454 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -6,6 +6,7 @@ lightsoff_vala_sources = [
   'puzzle-generator.vala',
   'game-view.vala',
   'game-view-gtk.vala',
+  'managed-window.vala',
 ]
 
 lightsoff_resources_file = files('lightsoff.gresource.xml')


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]