diff --git a/nix/patches/wlroots-hidpi.patch b/nix/patches/wlroots-hidpi.patch deleted file mode 100644 index fd4c8955..00000000 --- a/nix/patches/wlroots-hidpi.patch +++ /dev/null @@ -1,164 +0,0 @@ -diff --git a/include/xwayland/xwm.h b/include/xwayland/xwm.h -index 3d540522..1c5a2e37 100644 ---- a/include/xwayland/xwm.h -+++ b/include/xwayland/xwm.h -@@ -88,6 +88,7 @@ enum atom_name { - DND_ACTION_PRIVATE, - NET_CLIENT_LIST, - NET_CLIENT_LIST_STACKING, -+ XWAYLAND_GLOBAL_OUTPUT_SCALE, - ATOM_LAST // keep last - }; - -@@ -96,6 +97,7 @@ struct wlr_xwm { - struct wl_event_source *event_source; - struct wlr_seat *seat; - uint32_t ping_timeout; -+ uint32_t scale; - - xcb_atom_t atoms[ATOM_LAST]; - xcb_connection_t *xcb_conn; -diff --git a/xwayland/xwm.c b/xwayland/xwm.c -index 5f857f24..21584ebd 100644 ---- a/xwayland/xwm.c -+++ b/xwayland/xwm.c -@@ -19,6 +19,14 @@ - #include - #include "xwayland/xwm.h" - -+static int32_t scale(struct wlr_xwm *xwm, uint32_t val) { -+ return val * xwm->scale; -+} -+ -+static int32_t unscale(struct wlr_xwm *xwm, uint32_t val) { -+ return (val + xwm->scale/2) / xwm->scale; -+} -+ - static const char *const atom_map[ATOM_LAST] = { - [WL_SURFACE_ID] = "WL_SURFACE_ID", - [WL_SURFACE_SERIAL] = "WL_SURFACE_SERIAL", -@@ -90,6 +98,7 @@ static const char *const atom_map[ATOM_LAST] = { - [DND_ACTION_PRIVATE] = "XdndActionPrivate", - [NET_CLIENT_LIST] = "_NET_CLIENT_LIST", - [NET_CLIENT_LIST_STACKING] = "_NET_CLIENT_LIST_STACKING", -+ [XWAYLAND_GLOBAL_OUTPUT_SCALE] = "_XWAYLAND_GLOBAL_OUTPUT_SCALE", - }; - - #define STARTUP_INFO_REMOVE_PREFIX "remove: ID=" -@@ -965,8 +974,8 @@ static void xwm_handle_create_notify(struct wlr_xwm *xwm, - return; - } - -- xwayland_surface_create(xwm, ev->window, ev->x, ev->y, -- ev->width, ev->height, ev->override_redirect); -+ xwayland_surface_create(xwm, ev->window, unscale(xwm, ev->x), unscale(xwm, ev->y), -+ unscale(xwm, ev->width), unscale(xwm, ev->height), ev->override_redirect); - } - - static void xwm_handle_destroy_notify(struct wlr_xwm *xwm, -@@ -997,10 +1006,10 @@ static void xwm_handle_configure_request(struct wlr_xwm *xwm, - - struct wlr_xwayland_surface_configure_event wlr_event = { - .surface = surface, -- .x = mask & XCB_CONFIG_WINDOW_X ? ev->x : surface->x, -- .y = mask & XCB_CONFIG_WINDOW_Y ? ev->y : surface->y, -- .width = mask & XCB_CONFIG_WINDOW_WIDTH ? ev->width : surface->width, -- .height = mask & XCB_CONFIG_WINDOW_HEIGHT ? ev->height : surface->height, -+ .x = mask & XCB_CONFIG_WINDOW_X ? unscale(xwm, ev->x) : surface->x, -+ .y = mask & XCB_CONFIG_WINDOW_Y ? unscale(xwm, ev->y) : surface->y, -+ .width = mask & XCB_CONFIG_WINDOW_WIDTH ? unscale(xwm, ev->width) : surface->width, -+ .height = mask & XCB_CONFIG_WINDOW_HEIGHT ? unscale(xwm, ev->height) : surface->height, - .mask = mask, - }; - -@@ -1015,14 +1024,14 @@ static void xwm_handle_configure_notify(struct wlr_xwm *xwm, - } - - bool geometry_changed = -- (xsurface->x != ev->x || xsurface->y != ev->y || -- xsurface->width != ev->width || xsurface->height != ev->height); -+ (xsurface->x != unscale(xwm, ev->x) || xsurface->y != unscale(xwm, ev->y) || -+ xsurface->width != unscale(xwm, ev->width) || xsurface->height != unscale(xwm, ev->height)); - - if (geometry_changed) { -- xsurface->x = ev->x; -- xsurface->y = ev->y; -- xsurface->width = ev->width; -- xsurface->height = ev->height; -+ xsurface->x = unscale(xwm, ev->x); -+ xsurface->y = unscale(xwm, ev->y); -+ xsurface->width = unscale(xwm, ev->width); -+ xsurface->height = unscale(xwm, ev->height); - } - - if (xsurface->override_redirect != ev->override_redirect) { -@@ -1133,6 +1142,20 @@ static void xwm_handle_property_notify(struct wlr_xwm *xwm, - xcb_property_notify_event_t *ev) { - struct wlr_xwayland_surface *xsurface = lookup_surface(xwm, ev->window); - if (xsurface == NULL) { -+ if (ev->atom == xwm->atoms[XWAYLAND_GLOBAL_OUTPUT_SCALE]) { -+ xcb_get_property_cookie_t cookie = xcb_get_property(xwm->xcb_conn, 0, -+ ev->window, ev->atom, XCB_ATOM_ANY, 0, 2048); -+ xcb_get_property_reply_t *reply = xcb_get_property_reply(xwm->xcb_conn, -+ cookie, NULL); -+ if (reply == NULL) { -+ return; -+ } -+ if (reply->type == XCB_ATOM_CARDINAL) { -+ xwm->scale = *(uint32_t*)xcb_get_property_value(reply); -+ } -+ free(reply); -+ } -+ - return; - } - -@@ -1760,16 +1783,17 @@ void wlr_xwayland_surface_configure(struct wlr_xwayland_surface *xsurface, - int old_w = xsurface->width; - int old_h = xsurface->height; - -+ struct wlr_xwm *xwm = xsurface->xwm; -+ - xsurface->x = x; - xsurface->y = y; - xsurface->width = width; - xsurface->height = height; - -- struct wlr_xwm *xwm = xsurface->xwm; - uint32_t mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | - XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT | - XCB_CONFIG_WINDOW_BORDER_WIDTH; -- uint32_t values[] = {x, y, width, height, 0}; -+ uint32_t values[] = {scale(xwm, x), scale(xwm, y), scale(xwm, width), scale(xwm, height), 0}; - xcb_configure_window(xwm->xcb_conn, xsurface->window_id, mask, values); - - // If the window size did not change, then we cannot rely on -@@ -1777,15 +1801,15 @@ void wlr_xwayland_surface_configure(struct wlr_xwayland_surface *xsurface, - // we are supposed to send a synthetic event. See ICCCM part - // 4.1.5. But we ignore override-redirect windows as ICCCM does - // not apply to them. -- if (width == old_w && height == old_h && !xsurface->override_redirect) { -+ if (scale(xwm, width) == scale(xwm, old_w) && scale(xwm, height) == scale(xwm, old_h) && !xsurface->override_redirect) { - xcb_configure_notify_event_t configure_notify = { - .response_type = XCB_CONFIGURE_NOTIFY, - .event = xsurface->window_id, - .window = xsurface->window_id, -- .x = x, -- .y = y, -- .width = width, -- .height = height, -+ .x = scale(xwm, x), -+ .y = scale(xwm, y), -+ .width = scale(xwm, width), -+ .height = scale(xwm, height), - }; - - xcb_send_event(xwm->xcb_conn, 0, xsurface->window_id, -@@ -2122,6 +2146,7 @@ struct wlr_xwm *xwm_create(struct wlr_xwayland *xwayland, int wm_fd) { - wl_list_init(&xwm->pending_startup_ids); - xwm->ping_timeout = 10000; - -+ xwm->scale = 1; - xwm->xcb_conn = xcb_connect_to_fd(wm_fd, NULL); - - int rc = xcb_connection_has_error(xwm->xcb_conn); diff --git a/nix/patches/xwayland-hidpi.patch b/nix/patches/xwayland-hidpi.patch deleted file mode 100644 index a652ec85..00000000 --- a/nix/patches/xwayland-hidpi.patch +++ /dev/null @@ -1,493 +0,0 @@ -diff --git a/hw/xwayland/xwayland-cursor.c b/hw/xwayland/xwayland-cursor.c -index e3c1aaa50..eba29b5ba 100644 ---- a/hw/xwayland/xwayland-cursor.c -+++ b/hw/xwayland/xwayland-cursor.c -@@ -164,6 +164,8 @@ xwl_cursor_attach_pixmap(struct xwl_seat *xwl_seat, - } - - wl_surface_attach(xwl_cursor->surface, buffer, 0, 0); -+ wl_surface_set_buffer_scale(xwl_cursor->surface, -+ xwl_seat->xwl_screen->global_output_scale); - xwl_surface_damage(xwl_seat->xwl_screen, xwl_cursor->surface, 0, 0, - xwl_seat->x_cursor->bits->width, - xwl_seat->x_cursor->bits->height); -@@ -195,6 +197,7 @@ xwl_cursor_clear_frame_cb(struct xwl_cursor *xwl_cursor) - void - xwl_seat_set_cursor(struct xwl_seat *xwl_seat) - { -+ struct xwl_screen *xwl_screen = xwl_seat->xwl_screen; - struct xwl_cursor *xwl_cursor = &xwl_seat->cursor; - PixmapPtr pixmap; - CursorPtr cursor; -@@ -225,8 +228,8 @@ xwl_seat_set_cursor(struct xwl_seat *xwl_seat) - 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); -+ xwl_scale_to(xwl_screen, xwl_seat->x_cursor->bits->xhot), -+ xwl_scale_to(xwl_screen, xwl_seat->x_cursor->bits->yhot)); - - xwl_cursor_attach_pixmap(xwl_seat, xwl_cursor, pixmap); - } -@@ -235,6 +238,7 @@ 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; -@@ -263,8 +267,9 @@ xwl_tablet_tool_set_cursor(struct xwl_tablet_tool *xwl_tablet_tool) - 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); -+ xwl_scale_to(xwl_screen, xwl_seat->x_cursor->bits->xhot), -+ xwl_scale_to(xwl_screen, xwl_seat->x_cursor->bits->yhot)); -+ wl_surface_set_buffer_scale(xwl_cursor->surface, xwl_screen->global_output_scale); - - xwl_cursor_attach_pixmap(xwl_seat, xwl_cursor, pixmap); - } -diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c -index 6e0600e4e..4a22ebff0 100644 ---- a/hw/xwayland/xwayland-input.c -+++ b/hw/xwayland/xwayland-input.c -@@ -507,8 +507,8 @@ pointer_handle_enter(void *data, struct wl_pointer *pointer, - 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 = wl_fixed_to_int(sx_w) * xwl_seat->xwl_screen->global_output_scale; -+ int sy = wl_fixed_to_int(sy_w) * xwl_seat->xwl_screen->global_output_scale; - int dx, dy; - ScreenPtr pScreen = xwl_seat->xwl_screen->screen; - ValuatorMask mask; -@@ -731,13 +731,14 @@ pointer_handle_motion(void *data, struct wl_pointer *pointer, - uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w) - { - struct xwl_seat *xwl_seat = data; -+ int32_t scale = xwl_seat->xwl_screen->global_output_scale; - - if (!xwl_seat->focus_window) - return; - - xwl_seat->pending_pointer_event.has_absolute = TRUE; -- xwl_seat->pending_pointer_event.x = sx_w; -- xwl_seat->pending_pointer_event.y = sy_w; -+ xwl_seat->pending_pointer_event.x = sx_w * scale; -+ xwl_seat->pending_pointer_event.y = sy_w * scale; - - if (wl_proxy_get_version((struct wl_proxy *) xwl_seat->wl_pointer) < 5) - dispatch_pointer_motion_event(xwl_seat); -@@ -887,12 +888,13 @@ relative_pointer_handle_relative_motion(void *data, - wl_fixed_t dy_unaccelf) - { - struct xwl_seat *xwl_seat = data; -+ int32_t scale = xwl_seat->xwl_screen->global_output_scale; - - xwl_seat->pending_pointer_event.has_relative = TRUE; -- xwl_seat->pending_pointer_event.dx = wl_fixed_to_double(dxf); -- xwl_seat->pending_pointer_event.dy = wl_fixed_to_double(dyf); -- xwl_seat->pending_pointer_event.dx_unaccel = wl_fixed_to_double(dx_unaccelf); -- xwl_seat->pending_pointer_event.dy_unaccel = wl_fixed_to_double(dy_unaccelf); -+ xwl_seat->pending_pointer_event.dx = wl_fixed_to_double(dxf) * scale; -+ xwl_seat->pending_pointer_event.dy = wl_fixed_to_double(dyf) * scale; -+ xwl_seat->pending_pointer_event.dx_unaccel = wl_fixed_to_double(dx_unaccelf) * scale; -+ xwl_seat->pending_pointer_event.dy_unaccel = wl_fixed_to_double(dy_unaccelf) * scale; - - if (!xwl_seat->focus_window) - return; -@@ -1382,8 +1384,8 @@ touch_handle_down(void *data, struct wl_touch *wl_touch, - - xwl_touch->window = wl_surface_get_user_data(surface); - xwl_touch->id = id; -- xwl_touch->x = wl_fixed_to_int(sx_w); -- xwl_touch->y = wl_fixed_to_int(sy_w); -+ xwl_touch->x = wl_fixed_to_int(sx_w) * xwl_seat->xwl_screen->global_output_scale; -+ xwl_touch->y = wl_fixed_to_int(sy_w) * xwl_seat->xwl_screen->global_output_scale; - xorg_list_add(&xwl_touch->link_touch, &xwl_seat->touches); - - xwl_touch_send_event(xwl_touch, xwl_seat, XI_TouchBegin); -@@ -1419,8 +1421,8 @@ touch_handle_motion(void *data, struct wl_touch *wl_touch, - if (!xwl_touch) - return; - -- xwl_touch->x = wl_fixed_to_int(sx_w); -- xwl_touch->y = wl_fixed_to_int(sy_w); -+ xwl_touch->x = wl_fixed_to_int(sx_w) * xwl_seat->xwl_screen->global_output_scale; -+ xwl_touch->y = wl_fixed_to_int(sy_w) * xwl_seat->xwl_screen->global_output_scale; - xwl_touch_send_event(xwl_touch, xwl_seat, XI_TouchUpdate); - } - -@@ -2110,8 +2112,8 @@ 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; - int32_t dx, dy; -- double sx = wl_fixed_to_double(x); -- double sy = wl_fixed_to_double(y); -+ double sx = wl_fixed_to_double(x) * xwl_seat->xwl_screen->global_output_scale; -+ double sy = wl_fixed_to_double(y) * xwl_seat->xwl_screen->global_output_scale; - - if (!xwl_seat->tablet_focus_window) - return; -@@ -3152,6 +3154,7 @@ xwl_pointer_warp_emulator_set_fake_pos(struct xwl_pointer_warp_emulator *warp_em - int x, - int y) - { -+ struct xwl_screen *xwl_screen; - struct zwp_locked_pointer_v1 *locked_pointer = - warp_emulator->locked_pointer; - WindowPtr window; -@@ -3163,6 +3166,7 @@ xwl_pointer_warp_emulator_set_fake_pos(struct xwl_pointer_warp_emulator *warp_em - if (!warp_emulator->xwl_seat->focus_window) - return; - -+ xwl_screen = warp_emulator->xwl_seat->xwl_screen; - window = warp_emulator->xwl_seat->focus_window->window; - if (x >= window->drawable.x || - y >= window->drawable.y || -@@ -3171,8 +3175,8 @@ xwl_pointer_warp_emulator_set_fake_pos(struct xwl_pointer_warp_emulator *warp_em - sx = x - window->drawable.x; - sy = y - window->drawable.y; - zwp_locked_pointer_v1_set_cursor_position_hint(locked_pointer, -- wl_fixed_from_int(sx), -- wl_fixed_from_int(sy)); -+ wl_fixed_from_int(xwl_scale_to(xwl_screen, sx)), -+ wl_fixed_from_int(xwl_scale_to(xwl_screen, sy))); - wl_surface_commit(warp_emulator->xwl_seat->focus_window->surface); - } - } -diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c -index 661e1828d..6c60aba34 100644 ---- a/hw/xwayland/xwayland-output.c -+++ b/hw/xwayland/xwayland-output.c -@@ -186,6 +186,9 @@ update_backing_pixmaps(struct xwl_screen *xwl_screen, int width, int height) - static void - update_screen_size(struct xwl_screen *xwl_screen, int width, int height) - { -+ width *= xwl_screen->global_output_scale; -+ height *= xwl_screen->global_output_scale; -+ - xwl_screen->width = width; - xwl_screen->height = height; - -@@ -597,14 +600,15 @@ xwl_output_set_emulated_mode(struct xwl_output *xwl_output, ClientPtr client, - new_emulated_height); - } - --static void --apply_output_change(struct xwl_output *xwl_output) -+void -+xwl_output_apply_changes(struct xwl_output *xwl_output) - { - struct xwl_screen *xwl_screen = xwl_output->xwl_screen; - struct xwl_output *it; - int mode_width, mode_height, count; - int width = 0, height = 0, has_this_output = 0; - RRModePtr *randr_modes; -+ int32_t scale = xwl_screen->global_output_scale; - - /* Clear out the "done" received flags */ - xwl_output->wl_output_done = FALSE; -@@ -623,10 +627,10 @@ apply_output_change(struct xwl_output *xwl_output) - } - if (xwl_output->randr_output) { - /* Build a fresh modes array using the current refresh rate */ -- randr_modes = output_get_rr_modes(xwl_output, mode_width, mode_height, &count); -+ randr_modes = output_get_rr_modes(xwl_output, mode_width * scale, mode_height * scale, &count); - RROutputSetModes(xwl_output->randr_output, randr_modes, count, 1); - RRCrtcNotify(xwl_output->randr_crtc, randr_modes[0], -- xwl_output->x, xwl_output->y, -+ xwl_output->x * scale, xwl_output->y * scale, - xwl_output->rotation, NULL, 1, &xwl_output->randr_output); - /* RROutputSetModes takes ownership of the passed in modes, so we only - * have to free the pointer array. -@@ -686,7 +690,7 @@ output_handle_done(void *data, struct wl_output *wl_output) - */ - if (xwl_output->xdg_output_done || !xwl_output->xdg_output || - zxdg_output_v1_get_version(xwl_output->xdg_output) >= 3) -- apply_output_change(xwl_output); -+ xwl_output_apply_changes(xwl_output); - } - - static void -@@ -746,7 +750,7 @@ xdg_output_handle_done(void *data, struct zxdg_output_v1 *xdg_output) - xwl_output->xdg_output_done = TRUE; - if (xwl_output->wl_output_done && - zxdg_output_v1_get_version(xdg_output) < 3) -- apply_output_change(xwl_output); -+ xwl_output_apply_changes(xwl_output); - } - - static void -@@ -857,6 +861,8 @@ xwl_output_create(struct xwl_screen *xwl_screen, uint32_t id, - RRCrtcGammaSetSize(xwl_output->randr_crtc, 256); - RROutputSetCrtcs(xwl_output->randr_output, &xwl_output->randr_crtc, 1); - RROutputSetConnection(xwl_output->randr_output, RR_Connected); -+ -+ xwl_output->scale = 1; - } - /* We want the output to be in the list as soon as created so we can - * use it when binding to the xdg-output protocol... -diff --git a/hw/xwayland/xwayland-output.h b/hw/xwayland/xwayland-output.h -index a95288e4f..46d1ead2a 100644 ---- a/hw/xwayland/xwayland-output.h -+++ b/hw/xwayland/xwayland-output.h -@@ -53,7 +53,7 @@ struct xwl_output { - struct wl_output *output; - struct zxdg_output_v1 *xdg_output; - uint32_t server_output_id; -- int32_t x, y, width, height, refresh; -+ int32_t x, y, width, height, refresh, scale; - Rotation rotation; - Bool wl_output_done; - Bool xdg_output_done; -@@ -102,6 +102,8 @@ void xwl_output_set_emulated_mode(struct xwl_output *xwl_output, - void xwl_output_set_window_randr_emu_props(struct xwl_screen *xwl_screen, - WindowPtr window); - -+void xwl_output_apply_changes(struct xwl_output *xwl_output); -+ - void xwl_screen_init_xdg_output(struct xwl_screen *xwl_screen); - - #endif /* XWAYLAND_OUTPUT_H */ -diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c -index 189e7cfd6..555434031 100644 ---- a/hw/xwayland/xwayland-present.c -+++ b/hw/xwayland/xwayland-present.c -@@ -764,6 +764,8 @@ xwl_present_flip(WindowPtr present_window, - - /* We can flip directly to the main surface (full screen window without clips) */ - wl_surface_attach(xwl_window->surface, buffer, 0, 0); -+ wl_surface_set_buffer_scale(xwl_window->surface, -+ xwl_window->xwl_screen->global_output_scale); - - if (xorg_list_is_empty(&xwl_present_window->frame_callback_list)) { - xorg_list_add(&xwl_present_window->frame_callback_list, -diff --git a/hw/xwayland/xwayland-screen.c b/hw/xwayland/xwayland-screen.c -index 46ab4fed7..b2d7022e6 100644 ---- a/hw/xwayland/xwayland-screen.c -+++ b/hw/xwayland/xwayland-screen.c -@@ -51,6 +51,7 @@ - #include "xwayland-pixmap.h" - #include "xwayland-present.h" - #include "xwayland-shm.h" -+#include "xwayland-window-buffers.h" - - #ifdef MITSHM - #include "shmint.h" -@@ -111,6 +112,12 @@ xwl_screen_has_resolution_change_emulation(struct xwl_screen *xwl_screen) - return xwl_screen->rootless && xwl_screen_has_viewport_support(xwl_screen); - } - -+int -+xwl_scale_to(struct xwl_screen *xwl_screen, int value) -+{ -+ return value / (double)xwl_screen->global_output_scale + 0.5; -+} -+ - /* Return the output @ 0x0, falling back to the first output in the list */ - struct xwl_output * - xwl_screen_get_first_output(struct xwl_screen *xwl_screen) -@@ -128,6 +135,38 @@ xwl_screen_get_first_output(struct xwl_screen *xwl_screen) - return xorg_list_first_entry(&xwl_screen->output_list, struct xwl_output, link); - } - -+static void -+xwl_screen_set_global_scale_from_property(struct xwl_screen *screen, -+ PropertyPtr prop) -+{ -+ CARD32 *propdata; -+ -+ if (prop->type != XA_CARDINAL || prop->format != 32 || prop->size != 1) { -+ // TODO: handle warnings more cleanly. -+ LogMessageVerb(X_WARNING, 0, "Bad value for property %s.\n", -+ NameForAtom(prop->propertyName)); -+ return; -+ } -+ -+ propdata = prop->data; -+ xwl_screen_set_global_scale(screen, propdata[0]); -+} -+ -+static void -+xwl_screen_update_property(struct xwl_screen *screen, -+ PropertyStateRec *propstate) -+{ -+ switch (propstate->state) { -+ case PropertyNewValue: -+ xwl_screen_set_global_scale_from_property(screen, propstate->prop); -+ break; -+ case PropertyDelete: -+ xwl_screen_set_global_scale(screen, 1); -+ break; -+ } -+} -+ -+ - struct xwl_output * - xwl_screen_get_fixed_or_first_output(struct xwl_screen *xwl_screen) - { -@@ -144,19 +183,24 @@ xwl_property_callback(CallbackListPtr *pcbl, void *closure, - ScreenPtr screen = closure; - PropertyStateRec *rec = calldata; - struct xwl_screen *xwl_screen; -- struct xwl_window *xwl_window; - - if (rec->win->drawable.pScreen != screen) - return; - -- xwl_window = xwl_window_get(rec->win); -- if (!xwl_window) -- return; -- - xwl_screen = xwl_screen_get(screen); - -- if (rec->prop->propertyName == xwl_screen->allow_commits_prop) -- xwl_window_update_property(xwl_window, rec); -+ if (rec->prop->propertyName == xwl_screen->allow_commits_prop) { -+ struct xwl_window *xwl_window; -+ -+ xwl_window = xwl_window_get(rec->win); -+ if (!xwl_window) -+ return; -+ -+ xwl_window_update_property(xwl_window, rec); -+ } -+ else if (rec->prop->propertyName == xwl_screen->global_output_scale_prop) { -+ xwl_screen_update_property(xwl_screen, rec); -+ } - } - - static void -@@ -638,8 +682,14 @@ void xwl_surface_damage(struct xwl_screen *xwl_screen, - { - if (wl_surface_get_version(surface) >= WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION) - wl_surface_damage_buffer(surface, x, y, width, height); -- else -+ else { -+ x = xwl_scale_to(xwl_screen, x); -+ y = xwl_scale_to(xwl_screen, y); -+ width = xwl_scale_to(xwl_screen, width); -+ height = xwl_scale_to(xwl_screen, height); -+ - wl_surface_damage(surface, x, y, width, height); -+ } - } - - void -@@ -655,6 +705,30 @@ xwl_screen_roundtrip(struct xwl_screen *xwl_screen) - xwl_give_up("could not connect to wayland server\n"); - } - -+void -+xwl_screen_set_global_scale(struct xwl_screen *xwl_screen, int32_t scale) -+{ -+ struct xwl_output *it; -+ struct xwl_window *xwl_window; -+ -+ xwl_screen->global_output_scale = scale; -+ -+ /* change randr resolutions and positions */ -+ xorg_list_for_each_entry(it, &xwl_screen->output_list, link) { -+ xwl_output_apply_changes(it); -+ } -+ -+ if (!xwl_screen->rootless && xwl_screen->screen->root) { -+ /* Clear all the buffers, so that they'll be remade with the new sizes -+ * (this doesn't occur automatically because as far as Xorg is -+ * concerned, the window's size is the same) */ -+ xorg_list_for_each_entry(xwl_window, &xwl_screen->window_list, link_window) { -+ xwl_window_buffers_recycle(xwl_window); -+ } -+ } -+} -+ -+ - static int - xwl_server_grab(ClientPtr client) - { -@@ -712,6 +786,7 @@ Bool - xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) - { - static const char allow_commits[] = "_XWAYLAND_ALLOW_COMMITS"; -+ static const char global_output_scale[] = "_XWAYLAND_GLOBAL_OUTPUT_SCALE"; - struct xwl_screen *xwl_screen; - Pixel red_mask, blue_mask, green_mask; - int ret, bpc, green_bpc, i; -@@ -746,6 +821,7 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) - #ifdef XWL_HAS_GLAMOR - xwl_screen->glamor = 1; - #endif -+ xwl_screen->global_output_scale = 1; - - for (i = 1; i < argc; i++) { - if (strcmp(argv[i], "-rootless") == 0) { -@@ -988,6 +1064,13 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) - if (xwl_screen->allow_commits_prop == BAD_RESOURCE) - return FALSE; - -+ xwl_screen->global_output_scale_prop = MakeAtom(global_output_scale, -+ strlen(global_output_scale), -+ TRUE); -+ if (xwl_screen->global_output_scale_prop == BAD_RESOURCE) -+ return FALSE; -+ -+ - AddCallback(&PropertyStateCallback, xwl_property_callback, pScreen); - AddCallback(&RootWindowFinalizeCallback, xwl_root_window_finalized_callback, pScreen); - -diff --git a/hw/xwayland/xwayland-screen.h b/hw/xwayland/xwayland-screen.h -index fadd0526e..2ce6ce5ab 100644 ---- a/hw/xwayland/xwayland-screen.h -+++ b/hw/xwayland/xwayland-screen.h -@@ -87,6 +87,7 @@ struct xwl_screen { - struct xorg_list damage_window_list; - struct xorg_list window_list; - -+ int32_t global_output_scale; - int wayland_fd; - struct wl_display *display; - struct wl_registry *registry; -@@ -134,6 +135,7 @@ struct xwl_screen { - struct glamor_context *glamor_ctx; - - Atom allow_commits_prop; -+ Atom global_output_scale_prop; - - /* The preferred GLVND vendor. If NULL, "mesa" is assumed. */ - const char *glvnd_vendor; -@@ -166,6 +168,8 @@ void xwl_screen_roundtrip (struct xwl_screen *xwl_screen); - void xwl_surface_damage(struct xwl_screen *xwl_screen, - struct wl_surface *surface, - int32_t x, int32_t y, int32_t width, int32_t height); -+int xwl_scale_to(struct xwl_screen *xwl_screen, int value); -+void xwl_screen_set_global_scale(struct xwl_screen *xwl_screen, int32_t scale); - int xwl_screen_get_next_output_serial(struct xwl_screen * xwl_screen); - - #endif /* XWAYLAND_SCREEN_H */ -diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c -index 6b7f38605..2f1e0dee1 100644 ---- a/hw/xwayland/xwayland-window.c -+++ b/hw/xwayland/xwayland-window.c -@@ -788,7 +788,8 @@ xwl_create_root_surface(struct xwl_window *xwl_window) - } - - wl_region_add(region, 0, 0, -- window->drawable.width, window->drawable.height); -+ xwl_scale_to(xwl_screen, window->drawable.width), -+ xwl_scale_to(xwl_screen, window->drawable.height)); - wl_surface_set_opaque_region(xwl_window->surface, region); - wl_region_destroy(region); - -@@ -1322,6 +1323,7 @@ xwl_window_post_damage(struct xwl_window *xwl_window) - #endif - - wl_surface_attach(xwl_window->surface, buffer, 0, 0); -+ wl_surface_set_buffer_scale(xwl_window->surface, xwl_screen->global_output_scale); - - /* Arbitrary limit to try to avoid flooding the Wayland - * connection. If we flood it too much anyway, this could diff --git a/nix/patches/xwayland-vsync.patch b/nix/patches/xwayland-vsync.patch deleted file mode 100644 index 375db880..00000000 --- a/nix/patches/xwayland-vsync.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- a/hw/xwayland/xwayland-present.c -+++ b/hw/xwayland/xwayland-present.c -@@ -824,7 +824,8 @@ - dixDestroyPixmap(vblank->pixmap, vblank->pixmap->drawable.id); - vblank->pixmap = NULL; - -- if (xwl_present_queue_vblank(screen, window, vblank->crtc, -+ if (vblank->target_msc > crtc_msc && -+ xwl_present_queue_vblank(screen, window, vblank->crtc, - vblank->event_id, crtc_msc + 1) - == Success) - return;