1 #define _POSIX_C_SOURCE 200809L
2 #include <assert.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <wlr/util/log.h>
6 #include <wlr/util/edges.h>
7 #include "types/wlr_xdg_shell.h"
8 #include "util/signal.h"
9
handle_xdg_toplevel_ack_configure(struct wlr_xdg_surface * surface,struct wlr_xdg_surface_configure * configure)10 void handle_xdg_toplevel_ack_configure(
11 struct wlr_xdg_surface *surface,
12 struct wlr_xdg_surface_configure *configure) {
13 assert(surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL);
14 assert(configure->toplevel_state != NULL);
15
16 surface->toplevel->last_acked = *configure->toplevel_state;
17 }
18
compare_xdg_surface_toplevel_state(struct wlr_xdg_toplevel * state)19 bool compare_xdg_surface_toplevel_state(struct wlr_xdg_toplevel *state) {
20 // is pending state different from current state?
21 if (!state->base->configured) {
22 return false;
23 }
24
25 struct wlr_xdg_toplevel_state *configured = NULL;
26 if (wl_list_empty(&state->base->configure_list)) {
27 // There are currently no pending configures, so check against the last
28 // state acked by the client.
29 configured = &state->last_acked;
30 } else {
31 struct wlr_xdg_surface_configure *configure =
32 wl_container_of(state->base->configure_list.prev, configure, link);
33 configured = configure->toplevel_state;
34 }
35
36 if (state->server_pending.activated != configured->activated) {
37 return false;
38 }
39 if (state->server_pending.fullscreen != configured->fullscreen) {
40 return false;
41 }
42 if (state->server_pending.maximized != configured->maximized) {
43 return false;
44 }
45 if (state->server_pending.resizing != configured->resizing) {
46 return false;
47 }
48 if (state->server_pending.tiled != configured->tiled) {
49 return false;
50 }
51
52 if (state->server_pending.width == configured->width &&
53 state->server_pending.height == configured->height) {
54 return true;
55 }
56
57 if (state->server_pending.width == 0 && state->server_pending.height == 0) {
58 return true;
59 }
60
61 return false;
62 }
63
send_xdg_toplevel_configure(struct wlr_xdg_surface * surface,struct wlr_xdg_surface_configure * configure)64 void send_xdg_toplevel_configure(struct wlr_xdg_surface *surface,
65 struct wlr_xdg_surface_configure *configure) {
66 assert(surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL);
67
68 configure->toplevel_state = malloc(sizeof(*configure->toplevel_state));
69 if (configure->toplevel_state == NULL) {
70 wlr_log(WLR_ERROR, "Allocation failed");
71 wl_resource_post_no_memory(surface->toplevel->resource);
72 return;
73 }
74 *configure->toplevel_state = surface->toplevel->server_pending;
75
76 struct wl_array states;
77 wl_array_init(&states);
78 if (surface->toplevel->server_pending.maximized) {
79 uint32_t *s = wl_array_add(&states, sizeof(uint32_t));
80 if (!s) {
81 wlr_log(WLR_ERROR, "Could not allocate state for maximized xdg_toplevel");
82 goto error_out;
83 }
84 *s = XDG_TOPLEVEL_STATE_MAXIMIZED;
85 }
86 if (surface->toplevel->server_pending.fullscreen) {
87 uint32_t *s = wl_array_add(&states, sizeof(uint32_t));
88 if (!s) {
89 wlr_log(WLR_ERROR, "Could not allocate state for fullscreen xdg_toplevel");
90 goto error_out;
91 }
92 *s = XDG_TOPLEVEL_STATE_FULLSCREEN;
93 }
94 if (surface->toplevel->server_pending.resizing) {
95 uint32_t *s = wl_array_add(&states, sizeof(uint32_t));
96 if (!s) {
97 wlr_log(WLR_ERROR, "Could not allocate state for resizing xdg_toplevel");
98 goto error_out;
99 }
100 *s = XDG_TOPLEVEL_STATE_RESIZING;
101 }
102 if (surface->toplevel->server_pending.activated) {
103 uint32_t *s = wl_array_add(&states, sizeof(uint32_t));
104 if (!s) {
105 wlr_log(WLR_ERROR, "Could not allocate state for activated xdg_toplevel");
106 goto error_out;
107 }
108 *s = XDG_TOPLEVEL_STATE_ACTIVATED;
109 }
110 if (surface->toplevel->server_pending.tiled) {
111 if (wl_resource_get_version(surface->resource) >=
112 XDG_TOPLEVEL_STATE_TILED_LEFT_SINCE_VERSION) {
113 const struct {
114 enum wlr_edges edge;
115 enum xdg_toplevel_state state;
116 } tiled[] = {
117 { WLR_EDGE_LEFT, XDG_TOPLEVEL_STATE_TILED_LEFT },
118 { WLR_EDGE_RIGHT, XDG_TOPLEVEL_STATE_TILED_RIGHT },
119 { WLR_EDGE_TOP, XDG_TOPLEVEL_STATE_TILED_TOP },
120 { WLR_EDGE_BOTTOM, XDG_TOPLEVEL_STATE_TILED_BOTTOM },
121 };
122
123 for (size_t i = 0; i < sizeof(tiled)/sizeof(tiled[0]); ++i) {
124 if ((surface->toplevel->server_pending.tiled &
125 tiled[i].edge) == 0) {
126 continue;
127 }
128
129 uint32_t *s = wl_array_add(&states, sizeof(uint32_t));
130 if (!s) {
131 wlr_log(WLR_ERROR,
132 "Could not allocate state for tiled xdg_toplevel");
133 goto error_out;
134 }
135 *s = tiled[i].state;
136 }
137 } else if (!surface->toplevel->server_pending.maximized) {
138 // This version doesn't support tiling, best we can do is make the
139 // toplevel maximized
140 uint32_t *s = wl_array_add(&states, sizeof(uint32_t));
141 if (!s) {
142 wlr_log(WLR_ERROR,
143 "Could not allocate state for maximized xdg_toplevel");
144 goto error_out;
145 }
146 *s = XDG_TOPLEVEL_STATE_MAXIMIZED;
147 }
148 }
149
150 uint32_t width = surface->toplevel->server_pending.width;
151 uint32_t height = surface->toplevel->server_pending.height;
152 xdg_toplevel_send_configure(surface->toplevel->resource, width, height,
153 &states);
154
155 wl_array_release(&states);
156 return;
157
158 error_out:
159 wl_array_release(&states);
160 wl_resource_post_no_memory(surface->toplevel->resource);
161 }
162
handle_xdg_surface_toplevel_committed(struct wlr_xdg_surface * surface)163 void handle_xdg_surface_toplevel_committed(struct wlr_xdg_surface *surface) {
164 assert(surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL);
165
166 if (!surface->toplevel->added) {
167 // on the first commit, send a configure request to tell the client it
168 // is added
169 schedule_xdg_surface_configure(surface);
170 surface->toplevel->added = true;
171 return;
172 }
173
174 // apply state from the last acked configure now that the client committed
175 surface->toplevel->current = surface->toplevel->last_acked;
176
177 // update state from the client that doesn't need compositor approval
178 surface->toplevel->current.max_width =
179 surface->toplevel->client_pending.max_width;
180 surface->toplevel->current.min_width =
181 surface->toplevel->client_pending.min_width;
182 surface->toplevel->current.max_height =
183 surface->toplevel->client_pending.max_height;
184 surface->toplevel->current.min_height =
185 surface->toplevel->client_pending.min_height;
186 }
187
188 static const struct xdg_toplevel_interface xdg_toplevel_implementation;
189
wlr_xdg_surface_from_toplevel_resource(struct wl_resource * resource)190 struct wlr_xdg_surface *wlr_xdg_surface_from_toplevel_resource(
191 struct wl_resource *resource) {
192 assert(wl_resource_instance_of(resource, &xdg_toplevel_interface,
193 &xdg_toplevel_implementation));
194 return wl_resource_get_user_data(resource);
195 }
196
197 static void set_parent(struct wlr_xdg_surface *surface,
198 struct wlr_xdg_surface *parent);
199
handle_parent_unmap(struct wl_listener * listener,void * data)200 static void handle_parent_unmap(struct wl_listener *listener, void *data) {
201 struct wlr_xdg_toplevel *toplevel =
202 wl_container_of(listener, toplevel, parent_unmap);
203 set_parent(toplevel->base, toplevel->parent->toplevel->parent);
204 }
205
set_parent(struct wlr_xdg_surface * surface,struct wlr_xdg_surface * parent)206 static void set_parent(struct wlr_xdg_surface *surface,
207 struct wlr_xdg_surface *parent) {
208 assert(surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL);
209 assert(!parent || parent->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL);
210
211 if (surface->toplevel->parent) {
212 wl_list_remove(&surface->toplevel->parent_unmap.link);
213 }
214
215 surface->toplevel->parent = parent;
216 if (surface->toplevel->parent) {
217 surface->toplevel->parent_unmap.notify = handle_parent_unmap;
218 wl_signal_add(&surface->toplevel->parent->events.unmap,
219 &surface->toplevel->parent_unmap);
220 }
221
222 wlr_signal_emit_safe(&surface->toplevel->events.set_parent, surface);
223 }
224
xdg_toplevel_handle_set_parent(struct wl_client * client,struct wl_resource * resource,struct wl_resource * parent_resource)225 static void xdg_toplevel_handle_set_parent(struct wl_client *client,
226 struct wl_resource *resource, struct wl_resource *parent_resource) {
227 struct wlr_xdg_surface *surface =
228 wlr_xdg_surface_from_toplevel_resource(resource);
229 struct wlr_xdg_surface *parent = NULL;
230
231 if (parent_resource != NULL) {
232 parent = wlr_xdg_surface_from_toplevel_resource(parent_resource);
233 }
234
235 set_parent(surface, parent);
236 }
237
xdg_toplevel_handle_set_title(struct wl_client * client,struct wl_resource * resource,const char * title)238 static void xdg_toplevel_handle_set_title(struct wl_client *client,
239 struct wl_resource *resource, const char *title) {
240 struct wlr_xdg_surface *surface =
241 wlr_xdg_surface_from_toplevel_resource(resource);
242 char *tmp;
243
244 tmp = strdup(title);
245 if (tmp == NULL) {
246 return;
247 }
248
249 free(surface->toplevel->title);
250 surface->toplevel->title = tmp;
251 wlr_signal_emit_safe(&surface->toplevel->events.set_title, surface);
252 }
253
xdg_toplevel_handle_set_app_id(struct wl_client * client,struct wl_resource * resource,const char * app_id)254 static void xdg_toplevel_handle_set_app_id(struct wl_client *client,
255 struct wl_resource *resource, const char *app_id) {
256 struct wlr_xdg_surface *surface =
257 wlr_xdg_surface_from_toplevel_resource(resource);
258 char *tmp;
259
260 tmp = strdup(app_id);
261 if (tmp == NULL) {
262 return;
263 }
264
265 free(surface->toplevel->app_id);
266 surface->toplevel->app_id = tmp;
267 wlr_signal_emit_safe(&surface->toplevel->events.set_app_id, surface);
268 }
269
xdg_toplevel_handle_show_window_menu(struct wl_client * client,struct wl_resource * resource,struct wl_resource * seat_resource,uint32_t serial,int32_t x,int32_t y)270 static void xdg_toplevel_handle_show_window_menu(struct wl_client *client,
271 struct wl_resource *resource, struct wl_resource *seat_resource,
272 uint32_t serial, int32_t x, int32_t y) {
273 struct wlr_xdg_surface *surface =
274 wlr_xdg_surface_from_toplevel_resource(resource);
275 struct wlr_seat_client *seat =
276 wlr_seat_client_from_resource(seat_resource);
277
278 if (!surface->configured) {
279 wl_resource_post_error(surface->toplevel->resource,
280 XDG_SURFACE_ERROR_NOT_CONSTRUCTED,
281 "surface has not been configured yet");
282 return;
283 }
284
285 if (!wlr_seat_validate_grab_serial(seat->seat, serial)) {
286 wlr_log(WLR_DEBUG, "invalid serial for grab");
287 return;
288 }
289
290 struct wlr_xdg_toplevel_show_window_menu_event event = {
291 .surface = surface,
292 .seat = seat,
293 .serial = serial,
294 .x = x,
295 .y = y,
296 };
297
298 wlr_signal_emit_safe(&surface->toplevel->events.request_show_window_menu, &event);
299 }
300
xdg_toplevel_handle_move(struct wl_client * client,struct wl_resource * resource,struct wl_resource * seat_resource,uint32_t serial)301 static void xdg_toplevel_handle_move(struct wl_client *client,
302 struct wl_resource *resource, struct wl_resource *seat_resource,
303 uint32_t serial) {
304 struct wlr_xdg_surface *surface =
305 wlr_xdg_surface_from_toplevel_resource(resource);
306 struct wlr_seat_client *seat =
307 wlr_seat_client_from_resource(seat_resource);
308
309 if (!surface->configured) {
310 wl_resource_post_error(surface->toplevel->resource,
311 XDG_SURFACE_ERROR_NOT_CONSTRUCTED,
312 "surface has not been configured yet");
313 return;
314 }
315
316 if (!wlr_seat_validate_grab_serial(seat->seat, serial)) {
317 wlr_log(WLR_DEBUG, "invalid serial for grab");
318 return;
319 }
320
321 struct wlr_xdg_toplevel_move_event event = {
322 .surface = surface,
323 .seat = seat,
324 .serial = serial,
325 };
326
327 wlr_signal_emit_safe(&surface->toplevel->events.request_move, &event);
328 }
329
xdg_toplevel_handle_resize(struct wl_client * client,struct wl_resource * resource,struct wl_resource * seat_resource,uint32_t serial,uint32_t edges)330 static void xdg_toplevel_handle_resize(struct wl_client *client,
331 struct wl_resource *resource, struct wl_resource *seat_resource,
332 uint32_t serial, uint32_t edges) {
333 struct wlr_xdg_surface *surface =
334 wlr_xdg_surface_from_toplevel_resource(resource);
335 struct wlr_seat_client *seat =
336 wlr_seat_client_from_resource(seat_resource);
337
338 if (!surface->configured) {
339 wl_resource_post_error(surface->toplevel->resource,
340 XDG_SURFACE_ERROR_NOT_CONSTRUCTED,
341 "surface has not been configured yet");
342 return;
343 }
344
345 if (!wlr_seat_validate_grab_serial(seat->seat, serial)) {
346 wlr_log(WLR_DEBUG, "invalid serial for grab");
347 return;
348 }
349
350 struct wlr_xdg_toplevel_resize_event event = {
351 .surface = surface,
352 .seat = seat,
353 .serial = serial,
354 .edges = edges,
355 };
356
357 wlr_signal_emit_safe(&surface->toplevel->events.request_resize, &event);
358 }
359
xdg_toplevel_handle_set_max_size(struct wl_client * client,struct wl_resource * resource,int32_t width,int32_t height)360 static void xdg_toplevel_handle_set_max_size(struct wl_client *client,
361 struct wl_resource *resource, int32_t width, int32_t height) {
362 struct wlr_xdg_surface *surface =
363 wlr_xdg_surface_from_toplevel_resource(resource);
364 surface->toplevel->client_pending.max_width = width;
365 surface->toplevel->client_pending.max_height = height;
366 }
367
xdg_toplevel_handle_set_min_size(struct wl_client * client,struct wl_resource * resource,int32_t width,int32_t height)368 static void xdg_toplevel_handle_set_min_size(struct wl_client *client,
369 struct wl_resource *resource, int32_t width, int32_t height) {
370 struct wlr_xdg_surface *surface =
371 wlr_xdg_surface_from_toplevel_resource(resource);
372 surface->toplevel->client_pending.min_width = width;
373 surface->toplevel->client_pending.min_height = height;
374 }
375
xdg_toplevel_handle_set_maximized(struct wl_client * client,struct wl_resource * resource)376 static void xdg_toplevel_handle_set_maximized(struct wl_client *client,
377 struct wl_resource *resource) {
378 struct wlr_xdg_surface *surface =
379 wlr_xdg_surface_from_toplevel_resource(resource);
380 surface->toplevel->client_pending.maximized = true;
381 wlr_signal_emit_safe(&surface->toplevel->events.request_maximize, surface);
382 }
383
xdg_toplevel_handle_unset_maximized(struct wl_client * client,struct wl_resource * resource)384 static void xdg_toplevel_handle_unset_maximized(struct wl_client *client,
385 struct wl_resource *resource) {
386 struct wlr_xdg_surface *surface =
387 wlr_xdg_surface_from_toplevel_resource(resource);
388 surface->toplevel->client_pending.maximized = false;
389 wlr_signal_emit_safe(&surface->toplevel->events.request_maximize, surface);
390 }
391
handle_fullscreen_output_destroy(struct wl_listener * listener,void * data)392 static void handle_fullscreen_output_destroy(struct wl_listener *listener,
393 void *data) {
394 struct wlr_xdg_toplevel_state *state =
395 wl_container_of(listener, state, fullscreen_output_destroy);
396 state->fullscreen_output = NULL;
397 wl_list_remove(&state->fullscreen_output_destroy.link);
398 }
399
store_fullscreen_pending(struct wlr_xdg_surface * surface,bool fullscreen,struct wlr_output * output)400 static void store_fullscreen_pending(struct wlr_xdg_surface *surface,
401 bool fullscreen, struct wlr_output *output) {
402 struct wlr_xdg_toplevel_state *state = &surface->toplevel->client_pending;
403 state->fullscreen = fullscreen;
404 if (state->fullscreen_output) {
405 wl_list_remove(&state->fullscreen_output_destroy.link);
406 }
407 state->fullscreen_output = output;
408 if (state->fullscreen_output) {
409 state->fullscreen_output_destroy.notify =
410 handle_fullscreen_output_destroy;
411 wl_signal_add(&state->fullscreen_output->events.destroy,
412 &state->fullscreen_output_destroy);
413 }
414 }
415
xdg_toplevel_handle_set_fullscreen(struct wl_client * client,struct wl_resource * resource,struct wl_resource * output_resource)416 static void xdg_toplevel_handle_set_fullscreen(struct wl_client *client,
417 struct wl_resource *resource, struct wl_resource *output_resource) {
418 struct wlr_xdg_surface *surface =
419 wlr_xdg_surface_from_toplevel_resource(resource);
420
421 struct wlr_output *output = NULL;
422 if (output_resource != NULL) {
423 output = wlr_output_from_resource(output_resource);
424 }
425
426 store_fullscreen_pending(surface, true, output);
427
428 struct wlr_xdg_toplevel_set_fullscreen_event event = {
429 .surface = surface,
430 .fullscreen = true,
431 .output = output,
432 };
433
434 wlr_signal_emit_safe(&surface->toplevel->events.request_fullscreen, &event);
435 }
436
xdg_toplevel_handle_unset_fullscreen(struct wl_client * client,struct wl_resource * resource)437 static void xdg_toplevel_handle_unset_fullscreen(struct wl_client *client,
438 struct wl_resource *resource) {
439 struct wlr_xdg_surface *surface =
440 wlr_xdg_surface_from_toplevel_resource(resource);
441
442 store_fullscreen_pending(surface, false, NULL);
443
444 struct wlr_xdg_toplevel_set_fullscreen_event event = {
445 .surface = surface,
446 .fullscreen = false,
447 .output = NULL,
448 };
449
450 wlr_signal_emit_safe(&surface->toplevel->events.request_fullscreen, &event);
451 }
452
xdg_toplevel_handle_set_minimized(struct wl_client * client,struct wl_resource * resource)453 static void xdg_toplevel_handle_set_minimized(struct wl_client *client,
454 struct wl_resource *resource) {
455 struct wlr_xdg_surface *surface =
456 wlr_xdg_surface_from_toplevel_resource(resource);
457 wlr_signal_emit_safe(&surface->toplevel->events.request_minimize, surface);
458 }
459
xdg_toplevel_handle_destroy(struct wl_client * client,struct wl_resource * resource)460 static void xdg_toplevel_handle_destroy(struct wl_client *client,
461 struct wl_resource *resource) {
462 wl_resource_destroy(resource);
463 }
464
465 static const struct xdg_toplevel_interface xdg_toplevel_implementation = {
466 .destroy = xdg_toplevel_handle_destroy,
467 .set_parent = xdg_toplevel_handle_set_parent,
468 .set_title = xdg_toplevel_handle_set_title,
469 .set_app_id = xdg_toplevel_handle_set_app_id,
470 .show_window_menu = xdg_toplevel_handle_show_window_menu,
471 .move = xdg_toplevel_handle_move,
472 .resize = xdg_toplevel_handle_resize,
473 .set_max_size = xdg_toplevel_handle_set_max_size,
474 .set_min_size = xdg_toplevel_handle_set_min_size,
475 .set_maximized = xdg_toplevel_handle_set_maximized,
476 .unset_maximized = xdg_toplevel_handle_unset_maximized,
477 .set_fullscreen = xdg_toplevel_handle_set_fullscreen,
478 .unset_fullscreen = xdg_toplevel_handle_unset_fullscreen,
479 .set_minimized = xdg_toplevel_handle_set_minimized,
480 };
481
xdg_toplevel_handle_resource_destroy(struct wl_resource * resource)482 static void xdg_toplevel_handle_resource_destroy(struct wl_resource *resource) {
483 struct wlr_xdg_surface *surface =
484 wlr_xdg_surface_from_toplevel_resource(resource);
485 destroy_xdg_toplevel(surface);
486 }
487
488 const struct wlr_surface_role xdg_toplevel_surface_role = {
489 .name = "xdg_toplevel",
490 .commit = handle_xdg_surface_commit,
491 .precommit = handle_xdg_surface_precommit,
492 };
493
create_xdg_toplevel(struct wlr_xdg_surface * xdg_surface,uint32_t id)494 void create_xdg_toplevel(struct wlr_xdg_surface *xdg_surface,
495 uint32_t id) {
496 if (!wlr_surface_set_role(xdg_surface->surface, &xdg_toplevel_surface_role,
497 xdg_surface, xdg_surface->resource, XDG_WM_BASE_ERROR_ROLE)) {
498 return;
499 }
500
501 if (xdg_surface->role != WLR_XDG_SURFACE_ROLE_NONE) {
502 wl_resource_post_error(xdg_surface->resource,
503 XDG_SURFACE_ERROR_ALREADY_CONSTRUCTED,
504 "xdg-surface has already been constructed");
505 return;
506 }
507
508 assert(xdg_surface->toplevel == NULL);
509 xdg_surface->toplevel = calloc(1, sizeof(struct wlr_xdg_toplevel));
510 if (xdg_surface->toplevel == NULL) {
511 wl_resource_post_no_memory(xdg_surface->resource);
512 return;
513 }
514 xdg_surface->toplevel->base = xdg_surface;
515
516 wl_signal_init(&xdg_surface->toplevel->events.request_maximize);
517 wl_signal_init(&xdg_surface->toplevel->events.request_fullscreen);
518 wl_signal_init(&xdg_surface->toplevel->events.request_minimize);
519 wl_signal_init(&xdg_surface->toplevel->events.request_move);
520 wl_signal_init(&xdg_surface->toplevel->events.request_resize);
521 wl_signal_init(&xdg_surface->toplevel->events.request_show_window_menu);
522 wl_signal_init(&xdg_surface->toplevel->events.set_parent);
523 wl_signal_init(&xdg_surface->toplevel->events.set_title);
524 wl_signal_init(&xdg_surface->toplevel->events.set_app_id);
525
526 xdg_surface->toplevel->resource = wl_resource_create(
527 xdg_surface->client->client, &xdg_toplevel_interface,
528 wl_resource_get_version(xdg_surface->resource), id);
529 if (xdg_surface->toplevel->resource == NULL) {
530 free(xdg_surface->toplevel);
531 wl_resource_post_no_memory(xdg_surface->resource);
532 return;
533 }
534 wl_resource_set_implementation(xdg_surface->toplevel->resource,
535 &xdg_toplevel_implementation, xdg_surface,
536 xdg_toplevel_handle_resource_destroy);
537
538 xdg_surface->role = WLR_XDG_SURFACE_ROLE_TOPLEVEL;
539 }
540
destroy_xdg_toplevel(struct wlr_xdg_surface * xdg_surface)541 void destroy_xdg_toplevel(struct wlr_xdg_surface *xdg_surface) {
542 if (xdg_surface == NULL) {
543 return;
544 }
545 assert(xdg_surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL);
546 reset_xdg_surface(xdg_surface);
547 }
548
wlr_xdg_toplevel_set_size(struct wlr_xdg_surface * surface,uint32_t width,uint32_t height)549 uint32_t wlr_xdg_toplevel_set_size(struct wlr_xdg_surface *surface,
550 uint32_t width, uint32_t height) {
551 assert(surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL);
552 surface->toplevel->server_pending.width = width;
553 surface->toplevel->server_pending.height = height;
554
555 return schedule_xdg_surface_configure(surface);
556 }
557
wlr_xdg_toplevel_set_activated(struct wlr_xdg_surface * surface,bool activated)558 uint32_t wlr_xdg_toplevel_set_activated(struct wlr_xdg_surface *surface,
559 bool activated) {
560 assert(surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL);
561 surface->toplevel->server_pending.activated = activated;
562
563 return schedule_xdg_surface_configure(surface);
564 }
565
wlr_xdg_toplevel_set_maximized(struct wlr_xdg_surface * surface,bool maximized)566 uint32_t wlr_xdg_toplevel_set_maximized(struct wlr_xdg_surface *surface,
567 bool maximized) {
568 assert(surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL);
569 surface->toplevel->server_pending.maximized = maximized;
570
571 return schedule_xdg_surface_configure(surface);
572 }
573
wlr_xdg_toplevel_set_fullscreen(struct wlr_xdg_surface * surface,bool fullscreen)574 uint32_t wlr_xdg_toplevel_set_fullscreen(struct wlr_xdg_surface *surface,
575 bool fullscreen) {
576 assert(surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL);
577 surface->toplevel->server_pending.fullscreen = fullscreen;
578
579 return schedule_xdg_surface_configure(surface);
580 }
581
wlr_xdg_toplevel_set_resizing(struct wlr_xdg_surface * surface,bool resizing)582 uint32_t wlr_xdg_toplevel_set_resizing(struct wlr_xdg_surface *surface,
583 bool resizing) {
584 assert(surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL);
585 surface->toplevel->server_pending.resizing = resizing;
586
587 return schedule_xdg_surface_configure(surface);
588 }
589
wlr_xdg_toplevel_set_tiled(struct wlr_xdg_surface * surface,uint32_t tiled)590 uint32_t wlr_xdg_toplevel_set_tiled(struct wlr_xdg_surface *surface,
591 uint32_t tiled) {
592 assert(surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL);
593 surface->toplevel->server_pending.tiled = tiled;
594
595 return schedule_xdg_surface_configure(surface);
596 }
597