From fc0854d5f256466cd566497af71212795745ef83 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Fri, 31 Jan 2020 22:57:48 +0100 Subject: [PATCH] xwayland: add support for global scale factor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This does the necessary changes to support HiDPI in xwayland applications, with the following xwayland patch: https://gitlab.freedesktop.org/xorg/xserver/merge_requests/111 [Antonin Décimo: rebase after 27609ba] [Antonin Décimo: rebase after 99f3c64] Co-authored-by: Antonin Décimo --- include/wlr/xwayland/server.h | 2 ++ include/wlr/xwayland/xwayland.h | 2 ++ xwayland/server.c | 2 ++ xwayland/xwayland.c | 4 +++ xwayland/xwm.c | 47 ++++++++++++++++++++++++--------- 5 files changed, 44 insertions(+), 13 deletions(-) diff --git a/include/wlr/xwayland/server.h b/include/wlr/xwayland/server.h index 9fa82d8ecd..5493ed7700 100644 --- a/include/wlr/xwayland/server.h +++ b/include/wlr/xwayland/server.h @@ -30,6 +30,8 @@ struct wlr_xwayland_server { time_t server_start; + int32_t scale; + /* Anything above display is reset on Xwayland restart, rest is conserved */ int display; diff --git a/include/wlr/xwayland/xwayland.h b/include/wlr/xwayland/xwayland.h index d426a00d4e..c6ac039f93 100644 --- a/include/wlr/xwayland/xwayland.h +++ b/include/wlr/xwayland/xwayland.h @@ -193,6 +193,8 @@ struct wlr_xwayland *wlr_xwayland_create(struct wl_display *wl_display, void wlr_xwayland_destroy(struct wlr_xwayland *wlr_xwayland); +void wlr_xwayland_set_scale(struct wlr_xwayland *wlr_xwayland, int32_t scale); + void wlr_xwayland_set_cursor(struct wlr_xwayland *wlr_xwayland, uint8_t *pixels, uint32_t stride, uint32_t width, uint32_t height, int32_t hotspot_x, int32_t hotspot_y); diff --git a/xwayland/server.c b/xwayland/server.c index 75b919b4da..f144bee443 100644 --- a/xwayland/server.c +++ b/xwayland/server.c @@ -460,6 +460,8 @@ struct wlr_xwayland_server *wlr_xwayland_server_create( server->wl_fd[0] = server->wl_fd[1] = -1; server->wm_fd[0] = server->wm_fd[1] = -1; + server->scale = 1; + wl_signal_init(&server->events.ready); wl_signal_init(&server->events.destroy); diff --git a/xwayland/xwayland.c b/xwayland/xwayland.c index 1fde770037..05d8e4b562 100644 --- a/xwayland/xwayland.c +++ b/xwayland/xwayland.c @@ -108,6 +108,10 @@ struct wlr_xwayland *wlr_xwayland_create(struct wl_display *wl_display, return xwayland; } +void wlr_xwayland_set_scale(struct wlr_xwayland *xwayland, int32_t scale) { + xwayland->server->scale = scale; +} + void wlr_xwayland_set_cursor(struct wlr_xwayland *xwayland, uint8_t *pixels, uint32_t stride, uint32_t width, uint32_t height, int32_t hotspot_x, int32_t hotspot_y) { diff --git a/xwayland/xwm.c b/xwayland/xwm.c index f0d5bff4c4..93ad853bb7 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -18,6 +18,14 @@ #include #include "xwayland/xwm.h" +static int32_t scale(struct wlr_xwm *xwm, int32_t val) { + return val * xwm->xwayland->server->scale; +} + +static int32_t unscale(struct wlr_xwm *xwm, int32_t val) { + return (val + xwm->xwayland->server->scale/2) / xwm->xwayland->server->scale; +} + const char *const atom_map[ATOM_LAST] = { [WL_SURFACE_ID] = "WL_SURFACE_ID", [WM_DELETE_WINDOW] = "WM_DELETE_WINDOW", @@ -939,8 +947,13 @@ 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, @@ -971,10 +984,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 = unscale(xwm, mask & XCB_CONFIG_WINDOW_X ? ev->x : surface->x), + .y = unscale(xwm, mask & XCB_CONFIG_WINDOW_Y ? ev->y : surface->y), + .width = unscale(xwm, mask & XCB_CONFIG_WINDOW_WIDTH ? ev->width : surface->width), + .height = unscale(xwm, mask & XCB_CONFIG_WINDOW_HEIGHT ? ev->height : surface->height), .mask = mask, }; @@ -989,14 +1002,16 @@ 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) { @@ -1695,7 +1710,13 @@ void wlr_xwayland_surface_configure(struct wlr_xwayland_surface *xsurface, 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(xsurface->xwm, x), + scale(xsurface->xwm, y), + scale(xsurface->xwm, width), + scale(xsurface->xwm, height), + 0, + }; xcb_configure_window(xwm->xcb_conn, xsurface->window_id, mask, values); xcb_flush(xwm->xcb_conn); }