All of lore.kernel.org
 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

* Re: [Qemu-devel] [PATCH] gtk: Keep the pointer within window during input grab
  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
  1 sibling, 0 replies; 5+ messages in thread
From: Cole Robinson @ 2014-04-08 22:46 UTC (permalink / raw)
  To: Takashi Iwai, qemu-devel; +Cc: Gerd Hoffmann, Anthony Liguori

On 04/08/2014 08:46 AM, Takashi Iwai wrote:
> 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(-)
> 

Tested with gtk2 and gtk3

Tested-by: Cole Robinson <crobinso@redhat.com>
Reviewed-by: Cole Robinson <crobinso@redhat.com>

- Cole

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

* Re: [Qemu-devel] [PATCH] gtk: Keep the pointer within window during input grab
  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
  1 sibling, 1 reply; 5+ messages in thread
From: Gerd Hoffmann @ 2014-04-11 13:07 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: qemu-devel, Anthony Liguori, Cole Robinson

On Di, 2014-04-08 at 14:46 +0200, Takashi Iwai wrote:
> 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.

At least at X11 level it is possible to simply confine the pointer to a
certain window (see "man XGrabPointer").  Then you don't have to warp
the pointer.  Warping the pointer in absolute mode has ugly effects (see
2bda66028b4962c36d4eabe2995edab12df93691).

Other possible solution: Never ever grab the pointer in absolute mode.

cheers,
  Gerd

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

* Re: [Qemu-devel] [PATCH] gtk: Keep the pointer within window during input grab
  2014-04-11 13:07 ` Gerd Hoffmann
@ 2014-04-11 13:28   ` Takashi Iwai
  2014-04-11 21:08     ` Cole Robinson
  0 siblings, 1 reply; 5+ messages in thread
From: Takashi Iwai @ 2014-04-11 13:28 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: qemu-devel, Anthony Liguori, Cole Robinson

At Fri, 11 Apr 2014 15:07:34 +0200,
Gerd Hoffmann wrote:
 
> On Di, 2014-04-08 at 14:46 +0200, Takashi Iwai wrote:
> > 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.
> 
> At least at X11 level it is possible to simply confine the pointer to a
> certain window (see "man XGrabPointer").  Then you don't have to warp
> the pointer.

I have such a vague memory, too, and tried it before my patch, but
couldn't manage to make it working.  The man page describes the
pointer event processing, but it doesn't describe how the pointer
moves.  It's more than a decade when I played with it, so I really
forget how these things work...

>  Warping the pointer in absolute mode has ugly effects (see
> 2bda66028b4962c36d4eabe2995edab12df93691).

What exact effect do we see?  The commit log doesn't give much clue,
and I didn't notice any issue with gtk and qxl, so far.

> Other possible solution: Never ever grab the pointer in absolute mode.

It's sometimes more practical to have a grab mode even in the absolute
mode.  It's a minor requirement, I agree, though.


Takashi

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

* Re: [Qemu-devel] [PATCH] gtk: Keep the pointer within window during input grab
  2014-04-11 13:28   ` Takashi Iwai
@ 2014-04-11 21:08     ` Cole Robinson
  0 siblings, 0 replies; 5+ messages in thread
From: Cole Robinson @ 2014-04-11 21:08 UTC (permalink / raw)
  To: Takashi Iwai, Gerd Hoffmann; +Cc: qemu-devel, Anthony Liguori

On 04/11/2014 09:28 AM, Takashi Iwai wrote:
> At Fri, 11 Apr 2014 15:07:34 +0200,
> Gerd Hoffmann wrote:
>  
>> On Di, 2014-04-08 at 14:46 +0200, Takashi Iwai wrote:
>>> 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.
>>
>> At least at X11 level it is possible to simply confine the pointer to a
>> certain window (see "man XGrabPointer").  Then you don't have to warp
>> the pointer.
> 
> I have such a vague memory, too, and tried it before my patch, but
> couldn't manage to make it working.  The man page describes the
> pointer event processing, but it doesn't describe how the pointer
> moves.  It's more than a decade when I played with it, so I really
> forget how these things work...
> 
>>  Warping the pointer in absolute mode has ugly effects (see
>> 2bda66028b4962c36d4eabe2995edab12df93691).
> 
> What exact effect do we see?  The commit log doesn't give much clue,
> and I didn't notice any issue with gtk and qxl, so far.
> 

With an F20 guest at least, qxl + gtk was unusable, as described here:

https://lists.gnu.org/archive/html/qemu-devel/2014-03/msg02678.html

The mouse would just warp off the UI.

However your patch still preserves the do_mouse_set short circuiting when in
absolute mode, so that issue doesn't resurface.

The -7/-3 pixel offset I mention in the above mail might come into play, but I
actually can't verify it with my F20 vm, since initiating a pointer grab in
absolute mode with qxl makes the pointer entirely invisible. Thought it was
maybe https://lists.gnu.org/archive/html/qemu-devel/2013-12/msg01627.html but
that didn't help any.

- Cole

^ permalink raw reply	[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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.