1/*
2 * Copyright © 2018 Benjamin Otte
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authors: Benjamin Otte <otte@gnome.org>
18 */
19
20#include "config.h"
21
22#include "gtkshortcutmanager.h"
23#include "gtkshortcutmanagerprivate.h"
24#include "gtkflattenlistmodel.h"
25
26/**
27 * GtkShortcutManager:
28 *
29 * The `GtkShortcutManager` interface is used to implement
30 * shortcut scopes.
31 *
32 * This is important for [iface@Gtk.Native] widgets that have their
33 * own surface, since the event controllers that are used to implement
34 * managed and global scopes are limited to the same native.
35 *
36 * Examples for widgets implementing `GtkShortcutManager` are
37 * [class@Gtk.Window] and [class@Gtk.Popover].
38 *
39 * Every widget that implements `GtkShortcutManager` will be used as a
40 * %GTK_SHORTCUT_SCOPE_MANAGED.
41 */
42
43G_DEFINE_INTERFACE (GtkShortcutManager, gtk_shortcut_manager, G_TYPE_OBJECT)
44
45void
46gtk_shortcut_manager_create_controllers (GtkWidget *widget)
47{
48 GtkFlattenListModel *model;
49 GtkEventController *controller;
50
51 model = gtk_flatten_list_model_new (model: G_LIST_MODEL (ptr: g_list_store_new (GTK_TYPE_SHORTCUT_CONTROLLER)));
52 g_object_set_data_full (G_OBJECT (widget), key: "gtk-shortcut-manager-bubble", data: model, destroy: g_object_unref);
53 controller = gtk_shortcut_controller_new_for_model (model: G_LIST_MODEL (ptr: model));
54 gtk_event_controller_set_name (controller, name: "gtk-shortcut-manager-bubble");
55 gtk_widget_add_controller (widget, controller);
56
57 model = gtk_flatten_list_model_new (model: G_LIST_MODEL (ptr: g_list_store_new (GTK_TYPE_SHORTCUT_CONTROLLER)));
58 g_object_set_data_full (G_OBJECT (widget), key: "gtk-shortcut-manager-capture", data: model, destroy: g_object_unref);
59 controller = gtk_shortcut_controller_new_for_model (model: G_LIST_MODEL (ptr: model));
60 gtk_event_controller_set_name (controller, name: "gtk-shortcut-manager-capture");
61 gtk_event_controller_set_propagation_phase (controller, phase: GTK_PHASE_CAPTURE);
62 gtk_widget_add_controller (widget, controller);
63}
64
65static GtkFlattenListModel *
66gtk_shortcut_manager_get_model (GtkShortcutManager *self,
67 GtkPropagationPhase phase)
68{
69 switch (phase)
70 {
71 case GTK_PHASE_CAPTURE:
72 return g_object_get_data (G_OBJECT (self), key: "gtk-shortcut-manager-capture");
73 case GTK_PHASE_BUBBLE:
74 return g_object_get_data (G_OBJECT (self), key: "gtk-shortcut-manager-bubble");
75 case GTK_PHASE_NONE:
76 case GTK_PHASE_TARGET:
77 return NULL;
78 default:
79 g_assert_not_reached ();
80 return NULL;
81 }
82}
83
84static void
85gtk_shortcut_manager_default_add_controller (GtkShortcutManager *self,
86 GtkShortcutController *controller)
87{
88 GtkFlattenListModel *model;
89 GtkPropagationPhase phase;
90
91 phase = gtk_event_controller_get_propagation_phase (GTK_EVENT_CONTROLLER (controller));
92 model = gtk_shortcut_manager_get_model (self, phase);
93 if (model)
94 {
95 GListModel *store = gtk_flatten_list_model_get_model (self: model);
96 g_list_store_append (store: G_LIST_STORE (ptr: store), item: controller);
97 }
98}
99
100static void
101gtk_shortcut_manager_default_remove_controller (GtkShortcutManager *self,
102 GtkShortcutController *controller)
103{
104 GtkFlattenListModel *model;
105 GtkPropagationPhase phase;
106
107 phase = gtk_event_controller_get_propagation_phase (GTK_EVENT_CONTROLLER (controller));
108 model = gtk_shortcut_manager_get_model (self, phase);
109 if (model)
110 {
111 GListModel *store;
112 guint position;
113
114 store = gtk_flatten_list_model_get_model (self: model);
115 if (g_list_store_find (store: G_LIST_STORE (ptr: store), item: controller, position: &position))
116 g_list_store_remove (store: G_LIST_STORE (ptr: store), position);
117 }
118}
119
120static void
121gtk_shortcut_manager_default_init (GtkShortcutManagerInterface *iface)
122{
123 iface->add_controller = gtk_shortcut_manager_default_add_controller;
124 iface->remove_controller = gtk_shortcut_manager_default_remove_controller;
125}
126
127

source code of gtk/gtk/gtkshortcutmanager.c