[Spice-devel] [spice-gtk PATCH v2] Ability to release the cursor with a keyboard shortcut

David Jaša djasa at redhat.com
Fri Oct 10 02:42:16 PDT 2014


On Čt, 2014-10-09 at 05:54 -0400, Marc-André Lureau wrote:
> Hi,
> 
> ----- Original Message -----
> > The cursor is grabbed/ungrabbed automatically by spice-gtk,
> > this patch allows releasing the cursor in the client mouse mode
> > with a keyboard shortcut.
> 
> Could you describe the issue you have with the current behaviour, or the use case?

Keyboard navigation. Work in guest -> release cursor -> alt-tab to a
different client window.

David

> 
> thanks
>  
> > ---
> > v2:
> >  - fix crash on vm shutdown
> > 
> >  gtk/spice-widget-priv.h |  1 +
> >  gtk/spice-widget.c      | 68
> >  +++++++++++++++++++++++++++++--------------------
> >  2 files changed, 42 insertions(+), 27 deletions(-)
> > 
> > diff --git a/gtk/spice-widget-priv.h b/gtk/spice-widget-priv.h
> > index 597ce10..c5960bd 100644
> > --- a/gtk/spice-widget-priv.h
> > +++ b/gtk/spice-widget-priv.h
> > @@ -92,6 +92,7 @@ struct _SpiceDisplayPrivate {
> >      enum SpiceMouseMode     mouse_mode;
> >      int                     mouse_grab_active;
> >      bool                    mouse_have_pointer;
> > +    gboolean                cursor_released;
> >      GdkCursor               *mouse_cursor;
> >      GdkPixbuf               *mouse_pixbuf;
> >      GdkPoint                mouse_hotspot;
> > diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c
> > index 1220030..5a14236 100644
> > --- a/gtk/spice-widget.c
> > +++ b/gtk/spice-widget.c
> > @@ -916,8 +916,11 @@ static void update_mouse_pointer(SpiceDisplay *display)
> >  
> >      switch (d->mouse_mode) {
> >      case SPICE_MOUSE_MODE_CLIENT:
> > -        if (gdk_window_get_cursor(window) != d->mouse_cursor)
> > +        if (d->cursor_released) {
> > +            gdk_window_set_cursor(window, NULL);
> > +        } else if (gdk_window_get_cursor(window) != d->mouse_cursor) {
> >              gdk_window_set_cursor(window, d->mouse_cursor);
> > +        }
> >          break;
> >      case SPICE_MOUSE_MODE_SERVER:
> >          if (gdk_window_get_cursor(window) != NULL)
> > @@ -940,19 +943,21 @@ static void try_mouse_grab(SpiceDisplay *display)
> >  
> >      if (!d->mouse_have_pointer)
> >          return;
> > -    if (!d->keyboard_have_focus)
> > -        return;
> >  
> >      if (!d->mouse_grab_enable)
> >          return;
> > -    if (d->mouse_mode != SPICE_MOUSE_MODE_SERVER)
> > -        return;
> >      if (d->mouse_grab_active)
> >          return;
> >  
> > -    if (do_pointer_grab(display) != GDK_GRAB_SUCCESS)
> > -        return;
> > -
> > +    if (d->mouse_mode == SPICE_MOUSE_MODE_SERVER) {
> > +        if (do_pointer_grab(display) != GDK_GRAB_SUCCESS)
> > +            return;
> > +    } else {
> > +        try_keyboard_grab(display);
> > +        d->mouse_grab_active = true;
> > +        g_signal_emit(display, signals[SPICE_DISPLAY_MOUSE_GRAB], 0, true);
> > +    }
> > +    d->cursor_released = false;
> >      d->mouse_last_x = -1;
> >      d->mouse_last_y = -1;
> >  }
> > @@ -996,13 +1001,14 @@ static void try_mouse_ungrab(SpiceDisplay *display)
> >      if (!d->mouse_grab_active)
> >          return;
> >  
> > -    gdk_pointer_ungrab(GDK_CURRENT_TIME);
> >      gtk_grab_remove(GTK_WIDGET(display));
> > +    if (d->mouse_mode == SPICE_MOUSE_MODE_SERVER &&
> > gdk_pointer_is_grabbed()) {
> > +        gdk_pointer_ungrab(GDK_CURRENT_TIME);
> >  #ifdef G_OS_WIN32
> > -    ClipCursor(NULL);
> > +        ClipCursor(NULL);
> >  #endif
> > -    set_mouse_accel(display, TRUE);
> > -
> > +        set_mouse_accel(display, TRUE);
> > +    }
> >      d->mouse_grab_active = false;
> >  
> >      g_signal_emit(display, signals[SPICE_DISPLAY_MOUSE_GRAB], 0, false);
> > @@ -1308,11 +1314,11 @@ static gboolean key_event(GtkWidget *widget,
> > GdkEventKey *key)
> >      if (check_for_grab_key(display, key->type, key->keyval)) {
> >          g_signal_emit(widget, signals[SPICE_DISPLAY_GRAB_KEY_PRESSED], 0);
> >  
> > -        if (d->mouse_mode == SPICE_MOUSE_MODE_SERVER) {
> > -            if (d->mouse_grab_active)
> > -                try_mouse_ungrab(display);
> > -            else
> > -                try_mouse_grab(display);
> > +        if (d->mouse_grab_active) {
> > +            spice_display_mouse_ungrab(display);
> > +            try_keyboard_ungrab(display);
> > +        } else {
> > +            try_mouse_grab(display);
> >          }
> >      }
> >  
> > @@ -1402,7 +1408,10 @@ static gboolean enter_event(GtkWidget *widget,
> > GdkEventCrossing *crossing G_GNUC
> >      SPICE_DEBUG("%s", __FUNCTION__);
> >  
> >      d->mouse_have_pointer = true;
> > +    if (d->cursor_released)
> > +        return true;
> >      try_keyboard_grab(display);
> > +    try_mouse_grab(display);
> >      update_display(display);
> >  
> >      return true;
> > @@ -1415,11 +1424,9 @@ static gboolean leave_event(GtkWidget *widget,
> > GdkEventCrossing *crossing G_GNUC
> >  
> >      SPICE_DEBUG("%s", __FUNCTION__);
> >  
> > -    if (d->mouse_grab_active)
> > -        return true;
> > -
> >      d->mouse_have_pointer = false;
> >      try_keyboard_ungrab(display);
> > +    try_mouse_ungrab(display);
> >  
> >      return true;
> >  }
> > @@ -1442,6 +1449,8 @@ static gboolean focus_in_event(GtkWidget *widget,
> > GdkEventFocus *focus G_GNUC_UN
> >      if (!d->disable_inputs)
> >          spice_gtk_session_sync_keyboard_modifiers(d->gtk_session);
> >      update_keyboard_focus(display, true);
> > +    if (d->cursor_released)
> > +        return true;
> >      try_keyboard_grab(display);
> >      update_display(display);
> >  
> > @@ -1550,7 +1559,8 @@ static gboolean motion_event(GtkWidget *widget,
> > GdkEventMotion *motion)
> >  
> >      switch (d->mouse_mode) {
> >      case SPICE_MOUSE_MODE_CLIENT:
> > -        if (x >= 0 && x < d->area.width &&
> > +        if (d->mouse_grab_active &&
> > +            x >= 0 && x < d->area.width &&
> >              y >= 0 && y < d->area.height) {
> >              spice_inputs_position(d->inputs, x, y, get_display_id(display),
> >                                    button_mask_gdk_to_spice(motion->state));
> > @@ -1628,12 +1638,11 @@ static gboolean button_event(GtkWidget *widget,
> > GdkEventButton *button)
> >      }
> >  
> >      gtk_widget_grab_focus(widget);
> > -    if (d->mouse_mode == SPICE_MOUSE_MODE_SERVER) {
> > -        if (!d->mouse_grab_active) {
> > -            try_mouse_grab(display);
> > -            return true;
> > -        }
> > -    } else
> > +    if (!d->mouse_grab_active) {
> > +        try_mouse_grab(display);
> > +        return true;
> > +    }
> > +    if (d->mouse_mode == SPICE_MOUSE_MODE_CLIENT)
> >          /* allow to drag and drop between windows/displays:
> >  
> >             By default, X (and other window system) do a pointer grab
> > @@ -2491,9 +2500,14 @@ SpiceDisplay*
> > spice_display_new_with_monitor(SpiceSession *session, gint channel
> >   **/
> >  void spice_display_mouse_ungrab(SpiceDisplay *display)
> >  {
> > +    SpiceDisplayPrivate *d;
> > +
> >      g_return_if_fail(SPICE_IS_DISPLAY(display));
> >  
> > +    d = display->priv;
> > +
> >      try_mouse_ungrab(display);
> > +    d->cursor_released = true;
> >  }
> >  
> >  /**
> > --
> > 1.9.3
> > 
> > _______________________________________________
> > Spice-devel mailing list
> > Spice-devel at lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/spice-devel
> > 
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel




More information about the Spice-devel mailing list