@@ -61,16 +61,14 @@ void gd_egl_init(VirtualConsole *vc)
void gd_egl_draw(VirtualConsole *vc)
{
- GdkWindow *window;
int ww, wh;
if (!vc->gfx.gls) {
return;
}
- window = gtk_widget_get_window(vc->gfx.drawing_area);
- ww = gdk_window_get_width(window);
- wh = gdk_window_get_height(window);
+ ww = gtk_widget_get_allocated_width(vc->gfx.drawing_area);
+ wh = gtk_widget_get_allocated_height(vc->gfx.drawing_area);
if (vc->gfx.scanout_mode) {
gd_egl_scanout_flush(&vc->gfx.dcl, 0, 0, vc->gfx.w, vc->gfx.h);
@@ -255,7 +253,6 @@ void gd_egl_scanout_flush(DisplayChangeListener *dcl,
uint32_t x, uint32_t y, uint32_t w, uint32_t h)
{
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
- GdkWindow *window;
int ww, wh;
if (!vc->gfx.scanout_mode) {
@@ -268,9 +265,8 @@ void gd_egl_scanout_flush(DisplayChangeListener *dcl,
eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
vc->gfx.esurface, vc->gfx.ectx);
- window = gtk_widget_get_window(vc->gfx.drawing_area);
- ww = gdk_window_get_width(window);
- wh = gdk_window_get_height(window);
+ ww = gtk_widget_get_allocated_width(vc->gfx.drawing_area);
+ wh = gtk_widget_get_allocated_height(vc->gfx.drawing_area);
egl_fb_setup_default(&vc->gfx.win_fb, ww, wh);
if (vc->gfx.cursor_fb.texture) {
egl_texture_blit(vc->gfx.gls, &vc->gfx.win_fb, &vc->gfx.guest_fb,
@@ -393,8 +393,8 @@ static void gd_update_full_redraw(VirtualConsole *vc)
{
GtkWidget *area = vc->gfx.drawing_area;
int ww, wh;
- ww = gdk_window_get_width(gtk_widget_get_window(area));
- wh = gdk_window_get_height(gtk_widget_get_window(area));
+ ww = gtk_widget_get_allocated_width(area);
+ wh = gtk_widget_get_allocated_height(area);
#if defined(CONFIG_GTK_GL)
if (vc->gfx.gls && gtk_use_gl_area) {
gtk_gl_area_queue_render(GTK_GL_AREA(vc->gfx.drawing_area));
@@ -440,7 +440,6 @@ static void gd_update(DisplayChangeListener *dcl,
int x, int y, int w, int h)
{
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
- GdkWindow *win;
int x1, x2, y1, y2;
int mx, my;
int fbw, fbh;
@@ -467,12 +466,8 @@ static void gd_update(DisplayChangeListener *dcl,
fbw = surface_width(vc->gfx.ds) * vc->gfx.scale_x;
fbh = surface_height(vc->gfx.ds) * vc->gfx.scale_y;
- win = gtk_widget_get_window(vc->gfx.drawing_area);
- if (!win) {
- return;
- }
- ww = gdk_window_get_width(win);
- wh = gdk_window_get_height(win);
+ ww = gtk_widget_get_allocated_width(vc->gfx.drawing_area);
+ wh = gtk_widget_get_allocated_height(vc->gfx.drawing_area);
mx = my = 0;
if (ww > fbw) {
@@ -803,8 +798,8 @@ static gboolean gd_draw_event(GtkWidget *widget, cairo_t *cr, void *opaque)
fbw = surface_width(vc->gfx.ds);
fbh = surface_height(vc->gfx.ds);
- ww = gdk_window_get_width(gtk_widget_get_window(widget));
- wh = gdk_window_get_height(gtk_widget_get_window(widget));
+ ww = gtk_widget_get_allocated_width(widget);
+ wh = gtk_widget_get_allocated_height(widget);
if (s->full_screen) {
vc->gfx.scale_x = (double)ww / fbw;
@@ -865,8 +860,8 @@ static gboolean gd_motion_event(GtkWidget *widget, GdkEventMotion *motion,
fbw = surface_width(vc->gfx.ds) * vc->gfx.scale_x;
fbh = surface_height(vc->gfx.ds) * vc->gfx.scale_y;
- ww = gdk_window_get_width(gtk_widget_get_window(vc->gfx.drawing_area));
- wh = gdk_window_get_height(gtk_widget_get_window(vc->gfx.drawing_area));
+ ww = gtk_widget_get_allocated_width(vc->gfx.drawing_area);
+ wh = gtk_widget_get_allocated_height(vc->gfx.drawing_area);
mx = my = 0;
if (ww > fbw) {
Ubuntu 20.04, GNOME Wayland desktop, QEMU 5.1.0 compiled from sources. Absolute tablet/vmmouse location in guest window does not match cursor - coordinates reported to guest are smaller than visible mouse cursor location. Adding debug print to ui/gtk.c:gd_motion_event() to print surface and window szies and mouse coordinates and running guest with 1280x960 size I see the following. Under X11 fbw = 1280, fbh = 960, ww = 1280, wh = 960, x = 1278.000000, y = 38.000000 fbw = 1280, fbh = 960, ww = 1280, wh = 960, x = 1276.000000, y = 38.000000 Guest surface size is the same as containing window, mouse coordinates are reported relative to guest surface. It matches X11 window hierarchy: 0x606f8f (has no name): () 1300x1040+145+50 +145+50 1 child: 0x2e00009 "QEMU (Tumbleweed)": ("qemu" "Qemu-system-x86_64") 1280x985+10+45 +155+95 2 children: 0x2e00019 (has no name): () 1280x960+0+25 +155+120 0x2e0000a (has no name): () 1x1+-1+-1 +154+94 So guest surface has matching window with 1280x960 size. Under Wayland [430579.942] wl_pointer@11.motion(183842180, 1314.042969, 90.894531) ... [430680.056] wl_pointer@11.motion(183842288, 1306.355469, 91.171875) [430697.031] wl_pointer@11.motion(183842300, 1305.722656, 91.171875) [430735.908] wl_pointer@11.motion(183842347, 1304.832031, 91.171875) fbw = 1280, fbh = 960, ww = 1332, wh = 1074, x = 1278.832031, y = 6.171875 [430783.750] wl_pointer@11.motion(183842395, 1304.500000, 91.171875) fbw = 1280, fbh = 960, ww = 1332, wh = 1074, x = 1278.500000, y = 6.171875 [430863.804] wl_pointer@11.motion(183842467, 1303.492188, 91.527344) fbw = 1280, fbh = 960, ww = 1332, wh = 1074, x = 1277.492188, y = 6.527344 While mouse coordinates are still reported relative to guest surface, it seems that there is single (GDK) top level window with size 1332x1074 and all other widgets belong to this window. Mouse events are registered as soon as pointer enters this top level window but are reported to application only when they enter guest window surface. Because QEMU believes UI window was resized, it attempts to adjust mouse position before reporting it to guest. This does not contradict GTK manual which does not require that every widget has own window: Note that all realized widgets have a non-NULL “window” pointer (gtk_widget_get_window() never returns a NULL window when a widget is realized), but for many of them it’s actually the GdkWindow of one of its parent widgets. This patch replaces gdk_window_get_width/height(gtk_widget_get_window()) with gtk_widget_get_allocated_width/height(). I tested it both under Wayland and X11 and it fixed mouse issue and did not introduce regressions for me. I tested also UI resizing with fixed guest size and full screen which also worked. Signed-off-by: Andrei Borzenkov <arvidjaar@gmail.com> --- ui/gtk-egl.c | 12 ++++-------- ui/gtk.c | 21 ++++++++------------- 2 files changed, 12 insertions(+), 21 deletions(-)