mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-09-19 21:40:22 +00:00
x11: Add GdkX11Display:translate-event signal
This is supposed to replace gdk_window_add_filter() in the long run.
This commit is contained in:
parent
f34297cfba
commit
0d1ea05658
@ -4,5 +4,6 @@ VOID:POINTER,POINTER,POINTER
|
||||
OBJECT:VOID
|
||||
OBJECT:DOUBLE,DOUBLE
|
||||
BOXED:INT,INT
|
||||
BOXED:POINTER
|
||||
VOID:DOUBLE,DOUBLE,POINTER,POINTER
|
||||
VOID:POINTER,POINTER,BOOLEAN,BOOLEAN
|
||||
|
@ -33,9 +33,9 @@
|
||||
#include "gdkeventtranslator.h"
|
||||
#include "gdkframeclockprivate.h"
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkkeysprivate.h"
|
||||
#include "gdkmarshalers.h"
|
||||
#include "xsettings-client.h"
|
||||
#include "gdkclipboard-x11.h"
|
||||
#include "gdkprivate-x11.h"
|
||||
@ -76,6 +76,11 @@
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#endif
|
||||
|
||||
enum {
|
||||
TRANSLATE_EVENT,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
typedef struct _GdkErrorTrap GdkErrorTrap;
|
||||
|
||||
struct _GdkErrorTrap
|
||||
@ -176,6 +181,8 @@ static const char *const precache_atoms[] = {
|
||||
|
||||
static char *gdk_sm_client_id;
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GdkX11Display, gdk_x11_display, GDK_TYPE_DISPLAY,
|
||||
G_IMPLEMENT_INTERFACE (GDK_TYPE_EVENT_TRANSLATOR,
|
||||
gdk_x11_display_event_translator_init))
|
||||
@ -3156,6 +3163,24 @@ gdk_x11_display_get_last_seen_time (GdkDisplay *display)
|
||||
return gdk_x11_get_server_time (GDK_X11_DISPLAY (display)->leader_gdk_window);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_x11_display_translate_event_accumulator (GSignalInvocationHint *ihint,
|
||||
GValue *return_accu,
|
||||
const GValue *handler_return,
|
||||
gpointer dummy)
|
||||
{
|
||||
GdkEvent *event;
|
||||
|
||||
event = g_value_get_boxed (handler_return);
|
||||
if (event == NULL)
|
||||
return TRUE;
|
||||
|
||||
if (event->type != GDK_NOTHING)
|
||||
g_value_set_boxed (return_accu, event);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_x11_display_class_init (GdkX11DisplayClass * class)
|
||||
{
|
||||
@ -3216,5 +3241,53 @@ 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;
|
||||
|
||||
/**
|
||||
* GdkX11Display::translate-event:
|
||||
* @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)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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 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.
|
||||
*/
|
||||
signals[TRANSLATE_EVENT] =
|
||||
g_signal_new (g_intern_static_string ("translate-event"),
|
||||
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);
|
||||
|
||||
_gdk_x11_windowing_init ();
|
||||
}
|
||||
|
@ -26,8 +26,9 @@
|
||||
#include "gdkkeys.h"
|
||||
#include "gdkwindow.h"
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkx11screen.h"
|
||||
#include "gdkx11devicemanager.h"
|
||||
#include "gdkx11display.h"
|
||||
#include "gdkx11screen.h"
|
||||
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xlib.h>
|
||||
@ -166,6 +167,9 @@ struct _GdkX11Display
|
||||
struct _GdkX11DisplayClass
|
||||
{
|
||||
GdkDisplayClass parent_class;
|
||||
|
||||
GdkEvent * (* translate_event) (GdkX11Display *display,
|
||||
const XEvent *event);
|
||||
};
|
||||
|
||||
GdkX11Screen *_gdk_x11_display_screen_for_xrootwin (GdkDisplay *display,
|
||||
|
@ -263,29 +263,23 @@ handle_touch_synthetic_crossing (GdkEvent *event)
|
||||
}
|
||||
}
|
||||
|
||||
static GdkEvent *
|
||||
gdk_event_source_translate_event (GdkEventSource *event_source,
|
||||
XEvent *xevent)
|
||||
GdkEvent *
|
||||
gdk_event_source_translate_event (GdkX11Display *x11_display,
|
||||
const XEvent *xevent)
|
||||
{
|
||||
GdkEventSource *event_source = (GdkEventSource *) x11_display->event_source;
|
||||
GdkEvent *event = gdk_event_new (GDK_NOTHING);
|
||||
GdkFilterReturn result = GDK_FILTER_CONTINUE;
|
||||
GdkDisplay *display = GDK_DISPLAY (x11_display);
|
||||
GdkEventTranslator *event_translator;
|
||||
GdkWindow *filter_window;
|
||||
Display *dpy;
|
||||
GdkX11Screen *x11_screen;
|
||||
gpointer cache;
|
||||
|
||||
x11_screen = GDK_X11_DISPLAY (event_source->display)->screen;
|
||||
x11_screen = GDK_X11_DISPLAY (display)->screen;
|
||||
|
||||
dpy = GDK_DISPLAY_XDISPLAY (event_source->display);
|
||||
|
||||
#ifdef HAVE_XGENERICEVENTS
|
||||
/* Get cookie data here so it's available
|
||||
* to every event translator and event filter.
|
||||
*/
|
||||
if (xevent->type == GenericEvent)
|
||||
XGetEventData (dpy, &xevent->xcookie);
|
||||
#endif
|
||||
dpy = GDK_DISPLAY_XDISPLAY (display);
|
||||
|
||||
filter_window = gdk_event_source_get_filter_window (event_source, xevent,
|
||||
&event_translator);
|
||||
@ -300,7 +294,7 @@ gdk_event_source_translate_event (GdkEventSource *event_source,
|
||||
xevent->xany.window == x11_screen->xsettings_manager_window)
|
||||
result = gdk_xsettings_manager_window_filter (xevent, event, x11_screen);
|
||||
|
||||
cache = gdk_window_cache_get (event_source->display);
|
||||
cache = gdk_window_cache_get (display);
|
||||
if (cache)
|
||||
{
|
||||
if (result == GDK_FILTER_CONTINUE)
|
||||
@ -328,11 +322,6 @@ gdk_event_source_translate_event (GdkEventSource *event_source,
|
||||
|
||||
if (result != GDK_FILTER_CONTINUE)
|
||||
{
|
||||
#ifdef HAVE_XGENERICEVENTS
|
||||
if (xevent->type == GenericEvent)
|
||||
XFreeEventData (dpy, &xevent->xcookie);
|
||||
#endif
|
||||
|
||||
if (result == GDK_FILTER_REMOVE)
|
||||
{
|
||||
gdk_event_free (event);
|
||||
@ -349,7 +338,7 @@ gdk_event_source_translate_event (GdkEventSource *event_source,
|
||||
{
|
||||
/* Event translator was gotten before in get_filter_window() */
|
||||
event = _gdk_x11_event_translator_translate (event_translator,
|
||||
event_source->display,
|
||||
display,
|
||||
xevent);
|
||||
}
|
||||
else
|
||||
@ -362,7 +351,7 @@ gdk_event_source_translate_event (GdkEventSource *event_source,
|
||||
|
||||
list = list->next;
|
||||
event = _gdk_x11_event_translator_translate (translator,
|
||||
event_source->display,
|
||||
display,
|
||||
xevent);
|
||||
}
|
||||
}
|
||||
@ -386,11 +375,6 @@ gdk_event_source_translate_event (GdkEventSource *event_source,
|
||||
handle_touch_synthetic_crossing (event);
|
||||
}
|
||||
|
||||
#ifdef HAVE_XGENERICEVENTS
|
||||
if (xevent->type == GenericEvent)
|
||||
XFreeEventData (dpy, &xevent->xcookie);
|
||||
#endif
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
@ -449,11 +433,6 @@ _gdk_x11_display_queue_events (GdkDisplay *display)
|
||||
GdkEvent *event;
|
||||
XEvent xevent;
|
||||
Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
|
||||
GdkEventSource *event_source;
|
||||
GdkX11Display *display_x11;
|
||||
|
||||
display_x11 = GDK_X11_DISPLAY (display);
|
||||
event_source = (GdkEventSource *) display_x11->event_source;
|
||||
|
||||
while (!_gdk_event_queue_find_first (display) && XPending (xdisplay))
|
||||
{
|
||||
@ -469,9 +448,26 @@ _gdk_x11_display_queue_events (GdkDisplay *display)
|
||||
continue;
|
||||
}
|
||||
|
||||
event = gdk_event_source_translate_event (event_source, &xevent);
|
||||
#ifdef HAVE_XGENERICEVENTS
|
||||
/* Get cookie data here so it's available
|
||||
* to every event translator and event filter.
|
||||
*/
|
||||
if (xevent.type == GenericEvent)
|
||||
XGetEventData (xdisplay, &xevent.xcookie);
|
||||
#endif
|
||||
|
||||
if (event)
|
||||
g_signal_emit_by_name (display, "translate-event", &xevent, &event);
|
||||
|
||||
#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;
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
#define __GDK_X11_EVENT_SOURCE_H__
|
||||
|
||||
#include "gdkeventtranslator.h"
|
||||
#include "gdkx11display.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@ -37,6 +38,9 @@ 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,
|
||||
const XEvent *xevent);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user