summaryrefslogtreecommitdiff
path: root/src/x11/meta-x11-display.c
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2022-09-27 21:31:33 +0200
committerCarlos Garnacho <carlosg@gnome.org>2023-02-23 17:19:22 +0100
commita799ac8ff0d965c346dea6af845722e59a0ffc02 (patch)
tree49ef87d78705677653c8aeeda0ca99ca3fa43291 /src/x11/meta-x11-display.c
parent45bda2d969f22b1028a1c0062e7f8554e475b23a (diff)
downloadmutter-a799ac8ff0d965c346dea6af845722e59a0ffc02.tar.gz
x11: Add public API to handle X11 events
This API will be used by GNOME Shell to handle X11 events in the relevant places, as a substitute to gdk_window_add_filter(). It is ATM still a bit ironic, since the Mutter X11 event handler is itself a GdkFilterFunc, but it may move away from that eventually. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2779>
Diffstat (limited to 'src/x11/meta-x11-display.c')
-rw-r--r--src/x11/meta-x11-display.c82
1 files changed, 82 insertions, 0 deletions
diff --git a/src/x11/meta-x11-display.c b/src/x11/meta-x11-display.c
index 16b564d55..4ea0bbc91 100644
--- a/src/x11/meta-x11-display.c
+++ b/src/x11/meta-x11-display.c
@@ -77,6 +77,16 @@ G_DEFINE_TYPE (MetaX11Display, meta_x11_display, G_TYPE_OBJECT)
static GQuark quark_x11_display_logical_monitor_data = 0;
+typedef struct _MetaX11EventFilter MetaX11EventFilter;
+
+struct _MetaX11EventFilter
+{
+ unsigned int id;
+ MetaX11DisplayEventFunc func;
+ gpointer user_data;
+ GDestroyNotify destroy_notify;
+};
+
typedef struct _MetaX11DisplayLogicalMonitorData
{
int xinerama_index;
@@ -127,6 +137,14 @@ meta_x11_display_unmanage_windows (MetaX11Display *x11_display)
}
static void
+meta_x11_event_filter_free (MetaX11EventFilter *filter)
+{
+ if (filter->destroy_notify && filter->user_data)
+ filter->destroy_notify (filter->user_data);
+ g_free (filter);
+}
+
+static void
meta_x11_display_dispose (GObject *object)
{
MetaX11Display *x11_display = META_X11_DISPLAY (object);
@@ -135,6 +153,9 @@ meta_x11_display_dispose (GObject *object)
g_clear_pointer (&x11_display->alarm_filters, g_ptr_array_unref);
+ g_clear_list (&x11_display->event_funcs,
+ (GDestroyNotify) meta_x11_event_filter_free);
+
if (x11_display->frames_client_cancellable)
{
g_cancellable_cancel (x11_display->frames_client_cancellable);
@@ -2472,3 +2493,64 @@ meta_x11_display_clear_stage_input_region (MetaX11Display *x11_display)
meta_x11_display_set_stage_input_region (x11_display,
x11_display->empty_region);
}
+
+/**
+ * meta_x11_display_add_event_func: (skip):
+ **/
+unsigned int
+meta_x11_display_add_event_func (MetaX11Display *x11_display,
+ MetaX11DisplayEventFunc event_func,
+ gpointer user_data,
+ GDestroyNotify destroy_notify)
+{
+ MetaX11EventFilter *filter;
+ static unsigned int id = 0;
+
+ filter = g_new0 (MetaX11EventFilter, 1);
+ filter->func = event_func;
+ filter->user_data = user_data;
+ filter->destroy_notify = destroy_notify;
+ filter->id = ++id;
+
+ x11_display->event_funcs = g_list_prepend (x11_display->event_funcs, filter);
+
+ return filter->id;
+}
+
+/**
+ * meta_x11_display_remove_event_func: (skip):
+ **/
+void
+meta_x11_display_remove_event_func (MetaX11Display *x11_display,
+ unsigned int id)
+{
+ MetaX11EventFilter *filter;
+ GList *l;
+
+ for (l = x11_display->event_funcs; l; l = l->next)
+ {
+ filter = l->data;
+
+ if (filter->id != id)
+ continue;
+
+ x11_display->event_funcs =
+ g_list_delete_link (x11_display->event_funcs, l);
+ meta_x11_event_filter_free (filter);
+ break;
+ }
+}
+
+void
+meta_x11_display_run_event_funcs (MetaX11Display *x11_display,
+ XEvent *xevent)
+{
+ MetaX11EventFilter *filter;
+ GList *l;
+
+ for (l = x11_display->event_funcs; l; l = l->next)
+ {
+ filter = l->data;
+ filter->func (x11_display, xevent, filter->user_data);
+ }
+}