[gnome-builder] settings: track and restore window placement, size, and maximized



commit 6b25242d8107605db62f9c97a2619bc25e365a2a
Author: Christian Hergert <christian hergert me>
Date:   Sat Apr 18 15:11:04 2015 -0700

    settings: track and restore window placement, size, and maximized
    
    This adds new GSettings for the workbench window size, position, and
    maximized state. We apply the state to both the project selector and
    the workbench window. Mostly because long term I'd like these to be the
    same window.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=748090

 configure.ac                                    |    1 +
 data/gsettings.mk                               |    1 +
 data/gsettings/org.gnome.builder.gschema.xml.in |   19 +++
 src/app/gb-application.c                        |   33 -----
 src/dialogs/gb-projects-dialog.c                |    3 +
 src/gnome-builder.mk                            |    2 +
 src/util/gb-settings.c                          |  157 +++++++++++++++++++++++
 src/util/gb-settings.h                          |   30 +++++
 src/workbench/gb-workbench.c                    |    3 +
 9 files changed, 216 insertions(+), 33 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 613aef6..75cf1cf 100644
--- a/configure.ac
+++ b/configure.ac
@@ -71,6 +71,7 @@ AC_CONFIG_FILES([
        src/util/gb-version.h
        data/icons/Makefile
        data/libide-1.0.pc
+       data/gsettings/org.gnome.builder.gschema.xml
        data/gsettings/org.gnome.builder.editor.gschema.xml
        data/gsettings/org.gnome.builder.editor.language.gschema.xml
        data/gsettings/org.gnome.builder.experimental.gschema.xml
diff --git a/data/gsettings.mk b/data/gsettings.mk
index cad1ce8..5310ee1 100644
--- a/data/gsettings.mk
+++ b/data/gsettings.mk
@@ -1,4 +1,5 @@
 gsettingsschema_in_files = \
+       data/gsettings/org.gnome.builder.gschema.xml.in \
        data/gsettings/org.gnome.builder.editor.gschema.xml.in \
        data/gsettings/org.gnome.builder.editor.language.gschema.xml.in \
        data/gsettings/org.gnome.builder.experimental.gschema.xml.in \
diff --git a/data/gsettings/org.gnome.builder.gschema.xml.in b/data/gsettings/org.gnome.builder.gschema.xml.in
new file mode 100644
index 0000000..95c72e8
--- /dev/null
+++ b/data/gsettings/org.gnome.builder.gschema.xml.in
@@ -0,0 +1,19 @@
+<schemalist>
+  <schema id="org.gnome.builder" path="/org/gnome/builder/" gettext-domain="gnome-builder">
+    <key name="window-size" type="(ii)">
+      <default>(-1, -1)</default>
+      <summary>Window size</summary>
+      <description>Window size (width and height).</description>
+    </key>
+    <key name="window-position" type="(ii)">
+      <default>(-1,-1)</default>
+      <summary>Window position</summary>
+      <description>Window position (x and y).</description>
+    </key>
+    <key name="window-maximized" type="b">
+      <default>true</default>
+      <summary>Window maximized</summary>
+      <description>Window maximized state</description>
+    </key>
+  </schema>
+</schemalist>
diff --git a/src/app/gb-application.c b/src/app/gb-application.c
index 23d4425..09c34d0 100644
--- a/src/app/gb-application.c
+++ b/src/app/gb-application.c
@@ -43,27 +43,6 @@
 G_DEFINE_TYPE (GbApplication, gb_application, GTK_TYPE_APPLICATION)
 
 static void
-get_default_size (GtkRequisition *req)
-{
-  GdkScreen *screen;
-  GdkRectangle rect;
-  gint primary;
-
-  screen = gdk_screen_get_default ();
-  primary = gdk_screen_get_primary_monitor (screen);
-  gdk_screen_get_monitor_geometry (screen, primary, &rect);
-
-  req->width = rect.width * 0.75;
-  req->height = rect.height * 0.75;
-
-  if ((req->width == 0) || (req->height == 0))
-    {
-      req->width = 1080;
-      req->height = 675;
-    }
-}
-
-static void
 gb_application_setup_search_paths (void)
 {
   GtkSourceStyleSchemeManager *style_scheme_manager;
@@ -250,7 +229,6 @@ gb_application__context_new_cb (GObject      *object,
   IdeBufferManager *bufmgr;
   GbApplication *self;
   GbWorkbench *workbench;
-  GtkRequisition req;
   GPtrArray *ar;
   gboolean ret = FALSE;
   GError *error = NULL;
@@ -288,13 +266,9 @@ gb_application__context_new_cb (GObject      *object,
   bufmgr = ide_context_get_buffer_manager (context);
   g_signal_connect (bufmgr, "create-buffer", G_CALLBACK (on_create_buffer), NULL);
 
-  get_default_size (&req);
-
   workbench = g_object_new (GB_TYPE_WORKBENCH,
                             "application", self,
                             "context", context,
-                            "default-width", req.width,
-                            "default-height", req.height,
                             NULL);
 
   if (ar->len == 0)
@@ -310,7 +284,6 @@ gb_application__context_new_cb (GObject      *object,
       gb_workbench_open (workbench, file);
     }
 
-  gtk_window_maximize (GTK_WINDOW (workbench));
   gtk_window_present (GTK_WINDOW (workbench));
 
   ret = TRUE;
@@ -456,7 +429,6 @@ void
 gb_application_show_projects_window (GbApplication *self)
 {
   GbProjectsDialog *window;
-  GtkRequisition req;
   GList *windows;
 
   g_assert (GB_IS_APPLICATION (self));
@@ -472,14 +444,9 @@ gb_application_show_projects_window (GbApplication *self)
         }
     }
 
-  get_default_size (&req);
-
   window = g_object_new (GB_TYPE_PROJECTS_DIALOG,
                          "application", self,
-                         "default-width", req.width,
-                         "default-height", req.height,
                          NULL);
-  gtk_window_maximize (GTK_WINDOW (window));
   gtk_window_present (GTK_WINDOW (window));
 }
 
diff --git a/src/dialogs/gb-projects-dialog.c b/src/dialogs/gb-projects-dialog.c
index ec3f110..8e20ba9 100644
--- a/src/dialogs/gb-projects-dialog.c
+++ b/src/dialogs/gb-projects-dialog.c
@@ -33,6 +33,7 @@
 #include "gb-projects-dialog.h"
 #include "gb-recent-project-row.h"
 #include "gb-scrolled-window.h"
+#include "gb-settings.h"
 #include "gb-string.h"
 #include "gb-widget.h"
 #include "gb-workbench.h"
@@ -609,5 +610,7 @@ gb_projects_dialog_init (GbProjectsDialog *self)
 {
   gtk_widget_init_template (GTK_WIDGET (self));
 
+  gb_settings_init_window (GTK_WINDOW (self));
+
   self->recent_projects = ide_recent_projects_new ();
 }
diff --git a/src/gnome-builder.mk b/src/gnome-builder.mk
index 2391905..7316c89 100644
--- a/src/gnome-builder.mk
+++ b/src/gnome-builder.mk
@@ -141,6 +141,8 @@ libgnome_builder_la_SOURCES = \
        src/util/gb-pango.h \
        src/util/gb-rgba.c \
        src/util/gb-rgba.h \
+        src/util/gb-settings.c \
+        src/util/gb-settings.h \
        src/util/gb-string.c \
        src/util/gb-string.h \
        src/util/gb-widget.c \
diff --git a/src/util/gb-settings.c b/src/util/gb-settings.c
new file mode 100644
index 0000000..389275b
--- /dev/null
+++ b/src/util/gb-settings.c
@@ -0,0 +1,157 @@
+/* gb-settings.c
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "gb-settings.h"
+
+#define GB_WINDOW_MIN_WIDTH  1280
+#define GB_WINDOW_MIN_HEIGHT 720
+#define SAVE_TIMEOUT_SECS    1
+
+static GSettings *gSettings;
+
+static gboolean
+gb_settings__window_save_settings_cb (gpointer data)
+{
+  GtkWindow *window = data;
+  GdkRectangle geom;
+  gboolean maximized;
+
+  g_assert (GTK_IS_WINDOW (window));
+  g_assert (G_IS_SETTINGS (gSettings));
+
+  g_object_set_data (G_OBJECT (window), "SETTINGS_HANDLER_ID", NULL);
+
+  gtk_window_get_size (window, &geom.width, &geom.height);
+  gtk_window_get_position (window, &geom.x, &geom.y);
+  maximized = gtk_window_is_maximized (window);
+
+  g_settings_set (gSettings, "window-size", "(ii)", geom.width, geom.height);
+  g_settings_set (gSettings, "window-position", "(ii)", geom.x, geom.y);
+  g_settings_set_boolean (gSettings, "window-maximized", maximized);
+
+  return G_SOURCE_REMOVE;
+}
+
+static gboolean
+gb_settings__window_configure_event (GtkWindow         *window,
+                                     GdkEventConfigure *event,
+                                     GSettings         *settings)
+{
+  guint handler;
+
+  g_assert (GTK_IS_WINDOW (window));
+  g_assert (event != NULL);
+  g_assert (G_IS_SETTINGS (gSettings));
+
+  handler = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "SETTINGS_HANDLER_ID"));
+
+  if (handler == 0)
+    {
+      handler = g_timeout_add_seconds (SAVE_TIMEOUT_SECS,
+                                       gb_settings__window_save_settings_cb,
+                                       window);
+      g_object_set_data (G_OBJECT (window), "SETTINGS_HANDLER_ID", GINT_TO_POINTER (handler));
+    }
+
+  return GDK_EVENT_PROPAGATE;
+}
+
+static void
+gb_settings__window_realize (GtkWindow *window,
+                             GSettings *settings)
+{
+  GdkRectangle geom = { 0 };
+  gboolean maximized = FALSE;
+
+  g_assert (GTK_IS_WINDOW (window));
+  g_assert (G_IS_SETTINGS (gSettings));
+
+  g_settings_get (gSettings, "window-position", "(ii)", &geom.x, &geom.y);
+  g_settings_get (gSettings, "window-size", "(ii)", &geom.width, &geom.height);
+  g_settings_get (gSettings, "window-maximized", "b", &maximized);
+
+  geom.width = MAX (geom.width, GB_WINDOW_MIN_WIDTH);
+  geom.height = MAX (geom.height, GB_WINDOW_MIN_HEIGHT);
+  gtk_window_set_default_size (window, geom.width, geom.height);
+
+  gtk_window_move (window, geom.x, geom.y);
+
+  if (maximized)
+    gtk_window_maximize (window);
+}
+
+static void
+gb_settings__window_destroy (GtkWindow *window,
+                             GSettings *settings)
+{
+  guint handler;
+
+  g_assert (GTK_IS_WINDOW (window));
+  g_assert (G_IS_SETTINGS (gSettings));
+
+  handler = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "SETTINGS_HANDLER_ID"));
+
+  if (handler != 0)
+    {
+      g_source_remove (handler);
+      g_object_set_data (G_OBJECT (window), "SETTINGS_HANDLER_ID", NULL);
+    }
+
+  g_signal_handlers_disconnect_by_func (window,
+                                        G_CALLBACK (gb_settings__window_configure_event),
+                                        NULL);
+
+  g_signal_handlers_disconnect_by_func (window,
+                                        G_CALLBACK (gb_settings__window_destroy),
+                                        NULL);
+
+  g_signal_handlers_disconnect_by_func (window,
+                                        G_CALLBACK (gb_settings__window_realize),
+                                        NULL);
+
+  g_object_unref (gSettings);
+}
+
+void
+gb_settings_init_window (GtkWindow *window)
+{
+  if (gSettings == NULL)
+    {
+      gSettings = g_settings_new ("org.gnome.builder");
+      g_object_add_weak_pointer (G_OBJECT (gSettings), (gpointer *)&gSettings);
+    }
+  else
+    {
+      g_object_ref (gSettings);
+    }
+
+  g_signal_connect (window,
+                    "configure-event",
+                    G_CALLBACK (gb_settings__window_configure_event),
+                    NULL);
+
+  g_signal_connect (window,
+                    "destroy",
+                    G_CALLBACK (gb_settings__window_destroy),
+                    NULL);
+
+  g_signal_connect (window,
+                    "realize",
+                    G_CALLBACK (gb_settings__window_realize),
+                    NULL);
+}
diff --git a/src/util/gb-settings.h b/src/util/gb-settings.h
new file mode 100644
index 0000000..7069c18
--- /dev/null
+++ b/src/util/gb-settings.h
@@ -0,0 +1,30 @@
+/* gb-settings.h
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GB_SETTINGS_H
+#define GB_SETTINGS_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+void gb_settings_init_window (GtkWindow *window);
+
+G_END_DECLS
+
+#endif /* GB_SETTINGS_H */
diff --git a/src/workbench/gb-workbench.c b/src/workbench/gb-workbench.c
index 316add3..71782b8 100644
--- a/src/workbench/gb-workbench.c
+++ b/src/workbench/gb-workbench.c
@@ -24,6 +24,7 @@
 #include "gb-command-gaction-provider.h"
 #include "gb-command-vim-provider.h"
 #include "gb-dnd.h"
+#include "gb-settings.h"
 #include "gb-widget.h"
 #include "gb-workbench-actions.h"
 #include "gb-workbench-private.h"
@@ -498,6 +499,8 @@ gb_workbench_init (GbWorkbench *self)
                      (GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP),
                      gDropTypes, G_N_ELEMENTS (gDropTypes), GDK_ACTION_COPY);
 
+  gb_settings_init_window (GTK_WINDOW (self));
+
   IDE_EXIT;
 }
 


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