[Spice-devel] [PATCH spice-gtk 3/4] spice-gtk: hookup automount inhibiting
Hans de Goede
hdegoede at redhat.com
Thu Jun 21 13:09:15 PDT 2012
Inhibit automounting when usb-autoredirection is active.
Note:
1) While changing the prototype for the spice_gtk_session_update_keyboard_focus
function, this patch also renames it to spice_gtk_session_update_usb_autoredir
to better reflect its function.
2) This patch changes the "do we have focus?" tracking, to tracking a list of
toplevel window ids which have requested autoredirection to be enabled
(iow which have keyboard focus). The reason for this is that sometimes multiple
spice-widgets can have focus at the same time, yes really! Sometimes (rarely,
hard to reproduce) the focus in event for one window arrives before the
focus out of the other windows.
Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
gtk/spice-gtk-session-priv.h | 5 ++--
gtk/spice-gtk-session.c | 55 ++++++++++++++++++++++++++++++++++++++----
gtk/spice-widget.c | 23 +++++++++++++++---
3 files changed, 72 insertions(+), 11 deletions(-)
diff --git a/gtk/spice-gtk-session-priv.h b/gtk/spice-gtk-session-priv.h
index 21a4251..6e572b8 100644
--- a/gtk/spice-gtk-session-priv.h
+++ b/gtk/spice-gtk-session-priv.h
@@ -22,8 +22,9 @@
G_BEGIN_DECLS
-void spice_gtk_session_update_keyboard_focus(SpiceGtkSession *self,
- gboolean state);
+void spice_gtk_session_update_usb_autoredir(SpiceGtkSession *self,
+ guint toplevel_window_id,
+ gboolean state);
gboolean spice_gtk_session_get_read_only(SpiceGtkSession *self);
G_END_DECLS
diff --git a/gtk/spice-gtk-session.c b/gtk/spice-gtk-session.c
index 130cbc9..89fc724 100644
--- a/gtk/spice-gtk-session.c
+++ b/gtk/spice-gtk-session.c
@@ -18,6 +18,7 @@
#include <gtk/gtk.h>
#include <spice/vd_agent.h>
+#include "desktop-integration.h"
#include "spice-common.h"
#include "spice-gtk-session.h"
#include "spice-gtk-session-priv.h"
@@ -39,7 +40,7 @@ struct _SpiceGtkSessionPrivate {
gboolean clipboard_by_guest[CLIPBOARD_LAST];
/* auto-usbredir related */
gboolean auto_usbredir_enable;
- gboolean keyboard_focus;
+ GSList *auto_usbredir_toplevels;
};
/**
@@ -194,6 +195,20 @@ static void spice_gtk_session_finalize(GObject *gobject)
G_OBJECT_CLASS(spice_gtk_session_parent_class)->finalize(gobject);
}
+static void inhibit_automount(gpointer data, gpointer user_data)
+{
+ SpiceDesktopIntegration *di = SPICE_DESKTOP_INTEGRATION(user_data);
+
+ spice_desktop_integration_inhibit_automount(di, GPOINTER_TO_UINT(data));
+}
+
+static void uninhibit_automount(gpointer data, gpointer user_data)
+{
+ SpiceDesktopIntegration *di = SPICE_DESKTOP_INTEGRATION(user_data);
+
+ spice_desktop_integration_uninhibit_automount(di, GPOINTER_TO_UINT(data));
+}
+
static void spice_gtk_session_get_property(GObject *gobject,
guint prop_id,
GValue *value,
@@ -235,13 +250,23 @@ static void spice_gtk_session_set_property(GObject *gobject,
break;
case PROP_AUTO_USBREDIR:
s->auto_usbredir_enable = g_value_get_boolean(value);
- if (s->keyboard_focus) {
+ if (s->auto_usbredir_toplevels) {
+ SpiceDesktopIntegration *desktop_int;
SpiceUsbDeviceManager *manager =
spice_usb_device_manager_get(s->session, NULL);
if (!manager)
break;
+ desktop_int = spice_desktop_integration_get(s->session);
+ if (s->auto_usbredir_enable) {
+ g_slist_foreach(s->auto_usbredir_toplevels,
+ inhibit_automount, desktop_int);
+ } else {
+ g_slist_foreach(s->auto_usbredir_toplevels,
+ uninhibit_automount, desktop_int);
+ }
+
g_object_set(manager, "auto-connect", s->auto_usbredir_enable,
NULL);
}
@@ -837,15 +862,28 @@ static gboolean read_only(SpiceGtkSession *self)
/* ---------------------------------------------------------------- */
/* private functions (usbredir related) */
G_GNUC_INTERNAL
-void spice_gtk_session_update_keyboard_focus(SpiceGtkSession *self,
- gboolean state)
+void spice_gtk_session_update_usb_autoredir(SpiceGtkSession *self,
+ guint toplevel,
+ gboolean state)
{
g_return_if_fail(SPICE_IS_GTK_SESSION(self));
SpiceGtkSessionPrivate *s = self->priv;
+ SpiceDesktopIntegration *desktop_int;
SpiceUsbDeviceManager *manager;
- s->keyboard_focus = state;
+ if (state) {
+ if (!g_slist_find(s->auto_usbredir_toplevels,
+ GUINT_TO_POINTER(toplevel))) {
+ s->auto_usbredir_toplevels =
+ g_slist_prepend(s->auto_usbredir_toplevels,
+ GUINT_TO_POINTER(toplevel));
+ }
+ } else {
+ s->auto_usbredir_toplevels =
+ g_slist_remove(s->auto_usbredir_toplevels,
+ GUINT_TO_POINTER(toplevel));
+ }
if (!s->auto_usbredir_enable)
return;
@@ -854,6 +892,13 @@ void spice_gtk_session_update_keyboard_focus(SpiceGtkSession *self,
if (!manager)
return;
+ desktop_int = spice_desktop_integration_get(s->session);
+ if (state)
+ spice_desktop_integration_inhibit_automount(desktop_int, toplevel);
+ else
+ spice_desktop_integration_uninhibit_automount(desktop_int, toplevel);
+
+ state = s->auto_usbredir_toplevels != NULL;
g_object_set(manager, "auto-connect", state, NULL);
}
diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c
index d559273..9397750 100644
--- a/gtk/spice-widget.c
+++ b/gtk/spice-widget.c
@@ -209,6 +209,23 @@ static void update_size_request(SpiceDisplay *display)
recalc_geometry(GTK_WIDGET(display));
}
+static void update_usb_autoredir(SpiceDisplay *display)
+{
+ SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
+ guint toplevel_window_id = 0;
+#ifdef GDK_WINDOWING_X11
+ {
+ GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(display));
+ GdkWindow *w = GDK_WINDOW(gtk_widget_get_window(toplevel));
+
+ toplevel_window_id = GDK_WINDOW_XID(w);
+ }
+#endif
+ spice_gtk_session_update_usb_autoredir(d->gtk_session,
+ toplevel_window_id,
+ d->keyboard_have_focus);
+}
+
static void spice_display_set_property(GObject *object,
guint prop_id,
const GValue *value,
@@ -1097,8 +1114,7 @@ static gboolean focus_in_event(GtkWidget *widget, GdkEventFocus *focus G_GNUC_UN
sync_keyboard_lock_modifiers(display);
d->keyboard_have_focus = true;
try_keyboard_grab(display);
- spice_gtk_session_update_keyboard_focus(d->gtk_session,
- d->keyboard_have_focus);
+ update_usb_autoredir(display);
#ifdef WIN32
focus_window = GDK_WINDOW_HWND(gtk_widget_get_window(widget));
g_return_val_if_fail(focus_window != NULL, true);
@@ -1122,8 +1138,7 @@ static gboolean focus_out_event(GtkWidget *widget, GdkEventFocus *focus G_GNUC_U
release_keys(display);
d->keyboard_have_focus = false;
- spice_gtk_session_update_keyboard_focus(d->gtk_session,
- d->keyboard_have_focus);
+ update_usb_autoredir(display);
return true;
}
--
1.7.10.4
More information about the Spice-devel
mailing list