summaryrefslogtreecommitdiff
path: root/src/lib/ecore_wl2
diff options
context:
space:
mode:
authorDerek Foreman <derekf@osg.samsung.com>2017-10-11 15:45:11 -0500
committerDerek Foreman <derekf@osg.samsung.com>2017-10-12 12:24:03 -0500
commit10b63836403ca8879f8f371b1ff60892e5ae3405 (patch)
tree10adc8d367b9ef18795c1857812ab725dea2af0b /src/lib/ecore_wl2
parent9918a2c920dfe2e45ae6cfc776797a1806be49b9 (diff)
ecore_wl2: Synchronize state with surface commits
This is really several inseparable commits mashed together, as doing this a piece at a time would introduce broken intermediate revisions. Double buffer incoming "configure" state from the compositor so it's held back during asynchronous render and processed at frame completion. Hold off on certain requests if their API has been invoked during async render. This should fix a lot of races, cosmetic issues, issues where weston can kill our clients for acking configure (or not) at bad times, etc.
Diffstat (limited to 'src/lib/ecore_wl2')
-rw-r--r--src/lib/ecore_wl2/ecore_wl2_private.h6
-rw-r--r--src/lib/ecore_wl2/ecore_wl2_window.c293
2 files changed, 197 insertions, 102 deletions
diff --git a/src/lib/ecore_wl2/ecore_wl2_private.h b/src/lib/ecore_wl2/ecore_wl2_private.h
index ff78a82579..6c14ce5f2a 100644
--- a/src/lib/ecore_wl2/ecore_wl2_private.h
+++ b/src/lib/ecore_wl2/ecore_wl2_private.h
@@ -204,6 +204,7 @@ struct _Ecore_Wl2_Window
204 204
205 Ecore_Wl2_Window_Configure_State set_config; 205 Ecore_Wl2_Window_Configure_State set_config;
206 Ecore_Wl2_Window_Configure_State req_config; 206 Ecore_Wl2_Window_Configure_State req_config;
207 Ecore_Wl2_Window_Configure_State def_config;
207 208
208 Eina_Bool moving : 1; 209 Eina_Bool moving : 1;
209 Eina_Bool alpha : 1; 210 Eina_Bool alpha : 1;
@@ -222,6 +223,11 @@ struct _Ecore_Wl2_Window
222 Eina_Bool configure : 1; 223 Eina_Bool configure : 1;
223 Eina_Bool min : 1; 224 Eina_Bool min : 1;
224 Eina_Bool max : 1; 225 Eina_Bool max : 1;
226 Eina_Bool geom : 1;
227 Eina_Bool opaque : 1;
228 Eina_Bool input : 1;
229 Eina_Bool fullscreen : 1;
230 Eina_Bool maximized : 1;
225 } pending; 231 } pending;
226 232
227 struct 233 struct
diff --git a/src/lib/ecore_wl2/ecore_wl2_window.c b/src/lib/ecore_wl2/ecore_wl2_window.c
index 4750267b30..b33e4240d0 100644
--- a/src/lib/ecore_wl2/ecore_wl2_window.c
+++ b/src/lib/ecore_wl2/ecore_wl2_window.c
@@ -26,28 +26,6 @@ _ecore_wl2_window_semi_free(Ecore_Wl2_Window *window)
26 window->surface_id = -1; 26 window->surface_id = -1;
27} 27}
28 28
29
30static void
31_ecore_wl2_window_configure_send(Ecore_Wl2_Window *window, int w, int h, unsigned int edges, Eina_Bool fs, Eina_Bool max)
32{
33 Ecore_Wl2_Event_Window_Configure *ev;
34
35 ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Configure));
36 if (!ev) return;
37
38 ev->win = window->id;
39 ev->event_win = window->id;
40 ev->w = w;
41 ev->h = h;
42 ev->edges = edges;
43 if (fs)
44 ev->states |= ECORE_WL2_WINDOW_STATE_FULLSCREEN;
45 if (max)
46 ev->states |= ECORE_WL2_WINDOW_STATE_MAXIMIZED;
47
48 ecore_event_add(ECORE_WL2_EVENT_WINDOW_CONFIGURE, ev, NULL, NULL);
49}
50
51static void 29static void
52_ecore_wl2_window_activate_send(Ecore_Wl2_Window *window) 30_ecore_wl2_window_activate_send(Ecore_Wl2_Window *window)
53{ 31{
@@ -79,6 +57,44 @@ _ecore_wl2_window_deactivate_send(Ecore_Wl2_Window *window)
79} 57}
80 58
81static void 59static void
60_ecore_wl2_window_configure_send(Ecore_Wl2_Window *win)
61{
62 Ecore_Wl2_Event_Window_Configure *ev;
63
64 ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Configure));
65 if (!ev) return;
66
67 ev->win = win->id;
68 ev->event_win = win->id;
69
70 if ((win->set_config.geometry.w == win->def_config.geometry.w) &&
71 (win->set_config.geometry.h == win->def_config.geometry.h))
72 ev->w = ev->h = 0;
73 else if ((!win->def_config.geometry.w) && (!win->def_config.geometry.h) &&
74 (!win->def_config.fullscreen) &&
75 (!win->def_config.maximized) &&
76 ((win->def_config.fullscreen != win->req_config.fullscreen) ||
77 (win->def_config.maximized != win->req_config.maximized)))
78 ev->w = win->saved.w, ev->h = win->saved.h;
79 else
80 ev->w = win->def_config.geometry.w, ev->h = win->def_config.geometry.h;
81
82 ev->edges = !!win->def_config.resizing;
83 if (win->def_config.fullscreen)
84 ev->states |= ECORE_WL2_WINDOW_STATE_FULLSCREEN;
85 if (win->def_config.maximized)
86 ev->states |= ECORE_WL2_WINDOW_STATE_MAXIMIZED;
87
88 win->req_config = win->def_config;
89 ecore_event_add(ECORE_WL2_EVENT_WINDOW_CONFIGURE, ev, NULL, NULL);
90
91 if (win->def_config.focused)
92 _ecore_wl2_window_activate_send(win);
93 else
94 _ecore_wl2_window_deactivate_send(win);
95}
96
97static void
82_configure_complete(Ecore_Wl2_Window *window) 98_configure_complete(Ecore_Wl2_Window *window)
83{ 99{
84 Ecore_Wl2_Event_Window_Configure_Complete *ev; 100 Ecore_Wl2_Event_Window_Configure_Complete *ev;
@@ -99,10 +115,19 @@ _zxdg_surface_cb_configure(void *data, struct zxdg_surface_v6 *zxdg_surface EINA
99 Ecore_Wl2_Window *window; 115 Ecore_Wl2_Window *window;
100 116
101 window = data; 117 window = data;
102 window->req_config.serial = serial; 118 window->def_config.serial = serial;
103 if (!window->pending.configure) return;
104 119
105 _configure_complete(window); 120 if (window->pending.configure)
121 {
122 window->saved.w = window->set_config.geometry.w;
123 window->saved.h = window->set_config.geometry.h;
124 _configure_complete(window);
125 }
126 if (window->pending.configure && window->updating)
127 ERR("Window shouldn't be rendering before initial configure");
128
129 if (!window->updating)
130 _ecore_wl2_window_configure_send(window);
106} 131}
107 132
108static const struct zxdg_surface_v6_listener _zxdg_surface_listener = 133static const struct zxdg_surface_v6_listener _zxdg_surface_listener =
@@ -115,54 +140,35 @@ _zxdg_toplevel_cb_configure(void *data, struct zxdg_toplevel_v6 *zxdg_toplevel E
115{ 140{
116 Ecore_Wl2_Window *win = data; 141 Ecore_Wl2_Window *win = data;
117 uint32_t *s; 142 uint32_t *s;
118 Eina_Bool fs, max;
119 143
120 fs = win->req_config.fullscreen; 144 win->def_config.minimized = EINA_FALSE;
121 max = win->req_config.maximized; 145 win->def_config.maximized = EINA_FALSE;
122 146 win->def_config.fullscreen = EINA_FALSE;
123 win->req_config.minimized = EINA_FALSE; 147 win->def_config.focused = EINA_FALSE;
124 win->req_config.maximized = EINA_FALSE; 148 win->def_config.resizing = EINA_FALSE;
125 win->req_config.fullscreen = EINA_FALSE; 149 win->def_config.geometry.w = width;
126 win->req_config.focused = EINA_FALSE; 150 win->def_config.geometry.h = height;
127 win->req_config.resizing = EINA_FALSE;
128 151
129 wl_array_for_each(s, states) 152 wl_array_for_each(s, states)
130 { 153 {
131 switch (*s) 154 switch (*s)
132 { 155 {
133 case ZXDG_TOPLEVEL_V6_STATE_MAXIMIZED: 156 case ZXDG_TOPLEVEL_V6_STATE_MAXIMIZED:
134 win->req_config.maximized = EINA_TRUE; 157 win->def_config.maximized = EINA_TRUE;
135 break; 158 break;
136 case ZXDG_TOPLEVEL_V6_STATE_FULLSCREEN: 159 case ZXDG_TOPLEVEL_V6_STATE_FULLSCREEN:
137 win->req_config.fullscreen = EINA_TRUE; 160 win->def_config.fullscreen = EINA_TRUE;
138 break; 161 break;
139 case ZXDG_TOPLEVEL_V6_STATE_RESIZING: 162 case ZXDG_TOPLEVEL_V6_STATE_RESIZING:
140 win->req_config.resizing = EINA_TRUE; 163 win->def_config.resizing = EINA_TRUE;
141 break; 164 break;
142 case ZXDG_TOPLEVEL_V6_STATE_ACTIVATED: 165 case ZXDG_TOPLEVEL_V6_STATE_ACTIVATED:
143 win->req_config.focused = EINA_TRUE; 166 win->def_config.focused = EINA_TRUE;
144 win->req_config.minimized = EINA_FALSE; 167 win->def_config.minimized = EINA_FALSE;
145 default: 168 default:
146 break; 169 break;
147 } 170 }
148 } 171 }
149
150 if ((win->set_config.geometry.w == width) &&
151 (win->set_config.geometry.h == height))
152 width = height = 0;
153 else if ((!width) && (!height) && (!win->req_config.fullscreen) &&
154 (!win->req_config.maximized) &&
155 ((win->req_config.fullscreen != fs) ||
156 (win->req_config.maximized != max)))
157 width = win->saved.w, height = win->saved.h;
158
159 _ecore_wl2_window_configure_send(win, width, height, !!win->req_config.resizing,
160 win->req_config.fullscreen, win->req_config.maximized);
161
162 if (win->req_config.focused)
163 _ecore_wl2_window_activate_send(win);
164 else
165 _ecore_wl2_window_deactivate_send(win);
166} 172}
167 173
168static void 174static void
@@ -555,6 +561,7 @@ ecore_wl2_window_hide(Ecore_Wl2_Window *window)
555 561
556 window->set_config.serial = 0; 562 window->set_config.serial = 0;
557 window->req_config.serial = 0; 563 window->req_config.serial = 0;
564 window->def_config.serial = 0;
558 window->zxdg_configure_ack = NULL; 565 window->zxdg_configure_ack = NULL;
559 window->zxdg_set_min_size = NULL; 566 window->zxdg_set_min_size = NULL;
560 window->zxdg_set_max_size = NULL; 567 window->zxdg_set_max_size = NULL;
@@ -706,7 +713,6 @@ ecore_wl2_window_transparent_set(Ecore_Wl2_Window *window, Eina_Bool transparent
706EAPI void 713EAPI void
707ecore_wl2_window_opaque_region_set(Ecore_Wl2_Window *window, int x, int y, int w, int h) 714ecore_wl2_window_opaque_region_set(Ecore_Wl2_Window *window, int x, int y, int w, int h)
708{ 715{
709 struct wl_region *region;
710 int nx = 0, ny = 0, nw = 0, nh = 0; 716 int nx = 0, ny = 0, nw = 0, nh = 0;
711 717
712 EINA_SAFETY_ON_NULL_RETURN(window); 718 EINA_SAFETY_ON_NULL_RETURN(window);
@@ -750,32 +756,12 @@ ecore_wl2_window_opaque_region_set(Ecore_Wl2_Window *window, int x, int y, int w
750 window->opaque.w = nw; 756 window->opaque.w = nw;
751 window->opaque.h = nh; 757 window->opaque.h = nh;
752 window->opaque_set = x || y || w || h; 758 window->opaque_set = x || y || w || h;
753 759 window->pending.opaque = EINA_TRUE;
754 if (!window->surface) return;
755
756 if (!window->opaque_set)
757 {
758 wl_surface_set_opaque_region(window->surface, NULL);
759 return;
760 }
761
762 region = wl_compositor_create_region(window->display->wl.compositor);
763 if (!region)
764 {
765 ERR("Failed to create opaque region");
766 return;
767 }
768
769 wl_region_add(region, window->opaque.x, window->opaque.y,
770 window->opaque.w, window->opaque.h);
771 wl_surface_set_opaque_region(window->surface, region);
772 wl_region_destroy(region);
773} 760}
774 761
775EAPI void 762EAPI void
776ecore_wl2_window_input_region_set(Ecore_Wl2_Window *window, int x, int y, int w, int h) 763ecore_wl2_window_input_region_set(Ecore_Wl2_Window *window, int x, int y, int w, int h)
777{ 764{
778 struct wl_region *region;
779 int nx = 0, ny = 0, nw = 0, nh = 0; 765 int nx = 0, ny = 0, nw = 0, nh = 0;
780 766
781 EINA_SAFETY_ON_NULL_RETURN(window); 767 EINA_SAFETY_ON_NULL_RETURN(window);
@@ -819,27 +805,7 @@ ecore_wl2_window_input_region_set(Ecore_Wl2_Window *window, int x, int y, int w,
819 window->input_rect.w = nw; 805 window->input_rect.w = nw;
820 window->input_rect.h = nh; 806 window->input_rect.h = nh;
821 window->input_set = x || y || w || h; 807 window->input_set = x || y || w || h;
822 808 window->pending.input = EINA_TRUE;
823 if (!window->surface) return;
824 if (window->type == ECORE_WL2_WINDOW_TYPE_DND) return;
825
826 if (!window->input_set)
827 {
828 wl_surface_set_input_region(window->surface, NULL);
829 return;
830 }
831
832 region = wl_compositor_create_region(window->display->wl.compositor);
833 if (!region)
834 {
835 ERR("Failed to create input region");
836 return;
837 }
838
839 wl_region_add(region, window->input_rect.x, window->input_rect.y,
840 window->input_rect.w, window->input_rect.h);
841 wl_surface_set_input_region(window->surface, region);
842 wl_region_destroy(region);
843} 809}
844 810
845EAPI Eina_Bool 811EAPI Eina_Bool
@@ -862,6 +828,11 @@ ecore_wl2_window_maximized_set(Ecore_Wl2_Window *window, Eina_Bool maximized)
862 if (prev == maximized) return; 828 if (prev == maximized) return;
863 829
864 window->set_config.maximized = maximized; 830 window->set_config.maximized = maximized;
831 if (window->updating)
832 {
833 window->pending.maximized = EINA_TRUE;
834 return;
835 }
865 836
866 if (maximized) 837 if (maximized)
867 { 838 {
@@ -899,6 +870,11 @@ ecore_wl2_window_fullscreen_set(Ecore_Wl2_Window *window, Eina_Bool fullscreen)
899 if (prev == fullscreen) return; 870 if (prev == fullscreen) return;
900 871
901 window->set_config.fullscreen = fullscreen; 872 window->set_config.fullscreen = fullscreen;
873 if (window->updating)
874 {
875 window->pending.fullscreen = EINA_TRUE;
876 return;
877 }
902 878
903 if (fullscreen) 879 if (fullscreen)
904 { 880 {
@@ -982,9 +958,7 @@ ecore_wl2_window_geometry_set(Ecore_Wl2_Window *window, int x, int y, int w, int
982 window->set_config.geometry.y = y; 958 window->set_config.geometry.y = y;
983 window->set_config.geometry.w = w; 959 window->set_config.geometry.w = w;
984 window->set_config.geometry.h = h; 960 window->set_config.geometry.h = h;
985 961 window->pending.geom = EINA_TRUE;
986 if (window->zxdg_toplevel)
987 zxdg_surface_v6_set_window_geometry(window->zxdg_surface, x, y, w, h);
988} 962}
989 963
990EAPI Eina_Bool 964EAPI Eina_Bool
@@ -1390,6 +1364,84 @@ static struct wl_callback_listener _frame_listener =
1390 _frame_cb 1364 _frame_cb
1391}; 1365};
1392 1366
1367static void
1368_maximized_set(Ecore_Wl2_Window *window)
1369{
1370 EINA_SAFETY_ON_NULL_RETURN(window->zxdg_toplevel);
1371
1372 if (window->set_config.maximized)
1373 {
1374 window->saved = window->set_config.geometry;
1375 zxdg_toplevel_v6_set_maximized(window->zxdg_toplevel);
1376 }
1377 else
1378 zxdg_toplevel_v6_unset_maximized(window->zxdg_toplevel);
1379}
1380
1381static void
1382_fullscreen_set(Ecore_Wl2_Window *window)
1383{
1384 EINA_SAFETY_ON_NULL_RETURN(window->zxdg_toplevel);
1385
1386 if (window->set_config.fullscreen)
1387 {
1388 window->saved = window->set_config.geometry;
1389 zxdg_toplevel_v6_set_fullscreen(window->zxdg_toplevel, NULL);
1390 }
1391 else
1392 zxdg_toplevel_v6_unset_fullscreen(window->zxdg_toplevel);
1393}
1394
1395static void
1396_input_set(Ecore_Wl2_Window *window)
1397{
1398 struct wl_region *region;
1399
1400 if (window->type == ECORE_WL2_WINDOW_TYPE_DND) return;
1401
1402 if (!window->input_set)
1403 {
1404 wl_surface_set_input_region(window->surface, NULL);
1405 return;
1406 }
1407
1408 region = wl_compositor_create_region(window->display->wl.compositor);
1409 if (!region)
1410 {
1411 ERR("Failed to create input region");
1412 return;
1413 }
1414
1415 wl_region_add(region, window->input_rect.x, window->input_rect.y,
1416 window->input_rect.w, window->input_rect.h);
1417 wl_surface_set_input_region(window->surface, region);
1418 wl_region_destroy(region);
1419}
1420
1421static void
1422_opaque_set(Ecore_Wl2_Window *window)
1423{
1424 struct wl_region *region;
1425
1426 if (!window->opaque_set)
1427 {
1428 wl_surface_set_opaque_region(window->surface, NULL);
1429 return;
1430 }
1431
1432 region = wl_compositor_create_region(window->display->wl.compositor);
1433 if (!region)
1434 {
1435 ERR("Failed to create opaque region");
1436 return;
1437 }
1438
1439 wl_region_add(region, window->opaque.x, window->opaque.y,
1440 window->opaque.w, window->opaque.h);
1441 wl_surface_set_opaque_region(window->surface, region);
1442 wl_region_destroy(region);
1443}
1444
1393EAPI void 1445EAPI void
1394ecore_wl2_window_commit(Ecore_Wl2_Window *window, Eina_Bool flush) 1446ecore_wl2_window_commit(Ecore_Wl2_Window *window, Eina_Bool flush)
1395{ 1447{
@@ -1404,13 +1456,50 @@ ecore_wl2_window_commit(Ecore_Wl2_Window *window, Eina_Bool flush)
1404 window->commit_pending = EINA_TRUE; 1456 window->commit_pending = EINA_TRUE;
1405 window->callback = wl_surface_frame(window->surface); 1457 window->callback = wl_surface_frame(window->surface);
1406 wl_callback_add_listener(window->callback, &_frame_listener, window); 1458 wl_callback_add_listener(window->callback, &_frame_listener, window);
1459 /* Dispatch any state we've been saving along the way */
1460 if (window->pending.geom && window->zxdg_toplevel)
1461 zxdg_surface_v6_set_window_geometry(window->zxdg_surface,
1462 window->set_config.geometry.x,
1463 window->set_config.geometry.y,
1464 window->set_config.geometry.w,
1465 window->set_config.geometry.h);
1466 if (window->pending.opaque)
1467 _opaque_set(window);
1468
1469 if (window->pending.input)
1470 _input_set(window);
1471
1472 if (window->pending.maximized)
1473 _maximized_set(window);
1474
1475 if (window->pending.fullscreen)
1476 _fullscreen_set(window);
1477
1478 window->pending.geom = EINA_FALSE;
1479 window->pending.opaque = EINA_FALSE;
1480 window->pending.input = EINA_FALSE;
1481 window->pending.maximized = EINA_FALSE;
1482 window->pending.fullscreen = EINA_FALSE;
1483 }
1484
1485 if (window->req_config.serial != window->set_config.serial)
1486 {
1487 if (window->zxdg_configure_ack)
1488 window->zxdg_configure_ack(window->zxdg_surface,
1489 window->req_config.serial);
1490 window->set_config.serial = window->req_config.serial;
1407 } 1491 }
1408 if (flush) 1492 if (flush)
1409 { 1493 {
1410 wl_surface_commit(window->surface); 1494 wl_surface_commit(window->surface);
1411 ecore_wl2_display_flush(window->display); 1495 ecore_wl2_display_flush(window->display);
1412 } 1496 }
1497
1498 if (!window->updating) return;
1499
1413 window->updating = EINA_FALSE; 1500 window->updating = EINA_FALSE;
1501 if (window->def_config.serial != window->set_config.serial)
1502 _ecore_wl2_window_configure_send(window);
1414} 1503}
1415 1504
1416EAPI void ecore_wl2_window_false_commit(Ecore_Wl2_Window *window) 1505EAPI void ecore_wl2_window_false_commit(Ecore_Wl2_Window *window)