Re: [PATCH spice-gtk v2] Release keyboard grab using keyboard shortcut

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 





On Wed, Nov 12, 2014 at 10:11 AM, Pavel Grunt <pgrunt@xxxxxxxxxx> wrote:
This commit adds the ability to release the keyboard grab when
the release keys (ctrl+alt) are pressed and released. It allows
to use keyboard shortcuts (eg alt+tab, alt+f4) on the client.

The keyboard is grabbed again when the release keys are pressed
and released or when the mouse moves.


There is an issue to retake the grab with the same shortcut, after pressing alt-tab. It works only if pressed 2 times.

It seems to be because the sequence is cancelled in check_for_grab_key(), I haven't investigated further.
 
https://bugs.freedesktop.org/show_bug.cgi?id=85331
---
v2:
 - add missing 'release_keys(display)' calls
---
 gtk/spice-widget-priv.h |  2 ++
 gtk/spice-widget.c      | 51 ++++++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 46 insertions(+), 7 deletions(-)

diff --git a/gtk/spice-widget-priv.h b/gtk/spice-widget-priv.h
index 9c38e2e..0e1f661 100644
--- a/gtk/spice-widget-priv.h
+++ b/gtk/spice-widget-priv.h
@@ -109,6 +109,8 @@ struct _SpiceDisplayPrivate {
     guint                   key_delayed_id;
     SpiceGrabSequence         *grabseq; /* the configured key sequence */
     gboolean                *activeseq; /* the currently pressed keys */
+    gboolean                seq_pressed;
+    gboolean                keyboard_grab_released;
     gint                    mark;
 #ifdef WIN32
     HHOOK                   keyboard_hook;
diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c
index ae11073..aca12fe 100644
--- a/gtk/spice-widget.c
+++ b/gtk/spice-widget.c
@@ -719,6 +719,8 @@ static void try_keyboard_grab(SpiceDisplay *display)
         return;
     if (!d->mouse_have_pointer)
         return;
+    if (d->keyboard_grab_released)
+        return;

     g_return_if_fail(gtk_widget_is_focus(widget));

@@ -1198,6 +1200,9 @@ static void send_key(SpiceDisplay *display, int scancode, SendKeyType type, gboo
     if (d->disable_inputs)
         return;

+    if (d->keyboard_grab_released)
+        return;
+
     i = scancode / 32;
     b = scancode % 32;
     m = (1 << b);
@@ -1259,7 +1264,8 @@ static void release_keys(SpiceDisplay *display)
     }
 }

-static gboolean check_for_grab_key(SpiceDisplay *display, int type, int keyval)
+static gboolean check_for_grab_key(SpiceDisplay *display, int type, int keyval,
+                                   int check_type, int reset_type)
 {
     SpiceDisplayPrivate *d = display->priv;
     int i;
@@ -1267,13 +1273,13 @@ static gboolean check_for_grab_key(SpiceDisplay *display, int type, int keyval)
     if (!d->grabseq->nkeysyms)
         return FALSE;

-    if (type == GDK_KEY_PRESS) {
-        /* Record the new key press */
+    if (type == check_type) {
+        /* Record the new key */
         for (i = 0 ; i < d->grabseq->nkeysyms ; i++)
             if (d->grabseq->keysyms[i] == keyval)
                 d->activeseq[i] = TRUE;

-        /* Return if any key is not pressed */
+        /* Return if any key is missing */
         for (i = 0 ; i < d->grabseq->nkeysyms ; i++)
             if (d->activeseq[i] == FALSE)
                 return FALSE;
@@ -1281,9 +1287,10 @@ static gboolean check_for_grab_key(SpiceDisplay *display, int type, int keyval)
         /* resets the whole grab sequence on success */
         memset(d->activeseq, 0, sizeof(gboolean) * d->grabseq->nkeysyms);
         return TRUE;
-    } else if (type == GDK_KEY_RELEASE) {
-        /* Any key release resets the whole grab sequence */
+    } else if (type == reset_type) {
+        /* reset key event type resets the whole grab sequence */
         memset(d->activeseq, 0, sizeof(gboolean) * d->grabseq->nkeysyms);
+        d->seq_pressed = FALSE;
         return FALSE;
     } else
         g_warn_if_reached();
@@ -1291,6 +1298,16 @@ static gboolean check_for_grab_key(SpiceDisplay *display, int type, int keyval)
     return FALSE;
 }

+static gboolean check_for_grab_key_pressed(SpiceDisplay *display, int type, int keyval)
+{
+    return check_for_grab_key(display, type, keyval, GDK_KEY_PRESS, GDK_KEY_RELEASE);
+}
+
+static gboolean check_for_grab_key_released(SpiceDisplay *display, int type, int keyval)
+{
+    return check_for_grab_key(display, type, keyval, GDK_KEY_RELEASE, GDK_KEY_PRESS);
+}
+
 static void update_display(SpiceDisplay *display)
 {
 #ifdef G_OS_WIN32
@@ -1321,7 +1338,7 @@ static gboolean key_event(GtkWidget *widget, GdkEventKey *key)
             __FUNCTION__, key->type == GDK_KEY_PRESS ? "press" : "release",
             key->hardware_keycode, key->state, key->group, key->is_modifier);

-    if (check_for_grab_key(display, key->type, key->keyval)) {
+    if (!d->seq_pressed && check_for_grab_key_pressed(display, key->type, key->keyval)) {
         g_signal_emit(widget, signals[SPICE_DISPLAY_GRAB_KEY_PRESSED], 0);

         if (d->mouse_mode == SPICE_MOUSE_MODE_SERVER) {
@@ -1330,6 +1347,17 @@ static gboolean key_event(GtkWidget *widget, GdkEventKey *key)
             else
                 try_mouse_grab(display);
         }
+        d->seq_pressed = TRUE;
+    } else if (d->seq_pressed && check_for_grab_key_released(display, key->type, key->keyval)) {
+        release_keys(display);
+        if (!d->keyboard_grab_released) {
+            d->keyboard_grab_released = TRUE;
+            try_keyboard_ungrab(display);
+        } else {
+            d->keyboard_grab_released = FALSE;
+            try_keyboard_grab(display);
+        }
+        d->seq_pressed = FALSE;
     }

     if (!d->inputs)
@@ -1562,6 +1590,15 @@ static gboolean motion_event(GtkWidget *widget, GdkEventMotion *motion)
     if (d->disable_inputs)
         return true;

+    if (d->seq_pressed)
+        d->seq_pressed = FALSE;

You could set it unconditionaly
 
+
+    if (d->keyboard_grab_released) {
+        d->keyboard_grab_released = FALSE;
+        release_keys(display);
+        try_keyboard_grab(display);
+    }
+
     spicex_transform_input (display, motion->x, motion->y, &x, &y);

     switch (d->mouse_mode) {
--
1.9.3

_______________________________________________
Spice-devel mailing list
Spice-devel@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/spice-devel


looks good otherwise

--
Marc-André Lureau
_______________________________________________
Spice-devel mailing list
Spice-devel@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/spice-devel

[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]     [Monitors]