xwayland: add support for changing global scale factor on the fly via x extension.

This commit is contained in:
Dario Nieuwenhuis 2020-03-10 23:21:11 +01:00
parent 9bd9089045
commit d069ab71d4
3 changed files with 50 additions and 0 deletions

View file

@ -122,6 +122,7 @@ struct wlr_xwm {
struct wlr_xwayland_surface *drag_focus;
const xcb_query_extension_reply_t *xfixes;
const xcb_query_extension_reply_t *xwayland_ext;
#if WLR_HAS_XCB_ERRORS
xcb_errors_context_t *errors_context;
#endif
@ -155,4 +156,6 @@ char *xwm_get_atom_name(struct wlr_xwm *xwm, xcb_atom_t atom);
bool xwm_atoms_contains(struct wlr_xwm *xwm, xcb_atom_t *atoms,
size_t num_atoms, enum atom_name needle);
void xwm_scale_changed(struct wlr_xwm *xwm);
#endif

View file

@ -440,6 +440,9 @@ error_alloc:
void wlr_xwayland_set_scale(struct wlr_xwayland *wlr_xwayland, int32_t scale) {
wlr_xwayland->scale = scale;
if (wlr_xwayland->xwm != NULL) {
xwm_scale_changed(wlr_xwayland->xwm);
}
}
void wlr_xwayland_set_cursor(struct wlr_xwayland *wlr_xwayland,

View file

@ -13,6 +13,7 @@
#include <xcb/composite.h>
#include <xcb/render.h>
#include <xcb/xfixes.h>
#include <xcb/xcbext.h>
#include "util/signal.h"
#include "xwayland/xwm.h"
@ -25,6 +26,10 @@ static int32_t unscale(struct wlr_xwm *xwm, int32_t val) {
return (val + xwm->xwayland->scale/2) / xwm->xwayland->scale;
}
static xcb_extension_t xwayland_ext_id = {
.name = "XWAYLAND",
};
const char *atom_map[ATOM_LAST] = {
[WL_SURFACE_ID] = "WL_SURFACE_ID",
[WM_DELETE_WINDOW] = "WM_DELETE_WINDOW",
@ -1517,6 +1522,7 @@ void xwm_destroy(struct wlr_xwm *xwm) {
static void xwm_get_resources(struct wlr_xwm *xwm) {
xcb_prefetch_extension_data(xwm->xcb_conn, &xcb_xfixes_id);
xcb_prefetch_extension_data(xwm->xcb_conn, &xcb_composite_id);
xcb_prefetch_extension_data(xwm->xcb_conn, &xwayland_ext_id); // TODO what if extension is not present??
size_t i;
xcb_intern_atom_cookie_t cookies[ATOM_LAST];
@ -1548,6 +1554,8 @@ static void xwm_get_resources(struct wlr_xwm *xwm) {
wlr_log(WLR_DEBUG, "xfixes not available");
}
xwm->xwayland_ext = xcb_get_extension_data(xwm->xcb_conn, &xwayland_ext_id);
xcb_xfixes_query_version_cookie_t xfixes_cookie;
xcb_xfixes_query_version_reply_t *xfixes_reply;
xfixes_cookie =
@ -1878,3 +1886,39 @@ bool wlr_xwayland_or_surface_wants_focus(
return ret;
}
typedef struct {
uint8_t major_opcode;
uint8_t minor_opcode;
uint16_t length;
uint16_t screen;
uint16_t scale;
} xwayland_ext_set_scale_request_t;
void xwm_scale_changed(struct wlr_xwm *xwm) {
xcb_protocol_request_t req = {
.count = 1,
.ext = &xwayland_ext_id,
.opcode = 1,
.isvoid = false,
};
xwayland_ext_set_scale_request_t xcb_out = {
.screen = 0,
.scale = xwm->xwayland->scale,
};
struct iovec xcb_parts[3];
xcb_parts[2].iov_base = (char *) &xcb_out;
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_send_request(xwm->xcb_conn, 0, xcb_parts+2, &req);
// Reconfigure all surfaces with the new scale.
struct wlr_xwayland_surface *surface;
wl_list_for_each(surface, &xwm->surfaces, link) {
wlr_xwayland_surface_configure(surface, surface->x, surface->y, surface->width, surface->height);
}
xcb_flush(xwm->xcb_conn);
}