1 /*
2  * This an unstable interface of wlroots. No guarantees are made regarding the
3  * future consistency of this API.
4  */
5 #ifndef WLR_USE_UNSTABLE
6 #error "Add -DWLR_USE_UNSTABLE to enable unstable wlroots features"
7 #endif
8 
9 #ifndef WLR_TYPES_WLR_XDG_SHELL_H
10 #define WLR_TYPES_WLR_XDG_SHELL_H
11 #include <wlr/types/wlr_box.h>
12 #include <wlr/types/wlr_seat.h>
13 #include <wayland-server-core.h>
14 #include "xdg-shell-protocol.h"
15 
16 struct wlr_xdg_shell {
17 	struct wl_global *global;
18 	struct wl_list clients;
19 	struct wl_list popup_grabs;
20 	uint32_t ping_timeout;
21 
22 	struct wl_listener display_destroy;
23 
24 	struct {
25 		/**
26 		 * The `new_surface` event signals that a client has requested to
27 		 * create a new shell surface. At this point, the surface is ready to
28 		 * be configured but is not mapped or ready receive input events. The
29 		 * surface will be ready to be managed on the `map` event.
30 		 */
31 		struct wl_signal new_surface;
32 		struct wl_signal destroy;
33 	} events;
34 
35 	void *data;
36 };
37 
38 struct wlr_xdg_client {
39 	struct wlr_xdg_shell *shell;
40 	struct wl_resource *resource;
41 	struct wl_client *client;
42 	struct wl_list surfaces;
43 
44 	struct wl_list link; // wlr_xdg_shell::clients
45 
46 	uint32_t ping_serial;
47 	struct wl_event_source *ping_timer;
48 };
49 
50 struct wlr_xdg_positioner {
51 	struct wlr_box anchor_rect;
52 	enum xdg_positioner_anchor anchor;
53 	enum xdg_positioner_gravity gravity;
54 	enum xdg_positioner_constraint_adjustment constraint_adjustment;
55 
56 	struct {
57 		int32_t width, height;
58 	} size;
59 
60 	struct {
61 		int32_t x, y;
62 	} offset;
63 };
64 
65 struct wlr_xdg_popup {
66 	struct wlr_xdg_surface *base;
67 	struct wl_list link;
68 
69 	struct wl_resource *resource;
70 	bool committed;
71 	struct wlr_surface *parent;
72 	struct wlr_seat *seat;
73 
74 	// Position of the popup relative to the upper left corner of the window
75 	// geometry of the parent surface
76 	struct wlr_box geometry;
77 
78 	struct wlr_xdg_positioner positioner;
79 
80 	struct wl_list grab_link; // wlr_xdg_popup_grab::popups
81 };
82 
83 // each seat gets a popup grab
84 struct wlr_xdg_popup_grab {
85 	struct wl_client *client;
86 	struct wlr_seat_pointer_grab pointer_grab;
87 	struct wlr_seat_keyboard_grab keyboard_grab;
88 	struct wlr_seat_touch_grab touch_grab;
89 	struct wlr_seat *seat;
90 	struct wl_list popups;
91 	struct wl_list link; // wlr_xdg_shell::popup_grabs
92 	struct wl_listener seat_destroy;
93 };
94 
95 enum wlr_xdg_surface_role {
96 	WLR_XDG_SURFACE_ROLE_NONE,
97 	WLR_XDG_SURFACE_ROLE_TOPLEVEL,
98 	WLR_XDG_SURFACE_ROLE_POPUP,
99 };
100 
101 struct wlr_xdg_toplevel_state {
102 	bool maximized, fullscreen, resizing, activated;
103 	uint32_t tiled; // enum wlr_edges
104 	uint32_t width, height;
105 	uint32_t max_width, max_height;
106 	uint32_t min_width, min_height;
107 
108 	// Since the fullscreen request may be made before the toplevel's surface
109 	// is mapped, this is used to store the requested fullscreen output (if
110 	// any) for wlr_xdg_toplevel::client_pending.
111 	struct wlr_output *fullscreen_output;
112 	struct wl_listener fullscreen_output_destroy;
113 };
114 
115 struct wlr_xdg_toplevel {
116 	struct wl_resource *resource;
117 	struct wlr_xdg_surface *base;
118 	bool added;
119 
120 	struct wlr_xdg_surface *parent;
121 	struct wl_listener parent_unmap;
122 
123 	struct wlr_xdg_toplevel_state client_pending;
124 	struct wlr_xdg_toplevel_state server_pending;
125 	struct wlr_xdg_toplevel_state last_acked;
126 	struct wlr_xdg_toplevel_state current;
127 
128 	char *title;
129 	char *app_id;
130 
131 	struct {
132 		struct wl_signal request_maximize;
133 		struct wl_signal request_fullscreen;
134 		struct wl_signal request_minimize;
135 		struct wl_signal request_move;
136 		struct wl_signal request_resize;
137 		struct wl_signal request_show_window_menu;
138 		struct wl_signal set_parent;
139 		struct wl_signal set_title;
140 		struct wl_signal set_app_id;
141 	} events;
142 };
143 
144 struct wlr_xdg_surface_configure {
145 	struct wlr_xdg_surface *surface;
146 	struct wl_list link; // wlr_xdg_surface::configure_list
147 	uint32_t serial;
148 
149 	struct wlr_xdg_toplevel_state *toplevel_state;
150 };
151 
152 /**
153  * An xdg-surface is a user interface element requiring management by the
154  * compositor. An xdg-surface alone isn't useful, a role should be assigned to
155  * it in order to map it.
156  *
157  * When a surface has a role and is ready to be displayed, the `map` event is
158  * emitted. When a surface should no longer be displayed, the `unmap` event is
159  * emitted. The `unmap` event is guaranteed to be emitted before the `destroy`
160  * event if the view is destroyed when mapped.
161  */
162 struct wlr_xdg_surface {
163 	struct wlr_xdg_client *client;
164 	struct wl_resource *resource;
165 	struct wlr_surface *surface;
166 	struct wl_list link; // wlr_xdg_client::surfaces
167 	enum wlr_xdg_surface_role role;
168 
169 	union {
170 		struct wlr_xdg_toplevel *toplevel;
171 		struct wlr_xdg_popup *popup;
172 	};
173 
174 	struct wl_list popups; // wlr_xdg_popup::link
175 
176 	bool added, configured, mapped;
177 	uint32_t configure_serial;
178 	struct wl_event_source *configure_idle;
179 	uint32_t configure_next_serial;
180 	struct wl_list configure_list;
181 
182 	bool has_next_geometry;
183 	struct wlr_box next_geometry;
184 	struct wlr_box geometry;
185 
186 	struct wl_listener surface_destroy;
187 	struct wl_listener surface_commit;
188 
189 	struct {
190 		struct wl_signal destroy;
191 		struct wl_signal ping_timeout;
192 		struct wl_signal new_popup;
193 		/**
194 		 * The `map` event signals that the shell surface is ready to be
195 		 * managed by the compositor and rendered on the screen. At this point,
196 		 * the surface has configured its properties, has had the opportunity
197 		 * to bind to the seat to receive input events, and has a buffer that
198 		 * is ready to be rendered. You can now safely add this surface to a
199 		 * list of views.
200 		 */
201 		struct wl_signal map;
202 		/**
203 		 * The `unmap` event signals that the surface is no longer in a state
204 		 * where it should be shown on the screen. This might happen if the
205 		 * surface no longer has a displayable buffer because either the
206 		 * surface has been hidden or is about to be destroyed.
207 		 */
208 		struct wl_signal unmap;
209 
210 		// for protocol extensions
211 		struct wl_signal configure; // wlr_xdg_surface_configure
212 		struct wl_signal ack_configure; // wlr_xdg_surface_configure
213 	} events;
214 
215 	void *data;
216 };
217 
218 struct wlr_xdg_toplevel_move_event {
219 	struct wlr_xdg_surface *surface;
220 	struct wlr_seat_client *seat;
221 	uint32_t serial;
222 };
223 
224 struct wlr_xdg_toplevel_resize_event {
225 	struct wlr_xdg_surface *surface;
226 	struct wlr_seat_client *seat;
227 	uint32_t serial;
228 	uint32_t edges;
229 };
230 
231 struct wlr_xdg_toplevel_set_fullscreen_event {
232 	struct wlr_xdg_surface *surface;
233 	bool fullscreen;
234 	struct wlr_output *output;
235 };
236 
237 struct wlr_xdg_toplevel_show_window_menu_event {
238 	struct wlr_xdg_surface *surface;
239 	struct wlr_seat_client *seat;
240 	uint32_t serial;
241 	uint32_t x, y;
242 };
243 
244 struct wlr_xdg_shell *wlr_xdg_shell_create(struct wl_display *display);
245 
246 /** Returns the wlr_xdg_surface from an xdg_surface resource.
247  *
248  * Aborts if the resource doesn't have the correct type. Returns NULL if the
249  * resource is inert.
250  */
251 struct wlr_xdg_surface *wlr_xdg_surface_from_resource(
252 		struct wl_resource *resource);
253 struct wlr_xdg_surface *wlr_xdg_surface_from_popup_resource(
254 		struct wl_resource *resource);
255 struct wlr_xdg_surface *wlr_xdg_surface_from_toplevel_resource(
256 		struct wl_resource *resource);
257 
258 /**
259  * Send a ping to the surface. If the surface does not respond in a reasonable
260  * amount of time, the ping_timeout event will be emitted.
261  */
262 void wlr_xdg_surface_ping(struct wlr_xdg_surface *surface);
263 
264 /**
265  * Request that this toplevel surface be the given size. Returns the associated
266  * configure serial.
267  */
268 uint32_t wlr_xdg_toplevel_set_size(struct wlr_xdg_surface *surface,
269 		uint32_t width, uint32_t height);
270 
271 /**
272  * Request that this toplevel surface show itself in an activated or deactivated
273  * state. Returns the associated configure serial.
274  */
275 uint32_t wlr_xdg_toplevel_set_activated(struct wlr_xdg_surface *surface,
276 		bool activated);
277 
278 /**
279  * Request that this toplevel surface consider itself maximized or not
280  * maximized. Returns the associated configure serial.
281  */
282 uint32_t wlr_xdg_toplevel_set_maximized(struct wlr_xdg_surface *surface,
283 		bool maximized);
284 
285 /**
286  * Request that this toplevel surface consider itself fullscreen or not
287  * fullscreen. Returns the associated configure serial.
288  */
289 uint32_t wlr_xdg_toplevel_set_fullscreen(struct wlr_xdg_surface *surface,
290 		bool fullscreen);
291 
292 /**
293  * Request that this toplevel surface consider itself to be resizing or not
294  * resizing. Returns the associated configure serial.
295  */
296 uint32_t wlr_xdg_toplevel_set_resizing(struct wlr_xdg_surface *surface,
297 		bool resizing);
298 
299 /**
300  * Request that this toplevel surface consider itself in a tiled layout and some
301  * edges are adjacent to another part of the tiling grid. `tiled_edges` is a
302  * bitfield of `enum wlr_edges`. Returns the associated configure serial.
303  */
304 uint32_t wlr_xdg_toplevel_set_tiled(struct wlr_xdg_surface *surface,
305 		uint32_t tiled_edges);
306 
307 /**
308  * Request that this xdg toplevel closes.
309  */
310 void wlr_xdg_toplevel_send_close(struct wlr_xdg_surface *surface);
311 
312 /**
313  * Request that this xdg popup closes.
314  **/
315 void wlr_xdg_popup_destroy(struct wlr_xdg_surface *surface);
316 
317 /**
318  * Get the geometry for this positioner based on the anchor rect, gravity, and
319  * size of this positioner.
320  */
321 struct wlr_box wlr_xdg_positioner_get_geometry(
322 		struct wlr_xdg_positioner *positioner);
323 
324 /**
325  * Get the anchor point for this popup in the toplevel parent's coordinate system.
326  */
327 void wlr_xdg_popup_get_anchor_point(struct wlr_xdg_popup *popup,
328 		int *toplevel_sx, int *toplevel_sy);
329 
330 /**
331  * Convert the given coordinates in the popup coordinate system to the toplevel
332  * surface coordinate system.
333  */
334 void wlr_xdg_popup_get_toplevel_coords(struct wlr_xdg_popup *popup,
335 		int popup_sx, int popup_sy, int *toplevel_sx, int *toplevel_sy);
336 
337 /**
338  * Set the geometry of this popup to unconstrain it according to its
339  * xdg-positioner rules. The box should be in the popup's root toplevel parent
340  * surface coordinate system.
341  */
342 void wlr_xdg_popup_unconstrain_from_box(struct wlr_xdg_popup *popup,
343 		struct wlr_box *toplevel_sx_box);
344 
345 /**
346   Invert the right/left anchor and gravity for this positioner. This can be
347   used to "flip" the positioner around the anchor rect in the x direction.
348  */
349 void wlr_positioner_invert_x(struct wlr_xdg_positioner *positioner);
350 
351 /**
352   Invert the top/bottom anchor and gravity for this positioner. This can be
353   used to "flip" the positioner around the anchor rect in the y direction.
354  */
355 void wlr_positioner_invert_y(struct wlr_xdg_positioner *positioner);
356 
357 /**
358  * Find a surface within this xdg-surface tree at the given surface-local
359  * coordinates. Returns the surface and coordinates in the leaf surface
360  * coordinate system or NULL if no surface is found at that location.
361  */
362 struct wlr_surface *wlr_xdg_surface_surface_at(
363 		struct wlr_xdg_surface *surface, double sx, double sy,
364 		double *sub_x, double *sub_y);
365 
366 bool wlr_surface_is_xdg_surface(struct wlr_surface *surface);
367 
368 struct wlr_xdg_surface *wlr_xdg_surface_from_wlr_surface(
369 		struct wlr_surface *surface);
370 
371 /**
372  * Get the surface geometry.
373  * This is either the geometry as set by the client, or defaulted to the bounds
374  * of the surface + the subsurfaces (as specified by the protocol).
375  *
376  * The x and y value can be <0
377  */
378 void wlr_xdg_surface_get_geometry(struct wlr_xdg_surface *surface,
379 		struct wlr_box *box);
380 
381 /**
382  * Call `iterator` on each surface and popup in the xdg-surface tree, with the
383  * surface's position relative to the root xdg-surface. The function is called
384  * from root to leaves (in rendering order).
385  */
386 void wlr_xdg_surface_for_each_surface(struct wlr_xdg_surface *surface,
387 		wlr_surface_iterator_func_t iterator, void *user_data);
388 
389 /**
390  * Schedule a surface configuration. This should only be called by protocols
391  * extending the shell.
392  */
393 uint32_t wlr_xdg_surface_schedule_configure(struct wlr_xdg_surface *surface);
394 
395 /**
396  * Call `iterator` on each popup in the xdg-surface tree, with the popup's
397  * position relative to the root xdg-surface. The function is called from root
398  * to leaves (in rendering order).
399  */
400 void wlr_xdg_surface_for_each_popup(struct wlr_xdg_surface *surface,
401 	wlr_surface_iterator_func_t iterator, void *user_data);
402 
403 #endif
404