[Spice-devel] [PATCH spice-gtk 5/5] Release our keyboard grab when we're going to invoke the usb acl helper

Marc-André Lureau marcandre.lureau at gmail.com
Tue Nov 15 11:38:06 PST 2011


ack

On Tue, Nov 15, 2011 at 4:31 PM, Hans de Goede <hdegoede at redhat.com> wrote:
> The usb acl helper asks policykit, which may want to interact with the
> user through the policykit agent, which wants to grab the keyboard, if
> we then have the keyboard grabbed, the agent says authentication has failed,
> policykit rejects the helper opening up the acl and usbredir won't work.
>
> Unfortunately the only way to work around this is to temporarily release our
> own keyboard grab, not pretty but as discussed on irc, this is the "best"
> solution.
>
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
> ---
>  gtk/channel-usbredir.c   |    4 ++++
>  gtk/spice-session-priv.h |    4 ++++
>  gtk/spice-session.c      |   25 +++++++++++++++++++++++++
>  gtk/spice-widget-priv.h  |    1 +
>  gtk/spice-widget.c       |   22 ++++++++++++++++++++++
>  5 files changed, 56 insertions(+), 0 deletions(-)
>
> diff --git a/gtk/channel-usbredir.c b/gtk/channel-usbredir.c
> index f64ab0e..458a29d 100644
> --- a/gtk/channel-usbredir.c
> +++ b/gtk/channel-usbredir.c
> @@ -180,6 +180,8 @@ static void spice_usbredir_channel_open_acl_cb(
>
>     spice_usb_acl_helper_close_acl(priv->acl_helper);
>     g_clear_object(&priv->acl_helper);
> +    g_object_set(spice_channel_get_session(SPICE_CHANNEL(channel)),
> +                 "inhibit-keyboard-grab", (gboolean)FALSE, NULL);
>
>     g_simple_async_result_complete_in_idle(priv->result);
>     g_clear_object(&priv->result);
> @@ -220,6 +222,8 @@ void spice_usbredir_channel_connect(SpiceUsbredirChannel *channel,
>  #if USE_POLKIT
>         priv->result = result;
>         priv->acl_helper = spice_usb_acl_helper_new();
> +        g_object_set(spice_channel_get_session(SPICE_CHANNEL(channel)),
> +                     "inhibit-keyboard-grab", (gboolean)TRUE, NULL);
>         spice_usb_acl_helper_open_acl(priv->acl_helper,
>                                       g_usb_device_get_bus(device),
>                                       g_usb_device_get_address(device),
> diff --git a/gtk/spice-session-priv.h b/gtk/spice-session-priv.h
> index 8f10407..963735b 100644
> --- a/gtk/spice-session-priv.h
> +++ b/gtk/spice-session-priv.h
> @@ -59,6 +59,10 @@ struct _SpiceSessionPrivate {
>     /* whether to enable USB redirection */
>     gboolean          usbredir;
>
> +    /* Set when a usbredir channel has requested the keyboard grab to be
> +       temporarily released (because it is going to invoke policykit) */
> +    gboolean          inhibit_keyboard_grab;
> +
>     GStrv             disable_effects;
>     gint              color_depth;
>
> diff --git a/gtk/spice-session.c b/gtk/spice-session.c
> index 9e30c74..7e627e7 100644
> --- a/gtk/spice-session.c
> +++ b/gtk/spice-session.c
> @@ -96,6 +96,7 @@ enum {
>     PROP_SMARTCARD_CERTIFICATES,
>     PROP_SMARTCARD_DB,
>     PROP_USBREDIR,
> +    PROP_INHIBIT_KEYBOARD_GRAB,
>     PROP_DISABLE_EFFECTS,
>     PROP_COLOR_DEPTH,
>  };
> @@ -360,6 +361,9 @@ static void spice_session_get_property(GObject    *gobject,
>     case PROP_USBREDIR:
>         g_value_set_boolean(value, s->usbredir);
>         break;
> +    case PROP_INHIBIT_KEYBOARD_GRAB:
> +        g_value_set_boolean(value, s->inhibit_keyboard_grab);
> +        break;
>     case PROP_DISABLE_EFFECTS:
>         g_value_set_boxed(value, s->disable_effects);
>         break;
> @@ -452,6 +456,9 @@ static void spice_session_set_property(GObject      *gobject,
>     case PROP_USBREDIR:
>         s->usbredir = g_value_get_boolean(value);
>         break;
> +    case PROP_INHIBIT_KEYBOARD_GRAB:
> +        s->inhibit_keyboard_grab = g_value_get_boolean(value);
> +        break;
>     case PROP_DISABLE_EFFECTS:
>         g_strfreev(s->disable_effects);
>         s->disable_effects = g_value_dup_boxed(value);
> @@ -798,6 +805,24 @@ static void spice_session_class_init(SpiceSessionClass *klass)
>                           G_PARAM_STATIC_STRINGS));
>
>     /**
> +     * SpiceSession::inhibit-keyboard-grab
> +     *
> +     * This boolean is set by the usbredir channel to indicate to #SpiceDisplay
> +     * that the keyboard grab should be temporarily released, because it is
> +     * going to invoke policykit. It will get reset when the usbredir channel
> +     * is done with polickit.
> +     *
> +     * Since: 0.8
> +     **/
> +    g_object_class_install_property
> +        (gobject_class, PROP_INHIBIT_KEYBOARD_GRAB,
> +         g_param_spec_boolean("inhibit-keyboard-grab",
> +                        "Inhibit Keyboard Grab",
> +                        "Request that SpiceDisplays don't grab the keyboard",
> +                        FALSE,
> +                        G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
> +
> +    /**
>      * SpiceSession::channel-new:
>      * @session: the session that emitted the signal
>      * @channel: the new #SpiceChannel
> diff --git a/gtk/spice-widget-priv.h b/gtk/spice-widget-priv.h
> index a5791a4..a86168d 100644
> --- a/gtk/spice-widget-priv.h
> +++ b/gtk/spice-widget-priv.h
> @@ -46,6 +46,7 @@ struct _SpiceDisplayPrivate {
>
>     /* options */
>     bool                    keyboard_grab_enable;
> +    gboolean                keyboard_grab_inhibit;
>     bool                    mouse_grab_enable;
>     bool                    resize_guest_enable;
>
> diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c
> index cec9aaa..f095130 100644
> --- a/gtk/spice-widget.c
> +++ b/gtk/spice-widget.c
> @@ -222,6 +222,22 @@ static void gtk_session_property_changed(GObject    *gobject,
>     g_object_notify(G_OBJECT(display), g_param_spec_get_name(pspec));
>  }
>
> +static void session_inhibit_keyboard_grab_changed(GObject    *gobject,
> +                                                  GParamSpec *pspec,
> +                                                  gpointer    user_data)
> +{
> +    SpiceDisplay *display = user_data;
> +    SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
> +
> +    g_object_get(d->session, "inhibit-keyboard-grab",
> +                 &d->keyboard_grab_inhibit, NULL);
> +    if (d->keyboard_grab_inhibit) {
> +        try_keyboard_ungrab(display);
> +    } else {
> +        try_keyboard_grab(display);
> +    }
> +}
> +
>  static void spice_display_dispose(GObject *obj)
>  {
>     SpiceDisplay *display = SPICE_DISPLAY(obj);
> @@ -330,6 +346,10 @@ spice_display_constructor(GType                  gtype,
>     g_signal_connect(d->gtk_session, "notify::auto-clipboard",
>                      G_CALLBACK(gtk_session_property_changed), display);
>
> +    g_signal_connect(d->session, "notify::inhibit-keyboard-grab",
> +                     G_CALLBACK(session_inhibit_keyboard_grab_changed),
> +                     display);
> +
>     return obj;
>  }
>
> @@ -414,6 +434,8 @@ static void try_keyboard_grab(SpiceDisplay *display)
>     if (d->keyboard_grab_active)
>         return;
>
> +    if (d->keyboard_grab_inhibit)
> +        return;
>     if (!d->keyboard_grab_enable)
>         return;
>     if (!d->keyboard_have_focus)
> --
> 1.7.7.1
>
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel
>



-- 
Marc-André Lureau


More information about the Spice-devel mailing list