From c386c52cf9fbd442e3c6efec4664d9907fd2cfb1 Mon Sep 17 00:00:00 2001 From: Mihai Fufezan Date: Sat, 4 Mar 2023 01:41:37 +0200 Subject: [PATCH] Nix: fix hidpi patch --- flake.nix | 11 +++ nix/wlroots-hidpi.patch | 164 ++++++++++++++++++++++++++++++++++++++++ nix/wlroots.nix | 8 +- 3 files changed, 178 insertions(+), 5 deletions(-) create mode 100644 nix/wlroots-hidpi.patch diff --git a/flake.nix b/flake.nix index 95587a66..269bd41e 100644 --- a/flake.nix +++ b/flake.nix @@ -47,6 +47,17 @@ sha256 = "sha256-/q79o13Zvu7x02SBGu0W5yQznQ+p7ltZ9L6cMW5t/o4="; }; }); + + libliftoff = prev.libliftoff.overrideAttrs (old: { + version = "0.5.0-dev"; + src = prev.fetchFromGitLab { + domain = "gitlab.freedesktop.org"; + owner = "emersion"; + repo = old.pname; + rev = "d98ae243280074b0ba44bff92215ae8d785658c0"; + sha256 = "sha256-DjwlS8rXE7srs7A8+tHqXyUsFGtucYSeq6X0T/pVOc8="; + }; + }); }) ]; }); diff --git a/nix/wlroots-hidpi.patch b/nix/wlroots-hidpi.patch new file mode 100644 index 00000000..a61fcb45 --- /dev/null +++ b/nix/wlroots-hidpi.patch @@ -0,0 +1,164 @@ +diff --git a/include/xwayland/xwm.h b/include/xwayland/xwm.h +index c69504e8..40d8de8c 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 + }; + +@@ -98,6 +99,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 5a36dc21..83981a87 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; ++} ++ + const char *const atom_map[ATOM_LAST] = { + [WL_SURFACE_ID] = "WL_SURFACE_ID", + [WL_SURFACE_SERIAL] = "WL_SURFACE_SERIAL", +@@ -90,6 +98,7 @@ 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=" +@@ -968,8 +977,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, +@@ -1000,10 +1009,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, + }; + +@@ -1018,14 +1027,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) { +@@ -1136,6 +1145,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; + } + +@@ -1763,16 +1786,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 +@@ -1780,15 +1804,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, +@@ -2125,6 +2149,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/wlroots.nix b/nix/wlroots.nix index 4413259e..ebc85a1b 100644 --- a/nix/wlroots.nix +++ b/nix/wlroots.nix @@ -9,7 +9,7 @@ hwdata, libliftoff, libdisplay-info, - hidpiXWayland ? false, + hidpiXWayland ? true, enableXWayland ? true, nvidiaPatches ? false, }: @@ -35,10 +35,8 @@ assert (lib.assertMsg (hidpiXWayland -> enableXWayland) '' patches = (old.patches or []) ++ (lib.optionals (enableXWayland && hidpiXWayland) [ - (fetchpatch { - url = "https://gitlab.freedesktop.org/lilydjwg/wlroots/-/commit/6c5ffcd1fee9e44780a6a8792f74ecfbe24a1ca7.diff"; - sha256 = "sha256-Eo1pTa/PIiJsRZwIUnHGTIFFIedzODVf0ZeuXb0a3TQ="; - }) + # adapted from https://gitlab.freedesktop.org/lilydjwg/wlroots/-/commit/6c5ffcd1fee9e44780a6a8792f74ecfbe24a1ca7 + ./wlroots-hidpi.patch (fetchpatch { url = "https://gitlab.freedesktop.org/wlroots/wlroots/-/commit/18595000f3a21502fd60bf213122859cc348f9af.diff"; sha256 = "sha256-jvfkAMh3gzkfuoRhB4E9T5X1Hu62wgUjj4tZkJm0mrI=";