[gnome-builder/wip/gtk4-port] libide/gui: move internal shortcut loading into manager
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/gtk4-port] libide/gui: move internal shortcut loading into manager
- Date: Sat, 7 May 2022 05:27:23 +0000 (UTC)
commit 5226ce38375478af7d5b04a4b9ec8be384866e39
Author: Christian Hergert <chergert redhat com>
Date: Fri May 6 22:27:18 2022 -0700
libide/gui: move internal shortcut loading into manager
This will give us a bit easier time controlling how this stuff loads as
we begin to migrate plugins to using keybindings.json.
src/libide/gui/ide-shortcut-controller.c | 62 -------
...er-private.h => ide-shortcut-manager-private.h} | 16 +-
src/libide/gui/ide-shortcut-manager.c | 196 +++++++++++++++++++++
src/libide/gui/ide-shortcut-model-private.h | 41 -----
src/libide/gui/ide-shortcut-model.c | 187 --------------------
src/libide/gui/ide-workbench.c | 71 ++------
src/libide/gui/ide-workbench.h | 2 -
src/libide/gui/ide-workspace.c | 6 -
src/libide/gui/meson.build | 6 +-
9 files changed, 225 insertions(+), 362 deletions(-)
---
diff --git a/src/libide/gui/ide-shortcut-controller-private.h b/src/libide/gui/ide-shortcut-manager-private.h
similarity index 53%
rename from src/libide/gui/ide-shortcut-controller-private.h
rename to src/libide/gui/ide-shortcut-manager-private.h
index 9215dff23..7cb55f5e1 100644
--- a/src/libide/gui/ide-shortcut-controller-private.h
+++ b/src/libide/gui/ide-shortcut-manager-private.h
@@ -1,4 +1,4 @@
-/* ide-shortcut-controller-private.h
+/* ide-shortcut-manager-private.h
*
* Copyright 2022 Christian Hergert <chergert redhat com>
*
@@ -20,10 +20,20 @@
#pragma once
-#include <gtk/gtk.h>
+#include <libpeas/peas.h>
+
+#include <libide-core.h>
G_BEGIN_DECLS
-GtkEventController *ide_shortcut_controller_new_for_window (GtkWindow *window);
+#define IDE_TYPE_SHORTCUT_MANAGER (ide_shortcut_manager_get_type())
+
+G_DECLARE_FINAL_TYPE (IdeShortcutManager, ide_shortcut_manager, IDE, SHORTCUT_MANAGER, IdeObject)
+
+IdeShortcutManager *ide_shortcut_manager_from_context (IdeContext *context);
+void ide_shortcut_manager_add_plugin (IdeShortcutManager *self,
+ const PeasPluginInfo *plugin_info);
+void ide_shortcut_manager_remove_plugin (IdeShortcutManager *self,
+ const PeasPluginInfo *plugin_info);
G_END_DECLS
diff --git a/src/libide/gui/ide-shortcut-manager.c b/src/libide/gui/ide-shortcut-manager.c
new file mode 100644
index 000000000..44a3172f0
--- /dev/null
+++ b/src/libide/gui/ide-shortcut-manager.c
@@ -0,0 +1,196 @@
+/* ide-shortcut-manager.c
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * 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/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define G_LOG_DOMAIN "ide-shortcut-manager"
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+
+#include "ide-shortcut-bundle-private.h"
+#include "ide-shortcut-manager-private.h"
+
+struct _IdeShortcutManager
+{
+ IdeObject parent_instance;
+
+ /* Holds [plugin_models,internal_models] so that plugin models take
+ * priority over the others.
+ */
+ GListStore *toplevel;
+
+ /* Holds bundles loaded from plugins, more recently loaded plugins
+ * towards the head of the list.
+ *
+ * Plugins loaded dynamically could change ordering here, which might
+ * be something we want to address someday. In practice, it doesn't
+ * happen very often and people restart applications often.
+ */
+ GListStore *plugin_models;
+
+ /* A flattened list model we proxy through our interface */
+ GtkFlattenListModel *flatten;
+};
+
+static GType
+ide_shortcut_manager_get_item_type (GListModel *model)
+{
+ return GTK_TYPE_SHORTCUT;
+}
+
+static guint
+ide_shortcut_manager_get_n_items (GListModel *model)
+{
+ IdeShortcutManager *self = IDE_SHORTCUT_MANAGER (model);
+
+ if (self->flatten)
+ return g_list_model_get_n_items (G_LIST_MODEL (self->flatten));
+
+ return 0;
+}
+
+static gpointer
+ide_shortcut_manager_get_item (GListModel *model,
+ guint position)
+{
+ IdeShortcutManager *self = IDE_SHORTCUT_MANAGER (model);
+
+ if (self->flatten)
+ return g_list_model_get_item (G_LIST_MODEL (self->flatten), position);
+
+ return NULL;
+}
+
+static void
+list_model_iface_init (GListModelInterface *iface)
+{
+ iface->get_item_type = ide_shortcut_manager_get_item_type;
+ iface->get_n_items = ide_shortcut_manager_get_n_items;
+ iface->get_item = ide_shortcut_manager_get_item;
+}
+
+G_DEFINE_FINAL_TYPE_WITH_CODE (IdeShortcutManager, ide_shortcut_manager, IDE_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, list_model_iface_init))
+
+static GListModel *
+get_internal_models (void)
+{
+ static GListStore *internal_models;
+
+ if (internal_models == NULL)
+ {
+ static const char *names[] = {
+ "libide-gui",
+ };
+
+ internal_models = g_list_store_new (G_TYPE_LIST_MODEL);
+
+ for (guint i = 0; i < G_N_ELEMENTS (names); i++)
+ {
+ g_autoptr(IdeShortcutBundle) bundle = ide_shortcut_bundle_new ();
+ g_autofree char *uri = g_strdup_printf ("resource:///org/gnome/%s/gtk/keybindings.json", names[i]);
+ g_autoptr(GFile) file = g_file_new_for_uri (uri);
+ g_autoptr(GError) error = NULL;
+
+ if (!g_file_query_exists (file, NULL))
+ continue;
+
+ if (!ide_shortcut_bundle_parse (bundle, file, &error))
+ g_critical ("Failed to parse %s: %s", uri, error->message);
+ else
+ g_list_store_append (internal_models, bundle);
+ }
+ }
+
+ return G_LIST_MODEL (internal_models);
+}
+
+static void
+ide_shortcut_manager_items_changed_cb (IdeShortcutManager *self,
+ guint position,
+ guint removed,
+ guint added,
+ GListModel *model)
+{
+ g_list_model_items_changed (G_LIST_MODEL (self), position, removed, added);
+}
+
+static void
+ide_shortcut_manager_dispose (GObject *object)
+{
+ IdeShortcutManager *self = (IdeShortcutManager *)object;
+
+ g_clear_object (&self->toplevel);
+ g_clear_object (&self->plugin_models);
+ g_clear_object (&self->flatten);
+
+ G_OBJECT_CLASS (ide_shortcut_manager_parent_class)->dispose (object);
+}
+
+static void
+ide_shortcut_manager_class_init (IdeShortcutManagerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = ide_shortcut_manager_dispose;
+}
+
+static void
+ide_shortcut_manager_init (IdeShortcutManager *self)
+{
+ self->toplevel = g_list_store_new (G_TYPE_LIST_MODEL);
+ self->plugin_models = g_list_store_new (G_TYPE_LIST_MODEL);
+ g_list_store_append (self->toplevel, G_LIST_MODEL (self->plugin_models));
+ g_list_store_append (self->toplevel, get_internal_models ());
+
+ self->flatten = gtk_flatten_list_model_new (g_object_ref (G_LIST_MODEL (self->toplevel)));
+ g_signal_connect_object (self->flatten,
+ "items-changed",
+ G_CALLBACK (ide_shortcut_manager_items_changed_cb),
+ self,
+ G_CONNECT_SWAPPED);
+}
+
+/**
+ * ide_shortcut_manager_from_context:
+ * @context: an #IdeContext
+ *
+ * Gets the shortcut manager for the contenxt
+ *
+ * Returns: (transfer none): an #IdeShortcutManager
+ */
+IdeShortcutManager *
+ide_shortcut_manager_from_context (IdeContext *context)
+{
+ IdeShortcutManager *ret;
+
+ g_return_val_if_fail (IDE_IS_MAIN_THREAD (), NULL);
+ g_return_val_if_fail (IDE_IS_CONTEXT (context), NULL);
+
+ if (!(ret = ide_context_peek_child_typed (context, IDE_TYPE_SHORTCUT_MANAGER)))
+ {
+ g_autoptr(IdeObject) child = NULL;
+
+ child = ide_object_ensure_child_typed (IDE_OBJECT (context), IDE_TYPE_SHORTCUT_MANAGER);
+ ret = ide_context_peek_child_typed (context, IDE_TYPE_SHORTCUT_MANAGER);
+ }
+
+ return ret;
+}
diff --git a/src/libide/gui/ide-workbench.c b/src/libide/gui/ide-workbench.c
index d9c35de8b..d9f3f0618 100644
--- a/src/libide/gui/ide-workbench.c
+++ b/src/libide/gui/ide-workbench.c
@@ -40,7 +40,7 @@
#include "ide-gui-global.h"
#include "ide-preferences-window.h"
#include "ide-primary-workspace.h"
-#include "ide-shortcut-bundle-private.h"
+#include "ide-shortcut-manager-private.h"
#include "ide-workbench-addin.h"
#include "ide-workbench-private.h"
#include "ide-workspace-private.h"
@@ -75,8 +75,6 @@ struct _IdeWorkbench
IdeVcs *vcs;
IdeVcsMonitor *vcs_monitor;
IdeSearchEngine *search_engine;
- GListStore *shortcut_bundles;
- GtkFlattenListModel *shortcuts;
/* Various flags */
guint unloaded : 1;
@@ -183,26 +181,6 @@ ignore_error (GError *error)
g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
}
-static IdeShortcutBundle *
-get_internal_shortcuts (void)
-{
- static IdeShortcutBundle *internal_shortcuts;
-
- if (internal_shortcuts == NULL)
- {
- g_autoptr(GFile) file = NULL;
- g_autoptr(GError) error = NULL;
-
- file = g_file_new_for_uri ("resource:///org/gnome/libide-gui/gtk/keybindings.json");
- internal_shortcuts = ide_shortcut_bundle_new ();
-
- if (!ide_shortcut_bundle_parse (internal_shortcuts, file, &error))
- g_critical ("Failed to parse keybindings.json: %s", error->message);
- }
-
- return internal_shortcuts;
-}
-
/**
* ide_workbench_from_context:
* @context: an #IdeContext
@@ -419,8 +397,6 @@ ide_workbench_finalize (GObject *object)
if (self->context != NULL)
g_object_set_data (G_OBJECT (self->context), "WORKBENCH", NULL);
- g_clear_object (&self->shortcut_bundles);
- g_clear_object (&self->shortcuts);
g_clear_object (&self->build_system);
g_clear_object (&self->vcs);
g_clear_object (&self->search_engine);
@@ -524,11 +500,6 @@ static void
ide_workbench_init (IdeWorkbench *self)
{
ide_workbench_set_action_enabled (self, "configure", FALSE);
-
- /* Setup shortcuts */
- self->shortcut_bundles = g_list_store_new (IDE_TYPE_SHORTCUT_BUNDLE);
- g_list_store_append (self->shortcut_bundles, get_internal_shortcuts ());
- self->shortcuts = gtk_flatten_list_model_new (g_object_ref (G_LIST_MODEL (self->shortcut_bundles)));
}
static void
@@ -802,8 +773,9 @@ ide_workbench_add_workspace (IdeWorkbench *self,
g_autoptr(GPtrArray) addins = NULL;
g_autoptr(GtkFilterListModel) capture = NULL;
g_autoptr(GtkFilterListModel) bubble = NULL;
+ IdeShortcutManager *shortcuts;
+ GtkEventController *controller;
IdeCommandManager *command_manager;
- GtkEventController *shortcuts;
GList *mru_link;
g_return_if_fail (IDE_IS_MAIN_THREAD ());
@@ -847,20 +819,21 @@ ide_workbench_add_workspace (IdeWorkbench *self,
insert_action_groups_foreach_cb (workspace, self);
/* Setup capture shortcut controller for workspace */
- capture = gtk_filter_list_model_new (g_object_ref (G_LIST_MODEL (self->shortcuts)),
+ shortcuts = ide_shortcut_manager_from_context (self->context);
+ capture = gtk_filter_list_model_new (g_object_ref (G_LIST_MODEL (shortcuts)),
create_shortcut_filter (GTK_PHASE_CAPTURE));
- shortcuts = gtk_shortcut_controller_new_for_model (G_LIST_MODEL (g_steal_pointer (&capture)));
- gtk_event_controller_set_name (shortcuts, "ide-shortcuts-capture");
- gtk_event_controller_set_propagation_phase (shortcuts, GTK_PHASE_CAPTURE);
- gtk_widget_add_controller (GTK_WIDGET (workspace), shortcuts);
+ controller = gtk_shortcut_controller_new_for_model (G_LIST_MODEL (g_steal_pointer (&capture)));
+ gtk_event_controller_set_name (controller, "ide-shortcuts-capture");
+ gtk_event_controller_set_propagation_phase (controller, GTK_PHASE_CAPTURE);
+ gtk_widget_add_controller (GTK_WIDGET (workspace), controller);
/* Setup bubble shortcut controller for workspace */
- bubble = gtk_filter_list_model_new (g_object_ref (G_LIST_MODEL (self->shortcuts)),
+ bubble = gtk_filter_list_model_new (g_object_ref (G_LIST_MODEL (shortcuts)),
create_shortcut_filter (GTK_PHASE_BUBBLE));
- shortcuts = gtk_shortcut_controller_new_for_model (G_LIST_MODEL (g_steal_pointer (&bubble)));
- gtk_event_controller_set_name (shortcuts, "ide-shortcuts-bubble");
- gtk_event_controller_set_propagation_phase (shortcuts, GTK_PHASE_BUBBLE);
- gtk_widget_add_controller (GTK_WIDGET (workspace), shortcuts);
+ controller = gtk_shortcut_controller_new_for_model (G_LIST_MODEL (g_steal_pointer (&bubble)));
+ gtk_event_controller_set_name (controller, "ide-shortcuts-bubble");
+ gtk_event_controller_set_propagation_phase (controller, GTK_PHASE_BUBBLE);
+ gtk_widget_add_controller (GTK_WIDGET (workspace), controller);
/* Track toplevel focus changes to maintain a most-recently-used queue. */
g_signal_connect_object (workspace,
@@ -2736,19 +2709,3 @@ ide_workbench_action_configure (IdeWorkbench *self,
gtk_window_present (window);
}
}
-
-/**
- * ide_workbench_get_shortcuts:
- * @self: a #IdeWorkbench
- *
- * Gets a [iface@Gio.ListModel] of [class@Gtk.Shortcut]s.
- *
- * Returns: (transfer none): a #GListModel
- */
-GListModel *
-ide_workbench_get_shortcuts (IdeWorkbench *self)
-{
- g_return_val_if_fail (IDE_IS_WORKBENCH (self), NULL);
-
- return G_LIST_MODEL (self->shortcuts);
-}
diff --git a/src/libide/gui/ide-workbench.h b/src/libide/gui/ide-workbench.h
index 8d9c356c9..b534049b8 100644
--- a/src/libide/gui/ide-workbench.h
+++ b/src/libide/gui/ide-workbench.h
@@ -61,8 +61,6 @@ IdeWorkspace *ide_workbench_get_workspace_by_type (IdeWorkbench *self
IDE_AVAILABLE_IN_ALL
IdeSearchEngine *ide_workbench_get_search_engine (IdeWorkbench *self);
IDE_AVAILABLE_IN_ALL
-GListModel *ide_workbench_get_shortcuts (IdeWorkbench *self);
-IDE_AVAILABLE_IN_ALL
IdeWorkbench *ide_workbench_from_widget (GtkWidget *widget);
IDE_AVAILABLE_IN_ALL
void ide_workbench_add_workspace (IdeWorkbench *self,
diff --git a/src/libide/gui/ide-workspace.c b/src/libide/gui/ide-workspace.c
index 2c998a6c8..02bbdca83 100644
--- a/src/libide/gui/ide-workspace.c
+++ b/src/libide/gui/ide-workspace.c
@@ -27,7 +27,6 @@
#include "ide-gui-global.h"
#include "ide-search-popover-private.h"
-#include "ide-shortcut-controller-private.h"
#include "ide-workspace-addin.h"
#include "ide-workspace-private.h"
#include "ide-workbench-private.h"
@@ -565,7 +564,6 @@ static void
ide_workspace_init (IdeWorkspace *self)
{
IdeWorkspacePrivate *priv = ide_workspace_get_instance_private (self);
- GtkEventController *shortcuts;
g_autofree gchar *app_id = NULL;
#ifdef DEVELOPMENT_BUILD
@@ -600,10 +598,6 @@ ide_workspace_init (IdeWorkspace *self)
/* Initialize GActions for workspace */
_ide_workspace_init_actions (self);
-
- /* Initialize shortcuts for the window */
- shortcuts = ide_shortcut_controller_new_for_window (GTK_WINDOW (self));
- gtk_widget_add_controller (GTK_WIDGET (self), shortcuts);
}
GList *
diff --git a/src/libide/gui/meson.build b/src/libide/gui/meson.build
index 0c5909b3f..c516c66a3 100644
--- a/src/libide/gui/meson.build
+++ b/src/libide/gui/meson.build
@@ -56,8 +56,7 @@ libide_gui_private_headers = [
'ide-search-popover-private.h',
'ide-session-private.h',
'ide-shortcut-bundle-private.h',
- 'ide-shortcut-model-private.h',
- 'ide-shortcut-controller-private.h',
+ 'ide-shortcut-manager-private.h',
'ide-style-variant-preview-private.h',
]
@@ -76,8 +75,7 @@ libide_gui_private_sources = [
'ide-search-popover.c',
'ide-session.c',
'ide-shortcut-bundle.c',
- 'ide-shortcut-model.c',
- 'ide-shortcut-controller.c',
+ 'ide-shortcut-manager.c',
'ide-style-variant-preview.c',
'ide-workspace-actions.c',
]
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]