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

Marc-André Lureau mlureau at redhat.com
Thu Oct 9 02:54:18 PDT 2014


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?

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
> 


More information about the Spice-devel mailing list