e_xdg_shell_v6: fix bug for updating min_max size
[platform/upstream/enlightenment.git] / src / bin / e_xdg_shell_v6.c
1 #include "e.h"
2
3 #include <libds/surface.h>
4 #include <libds/types/ds_xdg_shell_v6.h>
5
6 #ifdef LOG
7 #undef LOG
8 #endif
9 #ifdef ERR
10 #undef ERR
11 #endif
12
13 #define LOG(f, e, x...)  ELOGF("XDG6 <LOG>", f, e, ##x)
14 #define ERR(f, e, x...)  ELOGF("XDG6 <ERR>", f, e, ##x)
15
16 typedef struct _E_Xdg_Shell_V6 E_Xdg_Shell_V6;
17 typedef struct _E_Xdg_Toplevel_V6 E_Xdg_Toplevel_V6;
18
19 struct _E_Xdg_Shell_V6
20 {
21    struct ds_xdg_shell_v6 *ds_xdg_shell;
22
23    struct wl_listener destroy;
24    struct wl_listener new_surface;
25 };
26
27 struct _E_Xdg_Toplevel_V6
28 {
29    struct ds_xdg_toplevel_v6 *ds_toplevel;
30    E_Client *ec;
31
32    struct wl_listener set_parent;
33    struct wl_listener set_title;
34    struct wl_listener set_app_id;
35    struct wl_listener request_move;
36    struct wl_listener request_resize;
37    struct wl_listener request_maximize;
38    struct wl_listener request_fullscreen;
39    struct wl_listener request_minimize;
40    struct wl_listener destroy;
41    struct wl_listener configure;
42    struct wl_listener ping_timeout;
43    struct wl_listener surface_commit;
44 };
45
46 static void _e_xdg_shell_v6_cb_destroy(struct wl_listener *listener, void *data);
47 static void _e_xdg_shell_v6_cb_new_surface(struct wl_listener *listener, void *data);
48 static void _e_xdg_toplevel_v6_add(struct ds_xdg_surface_v6 *ds_xdg_surface);
49 static void _e_xdg_toplevel_v6_cb_xdg_surface_destroy(struct wl_listener *listener, void *data);
50 static E_Xdg_Toplevel_V6 *_e_xdg_toplevel_v6_from_shell_surface_resource(struct wl_resource *shsurface_resource);
51
52 EINTERN Eina_Bool
53 e_xdg_shell_v6_init(void)
54 {
55    static E_Xdg_Shell_V6 shell = { .ds_xdg_shell = NULL };
56
57    LOG("Initializing Xdg_Shell_V6", NULL);
58
59    if (shell.ds_xdg_shell)
60      {
61         LOG("Xdg_Shell_V6 already initialized", NULL);
62         return EINA_TRUE;
63      }
64
65
66    shell.ds_xdg_shell = ds_xdg_shell_v6_create(e_comp_wl->wl.disp);
67    if (!shell.ds_xdg_shell)
68      {
69         ERR("Could not create ds_xdg_shell_v6", NULL);
70         return EINA_FALSE;
71      }
72
73    shell.destroy.notify = _e_xdg_shell_v6_cb_destroy;
74    ds_xdg_shell_v6_add_destroy_listener(shell.ds_xdg_shell, &shell.destroy);
75    shell.new_surface.notify = _e_xdg_shell_v6_cb_new_surface;
76    ds_xdg_shell_v6_add_new_surface_listener(shell.ds_xdg_shell, &shell.new_surface);
77
78    return EINA_TRUE;
79 }
80
81 EINTERN E_Client *
82 e_xdg_shell_v6_xdg_surface_ec_get(struct wl_resource *resource)
83 {
84    E_Xdg_Toplevel_V6 *toplevel;
85
86    toplevel = _e_xdg_toplevel_v6_from_shell_surface_resource(resource);
87    if (!toplevel)
88      {
89         ERR("No E_Xdg_Toplevel_V6 in wl_resource", NULL);
90         return NULL;
91      }
92
93    return toplevel->ec;
94 }
95
96 static void
97 _e_xdg_shell_v6_cb_destroy(struct wl_listener *listener, void *data)
98 {
99    E_Xdg_Shell_V6 *shell;
100
101    LOG("Destroy Xdg_Shell_V6", NULL);
102
103    shell = wl_container_of(listener, shell, destroy);
104    wl_list_remove(&shell->destroy.link);
105    wl_list_remove(&shell->new_surface.link);
106    shell->ds_xdg_shell = NULL;
107 }
108
109 static void
110 _e_xdg_shell_v6_cb_new_surface(struct wl_listener *listener, void *data)
111 {
112    struct ds_xdg_surface_v6 *ds_xdg_surface = data;
113
114    if (ds_xdg_surface->role == DS_XDG_SURFACE_V6_ROLE_TOPLEVEL)
115      _e_xdg_toplevel_v6_add(ds_xdg_surface);
116    else
117      ERR("Not implemented: xdg_surface_v6(role:%d)", NULL, ds_xdg_surface->role);
118 }
119
120 static E_Xdg_Toplevel_V6 *
121 _e_xdg_toplevel_v6_from_shell_surface_resource(struct wl_resource *shsurface_resource)
122 {
123    E_Xdg_Toplevel_V6 *toplevel;
124    struct ds_xdg_surface_v6 *ds_xdg_surface;
125    struct wl_listener *listener;
126
127    ds_xdg_surface = ds_xdg_surface_v6_from_resource(shsurface_resource);
128    if (!ds_xdg_surface)
129      return NULL;
130
131    listener = wl_signal_get(&ds_xdg_surface->events.destroy,
132                             _e_xdg_toplevel_v6_cb_xdg_surface_destroy);
133    if (listener)
134      return wl_container_of(listener, toplevel, destroy);
135
136    return NULL;
137 }
138
139 static void
140 _e_xdg_toplevel_v6_fullscreen_send(E_Xdg_Toplevel_V6 *toplevel)
141 {
142    struct ds_xdg_toplevel_v6 *ds_toplevel = toplevel->ds_toplevel;
143    E_Client *ec = toplevel->ec;
144
145    if (ds_toplevel->scheduled.fullscreen == ec->fullscreen)
146      return;
147
148    LOG("Send fullscreen(%d)", ec, ec->fullscreen);
149
150    ds_xdg_toplevel_v6_set_fullscreen(ds_toplevel, ec->fullscreen);
151 }
152
153 static void
154 _e_xdg_toplevel_v6_maximized_send(E_Xdg_Toplevel_V6 *toplevel)
155 {
156    struct ds_xdg_toplevel_v6 *ds_toplevel = toplevel->ds_toplevel;
157    E_Client *ec = toplevel->ec;
158
159    if (ds_toplevel->scheduled.maximized == !!ec->maximized)
160      return;
161
162    LOG("Send maximized(%d)", ec, ec->maximized);
163
164    ds_xdg_toplevel_v6_set_maximized(ds_toplevel, ec->maximized);
165 }
166
167 static void
168 _e_xdg_toplevel_v6_resizing_send(E_Xdg_Toplevel_V6 *toplevel, Eina_Bool resizing)
169 {
170    struct ds_xdg_toplevel_v6 *ds_toplevel = toplevel->ds_toplevel;
171
172    if (ds_toplevel->scheduled.resizing == resizing)
173      return;
174
175    LOG("Send resizing(%d)", toplevel->ec, resizing);
176
177    ds_xdg_toplevel_v6_set_resizing(ds_toplevel, resizing);
178 }
179
180 static void
181 _e_xdg_toplevel_v6_activated_send(E_Xdg_Toplevel_V6 *toplevel)
182 {
183    struct ds_xdg_toplevel_v6 *ds_toplevel = toplevel->ds_toplevel;
184    E_Client *ec = toplevel->ec, *focused_ec;
185    Eina_Bool activated;
186
187    focused_ec = e_client_focused_get();
188    activated = (focused_ec == ec);
189
190    if (ds_toplevel->scheduled.activated == activated)
191      return;
192
193    LOG("Send activated(%d)", ec, activated);
194
195    ds_xdg_toplevel_v6_set_activated(ds_toplevel, activated);
196 }
197
198 static void
199 _e_xdg_toplevel_v6_size_send(E_Xdg_Toplevel_V6 *toplevel, int32_t width, int32_t height)
200 {
201    E_Client *ec = toplevel->ec;
202    struct ds_xdg_toplevel_v6 *ds_toplevel = toplevel->ds_toplevel;
203    int32_t configure_width = 0, configure_height = 0;
204    int mw, mh;
205
206    if (ec->fullscreen)
207      {
208         e_client_base_output_resolution_useful_geometry_get(ec, NULL, NULL, &mw, &mh);
209         LOG("FORCELY STAY current fullscreen size (%d %d) of E_Client, requested size "
210             "is (%d %d), the state (maximize %d, fullscreen %d)",
211             ec, mw, mh, width, height, ec->maximized, ec->fullscreen);
212         configure_width = mw;
213         configure_height = mh;
214      }
215    else if (ec->maximized)
216      {
217         e_client_maximized_geometry_get(ec, NULL, NULL, &mw, &mh);
218         LOG("FORCELY STAY current maximized size (%d %d) of E_Client, requested size "
219             "is (%d %d), the state (maximize %d, fullscreen %d)",
220             ec, mw, mh, width, height, ec->maximized, ec->fullscreen);
221         configure_width = mw;
222         configure_height = mh;
223      }
224    else if ((width != -1) && (height != -1))
225      {
226         configure_width = width;
227         configure_height = height;
228      }
229
230    LOG("Send size(%dx%d)", ec, configure_width, configure_height);
231
232    ds_xdg_toplevel_v6_set_size(ds_toplevel, configure_width, configure_height);
233 }
234
235 static void
236 _e_xdg_toplevel_v6_configure_send(struct wl_resource *shsurface_resource,
237                                   uint32_t edges, int32_t width, int32_t height)
238 {
239    E_Xdg_Toplevel_V6 *toplevel;
240
241    toplevel = _e_xdg_toplevel_v6_from_shell_surface_resource(shsurface_resource);
242    if (!toplevel)
243      return;
244
245    _e_xdg_toplevel_v6_fullscreen_send(toplevel);
246    _e_xdg_toplevel_v6_maximized_send(toplevel);
247    _e_xdg_toplevel_v6_resizing_send(toplevel, !!edges);
248    _e_xdg_toplevel_v6_size_send(toplevel, width, height);
249    _e_xdg_toplevel_v6_activated_send(toplevel);
250 }
251
252 static void
253 _e_xdg_toplevel_v6_configure(struct wl_resource *shsurface_resource,
254                              Evas_Coord x, Evas_Coord y,
255                              Evas_Coord w, Evas_Coord h)
256 {
257    E_Xdg_Toplevel_V6 *toplevel;
258
259    toplevel = _e_xdg_toplevel_v6_from_shell_surface_resource(shsurface_resource);
260    if (!toplevel)
261      return;
262
263    e_client_util_move_resize_without_frame(toplevel->ec, x, y, w, h);
264 }
265
266 static void
267 _e_xdg_toplevel_v6_ping(struct wl_resource *shsurface_resource)
268 {
269    E_Xdg_Toplevel_V6 *toplevel;
270
271    toplevel = _e_xdg_toplevel_v6_from_shell_surface_resource(shsurface_resource);
272    if (!toplevel)
273      return;
274
275    LOG("Ping", toplevel->ec);
276
277    ds_xdg_surface_v6_ping(toplevel->ds_toplevel->base);
278 }
279
280 static void
281 _e_xdg_surface_v6_map(struct wl_resource *shsurface_resource)
282 {
283    E_Xdg_Toplevel_V6 *toplevel;
284
285    toplevel = _e_xdg_toplevel_v6_from_shell_surface_resource(shsurface_resource);
286    if (!toplevel)
287      return;
288
289    LOG("Map", toplevel->ec);
290
291    toplevel->ds_toplevel->base->mapped = true;
292    e_shell_e_client_map(toplevel->ec);
293 }
294
295 static void
296 _e_xdg_toplevel_v6_unmap(struct wl_resource *shsurface_resource)
297 {
298    E_Xdg_Toplevel_V6 *toplevel;
299
300    toplevel = _e_xdg_toplevel_v6_from_shell_surface_resource(shsurface_resource);
301    if (!toplevel)
302      return;
303
304    LOG("Unmap", toplevel->ec);
305
306    toplevel->ds_toplevel->base->mapped = false;
307    e_shell_e_client_unmap(toplevel->ec);
308 }
309
310 static E_Shell_Surface_Api shell_xdg_toplevel_v6_api = {
311      .configure_send = _e_xdg_toplevel_v6_configure_send,
312      .configure = _e_xdg_toplevel_v6_configure,
313      .ping = _e_xdg_toplevel_v6_ping,
314      .map = _e_xdg_surface_v6_map,
315      .unmap = _e_xdg_toplevel_v6_unmap,
316 };
317
318 static void
319 _e_xdg_toplevel_v6_role_init(E_Xdg_Toplevel_V6 *toplevel)
320 {
321    E_Client *ec = toplevel->ec;
322    struct ds_xdg_surface_v6 *ds_xdg_surface = toplevel->ds_toplevel->base;
323    E_Comp_Wl_Client_Data *cdata;
324
325    e_shell_e_client_shsurface_assign(ec,
326                                      ds_xdg_surface->resource,
327                                      &shell_xdg_toplevel_v6_api);
328
329    cdata = e_client_cdata_get(ec);
330    if (cdata)
331      {
332         cdata->sh_v6.res_role = toplevel->ds_toplevel->resource;
333         cdata->sh_v6.role = E_COMP_WL_SH_SURF_ROLE_TOPLV;
334      }
335
336    e_shell_e_client_toplevel_set(ec);
337    e_comp_wl_shell_surface_ready(toplevel->ec);
338 }
339
340 static void
341 _e_xdg_toplevel_v6_client_parent_update(E_Xdg_Toplevel_V6 *toplevel)
342 {
343    E_Client *ec = toplevel->ec;
344    struct ds_xdg_toplevel_v6 *parent = toplevel->ds_toplevel->parent;
345    struct wl_resource *parent_surface_resource = NULL;
346
347    if (parent)
348      {
349         parent_surface_resource =
350            ds_surface_get_wl_resource(parent->base->ds_surface);
351      }
352
353    LOG("Set parent: resource(%p)", ec, parent_surface_resource);
354
355    e_shell_e_client_parent_set(ec, parent_surface_resource);
356    EC_CHANGED(ec);
357 }
358
359 static void
360 _e_xdg_toplevel_v6_title_update(E_Xdg_Toplevel_V6 *toplevel)
361 {
362    E_Client *ec = toplevel->ec;
363    char *title = toplevel->ds_toplevel->title;
364
365    LOG("Set title: %s", ec, title ? title : "(null)");
366
367    e_shell_e_client_name_title_set(ec, title, title);
368 }
369
370 static void
371 _e_xdg_toplevel_v6_app_id_update(E_Xdg_Toplevel_V6 *toplevel)
372 {
373    E_Client *ec = toplevel->ec;
374    char *app_id = toplevel->ds_toplevel->app_id;
375    struct wl_client *client;
376
377    client = wl_resource_get_client(toplevel->ds_toplevel->resource);
378    wl_client_get_credentials(client, &ec->netwm.pid, NULL, NULL);
379
380    LOG("Set app_id: %s, PID(%d)", ec, app_id ? app_id : "(null)", ec->netwm.pid);
381
382    e_shell_e_client_app_id_set(ec, app_id);
383 }
384
385 static void
386 _e_xdg_toplevel_v6_move_begin(E_Xdg_Toplevel_V6 *toplevel, struct wl_resource *seat_resource)
387 {
388    E_Client *ec = toplevel->ec;
389
390    LOG("Begin interactive move", ec);
391
392    if (!e_shell_e_client_interactive_move(ec, seat_resource))
393      ERR("Failed to move this Toplevel(%p)", ec, toplevel);
394 }
395
396 static void
397 _e_xdg_toplevel_v6_resize_begin(E_Xdg_Toplevel_V6 *toplevel, struct wl_resource *seat_resource, uint32_t edges)
398 {
399    E_Client *ec = toplevel->ec;
400    struct wl_resource *toplevel_resource = toplevel->ds_toplevel->resource;
401
402    LOG("Begin interactive resize", ec);
403
404    if (!e_shell_e_client_interactive_resize(ec, toplevel_resource, seat_resource, edges))
405      ERR("Failed to move this Toplevel(%p)", ec, toplevel);
406 }
407
408 static void
409 _e_xdg_toplevel_v6_maximize_set(E_Xdg_Toplevel_V6 *toplevel)
410 {
411    E_Client *ec = toplevel->ec;
412    E_Maximize max = ec->maximize_type | E_MAXIMIZE_BOTH;
413
414    LOG("Set maximize. lock_user_maximize:%d, dir:%d",
415        ec, ec->lock_user_maximize, ec->maximize_dir);
416
417    if (ec->lock_user_maximize)
418      return;
419
420    if ((ec->maximize_dir != E_MAXIMIZE_DIRECTION_ALL) &&
421        (ec->maximize_dir != E_MAXIMIZE_DIRECTION_NONE))
422      return;
423
424    e_client_layout_apply(ec, EINA_FALSE);
425    e_client_maximize(ec, max);
426 }
427
428 static void
429 _e_xdg_toplevel_v6_maximize_unset(E_Xdg_Toplevel_V6 *toplevel)
430 {
431    E_Client *ec = toplevel->ec;
432
433    LOG("Unset maximize. lock_user_maximize:%d", ec, ec->lock_user_maximize);
434
435    e_client_layout_apply(ec, EINA_FALSE);
436
437    ec->maximize_dir = E_MAXIMIZE_DIRECTION_NONE;
438    /* it's doubtful */
439    e_client_unmaximize(ec, E_MAXIMIZE_BOTH);
440 }
441
442 static void
443 _e_xdg_toplevel_v6_fullscreen_set(E_Xdg_Toplevel_V6 *toplevel)
444 {
445    E_Client *ec = toplevel->ec;
446
447    LOG("Set fullscreen. lock_user_fullscreen:%d", ec, ec->lock_user_fullscreen);
448
449    if (ec->lock_user_fullscreen)
450      return;
451
452    e_client_fullscreen(ec, e_config->fullscreen_policy);
453 }
454
455 static void
456 _e_xdg_toplevel_v6_fullscreen_unset(E_Xdg_Toplevel_V6 *toplevel)
457 {
458    E_Client *ec = toplevel->ec;
459
460    LOG("Unset fullscreen. lock_user_fullscreen:%d", ec, ec->lock_user_fullscreen);
461
462    if (ec->lock_user_fullscreen)
463      return;
464
465    e_client_unfullscreen(ec);
466 }
467
468 static void
469 _e_xdg_toplevel_v6_minimize_set(E_Xdg_Toplevel_V6 *toplevel)
470 {
471    E_Client *ec = toplevel->ec;
472
473    LOG("Set minimize. lock_client_iconify:%d", ec, ec->lock_client_iconify);
474
475    if (ec->lock_client_iconify)
476      return;
477
478    e_client_iconify(ec);
479 }
480
481 static void
482 _e_xdg_toplevel_v6_oldest_configure_remove(E_Xdg_Toplevel_V6 *toplevel)
483 {
484    struct ds_xdg_surface_v6 *ds_xdg_surface;
485    struct ds_xdg_surface_v6_configure *oldest_configure;
486    const int WAIT_ACK_COUNT_MAX = 16;
487
488    ds_xdg_surface = toplevel->ds_toplevel->base;
489    if (wl_list_length(&ds_xdg_surface->configure_list) <= WAIT_ACK_COUNT_MAX)
490      return;
491
492    oldest_configure = wl_container_of(ds_xdg_surface->configure_list.next,
493                                       oldest_configure,
494                                       link);
495
496    LOG("Don't rececive Configure Ack. Remove oldest configure:%p, serial:%d",
497        toplevel->ec, oldest_configure, oldest_configure->serial);
498
499    wl_list_remove(&oldest_configure->link);
500    free(oldest_configure);
501 }
502
503 static void
504 _e_xdg_toplevel_v6_window_geometry_update(E_Xdg_Toplevel_V6 *toplevel)
505 {
506    struct ds_xdg_surface_v6 *ds_xdg_surface = toplevel->ds_toplevel->base;
507    E_Comp_Wl_Client_Data *cdata;
508
509    cdata = e_client_cdata_get(toplevel->ec);
510    if (!cdata)
511      return;
512
513    EINA_RECTANGLE_SET(&cdata->shell.window,
514                       ds_xdg_surface->current.geometry.x,
515                       ds_xdg_surface->current.geometry.y,
516                       ds_xdg_surface->current.geometry.width,
517                       ds_xdg_surface->current.geometry.height);
518 }
519
520 static void
521 _e_xdg_toplevel_v6_min_max_size_update(E_Xdg_Toplevel_V6 *toplevel)
522 {
523    E_Client *ec = toplevel->ec;
524    struct ds_xdg_toplevel_v6 *ds_toplevel = toplevel->ds_toplevel;
525
526    if (ec->lock_client_size)
527      return;
528
529    ec->icccm.min_w = ds_toplevel->current.min_width;
530    ec->icccm.min_h = ds_toplevel->current.min_height;
531    ec->icccm.max_w = ds_toplevel->current.max_width;
532    ec->icccm.max_h = ds_toplevel->current.max_height;
533 }
534
535 static void
536 _e_xdg_toplevel_v6_cb_set_parent(struct wl_listener *listener, void *data)
537 {
538    E_Xdg_Toplevel_V6 *toplevel;
539
540    toplevel = wl_container_of(listener, toplevel, set_parent);
541    _e_xdg_toplevel_v6_client_parent_update(toplevel);
542 }
543
544 static void
545 _e_xdg_toplevel_v6_cb_set_title(struct wl_listener *listener, void *data)
546 {
547    E_Xdg_Toplevel_V6 *toplevel;
548
549    toplevel = wl_container_of(listener, toplevel, set_title);
550    _e_xdg_toplevel_v6_title_update(toplevel);
551 }
552
553 static void
554 _e_xdg_toplevel_v6_cb_set_app_id(struct wl_listener *listener, void *data)
555 {
556    E_Xdg_Toplevel_V6 *toplevel;
557
558    toplevel = wl_container_of(listener, toplevel, set_app_id);
559    _e_xdg_toplevel_v6_app_id_update(toplevel);
560 }
561
562 static void
563 _e_xdg_toplevel_v6_cb_request_move(struct wl_listener *listener, void *data)
564 {
565    E_Xdg_Toplevel_V6 *toplevel;
566    struct ds_xdg_toplevel_v6_event_request_move *event = data;
567
568    toplevel = wl_container_of(listener, toplevel, request_move);
569    _e_xdg_toplevel_v6_move_begin(toplevel, event->seat_resource);
570 }
571
572 static void
573 _e_xdg_toplevel_v6_cb_request_resize(struct wl_listener *listener, void *data)
574 {
575    E_Xdg_Toplevel_V6 *toplevel;
576    struct ds_xdg_toplevel_v6_event_request_resize *event = data;
577
578    toplevel = wl_container_of(listener, toplevel, request_resize);
579    _e_xdg_toplevel_v6_resize_begin(toplevel, event->seat_resource, event->edges);
580 }
581
582 static void
583 _e_xdg_toplevel_v6_cb_request_maximize(struct wl_listener *listener, void *data)
584 {
585    E_Xdg_Toplevel_V6 *toplevel;
586
587    toplevel = wl_container_of(listener, toplevel, request_maximize);
588    if (toplevel->ds_toplevel->requested.maximized)
589      _e_xdg_toplevel_v6_maximize_set(toplevel);
590    else
591      _e_xdg_toplevel_v6_maximize_unset(toplevel);
592 }
593
594 static void
595 _e_xdg_toplevel_v6_cb_request_fullscreen(struct wl_listener *listener, void *data)
596 {
597    E_Xdg_Toplevel_V6 *toplevel;
598
599    toplevel = wl_container_of(listener, toplevel, request_fullscreen);
600    if (toplevel->ds_toplevel->requested.fullscreen)
601      _e_xdg_toplevel_v6_fullscreen_set(toplevel);
602    else
603      _e_xdg_toplevel_v6_fullscreen_unset(toplevel);
604 }
605
606 static void
607 _e_xdg_toplevel_v6_cb_request_minimize(struct wl_listener *listener, void *data)
608 {
609    E_Xdg_Toplevel_V6 *toplevel;
610
611    toplevel = wl_container_of(listener, toplevel, request_minimize);
612    _e_xdg_toplevel_v6_minimize_set(toplevel);
613 }
614
615 static void
616 _e_xdg_toplevel_v6_cb_xdg_surface_configure(struct wl_listener *listener, void *data)
617 {
618    E_Xdg_Toplevel_V6 *toplevel;
619
620    toplevel = wl_container_of(listener, toplevel, configure);
621    _e_xdg_toplevel_v6_oldest_configure_remove(toplevel);
622 }
623
624 static void
625 _e_xdg_toplevel_v6_cb_ping_timeout(struct wl_listener *listener, void *data)
626 {
627    // This is intentionally left blank.
628 }
629
630 static void
631 _e_xdg_toplevel_v6_cb_surface_commit(struct wl_listener *listener, void *data)
632 {
633    E_Xdg_Toplevel_V6 *toplevel;
634
635    toplevel = wl_container_of(listener, toplevel, surface_commit);
636    _e_xdg_toplevel_v6_window_geometry_update(toplevel);
637    _e_xdg_toplevel_v6_min_max_size_update(toplevel);
638 }
639
640 static void
641 _e_xdg_toplevel_v6_listener_init(E_Xdg_Toplevel_V6 *toplevel)
642 {
643    struct ds_xdg_toplevel_v6 *ds_toplevel = toplevel->ds_toplevel;
644    struct ds_xdg_surface_v6 *ds_xdg_surface = toplevel->ds_toplevel->base;
645    struct ds_surface *ds_surface = ds_xdg_surface->ds_surface;
646
647    toplevel->set_parent.notify = _e_xdg_toplevel_v6_cb_set_parent;
648    ds_xdg_toplevel_v6_add_set_parent_listener(ds_toplevel, &toplevel->set_parent);
649    toplevel->set_title.notify = _e_xdg_toplevel_v6_cb_set_title;
650    ds_xdg_toplevel_v6_add_set_title_listener(ds_toplevel, &toplevel->set_title);
651    toplevel->set_app_id.notify = _e_xdg_toplevel_v6_cb_set_app_id;
652    ds_xdg_toplevel_v6_add_set_app_id_listener(ds_toplevel, &toplevel->set_app_id);
653    toplevel->request_move.notify = _e_xdg_toplevel_v6_cb_request_move;
654    ds_xdg_toplevel_v6_add_request_move_listener(ds_toplevel, &toplevel->request_move);
655    toplevel->request_resize.notify = _e_xdg_toplevel_v6_cb_request_resize;
656    ds_xdg_toplevel_v6_add_request_resize_listener(ds_toplevel, &toplevel->request_resize);
657    toplevel->request_maximize.notify = _e_xdg_toplevel_v6_cb_request_maximize;
658    ds_xdg_toplevel_v6_add_request_maximize_listener(ds_toplevel, &toplevel->request_maximize);
659    toplevel->request_fullscreen.notify = _e_xdg_toplevel_v6_cb_request_fullscreen;
660    ds_xdg_toplevel_v6_add_request_fullscreen_listener(ds_toplevel, &toplevel->request_fullscreen);
661    toplevel->request_minimize.notify = _e_xdg_toplevel_v6_cb_request_minimize;
662    ds_xdg_toplevel_v6_add_request_minimize_listener(ds_toplevel, &toplevel->request_minimize);
663    toplevel->destroy.notify = _e_xdg_toplevel_v6_cb_xdg_surface_destroy;
664    ds_xdg_surface_v6_add_destroy_listener(ds_xdg_surface, &toplevel->destroy);
665    toplevel->configure.notify = _e_xdg_toplevel_v6_cb_xdg_surface_configure;
666    ds_xdg_surface_v6_add_configure_listener(ds_xdg_surface, &toplevel->configure);
667    toplevel->ping_timeout.notify = _e_xdg_toplevel_v6_cb_ping_timeout;
668    ds_xdg_surface_v6_add_ping_timeout_listener(ds_xdg_surface, &toplevel->ping_timeout);
669    toplevel->surface_commit.notify = _e_xdg_toplevel_v6_cb_surface_commit;
670    ds_surface_add_commit_listener(ds_surface, &toplevel->surface_commit);
671 }
672
673 static void
674 _e_xdg_toplevel_v6_listener_finish(E_Xdg_Toplevel_V6 *toplevel)
675 {
676    wl_list_remove(&toplevel->set_parent.link);
677    wl_list_remove(&toplevel->set_title.link);
678    wl_list_remove(&toplevel->set_app_id.link);
679    wl_list_remove(&toplevel->request_move.link);
680    wl_list_remove(&toplevel->request_resize.link);
681    wl_list_remove(&toplevel->request_maximize.link);
682    wl_list_remove(&toplevel->request_fullscreen.link);
683    wl_list_remove(&toplevel->request_minimize.link);
684    wl_list_remove(&toplevel->destroy.link);
685    wl_list_remove(&toplevel->configure.link);
686    wl_list_remove(&toplevel->ping_timeout.link);
687    wl_list_remove(&toplevel->surface_commit.link);
688 }
689
690 static void
691 _e_xdg_toplevel_v6_init(E_Xdg_Toplevel_V6 *toplevel)
692 {
693    struct ds_xdg_toplevel_v6 *ds_toplevel = toplevel->ds_toplevel;
694
695    _e_xdg_toplevel_v6_title_update(toplevel);
696    _e_xdg_toplevel_v6_app_id_update(toplevel);
697
698    if (ds_toplevel->requested.maximized)
699      _e_xdg_toplevel_v6_maximize_set(toplevel);
700
701    if (ds_toplevel->requested.fullscreen)
702      _e_xdg_toplevel_v6_fullscreen_set(toplevel);
703
704    _e_xdg_toplevel_v6_role_init(toplevel);
705 }
706
707 static void
708 _e_xdg_toplevel_v6_finish(E_Xdg_Toplevel_V6 *toplevel)
709 {
710    E_Client *ec = toplevel->ec;
711    E_Comp_Wl_Client_Data *cdata;
712
713    cdata = e_client_cdata_get(ec);
714    if (cdata)
715      {
716         cdata->sh_v6.res_role = toplevel->ds_toplevel->resource;
717         cdata->sh_v6.role = E_COMP_WL_SH_SURF_ROLE_NONE;
718      }
719
720    e_shell_e_client_destroy(ec);
721 }
722
723 static void
724 _e_xdg_toplevel_v6_add(struct ds_xdg_surface_v6 *ds_xdg_surface)
725 {
726    E_Xdg_Toplevel_V6 *toplevel;
727
728    toplevel = E_NEW(E_Xdg_Toplevel_V6, 1);
729    if (!toplevel)
730      {
731         ERR("Could not create E_Xdg_Toplevel_V6", NULL);
732         return;
733      }
734
735    toplevel->ds_toplevel = ds_xdg_surface->toplevel;
736    toplevel->ec = e_client_from_surface_resource(
737       ds_surface_get_wl_resource(ds_xdg_surface->ds_surface));
738
739    _e_xdg_toplevel_v6_listener_init(toplevel);
740    _e_xdg_toplevel_v6_init(toplevel);
741
742    LOG("Created E_Xdg_Toplevel_V6(%p)", toplevel->ec, toplevel);
743 }
744
745 static void
746 _e_xdg_toplevel_v6_cb_xdg_surface_destroy(struct wl_listener *listener, void *data)
747 {
748    E_Xdg_Toplevel_V6 *toplevel;
749
750    toplevel = wl_container_of(listener, toplevel, destroy);
751
752    LOG("Destroy E_Xdg_Toplevel_V6(%p)", toplevel->ec, toplevel);
753
754    _e_xdg_toplevel_v6_listener_finish(toplevel);
755    _e_xdg_toplevel_v6_finish(toplevel);
756    free(toplevel);
757 }