[Spice-devel] [PATCH spice-gtk 5/8] Add disable-inputs on Spice widget
Marc-André Lureau
marcandre.lureau at gmail.com
Wed Nov 23 04:23:41 PST 2011
---
gtk/spice-widget-priv.h | 1 +
gtk/spice-widget.c | 111 +++++++++++++++++++++++++++++++++++-----------
gtk/spicy.c | 6 +++
3 files changed, 91 insertions(+), 27 deletions(-)
diff --git a/gtk/spice-widget-priv.h b/gtk/spice-widget-priv.h
index a5791a4..5065f7c 100644
--- a/gtk/spice-widget-priv.h
+++ b/gtk/spice-widget-priv.h
@@ -61,6 +61,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 cec9aaa..fa347a1 100644
--- a/gtk/spice-widget.c
+++ b/gtk/spice-widget.c
@@ -34,6 +34,7 @@
#include "spice-widget-priv.h"
#include "spice-gtk-session-priv.h"
#include "vncdisplaykeymap.h"
+#include "spice-util-priv.h"
/* Some compatibility defines to let us build on both Gtk2 and Gtk3 */
#if GTK_CHECK_VERSION (2, 91, 0)
@@ -86,6 +87,7 @@ enum {
PROP_RESIZE_GUEST,
PROP_AUTO_CLIPBOARD,
PROP_SCALING,
+ PROP_DISABLE_INPUTS,
};
/* Signals */
@@ -102,10 +104,12 @@ 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 try_mouse_grab(GtkWidget *widget);
-static void try_mouse_ungrab(GtkWidget *widget);
+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);
static void disconnect_main(SpiceDisplay *display);
static void disconnect_cursor(SpiceDisplay *display);
@@ -148,6 +152,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 +179,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(GTK_WIDGET(display));
- }
+ update_mouse_grab(display);
break;
case PROP_RESIZE_GUEST:
d->resize_guest_enable = g_value_get_boolean(value);
@@ -207,6 +208,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;
@@ -327,8 +334,8 @@ spice_display_constructor(GType gtype,
}
g_list_free(list);
- g_signal_connect(d->gtk_session, "notify::auto-clipboard",
- G_CALLBACK(gtk_session_property_changed), display);
+ spice_g_signal_connect_object(d->gtk_session, "notify::auto-clipboard",
+ G_CALLBACK(gtk_session_property_changed), display, 0);
return obj;
}
@@ -410,12 +417,12 @@ 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_enable)
return;
+ if (d->keyboard_grab_active)
+ return;
if (!d->keyboard_have_focus)
return;
if (!d->mouse_have_pointer)
@@ -441,7 +448,6 @@ static void try_keyboard_grab(SpiceDisplay *display)
}
}
-
static void try_keyboard_ungrab(SpiceDisplay *display)
{
SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
@@ -460,6 +466,16 @@ 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->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);
@@ -514,8 +530,9 @@ static void update_mouse_pointer(SpiceDisplay *display)
if (!d->mouse_grab_active) {
gdk_window_set_cursor(window, NULL);
} else {
+ // FIXME: should it be transparent instead?
gdk_window_set_cursor(window, d->mouse_cursor);
- try_mouse_grab(GTK_WIDGET(display));
+ try_mouse_grab(display);
}
break;
default:
@@ -524,13 +541,14 @@ static void update_mouse_pointer(SpiceDisplay *display)
}
}
-static void try_mouse_grab(GtkWidget *widget)
+static void try_mouse_grab(SpiceDisplay *display)
{
- SpiceDisplay *display = SPICE_DISPLAY(widget);
SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
if (g_getenv("SPICE_NOGRAB"))
return;
+ if (d->disable_inputs)
+ return;
if (!d->mouse_grab_enable)
return;
@@ -579,9 +597,8 @@ static void mouse_check_edges(GtkWidget *widget, GdkEventMotion *motion)
}
}
-static void try_mouse_ungrab(GtkWidget *widget)
+static void try_mouse_ungrab(SpiceDisplay *display)
{
- SpiceDisplay *display = SPICE_DISPLAY(widget);
SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
if (!d->mouse_grab_active)
@@ -590,7 +607,17 @@ static void try_mouse_ungrab(GtkWidget *widget)
gdk_pointer_ungrab(GDK_CURRENT_TIME);
d->mouse_grab_active = false;
update_mouse_pointer(display);
- g_signal_emit(widget, signals[SPICE_DISPLAY_MOUSE_GRAB], 0, false);
+ 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)
@@ -725,6 +752,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);
@@ -814,11 +844,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_grab_active)
- try_mouse_ungrab(widget);
+ try_mouse_ungrab(display);
else
/* TODO: gtk-vnc has a weird condition here
if (!d->grab_keyboard || !d->absolute) */
- try_mouse_grab(widget);
+ try_mouse_grab(display);
}
@@ -970,6 +1000,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)) {
@@ -1030,6 +1062,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;
@@ -1056,6 +1090,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;
@@ -1069,7 +1106,7 @@ static gboolean button_event(GtkWidget *widget, GdkEventButton *button)
gtk_widget_grab_focus(widget);
if (d->mouse_mode == SPICE_MOUSE_MODE_SERVER)
- try_mouse_grab(widget);
+ try_mouse_grab(display);
else /* allow to drag and drop between windows/displays:
FIXME: should be multiple widget grab, but how?
or should now the position of the other widgets?..
@@ -1227,6 +1264,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
@@ -1295,7 +1349,7 @@ static void mouse_update(SpiceChannel *channel, gpointer data)
d->mouse_guest_x = -1;
d->mouse_guest_y = -1;
if (d->mouse_mode == SPICE_MOUSE_MODE_CLIENT) {
- try_mouse_ungrab(GTK_WIDGET(display));
+ try_mouse_ungrab(display);
}
update_mouse_pointer(display);
}
@@ -1646,7 +1700,7 @@ SpiceDisplay *spice_display_new(SpiceSession *session, int id)
**/
void spice_display_mouse_ungrab(SpiceDisplay *display)
{
- try_mouse_ungrab(GTK_WIDGET(display));
+ try_mouse_ungrab(display);
}
/**
@@ -1753,6 +1807,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
More information about the Spice-devel
mailing list