[gnome-builder/wip/gtk4-port: 143/736] libide/gui: make IdeWorkspace compile




commit 27c2eea1d2b1f145418607b557a8fd5a2565badb
Author: Christian Hergert <chergert redhat com>
Date:   Mon Mar 28 23:13:43 2022 -0700

    libide/gui: make IdeWorkspace compile
    
    Strip out surfaces, fix all the callback types, etc.

 src/libide/gui/ide-gui-private.h        |  22 +-
 src/libide/gui/ide-omni-bar.ui          |   1 -
 src/libide/gui/ide-workspace-actions.c  |   1 -
 src/libide/gui/ide-workspace-addin.c    |  51 ---
 src/libide/gui/ide-workspace-addin.h    |  16 +-
 src/libide/gui/ide-workspace.c          | 637 +++-----------------------------
 src/libide/gui/ide-workspace.h          |  19 +-
 src/libide/gui/ide-workspace.ui         |  33 --
 src/libide/gui/libide-gui.gresource.xml |   1 -
 9 files changed, 81 insertions(+), 700 deletions(-)
---
diff --git a/src/libide/gui/ide-gui-private.h b/src/libide/gui/ide-gui-private.h
index fc1e1922e..8875b0d60 100644
--- a/src/libide/gui/ide-gui-private.h
+++ b/src/libide/gui/ide-gui-private.h
@@ -20,29 +20,13 @@
 
 #pragma once
 
-#include <adwaita.h>
-#include <libpeas/peas.h>
-#include <libpeas/peas-autocleanups.h>
-#include <libpanel.h>
-
-#include <libide-core.h>
-#include <libide-projects.h>
-
 #include "ide-header-bar.h"
-#include "ide-notification-list-box-row-private.h"
-#include "ide-notification-stack-private.h"
-#include "ide-notification-view-private.h"
-#include "ide-page.h"
 #include "ide-primary-workspace.h"
-#include "ide-workbench.h"
-#include "ide-workspace.h"
 
 G_BEGIN_DECLS
 
-void      _ide_primary_workspace_init_actions   (IdePrimaryWorkspace *self);
-void      _ide_header_bar_init_shortcuts        (IdeHeaderBar        *self);
-void      _ide_header_bar_show_menu             (IdeHeaderBar        *self);
-void      _ide_surface_set_fullscreen           (IdeSurface          *self,
-                                                 gboolean             fullscreen);
+void _ide_primary_workspace_init_actions (IdePrimaryWorkspace *self);
+void _ide_header_bar_init_shortcuts      (IdeHeaderBar        *self);
+void _ide_header_bar_show_menu           (IdeHeaderBar        *self);
 
 G_END_DECLS
diff --git a/src/libide/gui/ide-omni-bar.ui b/src/libide/gui/ide-omni-bar.ui
index cd9ed03a3..c08d1f154 100644
--- a/src/libide/gui/ide-omni-bar.ui
+++ b/src/libide/gui/ide-omni-bar.ui
@@ -12,7 +12,6 @@
           <object class="GtkBox">
             <property name="orientation">vertical</property>
             <property name="spacing">12</property>
-            </child>
             <child>
               <object class="GtkBox" id="sections_box">
                 <property name="orientation">vertical</property>
diff --git a/src/libide/gui/ide-workspace-actions.c b/src/libide/gui/ide-workspace-actions.c
index daef11ed8..7d75dc95c 100644
--- a/src/libide/gui/ide-workspace-actions.c
+++ b/src/libide/gui/ide-workspace-actions.c
@@ -99,7 +99,6 @@ ide_workspace_actions_command (GSimpleAction *action,
 
 static const GActionEntry actions[] = {
   { "show-menu", ide_workspace_actions_show_menu },
-  { "surface", ide_workspace_actions_surface, "s" },
   { "close", ide_workspace_actions_close },
   { "command", ide_workspace_actions_command, "s" },
 };
diff --git a/src/libide/gui/ide-workspace-addin.c b/src/libide/gui/ide-workspace-addin.c
index 3b43dffc4..301777797 100644
--- a/src/libide/gui/ide-workspace-addin.c
+++ b/src/libide/gui/ide-workspace-addin.c
@@ -37,8 +37,6 @@
  * addin will only be loaded in the primary workspace. You may specify
  * multiple workspace kinds such as `primary` or `secondary` separated
  * by a comma such as `primary,secondary;`.
- *
- * Since: 3.32
  */
 
 G_DEFINE_INTERFACE (IdeWorkspaceAddin, ide_workspace_addin, G_TYPE_OBJECT)
@@ -56,8 +54,6 @@ ide_workspace_addin_default_init (IdeWorkspaceAddinInterface *iface)
  *
  * This is a good place to modify the workspace from your addin.
  * Remember to unmodify the workspace in ide_workspace_addin_unload().
- *
- * Since: 3.32
  */
 void
 ide_workspace_addin_load (IdeWorkspaceAddin *self,
@@ -79,8 +75,6 @@ ide_workspace_addin_load (IdeWorkspaceAddin *self,
  *
  * This is a good place to unmodify the workspace from anything you
  * did in ide_workspace_addin_load().
- *
- * Since: 3.32
  */
 void
 ide_workspace_addin_unload (IdeWorkspaceAddin *self,
@@ -93,48 +87,3 @@ ide_workspace_addin_unload (IdeWorkspaceAddin *self,
   if (IDE_WORKSPACE_ADDIN_GET_IFACE (self)->unload)
     IDE_WORKSPACE_ADDIN_GET_IFACE (self)->unload (self, workspace);
 }
-
-/**
- * ide_workspace_addin_surface_set:
- * @self: an #IdeWorkspaceAddin
- * @surface: (nullable): an #IdeSurface or %NULL
- *
- * This function is called to notify the addin of the current surface.
- * It may be set to %NULL before unloading the addin to allow addins
- * to do surface change state handling and cleanup in one function.
- *
- * Since: 3.32
- */
-void
-ide_workspace_addin_surface_set (IdeWorkspaceAddin *self,
-                                 IdeSurface        *surface)
-{
-  g_return_if_fail (IDE_IS_MAIN_THREAD ());
-  g_return_if_fail (IDE_IS_WORKSPACE_ADDIN (self));
-  g_return_if_fail (!surface || IDE_IS_SURFACE (surface));
-
-  if (IDE_WORKSPACE_ADDIN_GET_IFACE (self)->surface_set)
-    IDE_WORKSPACE_ADDIN_GET_IFACE (self)->surface_set (self, surface);
-}
-
-/**
- * ide_workspace_addin_can_close:
- * @self: an #IdeWorkspaceAddin
- *
- * This method is called to determine if the workspace can close. If the addin
- * needs to prevent the workspace closing, then return %FALSE; otherwise %TRUE.
- *
- * Returns: %TRUE if the workspace can close; otherwise %FALSE.
- *
- * Since: 3.34
- */
-gboolean
-ide_workspace_addin_can_close (IdeWorkspaceAddin *self)
-{
-  g_return_val_if_fail (IDE_IS_WORKSPACE_ADDIN (self), TRUE);
-
-  if (IDE_WORKSPACE_ADDIN_GET_IFACE (self)->can_close)
-    return IDE_WORKSPACE_ADDIN_GET_IFACE (self)->can_close (self);
-
-  return TRUE;
-}
diff --git a/src/libide/gui/ide-workspace-addin.h b/src/libide/gui/ide-workspace-addin.h
index 1bf8599bc..a38964a2b 100644
--- a/src/libide/gui/ide-workspace-addin.h
+++ b/src/libide/gui/ide-workspace-addin.h
@@ -26,7 +26,7 @@ G_BEGIN_DECLS
 
 #define IDE_TYPE_WORKSPACE_ADDIN (ide_workspace_addin_get_type())
 
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
 G_DECLARE_INTERFACE (IdeWorkspaceAddin, ide_workspace_addin, IDE, WORKSPACE_ADDIN, GObject)
 
 struct _IdeWorkspaceAddinInterface
@@ -37,23 +37,15 @@ struct _IdeWorkspaceAddinInterface
                            IdeWorkspace      *workspace);
   void     (*unload)      (IdeWorkspaceAddin *self,
                            IdeWorkspace      *workspace);
-  void     (*surface_set) (IdeWorkspaceAddin *self,
-                           IdeSurface        *surface);
-  gboolean (*can_close)   (IdeWorkspaceAddin *self);
 };
 
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
 void               ide_workspace_addin_load                (IdeWorkspaceAddin *self,
                                                             IdeWorkspace      *workspace);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
 void               ide_workspace_addin_unload              (IdeWorkspaceAddin *self,
                                                             IdeWorkspace      *workspace);
-IDE_AVAILABLE_IN_3_32
-void               ide_workspace_addin_surface_set         (IdeWorkspaceAddin *self,
-                                                            IdeSurface        *surface);
-IDE_AVAILABLE_IN_3_34
-gboolean           ide_workspace_addin_can_close           (IdeWorkspaceAddin *self);
-IDE_AVAILABLE_IN_3_40
+IDE_AVAILABLE_IN_ALL
 IdeWorkspaceAddin *ide_workspace_addin_find_by_module_name (IdeWorkspace      *workspace,
                                                             const gchar       *module_name);
 
diff --git a/src/libide/gui/ide-workspace.c b/src/libide/gui/ide-workspace.c
index 72282270b..bb2269818 100644
--- a/src/libide/gui/ide-workspace.c
+++ b/src/libide/gui/ide-workspace.c
@@ -26,8 +26,9 @@
 
 #include "ide-gui-global.h"
 #include "ide-gui-private.h"
-#include "ide-workspace.h"
 #include "ide-workspace-addin.h"
+#include "ide-workspace-private.h"
+#include "ide-workbench-private.h"
 
 #define MUX_ACTIONS_KEY "IDE_WORKSPACE_MUX_ACTIONS"
 
@@ -55,23 +56,6 @@ typedef struct
    */
   IdeExtensionSetAdapter *addins;
 
-  /* We use an overlay as our top-most child so that plugins can potentially
-   * render any widget a layer above the UI.
-   */
-  GtkOverlay *overlay;
-
-  /* All workspaces are comprised of a series of "surfaces". However there may
-   * only ever be a single surface in a workspace (such as the editor workspace
-   * which is dedicated for editing).
-   */
-  GtkStack *surfaces;
-
-  /* The event box ensures that we can have events that will be used by the
-   * fullscreen overlay so that it gets delivery of crossing events.
-   */
-  GtkEventBox *event_box;
-  GtkBox *vbox;
-
   /* A MRU that is updated as pages are focused. It allows us to move through
    * the pages in the order they've been most-recently focused.
    */
@@ -82,15 +66,10 @@ typedef struct
 
 typedef struct
 {
-  GtkCallback callback;
-  gpointer    user_data;
+  IdePageCallback callback;
+  gpointer        user_data;
 } ForeachPage;
 
-enum {
-  SURFACE_SET,
-  N_SIGNALS
-};
-
 enum {
   PROP_0,
   PROP_CONTEXT,
@@ -98,15 +77,9 @@ enum {
   N_PROPS
 };
 
-static void buildable_iface_init (GtkBuildableIface *iface);
+G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (IdeWorkspace, ide_workspace, ADW_TYPE_APPLICATION_WINDOW)
 
-G_DEFINE_ABSTRACT_TYPE_WITH_CODE (IdeWorkspace, ide_workspace, ADW_TYPE_APPLICATION_WINDOW,
-                                  G_ADD_PRIVATE (IdeWorkspace)
-                                  G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, buildable_iface_init))
-
-static GtkBuildableIface *parent_builder;
 static GParamSpec *properties [N_PROPS];
-static guint signals [N_SIGNALS];
 
 static void
 ide_workspace_addin_added_cb (IdeExtensionSetAdapter *set,
@@ -145,7 +118,6 @@ ide_workspace_addin_removed_cb (IdeExtensionSetAdapter *set,
   g_debug ("Unloading workspace addin from module %s",
            peas_plugin_info_get_module_name (plugin_info));
 
-  ide_workspace_addin_surface_set (addin, NULL);
   ide_workspace_addin_unload (addin, self);
 }
 
@@ -181,182 +153,53 @@ ide_workspace_real_context_set (IdeWorkspace *self,
 }
 
 static void
-ide_workspace_addin_surface_set_cb (IdeExtensionSetAdapter *set,
-                                    PeasPluginInfo         *plugin_info,
-                                    PeasExtension          *exten,
-                                    gpointer                user_data)
-{
-  IdeWorkspaceAddin *addin = (IdeWorkspaceAddin *)exten;
-  IdeSurface *surface = user_data;
-
-  g_assert (IDE_IS_EXTENSION_SET_ADAPTER (set));
-  g_assert (plugin_info != NULL);
-  g_assert (IDE_IS_WORKSPACE_ADDIN (addin));
-  g_assert (!surface || IDE_IS_SURFACE (surface));
-
-  ide_workspace_addin_surface_set (addin, surface);
-}
-
-static void
-ide_workspace_real_surface_set (IdeWorkspace *self,
-                                IdeSurface   *surface)
-{
-  IdeWorkspacePrivate *priv = ide_workspace_get_instance_private (self);
-
-  g_assert (IDE_IS_MAIN_THREAD ());
-  g_assert (IDE_IS_WORKSPACE (self));
-  g_assert (!surface || IDE_IS_SURFACE (surface));
-
-  if (priv->addins != NULL)
-    ide_extension_set_adapter_foreach (priv->addins,
-                                       ide_workspace_addin_surface_set_cb,
-                                       surface);
-}
-
-/**
- * ide_workspace_foreach_surface:
- * @self: a #IdeWorkspace
- * @callback: (scope call): a #GtkCallback to execute for every surface
- * @user_data: user data for @callback
- *
- * Calls callback for every #IdeSurface based #GtkWidget that is registered
- * in the workspace.
- *
- * Since: 3.32
- */
-void
-ide_workspace_foreach_surface (IdeWorkspace *self,
-                               GtkCallback   callback,
-                               gpointer      user_data)
-{
-  IdeWorkspacePrivate *priv = ide_workspace_get_instance_private (self);
-
-  g_assert (IDE_IS_WORKSPACE (self));
-  g_assert (callback != NULL);
-
-  gtk_container_foreach (GTK_CONTAINER (priv->surfaces), callback, user_data);
-}
-
-static void
-ide_workspace_agree_to_shutdown_cb (GtkWidget *widget,
-                                    gpointer   user_data)
-{
-  gboolean *blocked = user_data;
-
-  g_assert (IDE_IS_MAIN_THREAD ());
-  g_assert (IDE_IS_SURFACE (widget));
-  g_assert (blocked != NULL);
-
-  *blocked |= !ide_surface_agree_to_shutdown (IDE_SURFACE (widget));
-}
-
-static void
-ide_workspace_addin_can_close_cb (IdeExtensionSetAdapter *adapter,
-                                  PeasPluginInfo         *plugin_info,
-                                  PeasExtension          *exten,
-                                  gpointer                user_data)
-{
-  IdeWorkspaceAddin *addin = (IdeWorkspaceAddin *)exten;
-  gboolean *blocked = user_data;
-
-  g_assert (IDE_IS_MAIN_THREAD ());
-  g_assert (IDE_IS_WORKSPACE_ADDIN (addin));
-  g_assert (blocked != NULL);
-
-  *blocked |= !ide_workspace_addin_can_close (addin);
-}
-
-static gboolean
-ide_workspace_agree_to_shutdown (IdeWorkspace *self)
-{
-  IdeWorkspacePrivate *priv = ide_workspace_get_instance_private (self);
-  gboolean blocked = FALSE;
-
-  g_assert (IDE_IS_MAIN_THREAD ());
-  g_assert (IDE_IS_WORKSPACE (self));
-
-  ide_workspace_foreach_surface (self, ide_workspace_agree_to_shutdown_cb, &blocked);
-
-  if (!blocked)
-    ide_extension_set_adapter_foreach (priv->addins,
-                                       ide_workspace_addin_can_close_cb,
-                                       &blocked);
-
-  return !blocked;
-}
-
-static gboolean
-ide_workspace_delete_event (GtkWidget   *widget,
-                            GdkEventAny *any)
+ide_workspace_close_request_cb (GObject      *object,
+                                GAsyncResult *result,
+                                gpointer      user_data)
 {
-  IdeWorkspace *self = (IdeWorkspace *)widget;
+  IdeWorkspace *self = (IdeWorkspace *)object;
   IdeWorkspacePrivate *priv = ide_workspace_get_instance_private (self);
-  IdeWorkbench *workbench;
+  g_autoptr(GError) error = NULL;
 
   g_assert (IDE_IS_WORKSPACE (self));
-  g_assert (any != NULL);
+  g_assert (G_IS_ASYNC_RESULT (result));
 
-  /* TODO:
-   *
-   * If there are any active transfers, we want to ask the user if they
-   * are sure they want to exit and risk losing them. We can allow them
-   * to be completed in the background.
-   *
-   * Note that we only want to do this on the final workspace window.
-   */
-
-  if (!ide_workspace_agree_to_shutdown (self))
-    return GDK_EVENT_STOP;
-
-  g_cancellable_cancel (priv->cancellable);
+  if (IDE_WORKSPACE_GET_CLASS (self)->agree_to_close_finish (self, result, &error))
+    {
+      IdeWorkbench *workbench = IDE_WORKBENCH (gtk_window_get_group (GTK_WINDOW (self)));
 
-  workbench = ide_widget_get_workbench (widget);
+      if (ide_workbench_has_project (workbench) &&
+          _ide_workbench_is_last_workspace (workbench, self))
+        {
+          gtk_widget_hide (GTK_WIDGET (self));
+          ide_workbench_unload_async (workbench, NULL, NULL, NULL);
+          return;
+        }
 
-  if (ide_workbench_has_project (workbench) &&
-      _ide_workbench_is_last_workspace (workbench, self))
-    {
-      gtk_widget_hide (GTK_WIDGET (self));
-      ide_workbench_unload_async (workbench, NULL, NULL, NULL);
-      return GDK_EVENT_STOP;
+      g_cancellable_cancel (priv->cancellable);
+      gtk_window_destroy (GTK_WINDOW (self));
     }
-
-  return GDK_EVENT_PROPAGATE;
 }
 
-static void
-ide_workspace_notify_surface_cb (IdeWorkspace *self,
-                                 GParamSpec   *pspec,
-                                 GtkStack     *surfaces)
+static gboolean
+ide_workspace_close_request (GtkWindow *window)
 {
-  GtkWidget *visible_child;
-  IdeHeaderBar *header_bar;
+  IdeWorkspace *self = (IdeWorkspace *)window;
 
   g_assert (IDE_IS_WORKSPACE (self));
-  g_assert (GTK_IS_STACK (surfaces));
-
-  visible_child = gtk_stack_get_visible_child (surfaces);
-  if (!IDE_IS_SURFACE (visible_child))
-    visible_child = NULL;
-
-  if (visible_child != NULL)
-    gtk_widget_grab_focus (visible_child);
 
-  if ((header_bar = ide_workspace_get_header_bar (self)))
-    {
-      if (visible_child != NULL)
-        dzl_gtk_widget_mux_action_groups (GTK_WIDGET (header_bar), visible_child, MUX_ACTIONS_KEY);
-      else
-        dzl_gtk_widget_mux_action_groups (GTK_WIDGET (header_bar), NULL, MUX_ACTIONS_KEY);
-    }
+  IDE_WORKSPACE_GET_CLASS (self)->agree_to_close_async (self,
+                                                        NULL,
+                                                        ide_workspace_close_request_cb,
+                                                        NULL);
 
-  g_signal_emit (self, signals [SURFACE_SET], 0, visible_child);
-  g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_VISIBLE_SURFACE]);
+  return TRUE;
 }
 
 static void
-ide_workspace_destroy (GtkWidget *widget)
+ide_workspace_dispose (GObject *object)
 {
-  IdeWorkspace *self = (IdeWorkspace *)widget;
+  IdeWorkspace *self = (IdeWorkspace *)object;
   IdeWorkspacePrivate *priv = ide_workspace_get_instance_private (self);
   GtkWindowGroup *group;
 
@@ -368,7 +211,7 @@ ide_workspace_destroy (GtkWidget *widget)
   if (IDE_IS_WORKBENCH (group))
     ide_workbench_remove_workspace (IDE_WORKBENCH (group), self);
 
-  GTK_WIDGET_CLASS (ide_workspace_parent_class)->destroy (widget);
+  G_OBJECT_CLASS (ide_workspace_parent_class)->dispose (object);
 }
 
 /**
@@ -377,8 +220,6 @@ ide_workspace_destroy (GtkWidget *widget)
  *
  * Sets the shorthand name for the kind of workspace. This is used to limit
  * what #IdeWorkspaceAddin may load within the workspace.
- *
- * Since: 3.32
  */
 void
 ide_workspace_class_set_kind (IdeWorkspaceClass *klass,
@@ -389,97 +230,31 @@ ide_workspace_class_set_kind (IdeWorkspaceClass *klass,
   klass->kind = g_intern_string (kind);
 }
 
-
-static void
-ide_workspace_foreach_page_cb (GtkWidget *widget,
-                               gpointer   user_data)
-{
-  ForeachPage *state = user_data;
-
-  if (IDE_IS_SURFACE (widget))
-    ide_surface_foreach_page (IDE_SURFACE (widget), state->callback, state->user_data);
-}
-
 static void
-ide_workspace_real_foreach_page (IdeWorkspace *self,
-                                 GtkCallback   callback,
-                                 gpointer      user_data)
+ide_workspace_real_foreach_page (IdeWorkspace    *self,
+                                 IdePageCallback  callback,
+                                 gpointer         user_data)
 {
-  IdeWorkspacePrivate *priv = ide_workspace_get_instance_private (self);
-  ForeachPage state = { callback, user_data };
-
   g_assert (IDE_IS_WORKSPACE (self));
   g_assert (callback != NULL);
-
-  gtk_container_foreach (GTK_CONTAINER (priv->surfaces),
-                         ide_workspace_foreach_page_cb,
-                         &state);
-}
-
-#if 0
-static void
-ide_workspace_set_surface_fullscreen_cb (GtkWidget *widget,
-                                         gpointer   user_data)
-{
-  g_assert (GTK_IS_WIDGET (widget));
-
-  if (IDE_IS_SURFACE (widget))
-    _ide_surface_set_fullscreen (IDE_SURFACE (widget), !!user_data);
-}
-
-static void
-ide_workspace_real_set_fullscreen (DzlApplicationWindow *window,
-                                   gboolean              fullscreen)
-{
-  IdeWorkspace *self = (IdeWorkspace *)window;
-  IdeWorkspacePrivate *priv = ide_workspace_get_instance_private (self);
-  GtkWidget *titlebar;
-
-  g_assert (IDE_IS_WORKSPACE (self));
-
-  DZL_APPLICATION_WINDOW_CLASS (ide_workspace_parent_class)->set_fullscreen (window, fullscreen);
-
-  titlebar = dzl_application_window_get_titlebar (window);
-  gtk_header_bar_set_show_close_button (GTK_HEADER_BAR (titlebar), !fullscreen);
-
-  gtk_container_foreach (GTK_CONTAINER (priv->surfaces),
-                         ide_workspace_set_surface_fullscreen_cb,
-                         GUINT_TO_POINTER (fullscreen));
 }
-#endif
 
 static void
-ide_workspace_grab_focus (GtkWidget *widget)
+ide_workspace_agree_to_close_async (IdeWorkspace        *self,
+                                    GCancellable        *cancellable,
+                                    GAsyncReadyCallback  callback,
+                                    gpointer             user_data)
 {
-  IdeWorkspace *self = (IdeWorkspace *)widget;
-  IdeSurface *surface;
-
-  g_assert (IDE_IS_WORKSPACE (self));
-
-  if ((surface = ide_workspace_get_visible_surface (self)))
-    gtk_widget_grab_focus (GTK_WIDGET (surface));
+  g_autoptr(GTask) task = g_task_new (self, cancellable, callback, user_data);
+  g_task_return_boolean (task, TRUE);
 }
 
 static gboolean
-ide_workspace_key_press_event (GtkWidget   *widget,
-                               GdkEventKey *event)
+ide_workspace_agree_to_close_finish (IdeWorkspace *self,
+                                     GAsyncResult *result,
+                                     GError **error)
 {
-  IdeWorkspace *self = (IdeWorkspace *)widget;
-  IdeWorkspacePrivate *priv = ide_workspace_get_instance_private (self);
-  gboolean ret;
-
-  g_assert (IDE_IS_WORKSPACE (self));
-  g_assert (event != NULL);
-
-  /* Be re-entrant safe from the shortcut manager */
-  if (priv->in_key_press)
-    return GTK_WIDGET_CLASS (ide_workspace_parent_class)->key_press_event (widget, event);
-
-  priv->in_key_press = TRUE;
-  ret = dzl_shortcut_manager_handle_event (NULL, event, widget);
-  priv->in_key_press = FALSE;
-
-  return ret;
+  return g_task_propagate_boolean (G_TASK (result), error);
 }
 
 static void
@@ -508,10 +283,6 @@ ide_workspace_get_property (GObject    *object,
       g_value_set_object (value, ide_workspace_get_context (self));
       break;
 
-    case PROP_VISIBLE_SURFACE:
-      g_value_set_object (value, ide_workspace_get_visible_surface (self));
-      break;
-
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     }
@@ -523,14 +294,8 @@ ide_workspace_set_property (GObject      *object,
                             const GValue *value,
                             GParamSpec   *pspec)
 {
-  IdeWorkspace *self = IDE_WORKSPACE (object);
-
   switch (prop_id)
     {
-    case PROP_VISIBLE_SURFACE:
-      ide_workspace_set_visible_surface (self, g_value_get_object (value));
-      break;
-
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     }
@@ -540,31 +305,25 @@ static void
 ide_workspace_class_init (IdeWorkspaceClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
-  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-  //DzlApplicationWindowClass *window_class = DZL_APPLICATION_WINDOW_CLASS (klass);
+  GtkWindowClass *window_class = GTK_WINDOW_CLASS (klass);
 
+  object_class->dispose = ide_workspace_dispose;
   object_class->finalize = ide_workspace_finalize;
   object_class->get_property = ide_workspace_get_property;
   object_class->set_property = ide_workspace_set_property;
 
-  widget_class->destroy = ide_workspace_destroy;
-  widget_class->delete_event = ide_workspace_delete_event;
-  widget_class->grab_focus = ide_workspace_grab_focus;
-  widget_class->key_press_event = ide_workspace_key_press_event;
-
-  //window_class->set_fullscreen = ide_workspace_real_set_fullscreen;
+  window_class->close_request = ide_workspace_close_request;
 
   klass->foreach_page = ide_workspace_real_foreach_page;
   klass->context_set = ide_workspace_real_context_set;
-  klass->surface_set = ide_workspace_real_surface_set;
+  klass->agree_to_close_async = ide_workspace_agree_to_close_async;
+  klass->agree_to_close_finish = ide_workspace_agree_to_close_finish;
 
   /**
    * IdeWorkspace:context:
    *
    * The "context" property is the #IdeContext for the workspace. This is set
    * when the workspace joins a workbench.
-   *
-   * Since: 3.32
    */
   properties [PROP_CONTEXT] =
     g_param_spec_object ("context",
@@ -573,51 +332,7 @@ ide_workspace_class_init (IdeWorkspaceClass *klass)
                          IDE_TYPE_CONTEXT,
                          (G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
 
-  /**
-   * IdeWorkspace:visible-surface:
-   *
-   * The "visible-surface" property contains the currently foremost surface
-   * in the workspaces stack of surfaces. Usually, this is the editor surface,
-   * but may be other surfaces such as build preferences, profiler, etc.
-   *
-   * Since: 3.32
-   */
-  properties [PROP_VISIBLE_SURFACE] =
-    g_param_spec_object ("visible-surface",
-                         "Visible Surface",
-                         "The currently visible surface",
-                         IDE_TYPE_SURFACE,
-                         (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
-
   g_object_class_install_properties (object_class, N_PROPS, properties);
-
-  /**
-   * IdeWorkspace::surface-set:
-   * @self: an #IdeWorkspace
-   * @surface: (nullable): an #IdeSurface
-   *
-   * The "surface-set" signal is emitted when the current surface changes
-   * within the workspace.
-   *
-   * Since: 3.32
-   */
-  signals [SURFACE_SET] =
-    g_signal_new ("surface-set",
-                  G_TYPE_FROM_CLASS (klass),
-                  G_SIGNAL_RUN_LAST,
-                  G_STRUCT_OFFSET (IdeWorkspaceClass, surface_set),
-                  NULL, NULL,
-                  g_cclosure_marshal_VOID__OBJECT,
-                  G_TYPE_NONE, 1, IDE_TYPE_SURFACE);
-  g_signal_set_va_marshaller (signals [SURFACE_SET],
-                              G_TYPE_FROM_CLASS (klass),
-                              g_cclosure_marshal_VOID__OBJECTv);
-
-  gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/libide-gui/ui/ide-workspace.ui");
-  gtk_widget_class_bind_template_child_private (widget_class, IdeWorkspace, event_box);
-  gtk_widget_class_bind_template_child_private (widget_class, IdeWorkspace, overlay);
-  gtk_widget_class_bind_template_child_private (widget_class, IdeWorkspace, surfaces);
-  gtk_widget_class_bind_template_child_private (widget_class, IdeWorkspace, vbox);
 }
 
 static void
@@ -630,22 +345,10 @@ ide_workspace_init (IdeWorkspace *self)
 
   gtk_widget_init_template (GTK_WIDGET (self));
 
-  g_signal_connect_object (priv->surfaces,
-                           "notify::visible-child",
-                           G_CALLBACK (ide_workspace_notify_surface_cb),
-                           self,
-                           G_CONNECT_SWAPPED);
-
   /* Add org-gnome-Builder style CSS identifier */
   app_id = g_strdelimit (g_strdup (ide_get_application_id ()), ".", '-');
-  dzl_gtk_widget_add_style_class (GTK_WIDGET (self), app_id);
-  dzl_gtk_widget_add_style_class (GTK_WIDGET (self), "workspace");
-
-  /* Add events for motion controller of fullscreen titlebar */
-  gtk_widget_add_events (GTK_WIDGET (priv->event_box),
-                         (GDK_POINTER_MOTION_MASK |
-                          GDK_ENTER_NOTIFY_MASK |
-                          GDK_LEAVE_NOTIFY_MASK));
+  gtk_widget_add_css_class (GTK_WIDGET (self), app_id);
+  gtk_widget_add_css_class (GTK_WIDGET (self), "workspace");
 
   /* Initialize GActions for workspace */
   _ide_workspace_init_actions (self);
@@ -668,8 +371,6 @@ _ide_workspace_get_mru_link (IdeWorkspace *self)
  * workspace joins an #IdeWorkbench.
  *
  * Returns: (transfer none) (nullable): an #IdeContext or %NULL
- *
- * Since: 3.32
  */
 IdeContext *
 ide_workspace_get_context (IdeWorkspace *self)
@@ -707,8 +408,6 @@ _ide_workspace_set_context (IdeWorkspace *self,
  * to be cancelled if a window is closed.
  *
  * Returns: (transfer none): a #GCancellable
- *
- * Since: 3.32
  */
 GCancellable *
 ide_workspace_get_cancellable (IdeWorkspace *self)
@@ -731,13 +430,11 @@ ide_workspace_get_cancellable (IdeWorkspace *self)
  * @user_data: closure data for @callback
  *
  * Calls @callback for each #IdePage found within the workspace.
- *
- * Since: 3.32
  */
 void
-ide_workspace_foreach_page (IdeWorkspace *self,
-                            GtkCallback   callback,
-                            gpointer      user_data)
+ide_workspace_foreach_page (IdeWorkspace    *self,
+                            IdePageCallback  callback,
+                            gpointer         user_data)
 {
   g_return_if_fail (IDE_IS_WORKSPACE (self));
   g_return_if_fail (callback != NULL);
@@ -754,230 +451,22 @@ ide_workspace_foreach_page (IdeWorkspace *self,
  * Also works around Gtk giving back a GtkStack for the header bar.
  *
  * Returns: (nullable) (transfer none): an #IdeHeaderBar or %NULL
- *
- * Since: 3.32
  */
 IdeHeaderBar *
 ide_workspace_get_header_bar (IdeWorkspace *self)
 {
-  IdeWorkspacePrivate *priv = ide_workspace_get_instance_private (self);
-  IdeHeaderBar *ret = NULL;
-  GList *children;
+  GtkWidget *ret = NULL;
 
   g_return_val_if_fail (IDE_IS_WORKSPACE (self), NULL);
 
-  children = gtk_container_get_children (GTK_CONTAINER (priv->vbox));
-
-  for (const GList *iter = children; iter; iter = iter->next)
-    {
-      GtkWidget *widget = iter->data;
-
-      if (GTK_IS_STACK (widget))
-        widget = gtk_stack_get_visible_child (GTK_STACK (widget));
-
-      if (IDE_IS_HEADER_BAR (widget))
-        {
-          ret = IDE_HEADER_BAR (widget);
-          break;
-        }
-    }
-
-  g_list_free (children);
+  ret = gtk_window_get_titlebar (GTK_WINDOW (self));
 
-  return ret;
-}
-
-/**
- * ide_workspace_add_surface:
- * @self: a #IdeWorkspace
- *
- * Adds a new #IdeSurface to the workspace.
- *
- * Since: 3.32
- */
-void
-ide_workspace_add_surface (IdeWorkspace *self,
-                           IdeSurface   *surface)
-{
-  IdeWorkspacePrivate *priv = ide_workspace_get_instance_private (self);
-  g_autofree gchar *title = NULL;
-
-  g_return_if_fail (IDE_IS_WORKSPACE (self));
-  g_return_if_fail (IDE_IS_SURFACE (surface));
-
-  if (DZL_IS_DOCK_ITEM (surface))
-    title = dzl_dock_item_get_title (DZL_DOCK_ITEM (surface));
-
-  gtk_container_add_with_properties (GTK_CONTAINER (priv->surfaces), GTK_WIDGET (surface),
-                                     "name", gtk_widget_get_name (GTK_WIDGET (surface)),
-                                     "title", title,
-                                     NULL);
-}
-
-/**
- * ide_workspace_set_visible_surface_name:
- * @self: a #IdeWorkspace
- * @visible_surface_name: the name of the #IdeSurface
- *
- * Sets the visible surface based on the name of the surface.  The name of the
- * surface comes from gtk_widget_get_name(), which should be set when creating
- * the surface using gtk_widget_set_name().
- *
- * Since: 3.32
- */
-void
-ide_workspace_set_visible_surface_name (IdeWorkspace *self,
-                                        const gchar  *visible_surface_name)
-{
-  IdeWorkspacePrivate *priv = ide_workspace_get_instance_private (self);
-
-  g_return_if_fail (IDE_IS_WORKSPACE (self));
-  g_return_if_fail (visible_surface_name != NULL);
-
-  gtk_stack_set_visible_child_name (priv->surfaces, visible_surface_name);
-}
-
-/**
- * ide_workspace_get_visible_surface:
- * @self: a #IdeWorkspace
- *
- * Gets the currently visible #IdeSurface, or %NULL
- *
- * Returns: (transfer none) (nullable): an #IdeSurface or %NULL
- *
- * Since: 3.32
- */
-IdeSurface *
-ide_workspace_get_visible_surface (IdeWorkspace *self)
-{
-  IdeWorkspacePrivate *priv = ide_workspace_get_instance_private (self);
-  GtkWidget *child;
-
-  g_return_val_if_fail (IDE_IS_WORKSPACE (self), NULL);
-
-  child = gtk_stack_get_visible_child (priv->surfaces);
-  if (!IDE_IS_SURFACE (child))
-    child = NULL;
-
-  return IDE_SURFACE (child);
-}
-
-/**
- * ide_workspace_set_visible_surface:
- * @self: a #IdeWorkspace
- * @surface: an #IdeSurface
- *
- * Sets the #IdeWorkspace:visible-surface property which is the currently
- * visible #IdeSurface in the workspace.
- *
- * Since: 3.32
- */
-void
-ide_workspace_set_visible_surface (IdeWorkspace *self,
-                                   IdeSurface   *surface)
-{
-  IdeWorkspacePrivate *priv = ide_workspace_get_instance_private (self);
-
-  g_return_if_fail (IDE_IS_WORKSPACE (self));
-  g_return_if_fail (IDE_IS_SURFACE (surface));
-
-  gtk_stack_set_visible_child (priv->surfaces, GTK_WIDGET (surface));
-}
-
-/**
- * ide_workspace_get_surface_by_name:
- * @self: a #IdeWorkspace
- * @name: the name of the surface
- *
- * Locates an #IdeSurface that has been added to the workspace by the name
- * that was registered for the widget using gtk_widget_set_name().
- *
- * Returns: (transfer none) (nullable): an #IdeSurface or %NULL
- *
- * Since: 3.32
- */
-IdeSurface *
-ide_workspace_get_surface_by_name (IdeWorkspace *self,
-                                   const gchar  *name)
-{
-  IdeWorkspacePrivate *priv = ide_workspace_get_instance_private (self);
-  GtkWidget *child;
-
-  g_return_val_if_fail (IDE_IS_WORKSPACE (self), NULL);
-  g_return_val_if_fail (name != NULL, NULL);
-
-  child = gtk_stack_get_child_by_name (priv->surfaces, name);
-
-  return IDE_IS_SURFACE (child) ? IDE_SURFACE (child) : NULL;
-}
-
-static GObject *
-ide_workspace_get_internal_child (GtkBuildable *buildable,
-                                  GtkBuilder   *builder,
-                                  const gchar  *child_name)
-{
-  IdeWorkspace *self = (IdeWorkspace *)buildable;
-  IdeWorkspacePrivate *priv = ide_workspace_get_instance_private (self);
-
-  g_assert (GTK_IS_BUILDABLE (buildable));
-  g_assert (GTK_IS_BUILDER (builder));
-  g_assert (child_name != NULL);
-
-  if (ide_str_equal0 (child_name, "surfaces"))
-    return G_OBJECT (priv->surfaces);
+  if (IDE_IS_HEADER_BAR (ret))
+    return IDE_HEADER_BAR (ret);
 
   return NULL;
 }
 
-static void
-ide_workspace_add_child (GtkBuildable *buildable,
-                         GtkBuilder   *builder,
-                         GObject      *object,
-                         const char   *type)
-{
-  IdeWorkspace *self = (IdeWorkspace *)buildable;
-  IdeWorkspacePrivate *priv = ide_workspace_get_instance_private (self);
-
-  g_assert (IDE_IS_WORKSPACE (self));
-  g_assert (GTK_IS_BUILDER (builder));
-
-  if (g_strcmp0 (type, "titlebar") == 0 && GTK_IS_WIDGET (object))
-    gtk_box_pack_start (priv->vbox, GTK_WIDGET (object), FALSE, FALSE, 0);
-  else
-    parent_builder->add_child (buildable, builder, object, type);
-}
-
-static void
-buildable_iface_init (GtkBuildableIface *iface)
-{
-  parent_builder = g_type_interface_peek_parent (iface);
-
-  iface->get_internal_child = ide_workspace_get_internal_child;
-  iface->add_child = ide_workspace_add_child;
-}
-
-/**
- * ide_workspace_get_overlay:
- * @self: a #IdeWorkspace
- *
- * Gets a #GtkOverlay that contains all of the primary contents of the window
- * (everything except the headerbar). This can be used by plugins to draw
- * above the workspace contents.
- *
- * Returns: (transfer none): a #GtkOverlay
- *
- * Since: 3.32
- */
-GtkOverlay *
-ide_workspace_get_overlay (IdeWorkspace *self)
-{
-  IdeWorkspacePrivate *priv = ide_workspace_get_instance_private (self);
-
-  g_return_val_if_fail (IDE_IS_WORKSPACE (self), NULL);
-
-  return priv->overlay;
-}
-
 /**
  * ide_workspace_get_most_recent_page:
  * @self: a #IdeWorkspace
@@ -985,8 +474,6 @@ ide_workspace_get_overlay (IdeWorkspace *self)
  * Gets the most recently focused #IdePage.
  *
  * Returns: (transfer none) (nullable): an #IdePage or %NULL
- *
- * Since: 3.32
  */
 IdePage *
 ide_workspace_get_most_recent_page (IdeWorkspace *self)
@@ -1063,8 +550,6 @@ _ide_workspace_move_front_page_mru (IdeWorkspace *self,
  * Finds the addin (if any) matching the plugin's @module_name.
  *
  * Returns: (transfer none) (nullable): an #IdeWorkspaceAddin or %NULL
- *
- * Since: 3.40
  */
 IdeWorkspaceAddin *
 ide_workspace_addin_find_by_module_name (IdeWorkspace *workspace,
diff --git a/src/libide/gui/ide-workspace.h b/src/libide/gui/ide-workspace.h
index 22885c462..e6fd3ff6a 100644
--- a/src/libide/gui/ide-workspace.h
+++ b/src/libide/gui/ide-workspace.h
@@ -48,12 +48,19 @@ struct _IdeWorkspaceClass
 
   const gchar *kind;
 
-  void     (*context_set)          (IdeWorkspace    *self,
-                                    IdeContext      *context);
-  void     (*foreach_page)         (IdeWorkspace    *self,
-                                    IdePageCallback  callback,
-                                    gpointer         user_data);
-  IdePage *(*get_most_recent_page) (IdeWorkspace    *self);
+  void     (*context_set)           (IdeWorkspace         *self,
+                                     IdeContext           *context);
+  void     (*foreach_page)          (IdeWorkspace         *self,
+                                     IdePageCallback       callback,
+                                     gpointer              user_data);
+  IdePage *(*get_most_recent_page)  (IdeWorkspace         *self);
+  void     (*agree_to_close_async)  (IdeWorkspace         *self,
+                                     GCancellable         *cancellable,
+                                     GAsyncReadyCallback   callback,
+                                     gpointer              user_data);
+  gboolean (*agree_to_close_finish) (IdeWorkspace         *self,
+                                     GAsyncResult         *result,
+                                     GError              **error);
 
   /*< private >*/
   gpointer _reserved[8];
diff --git a/src/libide/gui/libide-gui.gresource.xml b/src/libide/gui/libide-gui.gresource.xml
index 79855ed83..bdd17e307 100644
--- a/src/libide/gui/libide-gui.gresource.xml
+++ b/src/libide/gui/libide-gui.gresource.xml
@@ -16,6 +16,5 @@
     <file preprocess="xml-stripblanks">ide-preferences-window.ui</file>
     <file preprocess="xml-stripblanks">ide-primary-workspace.ui</file>
     <file preprocess="xml-stripblanks">ide-run-button.ui</file>
-    <file preprocess="xml-stripblanks">ide-workspace.ui</file>
   </gresource>
 </gresources>


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