[gnome-contacts/wip/nielsdg/window-state-warnings] MainWindow: Rework window state restore




commit 2dedddb8dfc2fe03b89a2035f1f9efb7f4d46e64
Author: Niels De Graef <nielsdegraef gmail com>
Date:   Sun Jan 17 17:41:02 2021 +0100

    MainWindow: Rework window state restore
    
    The current mechanism for restoring the MainWindow state used deprecated
    API and did a lot of unnecessary work (keeping the window state in sync
    on each window resize, rather than doing it only once). This commit
    improves that by not using the deprecated GdkScreen API anymore and by
    only saving the window state on the destroy signal.

 src/contacts-main-window.vala      | 104 +++++++++++++++++++------------------
 src/contacts-settings.vala         |  40 ++++++++------
 src/org.gnome.Contacts.gschema.xml |   5 ++
 3 files changed, 83 insertions(+), 66 deletions(-)
---
diff --git a/src/contacts-main-window.vala b/src/contacts-main-window.vala
index 399a3d2f..60f26e4b 100644
--- a/src/contacts-main-window.vala
+++ b/src/contacts-main-window.vala
@@ -73,32 +73,23 @@ public class Contacts.MainWindow : Hdy.ApplicationWindow {
 
   public UiState state { get; set; default = UiState.NORMAL; }
 
-  /** Holds the current width. */
+  // Window state
   public int window_width { get; set; }
-  /** Holds the current height. */
   public int window_height { get; set; }
-  /** Holds true if the window is currently maximized. */
   public bool window_maximized { get; set; }
+  public bool window_fullscreen { get; set; }
 
-  private Settings settings;
+  public Settings settings { get; construct set; }
 
   public Store store {
     get; construct set;
   }
 
-  public MainWindow (Settings settings, App app, Store contacts_store) {
-    Object (
-      application: app,
-      show_menubar: false,
-      visible: true,
-      store: contacts_store
-    );
-
+  construct {
     SimpleActionGroup actions = new SimpleActionGroup ();
     actions.add_action_entries (action_entries, this);
-    this.insert_action_group ("window", actions);
+    insert_action_group ("window", actions);
 
-    this.settings = settings;
     this.sort_on_firstname_button.clicked.connect (() => {
       this.settings.sort_on_surname = false;
       on_sort_changed ();
@@ -111,38 +102,49 @@ public class Contacts.MainWindow : Hdy.ApplicationWindow {
 
     this.notify["state"].connect (on_ui_state_changed);
 
-    bind_dimension_properties_to_settings ();
     create_contact_pane ();
     connect_button_signals ();
-    restore_window_size_and_position_from_settings ();
+    restore_window_state ();
 
     if (Config.PROFILE == "development")
         get_style_context ().add_class ("devel");
   }
 
+  public MainWindow (Settings settings, App app, Store contacts_store) {
+    Object (
+      application: app,
+      settings: settings,
+      show_menubar: false,
+      visible: true,
+      store: contacts_store
+    );
+  }
+
   private void on_sort_changed () {
     this.sort_on_firstname_button.active = !this.settings.sort_on_surname;
     this.sort_on_surname_button.active = this.settings.sort_on_surname;
   }
 
-  private void restore_window_size_and_position_from_settings () {
-    unowned var screen = get_screen ();
-    if (screen != null && this.window_width <= screen.get_width () && this.window_height <= 
screen.get_height ()) {
+  private void restore_window_state () {
+    // Load initial values
+    this.window_width = this.settings.window_width;
+    this.window_height = this.settings.window_height;
+    this.window_maximized = this.settings.window_maximized;
+    this.window_fullscreen = this.settings.window_fullscreen;
+
+    // Apply them
+    if (this.window_width > 0 && this.window_height > 0)
       set_default_size (this.window_width, this.window_height);
-    }
-    if (this.window_maximized) {
-      maximize();
-    }
-    // always put the window into the center position to avoid losing it somewhere at the screen boundaries.
-    this.window_position = Gtk.WindowPosition.CENTER;
+    if (this.window_maximized)
+      maximize ();
+    if (this.window_fullscreen)
+      fullscreen ();
   }
 
   public override bool window_state_event (Gdk.EventWindowState event) {
-    if (!(Gdk.WindowState.WITHDRAWN in event.new_window_state)) {
-      bool maximized = (Gdk.WindowState.MAXIMIZED in event.new_window_state);
-      if (this.window_maximized != maximized)
-        this.window_maximized = maximized;
-    }
+    this.window_maximized = (Gdk.WindowState.MAXIMIZED in event.new_window_state);
+    this.window_fullscreen = (Gdk.WindowState.FULLSCREEN in event.new_window_state);
+
     return base.window_state_event (event);
   }
 
@@ -150,23 +152,19 @@ public class Contacts.MainWindow : Hdy.ApplicationWindow {
   public override void size_allocate (Gtk.Allocation allocation) {
     base.size_allocate (allocation);
 
-    unowned var screen = get_screen ();
-    if (screen != null && !this.window_maximized) {
-      // Get the size via ::get_size instead of the allocation
-      // so that the window isn't ever-expanding.
-      int width = 0;
-      int height = 0;
-      get_size(out width, out height);
-
-      // Only store if the values have changed and are
-      // reasonable-looking.
-      if (this.window_width != width && width > 0 && width <= screen.get_width ()) {
-        this.window_width = width;
-      }
-      if (this.window_height != height && height > 0 && height <= screen.get_height ()) {
-        this.window_height = height;
-      }
-    }
+    if (this.window_fullscreen || this.window_maximized)
+      return;
+
+    // Get the size via widget.get_size() instead of the allocation
+    // so that the window isn't ever-expanding (in case of CSD).
+    int width = 0;
+    int height = 0;
+    get_size(out width, out height);
+
+    if (this.window_width != width)
+      this.window_width = width;
+    if (this.window_height != height)
+      this.window_height = height;
   }
 
   private void create_contact_pane () {
@@ -578,9 +576,13 @@ public class Contacts.MainWindow : Hdy.ApplicationWindow {
     add_notification (notification);
   }
 
-  private void bind_dimension_properties_to_settings () {
-    this.settings.bind_default (Settings.WINDOW_WIDTH_KEY, this, "window-width");
-    this.settings.bind_default (Settings.WINDOW_HEIGHT_KEY, this, "window-height");
-    this.settings.bind_default (Settings.WINDOW_MAXIMIZED_KEY, this, "window-maximized");
+  // Override the default destroy() to save the window state
+  public override void destroy () {
+    this.settings.window_width = this.window_width;
+    this.settings.window_height = this.window_height;
+    this.settings.window_maximized = this.window_maximized;
+    this.settings.window_fullscreen = this.window_fullscreen;
+
+    base.destroy ();
   }
 }
diff --git a/src/contacts-settings.vala b/src/contacts-settings.vala
index db4333bb..376f1ea5 100644
--- a/src/contacts-settings.vala
+++ b/src/contacts-settings.vala
@@ -16,31 +16,41 @@
  */
 
 /**
- * Provides a convenient interface to deal with the settings.
+ * Provides a convenient interface to deal with Contacts' settings.
+ *
+ * When editing this, make sure you keep it in sync with the schema file!
  */
 public class Contacts.Settings : GLib.Settings {
 
-  public const string DID_INITIAL_SETUP_KEY = "did-initial-setup";
-  public const string SORT_ON_SURNAME_KEY = "sort-on-surname";
-  public const string WINDOW_WIDTH_KEY = "window-width";
-  public const string WINDOW_HEIGHT_KEY = "window-height";
-  public const string WINDOW_MAXIMIZED_KEY = "window-maximized";
-
   public bool did_initial_setup {
-    get { return get_boolean (DID_INITIAL_SETUP_KEY); }
-    set { set_boolean (DID_INITIAL_SETUP_KEY, value); }
+    get { return get_boolean ("did-initial-setup"); }
+    set { set_boolean ("did-initial-setup", value); }
   }
 
   public bool sort_on_surname {
-    get { return get_boolean (SORT_ON_SURNAME_KEY); }
-    set { set_boolean (SORT_ON_SURNAME_KEY, value); }
+    get { return get_boolean ("sort-on-surname"); }
+    set { set_boolean ("sort-on-surname", value); }
   }
 
-  public Settings (App app) {
-    Object (schema_id: "org.gnome.Contacts");
+  // Window state
+  public int window_width {
+    get { return get_int ("window-width"); }
+    set { set_int ("window-width", value); }
+  }
+  public int window_height {
+    get { return get_int ("window-height"); }
+    set { set_int ("window-height", value); }
+  }
+  public bool window_maximized {
+    get { return get_boolean ("window-maximized"); }
+    set { set_boolean ("window-maximized", value); }
+  }
+  public bool window_fullscreen {
+    get { return get_boolean ("window-fullscreen"); }
+    set { set_boolean ("window-fullscreen", value); }
   }
 
-  public void bind_default (string key, Object object, string property) {
-    bind (key, object, property, GLib.SettingsBindFlags.DEFAULT);
+  public Settings (App app) {
+    Object (schema_id: "org.gnome.Contacts");
   }
 }
diff --git a/src/org.gnome.Contacts.gschema.xml b/src/org.gnome.Contacts.gschema.xml
index d069ee6f..342a72f6 100644
--- a/src/org.gnome.Contacts.gschema.xml
+++ b/src/org.gnome.Contacts.gschema.xml
@@ -33,5 +33,10 @@
       <description>Stores if the window is currently maximized.</description>
       <default>false</default>
     </key>
+    <key name="window-fullscreen" type="b">
+      <summary>Is the window fullscreen</summary>
+      <description>Stores if the window is currently maximized.</description>
+      <default>false</default>
+    </key>
   </schema>
 </schemalist>


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