summarylogtreecommitdiffstats
path: root/0002-xwayland-add-support-for-changing-global-scale-facto.patch
blob: 98d7a95f32fe0b32101e02fab5b10d1e80fdd153 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
From 3a6ea68179e80eb743f03f8d05f4c437ffee61e1 Mon Sep 17 00:00:00 2001
From: Dario Nieuwenhuis <dirbaio@dirbaio.net>
Date: Tue, 10 Mar 2020 23:21:11 +0100
Subject: [PATCH 2/2] xwayland: add support for changing global scale factor on
 the fly via x extension.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

[Antonin Décimo: rebase after e0f239f]
[Antonin Décimo: rebase after 1eb38e0]
[Antonin Décimo: rebase after 79be26f]
---
 include/xwayland/xwm.h |  3 +++
 xwayland/xwayland.c    |  3 +++
 xwayland/xwm.c         | 44 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 50 insertions(+)

diff --git a/include/xwayland/xwm.h b/include/xwayland/xwm.h
index 41e35ef3..71002d0d 100644
--- a/include/xwayland/xwm.h
+++ b/include/xwayland/xwm.h
@@ -123,6 +123,7 @@ struct wlr_xwm {
 	const xcb_query_extension_reply_t *xfixes;
 	const xcb_query_extension_reply_t *xres;
 	uint32_t xfixes_major_version;
+	const xcb_query_extension_reply_t *xwayland_ext;
 #if HAS_XCB_ERRORS
 	xcb_errors_context_t *errors_context;
 #endif
@@ -157,4 +158,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
diff --git a/xwayland/xwayland.c b/xwayland/xwayland.c
index 09f48c60..5d12c949 100644
--- a/xwayland/xwayland.c
+++ b/xwayland/xwayland.c
@@ -111,6 +111,9 @@ struct wlr_xwayland *wlr_xwayland_create(struct wl_display *wl_display,
 
 void wlr_xwayland_set_scale(struct wlr_xwayland *xwayland, int32_t scale) {
 	xwayland->server->scale = scale;
+	if (xwayland->xwm != NULL) {
+		xwm_scale_changed(xwayland->xwm);
+	}
 }
 
 void wlr_xwayland_set_cursor(struct wlr_xwayland *xwayland,
diff --git a/xwayland/xwm.c b/xwayland/xwm.c
index f16caf8d..a7f23ba9 100644
--- a/xwayland/xwm.c
+++ b/xwayland/xwm.c
@@ -16,6 +16,7 @@
 #include <xcb/render.h>
 #include <xcb/res.h>
 #include <xcb/xfixes.h>
+#include <xcb/xcbext.h>
 #include "util/signal.h"
 #include "xwayland/xwm.h"
 
@@ -27,6 +28,10 @@ static int32_t unscale(struct wlr_xwm *xwm, int32_t val) {
 	return (val + xwm->xwayland->server->scale/2) / xwm->xwayland->server->scale;
 }
 
+static xcb_extension_t xwayland_ext_id = {
+	.name = "XWAYLAND",
+};
+
 const char *const atom_map[ATOM_LAST] = {
 	[WL_SURFACE_ID] = "WL_SURFACE_ID",
 	[WM_DELETE_WINDOW] = "WM_DELETE_WINDOW",
@@ -1822,6 +1827,7 @@ 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, &xcb_res_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];
@@ -1853,6 +1859,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 =
@@ -2252,3 +2260,39 @@ enum wlr_xwayland_icccm_input_model wlr_xwayland_icccm_input_model(
 	}
 	return WLR_ICCCM_INPUT_MODEL_NONE;
 }
+
+
+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->server->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);
+}
-- 
2.36.1