summary refs log tree commit diff stats
path: root/ui/gtk.c
diff options
context:
space:
mode:
Diffstat (limited to 'ui/gtk.c')
-rw-r--r--ui/gtk.c38
1 files changed, 36 insertions, 2 deletions
diff --git a/ui/gtk.c b/ui/gtk.c
index 185149571e..baabf865c0 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -340,13 +340,17 @@ static void gd_mouse_set(DisplayChangeListener *dcl,
     GdkDeviceManager *mgr;
     gint x_root, y_root;
 
+    if (qemu_input_is_absolute()) {
+        return;
+    }
+
     dpy = gtk_widget_get_display(s->drawing_area);
     mgr = gdk_display_get_device_manager(dpy);
     gdk_window_get_root_coords(gtk_widget_get_window(s->drawing_area),
                                x, y, &x_root, &y_root);
     gdk_device_warp(gdk_device_manager_get_client_pointer(mgr),
                     gtk_widget_get_screen(s->drawing_area),
-                    x, y);
+                    x_root, y_root);
 }
 #else
 static void gd_mouse_set(DisplayChangeListener *dcl,
@@ -355,6 +359,10 @@ static void gd_mouse_set(DisplayChangeListener *dcl,
     GtkDisplayState *s = container_of(dcl, GtkDisplayState, dcl);
     gint x_root, y_root;
 
+    if (qemu_input_is_absolute()) {
+        return;
+    }
+
     gdk_window_get_root_coords(gtk_widget_get_window(s->drawing_area),
                                x, y, &x_root, &y_root);
     gdk_display_warp_pointer(gtk_widget_get_display(s->drawing_area),
@@ -683,6 +691,27 @@ static gboolean gd_button_event(GtkWidget *widget, GdkEventButton *button,
     return TRUE;
 }
 
+static gboolean gd_scroll_event(GtkWidget *widget, GdkEventScroll *scroll,
+                                void *opaque)
+{
+    GtkDisplayState *s = opaque;
+    InputButton btn;
+
+    if (scroll->direction == GDK_SCROLL_UP) {
+        btn = INPUT_BUTTON_WHEEL_UP;
+    } else if (scroll->direction == GDK_SCROLL_DOWN) {
+        btn = INPUT_BUTTON_WHEEL_DOWN;
+    } else {
+        return TRUE;
+    }
+
+    qemu_input_queue_btn(s->dcl.con, btn, true);
+    qemu_input_event_sync();
+    qemu_input_queue_btn(s->dcl.con, btn, false);
+    qemu_input_event_sync();
+    return TRUE;
+}
+
 static gboolean gd_key_event(GtkWidget *widget, GdkEventKey *key, void *opaque)
 {
     GtkDisplayState *s = opaque;
@@ -1229,6 +1258,8 @@ static void gd_connect_signals(GtkDisplayState *s)
                      G_CALLBACK(gd_button_event), s);
     g_signal_connect(s->drawing_area, "button-release-event",
                      G_CALLBACK(gd_button_event), s);
+    g_signal_connect(s->drawing_area, "scroll-event",
+                     G_CALLBACK(gd_scroll_event), s);
     g_signal_connect(s->drawing_area, "key-press-event",
                      G_CALLBACK(gd_key_event), s);
     g_signal_connect(s->drawing_area, "key-release-event",
@@ -1415,7 +1446,7 @@ static const DisplayChangeListenerOps dcl_ops = {
     .dpy_cursor_define = gd_cursor_define,
 };
 
-void gtk_display_init(DisplayState *ds, bool full_screen)
+void gtk_display_init(DisplayState *ds, bool full_screen, bool grab_on_hover)
 {
     GtkDisplayState *s = g_malloc0(sizeof(*s));
     char *filename;
@@ -1494,6 +1525,9 @@ void gtk_display_init(DisplayState *ds, bool full_screen)
     if (full_screen) {
         gtk_menu_item_activate(GTK_MENU_ITEM(s->full_screen_item));
     }
+    if (grab_on_hover) {
+        gtk_menu_item_activate(GTK_MENU_ITEM(s->grab_on_hover_item));
+    }
 
     register_displaychangelistener(&s->dcl);