5 #include "xdg_shell_v6.h"
7 static const struct zxdg_toplevel_v6_interface xdg_toplevel_v6_impl;
9 static void xdg_toplevel_v6_handle_resource_destroy(struct wl_resource *resource);
10 static void xdg_toplevel_v6_set_parent(struct ds_xdg_toplevel_v6 *toplevel,
11 struct ds_xdg_toplevel_v6 *parent);
14 ds_xdg_toplevel_v6_add_set_parent_listener(struct ds_xdg_toplevel_v6 *toplevel,
15 struct wl_listener *listener)
17 wl_signal_add(&toplevel->events.set_parent, listener);
21 ds_xdg_toplevel_v6_add_request_move_listener(struct ds_xdg_toplevel_v6 *toplevel,
22 struct wl_listener *listener)
24 wl_signal_add(&toplevel->events.request_move, listener);
28 ds_xdg_toplevel_v6_add_request_resize_listener(struct ds_xdg_toplevel_v6 *toplevel,
29 struct wl_listener *listener)
31 wl_signal_add(&toplevel->events.request_resize, listener);
35 ds_xdg_toplevel_v6_add_request_maximize_listener(
36 struct ds_xdg_toplevel_v6 *toplevel,
37 struct wl_listener *listener)
39 wl_signal_add(&toplevel->events.request_maximize, listener);
43 ds_xdg_toplevel_v6_add_request_fullscreen_listener(
44 struct ds_xdg_toplevel_v6 *toplevel,
45 struct wl_listener *listener)
47 wl_signal_add(&toplevel->events.request_fullscreen, listener);
51 ds_xdg_toplevel_v6_add_request_minimize_listener(
52 struct ds_xdg_toplevel_v6 *toplevel,
53 struct wl_listener *listener)
55 wl_signal_add(&toplevel->events.request_minimize, listener);
59 ds_xdg_toplevel_v6_set_size(struct ds_xdg_toplevel_v6 *toplevel,
60 int32_t width, int32_t height)
62 toplevel->scheduled.width = width;
63 toplevel->scheduled.height = height;
64 return ds_xdg_surface_v6_schedule_configure(toplevel->base);
68 ds_xdg_toplevel_v6_set_activated(struct ds_xdg_toplevel_v6 *toplevel,
71 toplevel->scheduled.activated = activated;
72 return ds_xdg_surface_v6_schedule_configure(toplevel->base);
76 ds_xdg_toplevel_v6_set_maximized(struct ds_xdg_toplevel_v6 *toplevel,
79 toplevel->scheduled.maximized = maximized;
80 return ds_xdg_surface_v6_schedule_configure(toplevel->base);
84 ds_xdg_toplevel_v6_set_fullscreen(struct ds_xdg_toplevel_v6 *toplevel,
87 toplevel->scheduled.fullscreen = fullscreen;
88 return ds_xdg_surface_v6_schedule_configure(toplevel->base);
92 ds_xdg_toplevel_v6_set_resizing(struct ds_xdg_toplevel_v6 *toplevel,
95 toplevel->scheduled.resizing = resizing;
96 return ds_xdg_surface_v6_schedule_configure(toplevel->base);
100 create_xdg_toplevel_v6(struct ds_xdg_surface_v6 *surface, uint32_t id)
102 if (surface->role != DS_XDG_SURFACE_V6_ROLE_NONE) {
103 wl_resource_post_error(surface->resource,
104 ZXDG_SURFACE_V6_ERROR_ALREADY_CONSTRUCTED,
105 "xdg_surface_v6 has already been constructed");
109 DS_ASSERT(surface->toplevel == NULL);
111 surface->toplevel = calloc(1, sizeof *surface->toplevel);
112 if (!surface->toplevel) {
113 wl_resource_post_no_memory(surface->resource);
117 surface->toplevel->base = surface;
119 wl_signal_init(&surface->toplevel->events.request_maximize);
120 wl_signal_init(&surface->toplevel->events.request_fullscreen);
121 wl_signal_init(&surface->toplevel->events.request_minimize);
122 wl_signal_init(&surface->toplevel->events.request_move);
123 wl_signal_init(&surface->toplevel->events.request_resize);
124 wl_signal_init(&surface->toplevel->events.request_show_window_menu);
125 wl_signal_init(&surface->toplevel->events.set_parent);
126 wl_signal_init(&surface->toplevel->events.set_title);
127 wl_signal_init(&surface->toplevel->events.set_app_id);
129 surface->toplevel->resource = wl_resource_create(
130 surface->client->wl_client, &zxdg_toplevel_v6_interface,
131 wl_resource_get_version(surface->resource), id);
132 if (!surface->toplevel->resource) {
133 free(surface->toplevel);
134 wl_resource_post_no_memory(surface->resource);
138 wl_resource_set_implementation(surface->toplevel->resource,
139 &xdg_toplevel_v6_impl, surface->toplevel,
140 xdg_toplevel_v6_handle_resource_destroy);
142 surface->role = DS_XDG_SURFACE_V6_ROLE_TOPLEVEL;
146 handle_xdg_toplevel_v6_committed(struct ds_xdg_toplevel_v6 *toplevel)
148 toplevel->current = toplevel->pending;
150 if (!toplevel->sent_initial_configure) {
151 ds_xdg_surface_v6_schedule_configure(toplevel->base);
152 toplevel->sent_initial_configure = true;
157 send_xdg_toplevel_v6_configure(struct ds_xdg_surface_v6 *surface,
158 struct ds_xdg_surface_v6_configure *configure)
160 struct wl_array states;
161 uint32_t width, height;
163 configure->toplevel_configure =
164 malloc(sizeof *configure->toplevel_configure);
165 if (!configure->toplevel_configure) {
166 wl_resource_post_no_memory(surface->toplevel->resource);
170 *configure->toplevel_configure = surface->toplevel->scheduled;
172 wl_array_init(&states);
173 if (surface->toplevel->scheduled.maximized) {
174 uint32_t *s = wl_array_add(&states, sizeof(uint32_t));
177 *s = ZXDG_TOPLEVEL_V6_STATE_MAXIMIZED;
180 if (surface->toplevel->scheduled.fullscreen) {
181 uint32_t *s = wl_array_add(&states, sizeof(uint32_t));
184 *s = ZXDG_TOPLEVEL_V6_STATE_FULLSCREEN;
187 if (surface->toplevel->scheduled.resizing) {
188 uint32_t *s = wl_array_add(&states, sizeof(uint32_t));
191 *s = ZXDG_TOPLEVEL_V6_STATE_RESIZING;
194 if (surface->toplevel->scheduled.activated) {
195 uint32_t *s = wl_array_add(&states, sizeof(uint32_t));
198 *s = ZXDG_TOPLEVEL_V6_STATE_ACTIVATED;
201 width = surface->toplevel->scheduled.width;
202 height = surface->toplevel->scheduled.height;
204 zxdg_toplevel_v6_send_configure(surface->toplevel->resource, width, height,
206 wl_array_release(&states);
211 wl_array_release(&states);
212 wl_resource_post_no_memory(surface->toplevel->resource);
216 destroy_xdg_toplevel_v6(struct ds_xdg_toplevel_v6 *toplevel)
218 wl_resource_set_user_data(toplevel->resource, NULL);
223 reset_xdg_toplevel_v6(struct ds_xdg_toplevel_v6 *toplevel)
225 if (toplevel->parent) {
226 wl_list_remove(&toplevel->parent_unmap.link);
227 toplevel->parent = NULL;
230 free(toplevel->title);
231 toplevel->title = NULL;
233 free(toplevel->app_id);
234 toplevel->app_id = NULL;
236 if (toplevel->requested.fullscreen_output) {
237 wl_list_remove(&toplevel->requested.fullscreen_output_destroy.link);
238 toplevel->requested.fullscreen_output = NULL;
241 toplevel->requested.fullscreen = false;
242 toplevel->requested.maximized = false;
243 toplevel->requested.minimized = false;
245 toplevel->sent_initial_configure = false;
249 xdg_toplevel_v6_handle_destroy(struct wl_client *client,
250 struct wl_resource *resource)
252 wl_resource_destroy(resource);
256 xdg_toplevel_v6_handle_set_parent(struct wl_client *client,
257 struct wl_resource *resource, struct wl_resource *parent_resource)
259 struct ds_xdg_toplevel_v6 *toplevel, *parent = NULL;
261 toplevel = wl_resource_get_user_data(resource);
266 parent = wl_resource_get_user_data(parent_resource);
268 xdg_toplevel_v6_set_parent(toplevel, parent);
272 xdg_toplevel_v6_handle_set_title(struct wl_client *client,
273 struct wl_resource *resource, const char *title)
275 struct ds_xdg_toplevel_v6 *toplevel;
278 toplevel = wl_resource_get_user_data(resource);
284 wl_resource_post_no_memory(resource);
289 free(toplevel->title);
291 toplevel->title = tmp;
292 wl_signal_emit_mutable(&toplevel->events.set_title, toplevel);
296 xdg_toplevel_v6_handle_set_app_id(struct wl_client *client,
297 struct wl_resource *resource, const char *app_id)
299 struct ds_xdg_toplevel_v6 *toplevel;
302 toplevel = wl_resource_get_user_data(resource);
306 tmp = strdup(app_id);
308 wl_resource_post_no_memory(resource);
312 if (toplevel->app_id)
313 free(toplevel->app_id);
315 toplevel->app_id= tmp;
316 wl_signal_emit_mutable(&toplevel->events.set_app_id, toplevel);
320 xdg_toplevel_v6_handle_show_window_menu(struct wl_client *client,
321 struct wl_resource *resource, struct wl_resource *seat_resource,
322 uint32_t serial, int32_t x, int32_t y)
328 xdg_toplevel_v6_handle_move(struct wl_client *client,
329 struct wl_resource *resource, struct wl_resource *seat_resource,
332 struct ds_xdg_toplevel_v6 *toplevel;
334 toplevel = wl_resource_get_user_data(resource);
338 if (!toplevel->base->configured) {
339 wl_resource_post_error(toplevel->base->resource,
340 ZXDG_SURFACE_V6_ERROR_NOT_CONSTRUCTED,
341 "surface has not been configured yet");
345 struct ds_xdg_toplevel_v6_event_request_move event = {
346 .toplevel = toplevel,
347 .seat_resource = seat_resource,
350 wl_signal_emit_mutable(&toplevel->events.request_move, &event);
354 xdg_toplevel_v6_handle_resize(struct wl_client *client,
355 struct wl_resource *resource, struct wl_resource *seat_resource,
356 uint32_t serial, uint32_t edges)
358 struct ds_xdg_toplevel_v6 *toplevel;
360 toplevel = wl_resource_get_user_data(resource);
364 if (!toplevel->base->configured) {
365 wl_resource_post_error(toplevel->base->resource,
366 ZXDG_SURFACE_V6_ERROR_NOT_CONSTRUCTED,
367 "surface has not been configured yet");
371 struct ds_xdg_toplevel_v6_event_request_resize event = {
372 .toplevel = toplevel,
373 .seat_resource = seat_resource,
377 wl_signal_emit_mutable(&toplevel->events.request_resize, &event);
381 xdg_toplevel_v6_handle_set_max_size(struct wl_client *client,
382 struct wl_resource *resource, int32_t width, int32_t height)
384 struct ds_xdg_toplevel_v6 *toplevel;
386 toplevel = wl_resource_get_user_data(resource);
390 toplevel->pending.max_width = width;
391 toplevel->pending.max_height = height;
395 xdg_toplevel_v6_handle_set_min_size(struct wl_client *client,
396 struct wl_resource *resource, int32_t width, int32_t height)
398 struct ds_xdg_toplevel_v6 *toplevel;
400 toplevel = wl_resource_get_user_data(resource);
404 toplevel->pending.min_width = width;
405 toplevel->pending.min_height = height;
409 xdg_toplevel_v6_handle_set_maximized(struct wl_client *client,
410 struct wl_resource *resource)
412 struct ds_xdg_toplevel_v6 *toplevel;
414 toplevel = wl_resource_get_user_data(resource);
418 toplevel->requested.maximized = true;
419 wl_signal_emit_mutable(&toplevel->events.request_maximize, toplevel);
423 xdg_toplevel_v6_handle_unset_maximized(struct wl_client *client,
424 struct wl_resource *resource)
426 struct ds_xdg_toplevel_v6 *toplevel;
428 toplevel = wl_resource_get_user_data(resource);
432 toplevel->requested.maximized = false;
433 wl_signal_emit_mutable(&toplevel->events.request_maximize, toplevel);
437 xdg_toplevel_v6_handle_set_fullscreen(struct wl_client *client,
438 struct wl_resource *resource, struct wl_resource *output_resource)
440 struct ds_xdg_toplevel_v6 *toplevel;
442 toplevel = wl_resource_get_user_data(resource);
446 // TODO get a ds_output from an output_resource
448 toplevel->requested.fullscreen = true;
449 wl_signal_emit_mutable(&toplevel->events.request_fullscreen, toplevel);
453 xdg_toplevel_v6_handle_unset_fullscreen(struct wl_client *client,
454 struct wl_resource *resource)
456 struct ds_xdg_toplevel_v6 *toplevel;
458 toplevel = wl_resource_get_user_data(resource);
462 toplevel->requested.fullscreen = false;
463 wl_signal_emit_mutable(&toplevel->events.request_fullscreen, toplevel);
467 xdg_toplevel_v6_handle_set_minimized(struct wl_client *client,
468 struct wl_resource *resource)
470 struct ds_xdg_toplevel_v6 *toplevel;
472 toplevel = wl_resource_get_user_data(resource);
476 toplevel->requested.minimized = true;
477 wl_signal_emit_mutable(&toplevel->events.request_maximize, toplevel);
480 static const struct zxdg_toplevel_v6_interface xdg_toplevel_v6_impl =
482 xdg_toplevel_v6_handle_destroy,
483 xdg_toplevel_v6_handle_set_parent,
484 xdg_toplevel_v6_handle_set_title,
485 xdg_toplevel_v6_handle_set_app_id,
486 xdg_toplevel_v6_handle_show_window_menu,
487 xdg_toplevel_v6_handle_move,
488 xdg_toplevel_v6_handle_resize,
489 xdg_toplevel_v6_handle_set_max_size,
490 xdg_toplevel_v6_handle_set_min_size,
491 xdg_toplevel_v6_handle_set_maximized,
492 xdg_toplevel_v6_handle_unset_maximized,
493 xdg_toplevel_v6_handle_set_fullscreen,
494 xdg_toplevel_v6_handle_unset_fullscreen,
495 xdg_toplevel_v6_handle_set_minimized,
499 xdg_toplevel_v6_handle_resource_destroy(struct wl_resource *resource)
501 struct ds_xdg_toplevel_v6 *toplevel;
503 toplevel = wl_resource_get_user_data(resource);
507 destroy_xdg_surface_v6_role(toplevel->base);
511 xdg_toplevel_v6_handle_parent_unmap(struct wl_listener *listener, void *data)
513 struct ds_xdg_toplevel_v6 *toplevel;
515 toplevel = wl_container_of(listener, toplevel, parent_unmap);
516 xdg_toplevel_v6_set_parent(toplevel, toplevel->parent->parent);
520 xdg_toplevel_v6_set_parent(struct ds_xdg_toplevel_v6 *toplevel,
521 struct ds_xdg_toplevel_v6 *parent)
523 struct ds_xdg_toplevel_v6 *iter = parent;
526 if (iter == toplevel)
531 if (toplevel->parent)
532 wl_list_remove(&toplevel->parent_unmap.link);
534 if (parent && parent->base->mapped) {
535 toplevel->parent = parent;
536 toplevel->parent_unmap.notify = xdg_toplevel_v6_handle_parent_unmap;
537 wl_signal_add(&toplevel->parent->base->events.unmap,
538 &toplevel->parent_unmap);
541 toplevel->parent = NULL;
544 wl_signal_emit_mutable(&toplevel->events.set_parent, NULL);