[gtk+/xi2] Implement per-device motion hints emulation.
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/xi2] Implement per-device motion hints emulation.
- Date: Thu, 18 Feb 2010 01:51:31 +0000 (UTC)
commit a689e6624a07cd84698d458865534ffa08ef99ef
Author: Carlos Garnacho <carlosg gnome org>
Date: Thu Feb 18 01:30:42 2010 +0100
Implement per-device motion hints emulation.
Most of the points where the motion hint serial was
being updated had a GdkDevice around, so it's been
quite straightforward.
The only point without information about an specific
device was gdk_window_set_events(). In this case all
devices within the window are updated, as any other
device entering the window would have the motion hint
serial updated anyway on crossing events.
gdk/gdkdisplay.c | 24 ++++++++++++++++++------
gdk/gdkdisplay.h | 3 +--
gdk/gdkevents.c | 2 +-
gdk/gdkinternals.h | 3 ++-
gdk/gdkwindow.c | 34 ++++++++++++++++++++++++----------
5 files changed, 46 insertions(+), 20 deletions(-)
---
diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c
index 44e11a2..fee23ae 100644
--- a/gdk/gdkdisplay.c
+++ b/gdk/gdkdisplay.c
@@ -248,6 +248,8 @@ gdk_display_init (GdkDisplay *display)
display->device_hooks = &default_device_hooks;
display->device_grabs = g_hash_table_new (NULL, NULL);
+ display->motion_hint_info = g_hash_table_new_full (NULL, NULL, NULL,
+ (GDestroyNotify) g_free);
display->pointers_info = g_hash_table_new_full (NULL, NULL, NULL,
(GDestroyNotify) free_pointer_info);
@@ -653,11 +655,21 @@ _gdk_get_sm_client_id (void)
}
void
-_gdk_display_enable_motion_hints (GdkDisplay *display)
+_gdk_display_enable_motion_hints (GdkDisplay *display,
+ GdkDevice *device)
{
- gulong serial;
-
- if (display->motion_hint_serial != 0)
+ gulong *device_serial, serial;
+
+ device_serial = g_hash_table_lookup (display->motion_hint_info, device);
+
+ if (!device_serial)
+ {
+ device_serial = g_new0 (gulong, 1);
+ *device_serial = G_MAXULONG;
+ g_hash_table_insert (display->motion_hint_info, device, device_serial);
+ }
+
+ if (*device_serial != 0)
{
serial = _gdk_windowing_window_get_next_serial (display);
/* We might not actually generate the next request, so
@@ -666,8 +678,8 @@ _gdk_display_enable_motion_hints (GdkDisplay *display)
anyway. */
if (serial > 0)
serial--;
- if (serial < display->motion_hint_serial)
- display->motion_hint_serial = serial;
+ if (serial < *device_serial)
+ *device_serial = serial;
}
}
diff --git a/gdk/gdkdisplay.h b/gdk/gdkdisplay.h
index f57fa49..714cac5 100644
--- a/gdk/gdkdisplay.h
+++ b/gdk/gdkdisplay.h
@@ -104,8 +104,7 @@ struct _GdkDisplay
guint double_click_distance; /* Maximum distance between clicks in pixels */
GHashTable *device_grabs;
-
- gulong motion_hint_serial; /* 0 == didn't deliver hinted motion event */
+ GHashTable *motion_hint_info;
/* Hashtable containing a GdkPointerWindowInfo for each device */
GHashTable *pointers_info;
diff --git a/gdk/gdkevents.c b/gdk/gdkevents.c
index 61d5059..d717883 100644
--- a/gdk/gdkevents.c
+++ b/gdk/gdkevents.c
@@ -1041,7 +1041,7 @@ gdk_event_request_motions (const GdkEventMotion *event)
gdk_device_get_state (event->device, event->window, NULL, NULL);
display = gdk_drawable_get_display (event->window);
- _gdk_display_enable_motion_hints (display);
+ _gdk_display_enable_motion_hints (display, event->device);
}
}
diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h
index 07cc7d0..b154c57 100644
--- a/gdk/gdkinternals.h
+++ b/gdk/gdkinternals.h
@@ -625,7 +625,8 @@ gboolean _gdk_display_end_device_grab (GdkDisplay *display,
gboolean _gdk_display_check_grab_ownership (GdkDisplay *display,
GdkDevice *device,
gulong serial);
-void _gdk_display_enable_motion_hints (GdkDisplay *display);
+void _gdk_display_enable_motion_hints (GdkDisplay *display,
+ GdkDevice *device);
GdkPointerWindowInfo * _gdk_display_get_pointer_info (GdkDisplay *display,
GdkDevice *device);
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index 6be4f01..b326886 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -6366,7 +6366,7 @@ gdk_window_get_device_position (GdkWindow *window,
if (mask)
*mask = tmp_mask;
- _gdk_display_enable_motion_hints (display);
+ _gdk_display_enable_motion_hints (display, device);
return child;
}
@@ -7165,7 +7165,15 @@ gdk_window_set_events (GdkWindow *window,
display = gdk_drawable_get_display (window);
if ((private->event_mask & GDK_POINTER_MOTION_HINT_MASK) &&
!(event_mask & GDK_POINTER_MOTION_HINT_MASK))
- _gdk_display_enable_motion_hints (display);
+ {
+ GList *devices = private->devices_inside;
+
+ while (devices)
+ {
+ _gdk_display_enable_motion_hints (display, (GdkDevice *) devices->data);
+ devices = devices->next;
+ }
+ }
private->event_mask = event_mask;
@@ -7235,7 +7243,7 @@ gdk_window_set_device_events (GdkWindow *window,
display = gdk_drawable_get_display (window);
if ((private->event_mask & GDK_POINTER_MOTION_HINT_MASK) &&
!(event_mask & GDK_POINTER_MOTION_HINT_MASK))
- _gdk_display_enable_motion_hints (display);
+ _gdk_display_enable_motion_hints (display, device);
if (G_UNLIKELY (!private->device_events))
private->device_events = g_hash_table_new (NULL, NULL);
@@ -10096,7 +10104,7 @@ _gdk_display_set_window_under_pointer (GdkDisplay *display,
update_cursor (display, device);
}
- _gdk_display_enable_motion_hints (display);
+ _gdk_display_enable_motion_hints (display, device);
}
/*
@@ -10625,13 +10633,18 @@ proxy_pointer_event (GdkDisplay *display,
if (event_win &&
(evmask & GDK_POINTER_MOTION_HINT_MASK))
{
- if (display->motion_hint_serial != 0 &&
- serial < display->motion_hint_serial)
+ gulong *device_serial;
+
+ device_serial = g_hash_table_lookup (display->motion_hint_info, device);
+
+ if (!device_serial ||
+ (*device_serial != 0 &&
+ serial < *device_serial))
event_win = NULL; /* Ignore event */
else
{
is_hint = TRUE;
- display->motion_hint_serial = G_MAXULONG;
+ *device_serial = G_MAXULONG;
}
}
@@ -11038,9 +11051,10 @@ _gdk_windowing_got_event (GdkDisplay *display,
event->type == GDK_BUTTON_RELEASE)
pointer_info->button = event->button.button;
- if (pointer_info->state != old_state ||
- pointer_info->button != old_button)
- _gdk_display_enable_motion_hints (display);
+ if (device &&
+ (pointer_info->state != old_state ||
+ pointer_info->button != old_button))
+ _gdk_display_enable_motion_hints (display, device);
unlink_event = FALSE;
if (is_motion_type (event->type))
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]