aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/elementary/src/lib/elu_ews_wm.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libraries/elementary/src/lib/elu_ews_wm.c545
1 files changed, 545 insertions, 0 deletions
diff --git a/libraries/elementary/src/lib/elu_ews_wm.c b/libraries/elementary/src/lib/elu_ews_wm.c
new file mode 100644
index 0000000..15fdb65
--- /dev/null
+++ b/libraries/elementary/src/lib/elu_ews_wm.c
@@ -0,0 +1,545 @@
1#include <Elementary.h>
2#include "elm_priv.h"
3
4static Eina_Bool _ews_used = EINA_FALSE;
5static Eina_List *_ews_ev_handlers = NULL;
6static Eina_Hash *_ews_borders = NULL;
7static Eina_Hash *_ews_borders_geo = NULL;
8static Evas_Object *_ews_bg = NULL;
9static Ecore_Animator *_ews_border_mover = NULL;
10static Evas_Object *_ews_border_mover_obj = NULL;
11static Evas_Point _ews_border_mover_off = {0, 0};
12
13static void
14_elm_ews_border_usable_screen_geometry_get(int *x, int *y, int *w, int *h)
15{
16 Ecore_Evas *ee = ecore_evas_ews_ecore_evas_get();
17 ecore_evas_geometry_get(ee, NULL, NULL, w, h);
18 if (x) *x = 0;
19 if (y) *y = 0;
20 // TODO: when add a shelf for iconified, subtract its area here.
21}
22
23static void
24_elm_ews_wm_border_del(void *data)
25{
26 Evas_Object *deco = data;
27 evas_object_del(deco);
28
29 if (_ews_border_mover_obj == deco)
30 {
31 if (_ews_border_mover)
32 {
33 ecore_animator_del(_ews_border_mover);
34 _ews_border_mover = NULL;
35 }
36 _ews_border_mover_obj = NULL;
37 }
38}
39
40static Evas_Object *
41_elm_ews_wm_border_find(const Ecore_Evas *ee)
42{
43 return eina_hash_find(_ews_borders, &ee);
44}
45
46static Eina_Rectangle *
47_elm_ews_wm_border_geo_find(const Ecore_Evas *ee)
48{
49 return eina_hash_find(_ews_borders_geo, &ee);
50}
51
52static void
53_elm_ews_border_geo_apply(Ecore_Evas *ee, Evas_Object *o)
54{
55 int x, y, w, h;
56 ecore_evas_geometry_get(ee, &x, &y, &w, &h);
57 evas_object_move(o, x, y);
58 evas_object_resize(o, w, h);
59}
60
61static void
62_elm_ews_border_focus_apply(Ecore_Evas *ee, Evas_Object *o)
63{
64 const char *sig;
65 if (ecore_evas_focus_get(ee))
66 sig = "elm,state,focus,on";
67 else
68 sig = "elm,state,focus,off";
69 edje_object_signal_emit(o, sig, "elm");
70}
71
72static void
73_elm_ews_border_stack_apply(Ecore_Evas *ee, Evas_Object *o)
74{
75 Evas_Object *bs_o = ecore_evas_ews_backing_store_get(ee);
76 evas_object_stack_below(o, bs_o);
77}
78
79static void
80_elm_ews_border_iconified_apply(Ecore_Evas *ee, Evas_Object *o)
81{
82 const char *sig;
83 if (ecore_evas_iconified_get(ee))
84 sig = "elm,state,iconified,on";
85 else
86 sig = "elm,state,iconified,off";
87 edje_object_signal_emit(o, sig, "elm");
88
89 // TODO: add to some taskbar? and actually hide it?
90 DBG("EWS does not implement iconified yet");
91}
92
93static void
94_elm_ews_border_maximized_apply(Ecore_Evas *ee, Evas_Object *o)
95{
96 int x, y, w, h;
97 if (ecore_evas_maximized_get(ee))
98 {
99 Eina_Rectangle *r;
100 int ex, ey, ew, eh;
101
102 edje_object_signal_emit(o, "elm,state,maximized,on", "elm");
103 edje_object_message_signal_process(o);
104 ecore_evas_geometry_get(ee, &x, &y, &w, &h);
105
106 r = _elm_ews_wm_border_geo_find(ee);
107 if (!r)
108 {
109 r = malloc(sizeof(Eina_Rectangle));
110 eina_hash_add(_ews_borders_geo, &ee, r);
111 }
112
113 r->x = x;
114 r->y = y;
115 r->w = w;
116 r->h = h;
117 _elm_ews_border_usable_screen_geometry_get(&x, &y, &w, &h);
118 edje_object_parts_extends_calc(o, &ex, &ey, &ew, &eh);
119 x -= ex;
120 y -= ey;
121 w -= ew - r->w;
122 h -= eh - r->h;
123 }
124 else
125 {
126 Eina_Rectangle *r = _elm_ews_wm_border_geo_find(ee);
127 edje_object_signal_emit(o, "elm,state,maximized,off", "elm");
128
129 if (!r) ecore_evas_geometry_get(ee, &x, &y, &w, &h);
130 else
131 {
132 x = r->x;
133 y = r->y;
134 w = r->w;
135 h = r->h;
136 }
137 }
138
139 ecore_evas_move_resize(ee, x, y, w, h);
140 _elm_ews_border_geo_apply(ee, o);
141}
142
143static void
144_elm_ews_border_layer_apply(Ecore_Evas *ee, Evas_Object *o)
145{
146 Evas_Object *bs_o = ecore_evas_ews_backing_store_get(ee);
147 evas_object_layer_set(o, evas_object_layer_get(bs_o));
148 _elm_ews_border_stack_apply(ee, o);
149}
150
151static void
152_elm_ews_border_fullscreen_apply(Ecore_Evas *ee, Evas_Object *o)
153{
154 const char *sig;
155 if (ecore_evas_fullscreen_get(ee))
156 sig = "elm,state,fullscreen,on";
157 else
158 sig = "elm,state,fullscreen,off";
159 edje_object_signal_emit(o, sig, "elm");
160 _elm_ews_border_geo_apply(ee, o);
161}
162
163static void
164_elm_ews_border_config_apply(Ecore_Evas *ee, Evas_Object *o, Elm_Theme *th)
165{
166 const char *title, *name = NULL, *class = NULL, *style = NULL;
167 const char *sig;
168
169 if (ecore_evas_borderless_get(ee))
170 style = "borderless";
171
172 _elm_theme_set(th, o, "ews", "decoration", style ? style : "default");
173
174 if (ecore_evas_shaped_get(ee) || ecore_evas_alpha_get(ee) ||
175 ecore_evas_transparent_get(ee))
176 sig = "elm,state,alpha,on";
177 else
178 sig = "elm,state,alpha,off";
179 edje_object_signal_emit(o, sig, "elm");
180
181 title = ecore_evas_title_get(ee);
182 ecore_evas_name_class_get(ee, &name, &class);
183 edje_object_part_text_escaped_set(o, "elm.text.title", title);
184 edje_object_part_text_escaped_set(o, "elm.text.name", name);
185 edje_object_part_text_escaped_set(o, "elm.text.class", class);
186
187 _elm_ews_border_geo_apply(ee, o);
188 _elm_ews_border_focus_apply(ee, o);
189 _elm_ews_border_stack_apply(ee, o);
190 _elm_ews_border_iconified_apply(ee, o);
191 _elm_ews_border_maximized_apply(ee, o);
192 _elm_ews_border_layer_apply(ee, o);
193 _elm_ews_border_fullscreen_apply(ee, o);
194}
195
196static Eina_Bool
197_elm_ews_wm_border_theme_set(Ecore_Evas *ee, Evas_Object *o, Elm_Theme *th)
198{
199 _elm_ews_border_config_apply(ee, o, th);
200 return EINA_TRUE;
201}
202
203static void
204_elm_ews_border_sig_focus(void *data, Evas_Object *o __UNUSED__, const char *sig __UNUSED__, const char *source __UNUSED__)
205{
206 Ecore_Evas *ee = data;
207 ecore_evas_focus_set(ee, EINA_TRUE);
208}
209
210static void
211_elm_ews_border_sig_iconify(void *data, Evas_Object *o __UNUSED__, const char *sig __UNUSED__, const char *source __UNUSED__)
212{
213 Ecore_Evas *ee = data;
214 ecore_evas_iconified_set(ee, EINA_TRUE);
215}
216
217static void
218_elm_ews_border_sig_maximize(void *data, Evas_Object *o __UNUSED__, const char *sig __UNUSED__, const char *source __UNUSED__)
219{
220 Ecore_Evas *ee = data;
221 ecore_evas_maximized_set(ee, EINA_TRUE);
222}
223
224static void
225_elm_ews_border_sig_fullscreen(void *data, Evas_Object *o __UNUSED__, const char *sig __UNUSED__, const char *source __UNUSED__)
226{
227 Ecore_Evas *ee = data;
228 ecore_evas_fullscreen_set(ee, EINA_TRUE);
229}
230
231static void
232_elm_ews_border_sig_restore(void *data, Evas_Object *o __UNUSED__, const char *sig __UNUSED__, const char *source __UNUSED__)
233{
234 Ecore_Evas *ee = data;
235 ecore_evas_iconified_set(ee, EINA_FALSE);
236 ecore_evas_maximized_set(ee, EINA_FALSE);
237 ecore_evas_fullscreen_set(ee, EINA_FALSE);
238}
239
240static void
241_elm_ews_border_sig_close(void *data, Evas_Object *o __UNUSED__, const char *sig __UNUSED__, const char *source __UNUSED__)
242{
243 Ecore_Evas *ee = data;
244 ecore_evas_ews_delete_request(ee);
245}
246
247static void
248_elm_ews_border_sig_menu(void *data, Evas_Object *o __UNUSED__, const char *sig __UNUSED__, const char *source __UNUSED__)
249{
250 // TODO: show some menu?
251 ERR("EWS does not implement menu yet");
252 (void)data;
253}
254
255static Eina_Bool
256_elm_ews_border_mover(void *data)
257{
258 Ecore_Evas *ee = data;
259 Evas_Object *o = _elm_ews_wm_border_find(ee);
260 int x, y;
261
262 evas_pointer_output_xy_get(ecore_evas_ews_evas_get(), &x, &y);
263 x -= _ews_border_mover_off.x;
264 y -= _ews_border_mover_off.y;
265 ecore_evas_move(ee, x, y);
266 evas_object_move(o, x, y);
267
268 return EINA_TRUE;
269}
270
271static void
272_elm_ews_border_sig_move_start(void *data, Evas_Object *o __UNUSED__, const char *sig __UNUSED__, const char *source __UNUSED__)
273{
274 Ecore_Evas *ee = data;
275 Evas_Object *bs_o = ecore_evas_ews_backing_store_get(ee);
276 int x, y, ox, oy;
277
278 if (_ews_border_mover) ecore_animator_del(_ews_border_mover);
279
280 evas_pointer_output_xy_get(evas_object_evas_get(bs_o), &x, &y);
281 evas_object_geometry_get(bs_o, &ox, &oy, NULL, NULL);
282 _ews_border_mover_off.x = x - ox;
283 _ews_border_mover_off.y = y - oy;
284 _ews_border_mover_obj = bs_o;
285 _ews_border_mover = ecore_animator_add(_elm_ews_border_mover, ee);
286}
287
288static void
289_elm_ews_border_sig_move_stop(void *data __UNUSED__, Evas_Object *o __UNUSED__, const char *sig __UNUSED__, const char *source __UNUSED__)
290{
291 if (!_ews_border_mover) return;
292 ecore_animator_del(_ews_border_mover);
293 _ews_border_mover = NULL;
294 _ews_border_mover_obj = NULL;
295}
296
297static Eina_Bool
298_elm_ews_wm_add_cb(void *data __UNUSED__, int type __UNUSED__, void *event_info)
299{
300 Ecore_Evas *ee = event_info;
301 Evas_Object *o = edje_object_add(ecore_evas_ews_evas_get());
302 Evas_Coord x, y, w, h, sw, sh;
303
304 edje_object_signal_callback_add
305 (o, "elm,action,focus", "elm", _elm_ews_border_sig_focus, ee);
306 edje_object_signal_callback_add
307 (o, "elm,action,iconify", "elm", _elm_ews_border_sig_iconify, ee);
308 edje_object_signal_callback_add
309 (o, "elm,action,maximize", "elm", _elm_ews_border_sig_maximize, ee);
310 edje_object_signal_callback_add
311 (o, "elm,action,fullscreen", "elm", _elm_ews_border_sig_fullscreen, ee);
312 edje_object_signal_callback_add
313 (o, "elm,action,restore", "elm", _elm_ews_border_sig_restore, ee);
314 edje_object_signal_callback_add
315 (o, "elm,action,close", "elm", _elm_ews_border_sig_close, ee);
316 edje_object_signal_callback_add
317 (o, "elm,action,menu", "elm", _elm_ews_border_sig_menu, ee);
318 edje_object_signal_callback_add
319 (o, "elm,action,move,start", "elm", _elm_ews_border_sig_move_start, ee);
320 edje_object_signal_callback_add
321 (o, "elm,action,move,stop", "elm", _elm_ews_border_sig_move_stop, ee);
322
323 eina_hash_add(_ews_borders, &ee, o);
324 _elm_ews_wm_border_theme_set(ee, o, NULL);
325
326 ecore_evas_screen_geometry_get(ee, NULL, NULL, &sw, &sh);
327 ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
328 x = (sw - w) / 2;
329 y = (sh - h) / 2;
330 ecore_evas_move(ee, x, y);
331 ecore_evas_focus_set(ee, EINA_TRUE);
332
333 return EINA_TRUE;
334}
335
336static Eina_Bool
337_elm_ews_wm_del_cb(void *data __UNUSED__, int type __UNUSED__, void *event_info)
338{
339 Ecore_Evas *ee = event_info;
340 eina_hash_del(_ews_borders, &ee, NULL);
341 eina_hash_del(_ews_borders_geo, &ee, NULL);
342 return EINA_TRUE;
343}
344
345static Eina_Bool
346_elm_ews_wm_geo_cb(void *data __UNUSED__, int type __UNUSED__, void *event_info)
347{
348 Ecore_Evas *ee = event_info;
349 Evas_Object *o = _elm_ews_wm_border_find(ee);
350 _elm_ews_border_geo_apply(ee, o);
351 return EINA_TRUE;
352}
353
354static Eina_Bool
355_elm_ews_wm_show_cb(void *data __UNUSED__, int type __UNUSED__, void *event_info)
356{
357 Ecore_Evas *ee = event_info;
358 Evas_Object *o = _elm_ews_wm_border_find(ee);
359 evas_object_show(o);
360 return EINA_TRUE;
361}
362
363static Eina_Bool
364_elm_ews_wm_hide_cb(void *data __UNUSED__, int type __UNUSED__, void *event_info)
365{
366 Ecore_Evas *ee = event_info;
367 Evas_Object *o = _elm_ews_wm_border_find(ee);
368 evas_object_hide(o);
369 return EINA_TRUE;
370}
371
372static Eina_Bool
373_elm_ews_wm_focus_cb(void *data __UNUSED__, int type __UNUSED__, void *event_info)
374{
375 Ecore_Evas *ee = event_info;
376 Evas_Object *o = _elm_ews_wm_border_find(ee);
377 _elm_ews_border_focus_apply(ee, o);
378 return EINA_TRUE;
379}
380
381static Eina_Bool
382_elm_ews_wm_stack_cb(void *data __UNUSED__, int type __UNUSED__, void *event_info)
383{
384 Ecore_Evas *ee = event_info;
385 Evas_Object *o = _elm_ews_wm_border_find(ee);
386 _elm_ews_border_stack_apply(ee, o);
387 return EINA_TRUE;
388}
389
390static Eina_Bool
391_elm_ews_wm_iconified_change_cb(void *data __UNUSED__, int type __UNUSED__, void *event_info)
392{
393 Ecore_Evas *ee = event_info;
394 Evas_Object *o = _elm_ews_wm_border_find(ee);
395 _elm_ews_border_iconified_apply(ee, o);
396 return EINA_TRUE;
397}
398
399static Eina_Bool
400_elm_ews_wm_maximized_change_cb(void *data __UNUSED__, int type __UNUSED__, void *event_info)
401{
402 Ecore_Evas *ee = event_info;
403 Evas_Object *o = _elm_ews_wm_border_find(ee);
404 _elm_ews_border_maximized_apply(ee, o);
405 return EINA_TRUE;
406}
407
408static Eina_Bool
409_elm_ews_wm_layer_change_cb(void *data __UNUSED__, int type __UNUSED__, void *event_info)
410{
411 Ecore_Evas *ee = event_info;
412 Evas_Object *o = _elm_ews_wm_border_find(ee);
413 _elm_ews_border_layer_apply(ee, o);
414 return EINA_TRUE;
415}
416
417static Eina_Bool
418_elm_ews_wm_fullscreen_change_cb(void *data __UNUSED__, int type __UNUSED__, void *event_info)
419{
420 Ecore_Evas *ee = event_info;
421 Evas_Object *o = _elm_ews_wm_border_find(ee);
422 _elm_ews_border_fullscreen_apply(ee, o);
423 return EINA_TRUE;
424}
425
426static Eina_Bool
427_elm_ews_wm_config_change_cb(void *data __UNUSED__, int type __UNUSED__, void *event_info)
428{
429 Ecore_Evas *ee = event_info;
430 Evas_Object *o = _elm_ews_wm_border_find(ee);
431 _elm_ews_border_config_apply(ee, o, NULL);
432 return EINA_TRUE;
433}
434
435void
436_elm_ews_wm_rescale(Elm_Theme *th, Eina_Bool use_theme)
437{
438 Eina_Iterator *it;
439 Eina_Hash_Tuple *tp = NULL;
440
441 if (!_ews_borders) return;
442 it = eina_hash_iterator_tuple_new(_ews_borders);
443 if (!use_theme)
444 {
445 EINA_ITERATOR_FOREACH(it, tp)
446 _elm_ews_wm_border_theme_set(*(void**)tp->key, tp->data, NULL);
447
448 if (_ews_bg)
449 _elm_theme_set(NULL, _ews_bg, "ews", "background", "default");
450 }
451 else
452 {
453 EINA_ITERATOR_FOREACH(it, tp)
454 _elm_ews_wm_border_theme_set(*(void**)tp->key, tp->data, th);
455
456 if (_ews_bg)
457 _elm_theme_set(th, _ews_bg, "ews", "background", "default");
458 }
459
460 eina_iterator_free(it);
461}
462
463int
464_elm_ews_wm_init(void)
465{
466 Evas *e;
467 Evas_Object *o;
468
469 if (strcmp(_elm_config->engine, ELM_EWS) != 0)
470 {
471 _ews_used = EINA_FALSE;
472 return EINA_TRUE;
473 }
474
475 e = ecore_evas_ews_evas_get();
476 if (!e) return EINA_FALSE;
477 o = edje_object_add(e);
478 if (!o) return EINA_FALSE;
479
480 if (!_elm_theme_set(NULL, o, "ews", "background", "default"))
481 {
482 ERR("Could not set background theme, fallback to rectangle");
483 evas_object_del(o);
484 _ews_bg = o = NULL;
485 }
486 else
487 _ews_bg = o;
488 ecore_evas_ews_background_set(o);
489
490
491#define ADD_EH(ev, cb) \
492 _ews_ev_handlers = eina_list_append \
493 (_ews_ev_handlers, ecore_event_handler_add(ev, cb, NULL))
494 ADD_EH(ECORE_EVAS_EWS_EVENT_ADD, _elm_ews_wm_add_cb);
495 ADD_EH(ECORE_EVAS_EWS_EVENT_DEL, _elm_ews_wm_del_cb);
496 ADD_EH(ECORE_EVAS_EWS_EVENT_RESIZE, _elm_ews_wm_geo_cb);
497 ADD_EH(ECORE_EVAS_EWS_EVENT_MOVE, _elm_ews_wm_geo_cb);
498 ADD_EH(ECORE_EVAS_EWS_EVENT_SHOW, _elm_ews_wm_show_cb);
499 ADD_EH(ECORE_EVAS_EWS_EVENT_HIDE, _elm_ews_wm_hide_cb);
500 ADD_EH(ECORE_EVAS_EWS_EVENT_FOCUS, _elm_ews_wm_focus_cb);
501 ADD_EH(ECORE_EVAS_EWS_EVENT_UNFOCUS, _elm_ews_wm_focus_cb);
502 ADD_EH(ECORE_EVAS_EWS_EVENT_RAISE, _elm_ews_wm_stack_cb);
503 ADD_EH(ECORE_EVAS_EWS_EVENT_LOWER, _elm_ews_wm_stack_cb);
504 ADD_EH(ECORE_EVAS_EWS_EVENT_ICONIFIED_CHANGE, _elm_ews_wm_iconified_change_cb);
505 ADD_EH(ECORE_EVAS_EWS_EVENT_MAXIMIZED_CHANGE, _elm_ews_wm_maximized_change_cb);
506 ADD_EH(ECORE_EVAS_EWS_EVENT_LAYER_CHANGE, _elm_ews_wm_layer_change_cb);
507 ADD_EH(ECORE_EVAS_EWS_EVENT_FULLSCREEN_CHANGE, _elm_ews_wm_fullscreen_change_cb);
508 ADD_EH(ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE, _elm_ews_wm_config_change_cb);
509#undef ADD_EH
510
511 if (!_ews_borders)
512 _ews_borders = eina_hash_pointer_new(_elm_ews_wm_border_del);
513
514 if (!_ews_borders_geo)
515 _ews_borders_geo = eina_hash_pointer_new(free);
516
517 _ews_used = EINA_TRUE;
518 return EINA_TRUE;
519}
520
521void
522_elm_ews_wm_shutdown(void)
523{
524 Ecore_Event_Handler *eh;
525
526 if (_ews_border_mover)
527 {
528 ecore_animator_del(_ews_border_mover);
529 _ews_border_mover = NULL;
530 }
531 _ews_border_mover_obj = NULL;
532
533 EINA_LIST_FREE(_ews_ev_handlers, eh) ecore_event_handler_del(eh);
534 if (_ews_borders)
535 {
536 eina_hash_free(_ews_borders);
537 _ews_borders = NULL;
538 }
539 if (_ews_borders_geo)
540 {
541 eina_hash_free(_ews_borders_geo);
542 _ews_borders_geo = NULL;
543 }
544 _ews_bg = NULL;
545}