[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