/* * Copyright © 2018 Benjamin Otte * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . * * Authors: Benjamin Otte */ #include "config.h" #include "gtkshortcutmanager.h" #include "gtkshortcutmanagerprivate.h" #include "gtkflattenlistmodel.h" /** * GtkShortcutManager: * * The `GtkShortcutManager` interface is used to implement * shortcut scopes. * * This is important for [iface@Gtk.Native] widgets that have their * own surface, since the event controllers that are used to implement * managed and global scopes are limited to the same native. * * Examples for widgets implementing `GtkShortcutManager` are * [class@Gtk.Window] and [class@Gtk.Popover]. * * Every widget that implements `GtkShortcutManager` will be used as a * %GTK_SHORTCUT_SCOPE_MANAGED. */ G_DEFINE_INTERFACE (GtkShortcutManager, gtk_shortcut_manager, G_TYPE_OBJECT) void gtk_shortcut_manager_create_controllers (GtkWidget *widget) { GtkFlattenListModel *model; GtkEventController *controller; model = gtk_flatten_list_model_new (G_LIST_MODEL (g_list_store_new (GTK_TYPE_SHORTCUT_CONTROLLER))); 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); model = gtk_flatten_list_model_new (G_LIST_MODEL (g_list_store_new (GTK_TYPE_SHORTCUT_CONTROLLER))); 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 gtk_shortcut_manager_default_add_controller (GtkShortcutManager *self, GtkShortcutController *controller) { GtkFlattenListModel *model; GtkPropagationPhase phase; phase = gtk_event_controller_get_propagation_phase (GTK_EVENT_CONTROLLER (controller)); model = gtk_shortcut_manager_get_model (self, phase); if (model) { GListModel *store = gtk_flatten_list_model_get_model (model); g_list_store_append (G_LIST_STORE (store), controller); } } static void gtk_shortcut_manager_default_remove_controller (GtkShortcutManager *self, GtkShortcutController *controller) { GtkFlattenListModel *model; GtkPropagationPhase phase; phase = gtk_event_controller_get_propagation_phase (GTK_EVENT_CONTROLLER (controller)); model = gtk_shortcut_manager_get_model (self, phase); if (model) { GListModel *store; guint position; store = gtk_flatten_list_model_get_model (model); if (g_list_store_find (G_LIST_STORE (store), controller, &position)) g_list_store_remove (G_LIST_STORE (store), position); } } static void gtk_shortcut_manager_default_init (GtkShortcutManagerInterface *iface) { iface->add_controller = gtk_shortcut_manager_default_add_controller; iface->remove_controller = gtk_shortcut_manager_default_remove_controller; }