The cursor is grabbed/ungrabbed automatically by spice-gtk, this patch allows releasing the cursor in the client mouse mode with a keyboard shortcut. --- gtk/spice-widget-priv.h | 1 + gtk/spice-widget.c | 57 ++++++++++++++++++++++++++++++------------------- 2 files changed, 36 insertions(+), 22 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..bbbcdf9 100644 --- a/gtk/spice-widget.c +++ b/gtk/spice-widget.c @@ -945,14 +945,20 @@ static void try_mouse_grab(SpiceDisplay *display) 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; + g_return_if_fail(gtk_widget_is_focus(GTK_WIDGET(display))); + 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; } @@ -1001,8 +1007,9 @@ static void try_mouse_ungrab(SpiceDisplay *display) #ifdef G_OS_WIN32 ClipCursor(NULL); #endif - set_mouse_accel(display, TRUE); - + if (d->mouse_mode == SPICE_MOUSE_MODE_SERVER) { + set_mouse_accel(display, TRUE); + } d->mouse_grab_active = false; g_signal_emit(display, signals[SPICE_DISPLAY_MOUSE_GRAB], 0, false); @@ -1307,12 +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,6 +1408,9 @@ 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_mouse_grab(display); try_keyboard_grab(display); update_display(display); @@ -1415,10 +1424,8 @@ 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_mouse_ungrab(display); try_keyboard_ungrab(display); return true; @@ -1454,6 +1461,7 @@ static gboolean focus_out_event(GtkWidget *widget, GdkEventFocus *focus G_GNUC_U SpiceDisplayPrivate *d = display->priv; SPICE_DEBUG("%s", __FUNCTION__); + update_display(NULL); /* @@ -1550,7 +1558,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 +1637,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 +2499,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@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel