qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] gtk: Keep the pointer within window during input grab
@ 2014-04-08 12:46 Takashi Iwai
  2014-04-08 22:46 ` Cole Robinson
  2014-04-11 13:07 ` Gerd Hoffmann
  0 siblings, 2 replies; 5+ messages in thread
From: Takashi Iwai @ 2014-04-08 12:46 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann, Anthony Liguori, Cole Robinson

The current code shows annoying behavior where the X pointer can move
out of the window during the input grab in the absolute mode.  Due to
this, the pointer in qemu window looks as if frozen until the real
(invisible) X pointer comes back to the window again.

For avoiding such an unexpected lag, this patch limits the pointer
movement only within the qemu window during the input grab in the
absolute mode.  When the pointer goes out, it's moved back to the
boundary again.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 ui/gtk.c | 51 ++++++++++++++++++++++++++++++---------------------
 1 file changed, 30 insertions(+), 21 deletions(-)

diff --git a/ui/gtk.c b/ui/gtk.c
index 00fbbccb34b9..f87434093946 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -341,19 +341,13 @@ static void gd_refresh(DisplayChangeListener *dcl)
     graphic_hw_update(dcl->con);
 }
 
-#if GTK_CHECK_VERSION(3, 0, 0)
-static void gd_mouse_set(DisplayChangeListener *dcl,
-                         int x, int y, int visible)
+static void gd_warp_pointer(GtkDisplayState *s, int x, int y)
 {
-    GtkDisplayState *s = container_of(dcl, GtkDisplayState, dcl);
+#if GTK_CHECK_VERSION(3, 0, 0)
     GdkDisplay *dpy;
     GdkDeviceManager *mgr;
     gint x_root, y_root;
 
-    if (qemu_input_is_absolute()) {
-        return;
-    }
-
     dpy = gtk_widget_get_display(s->drawing_area);
     mgr = gdk_display_get_device_manager(dpy);
     gdk_window_get_root_coords(gtk_widget_get_window(s->drawing_area),
@@ -361,25 +355,27 @@ static void gd_mouse_set(DisplayChangeListener *dcl,
     gdk_device_warp(gdk_device_manager_get_client_pointer(mgr),
                     gtk_widget_get_screen(s->drawing_area),
                     x_root, y_root);
-}
 #else
+    gint x_root, y_root;
+
+    gdk_window_get_root_coords(gtk_widget_get_window(s->drawing_area),
+                               x, y, &x_root, &y_root);
+    gdk_display_warp_pointer(gtk_widget_get_display(s->drawing_area),
+                             gtk_widget_get_screen(s->drawing_area),
+                             x_root, y_root);
+#endif
+}
+
 static void gd_mouse_set(DisplayChangeListener *dcl,
                          int x, int y, int visible)
 {
     GtkDisplayState *s = container_of(dcl, GtkDisplayState, dcl);
-    gint x_root, y_root;
 
     if (qemu_input_is_absolute()) {
         return;
     }
-
-    gdk_window_get_root_coords(gtk_widget_get_window(s->drawing_area),
-                               x, y, &x_root, &y_root);
-    gdk_display_warp_pointer(gtk_widget_get_display(s->drawing_area),
-                             gtk_widget_get_screen(s->drawing_area),
-                             x_root, y_root);
+    gd_warp_pointer(s, x, y);
 }
-#endif
 
 static void gd_cursor_define(DisplayChangeListener *dcl,
                              QEMUCursor *c)
@@ -627,10 +623,23 @@ static gboolean gd_motion_event(GtkWidget *widget, GdkEventMotion *motion,
     y = (motion->y - my) / s->scale_y;
 
     if (qemu_input_is_absolute()) {
-        if (x < 0 || y < 0 ||
-            x >= surface_width(s->ds) ||
-            y >= surface_height(s->ds)) {
-            return TRUE;
+        int ox = x, oy = y;
+        if (x < 0) {
+            x = 0;
+        } else if (x >= surface_width(s->ds)) {
+            x = surface_width(s->ds) - 1;
+        }
+        if (y < 0) {
+            y = 0;
+        } else if (y >= surface_height(s->ds)) {
+            y = surface_height(s->ds) - 1;
+        }
+        if (ox != x || oy != y) {
+            if (!gd_is_grab_active(s)) {
+                return TRUE;
+            }
+            /* keep the pointer within the drawing area during input grab */
+            gd_warp_pointer(s, x * s->scale_x + mx, y * s->scale_y + my);
         }
         qemu_input_queue_abs(s->dcl.con, INPUT_AXIS_X, x,
                              surface_width(s->ds));
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2014-04-11 21:09 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-04-08 12:46 [Qemu-devel] [PATCH] gtk: Keep the pointer within window during input grab Takashi Iwai
2014-04-08 22:46 ` Cole Robinson
2014-04-11 13:07 ` Gerd Hoffmann
2014-04-11 13:28   ` Takashi Iwai
2014-04-11 21:08     ` Cole Robinson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).