--- gtk/spice-widget-priv.h | 1 + gtk/spice-widget.c | 88 ++++++++++++++++++++++++++++++++++++++-------- gtk/spicy.c | 6 +++ 3 files changed, 79 insertions(+), 16 deletions(-)
diff --git a/gtk/spice-widget-priv.h b/gtk/spice-widget-priv.h index a86168d..bd5eec6 100644 --- a/gtk/spice-widget-priv.h +++ b/gtk/spice-widget-priv.h @@ -62,6 +62,7 @@ struct _SpiceDisplayPrivate { bool convert; bool have_mitshm; gboolean allow_scaling; + gboolean disable_inputs; /* TODO: make a display object instead? */ #ifdef WITH_X11 diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c index 0edc70f..816a3e2 100644 --- a/gtk/spice-widget.c +++ b/gtk/spice-widget.c @@ -86,6 +86,7 @@ enum { PROP_RESIZE_GUEST, PROP_AUTO_CLIPBOARD, PROP_SCALING, + PROP_DISABLE_INPUTS, }; /* Signals */ @@ -102,8 +103,10 @@ static guint signals[SPICE_DISPLAY_LAST_SIGNAL]; static HWND focus_window = NULL; #endif +static void update_keyboard_grab(SpiceDisplay *display); static void try_keyboard_grab(SpiceDisplay *display); static void try_keyboard_ungrab(SpiceDisplay *display); +static void update_mouse_grab(SpiceDisplay *display); static void try_mouse_grab(SpiceDisplay *display); static void try_mouse_ungrab(SpiceDisplay *display); static void recalc_geometry(GtkWidget *widget, gboolean set_display); @@ -148,6 +151,9 @@ static void spice_display_get_property(GObject *object, case PROP_SCALING: g_value_set_boolean(value, d->allow_scaling); break; + case PROP_DISABLE_INPUTS: + g_value_set_boolean(value, d->disable_inputs); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -172,17 +178,11 @@ static void spice_display_set_property(GObject *object, break; case PROP_KEYBOARD_GRAB: d->keyboard_grab_enable = g_value_get_boolean(value); - if (d->keyboard_grab_enable) { - try_keyboard_grab(display); - } else { - try_keyboard_ungrab(display); - } + update_keyboard_grab(display); break; case PROP_MOUSE_GRAB: d->mouse_grab_enable = g_value_get_boolean(value); - if (!d->mouse_grab_enable) { - try_mouse_ungrab(display); - } + update_mouse_grab(display); break; case PROP_RESIZE_GUEST: d->resize_guest_enable = g_value_get_boolean(value); @@ -207,6 +207,12 @@ static void spice_display_set_property(GObject *object, g_object_set(d->gtk_session, "auto-clipboard", g_value_get_boolean(value), NULL); break; + case PROP_DISABLE_INPUTS: + d->disable_inputs = g_value_get_boolean(value); + gtk_widget_set_can_focus(GTK_WIDGET(display), !d->disable_inputs); + update_keyboard_grab(display); + update_mouse_grab(display); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -231,11 +237,7 @@ static void session_inhibit_keyboard_grab_changed(GObject *gobject, 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); - } + update_keyboard_grab(display); } static void spice_display_dispose(GObject *obj) @@ -430,14 +432,15 @@ static void try_keyboard_grab(SpiceDisplay *display) if (g_getenv("SPICE_NOGRAB")) return; - - if (d->keyboard_grab_active) + if (d->disable_inputs) return; if (d->keyboard_grab_inhibit) return; if (!d->keyboard_grab_enable) return; + if (d->keyboard_grab_active) + return; if (!d->keyboard_have_focus) return; if (!d->mouse_have_pointer) @@ -463,7 +466,6 @@ static void try_keyboard_grab(SpiceDisplay *display) } } - static void try_keyboard_ungrab(SpiceDisplay *display) { SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); @@ -482,6 +484,18 @@ static void try_keyboard_ungrab(SpiceDisplay *display) g_signal_emit(widget, signals[SPICE_DISPLAY_KEYBOARD_GRAB], 0, false); } +static void update_keyboard_grab(SpiceDisplay *display) +{ + SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); + + if (d->keyboard_grab_enable && + !d->keyboard_grab_inhibit && + !d->disable_inputs) + try_keyboard_grab(display); + else + try_keyboard_ungrab(display); +} + static GdkGrabStatus do_pointer_grab(SpiceDisplay *display) { SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); @@ -553,6 +567,8 @@ static void try_mouse_grab(SpiceDisplay *display) if (g_getenv("SPICE_NOGRAB")) return; + if (d->disable_inputs) + return; if (!d->mouse_grab_enable) return; @@ -614,6 +630,16 @@ static void try_mouse_ungrab(SpiceDisplay *display) g_signal_emit(display, signals[SPICE_DISPLAY_MOUSE_GRAB], 0, false); } +static void update_mouse_grab(SpiceDisplay *display) +{ + SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); + + if (d->mouse_grab_enable && !d->disable_inputs) + update_mouse_pointer(display); + else + try_mouse_ungrab(display); +} + static void recalc_geometry(GtkWidget *widget, gboolean set_display) { SpiceDisplay *display = SPICE_DISPLAY(widget); @@ -746,6 +772,9 @@ static void send_key(SpiceDisplay *display, int scancode, int down) if (!d->inputs) return; + if (d->disable_inputs) + return; + i = scancode / 32; b = scancode % 32; m = (1 << b); @@ -991,6 +1020,8 @@ static gboolean motion_event(GtkWidget *widget, GdkEventMotion *motion) if (!d->inputs) return true; + if (d->disable_inputs) + return true; gdk_drawable_get_size(gtk_widget_get_window(widget), &ww, &wh); if (spicex_is_scaled(display)) { @@ -1051,6 +1082,8 @@ static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *scroll) if (!d->inputs) return true; + if (d->disable_inputs) + return true; if (scroll->direction == GDK_SCROLL_UP) button = SPICE_MOUSE_BUTTON_UP; @@ -1077,6 +1110,9 @@ static gboolean button_event(GtkWidget *widget, GdkEventButton *button) button->type == GDK_BUTTON_PRESS ? "press" : "release", button->button, button->state); + if (d->disable_inputs) + return true; + if (!spicex_is_scaled(display)) { gint x, y; @@ -1248,6 +1284,23 @@ static void spice_display_class_init(SpiceDisplayClass *klass) G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); + + /** + * SpiceDisplay:disable-inputs: + * + * Disable all keyboard & mouse inputs. + * + * Since: 0.8 + **/ + g_object_class_install_property + (gobject_class, PROP_DISABLE_INPUTS, + g_param_spec_boolean("disable-inputs", "Disable inputs", + "Whether inputs should be disabled", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + /** * SpiceDisplay::mouse-grab: * @display: the #SpiceDisplay that emitted the signal @@ -1774,6 +1827,9 @@ static void sync_keyboard_lock_modifiers(SpiceDisplay *display) guint32 modifiers; GdkWindow *w; + if (d->disable_inputs) + return; + w = gtk_widget_get_parent_window(GTK_WIDGET(display)); if (w == NULL) /* it can happen if the display is not yet shown */ return; diff --git a/gtk/spicy.c b/gtk/spicy.c index 6c05b1e..427b8d1 100644 --- a/gtk/spicy.c +++ b/gtk/spicy.c @@ -721,6 +721,7 @@ static const char *spice_display_properties[] = { "grab-mouse", "resize-guest", "scaling", + "disable-inputs", }; static const char *spice_gtk_session_properties[] = { @@ -748,6 +749,10 @@ static const GtkToggleActionEntry tentries[] = { .label = N_("Scale display"), .callback = G_CALLBACK(menu_cb_bool_prop), },{ + .name = "disable-inputs", + .label = N_("Disable inputs"), + .callback = G_CALLBACK(menu_cb_bool_prop), + },{ .name = "auto-clipboard", .label = N_("Automagic clipboard sharing between host and guest"), .callback = G_CALLBACK(menu_cb_bool_prop), @@ -798,6 +803,7 @@ static char ui_xml[] = " <menuitem action='grab-mouse'/>\n" " <menuitem action='resize-guest'/>\n" " <menuitem action='scaling'/>\n" +" <menuitem action='disable-inputs'/>\n" " <menuitem action='auto-clipboard'/>\n" #ifdef USE_USBREDIR " <menuitem action='auto-usbredir'/>\n" -- 1.7.7 _______________________________________________ Spice-devel mailing list Spice-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/spice-devel