xwayland: Account for the scale factor
Apply the scale factor to the root window and adjust the coordinates and hotspot location for cursors. Signed-off-by: Olivier Fourdan <ofourdan@redhat.com> Reviewed-By: Kenny Levinsen <kl@kl.wtf> Acked-by: Peter Hutterer <peter.hutterer@who-t.net> Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1197>
This commit is contained in:
parent
b678297c53
commit
54f8fc4090
|
@ -156,6 +156,7 @@ xwl_cursor_attach_pixmap(struct xwl_seat *xwl_seat,
|
|||
struct xwl_cursor *xwl_cursor, PixmapPtr pixmap)
|
||||
{
|
||||
struct wl_buffer *buffer;
|
||||
struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
|
||||
|
||||
buffer = xwl_shm_pixmap_get_wl_buffer(pixmap);
|
||||
if (!buffer) {
|
||||
|
@ -164,7 +165,8 @@ xwl_cursor_attach_pixmap(struct xwl_seat *xwl_seat,
|
|||
}
|
||||
|
||||
wl_surface_attach(xwl_cursor->surface, buffer, 0, 0);
|
||||
xwl_surface_damage(xwl_seat->xwl_screen, xwl_cursor->surface, 0, 0,
|
||||
wl_surface_set_buffer_scale(xwl_cursor->surface, xwl_screen->global_surface_scale);
|
||||
xwl_surface_damage(xwl_screen, xwl_cursor->surface, 0, 0,
|
||||
xwl_seat->x_cursor->bits->width,
|
||||
xwl_seat->x_cursor->bits->height);
|
||||
|
||||
|
@ -196,8 +198,10 @@ void
|
|||
xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
|
||||
{
|
||||
struct xwl_cursor *xwl_cursor = &xwl_seat->cursor;
|
||||
struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
|
||||
PixmapPtr pixmap;
|
||||
CursorPtr cursor;
|
||||
int xhot, yhot;
|
||||
|
||||
if (!xwl_seat->wl_pointer)
|
||||
return;
|
||||
|
@ -222,11 +226,14 @@ xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
|
|||
|
||||
xwl_cursor_copy_bits_to_pixmap(cursor, pixmap);
|
||||
|
||||
xhot = xwl_seat->x_cursor->bits->xhot / xwl_screen->global_surface_scale;
|
||||
yhot = xwl_seat->x_cursor->bits->yhot / xwl_screen->global_surface_scale;
|
||||
|
||||
wl_pointer_set_cursor(xwl_seat->wl_pointer,
|
||||
xwl_seat->pointer_enter_serial,
|
||||
xwl_cursor->surface,
|
||||
xwl_seat->x_cursor->bits->xhot,
|
||||
xwl_seat->x_cursor->bits->yhot);
|
||||
xhot,
|
||||
yhot);
|
||||
|
||||
xwl_cursor_attach_pixmap(xwl_seat, xwl_cursor, pixmap);
|
||||
}
|
||||
|
@ -235,9 +242,11 @@ void
|
|||
xwl_tablet_tool_set_cursor(struct xwl_tablet_tool *xwl_tablet_tool)
|
||||
{
|
||||
struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
|
||||
struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
|
||||
struct xwl_cursor *xwl_cursor = &xwl_tablet_tool->cursor;
|
||||
PixmapPtr pixmap;
|
||||
CursorPtr cursor;
|
||||
int xhot, yhot;
|
||||
|
||||
if (!xwl_seat->x_cursor) {
|
||||
zwp_tablet_tool_v2_set_cursor(xwl_tablet_tool->tool,
|
||||
|
@ -260,11 +269,14 @@ xwl_tablet_tool_set_cursor(struct xwl_tablet_tool *xwl_tablet_tool)
|
|||
|
||||
xwl_cursor_copy_bits_to_pixmap(cursor, pixmap);
|
||||
|
||||
xhot = xwl_seat->x_cursor->bits->xhot / xwl_screen->global_surface_scale;
|
||||
yhot = xwl_seat->x_cursor->bits->yhot / xwl_screen->global_surface_scale;
|
||||
|
||||
zwp_tablet_tool_v2_set_cursor(xwl_tablet_tool->tool,
|
||||
xwl_tablet_tool->proximity_in_serial,
|
||||
xwl_cursor->surface,
|
||||
xwl_seat->x_cursor->bits->xhot,
|
||||
xwl_seat->x_cursor->bits->yhot);
|
||||
xhot,
|
||||
yhot);
|
||||
|
||||
xwl_cursor_attach_pixmap(xwl_seat, xwl_cursor, pixmap);
|
||||
}
|
||||
|
|
|
@ -515,13 +515,13 @@ pointer_handle_enter(void *data, struct wl_pointer *pointer,
|
|||
wl_fixed_t sx_w, wl_fixed_t sy_w)
|
||||
{
|
||||
struct xwl_seat *xwl_seat = data;
|
||||
struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
|
||||
DeviceIntPtr dev = get_pointer_device(xwl_seat);
|
||||
DeviceIntPtr master;
|
||||
int i;
|
||||
int sx = wl_fixed_to_int(sx_w);
|
||||
int sy = wl_fixed_to_int(sy_w);
|
||||
int sx, sy;
|
||||
int dx, dy;
|
||||
ScreenPtr pScreen = xwl_seat->xwl_screen->screen;
|
||||
ScreenPtr pScreen = xwl_screen->screen;
|
||||
ValuatorMask mask;
|
||||
|
||||
/* There's a race here where if we create and then immediately
|
||||
|
@ -536,6 +536,9 @@ pointer_handle_enter(void *data, struct wl_pointer *pointer,
|
|||
if (!is_surface_from_xwl_window(surface))
|
||||
return;
|
||||
|
||||
sx = wl_fixed_to_int(sx_w) * xwl_screen->global_surface_scale;
|
||||
sy = wl_fixed_to_int(sy_w) * xwl_screen->global_surface_scale;
|
||||
|
||||
xwl_seat->xwl_screen->serial = serial;
|
||||
xwl_seat->pointer_enter_serial = serial;
|
||||
|
||||
|
@ -624,6 +627,7 @@ pointer_handle_leave(void *data, struct wl_pointer *pointer,
|
|||
static void
|
||||
dispatch_relative_motion_with_warp(struct xwl_seat *xwl_seat)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
|
||||
double dx, dx_unaccel;
|
||||
double dy, dy_unaccel;
|
||||
|
||||
|
@ -632,6 +636,11 @@ dispatch_relative_motion_with_warp(struct xwl_seat *xwl_seat)
|
|||
dx_unaccel = xwl_seat->pending_pointer_event.dx_unaccel;
|
||||
dy_unaccel = xwl_seat->pending_pointer_event.dy_unaccel;
|
||||
|
||||
dx *= xwl_screen->global_surface_scale;
|
||||
dy *= xwl_screen->global_surface_scale;
|
||||
dx_unaccel *= xwl_screen->global_surface_scale;
|
||||
dy_unaccel *= xwl_screen->global_surface_scale;
|
||||
|
||||
xwl_pointer_warp_emulator_handle_motion(xwl_seat->pointer_warp_emulator,
|
||||
dx, dy,
|
||||
dx_unaccel, dy_unaccel);
|
||||
|
@ -640,6 +649,7 @@ dispatch_relative_motion_with_warp(struct xwl_seat *xwl_seat)
|
|||
static void
|
||||
dispatch_absolute_motion(struct xwl_seat *xwl_seat)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
|
||||
ValuatorMask mask;
|
||||
DeviceIntPtr device;
|
||||
int flags;
|
||||
|
@ -650,6 +660,9 @@ dispatch_absolute_motion(struct xwl_seat *xwl_seat)
|
|||
int x;
|
||||
int y;
|
||||
|
||||
event_x *= xwl_screen->global_surface_scale;
|
||||
event_y *= xwl_screen->global_surface_scale;
|
||||
|
||||
if (xwl_window_has_viewport_enabled(xwl_seat->focus_window)) {
|
||||
event_x *= xwl_seat->focus_window->scale_x;
|
||||
event_y *= xwl_seat->focus_window->scale_y;
|
||||
|
@ -676,12 +689,18 @@ dispatch_absolute_motion(struct xwl_seat *xwl_seat)
|
|||
static void
|
||||
dispatch_relative_motion(struct xwl_seat *xwl_seat)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
|
||||
ValuatorMask mask;
|
||||
double event_dx = xwl_seat->pending_pointer_event.dx;
|
||||
double event_dy = xwl_seat->pending_pointer_event.dy;
|
||||
double event_dx_unaccel = xwl_seat->pending_pointer_event.dx_unaccel;
|
||||
double event_dy_unaccel = xwl_seat->pending_pointer_event.dy_unaccel;
|
||||
|
||||
event_dx *= xwl_screen->global_surface_scale;
|
||||
event_dy *= xwl_screen->global_surface_scale;
|
||||
event_dx_unaccel *= xwl_screen->global_surface_scale;
|
||||
event_dy_unaccel *= xwl_screen->global_surface_scale;
|
||||
|
||||
valuator_mask_zero(&mask);
|
||||
valuator_mask_set_unaccelerated(&mask, 0, event_dx, event_dx_unaccel);
|
||||
valuator_mask_set_unaccelerated(&mask, 1, event_dy, event_dy_unaccel);
|
||||
|
@ -955,9 +974,13 @@ pointer_gesture_swipe_handle_update(void *data,
|
|||
wl_fixed_t dyf)
|
||||
{
|
||||
struct xwl_seat *xwl_seat = data;
|
||||
struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
|
||||
double dx = wl_fixed_to_double(dxf);
|
||||
double dy = wl_fixed_to_double(dyf);
|
||||
|
||||
dx *= xwl_screen->global_surface_scale;
|
||||
dy *= xwl_screen->global_surface_scale;
|
||||
|
||||
QueueGestureSwipeEvents(xwl_seat->pointer_gestures,
|
||||
XI_GestureSwipeUpdate,
|
||||
xwl_seat->pointer_gesture_swipe_fingers,
|
||||
|
@ -1021,10 +1044,14 @@ pointer_gesture_pinch_handle_update(void *data,
|
|||
wl_fixed_t rotation)
|
||||
{
|
||||
struct xwl_seat *xwl_seat = data;
|
||||
struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
|
||||
double dx = wl_fixed_to_double(dxf);
|
||||
double dy = wl_fixed_to_double(dyf);
|
||||
double scale = wl_fixed_to_double(scalef);
|
||||
|
||||
dx *= xwl_screen->global_surface_scale;
|
||||
dy *= xwl_screen->global_surface_scale;
|
||||
|
||||
xwl_seat->pointer_gesture_pinch_last_scale = scale;
|
||||
QueueGesturePinchEvents(xwl_seat->pointer_gestures,
|
||||
XI_GesturePinchUpdate,
|
||||
|
@ -1403,6 +1430,7 @@ touch_handle_down(void *data, struct wl_touch *wl_touch,
|
|||
int32_t id, wl_fixed_t sx_w, wl_fixed_t sy_w)
|
||||
{
|
||||
struct xwl_seat *xwl_seat = data;
|
||||
struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
|
||||
struct xwl_touch *xwl_touch;
|
||||
|
||||
if (surface == NULL)
|
||||
|
@ -1423,6 +1451,9 @@ touch_handle_down(void *data, struct wl_touch *wl_touch,
|
|||
xwl_touch->y = wl_fixed_to_int(sy_w);
|
||||
xorg_list_add(&xwl_touch->link_touch, &xwl_seat->touches);
|
||||
|
||||
xwl_touch->x *= xwl_screen->global_surface_scale;
|
||||
xwl_touch->y *= xwl_screen->global_surface_scale;
|
||||
|
||||
xwl_touch_send_event(xwl_touch, xwl_seat, XI_TouchBegin);
|
||||
}
|
||||
|
||||
|
@ -1449,6 +1480,7 @@ touch_handle_motion(void *data, struct wl_touch *wl_touch,
|
|||
wl_fixed_t sx_w, wl_fixed_t sy_w)
|
||||
{
|
||||
struct xwl_seat *xwl_seat = data;
|
||||
struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
|
||||
struct xwl_touch *xwl_touch;
|
||||
|
||||
xwl_touch = xwl_seat_lookup_touch(xwl_seat, id);
|
||||
|
@ -1458,6 +1490,10 @@ touch_handle_motion(void *data, struct wl_touch *wl_touch,
|
|||
|
||||
xwl_touch->x = wl_fixed_to_int(sx_w);
|
||||
xwl_touch->y = wl_fixed_to_int(sy_w);
|
||||
|
||||
xwl_touch->x *= xwl_screen->global_surface_scale;
|
||||
xwl_touch->y *= xwl_screen->global_surface_scale;
|
||||
|
||||
xwl_touch_send_event(xwl_touch, xwl_seat, XI_TouchUpdate);
|
||||
}
|
||||
|
||||
|
@ -2146,6 +2182,7 @@ tablet_tool_motion(void *data, struct zwp_tablet_tool_v2 *tool,
|
|||
{
|
||||
struct xwl_tablet_tool *xwl_tablet_tool = data;
|
||||
struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
|
||||
struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
|
||||
int32_t dx, dy;
|
||||
double sx = wl_fixed_to_double(x);
|
||||
double sy = wl_fixed_to_double(y);
|
||||
|
@ -2153,6 +2190,9 @@ tablet_tool_motion(void *data, struct zwp_tablet_tool_v2 *tool,
|
|||
if (!xwl_seat->tablet_focus_window)
|
||||
return;
|
||||
|
||||
sx *= xwl_screen->global_surface_scale;
|
||||
sy *= xwl_screen->global_surface_scale;
|
||||
|
||||
dx = xwl_seat->tablet_focus_window->window->drawable.x;
|
||||
dy = xwl_seat->tablet_focus_window->window->drawable.y;
|
||||
|
||||
|
@ -2186,12 +2226,16 @@ tablet_tool_tilt(void *data, struct zwp_tablet_tool_v2 *tool,
|
|||
{
|
||||
struct xwl_tablet_tool *xwl_tablet_tool = data;
|
||||
struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
|
||||
struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
|
||||
|
||||
if (!xwl_seat->tablet_focus_window)
|
||||
return;
|
||||
|
||||
xwl_tablet_tool->tilt_x = wl_fixed_to_double(tilt_x);
|
||||
xwl_tablet_tool->tilt_y = wl_fixed_to_double(tilt_y);
|
||||
|
||||
xwl_tablet_tool->tilt_x *= xwl_screen->global_surface_scale;
|
||||
xwl_tablet_tool->tilt_y *= xwl_screen->global_surface_scale;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <X11/X.h>
|
||||
|
@ -266,6 +267,9 @@ xwl_window_enable_viewport(struct xwl_window *xwl_window,
|
|||
struct xwl_output *xwl_output,
|
||||
struct xwl_emulated_mode *emulated_mode)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
|
||||
int width, height;
|
||||
|
||||
if (!xwl_window_has_viewport_enabled(xwl_window)) {
|
||||
DebugF("XWAYLAND: enabling viewport %dx%d -> %dx%d\n",
|
||||
emulated_mode->width, emulated_mode->height,
|
||||
|
@ -274,17 +278,20 @@ xwl_window_enable_viewport(struct xwl_window *xwl_window,
|
|||
xwl_window->surface);
|
||||
}
|
||||
|
||||
width = emulated_mode->width / xwl_screen->global_surface_scale;
|
||||
height = emulated_mode->height / xwl_screen->global_surface_scale;
|
||||
|
||||
wp_viewport_set_source(xwl_window->viewport,
|
||||
wl_fixed_from_int(0),
|
||||
wl_fixed_from_int(0),
|
||||
wl_fixed_from_int(emulated_mode->width),
|
||||
wl_fixed_from_int(emulated_mode->height));
|
||||
wl_fixed_from_int(width),
|
||||
wl_fixed_from_int(height));
|
||||
wp_viewport_set_destination(xwl_window->viewport,
|
||||
xwl_output->width,
|
||||
xwl_output->height);
|
||||
|
||||
xwl_window->scale_x = (float)emulated_mode->width / xwl_output->width;
|
||||
xwl_window->scale_y = (float)emulated_mode->height / xwl_output->height;
|
||||
xwl_window->scale_x = (float) width / xwl_output->width;
|
||||
xwl_window->scale_y = (float) height / xwl_output->height;
|
||||
}
|
||||
|
||||
static Bool
|
||||
|
@ -641,12 +648,20 @@ xwl_window_maybe_resize(struct xwl_window *xwl_window, double width, double heig
|
|||
{
|
||||
struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
|
||||
struct xwl_output *xwl_output;
|
||||
double scale;
|
||||
RRModePtr mode;
|
||||
|
||||
/* Clamp the size */
|
||||
width = min(max(width, MIN_ROOTFUL_WIDTH), MAX_ROOTFUL_WIDTH);
|
||||
height = min(max(height, MIN_ROOTFUL_HEIGHT), MAX_ROOTFUL_HEIGHT);
|
||||
|
||||
/* Make sure the size is a multiple of the scale, it's a protocol error otherwise. */
|
||||
scale = xwl_screen->global_surface_scale;
|
||||
if (scale > 1.0) {
|
||||
width = round(width / scale) * scale;
|
||||
height = round(height / scale) * scale;
|
||||
}
|
||||
|
||||
if (width == xwl_screen->width && height == xwl_screen->height)
|
||||
return;
|
||||
|
||||
|
@ -667,10 +682,18 @@ xwl_window_maybe_resize(struct xwl_window *xwl_window, double width, double heig
|
|||
static void
|
||||
xwl_window_libdecor_set_size_limits(struct xwl_window *xwl_window)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
|
||||
|
||||
libdecor_frame_set_min_content_size(xwl_window->libdecor_frame,
|
||||
MIN_ROOTFUL_WIDTH, MIN_ROOTFUL_HEIGHT);
|
||||
MIN_ROOTFUL_WIDTH /
|
||||
xwl_screen->global_surface_scale,
|
||||
MIN_ROOTFUL_HEIGHT /
|
||||
xwl_screen->global_surface_scale);
|
||||
libdecor_frame_set_max_content_size(xwl_window->libdecor_frame,
|
||||
MAX_ROOTFUL_WIDTH, MAX_ROOTFUL_HEIGHT);
|
||||
MAX_ROOTFUL_WIDTH /
|
||||
xwl_screen->global_surface_scale,
|
||||
MAX_ROOTFUL_HEIGHT /
|
||||
xwl_screen->global_surface_scale);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -701,11 +724,21 @@ handle_libdecor_configure(struct libdecor_frame *frame,
|
|||
new_width = (double) width;
|
||||
new_height = (double) height;
|
||||
}
|
||||
else {
|
||||
new_width = xwl_screen->width / xwl_screen->global_surface_scale;
|
||||
new_height = xwl_screen->height / xwl_screen->global_surface_scale;
|
||||
}
|
||||
|
||||
new_width *= xwl_screen->global_surface_scale;
|
||||
new_height *= xwl_screen->global_surface_scale;
|
||||
|
||||
xwl_window_maybe_resize(xwl_window, new_width, new_height);
|
||||
|
||||
new_width = xwl_screen->width / xwl_screen->global_surface_scale;
|
||||
new_height = xwl_screen->height / xwl_screen->global_surface_scale;
|
||||
|
||||
xwl_window_update_libdecor_size(xwl_window, configuration,
|
||||
xwl_screen_get_width(xwl_screen),
|
||||
xwl_screen_get_height(xwl_screen));
|
||||
round(new_width), round(new_height));
|
||||
wl_surface_commit(xwl_window->surface);
|
||||
}
|
||||
|
||||
|
@ -802,14 +835,17 @@ xdg_toplevel_handle_configure(void *data,
|
|||
struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
|
||||
uint32_t *p;
|
||||
Bool old_active = xwl_screen->active;
|
||||
int new_width, new_height;
|
||||
|
||||
/* Maintain our current size if no dimensions are requested */
|
||||
if (width == 0 && height == 0)
|
||||
return;
|
||||
|
||||
if (!xwl_screen->fullscreen) {
|
||||
new_width = width * xwl_screen->global_surface_scale;
|
||||
new_height = height * xwl_screen->global_surface_scale;
|
||||
/* This will be committed by the xdg_surface.configure handler */
|
||||
xwl_window_maybe_resize(xwl_window, width, height);
|
||||
xwl_window_maybe_resize(xwl_window, new_width, new_height);
|
||||
}
|
||||
|
||||
xwl_screen->active = FALSE;
|
||||
|
@ -1273,8 +1309,14 @@ xwl_resize_window(WindowPtr window,
|
|||
if (xwl_window_get(window) || xwl_window_is_toplevel(window))
|
||||
xwl_window_check_resolution_change_emulation(xwl_window);
|
||||
#ifdef XWL_HAS_LIBDECOR
|
||||
if (window == screen->root)
|
||||
xwl_window_update_libdecor_size(xwl_window, NULL, width, height);
|
||||
if (window == screen->root) {
|
||||
unsigned int decor_width, decor_height;
|
||||
|
||||
decor_width = width / xwl_screen->global_surface_scale;
|
||||
decor_height = height / xwl_screen->global_surface_scale;
|
||||
xwl_window_update_libdecor_size(xwl_window, NULL,
|
||||
decor_width, decor_height);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue