-
Notifications
You must be signed in to change notification settings - Fork 2
/
sommelier-window.h
348 lines (306 loc) · 12.4 KB
/
sommelier-window.h
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
// Copyright 2021 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef VM_TOOLS_SOMMELIER_SOMMELIER_WINDOW_H_
#define VM_TOOLS_SOMMELIER_SOMMELIER_WINDOW_H_
#include <pixman.h>
#include <wayland-client-protocol.h>
#include <wayland-server-core.h>
#include <cstdint>
#include <set>
#include <string>
#include <xcb/xcb.h>
#define US_POSITION (1L << 0)
#define US_SIZE (1L << 1)
#define P_POSITION (1L << 2)
#define P_SIZE (1L << 3)
#define P_MIN_SIZE (1L << 4)
#define P_MAX_SIZE (1L << 5)
#define P_RESIZE_INC (1L << 6)
#define P_ASPECT (1L << 7)
#define P_BASE_SIZE (1L << 8)
#define P_WIN_GRAVITY (1L << 9)
struct sl_config {
uint32_t serial = 0;
uint32_t mask = 0;
// Values and states here are consumed during sl_configure_window
uint32_t values[5];
uint32_t states_length = 0;
uint32_t states[3];
};
struct sl_host_surface;
// An X11 window.
struct sl_window {
sl_window(struct sl_context* ctx,
xcb_window_t id,
int x,
int y,
int width,
int height,
int border_width);
~sl_window();
struct sl_context* ctx = nullptr;
xcb_window_t id = XCB_WINDOW_NONE;
xcb_window_t frame_id = XCB_WINDOW_NONE;
uint32_t host_surface_id = 0;
int unpaired = 1;
bool shaped = false;
// Window position and size are specified in X11's coordinate space
// (Virtual Coordinate Space, as defined in sommelier-transform.h).
int x = 0;
int y = 0;
int width = 0;
int height = 0;
// Emulated x,y,width,height are 'faked' position and size by XWayland. We
// only need to set and return this value to the clients (X11 windows). We
// should continue doing normal window position and sizing operations with Exo
// with real x,y,width,height.
bool use_emulated_rects = false;
int emulated_width = 0;
int emulated_height = 0;
int emulated_x = 0;
int emulated_y = 0;
int border_width = 0;
int depth = 0;
int managed = 0;
int realized = 0;
int activated = 0;
int fullscreen = 0;
int compositor_fullscreen = 0;
int maximized = 0;
int iconified = 0;
// True if there has been changes to the fullscreen/maximized state
// while this window is iconified.
bool pending_fullscreen_change = false;
bool pending_maximized_change = false;
int allow_resize = 1;
xcb_window_t transient_for = XCB_WINDOW_NONE;
xcb_window_t client_leader = XCB_WINDOW_NONE;
int decorated = 0;
char* name = nullptr;
bool has_net_wm_name = false;
char* clazz = nullptr;
char* startup_id = nullptr;
uint32_t steam_game_id = 0;
std::string app_id_property;
int dark_frame = 0;
uint32_t size_flags = P_POSITION;
int focus_model_take_focus = 0;
// TODO(b/331112549): introduce and utilize size structs for width/height
int min_width = 0;
int min_height = 0;
int max_width = 0;
int max_height = 0;
// If true, use overridden viewport_width/height values to set destination.
int viewport_override = false;
// Determines scale factor for pointer movements. Incorrect value (i.e.
// viewport scaling factor was not calculated correctly for X and Y axis.
// Currently we assume X and Y axis have the same factor) will result in
// pointer offset.
double viewport_pointer_scale = 0;
// Configured viewport destination width and height, usually done during
// xdg_toplevel_configure. Only utilized if viewport_override is true.
int viewport_width = -1;
int viewport_height = -1;
// The latest width and height that viewport.set_destination was called with
// (ie. sent to Exo), usually done in host_surface_commit.
int viewport_width_realized = -1;
int viewport_height_realized = -1;
// If true, check if borderless window should be set to fullscreen in Exo
// during surface_commit. Initially set to true because some games (that
// launch in borderless-windowed mode) assume the default state is fullscreen
// not set.
bool maybe_promote_to_fullscreen = true;
// Value of _NET_WM_WINDOW_TYPE for the window set in x11.
uint32_t type = 0;
// PID of the window.
uint32_t pid = 0;
// If true, this window is probably a real game window based on derived
// information from PID.
bool should_be_containerized_from_pid = true;
#ifdef QUIRKS_SUPPORT
// Quirk feature flags previously applied to this window, for which log
// messages have already been written.
std::set<int> logged_quirks;
#endif
// Window rect and state from the most recent xdg_toplevel/aura_toplevel
// configure event, to be applied when xdg_surface.configure is next received.
struct sl_config next_config;
// Window rect and state applied by xdg_surface.configure. Sommelier now waits
// for the client to commit surface contents consistent with this config.
struct sl_config pending_config;
// When null, xdg_surface.configure events are processed immediately.
// When set, all xdg_surface.configure events are coalesced together,
// and Sommelier won't apply them until this callback's done event fires.
// When the done event fires, the last received xdg_surface.configure event
// is processed.
struct wl_callback* configure_event_barrier = nullptr;
// Most recent config received while the |configure_event_barrier| was active.
struct sl_config coalesced_next_config;
struct xdg_surface* xdg_surface = nullptr;
struct xdg_toplevel* xdg_toplevel = nullptr;
struct xdg_popup* xdg_popup = nullptr;
struct zaura_surface* aura_surface = nullptr;
struct zaura_toplevel* aura_toplevel = nullptr;
struct sl_host_surface* paired_surface = nullptr;
struct pixman_region32 shape_rectangles;
struct wl_list link = {};
};
enum {
PROPERTY_WM_NAME,
PROPERTY_NET_WM_NAME,
PROPERTY_WM_CLASS,
PROPERTY_WM_TRANSIENT_FOR,
PROPERTY_WM_NORMAL_HINTS,
PROPERTY_WM_CLIENT_LEADER,
PROPERTY_WM_PROTOCOLS,
PROPERTY_MOTIF_WM_HINTS,
PROPERTY_NET_STARTUP_ID,
PROPERTY_NET_WM_PID,
PROPERTY_NET_WM_STATE,
PROPERTY_NET_WM_WINDOW_TYPE,
PROPERTY_GTK_THEME_VARIANT,
PROPERTY_XWAYLAND_RANDR_EMU_MONITOR_RECTS,
PROPERTY_STEAM_GAME,
// The atom corresponding to this property changes depending on the
// --application-id-format command-line argument.
PROPERTY_SPECIFIED_FOR_APP_ID,
};
struct sl_wm_size_hints {
uint32_t flags;
int32_t x, y;
int32_t width, height;
int32_t min_width, min_height;
int32_t max_width, max_height;
int32_t width_inc, height_inc;
struct {
int32_t x;
int32_t y;
} min_aspect, max_aspect;
int32_t base_width, base_height;
int32_t win_gravity;
};
// WM_HINTS is defined at: https://tronche.com/gui/x/icccm/sec-4.html
#define WM_HINTS_FLAG_INPUT (1L << 0)
#define WM_HINTS_FLAG_STATE (1L << 1)
#define WM_HINTS_FLAG_ICON_PIXMAP (1L << 2)
#define WM_HINTS_FLAG_ICON_WINDOW (1L << 3)
#define WM_HINTS_FLAG_ICON_POSITION (1L << 4)
#define WM_HINTS_FLAG_ICON_MASK (1L << 5)
#define WM_HINTS_FLAG_WINDOW_GROUP (1L << 6)
#define WM_HINTS_FLAG_MESSAGE (1L << 7)
#define WM_HINTS_FLAG_URGENCY (1L << 8)
struct sl_wm_hints {
uint32_t flags;
uint32_t input;
uint32_t initial_state;
xcb_pixmap_t icon_pixmap;
xcb_window_t icon_window;
int32_t icon_x;
int32_t icon_y;
xcb_pixmap_t icon_mask;
};
#define MWM_HINTS_FUNCTIONS (1L << 0)
#define MWM_HINTS_DECORATIONS (1L << 1)
#define MWM_HINTS_INPUT_MODE (1L << 2)
#define MWM_HINTS_STATUS (1L << 3)
#define MWM_DECOR_ALL (1L << 0)
#define MWM_DECOR_BORDER (1L << 1)
#define MWM_DECOR_RESIZEH (1L << 2)
#define MWM_DECOR_TITLE (1L << 3)
#define MWM_DECOR_MENU (1L << 4)
#define MWM_DECOR_MINIMIZE (1L << 5)
#define MWM_DECOR_MAXIMIZE (1L << 6)
struct sl_mwm_hints {
uint32_t flags;
uint32_t functions;
uint32_t decorations;
int32_t input_mode;
uint32_t status;
};
#define NET_WM_MOVERESIZE_SIZE_TOPLEFT 0
#define NET_WM_MOVERESIZE_SIZE_TOP 1
#define NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2
#define NET_WM_MOVERESIZE_SIZE_RIGHT 3
#define NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4
#define NET_WM_MOVERESIZE_SIZE_BOTTOM 5
#define NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6
#define NET_WM_MOVERESIZE_SIZE_LEFT 7
#define NET_WM_MOVERESIZE_MOVE 8
#define NET_WM_STATE_REMOVE 0
#define NET_WM_STATE_ADD 1
#define NET_WM_STATE_TOGGLE 2
#define WM_STATE_WITHDRAWN 0
#define WM_STATE_NORMAL 1
#define WM_STATE_ICONIC 3
void sl_window_update(struct sl_window* window);
void sl_toplevel_send_window_bounds_to_host(struct sl_window* window);
void sl_update_application_id(struct sl_context* ctx, struct sl_window* window);
void sl_configure_window(struct sl_window* window);
void sl_send_configure_notify(struct sl_window* window);
// TODO(b/331132756): Refactor containerization logic into more OO style, this
// will probably impact other areas of code as well.
void sl_internal_toplevel_configure(struct sl_window* window,
int32_t x,
int32_t y,
int32_t width,
int32_t height,
struct wl_array* states);
void sl_internal_toplevel_configure_size(struct sl_window* window,
int32_t x,
int32_t y,
int32_t host_width,
int32_t host_height,
int32_t width_in_pixels,
int32_t height_in_pixels,
int& mut_config_idx);
void sl_internal_toplevel_configure_size_containerized(struct sl_window* window,
int32_t x,
int32_t y,
int32_t host_width,
int32_t host_height,
int32_t width_in_pixels,
int32_t height_in_pixels,
int& mut_config_idx);
void sl_internal_toplevel_configure_position(struct sl_window* window,
uint32_t x,
uint32_t y,
int32_t width_in_pixels,
int32_t height_in_pixels,
int& mut_config_idx);
void sl_internal_toplevel_configure_state(struct sl_window* window,
struct wl_array* states);
void sl_internal_toplevel_configure_state_containerized(
struct sl_window* window, struct wl_array* states);
int sl_process_pending_configure_acks(struct sl_window* window,
struct sl_host_surface* host_surface);
#ifdef QUIRKS_SUPPORT
// Returns true if this function hasn't been called with this combination of
// `window` and `feature_enum` before. In that case, the caller is expected to
// write a log message indicating that the quirk has been applied.
bool sl_window_should_log_quirk(struct sl_window* window, int feature_enum);
// Returns all quirks ever logged against this window.
// This "latches"; if a quirk has ever been enabled, it will stay in this list,
// even if the quirk is no longer enabled.
std::set<int> sl_window_logged_quirks(struct sl_window* window);
#endif // QUIRKS_SUPPORT
bool sl_window_is_client_positioned(struct sl_window* window);
// Set correct viewport destination from xwayland for incorrectly behaving
// games.
bool sl_window_should_fix_randr_emu(struct sl_window* window);
// Get position of the window.
void sl_window_get_x_y(struct sl_window* window, uint32_t* x, uint32_t* y);
// Get size of the window, taking account of emulated status.
void sl_window_get_width_height(struct sl_window* window,
uint32_t* w,
uint32_t* h);
void sl_window_update_should_be_containerized_from_pid(
struct sl_window* window);
bool sl_window_is_containerized(struct sl_window* window);
void sl_window_reset_viewport(struct sl_window* window);
// Get the virtual screen position that the window is in. Returns true if mut_x
// and mut_y were updated with the found screen, false otherwise.
bool sl_window_get_output_virt_position(struct sl_window* window,
uint32_t& mut_x,
uint32_t& mut_y);
#endif // VM_TOOLS_SOMMELIER_SOMMELIER_WINDOW_H_