diff --git a/src/ui/ui.c b/src/ui/ui.c index 6cf90303b..922c4b7ca 100644 --- a/src/ui/ui.c +++ b/src/ui/ui.c @@ -30,6 +30,7 @@ #include "menu.h" #include "core.h" #include "theme-private.h" +#include "input-events.h" #include "inlinepixbufs.h" @@ -102,27 +103,30 @@ maybe_redirect_mouse_event (XEvent *xevent) { GdkDisplay *gdisplay; GdkDeviceManager *gmanager; + GdkDevice *gdevice; MetaUI *ui; GdkEvent *gevent; GdkWindow *gdk_window; Window window; + MetaDisplay *display; + MetaDevice *device; + gdouble x, y, x_root, y_root; + guint evtype, n_button; + Time evtime; - switch (xevent->type) - { - case ButtonPress: - case ButtonRelease: - window = xevent->xbutton.window; - break; - case MotionNotify: - window = xevent->xmotion.window; - break; - case EnterNotify: - case LeaveNotify: - window = xevent->xcrossing.window; - break; - default: - return FALSE; - } + display = meta_display_for_x_display (xevent->xany.display); + + if (!meta_input_event_get_type (display, xevent, &evtype)) + return FALSE; + + if (evtype != ButtonPress && + evtype != ButtonRelease && + evtype != EnterNotify && + evtype != LeaveNotify && + evtype != MotionNotify) + return FALSE; + + window = meta_input_event_get_window (display, xevent); gdisplay = gdk_x11_lookup_xdisplay (xevent->xany.display); ui = g_object_get_data (G_OBJECT (gdisplay), "meta-ui"); @@ -133,18 +137,32 @@ maybe_redirect_mouse_event (XEvent *xevent) if (gdk_window == NULL) return FALSE; + device = meta_input_event_get_device (display, xevent); + + if (!device) + return FALSE; + + gmanager = gdk_display_get_device_manager (gdisplay); + gdevice = gdk_x11_device_manager_lookup (gmanager, + meta_device_get_id (device)); + /* If GDK already thinks it has a grab, we better let it see events; this * is the menu-navigation case and events need to get sent to the appropriate * (client-side) subwindow for individual menu items. */ - if (gdk_display_pointer_is_grabbed (gdisplay)) + if (gdk_display_device_is_grabbed (gdisplay, gdevice)) return FALSE; - switch (xevent->type) + evtime = meta_input_event_get_time (display, xevent); + meta_input_event_get_coordinates (display, xevent, + &x, &y, &x_root, &y_root); + switch (evtype) { case ButtonPress: case ButtonRelease: - if (xevent->type == ButtonPress) + meta_input_event_get_button (display, xevent, &n_button); + + if (evtype == ButtonPress) { GtkSettings *settings = gtk_settings_get_default (); int double_click_time; @@ -155,11 +173,11 @@ maybe_redirect_mouse_event (XEvent *xevent) "gtk-double-click-distance", &double_click_distance, NULL); - if (xevent->xbutton.button == ui->button_click_number && - xevent->xbutton.window == ui->button_click_window && - xevent->xbutton.time < ui->button_click_time + double_click_time && - ABS (xevent->xbutton.x - ui->button_click_x) <= double_click_distance && - ABS (xevent->xbutton.y - ui->button_click_y) <= double_click_distance) + if (n_button == ui->button_click_number && + window == ui->button_click_window && + evtime < ui->button_click_time + double_click_time && + ABS ((int) x - ui->button_click_x) <= double_click_distance && + ABS ((int) y - ui->button_click_y) <= double_click_distance) { gevent = gdk_event_new (GDK_2BUTTON_PRESS); @@ -168,11 +186,11 @@ maybe_redirect_mouse_event (XEvent *xevent) else { gevent = gdk_event_new (GDK_BUTTON_PRESS); - ui->button_click_number = xevent->xbutton.button; - ui->button_click_window = xevent->xbutton.window; - ui->button_click_time = xevent->xbutton.time; - ui->button_click_x = xevent->xbutton.x; - ui->button_click_y = xevent->xbutton.y; + ui->button_click_number = n_button; + ui->button_click_window = window; + ui->button_click_time = evtime; + ui->button_click_x = (int) x; + ui->button_click_y = (int) y; } } else @@ -181,12 +199,12 @@ maybe_redirect_mouse_event (XEvent *xevent) } gevent->button.window = g_object_ref (gdk_window); - gevent->button.button = xevent->xbutton.button; - gevent->button.time = xevent->xbutton.time; - gevent->button.x = xevent->xbutton.x; - gevent->button.y = xevent->xbutton.y; - gevent->button.x_root = xevent->xbutton.x_root; - gevent->button.y_root = xevent->xbutton.y_root; + gevent->button.button = n_button; + gevent->button.time = evtime; + gevent->button.x = x; + gevent->button.y = y; + gevent->button.x_root = x_root; + gevent->button.y_root = y_root; break; case MotionNotify: @@ -196,10 +214,10 @@ maybe_redirect_mouse_event (XEvent *xevent) break; case EnterNotify: case LeaveNotify: - gevent = gdk_event_new (xevent->type == EnterNotify ? GDK_ENTER_NOTIFY : GDK_LEAVE_NOTIFY); + gevent = gdk_event_new (evtype == EnterNotify ? GDK_ENTER_NOTIFY : GDK_LEAVE_NOTIFY); gevent->crossing.window = g_object_ref (gdk_window); - gevent->crossing.x = xevent->xcrossing.x; - gevent->crossing.y = xevent->xcrossing.y; + gevent->crossing.x = x; + gevent->crossing.y = y; break; default: g_assert_not_reached (); @@ -207,8 +225,7 @@ maybe_redirect_mouse_event (XEvent *xevent) } /* If we've gotten here, we've created the gdk_event and should send it on */ - gmanager = gdk_display_get_device_manager (gdisplay); - gdk_event_set_device (gevent, gdk_device_manager_get_client_pointer (gmanager)); + gdk_event_set_device (gevent, gdevice); gtk_main_do_event (gevent); gdk_event_free (gevent);