shortcutmanager: Use list models

This commit is contained in:
Matthias Clasen 2020-03-25 17:28:34 -04:00
parent 5763514ab8
commit c2e2e2993b
3 changed files with 93 additions and 23 deletions

View File

@ -20,6 +20,8 @@
#include "config.h" #include "config.h"
#include "gtkshortcutmanager.h" #include "gtkshortcutmanager.h"
#include "gtkshortcutmanagerprivate.h"
#include "gtkflattenlistmodel.h"
/** /**
* SECTION:gtkshortcutmanager * SECTION:gtkshortcutmanager
@ -29,36 +31,100 @@
* The GtkShortcutManager interface is used to implement * The GtkShortcutManager interface is used to implement
* shortcut scopes. * shortcut scopes.
*/ */
G_DEFINE_INTERFACE (GtkShortcutManager, gtk_shortcut_manager, G_TYPE_OBJECT) G_DEFINE_INTERFACE (GtkShortcutManager, gtk_shortcut_manager, G_TYPE_OBJECT)
static void void
complain_if_reached (gpointer should_be_gone) gtk_shortcut_manager_create_controllers (GtkWidget *widget)
{ {
g_critical ("Shortcut controllers failed to clean up."); GListStore *store;
GtkFlattenListModel *model;
GtkEventController *controller;
store = g_list_store_new (GTK_TYPE_SHORTCUT_CONTROLLER);
model = gtk_flatten_list_model_new (GTK_TYPE_SHORTCUT, G_LIST_MODEL (store));
g_object_unref (store);
g_object_set_data_full (G_OBJECT (widget), "gtk-shortcut-manager-bubble", model, g_object_unref);
controller = gtk_shortcut_controller_new_for_model (G_LIST_MODEL (model));
gtk_event_controller_set_name (controller, "gtk-shortcut-manager-bubble");
gtk_widget_add_controller (widget, controller);
store = g_list_store_new (GTK_TYPE_SHORTCUT_CONTROLLER);
model = gtk_flatten_list_model_new (GTK_TYPE_SHORTCUT, G_LIST_MODEL (store));
g_object_unref (store);
g_object_set_data_full (G_OBJECT (widget), "gtk-shortcut-manager-capture", model, g_object_unref);
controller = gtk_shortcut_controller_new_for_model (G_LIST_MODEL (model));
gtk_event_controller_set_name (controller, "gtk-shortcut-manager-capture");
gtk_event_controller_set_propagation_phase (controller, GTK_PHASE_CAPTURE);
gtk_widget_add_controller (widget, controller);
}
static GtkFlattenListModel *
gtk_shortcut_manager_get_model (GtkShortcutManager *self,
GtkPropagationPhase phase)
{
switch (phase)
{
case GTK_PHASE_CAPTURE:
return g_object_get_data (G_OBJECT (self), "gtk-shortcut-manager-capture");
case GTK_PHASE_BUBBLE:
return g_object_get_data (G_OBJECT (self), "gtk-shortcut-manager-bubble");
case GTK_PHASE_NONE:
case GTK_PHASE_TARGET:
return NULL;
default:
g_assert_not_reached ();
return NULL;
}
} }
static void static void
gtk_shortcut_manager_default_add_controller (GtkShortcutManager *self, gtk_shortcut_manager_default_add_controller (GtkShortcutManager *self,
GtkShortcutController *controller) GtkShortcutController *controller)
{ {
GSList *controllers; GtkFlattenListModel *model;
GtkPropagationPhase phase;
controllers = g_object_steal_data (G_OBJECT (self), "gtk-shortcut-controllers"); phase = gtk_event_controller_get_propagation_phase (GTK_EVENT_CONTROLLER (controller));
controllers = g_slist_prepend (controllers, g_object_ref (controller)); model = gtk_shortcut_manager_get_model (self, phase);
g_object_set_data_full (G_OBJECT (self), "gtk-shortcut-controllers", controllers, complain_if_reached); if (model)
{
GListModel *store = gtk_flatten_list_model_get_model (model);
g_list_store_append (G_LIST_STORE (store), controller);
}
} }
static void static void
gtk_shortcut_manager_default_remove_controller (GtkShortcutManager *self, gtk_shortcut_manager_default_remove_controller (GtkShortcutManager *self,
GtkShortcutController *controller) GtkShortcutController *controller)
{ {
GSList *controllers; GtkFlattenListModel *model;
GtkPropagationPhase phase;
controllers = g_object_steal_data (G_OBJECT (self), "gtk-shortcut-controllers"); phase = gtk_event_controller_get_propagation_phase (GTK_EVENT_CONTROLLER (controller));
controllers = g_slist_remove (controllers, controller); model = gtk_shortcut_manager_get_model (self, phase);
if (controllers) if (model)
g_object_set_data_full (G_OBJECT (self), "gtk-shortcut-controllers", controllers, complain_if_reached); {
g_object_unref (controller); GListModel *store;
guint position;
store = gtk_flatten_list_model_get_model (model);
#if 0 && GLIB_CHECK_VERSION(2,64,0)
if (_g_list_store_find (G_LIST_STORE (store), controller, &position))
g_list_store_remove (G_LIST_STORE (store), position);
#else
for (position = 0; position < g_list_model_get_n_items (G_LIST_MODEL (store)); position++)
{
GtkShortcutController *item = g_list_model_get_item (G_LIST_MODEL (store), position);
g_object_unref (item);
if (item == controller)
{
g_list_store_remove (G_LIST_STORE (store), position);
break;
}
}
#endif
}
} }
static void static void

View File

@ -0,0 +1,12 @@
#ifndef __GTK_SHORTCUT_MANAGER_PRIVATE_H__
#define __GTK_SHORTCUT_MANAGER__PRIVATE_H__
#include "gtkshortcutmanager.h"
G_BEGIN_DECLS
void gtk_shortcut_manager_create_controllers (GtkWidget *widget);
G_END_DECLS
#endif /* __GTK_SHORTCUT_MANAGER_PRIVATE_H__ */

View File

@ -60,6 +60,7 @@
#include "gtkshortcut.h" #include "gtkshortcut.h"
#include "gtkshortcutcontrollerprivate.h" #include "gtkshortcutcontrollerprivate.h"
#include "gtkshortcutmanager.h" #include "gtkshortcutmanager.h"
#include "gtkshortcutmanagerprivate.h"
#include "gtkshortcuttrigger.h" #include "gtkshortcuttrigger.h"
#include "gtksizegroup-private.h" #include "gtksizegroup-private.h"
#include "gtksnapshotprivate.h" #include "gtksnapshotprivate.h"
@ -2444,16 +2445,7 @@ gtk_widget_init (GTypeInstance *instance, gpointer g_class)
priv->root = (GtkRoot *) widget; priv->root = (GtkRoot *) widget;
if (g_type_is_a (G_TYPE_FROM_CLASS (g_class), GTK_TYPE_SHORTCUT_MANAGER)) if (g_type_is_a (G_TYPE_FROM_CLASS (g_class), GTK_TYPE_SHORTCUT_MANAGER))
{ gtk_shortcut_manager_create_controllers (widget);
controller = gtk_shortcut_controller_new ();
gtk_shortcut_controller_set_run_managed (GTK_SHORTCUT_CONTROLLER (controller), TRUE);
gtk_widget_add_controller (widget, controller);
controller = gtk_shortcut_controller_new ();
gtk_event_controller_set_propagation_phase (controller, GTK_PHASE_CAPTURE);
gtk_shortcut_controller_set_run_managed (GTK_SHORTCUT_CONTROLLER (controller), TRUE);
gtk_widget_add_controller (widget, controller);
}
layout_manager_type = gtk_widget_class_get_layout_manager_type (g_class); layout_manager_type = gtk_widget_class_get_layout_manager_type (g_class);
if (layout_manager_type != G_TYPE_INVALID) if (layout_manager_type != G_TYPE_INVALID)