summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2010-09-11 00:43:14 +0200
committerGerd Hoffmann <kraxel@redhat.com>2010-09-11 00:43:14 +0200
commitaa564e7bc353f529f17568f49daef57b6138f3da (patch)
treee79c7c01c409a83247e09d16f0973bd547b9f29a
parente52eeef895866acae75918ce527ce8abc2ba1326 (diff)
add keyboard grab.
-rw-r--r--gtk/spice-widget.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c
index 103bcc1..30e7919 100644
--- a/gtk/spice-widget.c
+++ b/gtk/spice-widget.c
@@ -29,6 +29,11 @@ struct spice_display {
SpiceChannel *inputs;
enum SpiceMouseMode mouse_mode;
+ int mouse_have_pointer;
+
+ int keyboard_grab_enable;
+ int keyboard_grab_active;
+ int keyboard_have_focus;
const guint16 const *keycode_map;
size_t keycode_maplen;
@@ -111,6 +116,39 @@ static void spice_display_init(SpiceDisplay *display)
gtk_widget_set_can_focus(widget, true);
d->keycode_map = vnc_display_keymap_gdk2xtkbd_table(&d->keycode_maplen);
+
+ d->keyboard_grab_enable = true;
+}
+
+static void try_keyboard_grab(GtkWidget *widget)
+{
+ SpiceDisplay *display = SPICE_DISPLAY(widget);
+ spice_display *d = SPICE_DISPLAY_GET_PRIVATE(display);
+
+ if (!d->keyboard_grab_enable)
+ return;
+ if (!d->keyboard_have_focus)
+ return;
+ if (!d->mouse_have_pointer)
+ return;
+
+ fprintf(stderr, "grab keyboard\n");
+ gdk_keyboard_grab(gtk_widget_get_window(widget), FALSE,
+ GDK_CURRENT_TIME);
+ d->keyboard_grab_active = true;
+}
+
+
+static void try_keyboard_ungrab(GtkWidget *widget)
+{
+ SpiceDisplay *display = SPICE_DISPLAY(widget);
+ spice_display *d = SPICE_DISPLAY_GET_PRIVATE(display);
+
+ if (!d->keyboard_grab_active)
+ return;
+
+ fprintf(stderr, "ungrab keyboard\n");
+ gdk_keyboard_ungrab(GDK_CURRENT_TIME);
}
static void recalc_geometry(GtkWidget *widget)
@@ -296,25 +334,45 @@ static gboolean key_event(GtkWidget *widget, GdkEventKey *key)
static gboolean enter_event(GtkWidget *widget, GdkEventCrossing *crossing G_GNUC_UNUSED)
{
+ SpiceDisplay *display = SPICE_DISPLAY(widget);
+ spice_display *d = SPICE_DISPLAY_GET_PRIVATE(display);
+
fprintf(stderr, "%s\n", __FUNCTION__);
+ d->mouse_have_pointer = true;
+ try_keyboard_grab(widget);
return true;
}
static gboolean leave_event(GtkWidget *widget, GdkEventCrossing *crossing G_GNUC_UNUSED)
{
+ SpiceDisplay *display = SPICE_DISPLAY(widget);
+ spice_display *d = SPICE_DISPLAY_GET_PRIVATE(display);
+
fprintf(stderr, "%s\n", __FUNCTION__);
+ d->mouse_have_pointer = false;
+ try_keyboard_ungrab(widget);
return true;
}
static gboolean focus_in_event(GtkWidget *widget, GdkEventFocus *focus G_GNUC_UNUSED)
{
+ SpiceDisplay *display = SPICE_DISPLAY(widget);
+ spice_display *d = SPICE_DISPLAY_GET_PRIVATE(display);
+
fprintf(stderr, "%s\n", __FUNCTION__);
+ d->keyboard_have_focus = true;
+ try_keyboard_grab(widget);
return true;
}
static gboolean focus_out_event(GtkWidget *widget, GdkEventFocus *focus G_GNUC_UNUSED)
{
+ SpiceDisplay *display = SPICE_DISPLAY(widget);
+ spice_display *d = SPICE_DISPLAY_GET_PRIVATE(display);
+
fprintf(stderr, "%s\n", __FUNCTION__);
+ d->keyboard_have_focus = false;
+ try_keyboard_ungrab(widget);
return true;
}