summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Blumenkrantz <zmike@osg.samsung.com>2016-05-05 10:45:59 -0400
committerMike Blumenkrantz <zmike@osg.samsung.com>2016-05-05 10:49:31 -0400
commit9d5caf00b624b149b01fc689f3e16c2ff3469335 (patch)
tree8194b3b2e5c53736959be8e53caed0234af41c1a /src
parent0231800b60c7bab5162db8c04b815b884ecd36ab (diff)
wayland: implement session recovery
add support for reconnecting wayland applications if the compositor dies disconnect -> destroy gl ctx + image textures -> block rendering -> reconnect -> create gl ctx -> create image textures -> unblock rendering -> sprinkle special seasoning on top -> just like ma used to make #SamsungFeatures @feature
Diffstat (limited to 'src')
-rw-r--r--src/Makefile_Ecore_Wl2.am4
-rw-r--r--src/lib/ecore_wl2/Ecore_Wl2.h9
-rw-r--r--src/lib/ecore_wl2/ecore_wl2.c8
-rw-r--r--src/lib/ecore_wl2/ecore_wl2_display.c254
-rw-r--r--src/lib/ecore_wl2/ecore_wl2_private.h8
-rw-r--r--src/lib/ecore_wl2/ecore_wl2_window.c59
-rw-r--r--src/lib/ecore_wl2/session-recovery-client-protocol.h68
-rw-r--r--src/lib/ecore_wl2/session-recovery.c (renamed from src/lib/ecore_wl2/session-recovery-protocol.c)15
-rw-r--r--src/lib/ecore_wl2/session-recovery.h97
-rw-r--r--src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c36
-rw-r--r--src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_egl.c43
-rw-r--r--src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_private.h6
-rw-r--r--src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_shm.c21
13 files changed, 390 insertions, 238 deletions
diff --git a/src/Makefile_Ecore_Wl2.am b/src/Makefile_Ecore_Wl2.am
index 8a55a2d7d0..9bf375e5a0 100644
--- a/src/Makefile_Ecore_Wl2.am
+++ b/src/Makefile_Ecore_Wl2.am
@@ -8,8 +8,8 @@ installed_ecorewl2mainheadersdir = $(includedir)/ecore-wl2-@VMAJ@
8dist_installed_ecorewl2mainheaders_DATA = lib/ecore_wl2/Ecore_Wl2.h 8dist_installed_ecorewl2mainheaders_DATA = lib/ecore_wl2/Ecore_Wl2.h
9 9
10lib_ecore_wl2_libecore_wl2_la_SOURCES = \ 10lib_ecore_wl2_libecore_wl2_la_SOURCES = \
11lib/ecore_wl2/session-recovery-client-protocol.h \ 11lib/ecore_wl2/session-recovery.h \
12lib/ecore_wl2/session-recovery-protocol.c \ 12lib/ecore_wl2/session-recovery.c \
13lib/ecore_wl2/subsurface-client-protocol.h \ 13lib/ecore_wl2/subsurface-client-protocol.h \
14lib/ecore_wl2/subsurface-protocol.c \ 14lib/ecore_wl2/subsurface-protocol.c \
15lib/ecore_wl2/xdg-shell-client-protocol.h \ 15lib/ecore_wl2/xdg-shell-client-protocol.h \
diff --git a/src/lib/ecore_wl2/Ecore_Wl2.h b/src/lib/ecore_wl2/Ecore_Wl2.h
index 02099f73c9..fef28a6604 100644
--- a/src/lib/ecore_wl2/Ecore_Wl2.h
+++ b/src/lib/ecore_wl2/Ecore_Wl2.h
@@ -53,6 +53,13 @@ typedef enum
53 ECORE_WL2_DRAG_ACTION_ASK = 4, 53 ECORE_WL2_DRAG_ACTION_ASK = 4,
54} Ecore_Wl2_Drag_Action; 54} Ecore_Wl2_Drag_Action;
55 55
56struct _Ecore_Wl2_Event_Connection
57{
58 Ecore_Wl2_Display *display;
59};
60typedef struct _Ecore_Wl2_Event_Connection Ecore_Wl2_Event_Connect;
61typedef struct _Ecore_Wl2_Event_Connection Ecore_Wl2_Event_Disconnect;
62
56typedef struct _Ecore_Wl2_Global 63typedef struct _Ecore_Wl2_Global
57{ 64{
58 Eina_Stringshare *interface; 65 Eina_Stringshare *interface;
@@ -175,6 +182,8 @@ typedef enum _Ecore_Wl2_Window_Type
175typedef void (*Ecore_Wl2_Bind_Cb)(struct wl_client *client, void *data, uint32_t version, uint32_t id); 182typedef void (*Ecore_Wl2_Bind_Cb)(struct wl_client *client, void *data, uint32_t version, uint32_t id);
176typedef void (*Ecore_Wl2_Unbind_Cb)(struct wl_resource *resource); 183typedef void (*Ecore_Wl2_Unbind_Cb)(struct wl_resource *resource);
177 184
185EAPI extern int ECORE_WL2_EVENT_DISCONNECT; /** @since 1.18 */
186EAPI extern int ECORE_WL2_EVENT_CONNECT; /** @since 1.18 */
178EAPI extern int ECORE_WL2_EVENT_GLOBAL_ADDED; /** @since 1.17 */ 187EAPI extern int ECORE_WL2_EVENT_GLOBAL_ADDED; /** @since 1.17 */
179EAPI extern int ECORE_WL2_EVENT_GLOBAL_REMOVED; /** @since 1.17 */ 188EAPI extern int ECORE_WL2_EVENT_GLOBAL_REMOVED; /** @since 1.17 */
180EAPI extern int ECORE_WL2_EVENT_FOCUS_IN; /** @since 1.17 */ 189EAPI extern int ECORE_WL2_EVENT_FOCUS_IN; /** @since 1.17 */
diff --git a/src/lib/ecore_wl2/ecore_wl2.c b/src/lib/ecore_wl2/ecore_wl2.c
index f1fded6193..e9cf9f6131 100644
--- a/src/lib/ecore_wl2/ecore_wl2.c
+++ b/src/lib/ecore_wl2/ecore_wl2.c
@@ -8,9 +8,12 @@
8static int _ecore_wl2_init_count = 0; 8static int _ecore_wl2_init_count = 0;
9 9
10/* external variables */ 10/* external variables */
11Eina_Bool no_session_recovery;
11int _ecore_wl2_log_dom = -1; 12int _ecore_wl2_log_dom = -1;
12 13
13/* public API variables */ 14/* public API variables */
15EAPI int ECORE_WL2_EVENT_CONNECT = 0;
16EAPI int ECORE_WL2_EVENT_DISCONNECT = 0;
14EAPI int ECORE_WL2_EVENT_GLOBAL_ADDED = 0; 17EAPI int ECORE_WL2_EVENT_GLOBAL_ADDED = 0;
15EAPI int ECORE_WL2_EVENT_GLOBAL_REMOVED = 0; 18EAPI int ECORE_WL2_EVENT_GLOBAL_REMOVED = 0;
16EAPI int ECORE_WL2_EVENT_FOCUS_IN = 0; 19EAPI int ECORE_WL2_EVENT_FOCUS_IN = 0;
@@ -67,6 +70,8 @@ ecore_wl2_init(void)
67 /* handle creating new Ecore_Wl2 event types */ 70 /* handle creating new Ecore_Wl2 event types */
68 if (!ECORE_WL2_EVENT_GLOBAL_ADDED) 71 if (!ECORE_WL2_EVENT_GLOBAL_ADDED)
69 { 72 {
73 ECORE_WL2_EVENT_CONNECT = ecore_event_type_new();
74 ECORE_WL2_EVENT_DISCONNECT = ecore_event_type_new();
70 ECORE_WL2_EVENT_GLOBAL_ADDED = ecore_event_type_new(); 75 ECORE_WL2_EVENT_GLOBAL_ADDED = ecore_event_type_new();
71 ECORE_WL2_EVENT_GLOBAL_REMOVED = ecore_event_type_new(); 76 ECORE_WL2_EVENT_GLOBAL_REMOVED = ecore_event_type_new();
72 ECORE_WL2_EVENT_FOCUS_IN = ecore_event_type_new(); 77 ECORE_WL2_EVENT_FOCUS_IN = ecore_event_type_new();
@@ -87,6 +92,7 @@ ecore_wl2_init(void)
87 _ecore_wl2_event_window_www = ecore_event_type_new(); 92 _ecore_wl2_event_window_www = ecore_event_type_new();
88 _ecore_wl2_event_window_www_drag = ecore_event_type_new(); 93 _ecore_wl2_event_window_www_drag = ecore_event_type_new();
89 } 94 }
95 no_session_recovery = !!getenv("EFL_NO_WAYLAND_SESSION_RECOVERY");
90 96
91 return _ecore_wl2_init_count; 97 return _ecore_wl2_init_count;
92 98
@@ -114,6 +120,8 @@ ecore_wl2_shutdown(void)
114 if (--_ecore_wl2_init_count != 0) return _ecore_wl2_init_count; 120 if (--_ecore_wl2_init_count != 0) return _ecore_wl2_init_count;
115 121
116 /* reset events */ 122 /* reset events */
123 ECORE_WL2_EVENT_CONNECT = 0;
124 ECORE_WL2_EVENT_DISCONNECT = 0;
117 ECORE_WL2_EVENT_GLOBAL_ADDED = 0; 125 ECORE_WL2_EVENT_GLOBAL_ADDED = 0;
118 ECORE_WL2_EVENT_GLOBAL_REMOVED = 0; 126 ECORE_WL2_EVENT_GLOBAL_REMOVED = 0;
119 ECORE_WL2_EVENT_FOCUS_IN = 0; 127 ECORE_WL2_EVENT_FOCUS_IN = 0;
diff --git a/src/lib/ecore_wl2/ecore_wl2_display.c b/src/lib/ecore_wl2/ecore_wl2_display.c
index ccc4a8bcbb..a993ea119b 100644
--- a/src/lib/ecore_wl2/ecore_wl2_display.c
+++ b/src/lib/ecore_wl2/ecore_wl2_display.c
@@ -8,10 +8,24 @@
8#include <sys/param.h> 8#include <sys/param.h>
9#include "linux-dmabuf-unstable-v1-client-protocol.h" 9#include "linux-dmabuf-unstable-v1-client-protocol.h"
10 10
11static Eina_Bool _fatal_error = EINA_FALSE;
12static Eina_Hash *_server_displays = NULL; 11static Eina_Hash *_server_displays = NULL;
13static Eina_Hash *_client_displays = NULL; 12static Eina_Hash *_client_displays = NULL;
14 13
14static Eina_Bool _cb_connect_idle(void *data);
15static Eina_Bool _cb_connect_data(void *data, Ecore_Fd_Handler *hdl);
16static Eina_Bool _ecore_wl2_display_connect(Ecore_Wl2_Display *ewd, Eina_Bool sync);
17
18static void
19_ecore_wl2_display_event(Ecore_Wl2_Display *ewd, int event)
20{
21 Ecore_Wl2_Event_Connect *ev;
22
23 ev = calloc(1, sizeof(Ecore_Wl2_Event_Connect));
24 EINA_SAFETY_ON_NULL_RETURN(ev);
25 ev->display = ewd;
26 ecore_event_add(event, ev, NULL, NULL);
27}
28
15static void 29static void
16_ecore_wl2_display_signal_exit(void) 30_ecore_wl2_display_signal_exit(void)
17{ 31{
@@ -147,7 +161,7 @@ _cb_global_add(void *data, struct wl_registry *registry, unsigned int id, const
147 _ecore_wl2_window_www_surface_init(window); 161 _ecore_wl2_window_www_surface_init(window);
148 } 162 }
149 else if ((!strcmp(interface, "zwp_e_session_recovery")) && 163 else if ((!strcmp(interface, "zwp_e_session_recovery")) &&
150 (getenv("EFL_WAYLAND_SESSION_RECOVERY"))) 164 (!no_session_recovery))
151 { 165 {
152 ewd->wl.session_recovery = 166 ewd->wl.session_recovery =
153 wl_registry_bind(registry, id, 167 wl_registry_bind(registry, id,
@@ -210,25 +224,11 @@ static const struct wl_registry_listener _registry_listener =
210}; 224};
211 225
212static Eina_Bool 226static Eina_Bool
213_cb_create_data(void *data, Ecore_Fd_Handler *hdl) 227_cb_create_data(void *data, Ecore_Fd_Handler *hdl EINA_UNUSED)
214{ 228{
215 Ecore_Wl2_Display *ewd; 229 Ecore_Wl2_Display *ewd = data;
216 struct wl_event_loop *loop; 230 struct wl_event_loop *loop;
217 231
218 ewd = data;
219
220 if (_fatal_error) return ECORE_CALLBACK_CANCEL;
221
222 if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_ERROR))
223 {
224 ERR("Received Fatal Error on Wayland Display");
225
226 _fatal_error = EINA_TRUE;
227 _ecore_wl2_display_signal_exit();
228
229 return ECORE_CALLBACK_CANCEL;
230 }
231
232 loop = wl_display_get_event_loop(ewd->wl.display); 232 loop = wl_display_get_event_loop(ewd->wl.display);
233 wl_event_loop_dispatch(loop, 0); 233 wl_event_loop_dispatch(loop, 0);
234 234
@@ -240,44 +240,83 @@ _cb_create_data(void *data, Ecore_Fd_Handler *hdl)
240static void 240static void
241_cb_create_prepare(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED) 241_cb_create_prepare(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED)
242{ 242{
243 Ecore_Wl2_Display *ewd; 243 Ecore_Wl2_Display *ewd = data;
244 244
245 ewd = data;
246 wl_display_flush_clients(ewd->wl.display); 245 wl_display_flush_clients(ewd->wl.display);
247} 246}
248 247
249static Eina_Bool 248static Eina_Bool
250_cb_connect_data(void *data, Ecore_Fd_Handler *hdl) 249_recovery_timer(Ecore_Wl2_Display *ewd)
251{ 250{
252 Ecore_Wl2_Display *ewd; 251 if (!_ecore_wl2_display_connect(ewd, 1))
253 int ret = 0; 252 return EINA_TRUE;
254 253
255 ewd = data; 254 ewd->recovery_timer = NULL;
255 return EINA_FALSE;
256}
256 257
257 if (_fatal_error) return ECORE_CALLBACK_CANCEL; 258static void
259_recovery_timer_add(Ecore_Wl2_Display *ewd)
260{
261 Eina_Inlist *tmp;
262 Ecore_Wl2_Output *output;
263 Ecore_Wl2_Input *input;
264 Ecore_Wl2_Window *window;
258 265
259 if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_ERROR)) 266 eina_hash_free_buckets(ewd->globals);
260 { 267 ecore_idle_enterer_del(ewd->idle_enterer);
261 ERR("Received Fatal Error on Wayland Display"); 268 ewd->idle_enterer = NULL;
262 269
263 _fatal_error = EINA_TRUE; 270 ecore_main_fd_handler_del(ewd->fd_hdl);
264 _ecore_wl2_display_signal_exit(); 271 ewd->fd_hdl = NULL;
265 272
266 return ECORE_CALLBACK_CANCEL; 273 if (ewd->wl.session_recovery)
267 } 274 zwp_e_session_recovery_destroy(ewd->wl.session_recovery);
275 if (ewd->wl.www) www_destroy(ewd->wl.www);
276 if (ewd->wl.xdg_shell) xdg_shell_destroy(ewd->wl.xdg_shell);
277 if (ewd->wl.wl_shell) wl_shell_destroy(ewd->wl.wl_shell);
278 if (ewd->wl.shm) wl_shm_destroy(ewd->wl.shm);
279 if (ewd->wl.data_device_manager)
280 wl_data_device_manager_destroy(ewd->wl.data_device_manager);
281 if (ewd->wl.compositor) wl_compositor_destroy(ewd->wl.compositor);
282 if (ewd->wl.subcompositor) wl_subcompositor_destroy(ewd->wl.subcompositor);
283
284 if (ewd->wl.registry) wl_registry_destroy(ewd->wl.registry);
285
286 memset(&ewd->wl, 0, sizeof(ewd->wl));
287 EINA_INLIST_FOREACH_SAFE(ewd->inputs, tmp, input)
288 _ecore_wl2_input_del(input);
289
290 EINA_INLIST_FOREACH_SAFE(ewd->outputs, tmp, output)
291 _ecore_wl2_output_del(output);
292
293 EINA_INLIST_FOREACH_SAFE(ewd->windows, tmp, window)
294 ecore_wl2_window_hide(window);
295
296 ewd->recovery_timer = ecore_timer_add(0.5, (Ecore_Task_Cb)_recovery_timer, ewd);
297 _ecore_wl2_display_event(ewd, ECORE_WL2_EVENT_DISCONNECT);
298}
299
300static void
301_begin_recovery_maybe(Ecore_Wl2_Display *ewd)
302{
303 ERR("Wayland Socket Error: %s", strerror(errno));
304 if (ewd->wl.session_recovery)// && (errno == EPIPE))
305 _recovery_timer_add(ewd);
306 else
307 _ecore_wl2_display_signal_exit();
308}
309
310static Eina_Bool
311_cb_connect_data(void *data, Ecore_Fd_Handler *hdl)
312{
313 Ecore_Wl2_Display *ewd = data;
314 int ret = 0;
268 315
269 if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_READ)) 316 if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_READ))
270 { 317 {
271 ret = wl_display_dispatch(ewd->wl.display); 318 ret = wl_display_dispatch(ewd->wl.display);
272 if ((ret < 0) && (errno != EAGAIN)) 319 if ((ret < 0) && (errno != EAGAIN)) goto err;
273 {
274 ERR("Received Fatal Error on Wayland Display");
275
276 _fatal_error = EINA_TRUE;
277 _ecore_wl2_display_signal_exit();
278
279 return ECORE_CALLBACK_CANCEL;
280 }
281 } 320 }
282 321
283 if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_WRITE)) 322 if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_WRITE))
@@ -286,18 +325,16 @@ _cb_connect_data(void *data, Ecore_Fd_Handler *hdl)
286 if (ret == 0) 325 if (ret == 0)
287 ecore_main_fd_handler_active_set(hdl, ECORE_FD_READ); 326 ecore_main_fd_handler_active_set(hdl, ECORE_FD_READ);
288 327
289 if ((ret < 0) && (errno != EAGAIN)) 328 if ((ret < 0) && (errno != EAGAIN)) goto err;
290 {
291 ERR("Received Fatal Error on Wayland Display");
292
293 _fatal_error = EINA_TRUE;
294 _ecore_wl2_display_signal_exit();
295
296 return ECORE_CALLBACK_CANCEL;
297 }
298 } 329 }
299 330
300 return ECORE_CALLBACK_RENEW; 331 return ECORE_CALLBACK_RENEW;
332
333err:
334 ewd->fd_hdl = NULL;
335 _begin_recovery_maybe(ewd);
336
337 return ECORE_CALLBACK_CANCEL;
301} 338}
302 339
303static void 340static void
@@ -315,14 +352,9 @@ _cb_globals_hash_del(void *data)
315static Eina_Bool 352static Eina_Bool
316_cb_connect_idle(void *data) 353_cb_connect_idle(void *data)
317{ 354{
318 Ecore_Wl2_Display *ewd; 355 Ecore_Wl2_Display *ewd = data;
319 int ret = 0; 356 int ret = 0;
320 357
321 ewd = data;
322 if (!ewd) return ECORE_CALLBACK_RENEW;
323
324 if (_fatal_error) return ECORE_CALLBACK_CANCEL;
325
326 ret = wl_display_get_error(ewd->wl.display); 358 ret = wl_display_get_error(ewd->wl.display);
327 if (ret < 0) goto err; 359 if (ret < 0) goto err;
328 360
@@ -339,10 +371,8 @@ _cb_connect_idle(void *data)
339err: 371err:
340 if ((ret < 0) && (errno != EAGAIN)) 372 if ((ret < 0) && (errno != EAGAIN))
341 { 373 {
342 ERR("Wayland Socket Error: %s", strerror(errno)); 374 ewd->idle_enterer = NULL;
343 375 _begin_recovery_maybe(ewd);
344 _fatal_error = EINA_TRUE;
345 _ecore_wl2_display_signal_exit();
346 376
347 return ECORE_CALLBACK_CANCEL; 377 return ECORE_CALLBACK_CANCEL;
348 } 378 }
@@ -373,6 +403,56 @@ static const struct wl_callback_listener _sync_listener =
373 _cb_sync_done 403 _cb_sync_done
374}; 404};
375 405
406static Eina_Bool
407_ecore_wl2_display_connect(Ecore_Wl2_Display *ewd, Eina_Bool sync)
408{
409 struct wl_callback *cb;
410 /* try to connect to wayland display with this name */
411 ewd->wl.display = wl_display_connect(ewd->name);
412 if (!ewd->wl.display)
413 {
414 ERR("Could not connect to display %s", ewd->name);
415 return EINA_FALSE;
416 }
417
418 ewd->wl.registry = wl_display_get_registry(ewd->wl.display);
419 wl_registry_add_listener(ewd->wl.registry, &_registry_listener, ewd);
420
421 cb = wl_display_sync(ewd->wl.display);
422 wl_callback_add_listener(cb, &_sync_listener, ewd);
423
424 if (sync)
425 {
426 /* NB: If we are connecting (as a client), then we will need to setup
427 * a callback for display_sync and wait for it to complete. There is no
428 * other option here as we need the compositor, shell, etc, to be setup
429 * before we can allow a user to make use of the API functions */
430 while (!ewd->sync_done)
431 {
432 int ret;
433
434 ret = wl_display_dispatch(ewd->wl.display);
435 if ((ret < 0) && (errno != EAGAIN))
436 {
437 ERR("Received Fatal Error on Wayland Display");
438
439 wl_registry_destroy(ewd->wl.registry);
440 return EINA_FALSE;
441 }
442 }
443 }
444
445 ewd->fd_hdl =
446 ecore_main_fd_handler_add(wl_display_get_fd(ewd->wl.display),
447 ECORE_FD_READ | ECORE_FD_WRITE | ECORE_FD_ERROR,
448 _cb_connect_data, ewd, NULL, NULL);
449
450 ewd->idle_enterer = ecore_idle_enterer_add(_cb_connect_idle, ewd);
451
452 _ecore_wl2_display_event(ewd, ECORE_WL2_EVENT_CONNECT);
453 return EINA_TRUE;
454}
455
376static void 456static void
377_ecore_wl2_display_cleanup(Ecore_Wl2_Display *ewd) 457_ecore_wl2_display_cleanup(Ecore_Wl2_Display *ewd)
378{ 458{
@@ -545,8 +625,6 @@ EAPI Ecore_Wl2_Display *
545ecore_wl2_display_connect(const char *name) 625ecore_wl2_display_connect(const char *name)
546{ 626{
547 Ecore_Wl2_Display *ewd; 627 Ecore_Wl2_Display *ewd;
548 Eina_Bool sync = EINA_TRUE;
549 struct wl_callback *cb;
550 const char *n; 628 const char *n;
551 Eina_Bool hash_create = !_client_displays; 629 Eina_Bool hash_create = !_client_displays;
552 630
@@ -594,56 +672,13 @@ ecore_wl2_display_connect(const char *name)
594 672
595 ewd->globals = eina_hash_int32_new(_cb_globals_hash_del); 673 ewd->globals = eina_hash_int32_new(_cb_globals_hash_del);
596 674
597 /* try to connect to wayland display with this name */ 675 /* check server display hash and match on pid. If match, skip sync */
598 ewd->wl.display = wl_display_connect(ewd->name); 676 if (!_ecore_wl2_display_connect(ewd, _ecore_wl2_display_sync_get()))
599 if (!ewd->wl.display) 677 goto connect_err;
600 {
601 ERR("Could not connect to display %s", ewd->name);
602 goto connect_err;
603 }
604
605 ewd->fd_hdl =
606 ecore_main_fd_handler_add(wl_display_get_fd(ewd->wl.display),
607 ECORE_FD_READ | ECORE_FD_WRITE | ECORE_FD_ERROR,
608 _cb_connect_data, ewd, NULL, NULL);
609
610 ewd->idle_enterer = ecore_idle_enterer_add(_cb_connect_idle, ewd);
611
612 ewd->wl.registry = wl_display_get_registry(ewd->wl.display);
613 wl_registry_add_listener(ewd->wl.registry, &_registry_listener, ewd);
614 678
615 ewd->xkb_context = xkb_context_new(0); 679 ewd->xkb_context = xkb_context_new(0);
616 if (!ewd->xkb_context) goto context_err; 680 if (!ewd->xkb_context) goto context_err;
617 681
618 /* check server display hash and match on pid. If match, skip sync */
619 sync = _ecore_wl2_display_sync_get();
620
621 cb = wl_display_sync(ewd->wl.display);
622 wl_callback_add_listener(cb, &_sync_listener, ewd);
623
624 if (sync)
625 {
626 /* NB: If we are connecting (as a client), then we will need to setup
627 * a callback for display_sync and wait for it to complete. There is no
628 * other option here as we need the compositor, shell, etc, to be setup
629 * before we can allow a user to make use of the API functions */
630 while (!ewd->sync_done)
631 {
632 int ret;
633
634 ret = wl_display_dispatch(ewd->wl.display);
635 if ((ret < 0) && (errno != EAGAIN))
636 {
637 ERR("Received Fatal Error on Wayland Display");
638
639 _fatal_error = EINA_TRUE;
640 _ecore_wl2_display_signal_exit();
641
642 goto context_err;
643 }
644 }
645 }
646
647 /* add this new client display to hash */ 682 /* add this new client display to hash */
648 eina_hash_add(_client_displays, ewd->name, ewd); 683 eina_hash_add(_client_displays, ewd->name, ewd);
649 684
@@ -703,6 +738,7 @@ ecore_wl2_display_destroy(Ecore_Wl2_Display *display)
703 738
704 /* remove this client display from hash */ 739 /* remove this client display from hash */
705 eina_hash_del_by_key(_server_displays, display->name); 740 eina_hash_del_by_key(_server_displays, display->name);
741 ecore_timer_del(display->recovery_timer);
706 742
707 free(display->name); 743 free(display->name);
708 free(display); 744 free(display);
diff --git a/src/lib/ecore_wl2/ecore_wl2_private.h b/src/lib/ecore_wl2/ecore_wl2_private.h
index 6913edc662..be69725321 100644
--- a/src/lib/ecore_wl2/ecore_wl2_private.h
+++ b/src/lib/ecore_wl2/ecore_wl2_private.h
@@ -2,7 +2,6 @@
2# define _ECORE_WL2_PRIVATE_H 2# define _ECORE_WL2_PRIVATE_H
3 3
4# include <unistd.h> 4# include <unistd.h>
5# include <uuid/uuid.h>
6# include "Ecore_Wl2.h" 5# include "Ecore_Wl2.h"
7# include "Ecore_Input.h" 6# include "Ecore_Input.h"
8# include "www-protocol.h" 7# include "www-protocol.h"
@@ -16,9 +15,10 @@
16# include "xdg-shell-client-protocol.h" 15# include "xdg-shell-client-protocol.h"
17# define XDG_VERSION 5 16# define XDG_VERSION 5
18 17
19# include "session-recovery-client-protocol.h" 18# include "session-recovery.h"
20 19
21extern int _ecore_wl2_log_dom; 20extern int _ecore_wl2_log_dom;
21extern Eina_Bool no_session_recovery;
22 22
23# ifdef EAPI 23# ifdef EAPI
24# undef EAPI 24# undef EAPI
@@ -95,6 +95,7 @@ struct _Ecore_Wl2_Display
95 Ecore_Fd_Handler *fd_hdl; 95 Ecore_Fd_Handler *fd_hdl;
96 96
97 Eina_Hash *globals; 97 Eina_Hash *globals;
98 Ecore_Timer *recovery_timer;
98 99
99 Eina_Inlist *windows; 100 Eina_Inlist *windows;
100 Eina_Inlist *outputs; 101 Eina_Inlist *outputs;
@@ -141,7 +142,7 @@ struct _Ecore_Wl2_Window
141 struct xdg_popup *xdg_popup; 142 struct xdg_popup *xdg_popup;
142 struct www_surface *www_surface; 143 struct www_surface *www_surface;
143 144
144 uuid_t uuid; 145 Eina_Stringshare *uuid;
145 146
146 uint32_t configure_serial; 147 uint32_t configure_serial;
147 void (*configure_ack)(struct xdg_surface *surface, uint32_t serial); 148 void (*configure_ack)(struct xdg_surface *surface, uint32_t serial);
@@ -445,6 +446,7 @@ void _ecore_wl2_dnd_drop(Ecore_Wl2_Input *input);
445void _ecore_wl2_dnd_selection(Ecore_Wl2_Input *input, struct wl_data_offer *offer); 446void _ecore_wl2_dnd_selection(Ecore_Wl2_Input *input, struct wl_data_offer *offer);
446void _ecore_wl2_dnd_del(Ecore_Wl2_Dnd_Source *source); 447void _ecore_wl2_dnd_del(Ecore_Wl2_Dnd_Source *source);
447 448
449void _ecore_wl2_subsurf_unmap(Ecore_Wl2_Subsurface *subsurf);
448void _ecore_wl2_subsurf_free(Ecore_Wl2_Subsurface *subsurf); 450void _ecore_wl2_subsurf_free(Ecore_Wl2_Subsurface *subsurf);
449 451
450void _ecore_wl2_window_shell_surface_init(Ecore_Wl2_Window *window); 452void _ecore_wl2_window_shell_surface_init(Ecore_Wl2_Window *window);
diff --git a/src/lib/ecore_wl2/ecore_wl2_window.c b/src/lib/ecore_wl2/ecore_wl2_window.c
index c3415eaa34..b9fdb5c303 100644
--- a/src/lib/ecore_wl2/ecore_wl2_window.c
+++ b/src/lib/ecore_wl2/ecore_wl2_window.c
@@ -5,22 +5,16 @@
5#include "ecore_wl2_private.h" 5#include "ecore_wl2_private.h"
6 6
7static void 7static void
8_session_recovery_uuid(void *data, struct zwp_e_session_recovery *session_recovery, const char *uuid) 8_session_recovery_create_uuid(void *data, struct zwp_e_session_recovery *session_recovery EINA_UNUSED, struct wl_surface *surface EINA_UNUSED, const char *uuid)
9{ 9{
10 Ecore_Wl2_Window *win; 10 Ecore_Wl2_Window *win = data;
11 char str[37];
12 11
13 win = data; 12 eina_stringshare_replace(&win->uuid, uuid);
14 if (!win) return;
15 if (!session_recovery) return;
16 uuid_parse(uuid, win->uuid);
17 uuid_unparse(win->uuid, str);
18 DBG("UUID event received from compositor with UUID: %s\n", str);
19} 13}
20 14
21static const struct zwp_e_session_recovery_listener _session_listener = 15static const struct zwp_e_session_recovery_listener _session_listener =
22{ 16{
23 _session_recovery_uuid, 17 _session_recovery_create_uuid,
24}; 18};
25 19
26static void 20static void
@@ -300,6 +294,22 @@ _ecore_wl2_window_shell_surface_init(Ecore_Wl2_Window *window)
300 294
301 window->configure_ack = xdg_surface_ack_configure; 295 window->configure_ack = xdg_surface_ack_configure;
302 _ecore_wl2_window_type_set(window); 296 _ecore_wl2_window_type_set(window);
297 if (window->display->wl.session_recovery)
298 {
299 if (window->uuid)
300 {
301 zwp_e_session_recovery_set_uuid(window->display->wl.session_recovery,
302 window->surface, window->uuid);
303 xdg_surface_set_window_geometry(window->xdg_surface,
304 window->geometry.x, window->geometry.y,
305 window->geometry.w, window->geometry.h);
306 ecore_wl2_window_opaque_region_set(window,
307 window->opaque.x, window->opaque.y,
308 window->opaque.w, window->opaque.h);
309 }
310 else
311 zwp_e_session_recovery_get_uuid(window->display->wl.session_recovery, window->surface);
312 }
303 } 313 }
304 else if ((window->display->wl.wl_shell) && (!window->wl_shell_surface)) 314 else if ((window->display->wl.wl_shell) && (!window->wl_shell_surface))
305 { 315 {
@@ -380,19 +390,9 @@ ecore_wl2_window_surface_get(Ecore_Wl2_Window *window)
380 window->surface_id = 390 window->surface_id =
381 wl_proxy_get_id((struct wl_proxy *)window->surface); 391 wl_proxy_get_id((struct wl_proxy *)window->surface);
382 392
383 if ((window->display->wl.session_recovery) && 393 if (window->display->wl.session_recovery)
384 (getenv("EFL_WAYLAND_SESSION_RECOVERY"))) 394 zwp_e_session_recovery_add_listener(window->display->wl.session_recovery,
385 { 395 &_session_listener, window);
386 char uuid[37];
387
388 zwp_e_session_recovery_add_listener(window->display->wl.session_recovery,
389 &_session_listener, window);
390 if (!uuid_is_null(window->uuid))
391 {
392 uuid_unparse(window->uuid, uuid);
393 zwp_e_session_recovery_provide_uuid(window->display->wl.session_recovery, uuid);
394 }
395 }
396 } 396 }
397 397
398 return window->surface; 398 return window->surface;
@@ -432,6 +432,8 @@ ecore_wl2_window_show(Ecore_Wl2_Window *window)
432EAPI void 432EAPI void
433ecore_wl2_window_hide(Ecore_Wl2_Window *window) 433ecore_wl2_window_hide(Ecore_Wl2_Window *window)
434{ 434{
435 Ecore_Wl2_Subsurface *subsurf;
436 Eina_Inlist *tmp;
435 EINA_SAFETY_ON_NULL_RETURN(window); 437 EINA_SAFETY_ON_NULL_RETURN(window);
436 438
437 if (window->xdg_surface) xdg_surface_destroy(window->xdg_surface); 439 if (window->xdg_surface) xdg_surface_destroy(window->xdg_surface);
@@ -448,8 +450,18 @@ ecore_wl2_window_hide(Ecore_Wl2_Window *window)
448 www_surface_destroy(window->www_surface); 450 www_surface_destroy(window->www_surface);
449 window->www_surface = NULL; 451 window->www_surface = NULL;
450 452
453 EINA_INLIST_FOREACH_SAFE(window->subsurfs, tmp, subsurf)
454 _ecore_wl2_subsurf_unmap(subsurf);
455
456 if (window->uuid && window->surface && window->display->wl.session_recovery)
457 zwp_e_session_recovery_destroy_uuid(window->display->wl.session_recovery,
458 window->surface, window->uuid);
459
451 if (window->surface) wl_surface_destroy(window->surface); 460 if (window->surface) wl_surface_destroy(window->surface);
452 window->surface = NULL; 461 window->surface = NULL;
462
463 window->configure_serial = 0;
464 window->configure_ack = NULL;
453} 465}
454 466
455EAPI void 467EAPI void
@@ -482,6 +494,7 @@ ecore_wl2_window_free(Ecore_Wl2_Window *window)
482 _ecore_wl2_subsurf_free(subsurf); 494 _ecore_wl2_subsurf_free(subsurf);
483 495
484 ecore_wl2_window_hide(window); 496 ecore_wl2_window_hide(window);
497 eina_stringshare_replace(&window->uuid, NULL);
485 498
486 if (window->title) eina_stringshare_del(window->title); 499 if (window->title) eina_stringshare_del(window->title);
487 if (window->class) eina_stringshare_del(window->class); 500 if (window->class) eina_stringshare_del(window->class);
diff --git a/src/lib/ecore_wl2/session-recovery-client-protocol.h b/src/lib/ecore_wl2/session-recovery-client-protocol.h
deleted file mode 100644
index 24057471fb..0000000000
--- a/src/lib/ecore_wl2/session-recovery-client-protocol.h
+++ /dev/null
@@ -1,68 +0,0 @@
1#ifndef E_SESSION_RECOVERY_CLIENT_PROTOCOL_H
2#define E_SESSION_RECOVERY_CLIENT_PROTOCOL_H
3
4#ifdef __cplusplus
5extern "C" {
6#endif
7
8#include <stdint.h>
9#include <stddef.h>
10#include "wayland-client.h"
11
12struct wl_client;
13struct wl_resource;
14
15struct zwp_e_session_recovery;
16
17extern const struct wl_interface zwp_e_session_recovery_interface;
18
19struct zwp_e_session_recovery_listener {
20 /**
21 * uuid - (none)
22 * @uuid: (none)
23 */
24 void (*uuid)(void *data,
25 struct zwp_e_session_recovery *zwp_e_session_recovery,
26 const char *uuid);
27};
28
29static inline int
30zwp_e_session_recovery_add_listener(struct zwp_e_session_recovery *zwp_e_session_recovery,
31 const struct zwp_e_session_recovery_listener *listener, void *data)
32{
33 return wl_proxy_add_listener((struct wl_proxy *) zwp_e_session_recovery,
34 (void (**)(void)) listener, data);
35}
36
37#define ZWP_E_SESSION_RECOVERY_PROVIDE_UUID 0
38
39static inline void
40zwp_e_session_recovery_set_user_data(struct zwp_e_session_recovery *zwp_e_session_recovery, void *user_data)
41{
42 wl_proxy_set_user_data((struct wl_proxy *) zwp_e_session_recovery, user_data);
43}
44
45static inline void *
46zwp_e_session_recovery_get_user_data(struct zwp_e_session_recovery *zwp_e_session_recovery)
47{
48 return wl_proxy_get_user_data((struct wl_proxy *) zwp_e_session_recovery);
49}
50
51static inline void
52zwp_e_session_recovery_destroy(struct zwp_e_session_recovery *zwp_e_session_recovery)
53{
54 wl_proxy_destroy((struct wl_proxy *) zwp_e_session_recovery);
55}
56
57static inline void
58zwp_e_session_recovery_provide_uuid(struct zwp_e_session_recovery *zwp_e_session_recovery, const char *uuid)
59{
60 wl_proxy_marshal((struct wl_proxy *) zwp_e_session_recovery,
61 ZWP_E_SESSION_RECOVERY_PROVIDE_UUID, uuid);
62}
63
64#ifdef __cplusplus
65}
66#endif
67
68#endif
diff --git a/src/lib/ecore_wl2/session-recovery-protocol.c b/src/lib/ecore_wl2/session-recovery.c
index 32ddbcbefe..47ecbb9759 100644
--- a/src/lib/ecore_wl2/session-recovery-protocol.c
+++ b/src/lib/ecore_wl2/session-recovery.c
@@ -2,22 +2,31 @@
2#include <stdint.h> 2#include <stdint.h>
3#include "wayland-util.h" 3#include "wayland-util.h"
4 4
5extern const struct wl_interface wl_surface_interface;
5 6
6static const struct wl_interface *types[] = { 7static const struct wl_interface *types[] = {
8 &wl_surface_interface,
9 &wl_surface_interface,
10 NULL,
11 &wl_surface_interface,
12 NULL,
13 &wl_surface_interface,
7 NULL, 14 NULL,
8}; 15};
9 16
10static const struct wl_message zwp_e_session_recovery_requests[] = { 17static const struct wl_message zwp_e_session_recovery_requests[] = {
11 { "provide_uuid", "s", types + 0 }, 18 { "get_uuid", "o", types + 0 },
19 { "set_uuid", "os", types + 1 },
20 { "destroy_uuid", "os", types + 3 },
12}; 21};
13 22
14static const struct wl_message zwp_e_session_recovery_events[] = { 23static const struct wl_message zwp_e_session_recovery_events[] = {
15 { "uuid", "s", types + 0 }, 24 { "create_uuid", "os", types + 5 },
16}; 25};
17 26
18WL_EXPORT const struct wl_interface zwp_e_session_recovery_interface = { 27WL_EXPORT const struct wl_interface zwp_e_session_recovery_interface = {
19 "zwp_e_session_recovery", 1, 28 "zwp_e_session_recovery", 1,
20 1, zwp_e_session_recovery_requests, 29 3, zwp_e_session_recovery_requests,
21 1, zwp_e_session_recovery_events, 30 1, zwp_e_session_recovery_events,
22}; 31};
23 32
diff --git a/src/lib/ecore_wl2/session-recovery.h b/src/lib/ecore_wl2/session-recovery.h
new file mode 100644
index 0000000000..980d37fd81
--- /dev/null
+++ b/src/lib/ecore_wl2/session-recovery.h
@@ -0,0 +1,97 @@
1#ifndef E_SESSION_RECOVERY_CLIENT_PROTOCOL_H
2#define E_SESSION_RECOVERY_CLIENT_PROTOCOL_H
3
4#ifdef __cplusplus
5extern "C" {
6#endif
7
8#include <stdint.h>
9#include <stddef.h>
10#include "wayland-client.h"
11
12struct wl_client;
13struct wl_resource;
14
15struct wl_surface;
16struct zwp_e_session_recovery;
17
18extern const struct wl_interface zwp_e_session_recovery_interface;
19
20struct zwp_e_session_recovery_listener {
21 /**
22 * create_uuid - (none)
23 * @surface: (none)
24 * @uuid: (none)
25 */
26 void (*create_uuid)(void *data,
27 struct zwp_e_session_recovery *zwp_e_session_recovery,
28 struct wl_surface *surface,
29 const char *uuid);
30};
31
32static inline int
33zwp_e_session_recovery_add_listener(struct zwp_e_session_recovery *zwp_e_session_recovery,
34 const struct zwp_e_session_recovery_listener *listener, void *data)
35{
36 return wl_proxy_add_listener((struct wl_proxy *) zwp_e_session_recovery,
37 (void (**)(void)) listener, data);
38}
39
40#define ZWP_E_SESSION_RECOVERY_GET_UUID 0
41#define ZWP_E_SESSION_RECOVERY_SET_UUID 1
42#define ZWP_E_SESSION_RECOVERY_DESTROY_UUID 2
43
44#define ZWP_E_SESSION_RECOVERY_GET_UUID_SINCE_VERSION 1
45#define ZWP_E_SESSION_RECOVERY_SET_UUID_SINCE_VERSION 1
46#define ZWP_E_SESSION_RECOVERY_DESTROY_UUID_SINCE_VERSION 1
47
48static inline void
49zwp_e_session_recovery_set_user_data(struct zwp_e_session_recovery *zwp_e_session_recovery, void *user_data)
50{
51 wl_proxy_set_user_data((struct wl_proxy *) zwp_e_session_recovery, user_data);
52}
53
54static inline void *
55zwp_e_session_recovery_get_user_data(struct zwp_e_session_recovery *zwp_e_session_recovery)
56{
57 return wl_proxy_get_user_data((struct wl_proxy *) zwp_e_session_recovery);
58}
59
60static inline uint32_t
61zwp_e_session_recovery_get_version(struct zwp_e_session_recovery *zwp_e_session_recovery)
62{
63 return wl_proxy_get_version((struct wl_proxy *) zwp_e_session_recovery);
64}
65
66static inline void
67zwp_e_session_recovery_destroy(struct zwp_e_session_recovery *zwp_e_session_recovery)
68{
69 wl_proxy_destroy((struct wl_proxy *) zwp_e_session_recovery);
70}
71
72static inline void
73zwp_e_session_recovery_get_uuid(struct zwp_e_session_recovery *zwp_e_session_recovery, struct wl_surface *surface)
74{
75 wl_proxy_marshal((struct wl_proxy *) zwp_e_session_recovery,
76 ZWP_E_SESSION_RECOVERY_GET_UUID, surface);
77}
78
79static inline void
80zwp_e_session_recovery_set_uuid(struct zwp_e_session_recovery *zwp_e_session_recovery, struct wl_surface *surface, const char *uuid)
81{
82 wl_proxy_marshal((struct wl_proxy *) zwp_e_session_recovery,
83 ZWP_E_SESSION_RECOVERY_SET_UUID, surface, uuid);
84}
85
86static inline void
87zwp_e_session_recovery_destroy_uuid(struct zwp_e_session_recovery *zwp_e_session_recovery, struct wl_surface *surface, const char *uuid)
88{
89 wl_proxy_marshal((struct wl_proxy *) zwp_e_session_recovery,
90 ZWP_E_SESSION_RECOVERY_DESTROY_UUID, surface, uuid);
91}
92
93#ifdef __cplusplus
94}
95#endif
96
97#endif
diff --git a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c
index 67086667e5..10d4ccaf10 100644
--- a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c
+++ b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c
@@ -12,6 +12,8 @@
12static const char *interface_wl_name = "wayland"; 12static const char *interface_wl_name = "wayland";
13static const int interface_wl_version = 1; 13static const int interface_wl_version = 1;
14 14
15Eina_List *ee_list;
16
15/* local structures for the frame smart object */ 17/* local structures for the frame smart object */
16typedef struct _EE_Wl_Smart_Data EE_Wl_Smart_Data; 18typedef struct _EE_Wl_Smart_Data EE_Wl_Smart_Data;
17struct _EE_Wl_Smart_Data 19struct _EE_Wl_Smart_Data
@@ -34,7 +36,7 @@ EVAS_SMART_SUBCLASS_NEW(_smart_frame_type, _ecore_evas_wl_frame,
34 36
35/* local variables */ 37/* local variables */
36static int _ecore_evas_wl_init_count = 0; 38static int _ecore_evas_wl_init_count = 0;
37static Ecore_Event_Handler *_ecore_evas_wl_event_hdls[7]; 39static Ecore_Event_Handler *_ecore_evas_wl_event_hdls[8];
38 40
39static void _ecore_evas_wayland_resize(Ecore_Evas *ee, int location); 41static void _ecore_evas_wayland_resize(Ecore_Evas *ee, int location);
40 42
@@ -162,6 +164,30 @@ _ecore_evas_wl_common_cb_focus_out(void *data EINA_UNUSED, int type EINA_UNUSED,
162} 164}
163 165
164static Eina_Bool 166static Eina_Bool
167_ecore_evas_wl_common_cb_disconnect(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
168{
169 Ecore_Wl2_Event_Disconnect *ev = event;
170 Eina_List *l;
171 Ecore_Evas *ee;
172
173 EINA_LIST_FOREACH(ee_list, l, ee)
174 {
175 Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
176
177 if (wdata->display != ev->display) continue;
178 if (wdata->anim_callback) wl_callback_destroy(wdata->anim_callback);
179 wdata->anim_callback = NULL;
180 wdata->sync_done = EINA_FALSE;
181 wdata->defer_show = EINA_TRUE;
182 wdata->reset_pending = 1;
183 ecore_evas_manual_render_set(ee, 1);
184 if (wdata->display_unset)
185 wdata->display_unset(ee);
186 }
187 return ECORE_CALLBACK_RENEW;
188}
189
190static Eina_Bool
165_ecore_evas_wl_common_cb_window_configure(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) 191_ecore_evas_wl_common_cb_window_configure(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
166{ 192{
167 Ecore_Evas *ee; 193 Ecore_Evas *ee;
@@ -441,6 +467,9 @@ _ecore_evas_wl_common_init(void)
441 _ecore_evas_wl_event_hdls[6] = 467 _ecore_evas_wl_event_hdls[6] =
442 ecore_event_handler_add(_ecore_wl2_event_window_www_drag, 468 ecore_event_handler_add(_ecore_wl2_event_window_www_drag,
443 _ecore_evas_wl_common_cb_www_drag, NULL); 469 _ecore_evas_wl_common_cb_www_drag, NULL);
470 _ecore_evas_wl_event_hdls[7] =
471 ecore_event_handler_add(ECORE_WL2_EVENT_DISCONNECT,
472 _ecore_evas_wl_common_cb_disconnect, NULL);
444 ecore_event_evas_init(); 473 ecore_event_evas_init();
445 474
446 return _ecore_evas_wl_init_count; 475 return _ecore_evas_wl_init_count;
@@ -489,10 +518,15 @@ _ecore_evas_wl_common_free(Ecore_Evas *ee)
489 if (!ee) return; 518 if (!ee) return;
490 519
491 wdata = ee->engine.data; 520 wdata = ee->engine.data;
521 ee_list = eina_list_remove(ee_list, ee);
522
523 eina_list_free(wdata->regen_objs);
492 524
493 if (wdata->anim_callback) wl_callback_destroy(wdata->anim_callback); 525 if (wdata->anim_callback) wl_callback_destroy(wdata->anim_callback);
494 wdata->anim_callback = NULL; 526 wdata->anim_callback = NULL;
495 527
528 ecore_event_handler_del(wdata->sync_handler);
529
496 if (wdata->win) ecore_wl2_window_free(wdata->win); 530 if (wdata->win) ecore_wl2_window_free(wdata->win);
497 wdata->win = NULL; 531 wdata->win = NULL;
498 532
diff --git a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_egl.c b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_egl.c
index 47904d2f24..e3536da949 100644
--- a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_egl.c
+++ b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_egl.c
@@ -30,6 +30,9 @@
30# endif 30# endif
31#endif /* ! _WIN32 */ 31#endif /* ! _WIN32 */
32 32
33extern EAPI Eina_List *_evas_canvas_image_data_unset(Evas *eo_e);
34extern EAPI void _evas_canvas_image_data_regenerate(Eina_List *list);
35
33/* local function prototypes */ 36/* local function prototypes */
34static void _ecore_evas_wl_move_resize(Ecore_Evas *ee, int x, int y, int w, int h); 37static void _ecore_evas_wl_move_resize(Ecore_Evas *ee, int x, int y, int w, int h);
35static void _ecore_evas_wl_show(Ecore_Evas *ee); 38static void _ecore_evas_wl_show(Ecore_Evas *ee);
@@ -117,6 +120,19 @@ static Ecore_Evas_Engine_Func _ecore_wl_engine_func =
117 120
118/* external variables */ 121/* external variables */
119 122
123void
124_ee_egl_display_unset(Ecore_Evas *ee)
125{
126 Evas_Engine_Info_Wayland_Egl *einfo;
127 Ecore_Evas_Engine_Wl_Data *wdata;
128
129 einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas);
130 einfo->info.display = NULL;
131 wdata = ee->engine.data;
132 wdata->regen_objs = _evas_canvas_image_data_unset(ecore_evas_get(ee));
133 evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
134}
135
120static Eina_Bool 136static Eina_Bool
121_ee_cb_sync_done(void *data, int type EINA_UNUSED, void *event EINA_UNUSED) 137_ee_cb_sync_done(void *data, int type EINA_UNUSED, void *event EINA_UNUSED)
122{ 138{
@@ -136,10 +152,19 @@ _ee_cb_sync_done(void *data, int type EINA_UNUSED, void *event EINA_UNUSED)
136 einfo->info.rotation = ee->rotation; 152 einfo->info.rotation = ee->rotation;
137 einfo->info.surface = ecore_wl2_window_surface_get(wdata->win); 153 einfo->info.surface = ecore_wl2_window_surface_get(wdata->win);
138 154
139 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) 155 if (wdata->reset_pending)
140 { 156 {
141 ERR("Failed to set Evas Engine Info for '%s'", ee->driver); 157 ecore_evas_manual_render_set(ee, 0);
142 } 158 }
159 if (evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
160 {
161 if (wdata->reset_pending)
162 _evas_canvas_image_data_regenerate(wdata->regen_objs);
163 wdata->regen_objs = NULL;
164 }
165 else
166 ERR("Failed to set Evas Engine Info for '%s'", ee->driver);
167 wdata->reset_pending = 0;
143 } 168 }
144 else 169 else
145 { 170 {
@@ -164,15 +189,7 @@ _ee_cb_sync_done(void *data, int type EINA_UNUSED, void *event EINA_UNUSED)
164 einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas); 189 einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas);
165 if (einfo) 190 if (einfo)
166 { 191 {
167 struct wl_surface *surf; 192 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w + fw, ee->h + fh);
168
169 surf = ecore_wl2_window_surface_get(wdata->win);
170 if ((!einfo->info.surface) || (einfo->info.surface != surf))
171 {
172 einfo->info.surface = surf;
173 evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
174 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w + fw, ee->h + fh);
175 }
176 einfo->www_avail = !!wdata->win->www_surface; 193 einfo->www_avail = !!wdata->win->www_surface;
177 einfo->just_mapped = EINA_TRUE; 194 einfo->just_mapped = EINA_TRUE;
178 } 195 }
@@ -362,6 +379,7 @@ ecore_evas_wayland_egl_new_internal(const char *disp_name, unsigned int parent,
362 wdata->sync_done = EINA_FALSE; 379 wdata->sync_done = EINA_FALSE;
363 wdata->parent = p; 380 wdata->parent = p;
364 wdata->display = ewd; 381 wdata->display = ewd;
382 wdata->display_unset = _ee_egl_display_unset;
365 wdata->win = ecore_wl2_window_new(ewd, p, x, y, w + fw, h + fh); 383 wdata->win = ecore_wl2_window_new(ewd, p, x, y, w + fw, h + fh);
366 ee->prop.window = ecore_wl2_window_id_get(wdata->win); 384 ee->prop.window = ecore_wl2_window_id_get(wdata->win);
367 385
@@ -432,7 +450,8 @@ ecore_evas_wayland_egl_new_internal(const char *disp_name, unsigned int parent,
432 (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process, 450 (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
433 (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process); 451 (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
434 452
435 ecore_event_handler_add(ECORE_WL2_EVENT_SYNC_DONE, _ee_cb_sync_done, ee); 453 wdata->sync_handler = ecore_event_handler_add(ECORE_WL2_EVENT_SYNC_DONE, _ee_cb_sync_done, ee);
454 ee_list = eina_list_append(ee_list, ee);
436 455
437 return ee; 456 return ee;
438 457
diff --git a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_private.h b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_private.h
index 9942e908a2..49d02c43b4 100644
--- a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_private.h
+++ b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_private.h
@@ -33,7 +33,10 @@ typedef struct _Ecore_Evas_Engine_Wl_Data Ecore_Evas_Engine_Wl_Data;
33struct _Ecore_Evas_Engine_Wl_Data 33struct _Ecore_Evas_Engine_Wl_Data
34{ 34{
35 Ecore_Wl2_Display *display; 35 Ecore_Wl2_Display *display;
36 void (*display_unset)(Ecore_Evas*);
37 Eina_List *regen_objs;
36 Ecore_Wl2_Window *parent, *win; 38 Ecore_Wl2_Window *parent, *win;
39 Ecore_Event_Handler *sync_handler;
37 Evas_Object *frame; 40 Evas_Object *frame;
38 int fx, fy, fw, fh; 41 int fx, fy, fw, fh;
39#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL 42#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL
@@ -48,6 +51,7 @@ struct _Ecore_Evas_Engine_Wl_Data
48 51
49 Eina_Bool sync_done : 1; 52 Eina_Bool sync_done : 1;
50 Eina_Bool defer_show : 1; 53 Eina_Bool defer_show : 1;
54 Eina_Bool reset_pending : 1;
51}; 55};
52 56
53Ecore_Evas_Interface_Wayland *_ecore_evas_wl_interface_new(void); 57Ecore_Evas_Interface_Wayland *_ecore_evas_wl_interface_new(void);
@@ -100,6 +104,8 @@ void _ecore_evas_wl_common_frame_border_size_set(Evas_Object *obj, int fx, int f
100 104
101void _ecore_evas_wl_common_pointer_xy_get(const Ecore_Evas *ee, Evas_Coord *x, Evas_Coord *y); 105void _ecore_evas_wl_common_pointer_xy_get(const Ecore_Evas *ee, Evas_Coord *x, Evas_Coord *y);
102 106
107extern Eina_List *ee_list;
108
103#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM 109#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM
104void _ecore_evas_wayland_shm_resize(Ecore_Evas *ee, int location); 110void _ecore_evas_wayland_shm_resize(Ecore_Evas *ee, int location);
105void _ecore_evas_wayland_shm_resize_edge_set(Ecore_Evas *ee, int edge); 111void _ecore_evas_wayland_shm_resize_edge_set(Ecore_Evas *ee, int edge);
diff --git a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_shm.c b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_shm.c
index d97ce8bff6..ad87d90ee3 100644
--- a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_shm.c
+++ b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_shm.c
@@ -131,6 +131,7 @@ _ee_cb_sync_done(void *data, int type EINA_UNUSED, void *event EINA_UNUSED)
131 131
132 if ((einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas))) 132 if ((einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas)))
133 { 133 {
134 ecore_evas_manual_render_set(ee, 0);
134 einfo->info.wl_disp = ecore_wl2_display_get(wdata->display); 135 einfo->info.wl_disp = ecore_wl2_display_get(wdata->display);
135 einfo->info.wl_dmabuf = ecore_wl2_display_dmabuf_get(wdata->display); 136 einfo->info.wl_dmabuf = ecore_wl2_display_dmabuf_get(wdata->display);
136 einfo->info.wl_shm = ecore_wl2_display_shm_get(wdata->display); 137 einfo->info.wl_shm = ecore_wl2_display_shm_get(wdata->display);
@@ -162,22 +163,7 @@ _ee_cb_sync_done(void *data, int type EINA_UNUSED, void *event EINA_UNUSED)
162 evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh); 163 evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
163 164
164 if (wdata->win) 165 if (wdata->win)
165 { 166 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w + fw, ee->h + fh);
166
167 einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas);
168 if (einfo)
169 {
170 struct wl_surface *surf;
171
172 surf = ecore_wl2_window_surface_get(wdata->win);
173 if ((!einfo->info.wl_surface) || (einfo->info.wl_surface != surf))
174 {
175 einfo->info.wl_surface = surf;
176 evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
177 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w + fw, ee->h + fh);
178 }
179 }
180 }
181 167
182 if (wdata->frame) 168 if (wdata->frame)
183 { 169 {
@@ -373,7 +359,8 @@ ecore_evas_wayland_shm_new_internal(const char *disp_name, unsigned int parent,
373 (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process, 359 (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
374 (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process); 360 (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
375 361
376 ecore_event_handler_add(ECORE_WL2_EVENT_SYNC_DONE, _ee_cb_sync_done, ee); 362 wdata->sync_handler = ecore_event_handler_add(ECORE_WL2_EVENT_SYNC_DONE, _ee_cb_sync_done, ee);
363 ee_list = eina_list_append(ee_list, ee);
377 364
378 return ee; 365 return ee;
379 366