[Spice-devel] [PATCH spice-gtk 5/5] widget: differentiate key press & release from press only events

Christophe Fergeau cfergeau at redhat.com
Thu Aug 16 01:58:42 PDT 2012


I haven't looked at the patch, but the log has some typos:

On Wed, Aug 15, 2012 at 10:59:30PM +0300, Marc-André Lureau wrote:
> Until now, Spice clients only sent seperate key events for press and

separate

> release. But this may result in unwanted key repeatition from guest VM

repetition

> side. It seems OSes have various implementation. While MS Windows rely

implementations, relies

> on hardware key repeats (which are several sequential press events),
> otoh, X11 uses software key repeat (although not Linux keyboard/VT by

'repeats' maybe

> default).
> 
> We can't easily disable guest side repeaters, as it may be enforced by
> other components (a X11 client can adjust each key individually, or
> the desktop settings may change it etc.). Neither can we rely only on
> guest software repeater as Windows doesn't seem to have one by
> default, so we need to keep sending multiple press events as of today.
> 
> It seems a nice way to improve the situation is to send a single
> "press&release" key event when the user released the key within a
> short delay. If the key is pressed for longer, we keep the exisiting

existing

> behaviour which has been working pretty well so far, sending seperate

separate


Christophe

> "press", then repeatedly "press", and an ending "release" event.
> ---
>  gtk/spice-widget-priv.h |    2 ++
>  gtk/spice-widget.c      |   76 +++++++++++++++++++++++++++++++++++++++++++----
>  spice-common            |    2 +-
>  3 files changed, 73 insertions(+), 7 deletions(-)
> 
> diff --git a/gtk/spice-widget-priv.h b/gtk/spice-widget-priv.h
> index 97c6489..87d1de9 100644
> --- a/gtk/spice-widget-priv.h
> +++ b/gtk/spice-widget-priv.h
> @@ -106,6 +106,8 @@ struct _SpiceDisplayPrivate {
>      const guint16 const     *keycode_map;
>      size_t                  keycode_maplen;
>      uint32_t                key_state[512 / 32];
> +    int                     key_delayed_scancode;
> +    guint                   key_delayed_id;
>      SpiceGrabSequence         *grabseq; /* the configured key sequence */
>      gboolean                *activeseq; /* the currently pressed keys */
>      gint                    mark;
> diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c
> index 8cb7abb..d2b00f7 100644
> --- a/gtk/spice-widget.c
> +++ b/gtk/spice-widget.c
> @@ -393,6 +393,11 @@ static void spice_display_dispose(GObject *obj)
>      g_clear_object(&d->session);
>      d->gtk_session = NULL;
>  
> +    if (d->key_delayed_id) {
> +        g_source_remove(d->key_delayed_id);
> +        d->key_delayed_id = 0;
> +    }
> +
>      G_OBJECT_CLASS(spice_display_parent_class)->dispose(obj);
>  }
>  
> @@ -994,6 +999,40 @@ typedef enum {
>      SEND_KEY_RELEASE,
>  } SendKeyType;
>  
> +static void key_press_and_release(SpiceDisplay *display)
> +{
> +    SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
> +
> +    if (d->key_delayed_scancode == 0)
> +        return;
> +
> +    spice_inputs_key_press_and_release(d->inputs, d->key_delayed_scancode);
> +    d->key_delayed_scancode = 0;
> +
> +    if (d->key_delayed_id) {
> +        g_source_remove(d->key_delayed_id);
> +        d->key_delayed_id = 0;
> +    }
> +}
> +
> +static gboolean key_press_delayed(gpointer data)
> +{
> +    SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(data);
> +
> +    if (d->key_delayed_scancode == 0)
> +        goto end;
> +
> +    spice_inputs_key_press(d->inputs, d->key_delayed_scancode);
> +    d->key_delayed_scancode = 0;
> +
> +    if (d->key_delayed_id)
> +        g_source_remove(d->key_delayed_id);
> +
> +end:
> +    d->key_delayed_id = 0;
> +    return FALSE;
> +}
> +
>  static void send_key(SpiceDisplay *display, int scancode, SendKeyType type, gboolean press_delayed)
>  {
>      SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
> @@ -1010,15 +1049,40 @@ static void send_key(SpiceDisplay *display, int scancode, SendKeyType type, gboo
>      m = (1 << b);
>      g_return_if_fail(i < SPICE_N_ELEMENTS(d->key_state));
>  
> -    if (down) {
> -        spice_inputs_key_press(d->inputs, scancode);
> +    switch (type) {
> +    case SEND_KEY_PRESS:
> +        /* ensure delayed key is pressed before any new input event */
> +        key_press_delayed(display);
> +
> +        if (press_delayed &&
> +            d->keypress_delay != 0 &&
> +            !(d->key_state[i] & m)) {
> +            g_warn_if_fail(d->key_delayed_id == 0);
> +            d->key_delayed_id = g_timeout_add(d->keypress_delay, key_press_delayed, display);
> +            d->key_delayed_scancode = scancode;
> +        } else
> +            spice_inputs_key_press(d->inputs, scancode);
> +
>          d->key_state[i] |= m;
> -    } else {
> -        if (!(d->key_state[i] & m)) {
> -            return;
> +        break;
> +
> +    case SEND_KEY_RELEASE:
> +        if (!(d->key_state[i] & m))
> +            break;
> +
> +        if (d->key_delayed_scancode == scancode)
> +            key_press_and_release(display);
> +        else {
> +            /* ensure delayed key is pressed before other key are released */
> +            key_press_delayed(display);
> +            spice_inputs_key_release(d->inputs, scancode);
>          }
> -        spice_inputs_key_release(d->inputs, scancode);
> +
>          d->key_state[i] &= ~m;
> +        break;
> +
> +    default:
> +        g_warn_if_reached();
>      }
>  }
>  
> diff --git a/spice-common b/spice-common
> index c2adbb0..31f1bff 160000
> --- a/spice-common
> +++ b/spice-common
> @@ -1 +1 @@
> -Subproject commit c2adbb00dc0b29de0fe297f241fb0efeb4a81510
> +Subproject commit 31f1bff472da61ba07121ed31536c4af864c4a8f
> -- 
> 1.7.10.4
> 
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/spice-devel/attachments/20120816/c0d7687a/attachment.pgp>


More information about the Spice-devel mailing list