qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v2 2/2] ui/gtk: Fix mouse/motion event scaling issue with GTK


From: Marc-André Lureau
Subject: Re: [PATCH v2 2/2] ui/gtk: Fix mouse/motion event scaling issue with GTK display backend
Date: Mon, 13 May 2024 12:22:59 +0400

Hi

On Sun, May 12, 2024 at 3:16 PM hikalium <hikalium@hikalium.com> wrote:
>
> Remove gtk_widget_get_scale_factor() usage from the calculation of
> the motion events in the GTK backend to make it work correctly on
> environments that have `gtk_widget_get_scale_factor() != 1`.
>
> This scale factor usage had been introduced in the commit f14aab420c and
> at that time the window size was used for calculating the things and it
> was working correctly. However, in the commit 2f31663ed4 the logic
> switched to use the widget size instead of window size and because of
> the change the usage of scale factor becomes invalid (since widgets use
> `vc->gfx.scale_{x, y}` for scaling).
>
> Tested on Crostini on ChromeOS (15823.51.0) with an external display.
>
> Fixes: 2f31663ed4 ("ui/gtk: use widget size for cursor motion event")
> Fixes: f14aab420c ("ui: fix incorrect pointer position on highdpi with
> gtk")
>

Thanks for the fix, I am okay with it.

But the QEMU displays are not working well with HiDPI. By treating
size & position with logical units, we can't let the guest handle
HiDPI. Imho, we should fix the code differently so the guest has the
non-scaled units.

This is not as trivial, since widget geometry and drawing code is a
bit more involved. And in theory we should adopt the same behaviour
for other display backends.

> Signed-off-by: hikalium <hikalium@hikalium.com>
> ---
>  ui/gtk.c | 18 +++++++++++++-----
>  1 file changed, 13 insertions(+), 5 deletions(-)
>
> diff --git a/ui/gtk.c b/ui/gtk.c
> index ebae888d4f..4386198c95 100644
> --- a/ui/gtk.c
> +++ b/ui/gtk.c
> @@ -887,7 +887,7 @@ static gboolean gd_motion_event(GtkWidget *widget, 
> GdkEventMotion *motion,
>      int x, y;
>      int mx, my;
>      int fbh, fbw;
> -    int ww, wh, ws;
> +    int ww, wh;
>
>      if (!vc->gfx.ds) {
>          return TRUE;
> @@ -895,11 +895,15 @@ 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 = gtk_widget_get_allocated_width(widget);
>      wh = gtk_widget_get_allocated_height(widget);
> -    ws = gtk_widget_get_scale_factor(widget);
>
> +    /*
> +     * `widget` may not have the same size with the frame buffer.
> +     * In such cases, some paddings are needed around the `vc`.
> +     * To achieve that, `vc` will be displayed at (mx, my)
> +     * so that it is displayed at the center of the widget.
> +     */
>      mx = my = 0;
>      if (ww > fbw) {
>          mx = (ww - fbw) / 2;
> @@ -908,8 +912,12 @@ static gboolean gd_motion_event(GtkWidget *widget, 
> GdkEventMotion *motion,
>          my = (wh - fbh) / 2;
>      }
>
> -    x = (motion->x - mx) / vc->gfx.scale_x * ws;
> -    y = (motion->y - my) / vc->gfx.scale_y * ws;
> +    /*
> +     * `motion` is reported in `widget` coordinates
> +     * so translating it to the coordinates in `vc`.
> +     */
> +    x = (motion->x - mx) / vc->gfx.scale_x;
> +    y = (motion->y - my) / vc->gfx.scale_y;
>
>      trace_gd_motion_event(ww, wh, gtk_widget_get_scale_factor(widget), x, y);
>
> --
> 2.39.2
>
>


-- 
Marc-André Lureau



reply via email to

[Prev in Thread] Current Thread [Next in Thread]