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

Marc-André Lureau mlureau at redhat.com
Fri Oct 10 02:49:47 PDT 2014



----- Original Message -----
> 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.

How do you release (keyboard btw)? If there is a global binding for that?
What if the guest also use  those keys?
should it pass the key pressed to guest too?

Currently this use case is covered by move the mouse over the toolbar and
press alt-tab. Do we need a second way that would prevent guest from
having full keyboard input without conflicts?
 
> 
> 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
> 
> 
> _______________________________________________
> 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