[gnome-builder] libide/gui: start on basic restoration of frames



commit 36d19797c72d1be96b894b05f6610d0aad5bd430
Author: Christian Hergert <chergert redhat com>
Date:   Thu Sep 15 22:50:05 2022 -0700

    libide/gui: start on basic restoration of frames
    
    This is just the start. We should consider cleaning this all up a bunch
    by adding an IdeDock subclass of PanelDock. That way we can avoid all
    this subclass madness with primary/editor workspaces.

 src/libide/editor/ide-editor-workspace.c  |  69 +++----
 src/libide/editor/ide-editor-workspace.ui |   6 +-
 src/libide/gui/ide-primary-workspace.c    |  69 +++----
 src/libide/gui/ide-primary-workspace.ui   |   6 +-
 src/libide/gui/ide-workbench-session.c    |   2 +
 src/libide/gui/ide-workspace-addin.c      |  11 ++
 src/libide/gui/ide-workspace-addin.h      |   5 +
 src/libide/gui/ide-workspace-private.h    |  93 +++++----
 src/libide/gui/ide-workspace.c            | 305 +++++++++++++++++++++++++++---
 src/libide/gui/ide-workspace.h            |   2 +
 10 files changed, 409 insertions(+), 159 deletions(-)
---
diff --git a/src/libide/editor/ide-editor-workspace.c b/src/libide/editor/ide-editor-workspace.c
index 0a5063bad..1618d6717 100644
--- a/src/libide/editor/ide-editor-workspace.c
+++ b/src/libide/editor/ide-editor-workspace.c
@@ -43,11 +43,7 @@ struct _IdeEditorWorkspace
   IdeHeaderBar       *header_bar;
   AdwWindowTitle     *project_title;
   GtkMenuButton      *add_button;
-  PanelDock          *dock;
-  PanelPaned         *edge_start;
-  PanelPaned         *edge_end;
-  PanelPaned         *edge_bottom;
-  IdeGrid            *grid;
+  IdeWorkspaceDock    dock;
 };
 
 G_DEFINE_FINAL_TYPE (IdeEditorWorkspace, ide_editor_workspace, IDE_TYPE_WORKSPACE)
@@ -112,13 +108,7 @@ ide_editor_workspace_add_page (IdeWorkspace  *workspace,
 
   g_assert (IDE_IS_EDITOR_WORKSPACE (self));
 
-  _ide_workspace_add_widget (workspace,
-                             PANEL_WIDGET (page),
-                             position,
-                             self->edge_start,
-                             self->edge_end,
-                             self->edge_bottom,
-                             self->grid);
+  _ide_workspace_add_widget (workspace, PANEL_WIDGET (page), position, &self->dock);
 }
 
 static void
@@ -130,20 +120,14 @@ ide_editor_workspace_add_pane (IdeWorkspace  *workspace,
 
   g_assert (IDE_IS_EDITOR_WORKSPACE (self));
 
-  _ide_workspace_add_widget (workspace,
-                             PANEL_WIDGET (pane),
-                             position,
-                             self->edge_start,
-                             self->edge_end,
-                             self->edge_bottom,
-                             self->grid);
+  _ide_workspace_add_widget (workspace, PANEL_WIDGET (pane), position, &self->dock);
 }
 
 static void
 ide_editor_workspace_add_grid_column (IdeWorkspace *workspace,
                                       guint         position)
 {
-  panel_grid_insert_column (PANEL_GRID (IDE_EDITOR_WORKSPACE (workspace)->grid), position);
+  panel_grid_insert_column (PANEL_GRID (IDE_EDITOR_WORKSPACE (workspace)->dock.grid), position);
 }
 
 static IdeFrame *
@@ -153,7 +137,7 @@ ide_editor_workspace_get_most_recent_frame (IdeWorkspace *workspace)
 
   g_assert (IDE_IS_EDITOR_WORKSPACE (self));
 
-  return IDE_FRAME (panel_grid_get_most_recent_frame (PANEL_GRID (self->grid)));
+  return IDE_FRAME (panel_grid_get_most_recent_frame (PANEL_GRID (self->dock.grid)));
 }
 
 static PanelFrame *
@@ -165,12 +149,7 @@ ide_editor_workspace_get_frame_at_position (IdeWorkspace  *workspace,
   g_assert (IDE_IS_EDITOR_WORKSPACE (self));
   g_assert (position != NULL);
 
-  return _ide_workspace_find_frame (workspace,
-                                    position,
-                                    self->edge_start,
-                                    self->edge_end,
-                                    self->edge_bottom,
-                                    self->grid);
+  return _ide_workspace_find_frame (workspace, position, &self->dock);
 }
 
 static gboolean
@@ -190,7 +169,7 @@ ide_editor_workspace_foreach_page (IdeWorkspace    *workspace,
                                    IdePageCallback  callback,
                                    gpointer         user_data)
 {
-  ide_grid_foreach_page (IDE_EDITOR_WORKSPACE (workspace)->grid, callback, user_data);
+  ide_grid_foreach_page (IDE_EDITOR_WORKSPACE (workspace)->dock.grid, callback, user_data);
 }
 
 static void
@@ -217,7 +196,7 @@ toggle_panel_action (gpointer    instance,
 
   can_property = g_strconcat ("can-", property, NULL);
 
-  g_object_get (self->dock,
+  g_object_get (self->dock.dock,
                 can_property, &can_reveal,
                 property, &reveal,
                 NULL);
@@ -225,9 +204,9 @@ toggle_panel_action (gpointer    instance,
   reveal = !reveal;
 
   if (reveal && can_reveal)
-    g_object_set (self->dock, property, TRUE, NULL);
+    g_object_set (self->dock.dock, property, TRUE, NULL);
   else
-    g_object_set (self->dock, property, FALSE, NULL);
+    g_object_set (self->dock.dock, property, FALSE, NULL);
 }
 
 static void
@@ -237,7 +216,7 @@ ide_editor_workspace_agree_to_close_async (IdeWorkspace        *workspace,
                                            gpointer             user_data)
 {
   _ide_workspace_agree_to_close_async (workspace,
-                                       IDE_EDITOR_WORKSPACE (workspace)->grid,
+                                       IDE_EDITOR_WORKSPACE (workspace)->dock.grid,
                                        cancellable,
                                        callback,
                                        user_data);
@@ -260,7 +239,19 @@ ide_editor_workspace_save_session (IdeWorkspace *workspace,
   g_assert (IDE_IS_EDITOR_WORKSPACE (self));
   g_assert (IDE_IS_SESSION (session));
 
-  _ide_workspace_save_session_simple (workspace, session, self->dock, self->grid);
+  _ide_workspace_save_session_simple (workspace, session, &self->dock);
+}
+
+static void
+ide_editor_workspace_restore_session (IdeWorkspace *workspace,
+                                   IdeSession   *session)
+{
+  IdeEditorWorkspace *self = (IdeEditorWorkspace *)workspace;
+
+  g_assert (IDE_IS_EDITOR_WORKSPACE (self));
+  g_assert (IDE_IS_SESSION (session));
+
+  _ide_workspace_restore_session_simple (workspace, session, &self->dock);
 }
 
 static void
@@ -272,8 +263,8 @@ ide_editor_workspace_dispose (GObject *object)
    * addins/pages/etc before we ever get to removing the workspace
    * addins as part of the parent class.
    */
-  panel_dock_remove (self->dock, GTK_WIDGET (self->grid));
-  self->grid = NULL;
+  panel_dock_remove (self->dock.dock, GTK_WIDGET (self->dock.grid));
+  self->dock.grid = NULL;
 
   G_OBJECT_CLASS (ide_editor_workspace_parent_class)->dispose (object);
 }
@@ -299,19 +290,17 @@ ide_editor_workspace_class_init (IdeEditorWorkspaceClass *klass)
   workspace_class->get_header_bar = ide_editor_workspace_get_header_bar;
   workspace_class->get_most_recent_frame = ide_editor_workspace_get_most_recent_frame;
   workspace_class->save_session = ide_editor_workspace_save_session;
+  workspace_class->restore_session = ide_editor_workspace_restore_session;
 
   ide_workspace_class_set_kind (workspace_class, "editor");
 
   gtk_widget_class_set_template_from_resource (widget_class, 
"/org/gnome/libide-editor/ide-editor-workspace.ui");
   gtk_widget_class_bind_template_child (widget_class, IdeEditorWorkspace, add_button);
-  gtk_widget_class_bind_template_child (widget_class, IdeEditorWorkspace, dock);
-  gtk_widget_class_bind_template_child (widget_class, IdeEditorWorkspace, edge_bottom);
-  gtk_widget_class_bind_template_child (widget_class, IdeEditorWorkspace, edge_end);
-  gtk_widget_class_bind_template_child (widget_class, IdeEditorWorkspace, edge_start);
-  gtk_widget_class_bind_template_child (widget_class, IdeEditorWorkspace, grid);
   gtk_widget_class_bind_template_child (widget_class, IdeEditorWorkspace, header_bar);
   gtk_widget_class_bind_template_child (widget_class, IdeEditorWorkspace, project_title);
 
+  _ide_workspace_class_bind_template_dock (widget_class, G_STRUCT_OFFSET (IdeEditorWorkspace, dock));
+
   ide_workspace_class_install_action (workspace_class, "panel.toggle-start", NULL, toggle_panel_action);
   ide_workspace_class_install_action (workspace_class, "panel.toggle-end", NULL, toggle_panel_action);
   ide_workspace_class_install_action (workspace_class, "panel.toggle-bottom", NULL, toggle_panel_action);
diff --git a/src/libide/editor/ide-editor-workspace.ui b/src/libide/editor/ide-editor-workspace.ui
index 7bc9a9c39..04d13be01 100644
--- a/src/libide/editor/ide-editor-workspace.ui
+++ b/src/libide/editor/ide-editor-workspace.ui
@@ -47,12 +47,12 @@
           </object>
         </child>
         <child type="start">
-          <object class="PanelPaned" id="edge_start">
+          <object class="PanelPaned" id="start_area">
             <property name="orientation">vertical</property>
           </object>
         </child>
         <child type="end">
-          <object class="PanelPaned" id="edge_end">
+          <object class="PanelPaned" id="end_area">
             <property name="orientation">vertical</property>
             <child>
               <object class="PanelFrame">
@@ -61,7 +61,7 @@
           </object>
         </child>
         <child type="bottom">
-          <object class="PanelPaned" id="edge_bottom">
+          <object class="PanelPaned" id="bottom_area">
             <property name="orientation">horizontal</property>
           </object>
         </child>
diff --git a/src/libide/gui/ide-primary-workspace.c b/src/libide/gui/ide-primary-workspace.c
index a4d1c42c8..08d9af684 100644
--- a/src/libide/gui/ide-primary-workspace.c
+++ b/src/libide/gui/ide-primary-workspace.c
@@ -54,14 +54,10 @@ struct _IdePrimaryWorkspace
   IdeRunButton       *run_button;
   GtkLabel           *project_title;
   GtkMenuButton      *add_button;
-  PanelDock          *dock;
-  PanelPaned         *edge_start;
-  PanelPaned         *edge_end;
-  PanelPaned         *edge_bottom;
-  IdeGrid            *grid;
   GtkOverlay         *overlay;
   IdeOmniBar         *omni_bar;
   IdeJoinedMenu      *build_menu;
+  IdeWorkspaceDock    dock;
 };
 
 G_DEFINE_FINAL_TYPE (IdePrimaryWorkspace, ide_primary_workspace, IDE_TYPE_WORKSPACE)
@@ -104,13 +100,7 @@ ide_primary_workspace_add_page (IdeWorkspace  *workspace,
 
   g_assert (IDE_IS_PRIMARY_WORKSPACE (self));
 
-  _ide_workspace_add_widget (workspace,
-                             PANEL_WIDGET (page),
-                             position,
-                             self->edge_start,
-                             self->edge_end,
-                             self->edge_bottom,
-                             self->grid);
+  _ide_workspace_add_widget (workspace, PANEL_WIDGET (page), position, &self->dock);
 }
 
 static void
@@ -122,20 +112,14 @@ ide_primary_workspace_add_pane (IdeWorkspace  *workspace,
 
   g_assert (IDE_IS_PRIMARY_WORKSPACE (self));
 
-  _ide_workspace_add_widget (workspace,
-                             PANEL_WIDGET (pane),
-                             position,
-                             self->edge_start,
-                             self->edge_end,
-                             self->edge_bottom,
-                             self->grid);
+  _ide_workspace_add_widget (workspace, PANEL_WIDGET (pane), position, &self->dock);
 }
 
 static void
 ide_primary_workspace_add_grid_column (IdeWorkspace *workspace,
                                        guint         position)
 {
-  panel_grid_insert_column (PANEL_GRID (IDE_PRIMARY_WORKSPACE (workspace)->grid), position);
+  panel_grid_insert_column (PANEL_GRID (IDE_PRIMARY_WORKSPACE (workspace)->dock.grid), position);
 }
 
 static void
@@ -167,7 +151,7 @@ ide_primary_workspace_get_most_recent_frame (IdeWorkspace *workspace)
 
   g_assert (IDE_IS_PRIMARY_WORKSPACE (self));
 
-  return IDE_FRAME (panel_grid_get_most_recent_frame (PANEL_GRID (self->grid)));
+  return IDE_FRAME (panel_grid_get_most_recent_frame (PANEL_GRID (self->dock.grid)));
 }
 
 static PanelFrame *
@@ -179,12 +163,7 @@ ide_primary_workspace_get_frame_at_position (IdeWorkspace  *workspace,
   g_assert (IDE_IS_PRIMARY_WORKSPACE (self));
   g_assert (position != NULL);
 
-  return _ide_workspace_find_frame (workspace,
-                                    position,
-                                    self->edge_start,
-                                    self->edge_end,
-                                    self->edge_bottom,
-                                    self->grid);
+  return _ide_workspace_find_frame (workspace, position, &self->dock);
 }
 
 static gboolean
@@ -204,7 +183,7 @@ ide_primary_workspace_foreach_page (IdeWorkspace    *workspace,
                                     IdePageCallback  callback,
                                     gpointer         user_data)
 {
-  ide_grid_foreach_page (IDE_PRIMARY_WORKSPACE (workspace)->grid, callback, user_data);
+  ide_grid_foreach_page (IDE_PRIMARY_WORKSPACE (workspace)->dock.grid, callback, user_data);
 }
 
 static void
@@ -231,7 +210,7 @@ toggle_panel_action (gpointer    instance,
 
   can_property = g_strconcat ("can-", property, NULL);
 
-  g_object_get (self->dock,
+  g_object_get (self->dock.dock,
                 can_property, &can_reveal,
                 property, &reveal,
                 NULL);
@@ -239,9 +218,9 @@ toggle_panel_action (gpointer    instance,
   reveal = !reveal;
 
   if (reveal && can_reveal)
-    g_object_set (self->dock, property, TRUE, NULL);
+    g_object_set (self->dock.dock, property, TRUE, NULL);
   else
-    g_object_set (self->dock, property, FALSE, NULL);
+    g_object_set (self->dock.dock, property, FALSE, NULL);
 }
 
 static void
@@ -251,7 +230,7 @@ ide_primary_workspace_agree_to_close_async (IdeWorkspace        *workspace,
                                             gpointer             user_data)
 {
   _ide_workspace_agree_to_close_async (workspace,
-                                       IDE_PRIMARY_WORKSPACE (workspace)->grid,
+                                       IDE_PRIMARY_WORKSPACE (workspace)->dock.grid,
                                        cancellable,
                                        callback,
                                        user_data);
@@ -274,7 +253,19 @@ ide_primary_workspace_save_session (IdeWorkspace *workspace,
   g_assert (IDE_IS_PRIMARY_WORKSPACE (self));
   g_assert (IDE_IS_SESSION (session));
 
-  _ide_workspace_save_session_simple (workspace, session, self->dock, self->grid);
+  _ide_workspace_save_session_simple (workspace, session, &self->dock);
+}
+
+static void
+ide_primary_workspace_restore_session (IdeWorkspace *workspace,
+                                       IdeSession   *session)
+{
+  IdePrimaryWorkspace *self = (IdePrimaryWorkspace *)workspace;
+
+  g_assert (IDE_IS_PRIMARY_WORKSPACE (self));
+  g_assert (IDE_IS_SESSION (session));
+
+  _ide_workspace_restore_session_simple (workspace, session, &self->dock);
 }
 
 static void
@@ -286,8 +277,8 @@ ide_primary_workspace_dispose (GObject *object)
    * addins/pages/etc before we ever get to removing the workspace
    * addins as part of the parent class.
    */
-  panel_dock_remove (self->dock, GTK_WIDGET (self->grid));
-  self->grid = NULL;
+  panel_dock_remove (self->dock.dock, GTK_WIDGET (self->dock.grid));
+  self->dock.grid = NULL;
 
   G_OBJECT_CLASS (ide_primary_workspace_parent_class)->dispose (object);
 }
@@ -315,23 +306,21 @@ ide_primary_workspace_class_init (IdePrimaryWorkspaceClass *klass)
   workspace_class->get_most_recent_frame = ide_primary_workspace_get_most_recent_frame;
   workspace_class->remove_overlay = ide_primary_workspace_remove_overlay;
   workspace_class->save_session = ide_primary_workspace_save_session;
+  workspace_class->restore_session = ide_primary_workspace_restore_session;
 
   ide_workspace_class_set_kind (workspace_class, "primary");
 
   gtk_widget_class_set_template_from_resource (widget_class, 
"/org/gnome/libide-gui/ui/ide-primary-workspace.ui");
   gtk_widget_class_bind_template_child (widget_class, IdePrimaryWorkspace, add_button);
   gtk_widget_class_bind_template_child (widget_class, IdePrimaryWorkspace, build_menu);
-  gtk_widget_class_bind_template_child (widget_class, IdePrimaryWorkspace, dock);
-  gtk_widget_class_bind_template_child (widget_class, IdePrimaryWorkspace, edge_bottom);
-  gtk_widget_class_bind_template_child (widget_class, IdePrimaryWorkspace, edge_end);
-  gtk_widget_class_bind_template_child (widget_class, IdePrimaryWorkspace, edge_start);
-  gtk_widget_class_bind_template_child (widget_class, IdePrimaryWorkspace, grid);
   gtk_widget_class_bind_template_child (widget_class, IdePrimaryWorkspace, header_bar);
   gtk_widget_class_bind_template_child (widget_class, IdePrimaryWorkspace, omni_bar);
   gtk_widget_class_bind_template_child (widget_class, IdePrimaryWorkspace, overlay);
   gtk_widget_class_bind_template_child (widget_class, IdePrimaryWorkspace, project_title);
   gtk_widget_class_bind_template_child (widget_class, IdePrimaryWorkspace, run_button);
 
+  _ide_workspace_class_bind_template_dock (widget_class, G_STRUCT_OFFSET (IdePrimaryWorkspace, dock));
+
   ide_workspace_class_install_action (workspace_class, "panel.toggle-start", NULL, toggle_panel_action);
   ide_workspace_class_install_action (workspace_class, "panel.toggle-end", NULL, toggle_panel_action);
   ide_workspace_class_install_action (workspace_class, "panel.toggle-bottom", NULL, toggle_panel_action);
diff --git a/src/libide/gui/ide-primary-workspace.ui b/src/libide/gui/ide-primary-workspace.ui
index deaf9307e..94fad38e0 100644
--- a/src/libide/gui/ide-primary-workspace.ui
+++ b/src/libide/gui/ide-primary-workspace.ui
@@ -76,12 +76,12 @@
           </object>
         </child>
         <child type="start">
-          <object class="PanelPaned" id="edge_start">
+          <object class="PanelPaned" id="start_area">
             <property name="orientation">vertical</property>
           </object>
         </child>
         <child type="end">
-          <object class="PanelPaned" id="edge_end">
+          <object class="PanelPaned" id="end_area">
             <property name="orientation">vertical</property>
             <child>
               <object class="PanelFrame">
@@ -90,7 +90,7 @@
           </object>
         </child>
         <child type="bottom">
-          <object class="PanelPaned" id="edge_bottom">
+          <object class="PanelPaned" id="bottom_area">
             <property name="orientation">horizontal</property>
           </object>
         </child>
diff --git a/src/libide/gui/ide-workbench-session.c b/src/libide/gui/ide-workbench-session.c
index bebb31e4c..7e08cccf0 100644
--- a/src/libide/gui/ide-workbench-session.c
+++ b/src/libide/gui/ide-workbench-session.c
@@ -128,6 +128,8 @@ _ide_workbench_restore_workspaces (IdeWorkbench *self,
               if (is_maximized)
                 gtk_window_maximize (GTK_WINDOW (workspace));
 
+              _ide_workspace_restore_session (workspace, session);
+
               if (is_active)
                 active_window = workspace;
               else
diff --git a/src/libide/gui/ide-workspace-addin.c b/src/libide/gui/ide-workspace-addin.c
index 4abe70975..d82a18bf8 100644
--- a/src/libide/gui/ide-workspace-addin.c
+++ b/src/libide/gui/ide-workspace-addin.c
@@ -143,3 +143,14 @@ ide_workspace_addin_save_session (IdeWorkspaceAddin *self,
   if (IDE_WORKSPACE_ADDIN_GET_IFACE (self)->save_session)
     IDE_WORKSPACE_ADDIN_GET_IFACE (self)->save_session (self, session);
 }
+
+void
+ide_workspace_addin_restore_session (IdeWorkspaceAddin *self,
+                                     IdeSession        *session)
+{
+  g_return_if_fail (IDE_IS_WORKSPACE_ADDIN (self));
+  g_return_if_fail (IDE_IS_SESSION (session));
+
+  if (IDE_WORKSPACE_ADDIN_GET_IFACE (self)->restore_session)
+    IDE_WORKSPACE_ADDIN_GET_IFACE (self)->restore_session (self, session);
+}
diff --git a/src/libide/gui/ide-workspace-addin.h b/src/libide/gui/ide-workspace-addin.h
index 19db630fb..64f43691d 100644
--- a/src/libide/gui/ide-workspace-addin.h
+++ b/src/libide/gui/ide-workspace-addin.h
@@ -50,6 +50,8 @@ struct _IdeWorkspaceAddinInterface
   GActionGroup *(*ref_action_group) (IdeWorkspaceAddin *self);
   void          (*save_session)     (IdeWorkspaceAddin *self,
                                      IdeSession        *session);
+  void          (*restore_session)  (IdeWorkspaceAddin *self,
+                                     IdeSession        *session);
 };
 
 IDE_AVAILABLE_IN_ALL
@@ -65,6 +67,9 @@ IDE_AVAILABLE_IN_ALL
 void               ide_workspace_addin_save_session        (IdeWorkspaceAddin *self,
                                                             IdeSession        *session);
 IDE_AVAILABLE_IN_ALL
+void               ide_workspace_addin_restore_session     (IdeWorkspaceAddin *self,
+                                                            IdeSession        *session);
+IDE_AVAILABLE_IN_ALL
 GActionGroup      *ide_workspace_addin_ref_action_group    (IdeWorkspaceAddin *self);
 IDE_AVAILABLE_IN_ALL
 IdeWorkspaceAddin *ide_workspace_addin_find_by_module_name (IdeWorkspace      *workspace,
diff --git a/src/libide/gui/ide-workspace-private.h b/src/libide/gui/ide-workspace-private.h
index 492b5ab1f..634b0649f 100644
--- a/src/libide/gui/ide-workspace-private.h
+++ b/src/libide/gui/ide-workspace-private.h
@@ -26,47 +26,56 @@
 
 G_BEGIN_DECLS
 
-GList      *_ide_workspace_get_mru_link            (IdeWorkspace         *self);
-void        _ide_workspace_add_page_mru            (IdeWorkspace         *self,
-                                                    GList                *mru_link);
-void        _ide_workspace_remove_page_mru         (IdeWorkspace         *self,
-                                                    GList                *mru_link);
-void        _ide_workspace_move_front_page_mru     (IdeWorkspace         *workspace,
-                                                    GList                *mru_link);
-void        _ide_workspace_set_context             (IdeWorkspace         *workspace,
-                                                    IdeContext           *context);
-gboolean    _ide_workspace_can_search              (IdeWorkspace         *self);
-void        _ide_workspace_begin_global_search     (IdeWorkspace         *self);
-void        _ide_workspace_add_widget              (IdeWorkspace         *workspace,
-                                                    PanelWidget          *widget,
-                                                    PanelPosition        *position,
-                                                    PanelPaned           *dock_start,
-                                                    PanelPaned           *dock_end,
-                                                    PanelPaned           *dock_bottom,
-                                                    IdeGrid              *grid);
-PanelFrame *_ide_workspace_find_frame              (IdeWorkspace         *workspace,
-                                                    PanelPosition        *position,
-                                                    PanelPaned           *dock_start,
-                                                    PanelPaned           *dock_end,
-                                                    PanelPaned           *dock_bottom,
-                                                    IdeGrid              *grid);
-void        _ide_workspace_set_shortcut_model      (IdeWorkspace         *self,
-                                                    GListModel           *shortcuts);
-void        _ide_workspace_agree_to_close_async    (IdeWorkspace         *self,
-                                                    IdeGrid              *grid,
-                                                    GCancellable         *cancellable,
-                                                    GAsyncReadyCallback   callback,
-                                                    gpointer              user_data);
-gboolean    _ide_workspace_agree_to_close_finish   (IdeWorkspace         *self,
-                                                    GAsyncResult         *result,
-                                                    GError              **error);
-void        _ide_workspace_save_session_simple     (IdeWorkspace         *self,
-                                                    IdeSession           *session,
-                                                    PanelDock            *dock,
-                                                    IdeGrid              *grid);
-void        _ide_workspace_save_session            (IdeWorkspace         *self,
-                                                    IdeSession           *session);
-void        _ide_workspace_set_ignore_size_setting (IdeWorkspace         *self,
-                                                    gboolean              ignore_size_setting);
+typedef struct
+{
+  PanelDock  *dock;
+  IdeGrid    *grid;
+  PanelPaned *start_area;
+  PanelPaned *end_area;
+  PanelPaned *bottom_area;
+} IdeWorkspaceDock;
+
+void        _ide_workspace_class_bind_template_dock (GtkWidgetClass       *widget_class,
+                                                     goffset               struct_offset);
+GList      *_ide_workspace_get_mru_link             (IdeWorkspace         *self);
+void        _ide_workspace_add_page_mru             (IdeWorkspace         *self,
+                                                     GList                *mru_link);
+void        _ide_workspace_remove_page_mru          (IdeWorkspace         *self,
+                                                     GList                *mru_link);
+void        _ide_workspace_move_front_page_mru      (IdeWorkspace         *workspace,
+                                                     GList                *mru_link);
+void        _ide_workspace_set_context              (IdeWorkspace         *workspace,
+                                                     IdeContext           *context);
+gboolean    _ide_workspace_can_search               (IdeWorkspace         *self);
+void        _ide_workspace_begin_global_search      (IdeWorkspace         *self);
+void        _ide_workspace_add_widget               (IdeWorkspace         *workspace,
+                                                     PanelWidget          *widget,
+                                                     PanelPosition        *position,
+                                                     IdeWorkspaceDock     *dock);
+PanelFrame *_ide_workspace_find_frame               (IdeWorkspace         *workspace,
+                                                     PanelPosition        *position,
+                                                     IdeWorkspaceDock     *dock);
+void        _ide_workspace_set_shortcut_model       (IdeWorkspace         *self,
+                                                     GListModel           *shortcuts);
+void        _ide_workspace_agree_to_close_async     (IdeWorkspace         *self,
+                                                     IdeGrid              *grid,
+                                                     GCancellable         *cancellable,
+                                                     GAsyncReadyCallback   callback,
+                                                     gpointer              user_data);
+gboolean    _ide_workspace_agree_to_close_finish    (IdeWorkspace         *self,
+                                                     GAsyncResult         *result,
+                                                     GError              **error);
+void        _ide_workspace_save_session             (IdeWorkspace         *self,
+                                                     IdeSession           *session);
+void        _ide_workspace_save_session_simple      (IdeWorkspace         *self,
+                                                     IdeSession           *session,
+                                                     IdeWorkspaceDock     *dock);
+void        _ide_workspace_restore_session          (IdeWorkspace         *self,
+                                                     IdeSession           *session);
+void        _ide_workspace_restore_session_simple   (IdeWorkspace         *self,
+                                                     IdeSession           *session,
+                                                     IdeWorkspaceDock     *dock);
+void        _ide_workspace_set_ignore_size_setting  (IdeWorkspace         *self,
+                                                     gboolean              ignore_size_setting);
 
 G_END_DECLS
diff --git a/src/libide/gui/ide-workspace.c b/src/libide/gui/ide-workspace.c
index 83844d26a..dea513b96 100644
--- a/src/libide/gui/ide-workspace.c
+++ b/src/libide/gui/ide-workspace.c
@@ -127,6 +127,46 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (IdeWorkspace, ide_workspace, ADW_TYPE_APPLICAT
 static GParamSpec *properties [N_PROPS];
 static GSettings *settings;
 
+G_GNUC_UNUSED static void
+dump_position (PanelPosition *position)
+{
+  GString *str = g_string_new (NULL);
+
+  if (panel_position_get_area_set (position))
+    {
+      PanelArea area = panel_position_get_area (position);
+      g_autoptr(GEnumClass) klass = g_type_class_ref (PANEL_TYPE_AREA);
+      GEnumValue *value = g_enum_get_value (klass, area);
+
+      g_string_append_printf (str, "area=%s ", value->value_nick);
+    }
+
+  if (panel_position_get_column_set (position))
+    {
+      guint column = panel_position_get_column (position);
+      g_string_append_printf (str, "column=%d ", column);
+    }
+
+  if (panel_position_get_row_set (position))
+    {
+      guint row = panel_position_get_row (position);
+      g_string_append_printf (str, "row=%d ", row);
+    }
+
+  if (panel_position_get_depth_set (position))
+    {
+      guint depth = panel_position_get_depth (position);
+      g_string_append_printf (str, "depth=%d ", depth);
+    }
+
+  if (str->len == 0)
+    g_print ("Empty Position\n");
+  else
+    g_print ("%s\n", str->str);
+
+  g_string_free (str, TRUE);
+}
+
 static void
 ide_workspace_attach_shortcuts (IdeWorkspace *self,
                                 GtkWidget    *widget)
@@ -1274,13 +1314,10 @@ dummy_cb (gpointer data)
 }
 
 void
-_ide_workspace_add_widget (IdeWorkspace  *self,
-                           PanelWidget   *widget,
-                           PanelPosition *position,
-                           PanelPaned    *dock_start,
-                           PanelPaned    *dock_end,
-                           PanelPaned    *dock_bottom,
-                           IdeGrid       *grid)
+_ide_workspace_add_widget (IdeWorkspace     *self,
+                           PanelWidget      *widget,
+                           PanelPosition    *position,
+                           IdeWorkspaceDock *dock)
 {
   PanelFrame *frame;
   gboolean depth_set;
@@ -1291,12 +1328,9 @@ _ide_workspace_add_widget (IdeWorkspace  *self,
   g_return_if_fail (IDE_IS_WORKSPACE (self));
   g_return_if_fail (PANEL_IS_WIDGET (widget));
   g_return_if_fail (position != NULL);
-  g_return_if_fail (!dock_start || PANEL_IS_PANED (dock_start));
-  g_return_if_fail (!dock_end || PANEL_IS_PANED (dock_end));
-  g_return_if_fail (!dock_bottom || PANEL_IS_PANED (dock_bottom));
-  g_return_if_fail (IDE_IS_GRID (grid));
+  g_return_if_fail (dock != NULL);
 
-  if (!(frame = _ide_workspace_find_frame (self, position, dock_start, dock_end, dock_bottom, grid)))
+  if (!(frame = _ide_workspace_find_frame (self, position, dock)))
     {
       /* Extreme failure case, try to be nice and wait until
        * end of the main loop to destroy
@@ -1315,12 +1349,9 @@ _ide_workspace_add_widget (IdeWorkspace  *self,
 }
 
 PanelFrame *
-_ide_workspace_find_frame (IdeWorkspace  *self,
-                           PanelPosition *position,
-                           PanelPaned    *dock_start,
-                           PanelPaned    *dock_end,
-                           PanelPaned    *dock_bottom,
-                           IdeGrid       *grid)
+_ide_workspace_find_frame (IdeWorkspace     *self,
+                           PanelPosition    *position,
+                           IdeWorkspaceDock *dock)
 {
   PanelArea area;
   PanelPaned *paned = NULL;
@@ -1334,9 +1365,7 @@ _ide_workspace_find_frame (IdeWorkspace  *self,
 
   g_return_val_if_fail (IDE_IS_WORKSPACE (self), NULL);
   g_return_val_if_fail (position != NULL, NULL);
-  g_return_val_if_fail (!dock_start || PANEL_IS_PANED (dock_start), NULL);
-  g_return_val_if_fail (!dock_end || PANEL_IS_PANED (dock_end), NULL);
-  g_return_val_if_fail (!dock_bottom || PANEL_IS_PANED (dock_bottom), NULL);
+  g_return_val_if_fail (dock != NULL, NULL);
 
   if (!ide_panel_position_get_area (position, &area))
     area = PANEL_AREA_CENTER;
@@ -1352,11 +1381,11 @@ _ide_workspace_find_frame (IdeWorkspace  *self,
        */
       if (!has_column && !has_row)
         {
-          if (!find_open_frame (grid, &column, &row))
-            find_most_recent_frame (self, grid, &column, &row);
+          if (!find_open_frame (dock->grid, &column, &row))
+            find_most_recent_frame (self, dock->grid, &column, &row);
         }
 
-      ret = panel_grid_column_get_row (panel_grid_get_column (PANEL_GRID (grid), column), row);
+      ret = panel_grid_column_get_row (panel_grid_get_column (PANEL_GRID (dock->grid), column), row);
 
       IDE_RETURN (ret);
     }
@@ -1364,17 +1393,17 @@ _ide_workspace_find_frame (IdeWorkspace  *self,
   switch (area)
     {
     case PANEL_AREA_START:
-      paned = dock_start;
+      paned = dock->start_area;
       ide_panel_position_get_row (position, &nth);
       break;
 
     case PANEL_AREA_END:
-      paned = dock_end;
+      paned = dock->end_area;
       ide_panel_position_get_row (position, &nth);
       break;
 
     case PANEL_AREA_BOTTOM:
-      paned = dock_bottom;
+      paned = dock->bottom_area;
       ide_panel_position_get_column (position, &nth);
       break;
 
@@ -1761,11 +1790,48 @@ _ide_workspace_save_session (IdeWorkspace *self,
   IDE_EXIT;
 }
 
+static void
+ide_workspace_save_session_frame_cb (PanelFrame *frame,
+                                     gpointer    user_data)
+{
+  g_autoptr(PanelPosition) position = NULL;
+  g_autoptr(IdeSessionItem) item = NULL;
+  IdeSession *session = user_data;
+  IdeWorkspace *workspace;
+  int requested_size;
+
+  IDE_ENTRY;
+
+  g_assert (IDE_IS_MAIN_THREAD ());
+  g_assert (PANEL_IS_FRAME (frame));
+  g_assert (IDE_IS_SESSION (session));
+
+  position = panel_frame_get_position (frame);
+  workspace = ide_widget_get_workspace (GTK_WIDGET (frame));
+  requested_size = panel_frame_get_requested_size (frame);
+
+#if 0
+  dump_position (position);
+#endif
+
+  item = ide_session_item_new ();
+  ide_session_item_set_module_name (item, "libide-gui");
+  ide_session_item_set_type_hint (item, G_OBJECT_TYPE_NAME (frame));
+  ide_session_item_set_position (item, position);
+  ide_session_item_set_workspace (item, ide_workspace_get_id (workspace));
+
+  if (requested_size > -1)
+    ide_session_item_set_metadata (item, "size", "i", requested_size);
+
+  ide_session_append (session, item);
+
+  IDE_EXIT;
+}
+
 void
-_ide_workspace_save_session_simple (IdeWorkspace *self,
-                                    IdeSession   *session,
-                                    PanelDock    *dock,
-                                    IdeGrid      *grid)
+_ide_workspace_save_session_simple (IdeWorkspace     *self,
+                                    IdeSession       *session,
+                                    IdeWorkspaceDock *dock)
 {
   g_autoptr(IdeSessionItem) item = NULL;
   int width;
@@ -1789,11 +1855,168 @@ _ide_workspace_save_session_simple (IdeWorkspace *self,
     ide_session_item_set_metadata (item, "is-maximized", "b", TRUE);
   ide_session_prepend (session, item);
 
+  panel_dock_foreach_frame (dock->dock,
+                            ide_workspace_save_session_frame_cb,
+                            session);
+  panel_grid_foreach_frame (PANEL_GRID (dock->grid),
+                            ide_workspace_save_session_frame_cb,
+                            session);
+
   /* TODO: Save panel and grid frame size/positions */
 
   IDE_EXIT;
 }
 
+static void
+ide_workspace_addin_restore_session_cb (IdeExtensionSetAdapter *adapter,
+                                        PeasPluginInfo         *plugin_info,
+                                        PeasExtension          *exten,
+                                        gpointer                user_data)
+{
+  IdeWorkspaceAddin *addin = (IdeWorkspaceAddin *)exten;
+  IdeSession *session = user_data;
+
+  g_assert (IDE_IS_EXTENSION_SET_ADAPTER (adapter));
+  g_assert (plugin_info != NULL);
+  g_assert (IDE_IS_WORKSPACE_ADDIN (addin));
+  g_assert (IDE_IS_SESSION (session));
+
+  ide_workspace_addin_restore_session (addin, session);
+}
+
+void
+_ide_workspace_restore_session (IdeWorkspace *self,
+                                IdeSession   *session)
+{
+  IdeWorkspacePrivate *priv = ide_workspace_get_instance_private (self);
+
+  IDE_ENTRY;
+
+  g_return_if_fail (IDE_IS_WORKSPACE (self));
+  g_return_if_fail (IDE_IS_SESSION (session));
+
+  if (IDE_WORKSPACE_GET_CLASS (self)->restore_session)
+    IDE_WORKSPACE_GET_CLASS (self)->restore_session (self, session);
+
+  ide_extension_set_adapter_foreach (priv->addins,
+                                     ide_workspace_addin_restore_session_cb,
+                                     session);
+
+  IDE_EXIT;
+}
+
+static void
+ide_workspace_restore_frame (IdeWorkspace     *self,
+                             GType             type,
+                             IdeSessionItem   *item,
+                             IdeWorkspaceDock *dock)
+{
+  PanelPosition *position;
+  GtkWidget *frame;
+  PanelArea area;
+
+  g_assert (IDE_IS_WORKSPACE (self));
+  g_assert (g_type_is_a (type, PANEL_TYPE_FRAME));
+  g_assert (IDE_IS_SESSION_ITEM (item));
+
+  if (!(position = ide_session_item_get_position (item)))
+    return;
+
+  if (!panel_position_get_area_set (position))
+    return;
+
+  area = panel_position_get_area (position);
+  if ((area == PANEL_AREA_CENTER && type != IDE_TYPE_FRAME) ||
+      (area != PANEL_AREA_CENTER && type != PANEL_TYPE_FRAME))
+    return;
+
+  if (area == PANEL_AREA_START || area == PANEL_AREA_END)
+    {
+      PanelPaned *paned = area == PANEL_AREA_START ? dock->start_area : dock->end_area;
+      int row = panel_position_get_row (position);
+
+      while (panel_paned_get_n_children (paned) <= row)
+        {
+          frame = panel_frame_new ();
+          panel_paned_append (paned, GTK_WIDGET (frame));
+        }
+
+      frame = panel_paned_get_nth_child (paned, row);
+    }
+  else if (area == PANEL_AREA_TOP)
+    {
+      /* Ignored */
+      return;
+    }
+  else if (area == PANEL_AREA_BOTTOM)
+    {
+      PanelPaned *paned = dock->bottom_area;
+      int column = panel_position_get_column (position);
+
+      while (panel_paned_get_n_children (paned) <= column)
+        {
+          frame = panel_frame_new ();
+          panel_paned_append (paned, GTK_WIDGET (frame));
+        }
+
+      frame = panel_paned_get_nth_child (paned, column);
+    }
+  else
+    {
+      int column = panel_position_get_column (position);
+      int row = panel_position_get_row (position);
+
+      frame = GTK_WIDGET (ide_grid_make_frame (dock->grid, column, row));
+    }
+
+  if (ide_session_item_has_metadata_with_type (item, "size", G_VARIANT_TYPE ("i")))
+    {
+      int size;
+
+      ide_session_item_get_metadata (item, "size", "i", &size);
+      panel_frame_set_requested_size (PANEL_FRAME (frame), size);
+    }
+}
+
+void
+_ide_workspace_restore_session_simple (IdeWorkspace     *self,
+                                       IdeSession       *session,
+                                       IdeWorkspaceDock *dock)
+{
+  guint n_items;
+
+  IDE_ENTRY;
+
+  g_return_if_fail (IDE_IS_WORKSPACE (self));
+  g_return_if_fail (IDE_IS_SESSION (session));
+
+  n_items = ide_session_get_n_items (session);
+
+  for (guint i = 0; i < n_items; i++)
+    {
+      IdeSessionItem *item = ide_session_get_item (session, i);
+      const char *module_name = ide_session_item_get_module_name (item);
+
+      if (ide_str_equal0 (module_name, "libide-gui"))
+        {
+          const char *workspace_id = ide_session_item_get_workspace (item);
+          const char *type_hint = ide_session_item_get_type_hint (item);
+          GType type = type_hint ? g_type_from_name (type_hint) : G_TYPE_INVALID;
+
+          if (type == G_TYPE_INVALID)
+            continue;
+
+          if (!ide_str_equal0 (workspace_id, ide_workspace_get_id (self)))
+            continue;
+
+          if (g_type_is_a (type, PANEL_TYPE_FRAME))
+            ide_workspace_restore_frame (self, type, item, dock);
+        }
+    }
+
+  IDE_EXIT;
+}
+
 void
 ide_workspace_set_id (IdeWorkspace *self,
                       const char   *id)
@@ -1815,3 +2038,23 @@ ide_workspace_get_id (IdeWorkspace *self)
 
   return priv->id;
 }
+
+void
+_ide_workspace_class_bind_template_dock (GtkWidgetClass *widget_class,
+                                         goffset         struct_offset)
+{
+  g_return_if_fail (IDE_IS_WORKSPACE_CLASS (widget_class));
+  g_return_if_fail (struct_offset > 0);
+
+  /* TODO: We should just add an IdeDock class w/ the widgetry all defined. */
+
+#define BIND_CHILD(c, name) \
+  gtk_widget_class_bind_template_child_full (c, #name, FALSE, \
+                                             struct_offset + G_STRUCT_OFFSET (IdeWorkspaceDock, name))
+  BIND_CHILD (widget_class, dock);
+  BIND_CHILD (widget_class, grid);
+  BIND_CHILD (widget_class, start_area);
+  BIND_CHILD (widget_class, bottom_area);
+  BIND_CHILD (widget_class, end_area);
+#undef BIND_CHILD
+}
diff --git a/src/libide/gui/ide-workspace.h b/src/libide/gui/ide-workspace.h
index 547363c13..9521bdc19 100644
--- a/src/libide/gui/ide-workspace.h
+++ b/src/libide/gui/ide-workspace.h
@@ -95,6 +95,8 @@ struct _IdeWorkspaceClass
   gboolean      (*can_search)            (IdeWorkspace         *self);
   void          (*save_session)          (IdeWorkspace         *self,
                                           IdeSession           *session);
+  void          (*restore_session)       (IdeWorkspace         *self,
+                                          IdeSession           *session);
 };
 
 IDE_AVAILABLE_IN_ALL


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