1
0
mirror of https://github.com/wine-mirror/wine synced 2024-07-09 04:16:08 +00:00

winewayland.drv: Present cursors with the correct scale.

Take into account the window scale factor and use wp_viewport to
instruct the compositor to present cursors with that scale.
This commit is contained in:
Alexandros Frantzis 2023-10-26 14:41:41 +03:00 committed by Alexandre Julliard
parent 80f3e7ecc0
commit 9ddd0a5cb6
2 changed files with 45 additions and 4 deletions

View File

@ -417,7 +417,7 @@ static BOOL get_icon_info(HICON handle, ICONINFOEXW *ret)
return TRUE; return TRUE;
} }
static void wayland_pointer_update_cursor_buffer(HCURSOR hcursor) static void wayland_pointer_update_cursor_buffer(HCURSOR hcursor, double scale)
{ {
struct wayland_cursor *cursor = &process_wayland.pointer.cursor; struct wayland_cursor *cursor = &process_wayland.pointer.cursor;
ICONINFOEXW info = {0}; ICONINFOEXW info = {0};
@ -469,6 +469,9 @@ static void wayland_pointer_update_cursor_buffer(HCURSOR hcursor)
cursor->hotspot_y = cursor->shm_buffer->height / 2; cursor->hotspot_y = cursor->shm_buffer->height / 2;
} }
cursor->hotspot_x = round(cursor->hotspot_x / scale);
cursor->hotspot_y = round(cursor->hotspot_y / scale);
return; return;
clear_cursor: clear_cursor:
@ -479,7 +482,7 @@ clear_cursor:
} }
} }
static void wayland_pointer_update_cursor_surface(void) static void wayland_pointer_update_cursor_surface(double scale)
{ {
struct wayland_cursor *cursor = &process_wayland.pointer.cursor; struct wayland_cursor *cursor = &process_wayland.pointer.cursor;
@ -496,12 +499,32 @@ static void wayland_pointer_update_cursor_surface(void)
} }
} }
if (!cursor->wp_viewport && process_wayland.wp_viewporter)
{
cursor->wp_viewport =
wp_viewporter_get_viewport(process_wayland.wp_viewporter,
cursor->wl_surface);
if (!cursor->wp_viewport)
WARN("Failed to create wp_viewport for cursor\n");
}
/* Commit the cursor buffer to the cursor surface. */ /* Commit the cursor buffer to the cursor surface. */
wl_surface_attach(cursor->wl_surface, wl_surface_attach(cursor->wl_surface,
cursor->shm_buffer->wl_buffer, 0, 0); cursor->shm_buffer->wl_buffer, 0, 0);
wl_surface_damage_buffer(cursor->wl_surface, 0, 0, wl_surface_damage_buffer(cursor->wl_surface, 0, 0,
cursor->shm_buffer->width, cursor->shm_buffer->width,
cursor->shm_buffer->height); cursor->shm_buffer->height);
/* Setting only the viewport is enough, but some compositors don't
* support wp_viewport for cursor surfaces, so also set the buffer
* scale. Note that setting the viewport destination overrides
* the buffer scale, so it's fine to set both. */
wl_surface_set_buffer_scale(cursor->wl_surface, round(scale));
if (cursor->wp_viewport)
{
wp_viewport_set_destination(cursor->wp_viewport,
round(cursor->shm_buffer->width / scale),
round(cursor->shm_buffer->height / scale));
}
wl_surface_commit(cursor->wl_surface); wl_surface_commit(cursor->wl_surface);
return; return;
@ -512,6 +535,11 @@ clear_cursor:
wayland_shm_buffer_unref(cursor->shm_buffer); wayland_shm_buffer_unref(cursor->shm_buffer);
cursor->shm_buffer = NULL; cursor->shm_buffer = NULL;
} }
if (cursor->wp_viewport)
{
wp_viewport_destroy(cursor->wp_viewport);
cursor->wp_viewport = NULL;
}
if (cursor->wl_surface) if (cursor->wl_surface)
{ {
wl_surface_destroy(cursor->wl_surface); wl_surface_destroy(cursor->wl_surface);
@ -522,12 +550,24 @@ clear_cursor:
static void wayland_set_cursor(HWND hwnd, HCURSOR hcursor, BOOL use_hcursor) static void wayland_set_cursor(HWND hwnd, HCURSOR hcursor, BOOL use_hcursor)
{ {
struct wayland_pointer *pointer = &process_wayland.pointer; struct wayland_pointer *pointer = &process_wayland.pointer;
struct wayland_surface *surface;
double scale;
if ((surface = wayland_surface_lock_hwnd(hwnd)))
{
scale = surface->window.scale;
pthread_mutex_unlock(&surface->mutex);
}
else
{
scale = 1.0;
}
pthread_mutex_lock(&pointer->mutex); pthread_mutex_lock(&pointer->mutex);
if (pointer->focused_hwnd == hwnd) if (pointer->focused_hwnd == hwnd)
{ {
if (use_hcursor) wayland_pointer_update_cursor_buffer(hcursor); if (use_hcursor) wayland_pointer_update_cursor_buffer(hcursor, scale);
wayland_pointer_update_cursor_surface(); wayland_pointer_update_cursor_surface(scale);
wl_pointer_set_cursor(pointer->wl_pointer, wl_pointer_set_cursor(pointer->wl_pointer,
pointer->enter_serial, pointer->enter_serial,
pointer->cursor.wl_surface, pointer->cursor.wl_surface,

View File

@ -79,6 +79,7 @@ struct wayland_cursor
{ {
struct wayland_shm_buffer *shm_buffer; struct wayland_shm_buffer *shm_buffer;
struct wl_surface *wl_surface; struct wl_surface *wl_surface;
struct wp_viewport *wp_viewport;
int hotspot_x, hotspot_y; int hotspot_x, hotspot_y;
}; };