[gnome-builder/wip/window-placement] wip on window placement



commit ce97ee3d5381d0352d4fe9aebca266c47371f50a
Author: Christian Hergert <christian hergert me>
Date:   Fri Apr 17 18:42:28 2015 -0700

    wip on window placement

 configure.ac                                    |    1 +
 data/gsettings.mk                               |    1 +
 data/gsettings/org.gnome.builder.gschema.xml.in |   24 ++++++
 src/app/gb-application.c                        |   48 ++++++++++--
 src/workbench/gb-workbench-private.h            |    2 +
 src/workbench/gb-workbench.c                    |   92 ++++++++++++++++++++++-
 6 files changed, 159 insertions(+), 9 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..838ff8b
--- /dev/null
+++ b/data/gsettings/org.gnome.builder.gschema.xml.in
@@ -0,0 +1,24 @@
+<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>
+    <key name="night-mode" type="b">
+      <default>false</default>
+      <summary>Night mode</summary>
+      <description>Whether the application is in night mode.</description>
+    </key>
+  </schema>
+</schemalist>
diff --git a/src/app/gb-application.c b/src/app/gb-application.c
index 23d4425..20cc52c 100644
--- a/src/app/gb-application.c
+++ b/src/app/gb-application.c
@@ -42,13 +42,46 @@
 
 G_DEFINE_TYPE (GbApplication, gb_application, GTK_TYPE_APPLICATION)
 
+static gboolean
+window_should_maximize (void)
+{
+  GSettings *settings;
+  gboolean ret;
+
+  settings = g_settings_new ("org.gnome.builder");
+  ret = g_settings_get_boolean (settings, "window-maximized");
+  g_object_unref (settings);
+
+  return ret;
+}
+
+static gboolean
+get_window_position (GdkPoint *loc)
+{
+  GSettings *settings;
+
+  settings = g_settings_new ("org.gnome.builder");
+  g_settings_get (settings, "window-position", "(ii)", &loc->x, &loc->y);
+  g_object_unref (settings);
+
+  return (loc->x >= 0) && (loc->y >= 0);
+}
+
 static void
 get_default_size (GtkRequisition *req)
 {
+  GSettings *settings;
   GdkScreen *screen;
   GdkRectangle rect;
   gint primary;
 
+  settings = g_settings_new ("org.gnome.builder");
+  g_settings_get (settings, "window-size", "(ii)", &req->width, &req->height);
+  g_object_unref (settings);
+
+  if (req->width > 0 && req->height > 0)
+    return;
+
   screen = gdk_screen_get_default ();
   primary = gdk_screen_get_primary_monitor (screen);
   gdk_screen_get_monitor_geometry (screen, primary, &rect);
@@ -250,7 +283,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 +320,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 +338,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;
@@ -457,6 +484,7 @@ gb_application_show_projects_window (GbApplication *self)
 {
   GbProjectsDialog *window;
   GtkRequisition req;
+  GdkPoint loc;
   GList *windows;
 
   g_assert (GB_IS_APPLICATION (self));
@@ -479,7 +507,13 @@ gb_application_show_projects_window (GbApplication *self)
                          "default-width", req.width,
                          "default-height", req.height,
                          NULL);
-  gtk_window_maximize (GTK_WINDOW (window));
+
+  if (get_window_position (&loc))
+    gtk_window_move (GTK_WINDOW (window), loc.x, loc.y);
+
+  if (window_should_maximize ())
+    gtk_window_maximize (GTK_WINDOW (window));
+
   gtk_window_present (GTK_WINDOW (window));
 }
 
diff --git a/src/workbench/gb-workbench-private.h b/src/workbench/gb-workbench-private.h
index e05138c..d88a413 100644
--- a/src/workbench/gb-workbench-private.h
+++ b/src/workbench/gb-workbench-private.h
@@ -53,6 +53,8 @@ struct _GbWorkbench
 
   gulong                  project_notify_name_handler;
 
+  guint                   store_settings_timeout;
+
   guint                   disposing;
   guint                   building : 1;
   guint                   unloading : 1;
diff --git a/src/workbench/gb-workbench.c b/src/workbench/gb-workbench.c
index 316add3..069f573 100644
--- a/src/workbench/gb-workbench.c
+++ b/src/workbench/gb-workbench.c
@@ -30,6 +30,8 @@
 #include "gb-workbench.h"
 #include "gb-workspace.h"
 
+#define STORE_SETTINGS_TIMEOUT_SECS 1
+
 G_DEFINE_TYPE (GbWorkbench, gb_workbench, GTK_TYPE_APPLICATION_WINDOW)
 
 enum {
@@ -262,16 +264,95 @@ gb_workbench_grab_focus (GtkWidget *widget)
 }
 
 static void
+gb_workbench_apply_window_settings (GbWorkbench *self)
+{
+  g_autoptr(GSettings) settings = NULL;
+  GtkRequisition req;
+  GdkPoint pos;
+  gboolean maximize;
+
+  g_assert (GB_IS_WORKBENCH (self));
+
+  settings = g_settings_new ("org.gnome.builder");
+
+  /* Apply previous window width and height */
+  g_settings_get (settings, "window-size", "(ii)", &req.width, &req.height);
+  if ((req.width > 0) && (req.height > 0))
+    gtk_window_set_default_size (GTK_WINDOW (self), req.width, req.height);
+
+  /* Apply previous window position */
+  g_settings_get (settings, "window-position", "(ii)", &pos.x, &pos.y);
+  if ((pos.x > 0) && (pos.y > 0))
+    gtk_window_move (GTK_WINDOW (self), pos.x, pos.y);
+  else
+    gtk_window_set_position (GTK_WINDOW (self), GTK_WIN_POS_CENTER);
+
+  /* Apply previous maximized state */
+  maximize = g_settings_get_boolean (settings, "window-maximized");
+  if (maximize)
+    gtk_window_maximize (GTK_WINDOW (self));
+}
+
+static gboolean
+gb_workbench_store_window_settings (gpointer data)
+{
+  g_autoptr(GSettings) settings = NULL;
+  GbWorkbench *self = data;
+  GtkRequisition req;
+  GdkPoint pos;
+  gboolean maximized;
+
+  g_assert (GB_IS_WORKBENCH (self));
+
+  self->store_settings_timeout = 0;
+
+  settings = g_settings_new ("org.gnome.builder");
+
+  gtk_window_get_size (GTK_WINDOW (self), &req.width, &req.height);
+  if ((req.width > 0) && (req.height > 0))
+    g_settings_set (settings, "window-size", "(ii)", req.width, req.height);
+
+  maximized = gtk_window_is_maximized (GTK_WINDOW (self));
+  g_settings_set_boolean (settings, "window-maximized", maximized);
+
+  gtk_window_get_position (GTK_WINDOW (self), &pos.x, &pos.y);
+  if ((pos.x >= 0) && (pos.y >= 0))
+    g_settings_set (settings, "window-position", "(ii)", pos.x, pos.y);
+
+  return G_SOURCE_REMOVE;
+}
+
+static void
 gb_workbench_realize (GtkWidget *widget)
 {
   GbWorkbench *self = (GbWorkbench *)widget;
 
-  if (GTK_WIDGET_CLASS (gb_workbench_parent_class)->realize)
-    GTK_WIDGET_CLASS (gb_workbench_parent_class)->realize (widget);
+  gb_workbench_apply_window_settings (self);
+
+  GTK_WIDGET_CLASS (gb_workbench_parent_class)->realize (widget);
 
   gtk_widget_grab_focus (GTK_WIDGET (self->editor_workspace));
 }
 
+static gboolean
+gb_workbench_configure_event (GtkWidget         *widget,
+                              GdkEventConfigure *event)
+{
+  GbWorkbench *self = (GbWorkbench *)widget;
+
+  g_assert (GB_IS_WORKBENCH (widget));
+  g_assert (event != NULL);
+
+  if (self->store_settings_timeout == 0)
+    {
+      self->store_settings_timeout = g_timeout_add_seconds (STORE_SETTINGS_TIMEOUT_SECS,
+                                                            gb_workbench_store_window_settings,
+                                                            self);
+    }
+
+  return GTK_WIDGET_CLASS (gb_workbench_parent_class)->configure_event (widget, event);
+}
+
 static void
 gb_workbench_constructed (GObject *object)
 {
@@ -325,6 +406,12 @@ gb_workbench_finalize (GObject *object)
 
   IDE_ENTRY;
 
+  if (self->store_settings_timeout)
+    {
+      g_source_remove (self->store_settings_timeout);
+      self->store_settings_timeout = 0;
+    }
+
   ide_clear_weak_pointer (&self->active_workspace);
   g_clear_object (&self->context);
   g_clear_pointer (&self->current_folder_uri, g_free);
@@ -400,6 +487,7 @@ gb_workbench_class_init (GbWorkbenchClass *klass)
   object_class->get_property = gb_workbench_get_property;
   object_class->set_property = gb_workbench_set_property;
 
+  widget_class->configure_event = gb_workbench_configure_event;
   widget_class->delete_event = gb_workbench_delete_event;
   widget_class->drag_data_received = gb_workbench_drag_data_received;
   widget_class->draw = gb_workbench_draw;


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