diff options
author | Benjamin Otte <otte@redhat.com> | 2017-12-13 01:53:17 +0100 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2017-12-13 01:55:56 +0100 |
commit | fb0fdddd767d174085bcc005633d2b48cea3c99d (patch) | |
tree | ee42a8a6441fa1553c9e39ab00c6dea7b4a21d30 | |
parent | 76b93f55981e6c16480fb169bdac97ab97d60e30 (diff) | |
download | gtk+-fb0fdddd767d174085bcc005633d2b48cea3c99d.tar.gz |
x11: Refactor xevent filtering some more
We now have a GdkX11Display::xevent signal that gets emitted for every
XEvent and allows you to interrupt processing via TRUE/FALSE return
values.
These return values to correspond to GDK_FILTER_REMOVE and
GDK_FILTER_CONTINUE respectively.
The GDK_FILTER_TRANSLATE case from gdk_window_add_filter() is now meant
to be handled via gdk_display_put_event().
-rw-r--r-- | gdk/gdkmarshalers.list | 2 | ||||
-rw-r--r-- | gdk/x11/gdkclipboard-x11.c | 42 | ||||
-rw-r--r-- | gdk/x11/gdkdisplay-x11.c | 75 | ||||
-rw-r--r-- | gdk/x11/gdkdisplay-x11.h | 2 | ||||
-rw-r--r-- | gdk/x11/gdkeventsource.c | 38 | ||||
-rw-r--r-- | gdk/x11/gdkeventsource.h | 2 | ||||
-rw-r--r-- | gdk/x11/gdkselectioninputstream-x11.c | 34 | ||||
-rw-r--r-- | gdk/x11/gdkselectionoutputstream-x11.c | 30 |
8 files changed, 108 insertions, 117 deletions
diff --git a/gdk/gdkmarshalers.list b/gdk/gdkmarshalers.list index c5df1db202..1281c143b2 100644 --- a/gdk/gdkmarshalers.list +++ b/gdk/gdkmarshalers.list @@ -1,2 +1,2 @@ -BOXED:POINTER +BOOLEAN:POINTER VOID:POINTER,POINTER,BOOLEAN,BOOLEAN diff --git a/gdk/x11/gdkclipboard-x11.c b/gdk/x11/gdkclipboard-x11.c index ce905b892e..ccbd3c19b3 100644 --- a/gdk/x11/gdkclipboard-x11.c +++ b/gdk/x11/gdkclipboard-x11.c @@ -372,10 +372,10 @@ gdk_x11_clipboard_claim_remote (GdkX11Clipboard *cb, gdk_x11_clipboard_request_targets (cb); } -static GdkEvent * -gdk_x11_clipboard_translate_event (GdkDisplay *display, - const XEvent *xevent, - gpointer data) +static gboolean +gdk_x11_clipboard_xevent (GdkDisplay *display, + const XEvent *xevent, + gpointer data) { GdkX11Clipboard *cb = GDK_X11_CLIPBOARD (data); Window xwindow; @@ -383,41 +383,41 @@ gdk_x11_clipboard_translate_event (GdkDisplay *display, xwindow = GDK_X11_DISPLAY (display)->leader_window; if (xevent->xany.window != xwindow) - return NULL; + return FALSE; switch (xevent->type) { case SelectionClear: if (xevent->xselectionclear.selection != cb->xselection) - return NULL; + return FALSE; if (xevent->xselectionclear.time < cb->timestamp) { GDK_NOTE(CLIPBOARD, g_printerr ("%s: ignoring SelectionClear with too old timestamp (%lu vs %lu)\n", cb->selection, xevent->xselectionclear.time, cb->timestamp)); - return NULL; + return FALSE; } GDK_NOTE(CLIPBOARD, g_printerr ("%s: got SelectionClear\n", cb->selection)); gdk_x11_clipboard_claim_remote (cb, xevent->xselectionclear.time); - return gdk_event_new (GDK_NOTHING); + return TRUE; case SelectionNotify: /* This code only checks clipboard manager replies, so... */ if (!g_str_equal (cb->selection, "CLIPBOARD")) - return NULL; + return FALSE; /* selection is not for us */ if (xevent->xselection.selection != gdk_x11_get_xatom_by_name_for_display (display, "CLIPBOARD_MANAGER") || xevent->xselection.target != gdk_x11_get_xatom_by_name_for_display (display, "SAVE_TARGETS")) - return NULL; + return FALSE; /* We already received a selectionNotify before */ if (cb->store_task == NULL) { GDK_NOTE(CLIPBOARD, g_printerr ("%s: got SelectionNotify for nonexisting task?!\n", cb->selection)); - return NULL; + return FALSE; } GDK_NOTE(CLIPBOARD, g_printerr ("%s: got SelectionNotify for store task\n", @@ -430,14 +430,14 @@ gdk_x11_clipboard_translate_event (GdkDisplay *display, _("Clipboard manager could not store selection.")); g_clear_object (&cb->store_task); - return NULL; + return FALSE; case SelectionRequest: { const char *target, *property; if (xevent->xselectionrequest.selection != cb->xselection) - return NULL; + return FALSE; target = gdk_x11_get_xatom_name_for_display (display, xevent->xselectionrequest.target); if (xevent->xselectionrequest.property == None) @@ -449,13 +449,13 @@ gdk_x11_clipboard_translate_event (GdkDisplay *display, { GDK_NOTE(CLIPBOARD, g_printerr ("%s: got SelectionRequest for %s @ %s even though we don't own the selection, huh?\n", cb->selection, target, property)); - return gdk_event_new (GDK_NOTHING); + return TRUE; } if (xevent->xselectionrequest.requestor == None) { GDK_NOTE(CLIPBOARD, g_printerr ("%s: got SelectionRequest for %s @ %s with NULL window, ignoring\n", cb->selection, target, property)); - return gdk_event_new (GDK_NOTHING); + return TRUE; } GDK_NOTE(CLIPBOARD, g_printerr ("%s: got SelectionRequest for %s @ %s\n", @@ -471,7 +471,7 @@ gdk_x11_clipboard_translate_event (GdkDisplay *display, xevent->xselectionrequest.time, gdk_x11_clipboard_default_output_handler, cb); - return gdk_event_new (GDK_NOTHING); + return TRUE; } default: @@ -481,13 +481,13 @@ gdk_x11_clipboard_translate_event (GdkDisplay *display, XFixesSelectionNotifyEvent *sn = (XFixesSelectionNotifyEvent *) xevent; if (sn->selection != cb->xselection) - return NULL; + return FALSE; if (sn->owner == GDK_X11_DISPLAY (display)->leader_window) { GDK_NOTE(CLIPBOARD, g_printerr ("%s: Ignoring XFixesSelectionNotify for ourselves\n", cb->selection)); - return NULL; + return FALSE; } GDK_NOTE(CLIPBOARD, g_printerr ("%s: Received XFixesSelectionNotify, claiming selection\n", @@ -496,7 +496,7 @@ gdk_x11_clipboard_translate_event (GdkDisplay *display, gdk_x11_clipboard_claim_remote (cb, sn->selection_timestamp); } #endif - return NULL; + return FALSE; } } @@ -506,7 +506,7 @@ gdk_x11_clipboard_finalize (GObject *object) GdkX11Clipboard *cb = GDK_X11_CLIPBOARD (object); g_signal_handlers_disconnect_by_func (gdk_clipboard_get_display (GDK_CLIPBOARD (cb)), - gdk_x11_clipboard_translate_event, + gdk_x11_clipboard_xevent, cb); g_free (cb->selection); @@ -814,7 +814,7 @@ gdk_x11_clipboard_new (GdkDisplay *display, cb->xselection = gdk_x11_get_xatom_by_name_for_display (display, selection); gdk_display_request_selection_notification (display, gdk_atom_intern (selection, FALSE)); - g_signal_connect (display, "translate-event", G_CALLBACK (gdk_x11_clipboard_translate_event), cb); + g_signal_connect (display, "xevent", G_CALLBACK (gdk_x11_clipboard_xevent), cb); gdk_x11_clipboard_claim_remote (cb, CurrentTime); return GDK_CLIPBOARD (cb); diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c index b8eaff19d5..ba8b69bc30 100644 --- a/gdk/x11/gdkdisplay-x11.c +++ b/gdk/x11/gdkdisplay-x11.c @@ -77,7 +77,7 @@ #endif enum { - TRANSLATE_EVENT, + XEVENT, LAST_SIGNAL }; @@ -3164,21 +3164,19 @@ gdk_x11_display_get_last_seen_time (GdkDisplay *display) } static gboolean -gdk_x11_display_translate_event_accumulator (GSignalInvocationHint *ihint, - GValue *return_accu, - const GValue *handler_return, - gpointer dummy) +gdk_boolean_handled_accumulator (GSignalInvocationHint *ihint, + GValue *return_accu, + const GValue *handler_return, + gpointer dummy) { - GdkEvent *event; + gboolean continue_emission; + gboolean signal_handled; - event = g_value_get_boxed (handler_return); - if (event == NULL) - return TRUE; + signal_handled = g_value_get_boolean (handler_return); + g_value_set_boolean (return_accu, signal_handled); + continue_emission = !signal_handled; - if (event->type != GDK_NOTHING) - g_value_set_boxed (return_accu, event); - - return FALSE; + return continue_emission; } static void @@ -3241,53 +3239,40 @@ gdk_x11_display_class_init (GdkX11DisplayClass * class) display_class->get_last_seen_time = gdk_x11_display_get_last_seen_time; display_class->set_cursor_theme = gdk_x11_display_set_cursor_theme; - class->translate_event = gdk_event_source_translate_event; + class->xevent = gdk_event_source_xevent; /** - * GdkX11Display::translate-event: + * GdkX11Display::xevent: * @display: the object on which the signal is emitted * @xevent: a pointer to the XEvent to process * - * The ::translate-event signal is a low level signal that is emitted - * whenever an XEvent needs to be translated to a #GdkEvent. - * - * Handlers to this signal can return one of 3 possible values: - * - * 1. %NULL - * - * This will result in the next handler being invoked. - * - * 2. a #GdkEvent - * - * This will result in no further handlers being invoked and the returned - * event being enqueued for further processing by GDK. - * - * 3. gdk_event_new(GDK_NOTHING) + * The ::xevent signal is a low level signal that is emitted + * whenever an XEvent has been received. * - * If a handler returns an event of type GDK_NOTHING, the event will be - * discarded and no further handlers will be invoked. Use this if your - * function completely handled the @xevent. + * When handlers to this signal return %TRUE, no other handlers will be + * invoked. In particular, the default handler for this function is + * GDK's own event handling mechanism, so by returning %TRUE for an event + * that GDK expects to translate, you may break GDK and/or GTK+ in + * interesting ways. You have been warned. * - * Note that the default handler for this function is GDK's own event - * translation mechanism, so by translating an event that GDK expects to - * translate, you may break GDK and/or GTK+ in interesting ways, so you - * have to know what you're doing. + * If you want this signal handler to queue a #GdkEvent, you can use + * gdk_display_put_event(). * * If you are interested in X GenericEvents, bear in mind that * XGetEventData() has been already called on the event, and * XFreeEventData() will be called afterwards. * - * Returns: The translated #GdkEvent or %NULL to invoke further handlers to - * translate the event. + * Returns: %TRUE to stop other handlers from being invoked for the event. + * %FALSE to propagate the event further. */ - signals[TRANSLATE_EVENT] = - g_signal_new (g_intern_static_string ("translate-event"), + signals[XEVENT] = + g_signal_new (g_intern_static_string ("xevent"), G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GdkX11DisplayClass, translate_event), - gdk_x11_display_translate_event_accumulator, NULL, - _gdk_marshal_BOXED__POINTER, - GDK_TYPE_EVENT, 1, G_TYPE_POINTER); + G_STRUCT_OFFSET (GdkX11DisplayClass, xevent), + gdk_boolean_handled_accumulator, NULL, + _gdk_marshal_BOOLEAN__POINTER, + G_TYPE_BOOLEAN, 1, G_TYPE_POINTER); _gdk_x11_windowing_init (); } diff --git a/gdk/x11/gdkdisplay-x11.h b/gdk/x11/gdkdisplay-x11.h index 555b8551e7..efe28911d2 100644 --- a/gdk/x11/gdkdisplay-x11.h +++ b/gdk/x11/gdkdisplay-x11.h @@ -168,7 +168,7 @@ struct _GdkX11DisplayClass { GdkDisplayClass parent_class; - GdkEvent * (* translate_event) (GdkX11Display *display, + gboolean (* xevent) (GdkX11Display *display, const XEvent *event); }; diff --git a/gdk/x11/gdkeventsource.c b/gdk/x11/gdkeventsource.c index ccf4c59a4c..975ed89432 100644 --- a/gdk/x11/gdkeventsource.c +++ b/gdk/x11/gdkeventsource.c @@ -263,7 +263,7 @@ handle_touch_synthetic_crossing (GdkEvent *event) } } -GdkEvent * +static GdkEvent * gdk_event_source_translate_event (GdkX11Display *x11_display, const XEvent *xevent) { @@ -378,6 +378,24 @@ gdk_event_source_translate_event (GdkX11Display *x11_display, return event; } +gboolean +gdk_event_source_xevent (GdkX11Display *x11_display, + const XEvent *xevent) +{ + GdkDisplay *display = GDK_DISPLAY (x11_display); + GdkEvent *event; + GList *node; + + event = gdk_event_source_translate_event (x11_display, xevent); + if (event == NULL) + return FALSE; + + node = _gdk_event_queue_append (display, event); + _gdk_windowing_got_event (display, node, event, xevent->xany.serial); + + return TRUE; +} + static gboolean gdk_check_xpending (GdkDisplay *display) { @@ -430,9 +448,9 @@ gdk_event_source_check (GSource *source) void _gdk_x11_display_queue_events (GdkDisplay *display) { - GdkEvent *event; - XEvent xevent; Display *xdisplay = GDK_DISPLAY_XDISPLAY (display); + XEvent xevent; + gboolean unused; while (!_gdk_event_queue_find_first (display) && XPending (xdisplay)) { @@ -456,24 +474,12 @@ _gdk_x11_display_queue_events (GdkDisplay *display) XGetEventData (xdisplay, &xevent.xcookie); #endif - g_signal_emit_by_name (display, "translate-event", &xevent, &event); + g_signal_emit_by_name (display, "xevent", &xevent, &unused); #ifdef HAVE_XGENERICEVENTS if (xevent.type == GenericEvent) XFreeEventData (xdisplay, &xevent.xcookie); #endif - - if (event && event->type == GDK_NOTHING) - { - gdk_event_free (event); - } - else if (event) - { - GList *node; - - node = _gdk_event_queue_append (display, event); - _gdk_windowing_got_event (display, node, event, xevent.xany.serial); - } } } diff --git a/gdk/x11/gdkeventsource.h b/gdk/x11/gdkeventsource.h index 5398f4f936..1344231525 100644 --- a/gdk/x11/gdkeventsource.h +++ b/gdk/x11/gdkeventsource.h @@ -38,7 +38,7 @@ void gdk_x11_event_source_select_events (GdkEventSource *source, GdkEventMask event_mask, unsigned int extra_x_mask); -GdkEvent *gdk_event_source_translate_event (GdkX11Display *display, +gboolean gdk_event_source_xevent (GdkX11Display *x11_display, const XEvent *xevent); diff --git a/gdk/x11/gdkselectioninputstream-x11.c b/gdk/x11/gdkselectioninputstream-x11.c index 4ad213e073..4a6f501415 100644 --- a/gdk/x11/gdkselectioninputstream-x11.c +++ b/gdk/x11/gdkselectioninputstream-x11.c @@ -54,10 +54,10 @@ struct GdkX11SelectionInputStreamPrivate { G_DEFINE_TYPE_WITH_PRIVATE (GdkX11SelectionInputStream, gdk_x11_selection_input_stream, G_TYPE_INPUT_STREAM); -static GdkEvent * -gdk_x11_selection_input_stream_translate_event (GdkDisplay *display, - const XEvent *xevent, - gpointer data); +static gboolean +gdk_x11_selection_input_stream_xevent (GdkDisplay *display, + const XEvent *xevent, + gpointer data); static gboolean gdk_x11_selection_input_stream_has_data (GdkX11SelectionInputStream *stream) @@ -162,7 +162,7 @@ gdk_x11_selection_input_stream_complete (GdkX11SelectionInputStream *stream) GDK_X11_DISPLAY (priv->display)->streams = g_slist_remove (GDK_X11_DISPLAY (priv->display)->streams, stream); g_signal_handlers_disconnect_by_func (priv->display, - gdk_x11_selection_input_stream_translate_event, + gdk_x11_selection_input_stream_xevent, stream); g_object_unref (stream); @@ -378,10 +378,10 @@ err: } -static GdkEvent * -gdk_x11_selection_input_stream_translate_event (GdkDisplay *display, - const XEvent *xevent, - gpointer data) +static gboolean +gdk_x11_selection_input_stream_xevent (GdkDisplay *display, + const XEvent *xevent, + gpointer data) { GdkX11SelectionInputStream *stream = GDK_X11_SELECTION_INPUT_STREAM (data); GdkX11SelectionInputStreamPrivate *priv = gdk_x11_selection_input_stream_get_instance_private (stream); @@ -396,7 +396,7 @@ gdk_x11_selection_input_stream_translate_event (GdkDisplay *display, if (xevent->xany.display != xdisplay || xevent->xany.window != xwindow) - return NULL; + return FALSE; switch (xevent->type) { @@ -404,7 +404,7 @@ gdk_x11_selection_input_stream_translate_event (GdkDisplay *display, if (!priv->incr || xevent->xproperty.atom != priv->xproperty || xevent->xproperty.state != PropertyNewValue) - return NULL; + return FALSE; bytes = get_selection_property (xdisplay, xwindow, xevent->xproperty.atom, &type, &format); if (bytes == NULL) @@ -432,7 +432,7 @@ gdk_x11_selection_input_stream_translate_event (GdkDisplay *display, XDeleteProperty (xdisplay, xwindow, xevent->xproperty.atom); - return NULL; + return FALSE; case SelectionNotify: { @@ -441,12 +441,12 @@ gdk_x11_selection_input_stream_translate_event (GdkDisplay *display, /* selection is not for us */ if (priv->xselection != xevent->xselection.selection || priv->xtarget != xevent->xselection.target) - return NULL; + return FALSE; /* We already received a selectionNotify before */ if (priv->pending_task == NULL || g_task_get_source_tag (priv->pending_task) != gdk_x11_selection_input_stream_new_async) - return NULL; + return FALSE; GDK_NOTE(SELECTION, g_printerr ("%s:%s: got SelectionNotify\n", priv->selection, priv->target)); @@ -498,10 +498,10 @@ gdk_x11_selection_input_stream_translate_event (GdkDisplay *display, g_object_unref (task); } - return gdk_event_new (GDK_NOTHING); + return TRUE; default: - return NULL; + return FALSE; } } @@ -530,7 +530,7 @@ gdk_x11_selection_input_stream_new_async (GdkDisplay *display, priv->property = g_strdup_printf ("GDK_SELECTION_%p", stream); priv->xproperty = gdk_x11_get_xatom_by_name_for_display (display, priv->property); - g_signal_connect (display, "translate-event", G_CALLBACK (gdk_x11_selection_input_stream_translate_event), stream); + g_signal_connect (display, "xevent", G_CALLBACK (gdk_x11_selection_input_stream_xevent), stream); XConvertSelection (GDK_DISPLAY_XDISPLAY (display), priv->xselection, diff --git a/gdk/x11/gdkselectionoutputstream-x11.c b/gdk/x11/gdkselectionoutputstream-x11.c index 8428231420..fbca038869 100644 --- a/gdk/x11/gdkselectionoutputstream-x11.c +++ b/gdk/x11/gdkselectionoutputstream-x11.c @@ -147,10 +147,10 @@ gdk_x11_pending_selection_notify_send (GdkX11PendingSelectionNotify *notify, } } -static GdkEvent * -gdk_x11_selection_output_stream_translate_event (GdkDisplay *display, - const XEvent *xevent, - gpointer data); +static gboolean +gdk_x11_selection_output_stream_xevent (GdkDisplay *display, + const XEvent *xevent, + gpointer data); static gboolean gdk_x11_selection_output_stream_can_flush (GdkX11SelectionOutputStream *stream) @@ -493,7 +493,7 @@ gdk_x11_selection_output_stream_invoke_close (gpointer stream) GDK_X11_DISPLAY (priv->display)->streams = g_slist_remove (GDK_X11_DISPLAY (priv->display)->streams, stream); g_signal_handlers_disconnect_by_func (priv->display, - gdk_x11_selection_output_stream_translate_event, + gdk_x11_selection_output_stream_xevent, stream); return G_SOURCE_REMOVE; @@ -589,10 +589,10 @@ gdk_x11_selection_output_stream_init (GdkX11SelectionOutputStream *stream) priv->data = g_byte_array_new (); } -static GdkEvent * -gdk_x11_selection_output_stream_translate_event (GdkDisplay *display, - const XEvent *xevent, - gpointer data) +static gboolean +gdk_x11_selection_output_stream_xevent (GdkDisplay *display, + const XEvent *xevent, + gpointer data) { GdkX11SelectionOutputStream *stream = GDK_X11_SELECTION_OUTPUT_STREAM (data); GdkX11SelectionOutputStreamPrivate *priv = gdk_x11_selection_output_stream_get_instance_private (stream); @@ -602,7 +602,7 @@ gdk_x11_selection_output_stream_translate_event (GdkDisplay *display, if (xevent->xany.display != xdisplay || xevent->xany.window != priv->xwindow) - return NULL; + return FALSE; switch (xevent->type) { @@ -610,7 +610,7 @@ gdk_x11_selection_output_stream_translate_event (GdkDisplay *display, if (!priv->incr || xevent->xproperty.atom != priv->xproperty || xevent->xproperty.state != PropertyDelete) - return NULL; + return FALSE; GDK_NOTE(SELECTION, g_printerr ("%s:%s: got PropertyNotify Delete during INCR\n", priv->selection, priv->target)); @@ -618,10 +618,10 @@ gdk_x11_selection_output_stream_translate_event (GdkDisplay *display, if (gdk_x11_selection_output_stream_needs_flush (stream) & gdk_x11_selection_output_stream_can_flush (stream)) gdk_x11_selection_output_stream_perform_flush (stream); - return NULL; + return FALSE; default: - return NULL; + return FALSE; } } @@ -658,8 +658,8 @@ gdk_x11_selection_output_stream_new (GdkDisplay *display, priv->timestamp = timestamp; g_signal_connect (display, - "translate-event", - G_CALLBACK (gdk_x11_selection_output_stream_translate_event), + "xevent", + G_CALLBACK (gdk_x11_selection_output_stream_xevent), stream); return G_OUTPUT_STREAM (stream); |