1 #ifdef HAVE_CONFIG_H
2 # include "elementary_config.h"
3 #endif
4
5 #define EFL_ACCESS_OBJECT_PROTECTED
6 #define EFL_ACCESS_COMPONENT_PROTECTED
7 #define EFL_ACCESS_WIDGET_ACTION_PROTECTED
8 #define EFL_INPUT_EVENT_PROTECTED
9 #define EFL_GFX_HINT_PROTECTED
10 #define EFL_CANVAS_OBJECT_PROTECTED
11 #define EFL_UI_L10N_PROTECTED
12 #define EFL_UI_WIN_INLINED_PROTECTED
13 #define EFL_UI_FOCUS_OBJECT_PROTECTED
14 #define EFL_UI_WIDGET_FOCUS_MANAGER_PROTECTED
15 #define EFL_PART_PROTECTED
16 #define IPA_YLNO_ESU_LANRETNI_MLE
17
18 #include <Elementary.h>
19 #include <Elementary_Cursor.h>
20
21 #include "elm_priv.h"
22 #include "elm_widget_menu.h"
23 #ifdef HAVE_ELEMENTARY_WL2
24 # include "ecore_evas_wayland_private.h"
25 #endif
26
27 #include "../evas/canvas/evas_box_eo.h"
28
29 #include "elm_part_helper.h"
30 #include "efl_ui_win_part.eo.h"
31 #include "elm_plug_eo.h"
32 #include "efl_ui_win_legacy_eo.h"
33 #include "efl_ui_win_socket_legacy_eo.h"
34 #include "efl_ui_win_inlined_legacy_eo.h"
35 #include "efl_ui_widget_common.h"
36
37 #define MY_CLASS EFL_UI_WIN_CLASS
38 #define MY_CLASS_NAME "Efl.Ui.Win"
39 #define MY_CLASS_NAME_LEGACY "elm_win"
40
41 #define FRAME_OBJ_THEME_MIN_VERSION 119
42
43 extern void ecore_evas_dnd_mark_motion_used(Ecore_Evas *ee, unsigned int seat);
44
45 Ecore_Evas *_wayland_shm_new(const char *disp_name, Ecore_Window parent, int x, int y, int w, int h, Eina_Bool frame);
46 Ecore_Evas *_wayland_egl_new(const char *disp_name, Ecore_Window parent, int x, int y, int w, int h, Eina_Bool frame, const int *opt);
47
48 static const Elm_Win_Trap *trap = NULL;
49
50 static int _paused_windows = 0;
51
52 #define TRAP(sd, name, ...) \
53 do \
54 { \
55 if (sd->type != EFL_UI_WIN_TYPE_FAKE) \
56 if ((!trap) || (!trap->name) || \
57 ((trap->name) && \
58 (trap->name(sd->trap_data, sd->obj, ## __VA_ARGS__)))) \
59 ecore_evas_##name(sd->ee, ##__VA_ARGS__); \
60 } \
61 while (0)
62
63 #define ELM_WIN_DATA_GET(o, sd) \
64 Efl_Ui_Win_Data *sd = efl_data_scope_get(o, MY_CLASS)
65
66 #define ELM_WIN_DATA_GET_OR_RETURN(o, ptr, ...) \
67 ELM_WIN_DATA_GET(o, ptr); \
68 if (!ptr) \
69 { \
70 ERR("No widget data for object %p (%s)", \
71 o, efl_class_name_get(o)); \
72 return __VA_ARGS__; \
73 }
74
75 // Ecore_Evas callbacks are unsafe unlike EO calls. As a consequence a user
76 // callback (eg evas cb, efl event cb, ...) could be triggered that deletes the
77 // object. This macro ensures the sd data is still valid after a foreign call.
78 #define ELM_WIN_DATA_ALIVE_CHECK(_obj, _sd, ...) do { \
79 _sd = efl_data_scope_safe_get(_obj, MY_CLASS); \
80 if (EINA_UNLIKELY(!(_sd))) { return __VA_ARGS__; } \
81 } while (0)
82
83 #define ENGINE_GET() (_elm_preferred_engine ? _elm_preferred_engine : _elm_config->engine)
84
85 typedef struct _Efl_Ui_Win_Data Efl_Ui_Win_Data;
86 typedef struct _Input_Pointer_Iterator Input_Pointer_Iterator;
87
88 struct _Efl_Ui_Win_Data
89 {
90 Ecore_Evas *ee;
91 Evas *evas;
92 Evas_Object *parent; /* parent *window* object*/
93 Evas_Object *img_obj, *frame_obj;
94 Eo /* wref */ *bg, *content;
95 Evas_Object *obj; /* The object itself */
96 Evas_Object *indicator;
97 #ifdef HAVE_ELEMENTARY_X
98 struct
99 {
100 Ecore_X_Window xwin;
101 Ecore_Event_Handler *client_message_handler;
102 Ecore_Event_Handler *property_handler;
103 Eina_Bool shaped : 1;
104 } x;
105 #endif
106 #ifdef HAVE_ELEMENTARY_WL2
107 struct
108 {
109 Ecore_Wl2_Window *win;
110 Ecore_Event_Handler *configure_handler;
111 } wl;
112 #endif
113 #ifdef HAVE_ELEMENTARY_COCOA
114 struct {
115 Ecore_Cocoa_Window *win;
116 } cocoa;
117 #endif
118 #ifdef HAVE_ELEMENTARY_WIN32
119 struct
120 {
121 Ecore_Win32_Window *win;
122 Ecore_Event_Handler *key_down_handler;
123 } win32;
124 #endif
125
126 unsigned /* Efl_Ui_Win_Type */ type;
127 Efl_Ui_Win_Keyboard_Mode kbdmode;
128 Efl_Ui_Win_Indicator_Mode indimode;
129 struct
130 {
131 const char *info;
132 Ecore_Timer *timer;
133 int repeat_count;
134 int shot_counter;
135 } shot;
136 int *autodel_clear, rot;
137 struct
138 {
139 int x, y;
140 } screen;
141 struct
142 {
143 #ifdef HAVE_ELEMENTARY_WL2
144 Ecore_Wl2_Window *win;
145 struct wl_surface *surf;
146 #endif
147 Ecore_Evas *ee;
148 Evas_Object *obj;
149 int hot_x, hot_y;
150 Eina_Bool visible : 1;
151 } pointer;
152 struct
153 {
154 Evas_Object *fobj; /* focus highlight edje object */
155
156 struct
157 {
158 Evas_Object *target;
159 Eina_Bool visible : 1;
160 Eina_Bool in_theme: 1; /**< focus highlight is handled by theme.
161 this is set true if edc data item "focus_highlight" is set to "on" during focus in callback. */
162 } cur, prev;
163
164 const char *style;
165 Ecore_Job *reconf_job;
166
167 Eina_Bool enabled : 1;
168 Eina_Bool theme_changed : 1; /* set true when the focus theme is changed */
169 Eina_Bool animate : 1; /* set true when the focus highlight animate is enabled */
170 Eina_Bool animate_supported : 1; /* set true when the focus highlight animate is supported by theme */
171 Eina_Bool geometry_changed : 1;
172 Eina_Bool auto_enabled : 1;
173 Eina_Bool auto_animate : 1;
174 } focus_highlight;
175
176 Evas_Object *icon;
177 const char *title;
178 const char *icon_name;
179 const char *role;
180 const char *stack_id;
181 const char *stack_master_id;
182 Eina_Stringshare *name;
183 Eina_Stringshare *accel_pref;
184
185 Eina_Future *finalize_future;
186
187 Evas_Object *main_menu;
188
189 Efl_Ui_Focus_Parent_Provider_Standard *provider;
190
191 struct
192 {
193 Eina_Stringshare *name; /* Current profile in use */
194 Eina_Array *available; /* Never NULL, contains Eina_Stringshare */
195 } profile;
196 struct
197 {
198 int preferred_rot; /* indicates preferred rotation value, -1 means invalid. */
199 int *rots; /* indicates available rotations */
200 unsigned int count; /* number of elements in available rotations */
201 Eina_Bool wm_supported : 1; /* set true when the window manager support window rotation */
202 Eina_Bool use : 1; /* set true when application use window manager rotation. */
203 } wm_rot;
204
205 void *trap_data;
206
207 double aspect; /* defined as w/h or 0 */
208 int size_base_w, size_base_h;
209 int size_step_w, size_step_h;
210 int req_x, req_y, req_w, req_h;
211 int max_w, max_h;
212 int norender;
213 int modal_count;
214 int response;
215 int ignore_frame_resize;
216 Eina_Bool req_wh : 1;
217 Eina_Bool req_xy : 1;
218 Eina_Array *selection_changed;
219 Eina_Array *planned_changes;
220 Eina_Inarray *drop_target;
221
222 struct {
223 short pointer_move;
224 short pointer_down;
225 short pointer_up;
226 short pointer_in;
227 short pointer_out;
228 short pointer_cancel;
229 short pointer_wheel;
230 short finger_move;
231 short finger_down;
232 short finger_up;
233 short key_down;
234 short key_up;
235 short render_pre;
236 short render_post;
237 short focus_in;
238 short focus_out;
239 short object_focus_in;
240 short object_focus_out;
241 short device_changed;
242 } event_forward;
243
244 struct {
245 /* frame_obj is always used except for FAKE */
246 Eina_Bool need : 1; /**< if true, application draws its own csd */
247 Eina_Bool need_shadow : 1; /**< if true, application draws its csd and shadow */
248 Eina_Bool need_borderless : 1;
249 Eina_Bool need_bg_solid : 1;
250 Eina_Bool need_bg_standard : 1;
251 Eina_Bool need_menu : 1;
252 Eina_Bool need_unresizable : 1;
253 Eina_Bool need_indicator : 1;
254 Eina_Bool cur_borderless : 1;
255 Eina_Bool cur_shadow : 1;
256 Eina_Bool cur_focus : 1;
257 Eina_Bool cur_maximized : 1;
258 Eina_Bool cur_bg_solid : 1;
259 Eina_Bool cur_bg_standard : 1;
260 Eina_Bool cur_menu : 1;
261 Eina_Bool cur_unresizable : 1;
262 Eina_Bool cur_indicator : 1;
263 Eina_Bool wayland : 1;
264 } csd;
265
266 struct {
267 Evas_Object *box, *edje;
268 Elm_Win_Indicator_Mode indmode;
269 Elm_Win_Indicator_Opacity_Mode ind_o_mode;
270 Eina_Bool forbidden : 1; /**< Marks some legacy APIs as not allowed. */
271 Eina_Bool bg_must_swallow : 1; /**< Legacy theme compatibility (elm_bg for standard window) */
272 Eina_Bool bg_must_swallow_init : 1;
273 Eina_Bool ctor : 1; /**< legacy constructor: elm_win~add */
274 } legacy;
275 Efl_Ui_Shared_Win_Data spd;
276
277 Eina_Value exit_on_close;
278
279 Eina_Bool first_draw : 1;
280 Eina_Bool deferred_resize_job : 1;
281 Eina_Bool urgent : 1;
282 Eina_Bool modal : 1;
283 Eina_Bool demand_attention : 1;
284 Eina_Bool autodel : 1;
285 Eina_Bool autohide : 1;
286 Eina_Bool constrain : 1;
287 Eina_Bool resizing : 1;
288 Eina_Bool minimized : 1;
289 Eina_Bool withdrawn : 1;
290 Eina_Bool sticky : 1;
291 Eina_Bool fullscreen : 1;
292 Eina_Bool maximized : 1;
293 Eina_Bool skip_focus : 1;
294 Eina_Bool floating : 1;
295 Eina_Bool noblank : 1;
296 Eina_Bool theme_alpha : 1; /**< alpha value fetched by a theme. this has higher priority than application_alpha */
297 Eina_Bool application_alpha : 1; /**< alpha value set by an elm_win_alpha_set() api. this has lower priority than theme_alpha */
298 Eina_Bool tmp_updating_hints : 1;
299 Eina_Bool single_edje_content: 1; /* hack for E */
300 Eina_Bool shown : 1;
301 Eina_Bool stack_base : 1;
302 Eina_Bool paused : 1;
303 };
304
305 struct _Input_Pointer_Iterator
306 {
307 Eina_Iterator iterator;
308 Eina_List *list;
309 Eina_Iterator *real_iterator;
310 const Eo *object;
311 };
312
313 static const char SIG_DELETE_REQUEST[] = "delete,request";
314 static const char SIG_FOCUS_OUT[] = "focus,out"; // deprecated. use "unfocused" instead.
315 static const char SIG_FOCUS_IN[] = "focus,in"; // deprecated. use "focused" instead.
316 static const char SIG_MOVED[] = "moved";
317 static const char SIG_WITHDRAWN[] = "withdrawn";
318 static const char SIG_MINIMIZED[] = "minimized";
319 static const char SIG_NORMAL[] = "normal";
320 static const char SIG_STICK[] = "stick";
321 static const char SIG_UNSTICK[] = "unstick";
322 static const char SIG_FULLSCREEN[] = "fullscreen";
323 static const char SIG_UNFULLSCREEN[] = "unfullscreen";
324 static const char SIG_MAXIMIZED[] = "maximized";
325 static const char SIG_UNMAXIMIZED[] = "unmaximized";
326 static const char SIG_IOERR[] = "ioerr";
327 static const char SIG_INDICATOR_PROP_CHANGED[] = "indicator,prop,changed";
328 static const char SIG_ROTATION_CHANGED[] = "rotation,changed";
329 static const char SIG_PROFILE_CHANGED[] = "profile,changed";
330 static const char SIG_WM_ROTATION_CHANGED[] = "wm,rotation,changed";
331
332 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
333 {SIG_DELETE_REQUEST, ""},
334 {SIG_FOCUS_OUT, ""},
335 {SIG_FOCUS_IN, ""},
336 {SIG_MOVED, ""},
337 {SIG_WITHDRAWN, ""},
338 {SIG_MINIMIZED, ""},
339 {SIG_NORMAL, ""},
340 {SIG_STICK, ""},
341 {SIG_UNSTICK, ""},
342 {SIG_FULLSCREEN, ""},
343 {SIG_UNFULLSCREEN, ""},
344 {SIG_MAXIMIZED, ""},
345 {SIG_UNMAXIMIZED, ""},
346 {SIG_IOERR, ""},
347 {SIG_INDICATOR_PROP_CHANGED, ""},
348 {SIG_ROTATION_CHANGED, ""},
349 {SIG_PROFILE_CHANGED, ""},
350 {SIG_WM_ROTATION_CHANGED, ""},
351 {SIG_WIDGET_FOCUSED, ""}, /**< handled by elm_widget */
352 {SIG_WIDGET_UNFOCUSED, ""}, /**< handled by elm_widget */
353 {NULL, NULL}
354 };
355
356 static Eina_Bool _key_action_return(Evas_Object *obj, const char *params);
357 static Eina_Bool _key_action_move(Evas_Object *obj, const char *params);
358
359 static const Elm_Action key_actions[] = {
360 {"return", _key_action_return},
361 {"move", _key_action_move},
362 {NULL, NULL}
363 };
364
365 Eina_List *_elm_win_list = NULL;
366 int _elm_win_deferred_free = 0;
367 static Eina_Value exit_on_all_windows_closed;
368
369 static Eina_Bool _elm_win_throttle_ok = EINA_FALSE;
370 static int _elm_win_count = 0;
371
372 static Eina_Bool _elm_win_auto_throttled = EINA_FALSE;
373
374 static Ecore_Timer *_elm_win_state_eval_timer = NULL;
375
376 static void _elm_win_legacy_init(Efl_Ui_Win_Data *sd);
377 static void
378 _elm_win_on_resize_obj_changed_size_hints(void *data,
379 Evas *e,
380 Evas_Object *obj,
381 void *event_info);
382 static void
383 _elm_win_img_callbacks_del(Evas_Object *obj, Evas_Object *imgobj);
384 static Eina_Error _elm_win_theme_internal(Eo *obj, Efl_Ui_Win_Data *sd);
385 static void _elm_win_frame_add(Efl_Ui_Win_Data *sd, const char *element, const char *style);
386 static void _elm_win_frame_style_update(Efl_Ui_Win_Data *sd, Eina_Bool force_emit, Eina_Bool calc);
387 static inline void _elm_win_need_frame_adjust(Efl_Ui_Win_Data *sd, const char *engine);
388 static void _elm_win_resize_objects_eval(Evas_Object *obj, Eina_Bool force_resize);
389 static void _elm_win_frame_obj_update(Efl_Ui_Win_Data *sd, Eina_Bool force);
390 static void _ee_backbone_init(Efl_Ui_Win *obj, Efl_Ui_Win_Data *pd);
391 static void _ee_backbone_shutdown(Efl_Ui_Win *obj, Efl_Ui_Win_Data *pd);
392
393 static inline Efl_Ui_Win_Type
_elm_win_type_to_efl_ui_win_type(Elm_Win_Type type)394 _elm_win_type_to_efl_ui_win_type(Elm_Win_Type type)
395 {
396 switch (type)
397 {
398 #define CONVERT_TYPE(TYPE) case ELM_WIN_##TYPE: return EFL_UI_WIN_TYPE_##TYPE
399 CONVERT_TYPE(BASIC);
400 CONVERT_TYPE(DIALOG_BASIC);
401 CONVERT_TYPE(DESKTOP);
402 CONVERT_TYPE(DOCK);
403 CONVERT_TYPE(TOOLBAR);
404 CONVERT_TYPE(MENU);
405 CONVERT_TYPE(UTILITY);
406 CONVERT_TYPE(SPLASH);
407 CONVERT_TYPE(DROPDOWN_MENU);
408 CONVERT_TYPE(POPUP_MENU);
409 CONVERT_TYPE(TOOLTIP);
410 CONVERT_TYPE(NOTIFICATION);
411 CONVERT_TYPE(COMBO);
412 CONVERT_TYPE(DND);
413 CONVERT_TYPE(INLINED_IMAGE);
414 CONVERT_TYPE(SOCKET_IMAGE);
415 CONVERT_TYPE(FAKE);
416 CONVERT_TYPE(NAVIFRAME_BASIC);
417 default: break;
418 }
419 return EFL_UI_WIN_TYPE_UNKNOWN;
420 #undef CONVERT_TYPE
421 }
422
423 static inline Elm_Win_Type
_efl_ui_win_type_to_elm_win_type(Efl_Ui_Win_Type type)424 _efl_ui_win_type_to_elm_win_type(Efl_Ui_Win_Type type)
425 {
426 switch (type)
427 {
428 #define CONVERT_TYPE(TYPE) case EFL_UI_WIN_TYPE_##TYPE: return ELM_WIN_##TYPE
429 CONVERT_TYPE(BASIC);
430 CONVERT_TYPE(DIALOG_BASIC);
431 CONVERT_TYPE(DESKTOP);
432 CONVERT_TYPE(DOCK);
433 CONVERT_TYPE(TOOLBAR);
434 CONVERT_TYPE(MENU);
435 CONVERT_TYPE(UTILITY);
436 CONVERT_TYPE(SPLASH);
437 CONVERT_TYPE(DROPDOWN_MENU);
438 CONVERT_TYPE(POPUP_MENU);
439 CONVERT_TYPE(TOOLTIP);
440 CONVERT_TYPE(NOTIFICATION);
441 CONVERT_TYPE(COMBO);
442 CONVERT_TYPE(DND);
443 CONVERT_TYPE(INLINED_IMAGE);
444 CONVERT_TYPE(SOCKET_IMAGE);
445 CONVERT_TYPE(FAKE);
446 CONVERT_TYPE(NAVIFRAME_BASIC);
447 default: break;
448 }
449 return ELM_WIN_UNKNOWN;
450 #undef CONVERT_TYPE
451 }
452
453 #ifdef HAVE_ELEMENTARY_X
454 static void _elm_win_xwin_update(Efl_Ui_Win_Data *sd);
455 #endif
456
457 EAPI double _elm_startup_time = 0;
458
459 static void
_elm_win_first_frame_do(void * data,Evas * e EINA_UNUSED,void * event_info EINA_UNUSED)460 _elm_win_first_frame_do(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
461 {
462 double end = ecore_time_unix_get();
463 char *first = data;
464
465 switch (*first)
466 {
467 case 'A': abort();
468 case 'E':
469 case 'D': exit(-1);
470 case 'T': fprintf(stderr, "Startup time: '%f' - '%f' = '%f' sec\n", end, _elm_startup_time, end - _elm_startup_time);
471 break;
472 }
473
474 evas_event_callback_del_full(e, EVAS_CALLBACK_RENDER_POST, _elm_win_first_frame_do, data);
475 }
476
477 Ecore_X_Window
_elm_ee_xwin_get(const Ecore_Evas * ee)478 _elm_ee_xwin_get(const Ecore_Evas *ee)
479 {
480 #ifdef HAVE_ELEMENTARY_X
481 const char *engine_name;
482 if (!ee) return 0;
483
484 engine_name = ecore_evas_engine_name_get(ee);
485 if (EINA_UNLIKELY(!engine_name)) return 0;
486
487 if (!strcmp(engine_name, ELM_SOFTWARE_X11))
488 {
489 return ecore_evas_software_x11_window_get(ee);
490 }
491 else if (!strcmp(engine_name, ELM_OPENGL_X11))
492 {
493 return ecore_evas_gl_x11_window_get(ee);
494 }
495 #else
496 (void)ee;
497 #endif
498 return 0;
499 }
500
501 #ifdef HAVE_ELEMENTARY_X
502 static void
_internal_elm_win_xwindow_get(Efl_Ui_Win_Data * sd)503 _internal_elm_win_xwindow_get(Efl_Ui_Win_Data *sd)
504 {
505 Ecore_X_Window pwin = sd->x.xwin;
506 sd->x.xwin = _elm_ee_xwin_get(sd->ee);
507 if (sd->x.xwin != pwin)
508 {
509 char buf[128];
510
511 snprintf(buf, sizeof(buf), "%x", sd->x.xwin);
512 eina_stringshare_del(sd->stack_id);
513 sd->stack_id = eina_stringshare_add(buf);
514 }
515 }
516 #endif
517
518 Ecore_Wl2_Window *
_elm_ee_wlwin_get(const Ecore_Evas * ee)519 _elm_ee_wlwin_get(const Ecore_Evas *ee)
520 {
521 #ifdef HAVE_ELEMENTARY_WL2
522 const char *engine_name;
523
524 if (!ee) return NULL;
525
526 engine_name = ecore_evas_engine_name_get(ee);
527 if (EINA_UNLIKELY(!engine_name)) return NULL;
528
529 if ((!strcmp(engine_name, ELM_WAYLAND_SHM)) ||
530 (!strcmp(engine_name, ELM_WAYLAND_EGL)))
531 {
532 return ecore_evas_wayland2_window_get(ee);
533 }
534 #else
535 (void)ee;
536 #endif
537 return NULL;
538 }
539
540 static void
_win_noblank_eval(void)541 _win_noblank_eval(void)
542 {
543 #ifdef HAVE_ELEMENTARY_X
544 Eina_List *l;
545 Evas_Object *obj;
546 int noblanks = 0;
547 Eina_Bool change = EINA_FALSE;
548
549 EINA_LIST_FOREACH(_elm_win_list, l, obj)
550 {
551 ELM_WIN_DATA_GET(obj, sd);
552
553 if (sd->x.xwin)
554 {
555 _internal_elm_win_xwindow_get(sd);
556 if ((sd->noblank) && (!sd->minimized) && (!sd->withdrawn) &&
557 evas_object_visible_get(obj))
558 noblanks++;
559
560 change = EINA_TRUE;
561 }
562 }
563
564 if (!change) return;
565
566 if (noblanks > 0) ecore_x_screensaver_suspend();
567 else ecore_x_screensaver_resume();
568 #endif
569 #ifdef HAVE_ELEMENTARY_WL2
570 // XXX: no wl implementation of this yet - maybe higher up at prop level
571 #endif
572 }
573
574 static Elm_Process_State _elm_process_state = ELM_PROCESS_STATE_FOREGROUND;
575
576 EAPI Elm_Process_State
elm_process_state_get(void)577 elm_process_state_get(void)
578 {
579 return _elm_process_state;
580 }
581
582 static void
_elm_win_apply_alpha(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)583 _elm_win_apply_alpha(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
584 {
585 Eina_Bool enabled;
586
587 if (!sd->ee) return;
588
589 enabled = sd->theme_alpha | sd->application_alpha;
590 if (sd->img_obj)
591 {
592 evas_object_image_alpha_set(sd->img_obj, enabled);
593 ecore_evas_alpha_set(sd->ee, enabled);
594 }
595 else
596 {
597 #ifdef HAVE_ELEMENTARY_X
598 if (sd->x.xwin)
599 {
600 _internal_elm_win_xwindow_get(sd);
601 enabled |= (sd->csd.need && !sd->fullscreen);
602 if (!ecore_x_screen_is_composited(0))
603 {
604 if (enabled || (!sd->x.shaped))
605 TRAP(sd, shaped_set, enabled);
606 }
607 else
608 TRAP(sd, alpha_set, enabled);
609 }
610 else
611 #else
612 (void)obj;
613 #endif
614 TRAP(sd, alpha_set, enabled);
615 }
616 }
617
618 /* auto norender withdrawn is really only for X11.
619 * On other backends like wayland, there's actually
620 * no way for a client to tell if the window is
621 * minimized or not. You can request minimized state
622 * but there's no explicit feedback for minimization
623 * or return to normal state.
624 *
625 * So, blocking drawing based on client side thinking
626 * it's minimized, and having the compositor think
627 * the client should be drawing will lead to
628 * predictably disappointing results.
629 *
630 * If you maintain a backend that is really capable
631 * of handling this properly, feel free to extend
632 * the whitelist.
633 */
634 static Eina_Bool
_elm_win_auto_norender_withdrawn(const Evas_Object * obj)635 _elm_win_auto_norender_withdrawn(const Evas_Object *obj)
636 {
637 const char *engine;
638 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
639
640 if (!sd)
641 return _elm_config->auto_norender_withdrawn;
642
643 engine = ecore_evas_engine_name_get(sd->ee);
644 if (!strcmp(engine, ELM_SOFTWARE_X11) || !strcmp(engine, ELM_OPENGL_X11))
645 return _elm_config->auto_norender_withdrawn;
646
647 return EINA_FALSE;
648 }
649
650
651 static Eina_Bool
_elm_win_state_eval(void * data EINA_UNUSED)652 _elm_win_state_eval(void *data EINA_UNUSED)
653 {
654 Eina_List *l;
655 Evas_Object *obj;
656 int _elm_win_count_shown = 0;
657 int _elm_win_count_minimized = 0;
658 int _elm_win_count_withdrawn = 0;
659 Eina_Bool throttle = EINA_FALSE;
660
661 _elm_win_state_eval_timer = NULL;
662
663 EINA_LIST_FOREACH(_elm_win_list, l, obj)
664 {
665 if (_elm_win_auto_norender_withdrawn(obj))
666 {
667 if ((elm_win_withdrawn_get(obj)) ||
668 ((elm_win_iconified_get(obj) &&
669 (_elm_config->auto_norender_iconified_same_as_withdrawn))))
670 {
671 if (!evas_object_data_get(obj, "__win_auto_norender"))
672 {
673 Evas *evas = evas_object_evas_get(obj);
674
675 elm_win_norender_push(obj);
676 evas_object_data_set(obj, "__win_auto_norender", obj);
677
678 if (_elm_config->auto_flush_withdrawn)
679 {
680 edje_file_cache_flush();
681 edje_collection_cache_flush();
682 evas_image_cache_flush(evas);
683 evas_font_cache_flush(evas);
684 }
685 if (_elm_config->auto_dump_withdrawn)
686 {
687 evas_render_dump(evas);
688 }
689 }
690
691 if (elm_win_iconified_get(obj))
692 efl_event_callback_call(obj, EFL_UI_WIN_EVENT_PAUSE, NULL);
693 continue;
694 }
695 }
696 if (evas_object_data_get(obj, "__win_auto_norender"))
697 {
698 elm_win_norender_pop(obj);
699 evas_object_data_del(obj, "__win_auto_norender");
700 }
701 }
702 if (((_elm_config->auto_throttle) &&
703 (elm_policy_get(ELM_POLICY_THROTTLE) != ELM_POLICY_THROTTLE_NEVER)) ||
704 (elm_policy_get(ELM_POLICY_THROTTLE) == ELM_POLICY_THROTTLE_HIDDEN_ALWAYS))
705 throttle = EINA_TRUE;
706 if (_elm_win_count == 0)
707 {
708 if ((_elm_win_throttle_ok) && (_elm_win_auto_throttled))
709 {
710 _elm_process_state = ELM_PROCESS_STATE_FOREGROUND;
711 ecore_event_add(ELM_EVENT_PROCESS_FOREGROUND, NULL, NULL, NULL);
712 if (throttle)
713 ecore_throttle_adjust(-_elm_config->auto_throttle_amount);
714 _elm_win_auto_throttled = EINA_FALSE;
715 }
716 }
717 else
718 {
719 EINA_LIST_FOREACH(_elm_win_list, l, obj)
720 {
721 if (elm_win_withdrawn_get(obj)) _elm_win_count_withdrawn++;
722 else if (elm_win_iconified_get(obj)) _elm_win_count_minimized++;
723 else if (evas_object_visible_get(obj)) _elm_win_count_shown++;
724 }
725 if (_elm_win_count_shown <= 0)
726 {
727 if ((_elm_win_throttle_ok) && (!_elm_win_auto_throttled))
728 {
729 _elm_process_state = ELM_PROCESS_STATE_BACKGROUND;
730 ecore_event_add(ELM_EVENT_PROCESS_BACKGROUND, NULL, NULL, NULL);
731 if (throttle)
732 ecore_throttle_adjust(_elm_config->auto_throttle_amount);
733 _elm_win_auto_throttled = EINA_TRUE;
734 }
735 }
736 else
737 {
738 if ((_elm_win_throttle_ok) && (_elm_win_auto_throttled))
739 {
740 _elm_process_state = ELM_PROCESS_STATE_FOREGROUND;
741 ecore_event_add(ELM_EVENT_PROCESS_FOREGROUND, NULL, NULL, NULL);
742 if (throttle)
743 ecore_throttle_adjust(-_elm_config->auto_throttle_amount);
744 _elm_win_auto_throttled = EINA_FALSE;
745 }
746 }
747 }
748 _win_noblank_eval();
749 return EINA_FALSE;
750 }
751
752 static Eina_Bool
_elm_win_policy_quit_triggered(Eo * triggering_obj)753 _elm_win_policy_quit_triggered(Eo* triggering_obj)
754 {
755 if (elm_policy_get(ELM_POLICY_QUIT) == ELM_POLICY_QUIT_LAST_WINDOW_HIDDEN)
756 {
757 Eina_List *l;
758 Evas_Object *win;
759
760 EINA_LIST_FOREACH(_elm_win_list, l, win)
761 if (win != triggering_obj && evas_object_visible_get(win) == EINA_TRUE)
762 {
763 return EINA_FALSE;
764 }
765 return EINA_TRUE;
766 }
767
768 return EINA_FALSE;
769 }
770
771 static void
_elm_win_flush_cache_and_exit(Eo * obj)772 _elm_win_flush_cache_and_exit(Eo *obj)
773 {
774 edje_file_cache_flush();
775 edje_collection_cache_flush();
776 evas_image_cache_flush(evas_object_evas_get(obj));
777 evas_font_cache_flush(evas_object_evas_get(obj));
778 elm_exit();
779 }
780
781 static void
_elm_win_state_eval_queue(void)782 _elm_win_state_eval_queue(void)
783 {
784 if (_elm_win_state_eval_timer) ecore_timer_del(_elm_win_state_eval_timer);
785 _elm_win_state_eval_timer = ecore_timer_add(0.5, _elm_win_state_eval, NULL);
786 }
787
788 // example shot spec (wait 0.1 sec then save as my-window.png):
789 // ELM_ENGINE="shot:delay=0.1:file=my-window.png"
790
791 static double
_shot_delay_get(Efl_Ui_Win_Data * sd)792 _shot_delay_get(Efl_Ui_Win_Data *sd)
793 {
794 char *p, *pd;
795 char *d = strdup(sd->shot.info);
796
797 if (!d) return 0.5;
798 for (p = (char *)sd->shot.info; *p; p++)
799 {
800 if (!strncmp(p, "delay=", 6))
801 {
802 double v;
803
804 for (pd = d, p += 6; (*p) && (*p != ':'); p++, pd++)
805 {
806 *pd = *p;
807 }
808 *pd = 0;
809 v = _elm_atof(d);
810 free(d);
811 return v;
812 }
813 }
814 free(d);
815
816 return 0.5;
817 }
818
819 static char *
_shot_file_get(Efl_Ui_Win_Data * sd)820 _shot_file_get(Efl_Ui_Win_Data *sd)
821 {
822 char *p;
823 char *tmp = strdup(sd->shot.info);
824 char *repname = NULL;
825
826 if (!tmp) return NULL;
827
828 for (p = (char *)sd->shot.info; *p; p++)
829 {
830 if (!strncmp(p, "file=", 5))
831 {
832 strcpy(tmp, p + 5);
833 if (!sd->shot.repeat_count) return tmp;
834 else
835 {
836 char *dotptr = strrchr(tmp, '.');
837 if (dotptr)
838 {
839 size_t size = sizeof(char) * (strlen(tmp) + 16);
840 repname = malloc(size);
841 if (repname)
842 {
843 strncpy(repname, tmp, dotptr - tmp);
844 snprintf(repname + (dotptr - tmp), size -
845 (dotptr - tmp), "%03i",
846 sd->shot.shot_counter + 1);
847 strcat(repname, dotptr);
848 }
849 free(tmp);
850 return repname;
851 }
852 }
853 }
854 }
855 free(tmp);
856 if (!sd->shot.repeat_count) return strdup("out.png");
857
858 repname = malloc(sizeof(char) * 24);
859 if (!repname) return NULL;
860 snprintf(repname, sizeof(char) * 24, "out%03i.png",
861 sd->shot.shot_counter + 1);
862
863 return repname;
864 }
865
866 static int
_shot_repeat_count_get(Efl_Ui_Win_Data * sd)867 _shot_repeat_count_get(Efl_Ui_Win_Data *sd)
868 {
869 char *p, *pd;
870 char *d = strdup(sd->shot.info);
871
872 if (!d) return 0;
873 for (p = (char *)sd->shot.info; *p; p++)
874 {
875 if (!strncmp(p, "repeat=", 7))
876 {
877 int v;
878
879 for (pd = d, p += 7; (*p) && (*p != ':'); p++, pd++)
880 {
881 *pd = *p;
882 }
883 *pd = 0;
884 v = atoi(d);
885 if (v < 0) v = 0;
886 if (v > 1000) v = 999;
887 free(d);
888 return v;
889 }
890 }
891 free(d);
892
893 return 0;
894 }
895
896 static char *
_shot_key_get(Efl_Ui_Win_Data * sd EINA_UNUSED)897 _shot_key_get(Efl_Ui_Win_Data *sd EINA_UNUSED)
898 {
899 return NULL;
900 }
901
902 static char *
_shot_flags_get(Efl_Ui_Win_Data * sd EINA_UNUSED)903 _shot_flags_get(Efl_Ui_Win_Data *sd EINA_UNUSED)
904 {
905 return NULL;
906 }
907
908 static void
_shot_do(Efl_Ui_Win_Data * sd)909 _shot_do(Efl_Ui_Win_Data *sd)
910 {
911 Ecore_Evas *ee;
912 Evas_Object *o;
913 unsigned int *pixels;
914 int w, h;
915 char *file, *key, *flags;
916
917 ecore_evas_manual_render(sd->ee);
918 pixels = (void *)ecore_evas_buffer_pixels_get(sd->ee);
919 if (!pixels) return;
920
921 ecore_evas_geometry_get(sd->ee, NULL, NULL, &w, &h);
922 if ((w < 1) || (h < 1)) return;
923
924 file = _shot_file_get(sd);
925 if (!file) return;
926
927 key = _shot_key_get(sd);
928 flags = _shot_flags_get(sd);
929 ee = ecore_evas_buffer_new(1, 1);
930 o = evas_object_image_add(ecore_evas_get(ee));
931 evas_object_image_alpha_set(o,
932 sd->theme_alpha | sd->application_alpha);
933 evas_object_image_size_set(o, w, h);
934 evas_object_image_data_set(o, pixels);
935 if (!evas_object_image_save(o, file, key, flags))
936 {
937 ERR("Cannot save window to '%s' (key '%s', flags '%s')",
938 file, key, flags);
939 }
940 free(file);
941 free(key);
942 free(flags);
943 ecore_evas_free(ee);
944 if (sd->shot.repeat_count) sd->shot.shot_counter++;
945 }
946
947 static Eina_Bool
_shot_delay(void * data)948 _shot_delay(void *data)
949 {
950 ELM_WIN_DATA_GET(data, sd);
951
952 _shot_do(sd);
953 if (sd->shot.repeat_count)
954 {
955 int remainshot = (sd->shot.repeat_count - sd->shot.shot_counter);
956 if (remainshot > 0) return EINA_TRUE;
957 }
958 sd->shot.timer = NULL;
959 elm_exit();
960
961 return EINA_FALSE;
962 }
963
964 static void
_shot_init(Efl_Ui_Win_Data * sd)965 _shot_init(Efl_Ui_Win_Data *sd)
966 {
967 if (!sd->shot.info) return;
968
969 sd->shot.repeat_count = _shot_repeat_count_get(sd);
970 sd->shot.shot_counter = 0;
971 }
972
973 static void
_shot_handle(Efl_Ui_Win_Data * sd)974 _shot_handle(Efl_Ui_Win_Data *sd)
975 {
976 if (!sd->shot.info) return;
977
978 if (!sd->shot.timer)
979 sd->shot.timer = ecore_timer_add(_shot_delay_get(sd), _shot_delay,
980 sd->obj);
981 }
982
983 /* elm-win specific associate, does the trap while ecore_evas_object_associate()
984 * does not.
985 */
986 static Efl_Ui_Win_Data *
_elm_win_associate_get(const Ecore_Evas * ee)987 _elm_win_associate_get(const Ecore_Evas *ee)
988 {
989 Evas_Object *obj = ecore_evas_data_get(ee, "elm_win");
990 return efl_data_scope_safe_get(obj, MY_CLASS);
991 }
992
993 /* Interceptors Callbacks */
994 static void
_elm_win_obj_intercept_raise(void * data,Evas_Object * obj EINA_UNUSED)995 _elm_win_obj_intercept_raise(void *data, Evas_Object *obj EINA_UNUSED)
996 {
997 // Note: This is probably not necessary anymore (Win implements raise)
998 ELM_WIN_DATA_GET(data, sd);
999 TRAP(sd, raise);
1000 }
1001
1002 static void
_elm_win_obj_intercept_lower(void * data,Evas_Object * obj EINA_UNUSED)1003 _elm_win_obj_intercept_lower(void *data, Evas_Object *obj EINA_UNUSED)
1004 {
1005 // Note: This is probably not necessary anymore (Win ignores lower)
1006 ELM_WIN_DATA_GET(data, sd);
1007 TRAP(sd, lower);
1008 }
1009
1010 static void
_elm_win_obj_intercept_stack_above(void * data EINA_UNUSED,Evas_Object * obj EINA_UNUSED,Evas_Object * above EINA_UNUSED)1011 _elm_win_obj_intercept_stack_above(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, Evas_Object *above EINA_UNUSED)
1012 {
1013 INF("TODO: %s", __func__);
1014 }
1015
1016 static void
_elm_win_obj_intercept_stack_below(void * data EINA_UNUSED,Evas_Object * obj EINA_UNUSED,Evas_Object * below EINA_UNUSED)1017 _elm_win_obj_intercept_stack_below(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, Evas_Object *below EINA_UNUSED)
1018 {
1019 INF("TODO: %s", __func__);
1020 }
1021
1022 static void
_elm_win_obj_intercept_layer_set(void * data,Evas_Object * obj EINA_UNUSED,int l)1023 _elm_win_obj_intercept_layer_set(void *data, Evas_Object *obj EINA_UNUSED, int l)
1024 {
1025 ELM_WIN_DATA_GET(data, sd);
1026 TRAP(sd, layer_set, l);
1027 }
1028
1029 /* Event Callbacks */
1030
1031 static void
_elm_win_size_hints_update(Efl_Ui_Win * win,Efl_Ui_Win_Data * sd)1032 _elm_win_size_hints_update(Efl_Ui_Win *win, Efl_Ui_Win_Data *sd)
1033 {
1034 Eina_Size2D min, max;
1035
1036 min = efl_gfx_hint_size_combined_min_get(win);
1037 max = efl_gfx_hint_size_combined_max_get(win);
1038 if (max.w < 1) max.w = -1;
1039 if (max.h < 1) max.h = -1;
1040
1041 TRAP(sd, size_min_set, min.w, min.h);
1042 TRAP(sd, size_max_set, max.w, max.h);
1043 }
1044
1045 static void
_elm_win_obj_callback_changed_size_hints(void * data EINA_UNUSED,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info EINA_UNUSED)1046 _elm_win_obj_callback_changed_size_hints(void *data EINA_UNUSED, Evas *e EINA_UNUSED,
1047 Evas_Object *obj, void *event_info EINA_UNUSED)
1048 {
1049 ELM_WIN_DATA_GET(obj, sd);
1050
1051 if (sd->tmp_updating_hints) return;
1052 _elm_win_size_hints_update(obj, sd);
1053 }
1054 /* end of elm-win specific associate */
1055
1056 static void
_elm_win_move(Ecore_Evas * ee)1057 _elm_win_move(Ecore_Evas *ee)
1058 {
1059 Efl_Ui_Win_Data *sd = _elm_win_associate_get(ee);
1060 int x, y;
1061 Eo *obj;
1062 Eina_Position2D pos;
1063
1064 if (!sd) return;
1065 obj = sd->obj;
1066
1067 ecore_evas_geometry_get(ee, &x, &y, NULL, NULL);
1068 pos.x = sd->screen.x = x;
1069 pos.y = sd->screen.y = y;
1070 efl_event_callback_call(sd->obj, EFL_GFX_ENTITY_EVENT_POSITION_CHANGED, &pos);
1071 evas_object_smart_callback_call(sd->obj, "move", NULL);
1072 ELM_WIN_DATA_ALIVE_CHECK(obj, sd);
1073 evas_nochange_push(evas_object_evas_get(sd->obj));
1074 sd->response++;
1075 sd->req_xy = EINA_FALSE;
1076 evas_object_move(sd->obj, x, y);
1077 ELM_WIN_DATA_ALIVE_CHECK(obj, sd);
1078 sd->response--;
1079 evas_nochange_pop(evas_object_evas_get(sd->obj));
1080 }
1081
1082 static void
_elm_win_resize_job(void * data)1083 _elm_win_resize_job(void *data)
1084 {
1085 ELM_WIN_DATA_GET(data, sd);
1086 int w, h;
1087
1088 sd->deferred_resize_job = EINA_FALSE;
1089 ecore_evas_geometry_get(sd->ee, NULL, NULL, &w, &h);
1090 if (sd->constrain)
1091 {
1092 int sw, sh;
1093 ecore_evas_screen_geometry_get(sd->ee, NULL, NULL, &sw, &sh);
1094 w = MIN(w, sw);
1095 h = MIN(h, sh);
1096 }
1097
1098 if (sd->frame_obj)
1099 {
1100 int fx, fy, fw, fh;
1101
1102 evas_output_framespace_get(sd->evas, &fx, &fy, &fw, &fh);
1103 evas_object_geometry_set(sd->frame_obj, -fx, -fy, w + fw, h + fh);
1104 }
1105
1106 if (sd->main_menu)
1107 {
1108 Eina_Position2D pos;
1109
1110 pos = efl_gfx_entity_position_get(sd->main_menu);
1111 elm_menu_move(sd->main_menu, pos.x, pos.y);
1112 }
1113
1114 sd->response++;
1115 sd->req_wh = EINA_FALSE;
1116 evas_object_resize(sd->obj, w, h);
1117 evas_object_resize(sd->legacy.edje, w, h);
1118 sd->response--;
1119 }
1120
1121 static void
_elm_win_pre_render(Ecore_Evas * ee)1122 _elm_win_pre_render(Ecore_Evas *ee)
1123 {
1124 Efl_Ui_Win_Data *sd = _elm_win_associate_get(ee);
1125 Eo *obj;
1126
1127 if (!sd) return;
1128 obj = sd->obj;
1129
1130 _elm_win_throttle_ok = EINA_TRUE;
1131 if (!sd->first_draw)
1132 {
1133 int mw, mh;
1134
1135 if (sd->type != EFL_UI_WIN_TYPE_FAKE)
1136 {
1137 edje_object_thaw(sd->frame_obj);
1138 evas_object_show(sd->frame_obj);
1139 }
1140
1141 _elm_win_frame_style_update(sd, 1, 1);
1142 ELM_WIN_DATA_ALIVE_CHECK(obj, sd);
1143
1144 if (sd->frame_obj)
1145 {
1146 /* force initial sizing on frame to enable sizing of content */
1147 edje_object_size_min_calc(sd->frame_obj, &mw, &mh);
1148 evas_object_resize(sd->frame_obj, mw, mh);
1149 }
1150
1151 if (sd->img_obj)
1152 {
1153 evas_object_show(sd->img_obj);
1154 }
1155 if (sd->pointer.obj) evas_object_show(sd->pointer.obj);
1156 #ifdef ELEMENTARY_X
1157 if (sd->type == ELM_WIN_TOOLTIP)
1158 {
1159 _internal_elm_win_xwindow_get(sd);
1160 ecore_x_window_shape_input_rectangle_set(sd->x.xwin, 0, 0, 0, 0);
1161 }
1162 #endif
1163 sd->first_draw = EINA_TRUE;
1164 /* set this to handle ecore-evas engine code which incorrectly
1165 * assumes that a client resize call is the same as a server resize
1166 * event, or which has no server event
1167 */
1168 sd->deferred_resize_job = EINA_TRUE;
1169 }
1170 if (sd->deferred_resize_job)
1171 {
1172 _elm_win_resize_job(sd->obj);
1173 _elm_win_frame_obj_update(sd, 1);
1174 }
1175 }
1176
1177 static void
_elm_win_resize(Ecore_Evas * ee)1178 _elm_win_resize(Ecore_Evas *ee)
1179 {
1180 Efl_Ui_Win_Data *sd = _elm_win_associate_get(ee);
1181 if (!sd) return;
1182
1183 sd->deferred_resize_job = EINA_TRUE;
1184 }
1185
1186 static void
_elm_win_mouse_in(Ecore_Evas * ee)1187 _elm_win_mouse_in(Ecore_Evas *ee)
1188 {
1189 Efl_Ui_Win_Data *sd = _elm_win_associate_get(ee);
1190 if (!sd) return;
1191
1192 _elm_win_throttle_ok = EINA_TRUE;
1193 sd->resizing = EINA_FALSE;
1194 #ifdef HAVE_ELEMENTARY_WL2
1195 if ((sd->wl.win) && (sd->pointer.ee))
1196 {
1197 sd->pointer.visible = EINA_TRUE;
1198 sd->pointer.surf = ecore_wl2_window_surface_get(sd->pointer.win);
1199 _elm_win_wl_cursor_set(sd->obj, NULL);
1200 //ELM_WIN_DATA_ALIVE_CHECK(obj, sd);
1201 }
1202 #endif
1203 }
1204
1205 static void
_elm_win_mouse_out(Ecore_Evas * ee)1206 _elm_win_mouse_out(Ecore_Evas *ee)
1207 {
1208 Efl_Ui_Win_Data *sd = _elm_win_associate_get(ee);
1209 if (!sd) return;
1210
1211 #ifdef HAVE_ELEMENTARY_WL2
1212 if ((sd->wl.win) && (sd->pointer.ee))
1213 sd->pointer.visible = EINA_FALSE;
1214 #endif
1215 }
1216
1217 static void
_elm_win_focus_highlight_reconfigure_job_stop(Efl_Ui_Win_Data * sd)1218 _elm_win_focus_highlight_reconfigure_job_stop(Efl_Ui_Win_Data *sd)
1219 {
1220 ELM_SAFE_FREE(sd->focus_highlight.reconf_job, ecore_job_del);
1221 }
1222
1223 static void
_elm_win_focus_highlight_visible_set(Efl_Ui_Win_Data * sd,Eina_Bool visible)1224 _elm_win_focus_highlight_visible_set(Efl_Ui_Win_Data *sd,
1225 Eina_Bool visible)
1226 {
1227 Evas_Object *fobj = sd->focus_highlight.fobj;
1228 if (!fobj) return;
1229
1230 if (visible)
1231 {
1232 evas_object_show(fobj);
1233 if (elm_widget_is_legacy(sd->obj))
1234 edje_object_signal_emit(fobj, "elm,action,focus,show", "elm");
1235 else
1236 edje_object_signal_emit(fobj, "efl,focus,visible,on", "efl");
1237 }
1238 else
1239 {
1240 if (elm_widget_is_legacy(sd->obj))
1241 edje_object_signal_emit(fobj, "elm,action,focus,hide", "elm");
1242 else
1243 edje_object_signal_emit(fobj, "efl,focus,visible,off", "efl");
1244 }
1245 }
1246
1247 Evas_Object *
_elm_win_focus_highlight_object_get(Evas_Object * obj)1248 _elm_win_focus_highlight_object_get(Evas_Object *obj)
1249 {
1250 ELM_WIN_DATA_GET(obj, sd);
1251
1252 return sd->focus_highlight.fobj;
1253 }
1254
1255 static void
_elm_win_focus_highlight_anim_setup(Efl_Ui_Win_Data * sd,Evas_Object * obj)1256 _elm_win_focus_highlight_anim_setup(Efl_Ui_Win_Data *sd,
1257 Evas_Object *obj)
1258 {
1259 Eina_Rect rt, rp;
1260 Edje_Message_Int_Set *m;
1261 Evas_Object *target = sd->focus_highlight.cur.target;
1262
1263 rp = efl_gfx_entity_geometry_get(obj);
1264 rt = elm_widget_focus_highlight_geometry_get(target);
1265 efl_gfx_entity_geometry_set(obj, rt);
1266
1267 if (eina_rectangle_equal(&rp.rect, &rt.rect)) return;
1268
1269 if (!_elm_config->focus_highlight_clip_disable)
1270 evas_object_clip_unset(obj);
1271
1272 m = alloca(sizeof(*m) + (sizeof(int) * 8));
1273 m->count = 8;
1274 m->val[0] = rp.x - rt.x;
1275 m->val[1] = rp.y - rt.y;
1276 m->val[2] = rp.w;
1277 m->val[3] = rp.h;
1278 m->val[4] = 0;
1279 m->val[5] = 0;
1280 m->val[6] = rt.w;
1281 m->val[7] = rt.h;
1282 edje_object_message_send(obj, EDJE_MESSAGE_INT_SET, 1, m);
1283 }
1284
1285 static void
_elm_win_focus_highlight_simple_setup(Efl_Ui_Win_Data * sd,Evas_Object * obj)1286 _elm_win_focus_highlight_simple_setup(Efl_Ui_Win_Data *sd,
1287 Evas_Object *obj)
1288 {
1289 Evas_Object *clip, *target = sd->focus_highlight.cur.target;
1290
1291 efl_gfx_entity_geometry_set(obj, elm_widget_focus_highlight_geometry_get(target));
1292
1293 if (!_elm_config->focus_highlight_clip_disable)
1294 {
1295 clip = evas_object_clip_get(target);
1296 if (clip) evas_object_clip_set(obj, clip);
1297 }
1298
1299 if (elm_widget_is_legacy(sd->obj))
1300 edje_object_signal_emit(obj, "elm,state,anim,stop", "elm");
1301 else
1302 edje_object_signal_emit(obj, "efl,state,animating,stopped", "efl");
1303 }
1304
1305 static void
_elm_win_focus_prev_target_del(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)1306 _elm_win_focus_prev_target_del(void *data,
1307 Evas *e EINA_UNUSED,
1308 Evas_Object *obj EINA_UNUSED,
1309 void *event_info EINA_UNUSED)
1310 {
1311 ELM_WIN_DATA_GET(data, sd);
1312 sd->focus_highlight.prev.target = NULL;
1313 }
1314
1315 static void
_elm_win_focus_highlight_reconfigure_job(void * data)1316 _elm_win_focus_highlight_reconfigure_job(void *data)
1317 {
1318 ELM_WIN_DATA_GET(data, sd);
1319 Evas_Object *target = sd->focus_highlight.cur.target;
1320 Evas_Object *previous = sd->focus_highlight.prev.target;
1321 Evas_Object *fobj = sd->focus_highlight.fobj;
1322 Eina_Bool visible_changed;
1323 Eina_Bool common_visible;
1324 const char *sig = NULL;
1325
1326 _elm_win_focus_highlight_reconfigure_job_stop(sd);
1327
1328 visible_changed = (sd->focus_highlight.cur.visible !=
1329 sd->focus_highlight.prev.visible);
1330
1331 if ((target == previous) && (!visible_changed) &&
1332 (!sd->focus_highlight.geometry_changed) &&
1333 (!sd->focus_highlight.theme_changed))
1334 return;
1335
1336 if (previous)
1337 {
1338 evas_object_event_callback_del_full
1339 (previous, EVAS_CALLBACK_DEL, _elm_win_focus_prev_target_del, data);
1340 if (sd->focus_highlight.prev.in_theme)
1341 {
1342 if (elm_widget_is_legacy(sd->obj))
1343 elm_widget_signal_emit
1344 (previous, "elm,action,focus_highlight,hide", "elm");
1345 else
1346 elm_widget_signal_emit
1347 (previous, "efl,action,focus_highlight,hide", "efl");
1348 }
1349 }
1350
1351 if (!target)
1352 common_visible = EINA_FALSE;
1353 else if (sd->focus_highlight.cur.in_theme)
1354 {
1355 common_visible = EINA_FALSE;
1356
1357 if (elm_widget_is_legacy(sd->obj))
1358 {
1359 if (sd->focus_highlight.cur.visible)
1360 sig = "elm,action,focus_highlight,show";
1361 else
1362 sig = "elm,action,focus_highlight,hide";
1363 }
1364 else
1365 {
1366 if (sd->focus_highlight.cur.visible)
1367 sig = "efl,action,focus_highlight,show";
1368 else
1369 sig = "efl,action,focus_highlight,hide";
1370 }
1371 }
1372 else
1373 common_visible = sd->focus_highlight.cur.visible;
1374
1375 if (sig)
1376 {
1377 if (elm_widget_is_legacy(sd->obj))
1378 elm_widget_signal_emit(target, sig, "elm");
1379 else
1380 elm_widget_signal_emit(target, sig, "efl");
1381 }
1382
1383 if ((!target) || (!common_visible) || (sd->focus_highlight.cur.in_theme))
1384 {
1385 if (target)
1386 _elm_win_focus_highlight_simple_setup(sd, fobj);
1387 goto the_end;
1388 }
1389
1390 if (sd->focus_highlight.theme_changed)
1391 {
1392 const char *str;
1393
1394 if (sd->focus_highlight.style)
1395 str = sd->focus_highlight.style;
1396 else
1397 str = "default";
1398
1399 elm_widget_theme_object_set
1400 (sd->obj, fobj, "focus_highlight", "top", str);
1401 sd->focus_highlight.theme_changed = EINA_FALSE;
1402
1403 if ((sd->focus_highlight.animate) || (sd->focus_highlight.auto_animate))
1404 {
1405 str = edje_object_data_get(sd->focus_highlight.fobj, "animate");
1406 sd->focus_highlight.animate_supported = ((str) && (!strcmp(str, "on")));
1407 }
1408 else
1409 sd->focus_highlight.animate_supported = EINA_FALSE;
1410 }
1411
1412 if ((sd->focus_highlight.animate_supported) && (previous) &&
1413 (!sd->focus_highlight.prev.in_theme))
1414 _elm_win_focus_highlight_anim_setup(sd, fobj);
1415 else
1416 _elm_win_focus_highlight_simple_setup(sd, fobj);
1417 evas_object_raise(fobj);
1418
1419 the_end:
1420 _elm_win_focus_highlight_visible_set(sd, common_visible);
1421 sd->focus_highlight.geometry_changed = EINA_FALSE;
1422 sd->focus_highlight.prev = sd->focus_highlight.cur;
1423 if (sd->focus_highlight.prev.target)
1424 {
1425 evas_object_event_callback_add
1426 (sd->focus_highlight.prev.target,
1427 EVAS_CALLBACK_DEL, _elm_win_focus_prev_target_del, data);
1428 }
1429 }
1430
1431 static void
_elm_win_focus_highlight_reconfigure_job_start(Efl_Ui_Win_Data * sd)1432 _elm_win_focus_highlight_reconfigure_job_start(Efl_Ui_Win_Data *sd)
1433 {
1434 ecore_job_del(sd->focus_highlight.reconf_job);
1435
1436 sd->focus_highlight.reconf_job = ecore_job_add(
1437 _elm_win_focus_highlight_reconfigure_job, sd->obj);
1438 }
1439
1440 static void
_elm_win_focus_in(Ecore_Evas * ee)1441 _elm_win_focus_in(Ecore_Evas *ee)
1442 {
1443 Efl_Ui_Win_Data *sd = _elm_win_associate_get(ee);
1444 Evas_Object *obj;
1445
1446 if ((!sd) || (sd->modal_count)) return;
1447
1448 _elm_win_throttle_ok = EINA_TRUE;
1449 obj = sd->obj;
1450
1451 _elm_widget_top_win_focused_set(obj, EINA_TRUE);
1452 ELM_WIN_DATA_ALIVE_CHECK(obj, sd);
1453 if (sd->type != EFL_UI_WIN_TYPE_FAKE)
1454 {
1455 Efl_Ui_Focus_Manager *man = sd->obj;
1456 while(efl_ui_focus_manager_redirect_get(man))
1457 {
1458 man = efl_ui_focus_manager_redirect_get(man);
1459 }
1460
1461 Evas_Object *focused = efl_ui_focus_manager_focus_get(man);
1462 if (focused)
1463 efl_ui_focus_object_focus_set(focused, EINA_TRUE);
1464 }
1465
1466 evas_object_smart_callback_call(obj, SIG_FOCUS_IN, NULL);
1467 evas_object_smart_callback_call(obj, SIG_WIDGET_FOCUSED, NULL);
1468 ELM_WIN_DATA_ALIVE_CHECK(obj, sd);
1469 sd->focus_highlight.cur.visible = EINA_TRUE;
1470 _elm_win_focus_highlight_reconfigure_job_start(sd);
1471 _elm_win_frame_style_update(sd, 0, 1);
1472
1473 if (_elm_config->atspi_mode)
1474 {
1475 efl_access_window_activated_signal_emit(obj);
1476 efl_access_state_changed_signal_emit(obj, EFL_ACCESS_STATE_TYPE_ACTIVE, EINA_TRUE);
1477 }
1478
1479 /* do nothing */
1480 /* else if (sd->img_obj) */
1481 /* { */
1482 /* } */
1483 if ((!efl_ui_focus_manager_focus_get(sd->obj)) &&
1484 (!efl_ui_focus_manager_redirect_get(sd->obj)))
1485 {
1486 Efl_Ui_Focus_Object *child;
1487
1488 child = efl_ui_focus_manager_request_subchild(sd->obj, sd->obj);
1489
1490 if (child)
1491 efl_ui_focus_manager_focus_set(sd->obj, sd->obj);
1492 else if (!evas_focus_get(evas_object_evas_get(sd->obj)))
1493 evas_object_focus_set(obj, EINA_TRUE);
1494 }
1495 }
1496
1497 static void
_elm_win_focus_out(Ecore_Evas * ee)1498 _elm_win_focus_out(Ecore_Evas *ee)
1499 {
1500 Efl_Ui_Win_Data *sd = _elm_win_associate_get(ee);
1501 Evas_Object *obj;
1502
1503 if (!sd) return;
1504
1505 obj = sd->obj;
1506
1507 _elm_widget_top_win_focused_set(obj, EINA_FALSE);
1508 ELM_WIN_DATA_ALIVE_CHECK(obj, sd);
1509 evas_object_smart_callback_call(obj, SIG_FOCUS_OUT, NULL);
1510 evas_object_smart_callback_call(obj, SIG_WIDGET_UNFOCUSED, NULL);
1511 ELM_WIN_DATA_ALIVE_CHECK(obj, sd);
1512 sd->focus_highlight.cur.visible = EINA_FALSE;
1513 _elm_win_focus_highlight_reconfigure_job_start(sd);
1514 if (!sd->resizing)
1515 _elm_win_frame_style_update(sd, 0, 1);
1516
1517 /* access */
1518 _elm_access_object_highlight_disable(evas_object_evas_get(obj));
1519
1520 if (_elm_config->atspi_mode)
1521 {
1522 efl_access_window_deactivated_signal_emit(obj);
1523 efl_access_state_changed_signal_emit(obj, EFL_ACCESS_STATE_TYPE_ACTIVE, EINA_FALSE);
1524 }
1525
1526 if (sd->type != EFL_UI_WIN_TYPE_FAKE)
1527 {
1528 Efl_Ui_Focus_Manager *man = sd->obj;
1529 while(efl_ui_focus_manager_redirect_get(man))
1530 {
1531 man = efl_ui_focus_manager_redirect_get(man);
1532 }
1533
1534 Evas_Object *focused = efl_ui_focus_manager_focus_get(man);
1535 efl_ui_focus_object_focus_set(focused, EINA_FALSE);
1536 }
1537 /* do nothing */
1538 /* if (sd->img_obj) */
1539 /* { */
1540 /* } */
1541 }
1542
1543 static void
_elm_win_available_profiles_del(Efl_Ui_Win_Data * sd)1544 _elm_win_available_profiles_del(Efl_Ui_Win_Data *sd)
1545 {
1546 Eina_Stringshare *prof;
1547 Eina_Iterator *it;
1548
1549 it = eina_array_iterator_new(sd->profile.available);
1550 EINA_ITERATOR_FOREACH(it, prof)
1551 eina_stringshare_del(prof);
1552 eina_iterator_free(it);
1553 eina_array_flush(sd->profile.available);
1554 }
1555
1556 static void
_elm_win_profile_del(Efl_Ui_Win_Data * sd)1557 _elm_win_profile_del(Efl_Ui_Win_Data *sd)
1558 {
1559 ELM_SAFE_FREE(sd->profile.name, eina_stringshare_del);
1560 }
1561
1562 static Eina_Bool
_internal_elm_win_profile_set(Efl_Ui_Win_Data * sd,const char * profile)1563 _internal_elm_win_profile_set(Efl_Ui_Win_Data *sd, const char *profile)
1564 {
1565 Eina_Bool changed = EINA_FALSE;
1566
1567 if (profile == sd->profile.name) return EINA_FALSE;
1568 if (profile)
1569 {
1570 if (eina_stringshare_replace(&sd->profile.name, profile))
1571 changed = EINA_TRUE;
1572 }
1573 else
1574 _elm_win_profile_del(sd);
1575
1576 return changed;
1577 }
1578
1579 static inline Eina_Bool
_profile_exists(Efl_Ui_Win_Data * sd,const char * profile)1580 _profile_exists(Efl_Ui_Win_Data *sd, const char *profile)
1581 {
1582 Eina_Bool found = EINA_FALSE;
1583 Eina_Stringshare *prof;
1584 Eina_Iterator *it;
1585
1586 if (!profile) return EINA_FALSE;
1587 it = eina_array_iterator_new(sd->profile.available);
1588 EINA_ITERATOR_FOREACH(it, prof)
1589 if (!strcmp(profile, prof))
1590 {
1591 found = EINA_TRUE;
1592 break;
1593 }
1594 eina_iterator_free(it);
1595 return found;
1596 }
1597
1598 static void
_elm_win_profile_update(Efl_Ui_Win_Data * sd)1599 _elm_win_profile_update(Efl_Ui_Win_Data *sd)
1600 {
1601 if (getenv("ELM_PROFILE")) return;
1602
1603 if (eina_array_count(sd->profile.available))
1604 {
1605 Eina_Bool found = _profile_exists(sd, sd->profile.name);
1606
1607 /* If current profile is not present in an available profiles,
1608 * change current profile to the 1st element of an array.
1609 */
1610 if (!found)
1611 _internal_elm_win_profile_set(sd, eina_array_data_get(sd->profile.available, 0));
1612 }
1613
1614 _config_profile_lock = EINA_TRUE;
1615 _elm_config_profile_set(sd->profile.name);
1616
1617 /* update sub ee */
1618 Ecore_Evas *ee2;
1619 Eina_List *sub, *l = NULL;
1620
1621 sub = ecore_evas_sub_ecore_evas_list_get(sd->ee);
1622 EINA_LIST_FOREACH(sub, l, ee2)
1623 ecore_evas_window_profile_set(ee2, sd->profile.name);
1624
1625 efl_event_callback_legacy_call(sd->obj, EFL_UI_WIN_EVENT_PROFILE_CHANGED, NULL);
1626 }
1627
1628 static inline void
_elm_win_frame_geometry_adjust(Efl_Ui_Win_Data * sd)1629 _elm_win_frame_geometry_adjust(Efl_Ui_Win_Data *sd)
1630 {
1631 int l = 0, t = 0, r = 0, b = 0;
1632
1633 if (sd->frame_obj && sd->csd.need && !sd->fullscreen)
1634 {
1635 int fw, fh, ox, oy, ow, oh;
1636 evas_object_geometry_get(sd->frame_obj, NULL, NULL, &fw, &fh);
1637 sd->ignore_frame_resize++;
1638 evas_object_resize(sd->frame_obj, 1000, 1000);
1639 if (elm_widget_is_legacy(sd->obj))
1640 edje_object_part_geometry_get(sd->frame_obj, "elm.spacer.opaque",
1641 &ox, &oy, &ow, &oh);
1642 else
1643 edje_object_part_geometry_get(sd->frame_obj, "efl.spacer.opaque",
1644 &ox, &oy, &ow, &oh);
1645 evas_object_resize(sd->frame_obj, fw, fh);
1646 sd->ignore_frame_resize--;
1647 fw = 1000; fh = 1000;
1648 l = ox;
1649 t = oy;
1650 r = fw - ow - l;
1651 b = fh - oh - t;
1652 if (l < 0) l = 0;
1653 if (r < 0) r = 0;
1654 if (t < 0) t = 0;
1655 if (b < 0) b = 0;
1656 }
1657 ecore_evas_shadow_geometry_set(sd->ee, l, r, t, b);
1658 }
1659
1660 static inline Eina_Bool
_elm_win_framespace_set(Efl_Ui_Win_Data * sd,int x,int y,int w,int h)1661 _elm_win_framespace_set(Efl_Ui_Win_Data *sd, int x, int y, int w, int h)
1662 {
1663 int fx, fy, fw, fh;
1664
1665 evas_output_framespace_get(sd->evas, &fx, &fy, &fw, &fh);
1666 evas_output_framespace_set(sd->evas, x, y, w, h);
1667
1668 // return true if framespace geometry changed
1669 return ((fx != x) || (fy != y) || (fw != w) || (fh != h));
1670 }
1671
1672 static void
_elm_win_frame_obj_update(Efl_Ui_Win_Data * sd,Eina_Bool force)1673 _elm_win_frame_obj_update(Efl_Ui_Win_Data *sd, Eina_Bool force)
1674 {
1675 int ox, oy, ow, oh;
1676 int cx, cy, cw, ch;
1677 int w, h;
1678 int l, r, t, b;
1679
1680 if (!sd->frame_obj) return;
1681 if (!sd->csd.need) return;
1682 _elm_win_frame_geometry_adjust(sd);
1683 ecore_evas_shadow_geometry_get(sd->ee, &l, &r, &t, &b);
1684 sd->ignore_frame_resize++;
1685 evas_object_geometry_get(sd->frame_obj, &ox, &oy, &ow, &oh);
1686 evas_object_resize(sd->frame_obj, 1000, 1000);
1687 if (elm_widget_is_legacy(sd->obj))
1688 edje_object_part_geometry_get(sd->frame_obj, "elm.spacer.content", &cx, &cy, &cw, &ch);
1689 else
1690 edje_object_part_geometry_get(sd->frame_obj, "efl.spacer.content", &cx, &cy, &cw, &ch);
1691 evas_object_resize(sd->frame_obj, ow, oh);
1692 sd->ignore_frame_resize--;
1693 if (!_elm_win_framespace_set(sd, cx, cy, 1000 - cw, 1000 - ch) && (!force)) return;
1694 _elm_win_frame_geometry_adjust(sd);
1695
1696 if (!sd->first_draw) return;
1697
1698 evas_object_geometry_get(sd->obj, NULL, NULL, &w, &h);
1699 if (w && h)
1700 {
1701 TRAP(sd, resize, w, h);
1702 }
1703 }
1704
1705 static int
_win_rotation_degree_check(int rotation)1706 _win_rotation_degree_check(int rotation)
1707 {
1708 if ((rotation > 360) || (rotation < 0))
1709 {
1710 WRN("Rotation degree should be 0 ~ 360 (passed degree: %d)", rotation);
1711 rotation %= 360;
1712 if (rotation < 0) rotation += 360;
1713 }
1714 return rotation;
1715 }
1716
1717 /*
1718 * This API resizes the internal window(ex: X window) and evas_output.
1719 * But this does not resize the elm window object and its contents.
1720 */
1721 static void
_win_rotate(Evas_Object * obj,Efl_Ui_Win_Data * sd,int rotation,Eina_Bool resize)1722 _win_rotate(Evas_Object *obj, Efl_Ui_Win_Data *sd, int rotation, Eina_Bool resize)
1723 {
1724 rotation = _win_rotation_degree_check(rotation);
1725 if (sd->rot == rotation) return;
1726 sd->rot = rotation;
1727 if (resize) TRAP(sd, rotation_with_resize_set, rotation);
1728 else TRAP(sd, rotation_set, rotation);
1729 efl_gfx_hint_size_restricted_min_set(obj, EINA_SIZE2D(-1, -1));
1730 efl_gfx_hint_size_restricted_max_set(obj, EINA_SIZE2D(-1, -1));
1731 _elm_win_resize_objects_eval(obj, EINA_FALSE);
1732 #ifdef HAVE_ELEMENTARY_X
1733 _elm_win_xwin_update(sd);
1734 #endif
1735 _elm_win_frame_obj_update(sd, 0);
1736 efl_event_callback_call
1737 (obj, EFL_UI_WIN_EVENT_WIN_ROTATION_CHANGED, &rotation);
1738 evas_object_smart_callback_call(obj, "rotation,changed", NULL);
1739 if (_elm_config->atspi_mode)
1740 {
1741 Evas_Coord x = 0, y = 0, width = 0, height = 0;
1742 elm_win_screen_size_get(obj, &x, &y, &width, &height);
1743 if ((sd->rot == 0) || (sd->rot == 180))
1744 {
1745 efl_access_bounds_changed_signal_emit(obj, x, y, width, height);
1746 }
1747 else
1748 {
1749 efl_access_bounds_changed_signal_emit(obj, x, y, height, width);
1750 }
1751 }
1752 }
1753
1754 EOLIAN static void
_efl_ui_win_win_rotation_set(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * pd,int rotation)1755 _efl_ui_win_win_rotation_set(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *pd, int rotation)
1756 {
1757 Efl_Ui_Widget *widget;
1758 Eina_Iterator *it;
1759 int rot = rotation %360;
1760
1761 if (pd->rot == rot) return;
1762
1763 _win_rotate(obj, pd, rot, EINA_FALSE);
1764
1765 it = efl_ui_widget_tree_widget_iterator(obj);
1766 EINA_ITERATOR_FOREACH(it, widget)
1767 {
1768 if (!efl_isa(widget, EFL_UI_LAYOUT_BASE_CLASS)) continue;
1769
1770 if (efl_ui_layout_automatic_theme_rotation_get(widget))
1771 efl_ui_layout_theme_rotation_apply(widget, rot);
1772 }
1773 }
1774
1775 EOLIAN static int
_efl_ui_win_win_rotation_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * pd)1776 _efl_ui_win_win_rotation_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *pd)
1777 {
1778 return pd->rot;
1779 }
1780
1781 EAPI void
elm_win_rotation_set(Evas_Object * obj,int rotation)1782 elm_win_rotation_set(Evas_Object *obj, int rotation)
1783 {
1784 efl_ui_win_rotation_set(obj, rotation);
1785 }
1786
1787 EAPI int
elm_win_rotation_get(const Evas_Object * obj)1788 elm_win_rotation_get(const Evas_Object *obj)
1789 {
1790 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, -1);
1791 return efl_ui_win_rotation_get(obj);
1792 }
1793
1794 static void
_elm_win_state_change(Ecore_Evas * ee)1795 _elm_win_state_change(Ecore_Evas *ee)
1796 {
1797 Efl_Ui_Win_Data *sd = _elm_win_associate_get(ee);
1798 Evas_Object *obj;
1799 Eina_Bool ch_withdrawn = EINA_FALSE;
1800 Eina_Bool ch_sticky = EINA_FALSE;
1801 Eina_Bool ch_minimized = EINA_FALSE;
1802 Eina_Bool ch_fullscreen = EINA_FALSE;
1803 Eina_Bool ch_maximized = EINA_FALSE;
1804 Eina_Bool ch_profile = EINA_FALSE;
1805 Eina_Bool ch_wm_rotation = EINA_FALSE;
1806 const char *profile;
1807
1808 if (!sd) return;
1809
1810 obj = sd->obj;
1811
1812 if (sd->withdrawn != ecore_evas_withdrawn_get(sd->ee))
1813 {
1814 sd->withdrawn = ecore_evas_withdrawn_get(sd->ee);
1815 ch_withdrawn = EINA_TRUE;
1816 }
1817 if (sd->sticky != ecore_evas_sticky_get(sd->ee))
1818 {
1819 sd->sticky = ecore_evas_sticky_get(sd->ee);
1820 ch_sticky = EINA_TRUE;
1821 }
1822 if (sd->minimized != ecore_evas_iconified_get(sd->ee))
1823 {
1824 sd->minimized = ecore_evas_iconified_get(sd->ee);
1825 ch_minimized = EINA_TRUE;
1826 }
1827 if (sd->fullscreen != ecore_evas_fullscreen_get(sd->ee))
1828 {
1829 sd->fullscreen = ecore_evas_fullscreen_get(sd->ee);
1830 ch_fullscreen = EINA_TRUE;
1831 }
1832 if (sd->maximized != ecore_evas_maximized_get(sd->ee))
1833 {
1834 sd->maximized = ecore_evas_maximized_get(sd->ee);
1835 ch_maximized = EINA_TRUE;
1836 }
1837
1838 if (ecore_evas_window_profile_supported_get(sd->ee))
1839 {
1840 profile = ecore_evas_window_profile_get(sd->ee);
1841 ch_profile = _internal_elm_win_profile_set(sd, profile);
1842 }
1843
1844 ELM_WIN_DATA_ALIVE_CHECK(obj, sd);
1845 if (sd->wm_rot.use)
1846 {
1847 if (sd->rot != ecore_evas_rotation_get(sd->ee))
1848 {
1849 ch_wm_rotation = EINA_TRUE;
1850 }
1851 }
1852
1853 _elm_win_state_eval_queue();
1854
1855 if ((ch_withdrawn) || (ch_minimized))
1856 {
1857 ELM_WIN_DATA_ALIVE_CHECK(obj, sd);
1858 if (sd->withdrawn)
1859 efl_event_callback_legacy_call(obj, EFL_UI_WIN_EVENT_WITHDRAWN, NULL);
1860 else if (sd->minimized)
1861 {
1862 efl_event_callback_call(obj, EFL_UI_WIN_EVENT_MINIMIZED, NULL);
1863 evas_object_smart_callback_call(obj, "iconified", NULL);
1864 if (_elm_config->atspi_mode)
1865 efl_access_window_minimized_signal_emit(obj);
1866 }
1867 else
1868 {
1869 efl_event_callback_legacy_call(obj, EFL_UI_WIN_EVENT_NORMAL, NULL);
1870 if (_elm_config->atspi_mode)
1871 efl_access_window_restored_signal_emit(obj);
1872 }
1873 }
1874 if (ch_sticky)
1875 {
1876 if (sd->sticky)
1877 efl_event_callback_legacy_call(obj, EFL_UI_WIN_EVENT_STICK, NULL);
1878 else
1879 efl_event_callback_legacy_call(obj, EFL_UI_WIN_EVENT_UNSTICK, NULL);
1880 }
1881 #ifdef HAVE_ELEMENTARY_WL2
1882 if (sd->wl.win)
1883 {
1884 if (sd->csd.cur_focus != ecore_wl2_window_activated_get(sd->wl.win))
1885 _elm_win_frame_style_update(sd, 0, 1);
1886 }
1887 #endif
1888 if (ch_fullscreen)
1889 {
1890 Eina_Bool fullscreen;
1891 ELM_WIN_DATA_ALIVE_CHECK(obj, sd);
1892 _elm_win_frame_style_update(sd, 0, 1);
1893 fullscreen = sd->fullscreen;
1894 if (sd->fullscreen)
1895 {
1896 evas_object_smart_callback_call(obj, "fullscreen", NULL);
1897 }
1898 else
1899 {
1900 evas_object_smart_callback_call(obj, "unfullscreen", NULL);
1901 }
1902 efl_event_callback_call(obj, EFL_UI_WIN_EVENT_FULLSCREEN_CHANGED, &fullscreen);
1903 }
1904 if (ch_maximized)
1905 {
1906 Eina_Bool maximized;
1907 ELM_WIN_DATA_ALIVE_CHECK(obj, sd);
1908 _elm_win_frame_style_update(sd, 0, 1);
1909 maximized = sd->maximized;
1910 if (sd->maximized)
1911 {
1912 evas_object_smart_callback_call(obj, "maximized", NULL);
1913 if (_elm_config->atspi_mode)
1914 efl_access_window_maximized_signal_emit(obj);
1915 }
1916 else
1917 {
1918 evas_object_smart_callback_call(obj, "unmaximized", NULL);
1919 if (_elm_config->atspi_mode)
1920 efl_access_window_restored_signal_emit(obj);
1921 }
1922 efl_event_callback_call(obj, EFL_UI_WIN_EVENT_MAXIMIZED_CHANGED, &maximized);
1923 }
1924 if (ch_profile)
1925 {
1926 ELM_WIN_DATA_ALIVE_CHECK(obj, sd);
1927 _elm_win_profile_update(sd);
1928 }
1929 if (ch_wm_rotation)
1930 {
1931 efl_ui_win_rotation_set(obj, ecore_evas_rotation_get(sd->ee));
1932
1933 efl_event_callback_legacy_call
1934 (obj, EFL_UI_WIN_EVENT_WM_ROTATION_CHANGED, NULL);
1935 }
1936 }
1937
1938 EOLIAN static Eina_Bool
_efl_ui_win_efl_ui_focus_object_on_focus_update(Eo * obj,Efl_Ui_Win_Data * sd)1939 _efl_ui_win_efl_ui_focus_object_on_focus_update(Eo *obj, Efl_Ui_Win_Data *sd)
1940 {
1941 if (!efl_ui_focus_object_on_focus_update(efl_super(obj, MY_CLASS)))
1942 return EINA_TRUE;
1943
1944 if (sd->img_obj)
1945 evas_object_focus_set(sd->img_obj, efl_ui_focus_object_focus_get(obj));
1946 else
1947 evas_object_focus_set(obj, efl_ui_focus_object_focus_get(obj));
1948
1949 return EINA_TRUE;
1950 }
1951
1952 static Eina_Bool
_key_action_return(Evas_Object * obj EINA_UNUSED,const char * params EINA_UNUSED)1953 _key_action_return(Evas_Object *obj EINA_UNUSED, const char *params EINA_UNUSED)
1954 {
1955 return EINA_FALSE;
1956 }
1957
1958 static Eina_Bool
_key_action_move(Evas_Object * obj,const char * params)1959 _key_action_move(Evas_Object *obj, const char *params)
1960 {
1961 const char *dir = params;
1962
1963 _elm_widget_focus_auto_show(obj);
1964
1965 Efl_Ui_Focus_Direction focus_dir;
1966
1967 if (!strcmp(dir, "previous"))
1968 focus_dir = EFL_UI_FOCUS_DIRECTION_PREVIOUS;
1969 else if (!strcmp(dir, "next"))
1970 focus_dir = EFL_UI_FOCUS_DIRECTION_NEXT;
1971 else if (!strcmp(dir, "left"))
1972 focus_dir = EFL_UI_FOCUS_DIRECTION_LEFT;
1973 else if (!strcmp(dir, "right"))
1974 focus_dir = EFL_UI_FOCUS_DIRECTION_RIGHT;
1975 else if (!strcmp(dir, "up"))
1976 focus_dir = EFL_UI_FOCUS_DIRECTION_UP;
1977 else if (!strcmp(dir, "down"))
1978 focus_dir = EFL_UI_FOCUS_DIRECTION_DOWN;
1979 else return EINA_FALSE;
1980
1981
1982 // The handling for legacy is different due to elm_object_next set
1983 if (elm_widget_is_legacy(obj))
1984 elm_object_focus_next(obj, (Elm_Focus_Direction)focus_dir);
1985 else
1986 {
1987 Efl_Ui_Widget *o;
1988
1989 o = efl_ui_focus_manager_move(obj, focus_dir);
1990 if (!o)
1991 {
1992 if (focus_dir == EFL_UI_FOCUS_DIRECTION_NEXT || focus_dir == EFL_UI_FOCUS_DIRECTION_PREVIOUS)
1993 {
1994 Efl_Ui_Focus_Object *root;
1995
1996 root = efl_ui_focus_manager_root_get(obj);
1997 efl_ui_focus_manager_setup_on_first_touch(obj, focus_dir, root);
1998 }
1999 }
2000 }
2001
2002 return EINA_TRUE;
2003 }
2004
2005 /* forward events sent to evas to the window */
2006 static void
_evas_event_key_cb(void * data,const Efl_Event * ev)2007 _evas_event_key_cb(void *data, const Efl_Event *ev)
2008 {
2009 Eo *win = data;
2010 Eo *evt = ev->info;
2011 Efl_Input_Key_Data *evdata;
2012
2013 evdata = efl_data_scope_get(evt, EFL_INPUT_KEY_CLASS);
2014 if (!evdata || evdata->win_fed)
2015 return;
2016
2017 // evas_callbacks will send the event to the focused object (ie. this win)
2018 if (evas_focus_get(evas_object_evas_get(win)) == win)
2019 return;
2020
2021 efl_event_callback_call(win, ev->desc, evt);
2022 }
2023
2024 static void
_evas_event_pointer_cb(void * data,const Efl_Event * ev)2025 _evas_event_pointer_cb(void *data, const Efl_Event *ev)
2026 {
2027 Eo *win = data;
2028 Eo *evt = ev->info;
2029 Efl_Input_Pointer_Data *evdata;
2030
2031 evdata = efl_data_scope_get(evt, EFL_INPUT_POINTER_CLASS);
2032 if (!evdata || evdata->win_fed)
2033 return;
2034
2035 efl_event_callback_call(win, ev->desc, evt);
2036 }
2037
2038 /* feed events from the window to evas - for fake inputs */
2039 static void
_evas_event_key_feed_fake_cb(void * data,const Efl_Event * ev)2040 _evas_event_key_feed_fake_cb(void *data, const Efl_Event *ev)
2041 {
2042 Eo *evas = data;
2043 Efl_Input_Event *evt = ev->info;
2044 Efl_Input_Key_Data *evdata;
2045
2046 if (!efl_input_fake_get(evt))
2047 return;
2048
2049 evdata = efl_data_scope_get(evt, EFL_INPUT_KEY_CLASS);
2050 if (!evdata || evdata->win_fed)
2051 return;
2052 evdata->win_fed = EINA_TRUE;
2053
2054 efl_event_callback_call(evas, ev->desc, evt);
2055 evdata->win_fed = EINA_FALSE;
2056 evdata->evas_done = EINA_FALSE;
2057 }
2058
2059 static void
_evas_event_pointer_feed_fake_cb(void * data,const Efl_Event * ev)2060 _evas_event_pointer_feed_fake_cb(void *data, const Efl_Event *ev)
2061 {
2062 Eo *evas = data;
2063 Efl_Input_Event *evt = ev->info;
2064 Efl_Input_Pointer_Data *evdata;
2065
2066 if (!efl_input_fake_get(evt))
2067 return;
2068
2069 evdata = efl_data_scope_get(evt, EFL_INPUT_POINTER_CLASS);
2070 if (!evdata || evdata->win_fed)
2071 return;
2072 evdata->win_fed = EINA_TRUE;
2073
2074 efl_event_callback_call(evas, ev->desc, evt);
2075 evdata->win_fed = EINA_FALSE;
2076 evdata->evas_done = EINA_FALSE;
2077 }
2078
2079 EFL_CALLBACKS_ARRAY_DEFINE(_elm_win_evas_feed_fake_callbacks,
2080 { EFL_EVENT_POINTER_MOVE, _evas_event_pointer_feed_fake_cb },
2081 { EFL_EVENT_POINTER_DOWN, _evas_event_pointer_feed_fake_cb },
2082 { EFL_EVENT_POINTER_UP, _evas_event_pointer_feed_fake_cb },
2083 { EFL_EVENT_POINTER_IN, _evas_event_pointer_feed_fake_cb },
2084 { EFL_EVENT_POINTER_OUT, _evas_event_pointer_feed_fake_cb },
2085 { EFL_EVENT_POINTER_CANCEL, _evas_event_pointer_feed_fake_cb },
2086 { EFL_EVENT_POINTER_WHEEL, _evas_event_pointer_feed_fake_cb },
2087 { EFL_EVENT_FINGER_MOVE, _evas_event_pointer_feed_fake_cb },
2088 { EFL_EVENT_FINGER_DOWN, _evas_event_pointer_feed_fake_cb },
2089 { EFL_EVENT_FINGER_UP, _evas_event_pointer_feed_fake_cb },
2090 { EFL_EVENT_KEY_DOWN, _evas_event_key_feed_fake_cb },
2091 { EFL_EVENT_KEY_UP, _evas_event_key_feed_fake_cb })
2092
2093 static void
_elm_win_evas_render_post(void * data,Evas * e EINA_UNUSED,void * event_info)2094 _elm_win_evas_render_post(void *data,
2095 Evas *e EINA_UNUSED,
2096 void *event_info)
2097 {
2098 Efl_Gfx_Event_Render_Post *ev = event_info;
2099 Eo *win = data;
2100
2101 efl_event_callback_call(win, EFL_CANVAS_SCENE_EVENT_RENDER_POST, ev);
2102 }
2103
2104 static void
_elm_win_evas_render_pre(void * data,Evas * e EINA_UNUSED,void * event_info EINA_UNUSED)2105 _elm_win_evas_render_pre(void *data,
2106 Evas *e EINA_UNUSED,
2107 void *event_info EINA_UNUSED)
2108 {
2109 Eo *win = data;
2110
2111 _elm_win_throttle_ok = EINA_TRUE;
2112 efl_event_callback_call(win, EFL_CANVAS_SCENE_EVENT_RENDER_PRE, NULL);
2113 }
2114
2115 static void
_elm_win_evas_focus_in(void * data,Evas * e EINA_UNUSED,void * event_info EINA_UNUSED)2116 _elm_win_evas_focus_in(void *data,
2117 Evas *e EINA_UNUSED,
2118 void *event_info EINA_UNUSED)
2119 {
2120 Eo *win = data;
2121
2122 _elm_win_throttle_ok = EINA_TRUE;
2123 efl_event_callback_call(win, EFL_CANVAS_SCENE_EVENT_SCENE_FOCUS_IN, NULL);
2124 }
2125
2126 static void
_elm_win_evas_focus_out(void * data,Evas * e EINA_UNUSED,void * event_info EINA_UNUSED)2127 _elm_win_evas_focus_out(void *data,
2128 Evas *e EINA_UNUSED,
2129 void *event_info EINA_UNUSED)
2130 {
2131 Eo *win = data;
2132
2133 efl_event_callback_call(win, EFL_CANVAS_SCENE_EVENT_SCENE_FOCUS_OUT, NULL);
2134 }
2135
2136 static void
_evas_event_focus_object_cb(void * data,const Efl_Event * ev)2137 _evas_event_focus_object_cb(void *data, const Efl_Event *ev)
2138 {
2139 Eo *win = data;
2140
2141 if (ev->desc == EFL_CANVAS_SCENE_EVENT_OBJECT_FOCUS_IN)
2142 _elm_win_throttle_ok = EINA_TRUE;
2143
2144 efl_event_callback_call(win, ev->desc, ev->info);
2145 }
2146
2147 static void
_elm_win_evas_device_changed(void * data,Evas * e EINA_UNUSED,void * event_info)2148 _elm_win_evas_device_changed(void *data,
2149 Evas *e EINA_UNUSED,
2150 void *event_info)
2151 {
2152 Eo *device = event_info;
2153 Eo *win = data;
2154
2155 efl_event_callback_call(win, EFL_CANVAS_SCENE_EVENT_DEVICE_CHANGED, device);
2156 }
2157
2158 static void
_win_event_add_cb(void * data,const Efl_Event * ev)2159 _win_event_add_cb(void *data, const Efl_Event *ev)
2160 {
2161 const Efl_Callback_Array_Item_Full *array = ev->info;
2162 Efl_Ui_Win_Data *sd = data;
2163 Efl_Ui_Win *win = ev->object;
2164 int i;
2165
2166 for (i = 0; array[i].desc; i++)
2167 {
2168 if (array[i].desc == EFL_EVENT_POINTER_MOVE)
2169 {
2170 if (!(sd->event_forward.pointer_move++))
2171 efl_event_callback_add(sd->evas, array[i].desc,
2172 _evas_event_pointer_cb, win);
2173 }
2174 else if (array[i].desc == EFL_EVENT_POINTER_DOWN)
2175 {
2176 if (!(sd->event_forward.pointer_down++))
2177 efl_event_callback_add(sd->evas, array[i].desc,
2178 _evas_event_pointer_cb, win);
2179 }
2180 else if (array[i].desc == EFL_EVENT_POINTER_UP)
2181 {
2182 if (!(sd->event_forward.pointer_up++))
2183 efl_event_callback_add(sd->evas, array[i].desc,
2184 _evas_event_pointer_cb, win);
2185 }
2186 else if (array[i].desc == EFL_EVENT_POINTER_IN)
2187 {
2188 if (!(sd->event_forward.pointer_in++))
2189 efl_event_callback_add(sd->evas, array[i].desc,
2190 _evas_event_pointer_cb, win);
2191 }
2192 else if (array[i].desc == EFL_EVENT_POINTER_OUT)
2193 {
2194 if (!(sd->event_forward.pointer_out++))
2195 efl_event_callback_add(sd->evas, array[i].desc,
2196 _evas_event_pointer_cb, win);
2197 }
2198 else if (array[i].desc == EFL_EVENT_POINTER_CANCEL)
2199 {
2200 if (!(sd->event_forward.pointer_cancel++))
2201 efl_event_callback_add(sd->evas, array[i].desc,
2202 _evas_event_pointer_cb, win);
2203 }
2204 else if (array[i].desc == EFL_EVENT_POINTER_WHEEL)
2205 {
2206 if (!(sd->event_forward.pointer_wheel++))
2207 efl_event_callback_add(sd->evas, array[i].desc,
2208 _evas_event_pointer_cb, win);
2209 }
2210 else if (array[i].desc == EFL_EVENT_FINGER_MOVE)
2211 {
2212 if (!(sd->event_forward.finger_move++))
2213 efl_event_callback_add(sd->evas, array[i].desc,
2214 _evas_event_pointer_cb, win);
2215 }
2216 else if (array[i].desc == EFL_EVENT_FINGER_DOWN)
2217 {
2218 if (!(sd->event_forward.finger_down++))
2219 efl_event_callback_add(sd->evas, array[i].desc,
2220 _evas_event_pointer_cb, win);
2221 }
2222 else if (array[i].desc == EFL_EVENT_FINGER_UP)
2223 {
2224 if (!(sd->event_forward.finger_up++))
2225 efl_event_callback_add(sd->evas, array[i].desc,
2226 _evas_event_pointer_cb, win);
2227 }
2228 else if (array[i].desc == EFL_EVENT_KEY_DOWN)
2229 {
2230 // Legacy API: Must grab key
2231 if (elm_widget_is_legacy(win)) return;
2232 if (!(sd->event_forward.key_down++))
2233 efl_event_callback_add(sd->evas, array[i].desc,
2234 _evas_event_key_cb, win);
2235 }
2236 else if (array[i].desc == EFL_EVENT_KEY_UP)
2237 {
2238 // Legacy API: Must grab key
2239 if (elm_widget_is_legacy(win)) return;
2240 if (!(sd->event_forward.key_up++))
2241 efl_event_callback_add(sd->evas, array[i].desc,
2242 _evas_event_key_cb, win);
2243 }
2244 else if (array[i].desc == EFL_CANVAS_SCENE_EVENT_RENDER_POST)
2245 {
2246 if (!(sd->event_forward.render_post++))
2247 evas_event_callback_add(sd->evas, EVAS_CALLBACK_RENDER_POST,
2248 _elm_win_evas_render_post, win);
2249 }
2250 else if (array[i].desc == EFL_CANVAS_SCENE_EVENT_RENDER_PRE)
2251 {
2252 if (!(sd->event_forward.render_pre++))
2253 evas_event_callback_add(sd->evas, EVAS_CALLBACK_RENDER_PRE,
2254 _elm_win_evas_render_pre, win);
2255 }
2256 else if (array[i].desc == EFL_CANVAS_SCENE_EVENT_SCENE_FOCUS_IN)
2257 {
2258 if (!(sd->event_forward.focus_in++))
2259 evas_event_callback_add(sd->evas, EVAS_CALLBACK_CANVAS_FOCUS_IN,
2260 _elm_win_evas_focus_in, win);
2261 }
2262 else if (array[i].desc == EFL_CANVAS_SCENE_EVENT_SCENE_FOCUS_OUT)
2263 {
2264 if (!(sd->event_forward.focus_out++))
2265 evas_event_callback_add(sd->evas, EVAS_CALLBACK_CANVAS_FOCUS_OUT,
2266 _elm_win_evas_focus_out, win);
2267 }
2268 else if (array[i].desc == EFL_CANVAS_SCENE_EVENT_OBJECT_FOCUS_IN)
2269 {
2270 if (!(sd->event_forward.object_focus_in++))
2271 efl_event_callback_add(sd->evas, EFL_CANVAS_SCENE_EVENT_OBJECT_FOCUS_IN,
2272 _evas_event_focus_object_cb, win);
2273 }
2274 else if (array[i].desc == EFL_CANVAS_SCENE_EVENT_OBJECT_FOCUS_OUT)
2275 {
2276 if (!(sd->event_forward.object_focus_out++))
2277 efl_event_callback_add(sd->evas, EFL_CANVAS_SCENE_EVENT_OBJECT_FOCUS_OUT,
2278 _evas_event_focus_object_cb, win);
2279 }
2280 else if (array[i].desc == EFL_CANVAS_SCENE_EVENT_DEVICE_CHANGED)
2281 {
2282 if (!(sd->event_forward.device_changed++))
2283 evas_event_callback_add(sd->evas, EVAS_CALLBACK_DEVICE_CHANGED,
2284 _elm_win_evas_device_changed, win);
2285 }
2286 }
2287 }
2288
2289 static void
_win_event_del_cb(void * data,const Efl_Event * ev)2290 _win_event_del_cb(void *data, const Efl_Event *ev)
2291 {
2292 const Efl_Callback_Array_Item_Full *array = ev->info;
2293 Efl_Ui_Win_Data *sd = data;
2294 Efl_Ui_Win *win = ev->object;
2295 int i;
2296
2297 for (i = 0; array[i].desc; i++)
2298 {
2299 if (array[i].desc == EFL_EVENT_POINTER_MOVE)
2300 {
2301 if (!(--sd->event_forward.pointer_move))
2302 efl_event_callback_del(sd->evas, array[i].desc,
2303 _evas_event_pointer_cb, win);
2304 }
2305 else if (array[i].desc == EFL_EVENT_POINTER_DOWN)
2306 {
2307 if (!(--sd->event_forward.pointer_down))
2308 efl_event_callback_del(sd->evas, array[i].desc,
2309 _evas_event_pointer_cb, win);
2310 }
2311 else if (array[i].desc == EFL_EVENT_POINTER_UP)
2312 {
2313 if (!(--sd->event_forward.pointer_up))
2314 efl_event_callback_del(sd->evas, array[i].desc,
2315 _evas_event_pointer_cb, win);
2316 }
2317 else if (array[i].desc == EFL_EVENT_POINTER_IN)
2318 {
2319 if (!(--sd->event_forward.pointer_in))
2320 efl_event_callback_del(sd->evas, array[i].desc,
2321 _evas_event_pointer_cb, win);
2322 }
2323 else if (array[i].desc == EFL_EVENT_POINTER_OUT)
2324 {
2325 if (!(--sd->event_forward.pointer_out))
2326 efl_event_callback_del(sd->evas, array[i].desc,
2327 _evas_event_pointer_cb, win);
2328 }
2329 else if (array[i].desc == EFL_EVENT_POINTER_CANCEL)
2330 {
2331 if (!(--sd->event_forward.pointer_cancel))
2332 efl_event_callback_del(sd->evas, array[i].desc,
2333 _evas_event_pointer_cb, win);
2334 }
2335 else if (array[i].desc == EFL_EVENT_POINTER_WHEEL)
2336 {
2337 if (!(--sd->event_forward.pointer_wheel))
2338 efl_event_callback_del(sd->evas, array[i].desc,
2339 _evas_event_pointer_cb, win);
2340 }
2341 else if (array[i].desc == EFL_EVENT_FINGER_MOVE)
2342 {
2343 if (!(--sd->event_forward.finger_move))
2344 efl_event_callback_del(sd->evas, array[i].desc,
2345 _evas_event_pointer_cb, win);
2346 }
2347 else if (array[i].desc == EFL_EVENT_FINGER_DOWN)
2348 {
2349 if (!(--sd->event_forward.finger_down))
2350 efl_event_callback_del(sd->evas, array[i].desc,
2351 _evas_event_pointer_cb, win);
2352 }
2353 else if (array[i].desc == EFL_EVENT_FINGER_UP)
2354 {
2355 if (!(--sd->event_forward.finger_up))
2356 efl_event_callback_del(sd->evas, array[i].desc,
2357 _evas_event_pointer_cb, win);
2358 }
2359 else if (array[i].desc == EFL_EVENT_KEY_DOWN)
2360 {
2361 // Legacy API: Must grab key
2362 if (elm_widget_is_legacy(win)) return;
2363 if (!(--sd->event_forward.key_down))
2364 efl_event_callback_del(sd->evas, array[i].desc,
2365 _evas_event_key_cb, win);
2366 }
2367 else if (array[i].desc == EFL_EVENT_KEY_UP)
2368 {
2369 // Legacy API: Must grab key
2370 if (elm_widget_is_legacy(win)) return;
2371 if (!(--sd->event_forward.key_up))
2372 efl_event_callback_del(sd->evas, array[i].desc,
2373 _evas_event_key_cb, win);
2374 }
2375 else if (array[i].desc == EFL_CANVAS_SCENE_EVENT_RENDER_POST)
2376 {
2377 if (!(--sd->event_forward.render_post))
2378 evas_event_callback_del_full(sd->evas, EVAS_CALLBACK_RENDER_POST,
2379 _elm_win_evas_render_post, win);
2380 }
2381 else if (array[i].desc == EFL_CANVAS_SCENE_EVENT_RENDER_PRE)
2382 {
2383 if (!(--sd->event_forward.render_pre))
2384 evas_event_callback_del_full(sd->evas, EVAS_CALLBACK_RENDER_PRE,
2385 _elm_win_evas_render_pre, win);
2386 }
2387 else if (array[i].desc == EFL_CANVAS_SCENE_EVENT_SCENE_FOCUS_IN)
2388 {
2389 if (!(--sd->event_forward.focus_in))
2390 evas_event_callback_del_full(sd->evas, EVAS_CALLBACK_FOCUS_IN,
2391 _elm_win_evas_focus_in, win);
2392 }
2393 else if (array[i].desc == EFL_CANVAS_SCENE_EVENT_SCENE_FOCUS_OUT)
2394 {
2395 if (!(--sd->event_forward.focus_out))
2396 evas_event_callback_del_full(sd->evas, EVAS_CALLBACK_FOCUS_OUT,
2397 _elm_win_evas_focus_out, win);
2398 }
2399 else if (array[i].desc == EFL_CANVAS_SCENE_EVENT_OBJECT_FOCUS_IN)
2400 {
2401 if (!(--sd->event_forward.object_focus_in))
2402 efl_event_callback_del(sd->evas, EFL_CANVAS_SCENE_EVENT_OBJECT_FOCUS_IN,
2403 _evas_event_focus_object_cb, win);
2404 }
2405 else if (array[i].desc == EFL_CANVAS_SCENE_EVENT_OBJECT_FOCUS_OUT)
2406 {
2407 if (!(--sd->event_forward.object_focus_out))
2408 efl_event_callback_del(sd->evas, EFL_CANVAS_SCENE_EVENT_OBJECT_FOCUS_OUT,
2409 _evas_event_focus_object_cb, win);
2410 }
2411 else if (array[i].desc == EFL_CANVAS_SCENE_EVENT_DEVICE_CHANGED)
2412 {
2413 if (!(--sd->event_forward.device_changed))
2414 evas_event_callback_del_full(sd->evas, EVAS_CALLBACK_DEVICE_CHANGED,
2415 _elm_win_evas_device_changed, win);
2416 }
2417 }
2418 }
2419
2420 static void
_win_paused(void * data,const Efl_Event * ev)2421 _win_paused(void *data, const Efl_Event *ev)
2422 {
2423 Efl_Ui_Win_Data *sd = data;
2424
2425 if (sd->paused)
2426 {
2427 ERR("A window did receive a pause event while still paused. Dismissing.");
2428 return ;
2429 }
2430 sd->paused = EINA_TRUE;
2431 _paused_windows++;
2432
2433 if (_elm_win_count == _paused_windows)
2434 efl_event_callback_call(efl_loop_get(ev->object), EFL_APP_EVENT_PAUSE, NULL);
2435 }
2436
2437 EFL_CALLBACKS_ARRAY_DEFINE(_elm_win_tracking,
2438 { EFL_EVENT_CALLBACK_ADD, _win_event_add_cb },
2439 { EFL_EVENT_CALLBACK_DEL, _win_event_del_cb },
2440 { EFL_UI_WIN_EVENT_PAUSE, _win_paused })
2441
2442 static void
_elm_win_cb_mouse_up(void * data,const Efl_Event * ev EINA_UNUSED)2443 _elm_win_cb_mouse_up(void *data, const Efl_Event *ev EINA_UNUSED)
2444 {
2445 DBG("Evas mouse up event");
2446 /*Currently wayland server didn't send mouse up event after resize the window*/
2447 Efl_Ui_Win_Data *sd = data;
2448 if(sd->resizing) sd->resizing = EINA_FALSE;
2449 }
2450
2451 static void
_elm_win_resume(void * data,const Efl_Event * ev)2452 _elm_win_resume(void *data, const Efl_Event *ev)
2453 {
2454 Efl_Ui_Win_Data *sd = data;
2455
2456 if (!sd->paused) return ;
2457
2458 efl_event_callback_call(sd->obj, EFL_UI_WIN_EVENT_RESUME, NULL);
2459 sd->paused = EINA_FALSE;
2460
2461 if (_elm_win_count == _paused_windows)
2462 efl_event_callback_call(efl_loop_get(ev->object), EFL_APP_EVENT_RESUME, NULL);
2463
2464 _paused_windows--;
2465 }
2466
2467 EFL_CALLBACKS_ARRAY_DEFINE(_elm_evas_tracking,
2468 { EFL_EVENT_POINTER_UP, _elm_win_cb_mouse_up },
2469 { EFL_CANVAS_SCENE_EVENT_RENDER_PRE, _elm_win_resume })
2470
2471 static void
_deferred_ecore_evas_free(void * data)2472 _deferred_ecore_evas_free(void *data)
2473 {
2474 ecore_evas_free(data);
2475 _elm_win_deferred_free--;
2476 }
2477
2478 static inline Edje_Object *
_elm_win_modal_blocker_edje_get(Efl_Ui_Win_Data * sd)2479 _elm_win_modal_blocker_edje_get(Efl_Ui_Win_Data *sd)
2480 {
2481 /* Legacy theme compatibility */
2482 const char *version = edje_object_data_get(sd->legacy.edje, "version");
2483 int v = version ? atoi(version) : 0;
2484 if (v < FRAME_OBJ_THEME_MIN_VERSION)
2485 {
2486 DBG("Detected legacy theme (<1.19) for modal window blocker.");
2487 return sd->legacy.edje;
2488 }
2489 return sd->frame_obj;
2490 }
2491
2492 static void
_elm_win_modality_increment(Efl_Ui_Win_Data * modalsd)2493 _elm_win_modality_increment(Efl_Ui_Win_Data *modalsd)
2494 {
2495 Efl_Ui_Win *current;
2496 Eina_List *l;
2497 Eina_Bool is_legacy = elm_widget_is_legacy(modalsd->obj);
2498
2499 EINA_LIST_FOREACH(_elm_win_list, l, current)
2500 {
2501 ELM_WIN_DATA_GET_OR_RETURN(current, cursd);
2502 if (modalsd != cursd)
2503 cursd->modal_count++;
2504 if (cursd->modal_count > 0)
2505 {
2506 Edje_Object *ed = _elm_win_modal_blocker_edje_get(cursd);
2507 if (is_legacy)
2508 edje_object_signal_emit(ed, "elm,action,show_blocker", "elm");
2509 else
2510 edje_object_signal_emit(ed, "efl,action,show_blocker", "efl");
2511 efl_event_callback_legacy_call
2512 (cursd->main_menu, EFL_UI_WIN_EVENT_ELM_ACTION_BLOCK_MENU, NULL);
2513 _elm_win_frame_style_update(cursd, 0, 1);
2514 }
2515 }
2516 }
2517
2518 static void
_elm_win_modality_decrement(Efl_Ui_Win_Data * modalsd)2519 _elm_win_modality_decrement(Efl_Ui_Win_Data *modalsd)
2520 {
2521 Efl_Ui_Win *current;
2522 Eina_List *l;
2523 Eina_Bool is_legacy = elm_widget_is_legacy(modalsd->obj);
2524
2525 EINA_LIST_FOREACH(_elm_win_list, l, current)
2526 {
2527 ELM_WIN_DATA_GET_OR_RETURN(current, cursd);
2528 if ((modalsd != cursd) && (cursd->modal_count > 0))
2529 cursd->modal_count--;
2530 if (cursd->modal_count == 0)
2531 {
2532 Edje_Object *ed = _elm_win_modal_blocker_edje_get(cursd);
2533 if (is_legacy)
2534 edje_object_signal_emit(ed, "elm,action,hide_blocker", "elm");
2535 else
2536 edje_object_signal_emit(ed, "efl,action,hide_blocker", "efl");
2537 efl_event_callback_legacy_call
2538 (cursd->main_menu, ELM_MENU_EVENT_ELM_ACTION_UNBLOCK_MENU, NULL);
2539 _elm_win_frame_style_update(cursd, 0, 1);
2540 }
2541 }
2542 }
2543
2544 static void
_efl_ui_win_show(Eo * obj,Efl_Ui_Win_Data * sd)2545 _efl_ui_win_show(Eo *obj, Efl_Ui_Win_Data *sd)
2546 {
2547 Eina_Bool do_eval = EINA_FALSE;
2548
2549 sd->shown = EINA_TRUE;
2550 if (sd->modal_count)
2551 {
2552 /* FIXME FIXME FIXME
2553 * Ugly code flow: legacy code had an early return in smart_show, ie.
2554 * evas object show would be processed but smart object show would be
2555 * aborted. This super call tries to simulate that. */
2556 efl_gfx_entity_visible_set(efl_super(obj, EFL_CANVAS_GROUP_CLASS), EINA_TRUE);
2557 return;
2558 }
2559
2560 if ((sd->modal) && (!evas_object_visible_get(obj)))
2561 _elm_win_modality_increment(sd);
2562
2563 if (!evas_object_visible_get(obj)) do_eval = EINA_TRUE;
2564 efl_gfx_entity_visible_set(efl_super(obj, MY_CLASS), EINA_TRUE);
2565
2566 if (sd->deferred_resize_job)
2567 _elm_win_resize_job(sd->obj);
2568 evas_smart_objects_calculate(evas_object_evas_get(obj));
2569
2570 TRAP(sd, show);
2571
2572 if (_elm_config->atspi_mode)
2573 {
2574 Eo *root;
2575 efl_access_window_created_signal_emit(obj);
2576 root = efl_access_object_access_root_get();
2577 if (root)
2578 efl_access_children_changed_added_signal_emit(root, obj);
2579 }
2580
2581 if (do_eval)
2582 {
2583 if (_elm_win_state_eval_timer)
2584 {
2585 ecore_timer_del(_elm_win_state_eval_timer);
2586 _elm_win_state_eval_timer = NULL;
2587 }
2588 _elm_win_state_eval(NULL);
2589 }
2590
2591 if (sd->shot.info) _shot_handle(sd);
2592
2593 if (!sd->first_draw) return;
2594 if (sd->frame_obj)
2595 {
2596 evas_object_show(sd->frame_obj);
2597 }
2598 if (sd->img_obj)
2599 {
2600 evas_object_show(sd->img_obj);
2601 }
2602 if (sd->pointer.obj)
2603 {
2604 evas_object_show(sd->pointer.obj);
2605 }
2606 }
2607
2608 static void
_efl_ui_win_hide(Eo * obj,Efl_Ui_Win_Data * sd)2609 _efl_ui_win_hide(Eo *obj, Efl_Ui_Win_Data *sd)
2610 {
2611 if (sd->modal_count)
2612 {
2613 /* FIXME FIXME FIXME
2614 * Ugly code flow: legacy code had an early return in smart_show, ie.
2615 * evas object show would be processed but smart object show would be
2616 * aborted. This super call tries to simulate that. */
2617 efl_gfx_entity_visible_set(efl_super(obj, EFL_CANVAS_GROUP_CLASS), EINA_FALSE);
2618 return;
2619 }
2620
2621 _elm_win_state_eval_queue();
2622
2623 if ((sd->modal) && (evas_object_visible_get(obj)))
2624 _elm_win_modality_decrement(sd);
2625
2626 efl_gfx_entity_visible_set(efl_super(obj, MY_CLASS), EINA_FALSE);
2627 TRAP(sd, hide);
2628
2629 if (sd->frame_obj)
2630 {
2631 evas_object_hide(sd->frame_obj);
2632 }
2633 if (sd->img_obj)
2634 {
2635 evas_object_hide(sd->img_obj);
2636 }
2637 if (sd->pointer.obj)
2638 {
2639 evas_object_hide(sd->pointer.obj);
2640 }
2641
2642 if (_elm_config->atspi_mode)
2643 {
2644 Eo *root;
2645 root = efl_access_object_access_root_get();
2646 efl_access_window_destroyed_signal_emit(obj);
2647 if (root)
2648 efl_access_children_changed_del_signal_emit(root, obj);
2649 }
2650
2651 if (_elm_win_policy_quit_triggered(obj))
2652 _elm_win_flush_cache_and_exit(obj);
2653 }
2654
2655 EOLIAN static void
_efl_ui_win_efl_gfx_entity_visible_set(Eo * obj,Efl_Ui_Win_Data * sd,Eina_Bool vis)2656 _efl_ui_win_efl_gfx_entity_visible_set(Eo *obj, Efl_Ui_Win_Data *sd, Eina_Bool vis)
2657 {
2658 if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_VISIBLE, 0, vis))
2659 return;
2660
2661 if (vis) _efl_ui_win_show(obj, sd);
2662 else _efl_ui_win_hide(obj, sd);
2663 }
2664
2665 EOLIAN static Eina_Bool
_efl_ui_win_efl_canvas_scene_pointer_position_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,Eo * dev,Eina_Position2D * pos)2666 _efl_ui_win_efl_canvas_scene_pointer_position_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, Eo *dev, Eina_Position2D *pos)
2667 {
2668 return efl_canvas_scene_pointer_position_get(sd->evas, dev, pos);
2669 }
2670
2671 EOLIAN static Eina_Bool
_efl_ui_win_efl_canvas_pointer_pointer_inside_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,Eo * dev)2672 _efl_ui_win_efl_canvas_pointer_pointer_inside_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, Eo *dev)
2673 {
2674 return efl_canvas_pointer_inside_get(sd->evas, dev);
2675 }
2676
2677 /* multi touch support */
2678 static Eina_Bool
_input_pointer_iterator_next(Input_Pointer_Iterator * it,void ** data)2679 _input_pointer_iterator_next(Input_Pointer_Iterator *it, void **data)
2680 {
2681 Eo *sub;
2682
2683 if (!eina_iterator_next(it->real_iterator, (void **) &sub))
2684 return EINA_FALSE;
2685
2686 if (data) *data = sub;
2687 return EINA_TRUE;
2688 }
2689
2690 static Eo *
_input_pointer_iterator_get_container(Input_Pointer_Iterator * it)2691 _input_pointer_iterator_get_container(Input_Pointer_Iterator *it)
2692 {
2693 return (Eo *) it->object;
2694 }
2695
2696 static void
_input_pointer_iterator_free(Input_Pointer_Iterator * it)2697 _input_pointer_iterator_free(Input_Pointer_Iterator *it)
2698 {
2699 Efl_Input_Pointer *ptr;
2700
2701 EINA_LIST_FREE(it->list, ptr)
2702 efl_unref(ptr);
2703 eina_iterator_free(it->real_iterator);
2704 free(it);
2705 }
2706
2707 EOLIAN static Eina_Iterator *
_efl_ui_win_pointer_iterate(const Eo * obj,Efl_Ui_Win_Data * sd,Eina_Bool hover EINA_UNUSED)2708 _efl_ui_win_pointer_iterate(const Eo *obj, Efl_Ui_Win_Data *sd,
2709 Eina_Bool hover EINA_UNUSED)
2710 {
2711 Input_Pointer_Iterator *it;
2712 Eina_List *list = NULL;
2713 int i, cnt;
2714
2715 // Note: "hover" is here as a possible extension to this API. At the moment
2716 // I don't have any device that could track the position of hovering fingers
2717 // and Evas also wouldn't track those.
2718
2719 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
2720
2721 cnt = evas_touch_point_list_count(sd->evas);
2722 if (!cnt) return NULL;
2723
2724 it = calloc(1, sizeof(*it));
2725 if (!it) return NULL;
2726
2727 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
2728
2729 for (i = 0; i < cnt; i++)
2730 {
2731 Efl_Input_Pointer_Data *ptrdata;
2732 Evas_Touch_Point_State state;
2733 Efl_Input_Pointer *ptr;
2734 double x, y;
2735
2736 ptr = efl_input_pointer_instance_get( (Eo *) obj, (void **) &ptrdata);
2737 if (!ptrdata) break;
2738
2739 ptrdata->touch_id = evas_touch_point_list_nth_id_get(sd->evas, i);
2740 _efl_input_value_mark(ptrdata, EFL_INPUT_VALUE_TOUCH_ID);
2741
2742 // Note that "still" maps to "down" here.
2743 state = evas_touch_point_list_nth_state_get(sd->evas, i);
2744 switch (state)
2745 {
2746 case EVAS_TOUCH_POINT_DOWN: ptrdata->action = EFL_POINTER_ACTION_DOWN; break;
2747 case EVAS_TOUCH_POINT_UP: ptrdata->action = EFL_POINTER_ACTION_UP; break;
2748 case EVAS_TOUCH_POINT_MOVE: ptrdata->action = EFL_POINTER_ACTION_MOVE; break;
2749 case EVAS_TOUCH_POINT_STILL: ptrdata->action = EFL_POINTER_ACTION_DOWN; break;
2750 case EVAS_TOUCH_POINT_CANCEL: ptrdata->action = EFL_POINTER_ACTION_CANCEL; break;
2751 default: ptrdata->action = EFL_POINTER_ACTION_NONE; break;
2752 }
2753
2754 evas_canvas_touch_point_list_nth_xy_get(sd->evas, i, &x, &y);
2755 _efl_input_value_mark(ptrdata, EFL_INPUT_VALUE_X);
2756 _efl_input_value_mark(ptrdata, EFL_INPUT_VALUE_Y);
2757 ptrdata->cur.x = x;
2758 ptrdata->cur.y = y;
2759 ptrdata->prev = ptrdata->cur;
2760
2761 list = eina_list_append(list, ptr);
2762 }
2763
2764 it->list = list;
2765 it->real_iterator = eina_list_iterator_new(it->list);
2766 it->iterator.version = EINA_ITERATOR_VERSION;
2767 it->iterator.next = FUNC_ITERATOR_NEXT(_input_pointer_iterator_next);
2768 it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_input_pointer_iterator_get_container);
2769 it->iterator.free = FUNC_ITERATOR_FREE(_input_pointer_iterator_free);
2770 it->object = obj;
2771
2772 return &it->iterator;
2773 }
2774
2775 EOLIAN static Eina_Bool
_efl_ui_win_efl_canvas_scene_image_max_size_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,Eina_Size2D * max)2776 _efl_ui_win_efl_canvas_scene_image_max_size_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, Eina_Size2D *max)
2777 {
2778 return efl_canvas_scene_image_max_size_get(sd->evas, max);
2779 }
2780
2781 EOLIAN static void
_efl_ui_win_efl_canvas_scene_group_objects_calculate(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)2782 _efl_ui_win_efl_canvas_scene_group_objects_calculate(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
2783 {
2784 evas_smart_objects_calculate(sd->evas);
2785 }
2786
2787 EOLIAN static Eina_Bool
_efl_ui_win_efl_canvas_scene_group_objects_calculating_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)2788 _efl_ui_win_efl_canvas_scene_group_objects_calculating_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
2789 {
2790 return efl_canvas_scene_group_objects_calculating_get(sd->evas);
2791 }
2792
2793 EOLIAN static Eina_Iterator *
_efl_ui_win_efl_canvas_scene_objects_at_xy_get(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,Eina_Position2D pos,Eina_Bool include_pass_events_objects,Eina_Bool include_hidden_objects)2794 _efl_ui_win_efl_canvas_scene_objects_at_xy_get(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, Eina_Position2D pos, Eina_Bool include_pass_events_objects, Eina_Bool include_hidden_objects)
2795 {
2796 Eina_List *objs = NULL;
2797 objs = evas_objects_at_xy_get(sd->evas, pos.x, pos.y, include_pass_events_objects, include_hidden_objects);
2798 return eina_list_iterator_new(objs); // FIXME: This leaks the list!
2799 }
2800
2801 EOLIAN static Efl_Gfx_Entity *
_efl_ui_win_efl_canvas_scene_object_top_at_xy_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,Eina_Position2D pos,Eina_Bool include_pass_events_objects,Eina_Bool include_hidden_objects)2802 _efl_ui_win_efl_canvas_scene_object_top_at_xy_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, Eina_Position2D pos, Eina_Bool include_pass_events_objects, Eina_Bool include_hidden_objects)
2803 {
2804 return evas_object_top_at_xy_get(sd->evas, pos.x, pos.y, include_pass_events_objects, include_hidden_objects);
2805 }
2806
2807 EOLIAN static Eina_Iterator *
_efl_ui_win_efl_canvas_scene_objects_in_rectangle_get(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,Eina_Rect r,Eina_Bool include_pass_events_objects,Eina_Bool include_hidden_objects)2808 _efl_ui_win_efl_canvas_scene_objects_in_rectangle_get(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, Eina_Rect r, Eina_Bool include_pass_events_objects, Eina_Bool include_hidden_objects)
2809 {
2810 Eina_List *objs = NULL;
2811 objs = evas_objects_in_rectangle_get(sd->evas, r.x, r.y, r.w, r.h, include_pass_events_objects, include_hidden_objects);
2812 return eina_list_iterator_new(objs); // FIXME: This leaks the list!
2813 }
2814
2815 EOLIAN static Efl_Gfx_Entity *
_efl_ui_win_efl_canvas_scene_object_top_in_rectangle_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,Eina_Rect r,Eina_Bool include_pass_events_objects,Eina_Bool include_hidden_objects)2816 _efl_ui_win_efl_canvas_scene_object_top_in_rectangle_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, Eina_Rect r, Eina_Bool include_pass_events_objects, Eina_Bool include_hidden_objects)
2817 {
2818 return evas_object_top_in_rectangle_get(sd->evas, r.x, r.y, r.w, r.h, include_pass_events_objects, include_hidden_objects);
2819 }
2820
2821 EOLIAN static Efl_Input_Device *
_efl_ui_win_efl_canvas_scene_device_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,const char * name)2822 _efl_ui_win_efl_canvas_scene_device_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, const char *name)
2823 {
2824 return efl_canvas_scene_device_get(sd->evas, name);
2825 }
2826
2827 EOLIAN static Efl_Input_Device *
_efl_ui_win_efl_canvas_scene_seat_default_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)2828 _efl_ui_win_efl_canvas_scene_seat_default_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
2829 {
2830 return efl_canvas_scene_seat_default_get(sd->evas);
2831 }
2832
2833 EOLIAN static Efl_Input_Device *
_efl_ui_win_efl_canvas_scene_seat_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,int id)2834 _efl_ui_win_efl_canvas_scene_seat_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, int id)
2835 {
2836 return efl_canvas_scene_seat_get(sd->evas, id);
2837 }
2838
2839 static void
_elm_win_on_parent_del(void * data,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info EINA_UNUSED)2840 _elm_win_on_parent_del(void *data,
2841 Evas *e EINA_UNUSED,
2842 Evas_Object *obj,
2843 void *event_info EINA_UNUSED)
2844 {
2845 ELM_WIN_DATA_GET(data, sd);
2846
2847 if (obj == sd->parent) sd->parent = NULL;
2848 }
2849
2850 static void
_elm_win_focus_target_move(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)2851 _elm_win_focus_target_move(void *data,
2852 Evas *e EINA_UNUSED,
2853 Evas_Object *obj EINA_UNUSED,
2854 void *event_info EINA_UNUSED)
2855 {
2856 ELM_WIN_DATA_GET(data, sd);
2857
2858 sd->focus_highlight.geometry_changed = EINA_TRUE;
2859 _elm_win_focus_highlight_reconfigure_job_start(sd);
2860 }
2861
2862 static void
_elm_win_focus_target_resize(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)2863 _elm_win_focus_target_resize(void *data,
2864 Evas *e EINA_UNUSED,
2865 Evas_Object *obj EINA_UNUSED,
2866 void *event_info EINA_UNUSED)
2867 {
2868 ELM_WIN_DATA_GET(data, sd);
2869
2870 sd->focus_highlight.geometry_changed = EINA_TRUE;
2871 _elm_win_focus_highlight_reconfigure_job_start(sd);
2872 }
2873
2874 static void
_elm_win_focus_target_del(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)2875 _elm_win_focus_target_del(void *data,
2876 Evas *e EINA_UNUSED,
2877 Evas_Object *obj EINA_UNUSED,
2878 void *event_info EINA_UNUSED)
2879 {
2880 ELM_WIN_DATA_GET(data, sd);
2881
2882 sd->focus_highlight.cur.target = NULL;
2883
2884 _elm_win_focus_highlight_reconfigure_job_start(sd);
2885 }
2886
2887 static Evas_Object *
_elm_win_focus_target_get(Evas_Object * obj)2888 _elm_win_focus_target_get(Evas_Object *obj)
2889 {
2890 Evas_Object *o = obj;
2891
2892 while (o)
2893 {
2894 if (elm_widget_is(o))
2895 {
2896 if (!elm_widget_highlight_ignore_get(o))
2897 break;
2898 }
2899 o = elm_widget_parent_widget_get(o);
2900 }
2901
2902 return o;
2903 }
2904
2905 static void
_elm_win_focus_target_callbacks_add(Efl_Ui_Win_Data * sd)2906 _elm_win_focus_target_callbacks_add(Efl_Ui_Win_Data *sd)
2907 {
2908 Evas_Object *obj = sd->focus_highlight.cur.target;
2909 if (!obj) return;
2910
2911 evas_object_event_callback_add
2912 (obj, EVAS_CALLBACK_MOVE, _elm_win_focus_target_move, sd->obj);
2913 evas_object_event_callback_add
2914 (obj, EVAS_CALLBACK_RESIZE, _elm_win_focus_target_resize, sd->obj);
2915 }
2916
2917 static void
_elm_win_focus_target_callbacks_del(Efl_Ui_Win_Data * sd)2918 _elm_win_focus_target_callbacks_del(Efl_Ui_Win_Data *sd)
2919 {
2920 Evas_Object *obj = sd->focus_highlight.cur.target;
2921
2922 evas_object_event_callback_del_full
2923 (obj, EVAS_CALLBACK_MOVE, _elm_win_focus_target_move, sd->obj);
2924 evas_object_event_callback_del_full
2925 (obj, EVAS_CALLBACK_RESIZE, _elm_win_focus_target_resize, sd->obj);
2926 }
2927
2928 static void
_elm_win_object_focus_in(void * data,Evas * e EINA_UNUSED,void * event_info)2929 _elm_win_object_focus_in(void *data,
2930 Evas *e EINA_UNUSED,
2931 void *event_info)
2932 {
2933 Evas_Object *obj = event_info, *target;
2934 ELM_WIN_DATA_GET(data, sd);
2935
2936 if (sd->focus_highlight.cur.target == obj)
2937 return;
2938
2939 target = _elm_win_focus_target_get(obj);
2940 sd->focus_highlight.cur.target = target;
2941
2942 if (target)
2943 {
2944 if (elm_widget_highlight_in_theme_get(target))
2945 sd->focus_highlight.cur.in_theme = EINA_TRUE;
2946 else
2947 _elm_win_focus_target_callbacks_add(sd);
2948 evas_object_event_callback_add
2949 (target, EVAS_CALLBACK_DEL, _elm_win_focus_target_del, sd->obj);
2950 }
2951
2952 _elm_win_focus_highlight_reconfigure_job_start(sd);
2953 }
2954
2955 static void
_elm_win_object_focus_out(void * data,Evas * e EINA_UNUSED,void * event_info EINA_UNUSED)2956 _elm_win_object_focus_out(void *data,
2957 Evas *e EINA_UNUSED,
2958 void *event_info EINA_UNUSED)
2959 {
2960 ELM_WIN_DATA_GET(data, sd);
2961
2962 if (!sd->focus_highlight.cur.target)
2963 return;
2964
2965 if (!sd->focus_highlight.cur.in_theme)
2966 _elm_win_focus_target_callbacks_del(sd);
2967
2968 evas_object_event_callback_del_full
2969 (sd->focus_highlight.cur.target,
2970 EVAS_CALLBACK_DEL, _elm_win_focus_target_del, sd->obj);
2971
2972 sd->focus_highlight.cur.target = NULL;
2973 sd->focus_highlight.cur.in_theme = EINA_FALSE;
2974
2975 _elm_win_focus_highlight_reconfigure_job_start(sd);
2976 }
2977
2978 static void
_elm_win_focus_highlight_shutdown(Efl_Ui_Win_Data * sd)2979 _elm_win_focus_highlight_shutdown(Efl_Ui_Win_Data *sd)
2980 {
2981 _elm_win_focus_highlight_reconfigure_job_stop(sd);
2982 if (sd->focus_highlight.cur.target)
2983 {
2984 if (elm_widget_is_legacy(sd->obj))
2985 elm_widget_signal_emit(sd->focus_highlight.cur.target,
2986 "elm,action,focus_highlight,hide", "elm");
2987 else
2988 elm_widget_signal_emit(sd->focus_highlight.cur.target,
2989 "efl,action,focus_highlight,hide", "efl");
2990 _elm_win_focus_target_callbacks_del(sd);
2991 evas_object_event_callback_del_full
2992 (sd->focus_highlight.cur.target,
2993 EVAS_CALLBACK_DEL, _elm_win_focus_target_del, sd->obj);
2994 sd->focus_highlight.cur.target = NULL;
2995 }
2996 ELM_SAFE_FREE(sd->focus_highlight.fobj, evas_object_del);
2997
2998 evas_event_callback_del_full
2999 (sd->evas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN,
3000 _elm_win_object_focus_in, sd->obj);
3001 evas_event_callback_del_full
3002 (sd->evas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_OUT,
3003 _elm_win_object_focus_out, sd->obj);
3004 }
3005
3006 static void
_win_img_hide(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)3007 _win_img_hide(void *data,
3008 Evas *e EINA_UNUSED,
3009 Evas_Object *obj EINA_UNUSED,
3010 void *event_info EINA_UNUSED)
3011 {
3012 Efl_Ui_Win *real_win = elm_widget_top_get(data);
3013 efl_ui_focus_manager_redirect_set(real_win, NULL);
3014 }
3015
3016 static void
_win_img_mouse_up(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)3017 _win_img_mouse_up(void *data,
3018 Evas *e EINA_UNUSED,
3019 Evas_Object *obj EINA_UNUSED,
3020 void *event_info)
3021 {
3022 Evas_Event_Mouse_Up *ev = event_info;
3023 if (!(ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD))
3024 elm_widget_focus_mouse_up_handle(evas_object_widget_parent_find(data));
3025 }
3026
3027 static void
_win_img_focus_in(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)3028 _win_img_focus_in(void *data,
3029 Evas *e EINA_UNUSED,
3030 Evas_Object *obj EINA_UNUSED,
3031 void *event_info EINA_UNUSED)
3032 {
3033 Efl_Ui_Win *real_win = elm_widget_top_get(data);
3034 efl_ui_focus_manager_redirect_set(real_win, data);
3035 efl_ui_focus_manager_focus_set(data, efl_ui_focus_manager_root_get(data));
3036 }
3037
3038 static void
_win_img_focus_out(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)3039 _win_img_focus_out(void *data,
3040 Evas *e EINA_UNUSED,
3041 Evas_Object *obj EINA_UNUSED,
3042 void *event_info EINA_UNUSED)
3043 {
3044 Efl_Ui_Win *real_win = elm_widget_top_get(data);
3045 efl_ui_focus_manager_redirect_set(real_win, NULL);
3046 }
3047
3048 static void
_elm_win_on_img_obj_del(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)3049 _elm_win_on_img_obj_del(void *data,
3050 Evas *e EINA_UNUSED,
3051 Evas_Object *obj EINA_UNUSED,
3052 void *event_info EINA_UNUSED)
3053 {
3054 ELM_WIN_DATA_GET(data, sd);
3055 _elm_win_img_callbacks_del(sd->obj, sd->img_obj);
3056 sd->img_obj = NULL;
3057 }
3058
3059 static void
_elm_win_img_callbacks_del(Evas_Object * obj,Evas_Object * imgobj)3060 _elm_win_img_callbacks_del(Evas_Object *obj, Evas_Object *imgobj)
3061 {
3062 if (!imgobj) return;
3063 evas_object_event_callback_del_full
3064 (imgobj, EVAS_CALLBACK_DEL, _elm_win_on_img_obj_del, obj);
3065 evas_object_event_callback_del_full
3066 (imgobj, EVAS_CALLBACK_HIDE, _win_img_hide, obj);
3067 evas_object_event_callback_del_full
3068 (imgobj, EVAS_CALLBACK_MOUSE_UP, _win_img_mouse_up, obj);
3069 evas_object_event_callback_del_full
3070 (imgobj, EVAS_CALLBACK_FOCUS_IN, _win_img_focus_in, obj);
3071 evas_object_event_callback_del_full
3072 (imgobj, EVAS_CALLBACK_FOCUS_OUT, _win_img_focus_out, obj);
3073 }
3074
3075 EOLIAN static void
_efl_ui_win_efl_canvas_group_group_del(Eo * obj,Efl_Ui_Win_Data * sd)3076 _efl_ui_win_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Win_Data *sd)
3077 {
3078 efl_event_freeze(sd->evas);
3079
3080 if ((sd->modal) && (evas_object_visible_get(obj)))
3081 _elm_win_modality_decrement(sd);
3082
3083 if ((sd->modal) && (sd->modal_count > 0))
3084 ERR("Deleted modal win was blocked by another modal win which was created after creation of that win.");
3085
3086 evas_object_event_callback_del_full(sd->legacy.edje,
3087 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
3088 _elm_win_on_resize_obj_changed_size_hints,
3089 obj);
3090
3091 efl_event_callback_array_del(sd->evas, _elm_evas_tracking(), sd);
3092 efl_event_callback_array_del(obj, _elm_win_evas_feed_fake_callbacks(), sd->evas);
3093 efl_event_callback_array_del(obj, _elm_win_tracking(), sd);
3094 evas_object_del(sd->legacy.box);
3095 evas_object_del(sd->legacy.edje);
3096
3097 /* NB: child deletion handled by parent's smart del */
3098
3099 if ((sd->type != EFL_UI_WIN_TYPE_FAKE) && (trap) && (trap->del))
3100 trap->del(sd->trap_data, obj);
3101
3102 if (sd->parent)
3103 {
3104 evas_object_event_callback_del_full
3105 (sd->parent, EVAS_CALLBACK_DEL, _elm_win_on_parent_del, obj);
3106 sd->parent = NULL;
3107 }
3108
3109 if (sd->autodel_clear) *(sd->autodel_clear) = -1;
3110
3111 if (_elm_config->atspi_mode)
3112 efl_access_window_destroyed_signal_emit(obj);
3113
3114 _elm_win_list = eina_list_remove(_elm_win_list, obj);
3115 _elm_win_count--;
3116 _elm_win_state_eval_queue();
3117
3118 if (_elm_win_count == _paused_windows)
3119 efl_event_callback_call(efl_loop_get(obj), EFL_APP_EVENT_PAUSE, NULL);
3120
3121 if (sd->ee)
3122 {
3123 ecore_evas_callback_delete_request_set(sd->ee, NULL);
3124 ecore_evas_callback_resize_set(sd->ee, NULL);
3125 }
3126
3127 eina_stringshare_del(sd->shot.info);
3128 ecore_timer_del(sd->shot.timer);
3129
3130 #ifdef HAVE_ELEMENTARY_X
3131 ecore_event_handler_del(sd->x.client_message_handler);
3132 ecore_event_handler_del(sd->x.property_handler);
3133 #endif
3134 #ifdef HAVE_ELEMENTARY_WL2
3135 ecore_event_handler_del(sd->wl.configure_handler);
3136 if (sd->pointer.obj) evas_object_del(sd->pointer.obj);
3137 if (sd->pointer.ee) ecore_evas_free(sd->pointer.ee);
3138 sd->pointer.surf = NULL;
3139 #endif
3140 #ifdef HAVE_ELEMENTARY_WIN32
3141 ecore_event_handler_del(sd->win32.key_down_handler);
3142 #endif
3143
3144 if (sd->type == ELM_WIN_INLINED_IMAGE)
3145 {
3146 _elm_win_img_callbacks_del(obj, sd->img_obj);
3147 sd->img_obj = NULL;
3148 }
3149 else
3150 {
3151 if (sd->ee && (sd->type != EFL_UI_WIN_TYPE_FAKE))
3152 {
3153 ecore_evas_manual_render_set(sd->ee, EINA_TRUE);
3154 edje_object_freeze(sd->frame_obj);
3155 ecore_job_add(_deferred_ecore_evas_free, sd->ee);
3156 _elm_win_deferred_free++;
3157 }
3158 }
3159
3160 _elm_win_focus_highlight_shutdown(sd);
3161 eina_stringshare_del(sd->focus_highlight.style);
3162
3163 eina_stringshare_del(sd->title);
3164 eina_stringshare_del(sd->icon_name);
3165 eina_stringshare_del(sd->role);
3166 eina_stringshare_del(sd->name);
3167 eina_stringshare_del(sd->accel_pref);
3168 eina_stringshare_del(sd->stack_id);
3169 eina_stringshare_del(sd->stack_master_id);
3170 evas_object_del(sd->icon);
3171 evas_object_del(sd->main_menu);
3172 evas_object_del(sd->indicator);
3173
3174 sd->focus_highlight.style = NULL;
3175 sd->title = NULL;
3176 sd->icon_name = NULL;
3177 sd->role = NULL;
3178 sd->name = NULL;
3179 sd->icon = NULL;
3180 sd->main_menu = NULL;
3181
3182 _elm_win_profile_del(sd);
3183 _elm_win_available_profiles_del(sd);
3184 eina_array_free(sd->profile.available);
3185 sd->profile.available = NULL;
3186
3187 eina_array_free(sd->planned_changes);
3188 sd->planned_changes = NULL;
3189
3190 free(sd->wm_rot.rots);
3191 sd->wm_rot.rots = NULL;
3192
3193 /* Don't let callback in the air that point to sd */
3194 if (sd->ee)
3195 {
3196 ecore_evas_callback_mouse_in_set(sd->ee, NULL);
3197 ecore_evas_callback_focus_in_set(sd->ee, NULL);
3198 ecore_evas_callback_focus_out_set(sd->ee, NULL);
3199 ecore_evas_callback_move_set(sd->ee, NULL);
3200 ecore_evas_callback_state_change_set(sd->ee, NULL);
3201 ecore_evas_callback_pre_render_set(sd->ee, NULL);
3202 }
3203
3204 efl_canvas_group_del(efl_super(obj, MY_CLASS));
3205
3206 if (eina_value_type_get(&sd->exit_on_close))
3207 efl_loop_quit(efl_loop_get(obj), sd->exit_on_close);
3208 else if (!_elm_win_list)
3209 {
3210 if (elm_policy_get(ELM_POLICY_QUIT) == ELM_POLICY_QUIT_LAST_WINDOW_CLOSED)
3211 _elm_win_flush_cache_and_exit(obj);
3212 }
3213 if (!_elm_win_list)
3214 {
3215 efl_event_callback_call(efl_app_main_get(), EFL_APP_EVENT_STANDBY, NULL);
3216 if (eina_value_type_get(&exit_on_all_windows_closed))
3217 efl_loop_quit(efl_loop_get(obj), exit_on_all_windows_closed);
3218 }
3219 }
3220
3221 EOLIAN static void
_efl_ui_win_efl_gfx_entity_position_set(Eo * obj,Efl_Ui_Win_Data * sd,Eina_Position2D pos)3222 _efl_ui_win_efl_gfx_entity_position_set(Eo *obj, Efl_Ui_Win_Data *sd, Eina_Position2D pos)
3223 {
3224 if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_MOVE, 0, pos.x, pos.y))
3225 return;
3226
3227 if (sd->img_obj)
3228 {
3229 if ((pos.x != sd->screen.x) || (pos.y != sd->screen.y))
3230 {
3231 sd->screen.x = pos.x;
3232 sd->screen.y = pos.y;
3233 efl_event_callback_call(obj, EFL_GFX_ENTITY_EVENT_POSITION_CHANGED, &pos);
3234 evas_object_smart_callback_call(obj, "move", NULL);
3235 }
3236 goto super_skip;
3237 }
3238 else
3239 {
3240 if (!sd->response)
3241 {
3242 sd->req_xy = EINA_TRUE;
3243 sd->req_x = pos.x;
3244 sd->req_y = pos.y;
3245 TRAP(sd, move, pos.x, pos.y);
3246 }
3247 if (!ecore_evas_override_get(sd->ee)) goto super_skip;
3248 }
3249
3250 efl_gfx_entity_position_set(efl_super(obj, MY_CLASS), pos);
3251
3252 if (ecore_evas_override_get(sd->ee))
3253 {
3254 sd->screen.x = pos.x;
3255 sd->screen.y = pos.y;
3256 efl_event_callback_call(obj, EFL_GFX_ENTITY_EVENT_POSITION_CHANGED, &pos);
3257 evas_object_smart_callback_call(obj, "move", NULL);
3258 }
3259 if (sd->frame_obj)
3260 {
3261 #ifdef HAVE_ELEMENTARY_WL2
3262 /* TODO */
3263 /* ecore_wl_window_update_location(sd->wl.win, x, y); */
3264 #endif
3265 sd->screen.x = pos.x;
3266 sd->screen.y = pos.y;
3267 }
3268 if (sd->img_obj)
3269 {
3270 sd->screen.x = pos.x;
3271 sd->screen.y = pos.y;
3272 }
3273
3274 return;
3275
3276 super_skip:
3277 /* FIXME FIXME FIXME
3278 * Ugly code flow: legacy code had an early return in smart_move, ie.
3279 * evas object move would be processed but smart object move would be
3280 * aborted. This super call tries to simulate that. */
3281 efl_gfx_entity_position_set(efl_super(obj, EFL_CANVAS_GROUP_CLASS), pos);
3282 }
3283
3284 EOLIAN static void
_efl_ui_win_efl_gfx_entity_size_set(Eo * obj,Efl_Ui_Win_Data * sd,Eina_Size2D sz)3285 _efl_ui_win_efl_gfx_entity_size_set(Eo *obj, Efl_Ui_Win_Data *sd, Eina_Size2D sz)
3286 {
3287 if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_RESIZE, 0, sz.w, sz.h))
3288 return;
3289
3290 if (sd->img_obj)
3291 {
3292 if (sd->constrain)
3293 {
3294 int sw, sh;
3295
3296 ecore_evas_screen_geometry_get(sd->ee, NULL, NULL, &sw, &sh);
3297 sz.w = MIN(sz.w, sw);
3298 sz.h = MIN(sz.h, sh);
3299 }
3300 if (sz.w < 1) sz.w = 1;
3301 if (sz.h < 1) sz.h = 1;
3302
3303 evas_object_image_size_set(sd->img_obj, sz.w, sz.h);
3304 }
3305
3306 _elm_win_frame_obj_update(sd, 1);
3307 if (!sd->response)
3308 {
3309 sd->req_wh = EINA_TRUE;
3310 sd->req_w = sz.w;
3311 sd->req_h = sz.h;
3312 TRAP(sd, resize, sz.w, sz.h);
3313 }
3314
3315 efl_gfx_entity_size_set(efl_super(obj, MY_CLASS), sz);
3316 /* if window is hidden during a resize,
3317 * revert to initial state where pre-render triggers recalc and other resizes are deferred
3318 */
3319 if (efl_gfx_entity_visible_get(obj)) return;
3320 if (!sd->first_draw) return;
3321 sd->first_draw = EINA_FALSE;
3322 edje_object_freeze(sd->frame_obj);
3323 }
3324
3325 static void
_elm_win_delete_request(Ecore_Evas * ee)3326 _elm_win_delete_request(Ecore_Evas *ee)
3327 {
3328 Efl_Ui_Win_Data *sd = _elm_win_associate_get(ee);
3329 Evas_Object *obj;
3330
3331 if (!sd) return;
3332
3333 obj = sd->obj;
3334
3335 int autodel = sd->autodel;
3336 sd->autodel_clear = &autodel;
3337 evas_object_ref(obj);
3338 efl_event_callback_legacy_call(obj, EFL_UI_WIN_EVENT_DELETE_REQUEST, NULL);
3339 ELM_WIN_DATA_ALIVE_CHECK(obj, sd);
3340 if (sd->autohide)
3341 evas_object_hide(obj);
3342 ELM_WIN_DATA_ALIVE_CHECK(obj, sd);
3343 if (_elm_config->atspi_mode)
3344 efl_access_window_destroyed_signal_emit(obj);
3345 ELM_WIN_DATA_ALIVE_CHECK(obj, sd);
3346 if (autodel) evas_object_del(obj);
3347 else sd->autodel_clear = NULL;
3348 evas_object_unref(obj);
3349 }
3350
3351 #ifdef HAVE_ELEMENTARY_WL2
3352 static void
_elm_win_wlwindow_get(Efl_Ui_Win_Data * sd)3353 _elm_win_wlwindow_get(Efl_Ui_Win_Data *sd)
3354 {
3355 Ecore_Wl2_Window *pwin = sd->wl.win;
3356 sd->wl.win = _elm_ee_wlwin_get(sd->ee);
3357 if (sd->wl.win != pwin)
3358 {
3359 char buf[128];
3360 int id;
3361
3362 snprintf(buf, sizeof(buf), "%u||%p", getpid(), sd->wl.win);
3363 eina_stringshare_replace(&sd->stack_id, buf);
3364 id = ecore_evas_aux_hint_id_get(sd->ee, "stack_id");
3365 if (id >= 0) ecore_evas_aux_hint_val_set(sd->ee, id, sd->stack_id);
3366 else ecore_evas_aux_hint_add(sd->ee, "stack_id", sd->stack_id);
3367 }
3368 }
3369
3370 void
_elm_win_wl_cursor_set(Evas_Object * obj,const char * cursor)3371 _elm_win_wl_cursor_set(Evas_Object *obj, const char *cursor)
3372 {
3373 ELM_WIN_DATA_GET(obj, sd);
3374
3375 if (!sd) return;
3376
3377 if (sd->pointer.obj)
3378 {
3379 Evas_Coord mw = 1, mh = 1, hx = 0, hy = 0;
3380
3381 if (cursor)
3382 {
3383 if (elm_widget_theme_object_set(sd->obj, sd->pointer.obj,
3384 "cursor", cursor, "default"))
3385 {
3386 elm_widget_theme_object_set(sd->obj, sd->pointer.obj,
3387 "pointer", "base", "default");
3388 }
3389 }
3390 else
3391 elm_widget_theme_object_set(sd->obj, sd->pointer.obj,
3392 "pointer", "base", "default");
3393
3394 edje_object_size_min_get(sd->pointer.obj, &mw, &mh);
3395 edje_object_size_min_restricted_calc(sd->pointer.obj, &mw, &mh, mw, mh);
3396 if ((mw < 32) || (mh < 32))
3397 {
3398 mw = 32;
3399 mh = 32;
3400 }
3401 evas_object_geometry_set(sd->pointer.obj, 0, 0, mw, mh);
3402 if (elm_widget_is_legacy(obj))
3403 edje_object_part_geometry_get(sd->pointer.obj,
3404 "elm.swallow.hotspot",
3405 &hx, &hy, NULL, NULL);
3406 else
3407 edje_object_part_geometry_get(sd->pointer.obj,
3408 "efl.hotspot",
3409 &hx, &hy, NULL, NULL);
3410
3411 sd->pointer.hot_x = hx;
3412 sd->pointer.hot_y = hy;
3413
3414 ecore_evas_resize(sd->pointer.ee, mw, mh);
3415 }
3416
3417 if ((sd->wl.win) && (sd->pointer.surf) && (sd->pointer.visible))
3418 {
3419 /* FIXME: multiseat */
3420 Ecore_Wl2_Input *input;
3421 Eina_Iterator *it;
3422
3423 /* FIXME: Here be dragons...
3424 pointer_set_cursor is totally unsynchronized, and on a cursor
3425 change we get here before the new cursor is rendered. So
3426 the cursor frequently moves to its new hotspot with the old
3427 cursor image, causing an ugly jump.
3428 Forcing manual render causes us to render first then set the
3429 cursor, which is still racey but far more likely to win the
3430 race.
3431 The right way to do this is to create an entirely new surface
3432 on every cursor change.
3433 */
3434 ecore_evas_manual_render(sd->pointer.ee);
3435 it = ecore_wl2_display_inputs_get(ecore_wl2_window_display_get(sd->wl.win));
3436 EINA_ITERATOR_FOREACH(it, input)
3437 ecore_wl2_input_pointer_set(input, sd->pointer.surf, sd->pointer.hot_x, sd->pointer.hot_y);
3438 eina_iterator_free(it);
3439 }
3440 }
3441 #endif
3442
3443 Ecore_Cocoa_Window *
_elm_ee_cocoa_win_get(const Ecore_Evas * ee)3444 _elm_ee_cocoa_win_get(const Ecore_Evas *ee)
3445 {
3446 #ifdef HAVE_ELEMENTARY_COCOA
3447 const char *engine_name;
3448
3449 if (!ee) return NULL;
3450
3451 engine_name = ecore_evas_engine_name_get(ee);
3452 if (EINA_UNLIKELY(!engine_name)) return NULL;
3453
3454 if (!strcmp(engine_name, "opengl_cocoa") ||
3455 !strcmp(engine_name, "gl_cocoa"))
3456 return ecore_evas_cocoa_window_get(ee);
3457 #else
3458 (void)ee;
3459 #endif
3460 return NULL;
3461 }
3462
3463 Ecore_Win32_Window *
_elm_ee_win32win_get(const Ecore_Evas * ee)3464 _elm_ee_win32win_get(const Ecore_Evas *ee)
3465 {
3466 #ifdef HAVE_ELEMENTARY_WIN32
3467 const char *engine_name;
3468
3469 if (!ee) return NULL;
3470
3471 engine_name = ecore_evas_engine_name_get(ee);
3472 if (EINA_UNLIKELY(!engine_name)) return NULL;
3473
3474 if ((!strcmp(engine_name, ELM_SOFTWARE_WIN32)) ||
3475 (!strcmp(engine_name, ELM_SOFTWARE_DDRAW)))
3476 {
3477 return ecore_evas_win32_window_get(ee);
3478 }
3479 #else
3480 (void)ee;
3481 #endif
3482 return NULL;
3483 }
3484
3485 #ifdef HAVE_ELEMENTARY_COCOA
3486 static void
_elm_win_cocoawindow_get(Efl_Ui_Win_Data * sd)3487 _elm_win_cocoawindow_get(Efl_Ui_Win_Data *sd)
3488 {
3489 sd->cocoa.win = _elm_ee_cocoa_win_get(sd->ee);
3490 }
3491 #endif
3492
3493 #ifdef HAVE_ELEMENTARY_WIN32
3494 static void
_internal_elm_win_win32window_get(Efl_Ui_Win_Data * sd)3495 _internal_elm_win_win32window_get(Efl_Ui_Win_Data *sd)
3496 {
3497 sd->win32.win = _elm_ee_win32win_get(sd->ee);
3498 }
3499 #endif
3500
3501 #ifdef HAVE_ELEMENTARY_X
3502 static void
_elm_win_xwin_update(Efl_Ui_Win_Data * sd)3503 _elm_win_xwin_update(Efl_Ui_Win_Data *sd)
3504 {
3505 const char *s;
3506
3507 if (sd->type == EFL_UI_WIN_TYPE_FAKE) return;
3508 _internal_elm_win_xwindow_get(sd);
3509
3510 if (!sd->x.xwin) return; /* nothing more to do */
3511 _internal_elm_win_xwindow_get(sd);
3512
3513 if (sd->stack_master_id)
3514 {
3515 Ecore_X_Window win = strtol(sd->stack_master_id, NULL, 16);
3516 if (win)
3517 {
3518 ecore_x_icccm_transient_for_set(sd->x.xwin, win);
3519 if (sd->stack_base)
3520 ecore_x_e_stack_type_set(sd->x.xwin, ECORE_X_STACK_BASE);
3521 else
3522 ecore_x_e_stack_type_set(sd->x.xwin, ECORE_X_STACK_STANDARD);
3523 }
3524 }
3525 else
3526 {
3527 if (sd->parent)
3528 {
3529 ELM_WIN_DATA_GET(sd->parent, sdp);
3530 if (sdp)
3531 {
3532 _internal_elm_win_xwindow_get(sdp);
3533 ecore_x_icccm_transient_for_set(sd->x.xwin, sdp->x.xwin);
3534 }
3535 }
3536 }
3537
3538 s = sd->title;
3539 if (!s) s = _elm_appname;
3540 if (!s) s = "";
3541 if (sd->icon_name) s = sd->icon_name;
3542 ecore_x_icccm_icon_name_set(sd->x.xwin, s);
3543 ecore_x_netwm_icon_name_set(sd->x.xwin, s);
3544
3545 s = sd->role;
3546 if (s) ecore_x_icccm_window_role_set(sd->x.xwin, s);
3547
3548 // set window icon
3549 if (sd->icon)
3550 {
3551 Eo *image = NULL;
3552
3553 if (efl_isa(sd->icon, EFL_CANVAS_IMAGE_INTERNAL_CLASS))
3554 image = sd->icon;
3555 else if (efl_isa(sd->icon, EFL_UI_IMAGE_CLASS))
3556 image = elm_image_object_get(sd->icon);
3557
3558 if (image)
3559 {
3560 int w = 0, h = 0, stride, x, y;
3561 Eina_Bool unmap = EINA_FALSE;
3562 Eina_Rw_Slice sl = {};
3563
3564 if (efl_isa(image, EFL_CANVAS_IMAGE_CLASS))
3565 {
3566 Eina_Rect rect = {};
3567
3568 unmap = EINA_TRUE;
3569 rect.size = efl_gfx_buffer_size_get(image);
3570 sl = efl_gfx_buffer_map(image, EFL_GFX_BUFFER_ACCESS_MODE_READ,
3571 &rect, EFL_GFX_COLORSPACE_ARGB8888, 0,
3572 &stride);
3573 w = rect.w;
3574 h = rect.h;
3575 }
3576 else
3577 {
3578 evas_object_image_size_get(image, &w, &h);
3579 stride = evas_object_image_stride_get(image);
3580 sl.mem = evas_object_image_data_get(image, EINA_FALSE);
3581 }
3582
3583 if (sl.mem)
3584 {
3585 Ecore_X_Icon ic;
3586
3587 ic.width = w;
3588 ic.height = h;
3589 if ((w > 0) && (h > 0) &&
3590 (stride >= (int)(w * sizeof(unsigned int))))
3591 {
3592 if (stride == (int)(w * sizeof(unsigned int)))
3593 {
3594 ic.data = sl.mem;
3595 ecore_x_netwm_icons_set(sd->x.xwin, &ic, 1);
3596 }
3597 else
3598 {
3599 ic.data = malloc(w * h * sizeof(unsigned int));
3600 if (ic.data)
3601 {
3602 unsigned char *p = sl.mem;
3603 unsigned int *p2 = ic.data;
3604
3605 for (y = 0; y < h; y++)
3606 {
3607 for (x = 0; x < w; x++)
3608 {
3609 *p2 = *((unsigned int *)p);
3610 p += sizeof(unsigned int);
3611 p2++;
3612 }
3613 p += (stride - (w * sizeof(unsigned int)));
3614 }
3615 ecore_x_netwm_icons_set(sd->x.xwin, &ic, 1);
3616 free(ic.data);
3617 }
3618 }
3619 }
3620 if (unmap) efl_gfx_buffer_unmap(image, sl);
3621 else evas_object_image_data_set(image, sl.mem);
3622 }
3623 }
3624 }
3625
3626 switch (sd->type)
3627 {
3628 case ELM_WIN_BASIC:
3629 ecore_x_netwm_window_type_set(sd->x.xwin, ECORE_X_WINDOW_TYPE_NORMAL);
3630 break;
3631
3632 case ELM_WIN_DIALOG_BASIC:
3633 ecore_x_netwm_window_type_set(sd->x.xwin, ECORE_X_WINDOW_TYPE_DIALOG);
3634 break;
3635
3636 case ELM_WIN_DESKTOP:
3637 ecore_x_netwm_window_type_set(sd->x.xwin, ECORE_X_WINDOW_TYPE_DESKTOP);
3638 break;
3639
3640 case ELM_WIN_DOCK:
3641 ecore_x_netwm_window_type_set(sd->x.xwin, ECORE_X_WINDOW_TYPE_DOCK);
3642 break;
3643
3644 case ELM_WIN_TOOLBAR:
3645 ecore_x_netwm_window_type_set(sd->x.xwin, ECORE_X_WINDOW_TYPE_TOOLBAR);
3646 break;
3647
3648 case ELM_WIN_MENU:
3649 ecore_x_netwm_window_type_set(sd->x.xwin, ECORE_X_WINDOW_TYPE_MENU);
3650 break;
3651
3652 case ELM_WIN_UTILITY:
3653 ecore_x_netwm_window_type_set(sd->x.xwin, ECORE_X_WINDOW_TYPE_UTILITY);
3654 break;
3655
3656 case ELM_WIN_SPLASH:
3657 ecore_x_netwm_window_type_set(sd->x.xwin, ECORE_X_WINDOW_TYPE_SPLASH);
3658 break;
3659
3660 case ELM_WIN_DROPDOWN_MENU:
3661 ecore_x_netwm_window_type_set
3662 (sd->x.xwin, ECORE_X_WINDOW_TYPE_DROPDOWN_MENU);
3663 break;
3664
3665 case ELM_WIN_POPUP_MENU:
3666 ecore_x_netwm_window_type_set
3667 (sd->x.xwin, ECORE_X_WINDOW_TYPE_POPUP_MENU);
3668 break;
3669
3670 case ELM_WIN_TOOLTIP:
3671 ecore_x_netwm_window_type_set(sd->x.xwin, ECORE_X_WINDOW_TYPE_TOOLTIP);
3672 ecore_x_window_shape_input_rectangle_set(sd->x.xwin, 0, 0, 0, 0);
3673 break;
3674
3675 case ELM_WIN_NOTIFICATION:
3676 ecore_x_netwm_window_type_set
3677 (sd->x.xwin, ECORE_X_WINDOW_TYPE_NOTIFICATION);
3678 break;
3679
3680 case ELM_WIN_COMBO:
3681 ecore_x_netwm_window_type_set(sd->x.xwin, ECORE_X_WINDOW_TYPE_COMBO);
3682 break;
3683
3684 case ELM_WIN_DND:
3685 ecore_x_netwm_window_type_set(sd->x.xwin, ECORE_X_WINDOW_TYPE_DND);
3686 break;
3687
3688 default:
3689 break;
3690 }
3691 ecore_x_e_virtual_keyboard_state_set
3692 (sd->x.xwin, (Ecore_X_Virtual_Keyboard_State)sd->kbdmode);
3693 if (sd->legacy.indmode == ELM_WIN_INDICATOR_SHOW)
3694 ecore_x_e_illume_indicator_state_set
3695 (sd->x.xwin, ECORE_X_ILLUME_INDICATOR_STATE_ON);
3696 else if (sd->legacy.indmode == ELM_WIN_INDICATOR_HIDE)
3697 ecore_x_e_illume_indicator_state_set
3698 (sd->x.xwin, ECORE_X_ILLUME_INDICATOR_STATE_OFF);
3699
3700 if ((sd->wm_rot.count) && (sd->wm_rot.rots))
3701 ecore_evas_wm_rotation_available_rotations_set(sd->ee,
3702 sd->wm_rot.rots,
3703 sd->wm_rot.count);
3704 if (sd->wm_rot.preferred_rot != -1)
3705 ecore_evas_wm_rotation_preferred_rotation_set(sd->ee,
3706 sd->wm_rot.preferred_rot);
3707
3708 #ifdef HAVE_ELEMENTARY_X
3709 if (sd->csd.need && sd->x.xwin)
3710 TRAP(sd, borderless_set, EINA_TRUE);
3711 #endif
3712 }
3713
3714 #endif
3715
3716 /**
3717 * @internal
3718 *
3719 * Resize the window according to window layout's min and weight.
3720 * If the window layout's weight is 0.0, the window max is limited to layout's
3721 * min size.
3722 *
3723 * This is called when the window layout's weight hint is changed or when the
3724 * window is rotated.
3725 *
3726 * @param obj window object
3727 */
3728 static void
_elm_win_resize_objects_eval(Evas_Object * obj,Eina_Bool force_resize)3729 _elm_win_resize_objects_eval(Evas_Object *obj, Eina_Bool force_resize)
3730 {
3731 Efl_Ui_Win_Data *sd = efl_data_scope_get(obj, MY_CLASS);
3732 Evas_Coord w, h, minw, minh, maxw, maxh, ow, oh;
3733 Eina_Bool unresizable;
3734 double wx, wy;
3735
3736 evas_object_size_hint_combined_min_get(sd->legacy.edje, &minw, &minh);
3737 if ((!minw) && (!minh) && (!sd->deferred_resize_job)) return;
3738
3739 efl_gfx_hint_size_restricted_max_set(obj, EINA_SIZE2D(-1, -1));
3740 // If content has a weight, make resizable
3741 efl_gfx_hint_weight_get(sd->legacy.edje, &wx, &wy);
3742
3743 // Content max hint is ignored
3744 maxw = sd->max_w;
3745 maxh = sd->max_h;
3746
3747 // Compatibility hack (for E)
3748 if (sd->single_edje_content && EINA_DBL_EQ(wx, 0) && EINA_DBL_EQ(wy, 0))
3749 wx = wy = 1;
3750
3751 if (EINA_DBL_EQ(wx, 0)) maxw = minw;
3752 if (maxw < 1) maxw = 32767;
3753 if (EINA_DBL_EQ(wy, 0)) maxh = minh;
3754 if (maxh < 1) maxh = 32767;
3755 if (maxw < minw) maxw = minw;
3756 if (maxh < minh) maxh = minh;
3757 if (maxw > 32767) maxw = 32767;
3758 if (maxh > 32767) maxh = 32767;
3759
3760 unresizable = ((minw == maxw) && (minh == maxh));
3761
3762 if (sd->csd.need_unresizable != unresizable)
3763 {
3764 sd->csd.need_unresizable = unresizable;
3765 _elm_win_frame_style_update(sd, 0, 1);
3766 }
3767
3768 if (sd->frame_obj)
3769 {
3770 int fw, fh;
3771
3772 evas_output_framespace_get(sd->evas, NULL, NULL, &fw, &fh);
3773 // minw += fw;
3774 // minh += fh;
3775 // maxw += fw;
3776 // maxh += fh;
3777 }
3778
3779 sd->tmp_updating_hints = 1;
3780 efl_gfx_hint_size_restricted_min_set(obj, EINA_SIZE2D(minw, minh));
3781 efl_gfx_hint_size_restricted_max_set(obj, EINA_SIZE2D(maxw, maxh));
3782 sd->tmp_updating_hints = 0;
3783 _elm_win_size_hints_update(obj, sd);
3784
3785 if (sd->deferred_resize_job)
3786 _elm_win_resize_job(sd->obj);
3787
3788 /* do not need to go below. if you go, ee could become 0. */
3789 if ((!minw) && (!minh)) return;
3790
3791 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3792 w = ow;
3793 h = oh;
3794 if (w < minw) w = minw;
3795 if (h < minh) h = minh;
3796 if (w > maxw) w = maxw;
3797 if (h > maxh) h = maxh;
3798 if (!force_resize && (w == ow) && (h == oh))
3799 return;
3800
3801 sd->req_wh = EINA_FALSE;
3802 if (sd->img_obj) evas_object_resize(obj, w, h);
3803 else
3804 {
3805 _elm_win_frame_geometry_adjust(sd);
3806 if (!sd->response)
3807 {
3808 sd->req_wh = EINA_TRUE;
3809 sd->req_w = w;
3810 sd->req_h = h;
3811 TRAP(sd, resize, w, h);
3812 }
3813 }
3814 }
3815
3816 static void
_elm_win_on_resize_obj_changed_size_hints(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)3817 _elm_win_on_resize_obj_changed_size_hints(void *data,
3818 Evas *e EINA_UNUSED,
3819 Evas_Object *obj EINA_UNUSED,
3820 void *event_info EINA_UNUSED)
3821 {
3822 _elm_win_resize_objects_eval(data, EINA_FALSE);
3823 }
3824
3825 void
_elm_win_shutdown(void)3826 _elm_win_shutdown(void)
3827 {
3828 while (_elm_win_list)
3829 {
3830 Eina_List *itr = _elm_win_list;
3831 evas_object_del(itr->data);
3832 if (_elm_win_list == itr)
3833 {
3834 _elm_win_list = eina_list_remove_list(_elm_win_list, _elm_win_list);
3835 }
3836 }
3837 ELM_SAFE_FREE(_elm_win_state_eval_timer, ecore_timer_del);
3838 }
3839
3840 void
_elm_win_rescale(Elm_Theme * th,Eina_Bool use_theme)3841 _elm_win_rescale(Elm_Theme *th,
3842 Eina_Bool use_theme)
3843 {
3844 const Eina_List *l;
3845 Evas_Object *obj;
3846
3847 if (!use_theme)
3848 {
3849 EINA_LIST_FOREACH(_elm_win_list, l, obj)
3850 elm_widget_theme(obj);
3851 }
3852 else
3853 {
3854 EINA_LIST_FOREACH(_elm_win_list, l, obj)
3855 elm_widget_theme_specific(obj, th, EINA_FALSE);
3856 }
3857 }
3858
3859 void
_elm_win_access(Eina_Bool is_access)3860 _elm_win_access(Eina_Bool is_access)
3861 {
3862 Evas *evas;
3863 const Eina_List *l;
3864 Evas_Object *obj;
3865 Evas_Object *fobj;
3866
3867 EINA_LIST_FOREACH(_elm_win_list, l, obj)
3868 {
3869 elm_widget_access(obj, is_access);
3870
3871 /* floating orphan object. if there are A, B, C objects and user does
3872 as below, then there would be floating orphan objects.
3873
3874 1. elm_object_content_set(layout, A);
3875 2. elm_object_content_set(layout, B);
3876 3. elm_object_content_set(layout, C);
3877
3878 now, the object A and B are floating orphan objects */
3879
3880 fobj = obj;
3881 for (;;)
3882 {
3883 fobj = evas_object_below_get(fobj);
3884 if (!fobj) break;
3885
3886 if (elm_widget_is(fobj) && !elm_widget_parent_get(fobj))
3887 {
3888 elm_widget_access(fobj, is_access);
3889 }
3890 }
3891
3892 if (!is_access)
3893 {
3894 evas = evas_object_evas_get(obj);
3895 if (evas) _elm_access_object_highlight_disable(evas);
3896 }
3897 }
3898 }
3899
3900 void
_elm_win_translate(void)3901 _elm_win_translate(void)
3902 {
3903 const Eina_List *l;
3904 Evas_Object *obj;
3905
3906 EINA_LIST_FOREACH(_elm_win_list, l, obj)
3907 efl_ui_l10n_translation_update(obj);
3908 }
3909
3910
3911 #ifdef HAVE_ELEMENTARY_X
3912 static Eina_Bool
_elm_win_client_message(void * data,int type EINA_UNUSED,void * event)3913 _elm_win_client_message(void *data,
3914 int type EINA_UNUSED,
3915 void *event)
3916 {
3917 ELM_WIN_DATA_GET(data, sd);
3918 Ecore_X_Event_Client_Message *e = event;
3919
3920 if (e->format != 32) return ECORE_CALLBACK_PASS_ON;
3921 _internal_elm_win_xwindow_get(sd);
3922 if (e->message_type == ECORE_X_ATOM_E_COMP_FLUSH)
3923 {
3924 if ((unsigned int)e->data.l[0] == sd->x.xwin)
3925 {
3926 Evas *evas = evas_object_evas_get(sd->obj);
3927 if (evas)
3928 {
3929 edje_file_cache_flush();
3930 edje_collection_cache_flush();
3931 evas_image_cache_flush(evas);
3932 evas_font_cache_flush(evas);
3933 }
3934 }
3935 }
3936 else if (e->message_type == ECORE_X_ATOM_E_COMP_DUMP)
3937 {
3938 if ((unsigned int)e->data.l[0] == sd->x.xwin)
3939 {
3940 Evas *evas = evas_object_evas_get(sd->obj);
3941 if (evas)
3942 {
3943 edje_file_cache_flush();
3944 edje_collection_cache_flush();
3945 evas_image_cache_flush(evas);
3946 evas_font_cache_flush(evas);
3947 evas_render_dump(evas);
3948 }
3949 }
3950 }
3951 else if (e->message_type == ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL)
3952 {
3953 if ((unsigned int)e->data.l[0] == sd->x.xwin)
3954 {
3955 if ((unsigned int)e->data.l[1] ==
3956 ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_NEXT)
3957 {
3958 // XXX: call right access func
3959 }
3960 else if ((unsigned int)e->data.l[1] ==
3961 ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_PREV)
3962 {
3963 // XXX: call right access func
3964 }
3965 else if ((unsigned int)e->data.l[1] ==
3966 ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE)
3967 {
3968 _elm_access_highlight_object_activate
3969 (sd->obj, EFL_UI_ACTIVATE_DEFAULT);
3970 }
3971 else if ((unsigned int)e->data.l[1] ==
3972 ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ)
3973 {
3974 /* there would be better way to read highlight object */
3975 Evas *evas;
3976 evas = evas_object_evas_get(sd->obj);
3977 if (!evas) return ECORE_CALLBACK_PASS_ON;
3978
3979 _elm_access_mouse_event_enabled_set(EINA_TRUE);
3980
3981 evas_event_feed_mouse_in(evas, 0, NULL);
3982 evas_event_feed_mouse_move
3983 (evas, e->data.l[2], e->data.l[3], 0, NULL);
3984
3985 _elm_access_mouse_event_enabled_set(EINA_FALSE);
3986 }
3987 else if ((unsigned int)e->data.l[1] ==
3988 ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_NEXT)
3989 {
3990 _elm_access_highlight_cycle(sd->obj, ELM_FOCUS_NEXT);
3991 }
3992 else if ((unsigned int)e->data.l[1] ==
3993 ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_PREV)
3994 {
3995 _elm_access_highlight_cycle(sd->obj, ELM_FOCUS_PREVIOUS);
3996 }
3997 else if ((unsigned int)e->data.l[1] ==
3998 ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_UP)
3999 {
4000 _elm_access_highlight_object_activate
4001 (sd->obj, EFL_UI_ACTIVATE_UP);
4002 }
4003 else if ((unsigned int)e->data.l[1] ==
4004 ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DOWN)
4005 {
4006 _elm_access_highlight_object_activate
4007 (sd->obj, EFL_UI_ACTIVATE_DOWN);
4008 }
4009 }
4010 }
4011 return ECORE_CALLBACK_PASS_ON;
4012 }
4013
4014 static Eina_Bool
_elm_win_property_change(void * data,int type EINA_UNUSED,void * event)4015 _elm_win_property_change(void *data,
4016 int type EINA_UNUSED,
4017 void *event)
4018 {
4019 ELM_WIN_DATA_GET(data, sd);
4020 Ecore_X_Event_Window_Property *e = event;
4021
4022 if (e->atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_STATE)
4023 {
4024 _internal_elm_win_xwindow_get(sd);
4025 if (e->win == sd->x.xwin)
4026 {
4027 sd->legacy.indmode = (Elm_Win_Indicator_Mode)ecore_x_e_illume_indicator_state_get(e->win);
4028 efl_event_callback_legacy_call
4029 (sd->obj, EFL_UI_WIN_EVENT_INDICATOR_PROP_CHANGED, NULL);
4030 }
4031 }
4032 return ECORE_CALLBACK_PASS_ON;
4033 }
4034 #endif
4035
4036 #ifdef HAVE_ELEMENTARY_WIN32
4037 static Eina_Bool
_elm_win_key_down(void * data,int type EINA_UNUSED,void * event)4038 _elm_win_key_down(void *data,
4039 int type EINA_UNUSED,
4040 void *event)
4041 {
4042 ELM_WIN_DATA_GET(data, sd);
4043 Ecore_Event_Key *e = event;
4044 if ((e->modifiers & ECORE_EVENT_MODIFIER_ALT) &&
4045 (strcmp(e->key, "F4") == 0))
4046 _elm_win_delete_request(sd->ee);
4047
4048 return ECORE_CALLBACK_PASS_ON;
4049 }
4050
4051 #endif
4052
4053 static void
_elm_win_focus_highlight_hide(void * data EINA_UNUSED,Evas_Object * obj,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)4054 _elm_win_focus_highlight_hide(void *data EINA_UNUSED,
4055 Evas_Object *obj,
4056 const char *emission EINA_UNUSED,
4057 const char *source EINA_UNUSED)
4058 {
4059 evas_object_hide(obj);
4060 }
4061
4062 static void
_elm_win_focus_highlight_anim_end(void * data,Evas_Object * obj,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)4063 _elm_win_focus_highlight_anim_end(void *data,
4064 Evas_Object *obj,
4065 const char *emission EINA_UNUSED,
4066 const char *source EINA_UNUSED)
4067 {
4068 ELM_WIN_DATA_GET(data, sd);
4069
4070 _elm_win_focus_highlight_simple_setup(sd, obj);
4071 }
4072
4073 static void
_elm_win_focus_highlight_init(Efl_Ui_Win_Data * sd)4074 _elm_win_focus_highlight_init(Efl_Ui_Win_Data *sd)
4075 {
4076 evas_event_callback_add(sd->evas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN,
4077 _elm_win_object_focus_in, sd->obj);
4078 evas_event_callback_add(sd->evas,
4079 EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_OUT,
4080 _elm_win_object_focus_out, sd->obj);
4081
4082 sd->focus_highlight.cur.target = _elm_win_focus_target_get(evas_focus_get(sd->evas));
4083 if (sd->focus_highlight.cur.target)
4084 {
4085 if (elm_widget_highlight_in_theme_get(sd->focus_highlight.cur.target))
4086 sd->focus_highlight.cur.in_theme = EINA_TRUE;
4087 else
4088 _elm_win_focus_target_callbacks_add(sd);
4089
4090 evas_object_event_callback_add
4091 (sd->focus_highlight.cur.target,
4092 EVAS_CALLBACK_DEL, _elm_win_focus_target_del, sd->obj);
4093 }
4094
4095 sd->focus_highlight.prev.target = NULL;
4096 sd->focus_highlight.theme_changed = EINA_TRUE;
4097 if (!sd->focus_highlight.fobj)
4098 {
4099 sd->focus_highlight.fobj = edje_object_add(sd->evas);
4100
4101 if (elm_widget_is_legacy(sd->obj))
4102 {
4103 edje_object_signal_callback_add(sd->focus_highlight.fobj,
4104 "elm,action,focus,hide,end", "*",
4105 _elm_win_focus_highlight_hide, NULL);
4106 edje_object_signal_callback_add(sd->focus_highlight.fobj,
4107 "elm,action,focus,anim,end", "*",
4108 _elm_win_focus_highlight_anim_end, sd->obj);
4109 }
4110 else
4111 {
4112 edje_object_signal_callback_add(sd->focus_highlight.fobj,
4113 "efl,focus,visible,off,done", "*",
4114 _elm_win_focus_highlight_hide, NULL);
4115 edje_object_signal_callback_add(sd->focus_highlight.fobj,
4116 "efl,action,focus,anim,end", "*",
4117 _elm_win_focus_highlight_anim_end, sd->obj);
4118 }
4119 }
4120
4121 _elm_win_focus_highlight_reconfigure_job_start(sd);
4122 }
4123
4124 typedef struct _resize_info {
4125 const char *source;
4126 const char *cursor;
4127 Efl_Ui_Win_Move_Resize_Mode mode;
4128 int wl_location;
4129 #ifdef HAVE_ELEMENTARY_X
4130 #define XDIR(d) , ECORE_X_NETWM_DIRECTION_##d
4131 Ecore_X_Netwm_Direction x_dir;
4132 #else
4133 # define XDIR(d)
4134 #endif
4135 } resize_info;
4136
4137 static const resize_info _resize_infos_legacy[8] = {
4138 { "elm.event.resize.t", ELM_CURSOR_TOP_SIDE, EFL_UI_WIN_MOVE_RESIZE_MODE_TOP, 1 XDIR(SIZE_T) },
4139 { "elm.event.resize.b", ELM_CURSOR_BOTTOM_SIDE, EFL_UI_WIN_MOVE_RESIZE_MODE_BOTTOM, 2 XDIR(SIZE_B) },
4140 { "elm.event.resize.l", ELM_CURSOR_LEFT_SIDE, EFL_UI_WIN_MOVE_RESIZE_MODE_LEFT, 4 XDIR(SIZE_L) },
4141 { "elm.event.resize.r", ELM_CURSOR_RIGHT_SIDE, EFL_UI_WIN_MOVE_RESIZE_MODE_RIGHT, 8 XDIR(SIZE_R) },
4142 { "elm.event.resize.tl", ELM_CURSOR_TOP_LEFT_CORNER, EFL_UI_WIN_MOVE_RESIZE_MODE_TOP | EFL_UI_WIN_MOVE_RESIZE_MODE_LEFT, 5 XDIR(SIZE_TL) },
4143 { "elm.event.resize.bl", ELM_CURSOR_BOTTOM_LEFT_CORNER, EFL_UI_WIN_MOVE_RESIZE_MODE_BOTTOM | EFL_UI_WIN_MOVE_RESIZE_MODE_LEFT, 6 XDIR(SIZE_BL) },
4144 { "elm.event.resize.br", ELM_CURSOR_BOTTOM_RIGHT_CORNER, EFL_UI_WIN_MOVE_RESIZE_MODE_BOTTOM | EFL_UI_WIN_MOVE_RESIZE_MODE_RIGHT, 10 XDIR(SIZE_BR) },
4145 { "elm.event.resize.tr", ELM_CURSOR_TOP_RIGHT_CORNER, EFL_UI_WIN_MOVE_RESIZE_MODE_TOP | EFL_UI_WIN_MOVE_RESIZE_MODE_RIGHT, 9 XDIR(SIZE_TR) },
4146 };
4147
4148 static const resize_info _resize_infos[8] = {
4149 { "efl.event.resize.t", ELM_CURSOR_TOP_SIDE, EFL_UI_WIN_MOVE_RESIZE_MODE_TOP, 1 XDIR(SIZE_T) },
4150 { "efl.event.resize.b", ELM_CURSOR_BOTTOM_SIDE, EFL_UI_WIN_MOVE_RESIZE_MODE_BOTTOM, 2 XDIR(SIZE_B) },
4151 { "efl.event.resize.l", ELM_CURSOR_LEFT_SIDE, EFL_UI_WIN_MOVE_RESIZE_MODE_LEFT, 4 XDIR(SIZE_L) },
4152 { "efl.event.resize.r", ELM_CURSOR_RIGHT_SIDE, EFL_UI_WIN_MOVE_RESIZE_MODE_RIGHT, 8 XDIR(SIZE_R) },
4153 { "efl.event.resize.tl", ELM_CURSOR_TOP_LEFT_CORNER, EFL_UI_WIN_MOVE_RESIZE_MODE_TOP | EFL_UI_WIN_MOVE_RESIZE_MODE_LEFT, 5 XDIR(SIZE_TL) },
4154 { "efl.event.resize.bl", ELM_CURSOR_BOTTOM_LEFT_CORNER, EFL_UI_WIN_MOVE_RESIZE_MODE_BOTTOM | EFL_UI_WIN_MOVE_RESIZE_MODE_LEFT, 6 XDIR(SIZE_BL) },
4155 { "efl.event.resize.br", ELM_CURSOR_BOTTOM_RIGHT_CORNER, EFL_UI_WIN_MOVE_RESIZE_MODE_BOTTOM | EFL_UI_WIN_MOVE_RESIZE_MODE_RIGHT, 10 XDIR(SIZE_BR) },
4156 { "efl.event.resize.tr", ELM_CURSOR_TOP_RIGHT_CORNER, EFL_UI_WIN_MOVE_RESIZE_MODE_TOP | EFL_UI_WIN_MOVE_RESIZE_MODE_RIGHT, 9 XDIR(SIZE_TR) },
4157 };
4158
4159 static inline Efl_Ui_Win_Move_Resize_Mode
_move_resize_mode_rotate(int rotation,Efl_Ui_Win_Move_Resize_Mode mode)4160 _move_resize_mode_rotate(int rotation, Efl_Ui_Win_Move_Resize_Mode mode)
4161 {
4162 const Efl_Ui_Win_Move_Resize_Mode edges[4] = {
4163 EFL_UI_WIN_MOVE_RESIZE_MODE_TOP, EFL_UI_WIN_MOVE_RESIZE_MODE_LEFT,
4164 EFL_UI_WIN_MOVE_RESIZE_MODE_BOTTOM, EFL_UI_WIN_MOVE_RESIZE_MODE_RIGHT
4165 };
4166
4167 const Efl_Ui_Win_Move_Resize_Mode corners[4] = {
4168 EFL_UI_WIN_MOVE_RESIZE_MODE_TOP | EFL_UI_WIN_MOVE_RESIZE_MODE_LEFT,
4169 EFL_UI_WIN_MOVE_RESIZE_MODE_BOTTOM | EFL_UI_WIN_MOVE_RESIZE_MODE_LEFT,
4170 EFL_UI_WIN_MOVE_RESIZE_MODE_BOTTOM | EFL_UI_WIN_MOVE_RESIZE_MODE_RIGHT,
4171 EFL_UI_WIN_MOVE_RESIZE_MODE_TOP | EFL_UI_WIN_MOVE_RESIZE_MODE_RIGHT,
4172 };
4173
4174 const int i = rotation / 90;
4175 int k;
4176
4177 for (k = 0; k < 4; k++)
4178 if (mode == edges[k])
4179 return edges[(k + i) % 4];
4180
4181 for (k = 0; k < 4; k++)
4182 if (mode == corners[k])
4183 return corners[(k + i) % 4];
4184
4185 return EFL_UI_WIN_MOVE_RESIZE_MODE_MOVE;
4186 }
4187
4188 static const resize_info *
_resize_info_get(Evas_Object * obj,int rotation,Efl_Ui_Win_Move_Resize_Mode mode)4189 _resize_info_get(Evas_Object *obj, int rotation, Efl_Ui_Win_Move_Resize_Mode mode)
4190 {
4191 if (rotation)
4192 return _resize_info_get(obj, 0, _move_resize_mode_rotate(rotation, mode));
4193
4194 if (elm_widget_is_legacy(obj))
4195 {
4196 for (size_t k = 0; k < EINA_C_ARRAY_LENGTH(_resize_infos_legacy); k++)
4197 {
4198 if (_resize_infos_legacy[k].mode == mode)
4199 return &_resize_infos_legacy[k];
4200 }
4201 }
4202 else
4203 {
4204 for (size_t k = 0; k < EINA_C_ARRAY_LENGTH(_resize_infos); k++)
4205 {
4206 if (_resize_infos[k].mode == mode)
4207 return &_resize_infos[k];
4208 }
4209 }
4210
4211 return NULL;
4212 }
4213
4214 static Efl_Ui_Win_Move_Resize_Mode
_move_resize_mode_get(Evas_Object * obj,const char * source)4215 _move_resize_mode_get(Evas_Object *obj, const char *source)
4216 {
4217 if (elm_widget_is_legacy(obj))
4218 {
4219 for (size_t k = 0; k < EINA_C_ARRAY_LENGTH(_resize_infos_legacy); k++)
4220 if (!strcmp(source, _resize_infos_legacy[k].source))
4221 return _resize_infos_legacy[k].mode;
4222 }
4223 else
4224 {
4225 for (size_t k = 0; k < EINA_C_ARRAY_LENGTH(_resize_infos); k++)
4226 if (!strcmp(source, _resize_infos[k].source))
4227 return _resize_infos[k].mode;
4228 }
4229
4230 return EFL_UI_WIN_MOVE_RESIZE_MODE_MOVE;
4231 }
4232
4233 static void
_elm_win_frame_obj_move(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)4234 _elm_win_frame_obj_move(void *data,
4235 Evas *e EINA_UNUSED,
4236 Evas_Object *obj EINA_UNUSED,
4237 void *event_info EINA_UNUSED)
4238 {
4239 Efl_Ui_Win_Data *sd;
4240
4241 if (!(sd = data)) return;
4242 if (!sd->legacy.edje) return;
4243
4244 _elm_win_frame_obj_update(sd, 0);
4245 }
4246
4247 static void
_elm_win_frame_obj_resize(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)4248 _elm_win_frame_obj_resize(void *data,
4249 Evas *e EINA_UNUSED,
4250 Evas_Object *obj EINA_UNUSED,
4251 void *event_info EINA_UNUSED)
4252 {
4253 Efl_Ui_Win_Data *sd;
4254
4255 if (!(sd = data)) return;
4256 if (!sd->legacy.edje) return;
4257 if (sd->ignore_frame_resize > 0) return;
4258
4259 _elm_win_frame_obj_update(sd, 0);
4260 }
4261
4262 static void
_elm_win_frame_cb_resize_show(void * data,Evas_Object * obj EINA_UNUSED,const char * sig EINA_UNUSED,const char * source)4263 _elm_win_frame_cb_resize_show(void *data,
4264 Evas_Object *obj EINA_UNUSED,
4265 const char *sig EINA_UNUSED,
4266 const char *source)
4267 {
4268 ELM_WIN_DATA_GET(data, sd);
4269
4270 if (!sd) return;
4271 if (sd->resizing) return;
4272
4273 #ifdef HAVE_ELEMENTARY_WL2
4274 if (sd->pointer.obj)
4275 {
4276 Efl_Ui_Win_Move_Resize_Mode mode = _move_resize_mode_get(sd->obj, source);
4277 const resize_info *ri = _resize_info_get(sd->obj, sd->rot, mode);
4278 if (ri) elm_widget_theme_object_set(sd->obj, sd->pointer.obj, "pointer", "base", ri->cursor);
4279 }
4280 #else
4281 (void)source;
4282 #endif
4283 }
4284
4285 static void
_elm_win_frame_cb_resize_hide(void * data,Evas_Object * obj EINA_UNUSED,const char * sig EINA_UNUSED,const char * source EINA_UNUSED)4286 _elm_win_frame_cb_resize_hide(void *data,
4287 Evas_Object *obj EINA_UNUSED,
4288 const char *sig EINA_UNUSED,
4289 const char *source EINA_UNUSED)
4290 {
4291 ELM_WIN_DATA_GET(data, sd);
4292
4293 if (!sd) return;
4294 if (sd->resizing) return;
4295
4296 #ifdef HAVE_ELEMENTARY_WL2
4297 if (sd->pointer.obj)
4298 elm_widget_theme_object_set(sd->obj, sd->pointer.obj,
4299 "pointer", "base", "default");
4300 #endif
4301 }
4302
4303 #ifdef HAVE_ELEMENTARY_WL2
4304 /* This only works when called from an edje event
4305 * that propagates seat info...
4306 */
4307 static Ecore_Wl2_Input *
_elm_win_wayland_input_get(Efl_Ui_Win_Data * sd)4308 _elm_win_wayland_input_get(Efl_Ui_Win_Data *sd)
4309 {
4310 Ecore_Wl2_Display *di;
4311 char *sname;
4312 const char *engine;
4313
4314 engine = ecore_evas_engine_name_get(sd->ee);
4315 if (strcmp(engine, ELM_WAYLAND_SHM) &&
4316 strcmp(engine, ELM_WAYLAND_EGL))
4317 return NULL;
4318
4319 di = ecore_wl2_window_display_get(sd->wl.win);
4320
4321 sname = edje_object_signal_callback_seat_data_get();
4322 if (!sname) return NULL;
4323 return ecore_wl2_display_input_find_by_name(di, sname);
4324 }
4325 #endif
4326
4327 static inline Eina_Bool
_win_move_start(Efl_Ui_Win_Data * sd)4328 _win_move_start(Efl_Ui_Win_Data *sd)
4329 {
4330 #ifdef HAVE_ELEMENTARY_WL2
4331 if (sd->wl.win)
4332 {
4333 Ecore_Wl2_Input *ei;
4334
4335 ei = _elm_win_wayland_input_get(sd);
4336 ecore_wl2_window_move(sd->wl.win, ei);
4337 return EINA_TRUE;
4338 }
4339 #endif
4340
4341 #ifdef HAVE_ELEMENTARY_X
4342 if (sd->x.xwin)
4343 {
4344 int x, y;
4345
4346 _internal_elm_win_xwindow_get(sd);
4347 sd->resizing = EINA_TRUE;
4348 ecore_x_pointer_ungrab();
4349 ecore_x_pointer_root_xy_get(&x, &y);
4350 ecore_x_netwm_moveresize_request_send(sd->x.xwin, x, y,
4351 ECORE_X_NETWM_DIRECTION_MOVE, 1);
4352 return EINA_TRUE;
4353 }
4354 #endif
4355
4356 INF("Window move request not supported for this window!");
4357 return EINA_FALSE;
4358 }
4359
4360 static Eina_Bool
_win_move_resize_start(Efl_Ui_Win_Data * sd,Efl_Ui_Win_Move_Resize_Mode mode)4361 _win_move_resize_start(Efl_Ui_Win_Data *sd, Efl_Ui_Win_Move_Resize_Mode mode)
4362 {
4363 EINA_SAFETY_ON_NULL_RETURN_VAL(sd, EINA_FALSE);
4364 const resize_info *ri;
4365
4366 // 2. check move_resize already started
4367 if (sd->resizing)
4368 {
4369 ERR("Window is already being resized.");
4370 return EINA_FALSE;
4371 }
4372
4373 if (mode == EFL_UI_WIN_MOVE_RESIZE_MODE_MOVE)
4374 return _win_move_start(sd);
4375
4376 ri = _resize_info_get(sd->obj, sd->rot, mode);
4377 if (!ri)
4378 {
4379 ERR("Unsupported move_resize mode %#x", (int) mode);
4380 return EINA_FALSE;
4381 }
4382
4383 sd->resizing = EINA_TRUE;
4384
4385 #ifdef HAVE_ELEMENTARY_WL2
4386 if (sd->wl.win)
4387 {
4388 Ecore_Wl2_Input *ei;
4389
4390 ei = _elm_win_wayland_input_get(sd);
4391 ecore_wl2_window_resize(sd->wl.win, ei, ri->wl_location);
4392 return EINA_TRUE;
4393 }
4394 #endif
4395
4396 #ifdef HAVE_ELEMENTARY_X
4397 if (sd->x.xwin)
4398 {
4399 int x, y;
4400 _internal_elm_win_xwindow_get(sd);
4401 ecore_x_pointer_ungrab();
4402 ecore_x_pointer_root_xy_get(&x, &y);
4403 ecore_x_netwm_moveresize_request_send(sd->x.xwin, x, y, ri->x_dir, 1);
4404 return EINA_TRUE;
4405 }
4406 #endif
4407
4408 INF("Window resize request not supported for this window!");
4409 return EINA_FALSE;
4410 }
4411
4412 static void
_elm_win_frame_cb_move_start(void * data,Evas_Object * obj EINA_UNUSED,const char * sig EINA_UNUSED,const char * source EINA_UNUSED)4413 _elm_win_frame_cb_move_start(void *data,
4414 Evas_Object *obj EINA_UNUSED,
4415 const char *sig EINA_UNUSED,
4416 const char *source EINA_UNUSED)
4417 {
4418 ELM_WIN_DATA_GET_OR_RETURN(data, sd);
4419
4420 _win_move_resize_start(sd, EFL_UI_WIN_MOVE_RESIZE_MODE_MOVE);
4421 }
4422
4423 static void
_elm_win_frame_cb_resize_start(void * data,Evas_Object * obj EINA_UNUSED,const char * sig EINA_UNUSED,const char * source)4424 _elm_win_frame_cb_resize_start(void *data, Evas_Object *obj EINA_UNUSED,
4425 const char *sig EINA_UNUSED, const char *source)
4426 {
4427 ELM_WIN_DATA_GET_OR_RETURN(data, sd);
4428 Efl_Ui_Win_Move_Resize_Mode mode;
4429
4430 mode = _move_resize_mode_get(sd->obj, source);
4431 if (mode == EFL_UI_WIN_MOVE_RESIZE_MODE_MOVE) return;
4432
4433 _win_move_resize_start(sd, mode);
4434 }
4435
4436 static void
_elm_win_frame_cb_minimize(void * data,Evas_Object * obj EINA_UNUSED,const char * sig EINA_UNUSED,const char * source EINA_UNUSED)4437 _elm_win_frame_cb_minimize(void *data,
4438 Evas_Object *obj EINA_UNUSED,
4439 const char *sig EINA_UNUSED,
4440 const char *source EINA_UNUSED)
4441 {
4442 ELM_WIN_DATA_GET(data, sd);
4443
4444 if (!sd) return;
4445 // sd->minimized = EINA_TRUE;
4446 TRAP(sd, iconified_set, EINA_TRUE);
4447 }
4448
4449 static void
_elm_win_frame_cb_maximize(void * data,Evas_Object * obj EINA_UNUSED,const char * sig EINA_UNUSED,const char * source EINA_UNUSED)4450 _elm_win_frame_cb_maximize(void *data,
4451 Evas_Object *obj EINA_UNUSED,
4452 const char *sig EINA_UNUSED,
4453 const char *source EINA_UNUSED)
4454 {
4455 Eina_Bool value;
4456 ELM_WIN_DATA_GET(data, sd);
4457
4458 if (!sd) return;
4459 if (sd->maximized) value = EINA_FALSE;
4460 else value = EINA_TRUE;
4461
4462 efl_ui_win_maximized_set(sd->obj, value);
4463 }
4464
4465 static void
_elm_win_frame_cb_menu(void * data,Evas_Object * obj EINA_UNUSED,const char * sig EINA_UNUSED,const char * source EINA_UNUSED)4466 _elm_win_frame_cb_menu(void *data,
4467 Evas_Object *obj EINA_UNUSED,
4468 const char *sig EINA_UNUSED,
4469 const char *source EINA_UNUSED)
4470 {
4471 ELM_WIN_DATA_GET(data, sd);
4472 #ifdef HAVE_ELEMENTARY_WL2
4473 Ecore_Wl2_Input *input;
4474 int x, y, wx, wy;
4475
4476 if (!sd->wl.win) return;
4477 evas_pointer_canvas_xy_get(sd->evas, &x, &y);
4478 ecore_wl2_window_geometry_get(sd->wl.win, &wx, &wy, NULL, NULL);
4479 if (x < 0) x += wx;
4480 if (y < 0) y += wy;
4481
4482 {
4483 Eina_Iterator *it;
4484 Ecore_Wl2_Display *display = ecore_wl2_window_display_get(sd->wl.win);
4485 it = ecore_wl2_display_inputs_get(display);
4486 EINA_ITERATOR_FOREACH(it, input) break;
4487 eina_iterator_free(it);
4488 }
4489 if (sd->wl.win->xdg_toplevel)
4490 {
4491 xdg_toplevel_show_window_menu(sd->wl.win->xdg_toplevel,
4492 ecore_wl2_input_seat_get(input), 0, x, y);
4493 ecore_wl2_display_flush(input->display);
4494 }
4495 else if (sd->wl.win->zxdg_toplevel)
4496 {
4497 zxdg_toplevel_v6_show_window_menu(sd->wl.win->zxdg_toplevel,
4498 ecore_wl2_input_seat_get(input), 0, x, y);
4499 ecore_wl2_display_flush(input->display);
4500 }
4501 #else
4502 (void)sd;
4503 #endif
4504 }
4505 static void
_elm_win_frame_cb_close(void * data,Evas_Object * obj EINA_UNUSED,const char * sig EINA_UNUSED,const char * source EINA_UNUSED)4506 _elm_win_frame_cb_close(void *data,
4507 Evas_Object *obj EINA_UNUSED,
4508 const char *sig EINA_UNUSED,
4509 const char *source EINA_UNUSED)
4510 {
4511 ELM_WIN_DATA_GET(data, sd);
4512 Evas_Object *win;
4513
4514 /* FIXME: After the current freeze, this should be handled differently.
4515 *
4516 * Ideally, we would want to mimic the X11 backend and use something
4517 * like ECORE_WL_EVENT_WINDOW_DELETE and handle the delete_request
4518 * inside of ecore_evas. That would be the 'proper' way, but since we are
4519 * in a freeze right now, I cannot add a new event value, or a new
4520 * event structure to ecore_wayland.
4521 *
4522 * So yes, this is a temporary 'stop-gap' solution which will be fixed
4523 * when the freeze is over, but it does fix a trac bug for now, and in a
4524 * way which does not break API or the freeze. - dh
4525 */
4526
4527 if (!sd) return;
4528
4529 win = sd->obj;
4530
4531 int autodel = sd->autodel;
4532 sd->autodel_clear = &autodel;
4533 evas_object_ref(win);
4534 efl_event_callback_legacy_call(win, EFL_UI_WIN_EVENT_DELETE_REQUEST, NULL);
4535 if (sd->autohide)
4536 evas_object_hide(win);
4537 // FIXME: if above callback deletes - then the below will be invalid
4538 if (autodel) evas_object_del(win);
4539 else sd->autodel_clear = NULL;
4540 evas_object_unref(win);
4541 }
4542
4543 #ifdef HAVE_ELEMENTARY_WL2
4544 static Eina_Bool
_elm_win_wl_configure(void * data,int t EINA_UNUSED,void * event)4545 _elm_win_wl_configure(void *data, int t EINA_UNUSED, void *event)
4546 {
4547 Ecore_Wl2_Event_Window_Configure *ev = event;
4548 ELM_WIN_DATA_GET(data, sd);
4549 if (sd->wl.win != ev->win) return ECORE_CALLBACK_RENEW;
4550
4551 if (sd->resizing && (!ev->edges)) sd->resizing = EINA_FALSE;
4552 return ECORE_CALLBACK_RENEW;
4553 }
4554
4555 #endif
4556
4557 static inline void
_elm_object_part_cursor_set(Evas_Object * obj,Evas_Object * edj,const char * part,const char * cursor)4558 _elm_object_part_cursor_set(Evas_Object *obj, Evas_Object *edj,
4559 const char *part, const char *cursor)
4560 {
4561 Evas_Object *sub;
4562
4563 edje_object_freeze(edj);
4564 sub = (Evas_Object *)edje_object_part_object_get(edj, part);
4565 edje_object_thaw(edj);
4566 if (!sub) return;
4567
4568 elm_object_sub_cursor_set(sub, obj, cursor);
4569 }
4570
4571 static char *
_efl_system_theme_path_get(void)4572 _efl_system_theme_path_get(void)
4573 {
4574 // Find the default theme from EFL install. Quite ugly.
4575 const char *sysdir;
4576 char *version;
4577 char path[PATH_MAX];
4578 int v;
4579
4580 sysdir = elm_theme_system_dir_get();
4581 if (!sysdir) return NULL;
4582
4583 eina_file_path_join(path, PATH_MAX, sysdir, "default.edj");
4584 version = edje_file_data_get(path, "version");
4585 v = version ? atoi(version) : 0;
4586 free(version);
4587 if (v < FRAME_OBJ_THEME_MIN_VERSION)
4588 {
4589 ERR("Default system theme is too old, something is wrong with your installation of EFL.");
4590 return NULL;
4591 }
4592 return strdup(path);
4593 }
4594
4595 static void
_elm_win_frame_add(Efl_Ui_Win_Data * sd,const char * element,const char * style)4596 _elm_win_frame_add(Efl_Ui_Win_Data *sd, const char *element, const char *style)
4597 {
4598 Evas_Object *obj = sd->obj;
4599 int w, h, v;
4600 const char *version;
4601
4602 if (sd->frame_obj) return;
4603
4604 sd->frame_obj = edje_object_add(sd->evas);
4605
4606 // Verify theme version. Border requires an exact theme API.
4607 version = elm_theme_data_get(elm_widget_theme_get(sd->obj), "version");
4608 v = version ? atoi(version) : 0;
4609 if (EINA_LIKELY(v >= FRAME_OBJ_THEME_MIN_VERSION))
4610 {
4611 if (elm_widget_theme_object_set
4612 (sd->obj, sd->frame_obj, "border", element, style) == EFL_UI_THEME_APPLY_ERROR_GENERIC)
4613 {
4614 ERR("Failed to set main border theme for the window.");
4615 ELM_SAFE_FREE(sd->frame_obj, evas_object_del);
4616 return;
4617 }
4618
4619 // Verify border.edc version as well
4620 version = edje_object_data_get(sd->frame_obj, "version");
4621 v = version ? atoi(version) : 0;
4622 }
4623
4624 if (v < FRAME_OBJ_THEME_MIN_VERSION)
4625 {
4626 // Theme compatibility
4627 const char *key = "elm/border/base/default"; // FIXME?
4628 char *sys_theme;
4629
4630 WRN("Selected theme does not support the required border theme API "
4631 "(version = %d, requires >= %d).",
4632 v, FRAME_OBJ_THEME_MIN_VERSION);
4633 sys_theme = _efl_system_theme_path_get();
4634 if (!sys_theme ||
4635 !edje_object_file_set(sd->frame_obj, sys_theme, key))
4636 {
4637 ERR("Failed to set main border theme for the window.");
4638 ELM_SAFE_FREE(sd->frame_obj, evas_object_del);
4639 free(sys_theme);
4640 return;
4641 }
4642 free(sys_theme);
4643 }
4644
4645 edje_object_freeze(sd->frame_obj);
4646 /* Small hack: The special value 2 means this is the top frame object.
4647 * We propagate to the children now (the edc group contents), but subsequent
4648 * calls to smart_member_add will not propagate the flag further. Note that
4649 * this little hack will fall apart if edje creates and destroys objects on
4650 * the fly. */
4651 efl_canvas_object_is_frame_object_set(sd->frame_obj, 2);
4652
4653 if (elm_widget_is_legacy(sd->obj))
4654 edje_object_part_swallow(sd->frame_obj, "elm.swallow.client", sd->legacy.edje);
4655 else
4656 edje_object_part_swallow(sd->frame_obj, "efl.client", sd->legacy.edje);
4657
4658 if (sd->icon)
4659 evas_object_show(sd->icon);
4660 else
4661 {
4662 Eina_Bool set = EINA_FALSE;
4663 Eina_Bool legacy = elm_widget_is_legacy(sd->obj);
4664
4665 if (legacy)
4666 sd->icon = elm_icon_add(sd->obj);
4667 else
4668 sd->icon = efl_add(EFL_UI_IMAGE_CLASS, sd->obj);
4669
4670 if (sd->icon_name)
4671 {
4672 if (legacy)
4673 set = elm_icon_standard_set(sd->icon, sd->icon_name);
4674 else
4675 set = efl_ui_image_icon_set(sd->icon, sd->icon_name);
4676 }
4677 if (((!sd->icon_name) || (!set)) && _elm_appname)
4678 {
4679 Efreet_Desktop *d;
4680 d = efreet_util_desktop_exec_find(_elm_appname);
4681 if (d)
4682 {
4683 if (legacy)
4684 elm_icon_standard_set(sd->icon, d->icon);
4685 else
4686 efl_ui_image_icon_set(sd->icon, d->icon);
4687 efreet_desktop_free(d);
4688 }
4689 }
4690 efl_access_object_access_type_set(sd->icon, EFL_ACCESS_TYPE_DISABLED);
4691 }
4692
4693 if (elm_widget_is_legacy(sd->obj))
4694 edje_object_part_swallow(sd->frame_obj, "elm.swallow.icon", sd->icon);
4695 else
4696 edje_object_part_swallow(sd->frame_obj, "efl.icon", sd->icon);
4697
4698 efl_canvas_object_is_frame_object_set(sd->icon, EINA_TRUE);
4699
4700 evas_object_event_callback_add
4701 (sd->frame_obj, EVAS_CALLBACK_MOVE, _elm_win_frame_obj_move, sd);
4702 evas_object_event_callback_add
4703 (sd->frame_obj, EVAS_CALLBACK_RESIZE, _elm_win_frame_obj_resize, sd);
4704
4705 if (elm_widget_is_legacy(sd->obj))
4706 {
4707 edje_object_signal_callback_add
4708 (sd->frame_obj, "elm,action,move,start", "elm",
4709 _elm_win_frame_cb_move_start, obj);
4710 edje_object_signal_callback_add
4711 (sd->frame_obj, "elm,action,resize,show", "*",
4712 _elm_win_frame_cb_resize_show, obj);
4713 edje_object_signal_callback_add
4714 (sd->frame_obj, "elm,action,resize,hide", "*",
4715 _elm_win_frame_cb_resize_hide, obj);
4716 edje_object_signal_callback_add
4717 (sd->frame_obj, "elm,action,resize,start", "*",
4718 _elm_win_frame_cb_resize_start, obj);
4719 edje_object_signal_callback_add
4720 (sd->frame_obj, "elm,action,minimize", "elm",
4721 _elm_win_frame_cb_minimize, obj);
4722 edje_object_signal_callback_add
4723 (sd->frame_obj, "elm,action,maximize", "elm",
4724 _elm_win_frame_cb_maximize, obj);
4725 edje_object_signal_callback_add
4726 (sd->frame_obj, "elm,action,close", "elm",
4727 _elm_win_frame_cb_close, obj);
4728 edje_object_signal_callback_add
4729 (sd->frame_obj, "elm,action,menu", "elm",
4730 _elm_win_frame_cb_menu, obj);
4731 }
4732 else
4733 {
4734 edje_object_signal_callback_add
4735 (sd->frame_obj, "efl,action,move,start", "efl",
4736 _elm_win_frame_cb_move_start, obj);
4737 edje_object_signal_callback_add
4738 (sd->frame_obj, "efl,action,resize,show", "*",
4739 _elm_win_frame_cb_resize_show, obj);
4740 edje_object_signal_callback_add
4741 (sd->frame_obj, "efl,action,resize,hide", "*",
4742 _elm_win_frame_cb_resize_hide, obj);
4743 edje_object_signal_callback_add
4744 (sd->frame_obj, "efl,action,resize,start", "*",
4745 _elm_win_frame_cb_resize_start, obj);
4746 edje_object_signal_callback_add
4747 (sd->frame_obj, "efl,action,minimize", "efl",
4748 _elm_win_frame_cb_minimize, obj);
4749 edje_object_signal_callback_add
4750 (sd->frame_obj, "efl,action,maximize", "efl",
4751 _elm_win_frame_cb_maximize, obj);
4752 edje_object_signal_callback_add
4753 (sd->frame_obj, "efl,action,close", "efl",
4754 _elm_win_frame_cb_close, obj);
4755 edje_object_signal_callback_add
4756 (sd->frame_obj, "efl,action,menu", "efl",
4757 _elm_win_frame_cb_menu, obj);
4758 }
4759
4760 if (!sd->pointer.obj)
4761 {
4762 if (elm_widget_is_legacy(obj))
4763 {
4764 for (size_t k = 0; k < EINA_C_ARRAY_LENGTH(_resize_infos_legacy); k++)
4765 {
4766 const resize_info *ri = &_resize_infos_legacy[k];
4767 _elm_object_part_cursor_set(obj, sd->frame_obj, ri->source, ri->cursor);
4768 }
4769 }
4770 else
4771 {
4772 for (size_t k = 0; k < EINA_C_ARRAY_LENGTH(_resize_infos); k++)
4773 {
4774 const resize_info *ri = &_resize_infos[k];
4775 _elm_object_part_cursor_set(obj, sd->frame_obj, ri->source, ri->cursor);
4776 }
4777 }
4778 }
4779
4780 if (sd->title)
4781 {
4782 if (elm_widget_is_legacy(sd->obj))
4783 edje_object_part_text_escaped_set(sd->frame_obj, "elm.text.title", sd->title);
4784 else
4785 edje_object_part_text_escaped_set(sd->frame_obj, "efl.text.title", sd->title);
4786 }
4787
4788 {
4789 // HACK: Force render mode of bg rect to COPY. This avoids render garbage.
4790 Eo *bgrect;
4791 if (elm_widget_is_legacy(sd->obj))
4792 bgrect = (Eo *) edje_object_part_object_get(sd->frame_obj, "elm.rect.background");
4793 else
4794 bgrect = (Eo *) edje_object_part_object_get(sd->frame_obj, "efl.rect.background");
4795
4796 efl_canvas_object_render_op_set(bgrect, EFL_GFX_RENDER_OP_COPY);
4797 }
4798
4799 if (sd->first_draw)
4800 edje_object_thaw(sd->frame_obj);
4801 if (!efl_finalized_get(obj)) return;
4802 _elm_win_frame_style_update(sd, 1, 1);
4803 _elm_win_frame_geometry_adjust(sd);
4804 ecore_evas_geometry_get(sd->ee, NULL, NULL, &w, &h);
4805 if ((w > 1) && (h > 1))
4806 {
4807 ecore_evas_resize(sd->ee, w, h);
4808 }
4809 }
4810
4811 static void
_elm_win_frame_style_update(Efl_Ui_Win_Data * sd,Eina_Bool force_emit,Eina_Bool calc)4812 _elm_win_frame_style_update(Efl_Ui_Win_Data *sd, Eina_Bool force_emit, Eina_Bool calc)
4813 {
4814 Eina_Bool borderless, maximized, shadow, focus, bg_solid, menu, unresizable,
4815 alpha, bg_standard, indicator;
4816 Eina_Bool changed = EINA_FALSE;
4817
4818 if (!sd->frame_obj)
4819 {
4820 if (!efl_finalized_get(sd->obj)) return;
4821 if (EINA_LIKELY(sd->type == EFL_UI_WIN_TYPE_FAKE))
4822 return;
4823 if (!_elm_config->win_no_border)
4824 CRI("Window has no frame object!");
4825 return;
4826 }
4827
4828 if ((sd->type == ELM_WIN_INLINED_IMAGE) ||
4829 (sd->type == ELM_WIN_SOCKET_IMAGE) ||
4830 (sd->type == ELM_WIN_TOOLTIP) ||
4831 (sd->type == ELM_WIN_COMBO) ||
4832 (sd->type == ELM_WIN_MENU) ||
4833 (sd->type == ELM_WIN_POPUP_MENU))
4834 {
4835 sd->csd.need_shadow = EINA_FALSE;
4836 sd->csd.need_borderless = EINA_TRUE;
4837 sd->csd.need_unresizable = EINA_TRUE;
4838 sd->csd.need_menu = EINA_FALSE;
4839 sd->csd.need_indicator = EINA_FALSE;
4840 }
4841 else if (_elm_config->win_no_border)
4842 sd->csd.need_borderless = EINA_TRUE;
4843 else
4844 {
4845 sd->csd.need_shadow = sd->csd.need && (!sd->maximized);
4846 }
4847
4848 alpha = sd->application_alpha || sd->theme_alpha;
4849 borderless = sd->csd.need_borderless || (!sd->csd.need) || sd->fullscreen;
4850 maximized = sd->maximized;
4851 shadow = sd->csd.need_shadow && (!sd->fullscreen) && (!sd->maximized) && (!borderless);
4852 if (alpha && borderless) shadow = 0;
4853 #ifdef HAVE_ELEMENTARY_WL2
4854 if (sd->wl.win)
4855 focus = ecore_wl2_window_activated_get(sd->wl.win);
4856 else
4857 #endif
4858 focus = ecore_evas_focus_get(sd->ee);
4859 bg_standard = sd->csd.need_bg_standard;
4860 unresizable = sd->csd.need_unresizable;
4861 menu = sd->csd.need_menu;
4862 indicator = sd->csd.need_indicator;
4863 bg_solid = sd->csd.need_bg_solid;
4864 /* Set background transparent if window supports alpha.
4865 * If alpha window does not emit signal to show background rectangle, then
4866 * the background color set by _efl_ui_win_part_color_set cannot be applied
4867 * because the background rectangle remains hidden.
4868 */
4869 if (alpha && bg_solid && !(sd->csd.cur_bg_solid))
4870 edje_object_color_class_set(sd->frame_obj, "elm/win/background", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
4871
4872 /* FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
4873 * At the moment, E Wayland uses SSD for its internal windows. Which means
4874 * we must hide the shadow if the borderless flag is set. "trap" here means
4875 * we are likely to be running inside E compositor.
4876 * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME */
4877 if (trap && sd->csd.wayland && sd->csd.need_borderless)
4878 shadow = 0;
4879
4880 #define STATE_SET(state, s1, s2, s3) do { \
4881 if (force_emit || (state != sd->csd.cur_##state)) \
4882 { \
4883 const char *sig = state ? s1 : s2; \
4884 edje_object_signal_emit(sd->frame_obj, sig, s3); \
4885 DBG("frame style emit: %p %s", sd->obj, sig); \
4886 sd->csd.cur_##state = state; \
4887 changed = EINA_TRUE; \
4888 } } while (0)
4889
4890 if (elm_widget_is_legacy(sd->obj))
4891 {
4892 STATE_SET(borderless, "elm,state,borderless,on", "elm,state,borderless,off", "elm");
4893 STATE_SET(shadow, "elm,state,shadow,on", "elm,state,shadow,off", "elm");
4894 STATE_SET(maximized, "elm,state,maximized", "elm,state,unmaximized", "elm");
4895 STATE_SET(focus, "elm,action,focus", "elm,action,unfocus", "elm");
4896 STATE_SET(bg_solid, "elm,state,background,solid,on", "elm,state,background,solid,off", "elm");
4897 STATE_SET(bg_standard, "elm,state,background,standard,on", "elm,state,background,standard,off", "elm");
4898 STATE_SET(unresizable, "elm,state,unresizable,on", "elm,state,unresizable,off", "elm");
4899 STATE_SET(menu, "elm,action,show_menu", "elm,action,hide_menu", "elm");
4900 STATE_SET(indicator, "elm,action,show_indicator", "elm,action,hide_indicator", "elm");
4901 }
4902 else
4903 {
4904 STATE_SET(borderless, "efl,state,borderless,on", "efl,state,borderless,off", "efl");
4905 STATE_SET(shadow, "efl,state,shadow,on", "efl,state,shadow,off", "efl");
4906 STATE_SET(maximized, "efl,state,maximized", "efl,state,unmaximized", "efl");
4907 STATE_SET(focus, "efl,action,focus", "efl,action,unfocus", "efl");
4908 STATE_SET(bg_solid, "efl,state,background,solid,on", "efl,state,background,solid,off", "efl");
4909 STATE_SET(bg_standard, "efl,state,background,standard,on", "efl,state,background,standard,off", "efl");
4910 STATE_SET(unresizable, "efl,state,unresizable,on", "efl,state,unresizable,off", "efl");
4911 STATE_SET(menu, "efl,action,show_menu", "efl,action,hide_menu", "efl");
4912 STATE_SET(indicator, "efl,action,show_indicator", "efl,action,hide_indicator", "efl");
4913 }
4914
4915 #undef STATE_SET
4916
4917 if (changed)
4918 {
4919 if (calc || force_emit)
4920 edje_object_message_signal_process(sd->frame_obj);
4921 if (calc)
4922 evas_object_smart_calculate(sd->frame_obj);
4923 _elm_win_frame_obj_update(sd, 0);
4924 }
4925 }
4926
4927 #ifdef ELM_DEBUG
4928 static void
_debug_key_down(void * data EINA_UNUSED,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info)4929 _debug_key_down(void *data EINA_UNUSED,
4930 Evas *e EINA_UNUSED,
4931 Evas_Object *obj,
4932 void *event_info)
4933 {
4934 Evas_Event_Key_Down *ev = event_info;
4935
4936 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
4937 return;
4938
4939 if ((strcmp(ev->key, "F12")) ||
4940 (!evas_key_modifier_is_set(ev->modifiers, "Control")))
4941 return;
4942
4943 INF("Tree graph generated.");
4944 elm_object_tree_dot_dump(obj, "./dump.dot");
4945 }
4946
4947 #endif
4948
4949 static void
_win_inlined_image_set(Efl_Ui_Win_Data * sd)4950 _win_inlined_image_set(Efl_Ui_Win_Data *sd)
4951 {
4952 evas_object_image_alpha_set(sd->img_obj, EINA_FALSE);
4953 evas_object_image_filled_set(sd->img_obj, EINA_TRUE);
4954
4955 evas_object_event_callback_add
4956 (sd->img_obj, EVAS_CALLBACK_DEL, _elm_win_on_img_obj_del, sd->obj);
4957 evas_object_event_callback_add
4958 (sd->img_obj, EVAS_CALLBACK_HIDE, _win_img_hide, sd->obj);
4959 evas_object_event_callback_add
4960 (sd->img_obj, EVAS_CALLBACK_MOUSE_UP, _win_img_mouse_up, sd->obj);
4961 evas_object_event_callback_add
4962 (sd->img_obj, EVAS_CALLBACK_FOCUS_IN, _win_img_focus_in, sd->obj);
4963 evas_object_event_callback_add
4964 (sd->img_obj, EVAS_CALLBACK_FOCUS_OUT, _win_img_focus_out, sd->obj);
4965 }
4966
4967 static void
_elm_win_on_icon_del(void * data,const Efl_Event * ev)4968 _elm_win_on_icon_del(void *data, const Efl_Event *ev)
4969 {
4970 ELM_WIN_DATA_GET(data, sd);
4971
4972 if (sd->icon == ev->object) sd->icon = NULL;
4973 }
4974
4975 EOLIAN static void
_efl_ui_win_efl_canvas_group_group_add(Eo * obj,Efl_Ui_Win_Data * _pd EINA_UNUSED)4976 _efl_ui_win_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Win_Data *_pd EINA_UNUSED)
4977 {
4978 efl_canvas_group_add(efl_super(obj, MY_CLASS));
4979
4980 elm_widget_theme_klass_set(obj, "win");
4981 elm_widget_can_focus_set(obj, EINA_TRUE);
4982
4983 elm_widget_highlight_ignore_set(obj, EINA_TRUE);
4984 }
4985
4986 #ifdef HAVE_ELEMENTARY_X
4987 static void
_elm_x_io_err(void * data EINA_UNUSED)4988 _elm_x_io_err(void *data EINA_UNUSED)
4989 {
4990 Eina_List *l;
4991 Evas_Object *obj;
4992
4993 EINA_LIST_FOREACH(_elm_win_list, l, obj)
4994 evas_object_smart_callback_call(obj, "ioerr", NULL);
4995 fprintf(stderr, "X I/O Error - fatal. Exiting\n");
4996 exit(101);
4997 }
4998 #endif
4999
5000 static void
_elm_win_cb_hide(void * data EINA_UNUSED,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)5001 _elm_win_cb_hide(void *data EINA_UNUSED,
5002 Evas *e EINA_UNUSED,
5003 Evas_Object *obj EINA_UNUSED,
5004 void *event_info EINA_UNUSED)
5005 {
5006 _elm_win_state_eval_queue();
5007 }
5008
5009 static void
_elm_win_cb_show(void * data EINA_UNUSED,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)5010 _elm_win_cb_show(void *data EINA_UNUSED,
5011 Evas *e EINA_UNUSED,
5012 Evas_Object *obj EINA_UNUSED,
5013 void *event_info EINA_UNUSED)
5014 {
5015 _elm_win_state_eval_queue();
5016 }
5017
5018 static inline Eina_Bool
_efl_ui_win_accel(Efl_Ui_Win_Data * sd,Eina_Stringshare ** accel,int * gl_depth,int * gl_stencil,int * gl_msaa)5019 _efl_ui_win_accel(Efl_Ui_Win_Data *sd, Eina_Stringshare **accel, int *gl_depth, int *gl_stencil, int *gl_msaa)
5020 {
5021 const char *str = sd->accel_pref;
5022 const char *env;
5023 const char *cfg = NULL;
5024 Eina_Bool is_accel = EINA_FALSE;
5025
5026 /* current elm config OR global override */
5027 if ((!str) || ((_elm_config->accel_override) && (_elm_config->accel)))
5028 {
5029 if (_elm_config->accel) cfg = _elm_config->accel;
5030 if (_elm_config->accel_override && _elm_accel_preference) cfg = _elm_accel_preference;
5031 }
5032
5033 /* env var wins */
5034 env = getenv("ELM_ACCEL");
5035
5036 if (env)
5037 is_accel = _elm_config_accel_preference_parse(env, accel, gl_depth, gl_stencil, gl_msaa);
5038 else if (cfg)
5039 {
5040 is_accel = !!cfg;
5041 *accel = eina_stringshare_ref(cfg);
5042 *gl_depth = _elm_config->gl_depth;
5043 *gl_stencil = _elm_config->gl_stencil;
5044 *gl_msaa = _elm_config->gl_msaa;
5045 }
5046 else
5047 is_accel = _elm_config_accel_preference_parse(str, accel, gl_depth, gl_stencil, gl_msaa);
5048
5049 return is_accel;
5050 }
5051
5052 static inline void
_elm_win_need_frame_adjust(Efl_Ui_Win_Data * sd,const char * engine)5053 _elm_win_need_frame_adjust(Efl_Ui_Win_Data *sd, const char *engine)
5054 {
5055 const char *s;
5056
5057 /* this is for debug only - don't keep forever, it's not an api! */
5058 s = getenv("EFL_WIN_FRAME_MODE");
5059 sd->csd.wayland = (eina_streq(engine, ELM_WAYLAND_SHM) ||
5060 eina_streq(engine, ELM_WAYLAND_EGL));
5061
5062 if (sd->type == EFL_UI_WIN_TYPE_FAKE)
5063 sd->csd.need = EINA_FALSE;
5064 else if (eina_streq(s, "on"))
5065 sd->csd.need = EINA_TRUE;
5066 else if (eina_streq(s, "off"))
5067 sd->csd.need = EINA_FALSE;
5068 else
5069 sd->csd.need = sd->csd.wayland;
5070 }
5071
5072 static void
_indicator_resized(void * data,const Efl_Event * event)5073 _indicator_resized(void *data, const Efl_Event *event)
5074 {
5075 ELM_WIN_DATA_GET_OR_RETURN(data, sd);
5076 Evas_Object *indicator = event->object;
5077 Evas_Coord_Size *size = (Evas_Coord_Size *)event->info;
5078 efl_gfx_hint_size_min_set(indicator, EINA_SIZE2D(size->w, size->h));
5079 _elm_win_frame_obj_update(sd, 0);
5080 }
5081
5082 static Evas_Object*
_create_indicator(Evas_Object * obj)5083 _create_indicator(Evas_Object *obj)
5084 {
5085 Evas_Object *indicator = NULL;
5086 const char *indicator_serv_name;
5087
5088 indicator_serv_name = "elm_indicator_portrait";
5089
5090 indicator = elm_plug_add(obj);
5091 if (!indicator)
5092 {
5093 ERR("Conformant cannot create plug to server[%s]", indicator_serv_name);
5094 return NULL;
5095 }
5096
5097 if (!elm_plug_connect(indicator, indicator_serv_name, 0, EINA_FALSE))
5098 {
5099 ERR("Conformant cannot connect to server[%s]", indicator_serv_name);
5100 return NULL;
5101 }
5102
5103 return indicator;
5104 }
5105
5106 static void
_indicator_add(Efl_Ui_Win_Data * sd)5107 _indicator_add(Efl_Ui_Win_Data *sd)
5108 {
5109 Eo *obj = sd->obj;
5110
5111 sd->indicator = _create_indicator(obj);
5112
5113 if (!sd->indicator)
5114 return;
5115
5116 if (elm_widget_is_legacy(obj))
5117 {
5118 if (!edje_object_part_swallow(sd->frame_obj, "elm.swallow.indicator", sd->indicator))
5119 return;
5120 }
5121 else
5122 {
5123 if (!edje_object_part_swallow(sd->frame_obj, "efl.indicator", sd->indicator))
5124 return;
5125 }
5126
5127 efl_event_callback_add
5128 (sd->indicator, ELM_PLUG_EVENT_IMAGE_RESIZED, _indicator_resized, obj);
5129
5130 efl_canvas_object_is_frame_object_set(sd->indicator, EINA_TRUE);
5131 sd->csd.need_indicator = EINA_TRUE;
5132
5133 _elm_win_frame_style_update(sd, 0, 1);
5134 }
5135
5136 static void
_indicator_del(Efl_Ui_Win_Data * sd)5137 _indicator_del(Efl_Ui_Win_Data *sd)
5138 {
5139 Eo *obj = sd->obj;
5140
5141 efl_event_callback_del
5142 (sd->indicator, ELM_PLUG_EVENT_IMAGE_RESIZED, _indicator_resized, obj);
5143
5144 efl_del(sd->indicator);
5145 sd->indicator = NULL;
5146
5147 sd->csd.need_indicator = EINA_FALSE;
5148 _elm_win_frame_style_update(sd, 0, 1);
5149 }
5150
5151 static Eina_Value
_win_finalize_job_cb(void * data,const Eina_Value value)5152 _win_finalize_job_cb(void *data, const Eina_Value value)
5153 {
5154 Efl_Ui_Win_Data *sd = data;
5155 sd->finalize_future = NULL;
5156 if (!efl_invalidated_get(sd->obj))
5157 evas_render_pending_objects_flush(sd->evas);
5158 return value;
5159 }
5160
5161 static void
_gesture_manager_config_load(Eo * obj)5162 _gesture_manager_config_load(Eo *obj)
5163 {
5164 Eina_Value val;
5165 Eo *gm = efl_provider_find(obj, EFL_CONFIG_INTERFACE);
5166
5167 eina_value_setup(&val, EINA_VALUE_TYPE_DOUBLE);
5168 eina_value_set(&val, _elm_config->glayer_long_tap_start_timeout);
5169 efl_config_set(gm, "glayer_long_tap_start_timeout", &val);
5170
5171 eina_value_set(&val, _elm_config->glayer_double_tap_timeout);
5172 efl_config_set(gm, "glayer_double_tap_timeout", &val);
5173
5174 elm_config_scroll_thumbscroll_friction_set(_elm_config->thumbscroll_friction);
5175 elm_config_scroll_thumbscroll_momentum_threshold_set(_elm_config->thumbscroll_momentum_threshold);
5176
5177 eina_value_set(&val, _elm_config->glayer_line_min_length);
5178 efl_config_set(gm, "glayer_line_min_length", &val);
5179
5180 eina_value_set(&val, _elm_config->glayer_line_distance_tolerance);
5181 efl_config_set(gm, "glayer_line_distance_tolerance", &val);
5182
5183 eina_value_set(&val, _elm_config->glayer_line_angular_tolerance);
5184 efl_config_set(gm, "glayer_line_angular_tolerance", &val);
5185
5186 eina_value_set(&val, _elm_config->glayer_zoom_finger_factor);
5187 efl_config_set(gm, "glayer_zoom_finger_factor", &val);
5188
5189 eina_value_set(&val, _elm_config->glayer_zoom_distance_tolerance);
5190 efl_config_set(gm, "glayer_zoom_distance_tolerance", &val);
5191
5192 eina_value_setup(&val, EINA_VALUE_TYPE_UINT);
5193 eina_value_set(&val, _elm_config->glayer_flick_time_limit_ms);
5194 efl_config_set(gm, "glayer_flick_time_limit_ms", &val);
5195
5196 eina_value_setup(&val, EINA_VALUE_TYPE_UCHAR);
5197 eina_value_set(&val, _elm_config->glayer_continues_enable);
5198 efl_config_set(gm, "glayer_continues_enable", &val);
5199
5200 eina_value_set(&val, _elm_config->glayer_zoom_finger_enable);
5201 efl_config_set(gm, "glayer_zoom_finger_enable", &val);
5202 }
5203
5204 static Eo *
_elm_win_finalize_internal(Eo * obj,Efl_Ui_Win_Data * sd,const char * name,Efl_Ui_Win_Type type)5205 _elm_win_finalize_internal(Eo *obj, Efl_Ui_Win_Data *sd, const char *name, Efl_Ui_Win_Type type)
5206 {
5207 Evas_Object *parent = NULL;
5208 Evas *e;
5209 const Eina_List *l;
5210 const char *fontpath, *engine = NULL, *enginelist[32], *disp;
5211 int gl_depth = _elm_config->gl_depth;
5212 int gl_stencil = _elm_config->gl_stencil;
5213 int gl_msaa = _elm_config->gl_msaa;
5214 Eina_Stringshare *accel = NULL;
5215 Eina_Bool is_gl_accel;
5216 int i, p = 0;
5217 Ecore_Window parent_id = 0;
5218
5219 Efl_Ui_Win_Data tmp_sd;
5220
5221 if ((sd->type == ELM_WIN_INLINED_IMAGE) &&
5222 !efl_isa(obj, EFL_UI_WIN_INLINED_CLASS))
5223 {
5224 ERR("Failed to create an inlined window!");
5225 return NULL;
5226 }
5227
5228 parent = efl_parent_get(obj);
5229 if (!(efl_isa(parent, EFL_UI_WIN_CLASS) ||
5230 efl_isa(parent, EFL_UI_WIN_LEGACY_CLASS) ||
5231 efl_isa(parent, EFL_UI_WIN_INLINED_CLASS))) parent = NULL;
5232
5233 /* just to store some data while trying out to create a canvas */
5234 memset(&tmp_sd, 0, sizeof(Efl_Ui_Win_Data));
5235
5236 is_gl_accel = _efl_ui_win_accel(sd, &accel, &gl_depth, &gl_stencil, &gl_msaa);
5237
5238 switch ((int) type)
5239 {
5240 case EFL_UI_WIN_TYPE_FAKE:
5241 tmp_sd.ee = sd->ee;
5242 break;
5243 case ELM_WIN_INLINED_IMAGE:
5244 if (!parent) break;
5245 {
5246 Ecore_Evas *ee;
5247
5248 e = evas_object_evas_get(parent);
5249 if (!e) break;
5250
5251 ee = ecore_evas_ecore_evas_get(e);
5252 if (!ee) break;
5253
5254 tmp_sd.img_obj = ecore_evas_object_image_new(ee);
5255 if (!tmp_sd.img_obj) break;
5256
5257 tmp_sd.ee = ecore_evas_object_ecore_evas_get(tmp_sd.img_obj);
5258 if (!tmp_sd.ee)
5259 {
5260 ELM_SAFE_FREE(tmp_sd.img_obj, evas_object_del);
5261 }
5262 }
5263 break;
5264
5265 case ELM_WIN_SOCKET_IMAGE:
5266 tmp_sd.ee = ecore_evas_extn_socket_new(1, 1);
5267 break;
5268
5269 default:
5270 disp = getenv("ELM_DISPLAY");
5271 if ((disp) && (!strcmp(disp, "ews")))
5272 {
5273 enginelist[p++] = ELM_EWS;
5274 }
5275 else if ((disp) && (!strcmp(disp, "buffer")))
5276 {
5277 enginelist[p++] = ELM_BUFFER;
5278 }
5279 else if ((disp) && (!strcmp(disp, "shot")))
5280 {
5281 enginelist[p++] = ENGINE_GET();
5282 }
5283 // welcome to ifdef hell! :)
5284
5285 #ifdef HAVE_ELEMENTARY_X
5286 else if ((disp) && (!strcmp(disp, "x11")))
5287 {
5288 if (is_gl_accel)
5289 {
5290 enginelist[p++] = ELM_OPENGL_X11;
5291 enginelist[p++] = ELM_SOFTWARE_X11;
5292 }
5293 else
5294 {
5295 enginelist[p++] = ELM_SOFTWARE_X11;
5296 enginelist[p++] = ELM_OPENGL_X11;
5297 }
5298 }
5299 #endif
5300
5301 #ifdef HAVE_ELEMENTARY_WL2
5302 else if ((disp) && (!strcmp(disp, "wl")))
5303 {
5304 if (is_gl_accel)
5305 {
5306 enginelist[p++] = ELM_WAYLAND_EGL;
5307 enginelist[p++] = ELM_WAYLAND_SHM;
5308 }
5309 else
5310 {
5311 enginelist[p++] = ELM_WAYLAND_SHM;
5312 enginelist[p++] = ELM_WAYLAND_EGL;
5313 }
5314 }
5315 #endif
5316
5317 #ifdef HAVE_ELEMENTARY_WIN32
5318 else if ((disp) && (!strcmp(disp, "win")))
5319 {
5320 enginelist[p++] = ELM_SOFTWARE_WIN32;
5321 enginelist[p++] = ELM_SOFTWARE_DDRAW;
5322 }
5323 #endif
5324
5325 #ifdef HAVE_ELEMENTARY_SDL
5326 else if ((disp) && (!strcmp(disp, "sdl")))
5327 {
5328 if (is_gl_accel)
5329 {
5330 enginelist[p++] = ELM_OPENGL_SDL;
5331 enginelist[p++] = ELM_SOFTWARE_SDL;
5332 }
5333 else
5334 {
5335 enginelist[p++] = ELM_SOFTWARE_SDL;
5336 enginelist[p++] = ELM_OPENGL_SDL;
5337 }
5338 }
5339 #endif
5340
5341 #ifdef HAVE_ELEMENTARY_COCOA
5342 else if ((disp) && (!strcmp(disp, "mac")))
5343 {
5344 enginelist[p++] = ELM_OPENGL_COCOA;
5345 }
5346 #endif
5347
5348 #if defined(HAVE_ELEMENTARY_DRM) || defined(HAVE_ELEMENTARY_FB)
5349 else if ((disp) && (!strcmp(disp, "fb")))
5350 {
5351 #ifdef HAVE_ELEMENTARY_DRM
5352 if (is_gl_accel)
5353 {
5354 enginelist[p++] = ELM_GL_DRM;
5355 }
5356 enginelist[p++] = ELM_DRM;
5357 #endif
5358 #ifdef HAVE_ELEMENTARY_FB
5359 enginelist[p++] = ELM_SOFTWARE_FB;
5360 #endif
5361 }
5362 #endif
5363
5364 #ifdef HAVE_ELEMENTARY_X
5365 else if (!_elm_preferred_engine &&
5366 getenv("DISPLAY") && !getenv("ELM_ENGINE"))
5367 {
5368 if (is_gl_accel)
5369 {
5370 enginelist[p++] = ELM_OPENGL_X11;
5371 enginelist[p++] = ELM_SOFTWARE_X11;
5372 }
5373 else
5374 {
5375 enginelist[p++] = ELM_SOFTWARE_X11;
5376 enginelist[p++] = ELM_OPENGL_X11;
5377 }
5378 }
5379 #endif
5380 #ifdef HAVE_ELEMENTARY_WL2
5381 else if (!_elm_preferred_engine &&
5382 getenv("WAYLAND_DISPLAY") && !getenv("ELM_ENGINE"))
5383 {
5384 if (is_gl_accel)
5385 {
5386 enginelist[p++] = ELM_WAYLAND_EGL;
5387 enginelist[p++] = ELM_WAYLAND_SHM;
5388 }
5389 else
5390 {
5391 enginelist[p++] = ELM_WAYLAND_SHM;
5392 enginelist[p++] = ELM_WAYLAND_EGL;
5393 }
5394 }
5395 #endif
5396 else
5397 {
5398 if (is_gl_accel)
5399 {
5400 // add all engines with selected engine first - if any
5401 if (ENGINE_GET())
5402 enginelist[p++] = ENGINE_GET();
5403
5404 // add all engines with gl/accelerated ones first - only engines compiled
5405 #ifdef HAVE_ELEMENTARY_X
5406 enginelist[p++] = ELM_OPENGL_X11;
5407 #endif
5408 #ifdef HAVE_ELEMENTARY_WL2
5409 enginelist[p++] = ELM_WAYLAND_EGL;
5410 #endif
5411 #ifdef HAVE_ELEMENTARY_DRM
5412 enginelist[p++] = ELM_GL_DRM;
5413 enginelist[p++] = ELM_DRM;
5414 #endif
5415 #ifdef HAVE_ELEMENTARY_FB
5416 enginelist[p++] = ELM_SOFTWARE_FB;
5417 #endif
5418 #ifdef HAVE_ELEMENTARY_COCOA
5419 enginelist[p++] = ELM_OPENGL_COCOA;
5420 #endif
5421 #ifdef HAVE_ELEMENTARY_SDL
5422 enginelist[p++] = ELM_OPENGL_SDL;
5423 #endif
5424 #ifdef HAVE_ELEMENTARY_X
5425 enginelist[p++] = ELM_SOFTWARE_X11;
5426 #endif
5427 #ifdef HAVE_ELEMENTARY_WL2
5428 enginelist[p++] = ELM_WAYLAND_SHM;
5429 #endif
5430 #ifdef HAVE_ELEMENTARY_WIN32
5431 enginelist[p++] = ELM_SOFTWARE_WIN32;
5432 enginelist[p++] = ELM_SOFTWARE_DDRAW;
5433 #endif
5434 #ifdef HAVE_ELEMENTARY_SDL
5435 enginelist[p++] = ELM_SOFTWARE_SDL;
5436 #endif
5437 }
5438 else
5439 {
5440 // add all engines with selected engine first - if any
5441 if (elm_config_preferred_engine_get())
5442 enginelist[p++] = elm_config_preferred_engine_get();
5443 // add check _elm_gl_preference whether "none" or not
5444 else if (_elm_config->engine &&
5445 ((elm_config_accel_preference_get() &&
5446 !strcmp(elm_config_accel_preference_get(), "none"))
5447 || (accel && !strcmp(accel, "none"))))
5448 enginelist[p++] = _elm_config->engine;
5449 // add all engines with gl/accelerated ones first - only engines compiled
5450 #ifdef HAVE_ELEMENTARY_X
5451 enginelist[p++] = ELM_SOFTWARE_X11;
5452 #endif
5453 #ifdef HAVE_ELEMENTARY_WL2
5454 enginelist[p++] = ELM_WAYLAND_SHM;
5455 #endif
5456 #ifdef HAVE_ELEMENTARY_DRM
5457 enginelist[p++] = ELM_DRM;
5458 #endif
5459 #ifdef HAVE_ELEMENTARY_FB
5460 enginelist[p++] = ELM_SOFTWARE_FB;
5461 #endif
5462 #ifdef HAVE_ELEMENTARY_COCOA
5463 enginelist[p++] = ELM_OPENGL_COCOA;
5464 #endif
5465 #ifdef HAVE_ELEMENTARY_WIN32
5466 enginelist[p++] = ELM_SOFTWARE_WIN32;
5467 enginelist[p++] = ELM_SOFTWARE_DDRAW;
5468 #endif
5469 #ifdef HAVE_ELEMENTARY_SDL
5470 enginelist[p++] = ELM_SOFTWARE_SDL;
5471 #endif
5472 #ifdef HAVE_ELEMENTARY_X
5473 enginelist[p++] = ELM_OPENGL_X11;
5474 #endif
5475 #ifdef HAVE_ELEMENTARY_WL2
5476 enginelist[p++] = ELM_WAYLAND_EGL;
5477 #endif
5478 #ifdef HAVE_ELEMENTARY_DRM
5479 enginelist[p++] = ELM_GL_DRM;
5480 enginelist[p++] = ELM_DRM;
5481 #endif
5482 #ifdef HAVE_ELEMENTARY_SDL
5483 enginelist[p++] = ELM_OPENGL_SDL;
5484 #endif
5485 }
5486 }
5487 if (parent) parent_id = elm_win_window_id_get(parent);
5488 for (i = 0; i < p; i++)
5489 {
5490 int opt[20], opt_i = 0;
5491
5492 if (_elm_config->vsync)
5493 {
5494 opt[opt_i++] = ECORE_EVAS_OPT_VSYNC;
5495 opt[opt_i++] = 1;
5496 }
5497 if (gl_depth)
5498 {
5499 opt[opt_i++] = ECORE_EVAS_OPT_GL_DEPTH;
5500 opt[opt_i++] = gl_depth;
5501 }
5502 if (gl_stencil)
5503 {
5504 opt[opt_i++] = ECORE_EVAS_OPT_GL_STENCIL;
5505 opt[opt_i++] = gl_stencil;
5506 }
5507 if (gl_msaa)
5508 {
5509 opt[opt_i++] = ECORE_EVAS_OPT_GL_MSAA;
5510 opt[opt_i++] = gl_msaa;
5511 }
5512 opt[opt_i] = 0;
5513
5514 if (!strcmp(enginelist[i], ELM_SOFTWARE_X11))
5515 tmp_sd.ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 0, 0);
5516 else if (!strcmp(enginelist[i], ELM_OPENGL_X11))
5517 {
5518 if (opt_i > 0)
5519 tmp_sd.ee = ecore_evas_gl_x11_options_new(NULL, 0, 0, 0, 0, 0, opt);
5520 else
5521 tmp_sd.ee = ecore_evas_gl_x11_new(NULL, 0, 0, 0, 0, 0);
5522 }
5523 else if (!strcmp(enginelist[i], ELM_WAYLAND_SHM))
5524 tmp_sd.ee = _wayland_shm_new(NULL, parent_id, 0, 0, 0, 0, 0);
5525 else if (!strcmp(enginelist[i], ELM_WAYLAND_EGL))
5526 tmp_sd.ee = _wayland_egl_new(NULL, parent_id, 0, 0, 0, 0, 0, (opt_i > 0) ? opt : NULL);
5527 else if (!strcmp(enginelist[i], ELM_SOFTWARE_WIN32))
5528 tmp_sd.ee = ecore_evas_software_gdi_new(NULL, 0, 0, 1, 1);
5529 else if (!strcmp(enginelist[i], ELM_SOFTWARE_DDRAW))
5530 tmp_sd.ee = ecore_evas_software_ddraw_new(NULL, 0, 0, 1, 1);
5531 else if (!strcmp(enginelist[i], ELM_SOFTWARE_SDL))
5532 tmp_sd.ee = ecore_evas_sdl_new(NULL, 0, 0, 0, 0, 0, 1);
5533 else if (!strcmp(enginelist[i], ELM_OPENGL_SDL))
5534 tmp_sd.ee = ecore_evas_gl_sdl_new(NULL, 1, 1, 0, 0);
5535 else if (!strcmp(enginelist[i], ELM_OPENGL_COCOA))
5536 tmp_sd.ee = ecore_evas_cocoa_new(NULL, 1, 1, 0, 0);
5537 else if (!strcmp(enginelist[i], ELM_EWS))
5538 tmp_sd.ee = ecore_evas_ews_new(0, 0, 1, 1);
5539 else if (!strcmp(enginelist[i], ELM_SOFTWARE_FB))
5540 tmp_sd.ee = ecore_evas_fb_new(NULL, 0, 1, 1);
5541 else if (!strcmp(enginelist[i], ELM_BUFFER))
5542 tmp_sd.ee = ecore_evas_buffer_new(1, 1);
5543 else if (!strcmp(enginelist[i], ELM_DRM))
5544 tmp_sd.ee = ecore_evas_drm_new(NULL, 0, 0, 0, 1, 1);
5545 else if (!strcmp(enginelist[i], ELM_GL_DRM))
5546 tmp_sd.ee = ecore_evas_gl_drm_new(NULL, 0, 0, 0, 1, 1);
5547 else if (!strncmp(enginelist[i], "shot:", 5))
5548 {
5549 tmp_sd.ee = ecore_evas_buffer_new(1, 1);
5550 ecore_evas_manual_render_set(tmp_sd.ee, EINA_TRUE);
5551 tmp_sd.shot.info = eina_stringshare_add(ENGINE_GET() + 5);
5552 }
5553 engine = enginelist[i];
5554 if (tmp_sd.ee) break;
5555 }
5556 break;
5557 }
5558
5559 eina_stringshare_del(accel);
5560 if (!tmp_sd.ee)
5561 {
5562 ERR("Cannot create window.");
5563 return NULL;
5564 }
5565
5566 if (!sd->accel_pref)
5567 eina_stringshare_replace(&sd->accel_pref, elm_config_accel_preference_get());
5568
5569 efl_parent_set(obj, ecore_evas_get(tmp_sd.ee));
5570
5571 /* FIXME: Major hack: calling the constructor in the middle of finalize. */
5572 efl_constructor(efl_super(obj, MY_CLASS));
5573 evas_object_smart_callbacks_descriptions_set(obj, _smart_callbacks);
5574
5575 if (getenv("ELM_FIRST_FRAME"))
5576 evas_event_callback_add(ecore_evas_get(tmp_sd.ee), EVAS_CALLBACK_RENDER_POST,
5577 _elm_win_first_frame_do, getenv("ELM_FIRST_FRAME"));
5578
5579 /* copying possibly altered fields back */
5580 #define SD_CPY(_field) \
5581 do \
5582 { \
5583 sd->_field = tmp_sd._field; \
5584 } while (0)
5585
5586 SD_CPY(ee);
5587 SD_CPY(img_obj);
5588 SD_CPY(shot.info);
5589 #undef SD_CPY
5590
5591 if ((type != EFL_UI_WIN_TYPE_FAKE) && (trap) && (trap->add))
5592 sd->trap_data = trap->add(obj);
5593
5594 /* complementary actions, which depend on final smart data
5595 * pointer */
5596 if (type == EFL_UI_WIN_TYPE_INLINED_IMAGE)
5597 _win_inlined_image_set(sd);
5598 #ifdef HAVE_ELEMENTARY_X
5599 else if ((engine) &&
5600 ((!strcmp(engine, ELM_SOFTWARE_X11)) ||
5601 (!strcmp(engine, ELM_OPENGL_X11))))
5602 {
5603 sd->x.client_message_handler = ecore_event_handler_add
5604 (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, obj);
5605 sd->x.property_handler = ecore_event_handler_add
5606 (ECORE_X_EVENT_WINDOW_PROPERTY, _elm_win_property_change, obj);
5607 }
5608 #endif
5609 else if ((engine) && (!strncmp(engine, "shot:", 5)))
5610 _shot_init(sd);
5611
5612 sd->kbdmode = EFL_UI_WIN_KEYBOARD_MODE_UNKNOWN;
5613 sd->legacy.indmode = ELM_WIN_INDICATOR_UNKNOWN;
5614 sd->indimode = EFL_UI_WIN_INDICATOR_MODE_OFF;
5615
5616 #ifdef HAVE_ELEMENTARY_X
5617 _internal_elm_win_xwindow_get(sd);
5618 if (sd->x.xwin) ecore_x_io_error_handler_set(_elm_x_io_err, NULL);
5619 #endif
5620
5621 #ifdef HAVE_ELEMENTARY_WL2
5622 _elm_win_wlwindow_get(sd);
5623 if (sd->wl.win)
5624 {
5625 Ecore_Wl2_Window_Type wtype;
5626 sd->wl.configure_handler =
5627 ecore_event_handler_add(ECORE_WL2_EVENT_WINDOW_CONFIGURE, _elm_win_wl_configure, obj);
5628 switch (sd->type)
5629 {
5630 case ELM_WIN_BASIC:
5631 case ELM_WIN_DIALOG_BASIC:
5632 case ELM_WIN_NAVIFRAME_BASIC:
5633 case ELM_WIN_SPLASH:
5634 case ELM_WIN_TOOLBAR:
5635 case ELM_WIN_UTILITY:
5636 case ELM_WIN_DOCK:
5637 case ELM_WIN_DESKTOP:
5638 wtype = ECORE_WL2_WINDOW_TYPE_TOPLEVEL;
5639 break;
5640 case ELM_WIN_TOOLTIP:
5641 case ELM_WIN_COMBO:
5642 case ELM_WIN_MENU:
5643 case ELM_WIN_POPUP_MENU:
5644 wtype = ECORE_WL2_WINDOW_TYPE_MENU;
5645 break;
5646 case ELM_WIN_DND:
5647 wtype = ECORE_WL2_WINDOW_TYPE_DND;
5648 break;
5649 default:
5650 wtype = ECORE_WL2_WINDOW_TYPE_NONE;
5651 }
5652 ecore_wl2_window_type_set(sd->wl.win, wtype);
5653 }
5654 else if (sd->type == EFL_UI_WIN_TYPE_FAKE)
5655 {
5656 const char *env = getenv("WAYLAND_DISPLAY");
5657 if (env)
5658 {
5659 Ecore_Wl2_Display *d = ecore_wl2_display_connect(env);
5660 sd->wl.win = ecore_wl2_window_new(d, NULL, 0, 0, 1, 1);
5661 ecore_wl2_display_disconnect(d);
5662 }
5663 }
5664 #endif
5665
5666 #ifdef HAVE_ELEMENTARY_COCOA
5667 _elm_win_cocoawindow_get(sd);
5668 #endif
5669 #ifdef HAVE_ELEMENTARY_WIN32
5670 sd->win32.key_down_handler = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
5671 _elm_win_key_down, obj);
5672 _internal_elm_win_win32window_get(sd);
5673 #endif
5674
5675 if ((_elm_config->bgpixmap)
5676 #ifdef HAVE_ELEMENTARY_X
5677 && (((sd->x.xwin) && (!ecore_x_screen_is_composited(0))) ||
5678 (!sd->x.xwin))
5679 #endif
5680 )
5681 TRAP(sd, avoid_damage_set, ECORE_EVAS_AVOID_DAMAGE_EXPOSE);
5682 // bg pixmap done by x - has other issues like can be redrawn by x before it
5683 // is filled/ready by app
5684 // TRAP(sd, avoid_damage_set, ECORE_EVAS_AVOID_DAMAGE_BUILT_IN);
5685
5686 sd->type = type;
5687 sd->parent = parent;
5688 sd->modal_count = 0;
5689 sd->withdrawn = ecore_evas_withdrawn_get(sd->ee);
5690
5691 if (sd->parent)
5692 evas_object_event_callback_add
5693 (sd->parent, EVAS_CALLBACK_DEL, _elm_win_on_parent_del, obj);
5694
5695 sd->evas = ecore_evas_get(sd->ee);
5696
5697 evas_object_color_set(obj, 0, 0, 0, 0);
5698 evas_object_pass_events_set(obj, EINA_TRUE);
5699
5700 if (type == EFL_UI_WIN_TYPE_INLINED_IMAGE)
5701 efl_ui_win_inlined_parent_set(obj, parent);
5702
5703 /* use own version of ecore_evas_object_associate() that does TRAP() */
5704 ecore_evas_data_set(sd->ee, "elm_win", obj);
5705
5706 if (type != EFL_UI_WIN_TYPE_FAKE)
5707 {
5708 evas_object_event_callback_add(obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
5709 _elm_win_obj_callback_changed_size_hints, NULL);
5710 evas_object_intercept_raise_callback_add
5711 (obj, _elm_win_obj_intercept_raise, obj);
5712 evas_object_intercept_lower_callback_add
5713 (obj, _elm_win_obj_intercept_lower, obj);
5714 evas_object_intercept_stack_above_callback_add
5715 (obj, _elm_win_obj_intercept_stack_above, obj);
5716 evas_object_intercept_stack_below_callback_add
5717 (obj, _elm_win_obj_intercept_stack_below, obj);
5718 evas_object_intercept_layer_set_callback_add
5719 (obj, _elm_win_obj_intercept_layer_set, obj);
5720 }
5721
5722 TRAP(sd, name_class_set, name, _elm_appname);
5723 TRAP(sd, title_set, sd->title);
5724 ecore_evas_callback_delete_request_set(sd->ee, _elm_win_delete_request);
5725 ecore_evas_callback_state_change_set(sd->ee, _elm_win_state_change);
5726 ecore_evas_callback_focus_in_set(sd->ee, _elm_win_focus_in);
5727 ecore_evas_callback_focus_out_set(sd->ee, _elm_win_focus_out);
5728 ecore_evas_callback_resize_set(sd->ee, _elm_win_resize);
5729 ecore_evas_callback_move_set(sd->ee, _elm_win_move);
5730 ecore_evas_callback_pre_render_set(sd->ee, _elm_win_pre_render);
5731 if (type != EFL_UI_WIN_TYPE_FAKE)
5732 {
5733 ecore_evas_callback_mouse_in_set(sd->ee, _elm_win_mouse_in);
5734 ecore_evas_callback_mouse_out_set(sd->ee, _elm_win_mouse_out);
5735 }
5736
5737 evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _elm_win_cb_hide, NULL);
5738 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _elm_win_cb_show, NULL);
5739
5740 evas_image_cache_set(sd->evas, (_elm_config->image_cache * 1024));
5741 evas_font_cache_set(sd->evas, (_elm_config->font_cache * 1024));
5742
5743 EINA_LIST_FOREACH(_elm_config->font_dirs, l, fontpath)
5744 evas_font_path_append(sd->evas, fontpath);
5745
5746 if (!_elm_config->font_hinting)
5747 evas_font_hinting_set(sd->evas, EVAS_FONT_HINTING_NONE);
5748 else if (_elm_config->font_hinting == 1)
5749 evas_font_hinting_set(sd->evas, EVAS_FONT_HINTING_AUTO);
5750 else if (_elm_config->font_hinting == 2)
5751 evas_font_hinting_set(sd->evas, EVAS_FONT_HINTING_BYTECODE);
5752
5753 sd->wm_rot.wm_supported = ecore_evas_wm_rotation_supported_get(sd->ee);
5754 sd->wm_rot.preferred_rot = -1; // it means that elm_win doesn't use preferred rotation.
5755
5756 #ifdef HAVE_ELEMENTARY_X
5757 _elm_win_xwin_update(sd);
5758 #endif
5759
5760 if (type != EFL_UI_WIN_TYPE_FAKE)
5761 {
5762 //Prohibiting auto-rendering, until elm_win is shown.
5763 if (_elm_win_auto_norender_withdrawn(obj))
5764 {
5765 if (elm_win_withdrawn_get(obj))
5766 {
5767 if (!evas_object_data_get(obj, "__win_auto_norender"))
5768 {
5769 elm_win_norender_push(obj);
5770 evas_object_data_set(obj, "__win_auto_norender", obj);
5771 }
5772 }
5773 }
5774 }
5775
5776 #ifdef ELM_DEBUG
5777 Evas_Modifier_Mask mask = evas_key_modifier_mask_get(sd->evas, "Control");
5778 evas_object_event_callback_add
5779 (obj, EVAS_CALLBACK_KEY_DOWN, _debug_key_down, NULL);
5780
5781 if (evas_object_key_grab(obj, "F12", mask, 0, EINA_TRUE))
5782 INF("Ctrl+F12 key combination exclusive for dot tree generation\n");
5783 else
5784 ERR("failed to grab F12 key to elm widgets (dot) tree generation");
5785 #endif
5786
5787 if (type != EFL_UI_WIN_TYPE_FAKE)
5788 {
5789 if ((_elm_config->softcursor_mode == ELM_SOFTCURSOR_MODE_ON) ||
5790 ((_elm_config->softcursor_mode == ELM_SOFTCURSOR_MODE_AUTO) &&
5791 ((engine) &&
5792 ((!strcmp(engine, ELM_SOFTWARE_FB)) || (!strcmp(engine, ELM_DRM))
5793 || (!strcmp(engine, ELM_GL_DRM))))))
5794 {
5795 Evas_Object *o;
5796 Evas_Coord mw = 1, mh = 1, hx = 0, hy = 0;
5797
5798 sd->pointer.obj = o = edje_object_add(ecore_evas_get(tmp_sd.ee));
5799 elm_widget_theme_object_set(obj, o, "pointer", "base", "default");
5800 edje_object_size_min_calc(o, &mw, &mh);
5801 evas_object_resize(o, mw, mh);
5802 if (elm_widget_is_legacy(obj))
5803 edje_object_part_geometry_get(o, "elm.swallow.hotspot",
5804 &hx, &hy, NULL, NULL);
5805 else
5806 edje_object_part_geometry_get(o, "efl.hotspot",
5807 &hx, &hy, NULL, NULL);
5808
5809 sd->pointer.hot_x = hx;
5810 sd->pointer.hot_y = hy;
5811 evas_object_show(o);
5812 ecore_evas_object_cursor_set(tmp_sd.ee, o, EVAS_LAYER_MAX, hx, hy);
5813 }
5814 else if (_elm_config->softcursor_mode == ELM_SOFTCURSOR_MODE_OFF)
5815 {
5816 // do nothing
5817 }
5818 }
5819
5820 _elm_win_legacy_init(sd);
5821 _elm_win_need_frame_adjust(sd, engine);
5822 _elm_win_apply_alpha(obj, sd);
5823
5824 #ifdef HAVE_ELEMENTARY_WL2
5825 if ((type != EFL_UI_WIN_TYPE_FAKE) && (type != EFL_UI_WIN_TYPE_INLINED_IMAGE))
5826 {
5827 if ((engine) &&
5828 ((!strcmp(engine, ELM_WAYLAND_SHM) ||
5829 (!strcmp(engine, ELM_WAYLAND_EGL)))))
5830 {
5831 Evas *pevas;
5832
5833 if (!strcmp(engine, ELM_WAYLAND_SHM))
5834 sd->pointer.ee = ecore_evas_wayland_shm_new(NULL, 0, 0, 0, 0, 0, 0);
5835 else if (!strcmp(engine, ELM_WAYLAND_EGL))
5836 sd->pointer.ee = ecore_evas_wayland_egl_new(NULL, 0, 0, 0, 0, 0, 0);
5837 ecore_evas_alpha_set(sd->pointer.ee, EINA_TRUE);
5838
5839 pevas = ecore_evas_get(sd->pointer.ee);
5840
5841 sd->pointer.obj = edje_object_add(pevas);
5842
5843 sd->pointer.win = ecore_evas_wayland2_window_get(sd->pointer.ee);
5844 ecore_wl2_window_type_set(sd->pointer.win,
5845 ECORE_WL2_WINDOW_TYPE_NONE);
5846 _elm_win_wl_cursor_set(sd->obj, NULL);
5847 ecore_evas_show(sd->pointer.ee);
5848 }
5849 }
5850 #endif
5851
5852 /* do not append to list; all windows render as black rects */
5853 if (type != EFL_UI_WIN_TYPE_FAKE)
5854 {
5855 const char *element = "base";
5856 const char *style;
5857
5858 _elm_win_list = eina_list_append(_elm_win_list, obj);
5859 _elm_win_count++;
5860
5861 if ((engine) &&
5862 ((!strcmp(engine, ELM_SOFTWARE_FB)) || (!strcmp(engine, ELM_DRM))
5863 || (!strcmp(engine, ELM_GL_DRM))))
5864 {
5865 TRAP(sd, fullscreen_set, 1);
5866 }
5867 style = elm_widget_style_get(obj);
5868 if (!style) style = "default";
5869 switch (type)
5870 {
5871 case EFL_UI_WIN_TYPE_DIALOG_BASIC: element = "dialog"; break;
5872 case EFL_UI_WIN_TYPE_NAVIFRAME_BASIC: element = "naviframe"; break;
5873 default: break;
5874 }
5875
5876 if (!_elm_config->win_no_border)
5877 _elm_win_frame_add(sd, element, style);
5878
5879 if (sd->indimode != EFL_UI_WIN_INDICATOR_MODE_OFF)
5880 _indicator_add(sd);
5881
5882 if (_elm_config->focus_highlight_enable)
5883 elm_win_focus_highlight_enabled_set(obj, EINA_TRUE);
5884 if (_elm_config->focus_highlight_animate)
5885 elm_win_focus_highlight_animate_set(obj, EINA_TRUE);
5886 }
5887
5888 efl_access_object_role_set(obj, EFL_ACCESS_ROLE_WINDOW);
5889 if (_elm_config->atspi_mode)
5890 efl_access_window_created_signal_emit(obj);
5891
5892 // attach config API
5893 efl_composite_attach(obj, efl_provider_find(efl_main_loop_get(), EFL_CONFIG_GLOBAL_CLASS));
5894
5895 efl_event_callback_array_add(sd->evas, _elm_evas_tracking(), sd);
5896 efl_event_callback_array_add(obj, _elm_win_evas_feed_fake_callbacks(), sd->evas);
5897 efl_event_callback_array_add(obj, _elm_win_tracking(), sd);
5898 evas_object_show(sd->legacy.edje);
5899
5900 if (type == EFL_UI_WIN_TYPE_FAKE)
5901 {
5902 _elm_win_resize_job(obj);
5903 _elm_win_move(sd->ee);
5904 }
5905 else
5906 {
5907 sd->finalize_future = eina_future_then_easy(efl_loop_job(efl_loop_get(obj)),
5908 .success = _win_finalize_job_cb, .data = sd);
5909 }
5910
5911 // All normal windows are "standard" windows with EO API
5912 if (!sd->legacy.ctor)
5913 {
5914 switch (type)
5915 {
5916 case EFL_UI_WIN_TYPE_UNKNOWN:
5917 case EFL_UI_WIN_TYPE_BASIC:
5918 case EFL_UI_WIN_TYPE_DIALOG_BASIC:
5919 _elm_win_standard_init(obj);
5920 break;
5921 default: break;
5922 }
5923 }
5924
5925 // Load the config values into gesutre manager.
5926 _gesture_manager_config_load(obj);
5927
5928 return obj;
5929 }
5930
5931 EOLIAN static Eo *
_efl_ui_win_efl_object_finalize(Eo * obj,Efl_Ui_Win_Data * sd)5932 _efl_ui_win_efl_object_finalize(Eo *obj, Efl_Ui_Win_Data *sd)
5933 {
5934 Eina_Bool resume = !_elm_win_count;
5935
5936 obj = _elm_win_finalize_internal(obj, sd, sd->name, sd->type);
5937 if (!obj) return NULL;
5938 obj = efl_finalize(efl_super(obj, MY_CLASS));
5939 if (obj && resume) efl_event_callback_call(efl_loop_get(obj), EFL_APP_EVENT_RESUME, NULL);
5940 if (obj && (!elm_widget_is_legacy(obj)))
5941 {
5942 /* FIXME: if parts other than background are supported then this should change */
5943 if (efl_file_get(efl_super(efl_part(obj, "background"), EFL_UI_WIN_PART_CLASS)) ||
5944 efl_file_mmap_get(efl_super(efl_part(obj, "background"), EFL_UI_WIN_PART_CLASS)))
5945 efl_file_load(efl_part(obj, "background"));
5946 }
5947 _ee_backbone_init(obj, sd);
5948 return obj;
5949 }
5950
5951 EOLIAN static void
_efl_ui_win_efl_canvas_object_legacy_ctor(Eo * obj,Efl_Ui_Win_Data * sd)5952 _efl_ui_win_efl_canvas_object_legacy_ctor(Eo *obj, Efl_Ui_Win_Data *sd)
5953 {
5954 efl_canvas_object_legacy_ctor(efl_super(obj, MY_CLASS));
5955 sd->legacy.ctor = EINA_TRUE;
5956 }
5957
5958 EOLIAN static Efl_Ui_Focus_Manager*
_efl_ui_win_efl_ui_widget_focus_manager_focus_manager_create(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * pd EINA_UNUSED,Efl_Ui_Focus_Object * root)5959 _efl_ui_win_efl_ui_widget_focus_manager_focus_manager_create(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *pd EINA_UNUSED, Efl_Ui_Focus_Object *root)
5960 {
5961 Efl_Ui_Focus_Manager *manager;
5962
5963 manager = efl_add(EFL_UI_FOCUS_MANAGER_CALC_CLASS, obj,
5964 efl_ui_focus_manager_root_set(efl_added, root)
5965 );
5966
5967 return manager;
5968 }
5969
5970 EOLIAN static void
_efl_ui_win_efl_object_destructor(Eo * obj,Efl_Ui_Win_Data * pd EINA_UNUSED)5971 _efl_ui_win_efl_object_destructor(Eo *obj, Efl_Ui_Win_Data *pd EINA_UNUSED)
5972 {
5973 #ifdef HAVE_ELEMENTARY_WL2
5974 if (pd->type == EFL_UI_WIN_TYPE_FAKE)
5975 {
5976 if (pd->wl.win)
5977 ecore_wl2_window_free(pd->wl.win);
5978 }
5979 #endif
5980 if (pd->finalize_future)
5981 eina_future_cancel(pd->finalize_future);
5982
5983 _ee_backbone_shutdown(obj, pd);
5984
5985 efl_destructor(efl_super(obj, MY_CLASS));
5986
5987 efl_unref(pd->provider);
5988 }
5989
5990 EOLIAN static Eo *
_efl_ui_win_efl_object_constructor(Eo * obj,Efl_Ui_Win_Data * pd)5991 _efl_ui_win_efl_object_constructor(Eo *obj, Efl_Ui_Win_Data *pd)
5992 {
5993 /* UGLY HACK: Do (almost) nothing here:
5994 * We are calling the constructor chain from the finalizer. It's
5995 * really bad and hacky. Needs fixing. */
5996
5997 pd->obj = obj;
5998 pd->provider = efl_add_ref(EFL_UI_FOCUS_PARENT_PROVIDER_STANDARD_CLASS, NULL);
5999 pd->profile.available = eina_array_new(4);
6000 pd->max_w = pd->max_h = -1;
6001 pd->planned_changes = eina_array_new(10);
6002
6003 // For bindings: if no parent, allow simple unref
6004 if (!efl_parent_get(obj))
6005 efl_allow_parent_unref_set(obj, EINA_TRUE);
6006
6007 if (!elm_widget_is_legacy(obj))
6008 pd->type = EFL_UI_WIN_TYPE_BASIC;
6009
6010 return obj;
6011 }
6012
6013 EOLIAN static void
_efl_ui_win_efl_text_text_set(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,const char * title)6014 _efl_ui_win_efl_text_text_set(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, const char *title)
6015 {
6016 if (!title) return;
6017 eina_stringshare_replace(&(sd->title), title);
6018 if (sd->ee)
6019 TRAP(sd, title_set, sd->title);
6020 if (sd->frame_obj)
6021 {
6022 if (elm_widget_is_legacy(sd->obj))
6023 edje_object_part_text_escaped_set(sd->frame_obj, "elm.text.title", sd->title);
6024 else
6025 edje_object_part_text_escaped_set(sd->frame_obj, "efl.text.title", sd->title);
6026 }
6027 }
6028
6029 EOLIAN static const char*
_efl_ui_win_efl_text_text_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)6030 _efl_ui_win_efl_text_text_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
6031 {
6032 return sd->title;
6033 }
6034
6035 EOLIAN void
_efl_ui_win_efl_ui_i18n_language_set(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,const char * locale)6036 _efl_ui_win_efl_ui_i18n_language_set(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, const char *locale)
6037 {
6038 if (sd->frame_obj)
6039 efl_ui_language_set(sd->frame_obj, locale);
6040 }
6041
6042 EOLIAN const char *
_efl_ui_win_efl_ui_i18n_language_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)6043 _efl_ui_win_efl_ui_i18n_language_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
6044 {
6045 return sd->frame_obj ? efl_ui_language_get(sd->frame_obj) : NULL;
6046 }
6047
6048 EOLIAN static void
_efl_ui_win_efl_ui_l10n_l10n_text_set(Eo * obj,Efl_Ui_Win_Data * sd,const char * label,const char * domain)6049 _efl_ui_win_efl_ui_l10n_l10n_text_set(Eo *obj, Efl_Ui_Win_Data *sd, const char *label, const char *domain)
6050 {
6051 if (sd->frame_obj)
6052 efl_ui_l10n_text_set(efl_part(obj, "efl.text.title"), label, domain);
6053 }
6054
6055 EOLIAN static const char *
_efl_ui_win_efl_ui_l10n_l10n_text_get(const Eo * obj,Efl_Ui_Win_Data * sd,const char ** domain)6056 _efl_ui_win_efl_ui_l10n_l10n_text_get(const Eo *obj, Efl_Ui_Win_Data *sd, const char **domain)
6057 {
6058 return sd->frame_obj ?
6059 efl_ui_l10n_text_get(efl_part(obj, "efl.text.title"), domain) : NULL;
6060 }
6061
6062 EOLIAN static void
_efl_ui_win_win_type_set(Eo * obj,Efl_Ui_Win_Data * sd,Efl_Ui_Win_Type type)6063 _efl_ui_win_win_type_set(Eo *obj, Efl_Ui_Win_Data *sd, Efl_Ui_Win_Type type)
6064 {
6065 if (efl_finalized_get(obj))
6066 {
6067 ERR("This function is only allowed during construction.");
6068 return;
6069 }
6070 sd->type = type;
6071 }
6072
6073 EOLIAN static Efl_Ui_Win_Type
_efl_ui_win_win_type_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)6074 _efl_ui_win_win_type_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
6075 {
6076 return sd->type;
6077 }
6078
6079 EOLIAN static void
_efl_ui_win_win_name_set(Eo * obj,Efl_Ui_Win_Data * sd,const char * name)6080 _efl_ui_win_win_name_set(Eo *obj, Efl_Ui_Win_Data *sd, const char *name)
6081 {
6082 if (efl_finalized_get(obj))
6083 {
6084 ERR("This function is only allowed during construction.");
6085 return;
6086 }
6087 sd->name = eina_stringshare_add(name);
6088 }
6089
6090 EOLIAN static const char *
_efl_ui_win_win_name_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)6091 _efl_ui_win_win_name_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
6092 {
6093 return sd->name;
6094 }
6095
6096 EOLIAN static void
_efl_ui_win_accel_preference_set(Eo * obj,Efl_Ui_Win_Data * pd,const char * accel)6097 _efl_ui_win_accel_preference_set(Eo *obj, Efl_Ui_Win_Data *pd, const char *accel)
6098 {
6099 if (efl_finalized_get(obj))
6100 {
6101 ERR("This function is only allowed during construction.");
6102 return;
6103 }
6104 eina_stringshare_replace(&pd->accel_pref, accel);
6105 }
6106
6107 EOLIAN static const char *
_efl_ui_win_accel_preference_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * pd)6108 _efl_ui_win_accel_preference_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *pd)
6109 {
6110 return pd->accel_pref;
6111 }
6112
6113 EOLIAN static void
_efl_ui_win_win_role_set(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,const char * role)6114 _efl_ui_win_win_role_set(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, const char *role)
6115 {
6116 if (!role) return;
6117 eina_stringshare_replace(&(sd->role), role);
6118 #ifdef HAVE_ELEMENTARY_X
6119 _elm_win_xwin_update(sd);
6120 #endif
6121 }
6122
6123 EOLIAN static const char*
_efl_ui_win_win_role_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)6124 _efl_ui_win_win_role_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
6125 {
6126 return sd->role;
6127 }
6128
6129 EOLIAN static void
_efl_ui_win_icon_object_set(Eo * obj,Efl_Ui_Win_Data * sd,Evas_Object * icon)6130 _efl_ui_win_icon_object_set(Eo *obj, Efl_Ui_Win_Data *sd, Evas_Object *icon)
6131 {
6132 if (icon && (!efl_isa(icon, EFL_CANVAS_IMAGE_INTERNAL_CLASS) &&
6133 !efl_isa(icon, EFL_UI_IMAGE_CLASS)))
6134 {
6135 ERR("Icon object type is not supported!");
6136 efl_del(icon);
6137 return;
6138 }
6139
6140 if (sd->icon)
6141 {
6142 efl_event_callback_del(sd->icon, EFL_EVENT_DEL, _elm_win_on_icon_del, obj);
6143 efl_del(sd->icon);
6144 }
6145 sd->icon = icon;
6146 if (sd->icon)
6147 {
6148 efl_event_callback_add(sd->icon, EFL_EVENT_DEL, _elm_win_on_icon_del, obj);
6149 if (sd->frame_obj)
6150 {
6151 if (elm_widget_is_legacy(sd->obj))
6152 edje_object_part_swallow(sd->frame_obj, "elm.swallow.icon", sd->icon);
6153 else
6154 edje_object_part_swallow(sd->frame_obj, "efl.icon", sd->icon);
6155
6156 evas_object_is_frame_object_set(sd->icon, EINA_TRUE);
6157 }
6158 }
6159 #ifdef HAVE_ELEMENTARY_X
6160 _elm_win_xwin_update(sd);
6161 #endif
6162 }
6163
6164 EOLIAN static const Evas_Object*
_efl_ui_win_icon_object_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)6165 _efl_ui_win_icon_object_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
6166 {
6167 return sd->icon;
6168 }
6169
6170 EOLIAN static const Eina_Value *
_efl_ui_win_exit_on_close_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)6171 _efl_ui_win_exit_on_close_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
6172 {
6173 return &sd->exit_on_close;
6174 }
6175
6176 EOLIAN static void
_efl_ui_win_exit_on_close_set(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,const Eina_Value * exit_code)6177 _efl_ui_win_exit_on_close_set(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, const Eina_Value *exit_code)
6178 {
6179 const Eina_Value_Type *type = eina_value_type_get(exit_code);
6180
6181 if (type)
6182 eina_value_copy(exit_code, &sd->exit_on_close);
6183 else
6184 eina_value_flush(&sd->exit_on_close);
6185 }
6186
6187 /* Only for C API */
6188 EAPI void
elm_win_autodel_set(Eo * obj,Eina_Bool autodel)6189 elm_win_autodel_set(Eo *obj, Eina_Bool autodel)
6190 {
6191 ELM_WIN_DATA_GET_OR_RETURN(obj, sd);
6192 sd->autodel = autodel;
6193 }
6194
6195 EAPI Eina_Bool
elm_win_autodel_get(const Eo * obj)6196 elm_win_autodel_get(const Eo *obj)
6197 {
6198 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
6199 if (!sd) return EINA_FALSE;
6200 return sd->autodel;
6201 }
6202
6203 EOLIAN static void
_efl_ui_win_autohide_set(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,Eina_Bool autohide)6204 _efl_ui_win_autohide_set(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, Eina_Bool autohide)
6205 {
6206 sd->autohide = autohide;
6207 }
6208
6209 EOLIAN static Eina_Bool
_efl_ui_win_autohide_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)6210 _efl_ui_win_autohide_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
6211 {
6212 return sd->autohide;
6213 }
6214
6215 EOLIAN static void
_efl_ui_win_activate(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)6216 _efl_ui_win_activate(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
6217 {
6218 TRAP(sd, activate);
6219 }
6220
6221 EOLIAN static void
_efl_ui_win_efl_gfx_stack_raise_to_top(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * pd)6222 _efl_ui_win_efl_gfx_stack_raise_to_top(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *pd)
6223 {
6224 TRAP(pd, raise);
6225 }
6226
6227 EAPI void
elm_win_raise(Eo * obj)6228 elm_win_raise(Eo *obj)
6229 {
6230 efl_gfx_stack_raise_to_top(obj);
6231 }
6232
6233 EOLIAN static void
_efl_ui_win_efl_gfx_stack_lower_to_bottom(Eo * obj,Efl_Ui_Win_Data * pd EINA_UNUSED)6234 _efl_ui_win_efl_gfx_stack_lower_to_bottom(Eo *obj, Efl_Ui_Win_Data *pd EINA_UNUSED)
6235 {
6236 // Do nothing: in X we could request to stack lower but that has been abused
6237 // and transformed into a kind of "iconify". As a consequence, lower is
6238 // not allowed in EO land.
6239 if (!elm_widget_is_legacy(obj)) return;
6240
6241 // Legacy support...
6242 elm_win_lower(obj);
6243 }
6244
6245 EOLIAN static void
_efl_ui_win_center(Eo * obj,Efl_Ui_Win_Data * sd,Eina_Bool h,Eina_Bool v)6246 _efl_ui_win_center(Eo *obj, Efl_Ui_Win_Data *sd, Eina_Bool h, Eina_Bool v)
6247 {
6248 int win_w, win_h, screen_x, screen_y, screen_w, screen_h, nx, ny;
6249
6250 if (sd->deferred_resize_job) _elm_win_resize_job(sd->obj);
6251 if (sd->frame_obj) edje_object_message_signal_process(sd->frame_obj);
6252 evas_smart_objects_calculate(evas_object_evas_get(obj));
6253 _elm_win_resize_objects_eval(obj, EINA_FALSE);
6254 if ((trap) && (trap->center) && (!trap->center(sd->trap_data, obj, h, v)))
6255 return;
6256
6257 if (!efl_gfx_entity_visible_get(obj))
6258 {
6259 // Chose to use env var so this will also translate more easily
6260 // to wayland. yes - we can get x atoms to figure out if wm is
6261 // enlightenment, but this works just as well. for wl we'd need
6262 // an alternate wl specific way... this below works better IMHO
6263 const char *s = getenv("DESKTOP");
6264
6265 if ((s) && (!strcasecmp(s, "Enlightenment")))
6266 {
6267 #ifdef HAVE_ELEMENTARY_X
6268 if (sd->x.xwin)
6269 {
6270 static Ecore_X_Atom state = 0;
6271 static Ecore_X_Atom centered = 0;
6272
6273 _internal_elm_win_xwindow_get(sd);
6274 if (!centered) centered = ecore_x_atom_get
6275 ("__E_ATOM_WINDOW_STATE_CENTERED");
6276 if (!state) state = ecore_x_atom_get
6277 ("__E_ATOM_WINDOW_STATE");
6278 ecore_x_window_prop_card32_set(sd->x.xwin, state, ¢ered, 1);
6279 }
6280 #endif
6281 // XXX: what to do with wayland?
6282 // XXX: what to do with win32?
6283 // XXX: what to do with osx/coca?
6284 // etc.
6285 return;
6286 }
6287 // not e - fall back to manually placing on what we think the screen
6288 // is/will be... to do this move window to where pointer is first
6289 #ifdef HAVE_ELEMENTARY_X
6290 if (sd->x.xwin)
6291 {
6292 int x = 0, y = 0;
6293
6294 if (sd->req_wh)
6295 {
6296 win_w = sd->req_w;
6297 win_h = sd->req_h;
6298 }
6299 else evas_object_geometry_get(obj, NULL, NULL, &win_w, &win_h);
6300 ecore_x_pointer_root_xy_get(&x, &y);
6301 ecore_evas_move(sd->ee, x - (win_w / 2), y - (win_h / 2));
6302 }
6303 #endif
6304 // XXX: what to do with wayland?
6305 // XXX: what to do with win32?
6306 // XXX: what to do with osx/coca?
6307 // etc.
6308 }
6309
6310 ecore_evas_screen_geometry_get(sd->ee,
6311 &screen_x, &screen_y,
6312 &screen_w, &screen_h);
6313 if ((!screen_w) || (!screen_h)) return;
6314
6315 if (sd->req_wh)
6316 {
6317 win_w = sd->req_w;
6318 win_h = sd->req_h;
6319 }
6320 else evas_object_geometry_get(obj, NULL, NULL, &win_w, &win_h);
6321 if (sd->req_xy)
6322 {
6323 nx = sd->req_x;
6324 ny = sd->req_y;
6325 }
6326 else evas_object_geometry_get(obj, &nx, &ny, NULL, NULL);
6327
6328 if ((!win_w) || (!win_h)) return;
6329
6330 if (h) nx = win_w >= screen_w ? 0 : (screen_w / 2) - (win_w / 2);
6331 if (v) ny = win_h >= screen_h ? 0 : (screen_h / 2) - (win_h / 2);
6332
6333 sd->req_xy = EINA_TRUE;
6334 sd->req_x = screen_x + nx;
6335 sd->req_y = screen_y + ny;
6336 evas_object_move(obj, screen_x + nx, screen_y + ny);
6337 }
6338
6339 EOLIAN static void
_efl_ui_win_borderless_set(Eo * obj,Efl_Ui_Win_Data * sd,Eina_Bool borderless)6340 _efl_ui_win_borderless_set(Eo *obj, Efl_Ui_Win_Data *sd, Eina_Bool borderless)
6341 {
6342 sd->csd.need_borderless = borderless ? 1 : 0;
6343 _elm_win_frame_style_update(sd, 0, 1);
6344
6345 #ifdef HAVE_ELEMENTARY_X
6346 if (!sd->x.xwin || !sd->csd.need)
6347 #endif
6348 TRAP(sd, borderless_set, borderless);
6349
6350 _elm_win_resize_objects_eval(obj, EINA_FALSE);
6351 #ifdef HAVE_ELEMENTARY_X
6352 _elm_win_xwin_update(sd);
6353 #endif
6354 }
6355
6356 EOLIAN static Eina_Bool
_efl_ui_win_borderless_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)6357 _efl_ui_win_borderless_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
6358 {
6359 if (!sd->csd.need)
6360 return ecore_evas_borderless_get(sd->ee);
6361 return sd->csd.need_borderless;
6362 }
6363
6364 EOLIAN static void
_efl_ui_win_alpha_set(Eo * obj,Efl_Ui_Win_Data * sd,Eina_Bool enabled)6365 _efl_ui_win_alpha_set(Eo *obj, Efl_Ui_Win_Data *sd, Eina_Bool enabled)
6366 {
6367 sd->application_alpha = enabled;
6368 _elm_win_apply_alpha(obj, sd);
6369 _elm_win_frame_style_update(sd, 0, 1);
6370 }
6371
6372 EOLIAN static Eina_Bool
_efl_ui_win_alpha_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)6373 _efl_ui_win_alpha_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
6374 {
6375 if (sd->img_obj)
6376 {
6377 return evas_object_image_alpha_get(sd->img_obj);
6378 }
6379 else
6380 {
6381 return ecore_evas_alpha_get(sd->ee);
6382 }
6383
6384 return EINA_FALSE;
6385 }
6386
6387 EOLIAN static void
_efl_ui_win_fullscreen_set(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,Eina_Bool fullscreen)6388 _efl_ui_win_fullscreen_set(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, Eina_Bool fullscreen)
6389 {
6390 const char *engine_name = ecore_evas_engine_name_get(sd->ee);
6391 // YYY: handle if sd->img_obj
6392 if (engine_name &&
6393 ((!strcmp(engine_name, ELM_SOFTWARE_FB)) ||
6394 (!strcmp(engine_name, ELM_DRM)) ||
6395 (!strcmp(engine_name, ELM_GL_DRM))))
6396 {
6397 // these engines... can ONLY be fullscreen
6398 return;
6399 }
6400 else if (sd->type == EFL_UI_WIN_TYPE_FAKE)
6401 sd->fullscreen = !!fullscreen;
6402 else
6403 {
6404 // sd->fullscreen = fullscreen;
6405 TRAP(sd, fullscreen_set, fullscreen);
6406
6407 #ifdef HAVE_ELEMENTARY_X
6408 _elm_win_xwin_update(sd);
6409 #endif
6410 }
6411 }
6412
6413 EOLIAN static Eina_Bool
_efl_ui_win_fullscreen_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)6414 _efl_ui_win_fullscreen_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
6415 {
6416 const char *engine_name = ecore_evas_engine_name_get(sd->ee);
6417
6418 if (engine_name &&
6419 ((!strcmp(engine_name, ELM_SOFTWARE_FB)) ||
6420 (!strcmp(engine_name, ELM_DRM)) ||
6421 (!strcmp(engine_name, ELM_GL_DRM))))
6422 {
6423 // these engines... can ONLY be fullscreen
6424 return EINA_TRUE;
6425 }
6426 return sd->fullscreen;
6427 }
6428
6429 static inline Eo *
_main_menu_swallow_get(Efl_Ui_Win_Data * sd)6430 _main_menu_swallow_get(Efl_Ui_Win_Data *sd)
6431 {
6432 Eina_Bool legacy_menu_swallow = EINA_TRUE;
6433 const char *data;
6434 int version;
6435
6436 data = edje_object_data_get(sd->legacy.edje, "version");
6437 version = data ? atoi(data) : 0;
6438 if (version >= 119) legacy_menu_swallow = EINA_FALSE;
6439
6440 #ifdef HAVE_ELEMENTARY_COCOA
6441 if (sd->cocoa.win) legacy_menu_swallow = EINA_TRUE;
6442 #endif
6443
6444 if (legacy_menu_swallow)
6445 {
6446 DBG("Detected legacy theme, using legacy swallows.");
6447 return sd->legacy.edje;
6448 }
6449 return sd->frame_obj;
6450 }
6451
6452 static void
_main_menu_resize_cb(void * data EINA_UNUSED,const Efl_Event * ev)6453 _main_menu_resize_cb(void *data EINA_UNUSED, const Efl_Event *ev)
6454 {
6455 // After resize, the framespace size has changed, so update the win geometry
6456 _elm_win_resize_objects_eval(ev->object, EINA_FALSE);
6457 efl_event_callback_del(ev->object, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _main_menu_resize_cb, NULL);
6458 }
6459
6460 static void
_dbus_menu_set(Eina_Bool dbus_connect,void * data)6461 _dbus_menu_set(Eina_Bool dbus_connect, void *data)
6462 {
6463 ELM_WIN_DATA_GET_OR_RETURN(data, sd);
6464 Eo *swallow = _main_menu_swallow_get(sd);
6465
6466 if (dbus_connect)
6467 {
6468 DBG("Setting menu to D-Bus");
6469 edje_object_part_unswallow(swallow, sd->main_menu);
6470 sd->csd.need_menu = EINA_FALSE;
6471 _elm_menu_menu_bar_hide(sd->main_menu);
6472 _elm_win_resize_objects_eval(sd->obj, EINA_FALSE);
6473 if (swallow != sd->frame_obj)
6474 {
6475 // Note: Based on EFL 1.18 the signal was "elm,action,hide"
6476 // and not "elm,action,hide_menu" as expected.
6477 if (elm_widget_is_legacy(data))
6478 edje_object_signal_emit(swallow, "elm,action,hide", "elm");
6479 else
6480 edje_object_signal_emit(swallow, "efl,action,hide", "efl");
6481 edje_object_message_signal_recursive_process(swallow);
6482 }
6483 }
6484 else
6485 {
6486 DBG("Setting menu to local mode");
6487 efl_event_callback_add(sd->obj, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _main_menu_resize_cb, NULL);
6488
6489 if (elm_widget_is_legacy(sd->obj))
6490 edje_object_part_swallow(swallow, "elm.swallow.menu", sd->main_menu);
6491 else
6492 edje_object_part_swallow(swallow, "efl.menu", sd->main_menu);
6493
6494 evas_object_show(sd->main_menu);
6495 if (swallow == sd->frame_obj)
6496 {
6497 efl_canvas_object_is_frame_object_set(sd->main_menu, EINA_TRUE);
6498 sd->csd.need_menu = EINA_TRUE;
6499 }
6500 else
6501 {
6502 if (elm_widget_is_legacy(data))
6503 edje_object_signal_emit(swallow, "elm,action,show_menu", "elm");
6504 else
6505 edje_object_signal_emit(swallow, "efl,action,show_menu", "efl");
6506 edje_object_message_signal_recursive_process(swallow);
6507 }
6508 }
6509 _elm_win_frame_style_update(sd, 0, 1);
6510 //sd->deferred_resize_job = EINA_TRUE;
6511 }
6512
6513 EOLIAN static const Eina_Value *
_efl_ui_win_exit_on_all_windows_closed_get(void)6514 _efl_ui_win_exit_on_all_windows_closed_get(void)
6515 {
6516 return &exit_on_all_windows_closed;
6517 }
6518
6519 EOLIAN static void
_efl_ui_win_exit_on_all_windows_closed_set(const Eina_Value * exit_code)6520 _efl_ui_win_exit_on_all_windows_closed_set(const Eina_Value *exit_code)
6521 {
6522 const Eina_Value_Type *type = eina_value_type_get(exit_code);
6523
6524 if (type)
6525 eina_value_copy(exit_code, &exit_on_all_windows_closed);
6526 else
6527 eina_value_flush(&exit_on_all_windows_closed);
6528 }
6529
6530 EOLIAN static void
_efl_ui_win_maximized_set(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,Eina_Bool maximized)6531 _efl_ui_win_maximized_set(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, Eina_Bool maximized)
6532 {
6533 _elm_win_frame_style_update(sd, 0, 1);
6534 // YYY: handle if sd->img_obj
6535 TRAP(sd, maximized_set, maximized);
6536 #ifdef HAVE_ELEMENTARY_X
6537 _elm_win_xwin_update(sd);
6538 #endif
6539 }
6540
6541 EOLIAN static Eina_Bool
_efl_ui_win_maximized_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)6542 _efl_ui_win_maximized_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
6543 {
6544 return sd->maximized;
6545 }
6546
6547 EOLIAN static void
_efl_ui_win_minimized_set(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,Eina_Bool minimized)6548 _efl_ui_win_minimized_set(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, Eina_Bool minimized)
6549 {
6550 // sd->minimized = minimized;
6551 TRAP(sd, iconified_set, minimized);
6552 #ifdef HAVE_ELEMENTARY_X
6553 _elm_win_xwin_update(sd);
6554 #endif
6555 }
6556
6557 EOLIAN static Eina_Bool
_efl_ui_win_minimized_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)6558 _efl_ui_win_minimized_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
6559 {
6560 return sd->minimized;
6561 }
6562
6563 EOLIAN static void
_efl_ui_win_wm_available_profiles_set(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,const Eina_Array * profiles)6564 _efl_ui_win_wm_available_profiles_set(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, const Eina_Array *profiles)
6565 {
6566 Eina_Bool found = EINA_FALSE;
6567
6568 _elm_win_available_profiles_del(sd);
6569 if (profiles && eina_array_count(profiles))
6570 {
6571 Eina_Iterator *it;
6572 const char *prof;
6573
6574 it = eina_array_iterator_new(profiles);
6575 EINA_ITERATOR_FOREACH(it, prof)
6576 {
6577 Eina_Stringshare *str = eina_stringshare_add(prof);
6578 if (!str) continue;
6579
6580 eina_array_push(sd->profile.available, str);
6581 /* check to see if a given array has a current profile of elm_win */
6582 if (str == sd->profile.name)
6583 found = EINA_TRUE;
6584 }
6585 eina_iterator_free(it);
6586 }
6587
6588 if (ecore_evas_window_profile_supported_get(sd->ee))
6589 {
6590 ecore_evas_window_available_profiles_set(sd->ee,
6591 (const char **) sd->profile.available->data,
6592 eina_array_count(sd->profile.available));
6593
6594 /* current profile of elm_win is wrong, change profile */
6595 if (!found && eina_array_count(sd->profile.available))
6596 {
6597 eina_stringshare_replace(&(sd->profile.name),
6598 eina_array_data_get(sd->profile.available, 0));
6599 ecore_evas_window_profile_set(sd->ee, sd->profile.name);
6600 }
6601
6602 }
6603 else
6604 {
6605 if (eina_array_count(sd->profile.available))
6606 _elm_win_profile_update(sd);
6607 }
6608 }
6609
6610 EOLIAN static const Eina_Array *
_efl_ui_win_wm_available_profiles_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)6611 _efl_ui_win_wm_available_profiles_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
6612 {
6613 if (ecore_evas_window_profile_supported_get(sd->ee))
6614 {
6615 char **profiles = NULL; // all const
6616 unsigned int count, i;
6617 Eina_Bool ok;
6618
6619 ok = ecore_evas_window_available_profiles_get(sd->ee, &profiles, &count);
6620 if (!ok) return NULL;
6621
6622 if (count == eina_array_count(sd->profile.available))
6623 {
6624 for (i = 0; ok && (i < count); i++)
6625 {
6626 if (!eina_streq(profiles[i], eina_array_data_get(sd->profile.available, i)))
6627 ok = EINA_FALSE;
6628 }
6629 if (ok) return sd->profile.available;
6630 }
6631
6632 // Oops! What is going on here? Can this happen?
6633 INF("Available profile list has changed in ecore evas!");
6634 _elm_win_available_profiles_del(sd);
6635 for (i = 0; i < count; i++)
6636 {
6637 Eina_Stringshare *str = eina_stringshare_add(profiles[i]);
6638 if (str) eina_array_push(sd->profile.available, str);
6639 }
6640 }
6641
6642 return sd->profile.available;
6643 }
6644
6645 EOLIAN static void
_efl_ui_win_urgent_set(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,Efl_Ui_Win_Urgent_Mode urgent)6646 _efl_ui_win_urgent_set(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, Efl_Ui_Win_Urgent_Mode urgent)
6647 {
6648 Eina_Bool urgent_tmp = !!urgent;
6649
6650 if (sd->urgent == urgent_tmp) return;
6651
6652 sd->urgent = urgent_tmp;
6653 TRAP(sd, urgent_set, urgent_tmp);
6654 #ifdef HAVE_ELEMENTARY_X
6655 _elm_win_xwin_update(sd);
6656 #endif
6657 }
6658
6659 EOLIAN static Efl_Ui_Win_Urgent_Mode
_efl_ui_win_urgent_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)6660 _efl_ui_win_urgent_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
6661 {
6662 if (sd->urgent) return EFL_UI_WIN_URGENT_MODE_URGENT;
6663 return EFL_UI_WIN_URGENT_MODE_NONE;
6664 }
6665
6666 EOLIAN static void
_efl_ui_win_modal_set(Eo * obj,Efl_Ui_Win_Data * sd,Efl_Ui_Win_Modal_Mode modal)6667 _efl_ui_win_modal_set(Eo *obj, Efl_Ui_Win_Data *sd, Efl_Ui_Win_Modal_Mode modal)
6668 {
6669 Eina_Bool modal_tmp = !!modal;
6670
6671 if (sd->modal_count) return;
6672
6673 if ((modal_tmp) && (!sd->modal) && (evas_object_visible_get(obj)))
6674 _elm_win_modality_increment(sd);
6675 else if ((!modal_tmp) && (sd->modal) && (evas_object_visible_get(obj)))
6676 _elm_win_modality_decrement(sd);
6677
6678 sd->modal = modal_tmp;
6679 TRAP(sd, modal_set, modal_tmp);
6680 #ifdef HAVE_ELEMENTARY_X
6681 _elm_win_xwin_update(sd);
6682 #endif
6683 }
6684
6685 EOLIAN static Efl_Ui_Win_Modal_Mode
_efl_ui_win_modal_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)6686 _efl_ui_win_modal_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
6687 {
6688 if (sd->modal) return EFL_UI_WIN_MODAL_MODE_MODAL;
6689 return EFL_UI_WIN_MODAL_MODE_NONE;
6690 }
6691
6692 static void
_win_aspect_set(Efl_Ui_Win_Data * sd,double aspect)6693 _win_aspect_set(Efl_Ui_Win_Data *sd, double aspect)
6694 {
6695 sd->aspect = aspect;
6696 TRAP(sd, aspect_set, aspect);
6697 #ifdef HAVE_ELEMENTARY_X
6698 _elm_win_xwin_update(sd);
6699 #endif
6700 }
6701
6702 static double
_win_aspect_get(Efl_Ui_Win_Data * sd)6703 _win_aspect_get(Efl_Ui_Win_Data *sd)
6704 {
6705 return sd->aspect;
6706 }
6707
6708 EOLIAN static void
_efl_ui_win_efl_gfx_hint_hint_aspect_set(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * pd,Efl_Gfx_Hint_Aspect mode,Eina_Size2D sz)6709 _efl_ui_win_efl_gfx_hint_hint_aspect_set(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *pd,
6710 Efl_Gfx_Hint_Aspect mode, Eina_Size2D sz)
6711 {
6712 if (sz.h) _win_aspect_set(pd, (double) sz.w / (double) sz.h);
6713 else _win_aspect_set(pd, 0.0);
6714 efl_gfx_hint_aspect_set(efl_super(obj, MY_CLASS), mode, sz);
6715 #ifdef HAVE_ELEMENTARY_WL2
6716 if (pd->wl.win)
6717 ecore_wl2_window_aspect_set(pd->wl.win, sz.w, sz.h, mode);
6718 #endif
6719 }
6720
6721 EOLIAN static void
_efl_ui_win_efl_gfx_hint_hint_weight_set(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * pd EINA_UNUSED,double w,double h)6722 _efl_ui_win_efl_gfx_hint_hint_weight_set(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *pd EINA_UNUSED,
6723 double w, double h)
6724 {
6725 efl_gfx_hint_weight_set(efl_super(obj, MY_CLASS), w, h);
6726 #ifdef HAVE_ELEMENTARY_WL2
6727 if (pd->wl.win)
6728 ecore_wl2_window_weight_set(pd->wl.win, w, h);
6729 #endif
6730 }
6731
6732 EOLIAN static void
_efl_ui_win_hint_base_set(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,Eina_Size2D sz)6733 _efl_ui_win_hint_base_set(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, Eina_Size2D sz)
6734 {
6735 sd->size_base_w = sz.w;
6736 sd->size_base_h = sz.h;
6737 TRAP(sd, size_base_set, sz.w, sz.h);
6738 #ifdef HAVE_ELEMENTARY_X
6739 _elm_win_xwin_update(sd);
6740 #endif
6741 }
6742
6743 EOLIAN static Eina_Size2D
_efl_ui_win_hint_base_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)6744 _efl_ui_win_hint_base_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
6745 {
6746 return EINA_SIZE2D(sd->size_base_w, sd->size_base_h);
6747 }
6748
6749 EOLIAN static void
_efl_ui_win_hint_step_set(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,Eina_Size2D sz)6750 _efl_ui_win_hint_step_set(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, Eina_Size2D sz)
6751 {
6752 sd->size_step_w = sz.w;
6753 sd->size_step_h = sz.h;
6754 TRAP(sd, size_step_set, sz.w, sz.h);
6755 #ifdef HAVE_ELEMENTARY_X
6756 _elm_win_xwin_update(sd);
6757 #endif
6758 }
6759
6760 EOLIAN static void
_efl_ui_win_efl_gfx_hint_hint_size_max_set(Eo * obj,Efl_Ui_Win_Data * sd,Eina_Size2D sz)6761 _efl_ui_win_efl_gfx_hint_hint_size_max_set(Eo *obj, Efl_Ui_Win_Data *sd, Eina_Size2D sz)
6762 {
6763 if (sd->tmp_updating_hints)
6764 {
6765 efl_gfx_hint_size_max_set(efl_super(obj, MY_CLASS), sz);
6766 }
6767 else
6768 {
6769 if (sz.w < 1) sz.w = -1;
6770 if (sz.h < 1) sz.h = -1;
6771 sd->max_w = sz.w;
6772 sd->max_h = sz.h;
6773 _elm_win_resize_objects_eval(obj, EINA_FALSE);
6774 }
6775 }
6776
6777 EOLIAN static Eina_Size2D
_efl_ui_win_hint_step_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)6778 _efl_ui_win_hint_step_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
6779 {
6780 return EINA_SIZE2D(sd->size_step_w, sd->size_step_h);
6781 }
6782
6783 EAPI void
elm_win_norender_push(Evas_Object * obj)6784 elm_win_norender_push(Evas_Object *obj)
6785 {
6786 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
6787 if (!sd) return;
6788
6789 sd->norender++;
6790 if (sd->norender == 1) ecore_evas_manual_render_set(sd->ee, EINA_TRUE);
6791 }
6792
6793 EAPI void
elm_win_norender_pop(Evas_Object * obj)6794 elm_win_norender_pop(Evas_Object *obj)
6795 {
6796 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
6797 if (!sd) return;
6798
6799 if (sd->norender <= 0) return;
6800 sd->norender--;
6801 if (sd->norender == 0) ecore_evas_manual_render_set(sd->ee, EINA_FALSE);
6802 }
6803
6804 EAPI int
elm_win_norender_get(const Evas_Object * obj)6805 elm_win_norender_get(const Evas_Object *obj)
6806 {
6807 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
6808 if (!sd) return -1;
6809
6810 return sd->norender;
6811 }
6812
6813 EAPI void
elm_win_render(Evas_Object * obj)6814 elm_win_render(Evas_Object *obj)
6815 {
6816 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
6817 if (!sd) return;
6818
6819 ecore_evas_manual_render(sd->ee);
6820 }
6821
6822 EOLIAN static void
_efl_ui_win_wm_available_rotations_set(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,Eina_Bool allow_0,Eina_Bool allow_90,Eina_Bool allow_180,Eina_Bool allow_270)6823 _efl_ui_win_wm_available_rotations_set(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd,
6824 Eina_Bool allow_0, Eina_Bool allow_90,
6825 Eina_Bool allow_180, Eina_Bool allow_270)
6826 {
6827 unsigned cnt = 0;
6828 int rots[4];
6829
6830 if (allow_0) rots[cnt++] = 0;
6831 if (allow_90) rots[cnt++] = 90;
6832 if (allow_180) rots[cnt++] = 180;
6833 if (allow_270) rots[cnt++] = 270;
6834 sd->wm_rot.use = EINA_TRUE;
6835
6836 ELM_SAFE_FREE(sd->wm_rot.rots, free);
6837 sd->wm_rot.count = 0;
6838
6839 if (cnt)
6840 {
6841 sd->wm_rot.rots = malloc(sizeof(int) * cnt);
6842 if (!sd->wm_rot.rots) return;
6843 memcpy(sd->wm_rot.rots, rots, cnt * sizeof(int));
6844 sd->wm_rot.count = cnt;
6845 }
6846
6847 ecore_evas_wm_rotation_available_rotations_set(sd->ee,
6848 sd->wm_rot.rots,
6849 sd->wm_rot.count);
6850 }
6851
6852 EOLIAN static Eina_Bool
_efl_ui_win_wm_available_rotations_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,Eina_Bool * allow_0,Eina_Bool * allow_90,Eina_Bool * allow_180,Eina_Bool * allow_270)6853 _efl_ui_win_wm_available_rotations_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd,
6854 Eina_Bool *allow_0, Eina_Bool *allow_90,
6855 Eina_Bool *allow_180, Eina_Bool *allow_270)
6856 {
6857 if (!sd->wm_rot.use) goto end;
6858
6859 if (allow_0) *allow_0 = EINA_FALSE;
6860 if (allow_90) *allow_90 = EINA_FALSE;
6861 if (allow_180) *allow_180 = EINA_FALSE;
6862 if (allow_270) *allow_270 = EINA_FALSE;
6863
6864 for (unsigned k = 0; k < sd->wm_rot.count; k++)
6865 {
6866 switch (sd->wm_rot.rots[k])
6867 {
6868 case 0: if (allow_0) *allow_0 = EINA_TRUE; break;
6869 case 90: if (allow_90) *allow_90 = EINA_TRUE; break;
6870 case 180: if (allow_180) *allow_180 = EINA_TRUE; break;
6871 case 270: if (allow_270) *allow_270 = EINA_TRUE; break;
6872 default: ERR("Unsupported rotation %d", sd->wm_rot.rots[k]); break;
6873 }
6874 }
6875
6876 end:
6877 return !!sd->wm_rot.use;
6878 }
6879
6880 EAPI void
elm_win_wm_rotation_available_rotations_set(Elm_Win * obj,const int * rotations,unsigned int count)6881 elm_win_wm_rotation_available_rotations_set(Elm_Win *obj, const int *rotations, unsigned int count)
6882 {
6883 Eina_Bool allow[4] = { 0, };
6884 int found = 0;
6885
6886 if (!rotations || !count) goto end;
6887 for (unsigned k = 0; (k < count) && (found < 4); k++)
6888 {
6889 int rot = (((rotations[k] % 360) + 360) % 360) / 90;
6890 if (!allow[rot])
6891 {
6892 allow[rot] = EINA_TRUE;
6893 found++;
6894 }
6895 }
6896
6897 end:
6898 efl_ui_win_wm_available_rotations_set(obj, allow[0], allow[1], allow[2], allow[3]);
6899 }
6900
6901 EAPI Eina_Bool
elm_win_wm_rotation_available_rotations_get(const Elm_Win * obj,int ** rotations,unsigned int * count)6902 elm_win_wm_rotation_available_rotations_get(const Elm_Win *obj, int **rotations, unsigned int *count)
6903 {
6904 int rots[4] = { 0, };
6905 Eina_Bool allow[4] = { 0, };
6906 unsigned cnt = 0;
6907
6908 if (!efl_ui_win_wm_available_rotations_get(obj, &allow[0], &allow[1], &allow[2], &allow[3]))
6909 goto none;
6910
6911 for (int k = 0; k < 4; k++)
6912 if (allow[k])
6913 rots[cnt++] = k * 90;
6914
6915 if (!cnt) goto none;
6916
6917 if (rotations)
6918 {
6919 *rotations = malloc(sizeof(int) * cnt);
6920 if (!*rotations) goto none;
6921 memcpy(*rotations, rots, cnt * sizeof(int));
6922 }
6923 if (count) *count = cnt;
6924 return EINA_TRUE;
6925
6926 none:
6927 if (rotations) *rotations = NULL;
6928 if (count) *count = 0;
6929 return EINA_FALSE;
6930 }
6931
6932 EOLIAN static void
_efl_ui_win_sticky_set(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,Eina_Bool sticky)6933 _efl_ui_win_sticky_set(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, Eina_Bool sticky)
6934 {
6935 // sd->sticky = sticky;
6936 TRAP(sd, sticky_set, sticky);
6937 #ifdef HAVE_ELEMENTARY_X
6938 _elm_win_xwin_update(sd);
6939 #endif
6940 }
6941
6942 EOLIAN static Eina_Bool
_efl_ui_win_sticky_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)6943 _efl_ui_win_sticky_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
6944 {
6945 return sd->sticky;
6946 }
6947
6948 EOLIAN static void
_efl_ui_win_keyboard_mode_set(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,Efl_Ui_Win_Keyboard_Mode mode)6949 _efl_ui_win_keyboard_mode_set(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, Efl_Ui_Win_Keyboard_Mode mode)
6950 {
6951 if (mode == sd->kbdmode) return;
6952 #ifdef HAVE_ELEMENTARY_X
6953 _internal_elm_win_xwindow_get(sd);
6954 #endif
6955 sd->kbdmode = mode;
6956 #ifdef HAVE_ELEMENTARY_X
6957 if (sd->x.xwin)
6958 {
6959 _internal_elm_win_xwindow_get(sd);
6960 ecore_x_e_virtual_keyboard_state_set
6961 (sd->x.xwin, (Ecore_X_Virtual_Keyboard_State)sd->kbdmode);
6962 }
6963 #endif
6964 }
6965
6966 EOLIAN static Efl_Ui_Win_Keyboard_Mode
_efl_ui_win_keyboard_mode_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)6967 _efl_ui_win_keyboard_mode_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
6968 {
6969 return sd->kbdmode;
6970 }
6971
6972 EOLIAN static void
_efl_ui_win_indicator_mode_set(Eo * obj,Efl_Ui_Win_Data * sd,Efl_Ui_Win_Indicator_Mode mode)6973 _efl_ui_win_indicator_mode_set(Eo *obj, Efl_Ui_Win_Data *sd, Efl_Ui_Win_Indicator_Mode mode)
6974 {
6975 sd->legacy.forbidden = EINA_TRUE;
6976 if (sd->indimode == mode) return;
6977 sd->indimode = mode;
6978
6979 if (sd->indimode == EFL_UI_WIN_INDICATOR_MODE_OFF)
6980 {
6981 _indicator_del(sd);
6982 return;
6983 }
6984
6985 if (!sd->indicator) _indicator_add(sd);
6986
6987 if (elm_widget_is_legacy(obj))
6988 {
6989 if (sd->indimode == EFL_UI_WIN_INDICATOR_MODE_BG_OPAQUE)
6990 edje_object_signal_emit(sd->frame_obj, "elm,action,indicator,bg_opaque", "elm");
6991 else if (sd->indimode == EFL_UI_WIN_INDICATOR_MODE_BG_TRANSPARENT)
6992 edje_object_signal_emit(sd->frame_obj, "elm,action,indicator,bg_transparent", "elm");
6993 else if (sd->indimode == EFL_UI_WIN_INDICATOR_MODE_HIDDEN)
6994 edje_object_signal_emit(sd->frame_obj, "elm,action,indicator,hidden", "elm");
6995 }
6996 else
6997 {
6998 if (sd->indimode == EFL_UI_WIN_INDICATOR_MODE_BG_OPAQUE)
6999 edje_object_signal_emit(sd->frame_obj, "efl,action,indicator,bg_opaque", "efl");
7000 else if (sd->indimode == EFL_UI_WIN_INDICATOR_MODE_BG_TRANSPARENT)
7001 edje_object_signal_emit(sd->frame_obj, "efl,action,indicator,bg_transparent", "efl");
7002 else if (sd->indimode == EFL_UI_WIN_INDICATOR_MODE_HIDDEN)
7003 edje_object_signal_emit(sd->frame_obj, "efl,action,indicator,hidden", "efl");
7004 }
7005
7006 edje_object_message_signal_process(sd->frame_obj);
7007 evas_object_smart_calculate(sd->frame_obj);
7008 _elm_win_frame_obj_update(sd, 0);
7009 }
7010
7011 EOLIAN static Efl_Ui_Win_Indicator_Mode
_efl_ui_win_indicator_mode_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd EINA_UNUSED)7012 _efl_ui_win_indicator_mode_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd EINA_UNUSED)
7013 {
7014 sd->legacy.forbidden = EINA_TRUE;
7015 return sd->indimode;
7016 }
7017
7018 EOLIAN static Eina_Bool
_efl_ui_win_efl_ui_focus_object_focus_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)7019 _efl_ui_win_efl_ui_focus_object_focus_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
7020 {
7021 // Bypass widget implementation here.
7022 return ecore_evas_focus_get(sd->ee);
7023 }
7024
7025 EOLIAN static void
_efl_ui_win_screen_constrain_set(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,Eina_Bool constrain)7026 _efl_ui_win_screen_constrain_set(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, Eina_Bool constrain)
7027 {
7028 sd->constrain = !!constrain;
7029 }
7030
7031 EOLIAN static Eina_Bool
_efl_ui_win_screen_constrain_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)7032 _efl_ui_win_screen_constrain_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
7033 {
7034 return sd->constrain;
7035 }
7036
7037 EOLIAN static Eina_Size2D
_efl_ui_win_efl_screen_screen_size_in_pixels_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)7038 _efl_ui_win_efl_screen_screen_size_in_pixels_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
7039 {
7040 Eina_Size2D sz;
7041 ecore_evas_screen_geometry_get(sd->ee, NULL, NULL, &sz.w, &sz.h);
7042 return sz;
7043 }
7044
7045 EOLIAN static void
_efl_ui_win_efl_screen_screen_dpi_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,int * xdpi,int * ydpi)7046 _efl_ui_win_efl_screen_screen_dpi_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, int *xdpi, int *ydpi)
7047 {
7048 ecore_evas_screen_dpi_get(sd->ee, xdpi, ydpi);
7049 }
7050
7051 EOLIAN static int
_efl_ui_win_efl_screen_screen_rotation_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)7052 _efl_ui_win_efl_screen_screen_rotation_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
7053 {
7054 //TODO: query to wm about device's rotation
7055 (void)sd;
7056 WRN("Not yet implemented");
7057 return 0;
7058 }
7059
7060 EOLIAN static float
_efl_ui_win_efl_screen_screen_scale_factor_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd EINA_UNUSED)7061 _efl_ui_win_efl_screen_screen_scale_factor_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd EINA_UNUSED)
7062 {
7063 WRN("Not yet implemented");
7064 return 1.0;
7065 }
7066
7067 EOLIAN static void
_efl_ui_win_prop_focus_skip_set(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,Eina_Bool skip)7068 _efl_ui_win_prop_focus_skip_set(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, Eina_Bool skip)
7069 {
7070 sd->skip_focus = skip;
7071 TRAP(sd, focus_skip_set, skip);
7072 }
7073
7074 EOLIAN static void
_efl_ui_win_focus_highlight_enabled_set(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,Eina_Bool enabled)7075 _efl_ui_win_focus_highlight_enabled_set(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, Eina_Bool enabled)
7076 {
7077 enabled = !!enabled;
7078 if (sd->focus_highlight.enabled == enabled)
7079 return;
7080
7081 sd->focus_highlight.enabled = enabled;
7082
7083 if ((sd->focus_highlight.enabled) || (sd->focus_highlight.auto_enabled))
7084 _elm_win_focus_highlight_init(sd);
7085 else
7086 _elm_win_focus_highlight_shutdown(sd);
7087 }
7088
7089 EOLIAN static Eina_Bool
_efl_ui_win_focus_highlight_enabled_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)7090 _efl_ui_win_focus_highlight_enabled_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
7091 {
7092 return sd->focus_highlight.enabled;
7093 }
7094
7095 static Eina_Error
_elm_win_theme_internal(Eo * obj,Efl_Ui_Win_Data * sd)7096 _elm_win_theme_internal(Eo *obj, Efl_Ui_Win_Data *sd)
7097 {
7098 Eina_Error int_ret = EFL_UI_THEME_APPLY_ERROR_GENERIC;
7099 Eina_Bool prev_alpha;
7100 const char *s;
7101
7102 int_ret = elm_widget_theme_object_set(obj, sd->legacy.edje, "win", "base",
7103 elm_widget_style_get(obj));
7104 if (int_ret == EFL_UI_THEME_APPLY_ERROR_GENERIC) return int_ret;
7105
7106 edje_object_mirrored_set(sd->legacy.edje, efl_ui_mirrored_get(obj));
7107 edje_object_scale_set(sd->legacy.edje,
7108 efl_gfx_entity_scale_get(obj) * elm_config_scale_get());
7109
7110 efl_event_callback_legacy_call(obj, EFL_UI_WIN_EVENT_THEME_CHANGED, NULL);
7111
7112 prev_alpha = sd->theme_alpha;
7113 s = edje_object_data_get(sd->legacy.edje, "alpha");
7114 sd->theme_alpha = (eina_streq(s, "1") || eina_streq(s, "true"));
7115 if (sd->theme_alpha != prev_alpha)
7116 _elm_win_apply_alpha(obj, sd);
7117
7118 return int_ret;
7119 }
7120
7121 EOLIAN static Eina_Error
_efl_ui_win_efl_ui_widget_theme_apply(Eo * obj,Efl_Ui_Win_Data * sd)7122 _efl_ui_win_efl_ui_widget_theme_apply(Eo *obj, Efl_Ui_Win_Data *sd)
7123 {
7124 Eina_Error int_ret = EFL_UI_THEME_APPLY_ERROR_GENERIC;
7125 int_ret = efl_ui_widget_theme_apply(efl_super(obj, MY_CLASS));
7126 if (int_ret == EFL_UI_THEME_APPLY_ERROR_GENERIC) return int_ret;
7127
7128 sd->focus_highlight.theme_changed = EINA_TRUE;
7129
7130 int_ret = _elm_win_theme_internal(obj, sd) & int_ret;
7131 if (int_ret == EFL_UI_THEME_APPLY_ERROR_GENERIC) return int_ret;
7132 _elm_win_focus_highlight_reconfigure_job_start(sd);
7133
7134 return int_ret;
7135 }
7136
7137 EOLIAN static Eina_Bool
_efl_ui_win_focus_highlight_style_set(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,const char * style)7138 _efl_ui_win_focus_highlight_style_set(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, const char *style)
7139 {
7140 if (!eina_stringshare_replace(&sd->focus_highlight.style, style))
7141 return EINA_TRUE;
7142
7143 sd->focus_highlight.theme_changed = EINA_TRUE;
7144 _elm_win_focus_highlight_reconfigure_job_start(sd);
7145 return EINA_TRUE;
7146 }
7147
7148 EOLIAN static const char*
_efl_ui_win_focus_highlight_style_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)7149 _efl_ui_win_focus_highlight_style_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
7150 {
7151 return sd->focus_highlight.style;
7152 }
7153
7154 EOLIAN static void
_efl_ui_win_focus_highlight_animate_set(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,Eina_Bool animate)7155 _efl_ui_win_focus_highlight_animate_set(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, Eina_Bool animate)
7156 {
7157 animate = !!animate;
7158 if (sd->focus_highlight.animate == animate)
7159 return;
7160
7161 sd->focus_highlight.animate = animate;
7162 sd->focus_highlight.theme_changed = EINA_TRUE;
7163 _elm_win_focus_highlight_reconfigure_job_start(sd);
7164 }
7165
7166 EOLIAN static Eina_Bool
_efl_ui_win_focus_highlight_animate_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)7167 _efl_ui_win_focus_highlight_animate_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
7168 {
7169 return sd->focus_highlight.animate;
7170 }
7171
7172 EOLIAN static const char *
_efl_ui_win_stack_id_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)7173 _efl_ui_win_stack_id_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
7174 {
7175 return sd->stack_id;
7176 }
7177
7178 EOLIAN static void
_efl_ui_win_stack_master_id_set(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,const char * id)7179 _efl_ui_win_stack_master_id_set(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, const char *id)
7180 {
7181 if (sd->shown) return;
7182 eina_stringshare_replace(&(sd->stack_master_id), id);
7183 #ifdef HAVE_ELEMENTARY_X
7184 if (sd->x.xwin)
7185 _elm_win_xwin_update(sd);
7186 else
7187 #endif
7188 {
7189 int num = ecore_evas_aux_hint_id_get(sd->ee, "stack_master_id");
7190 if (num >= 0)
7191 ecore_evas_aux_hint_val_set(sd->ee, num, id);
7192 else
7193 ecore_evas_aux_hint_add(sd->ee, "stack_master_id", id);
7194 }
7195 }
7196
7197 EOLIAN static const char *
_efl_ui_win_stack_master_id_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)7198 _efl_ui_win_stack_master_id_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
7199 {
7200 return sd->stack_master_id;
7201 }
7202
7203 EOLIAN static void
_efl_ui_win_stack_base_set(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,Eina_Bool base)7204 _efl_ui_win_stack_base_set(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, Eina_Bool base)
7205 {
7206 int num;
7207 if (sd->shown) return;
7208 sd->stack_base = !!base;
7209 num = ecore_evas_aux_hint_id_get(sd->ee, "stack_base");
7210 if (num >= 0)
7211 ecore_evas_aux_hint_val_set(sd->ee, num, sd->stack_base ? "1" : "0");
7212 else
7213 ecore_evas_aux_hint_add(sd->ee, "stack_base", sd->stack_base ? "1" : "0");
7214 }
7215
7216 EOLIAN static Eina_Bool
_efl_ui_win_stack_base_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)7217 _efl_ui_win_stack_base_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
7218 {
7219 return sd->stack_base;
7220 }
7221
7222 #ifdef HAVE_ELEMENTARY_X
7223 // list transient from bottom to top by recursive walking
7224 static void
_x_transients_for_list(Ecore_X_Window base,Ecore_X_Window transient,Ecore_X_Window ** wins,int * num)7225 _x_transients_for_list(Ecore_X_Window base, Ecore_X_Window transient,
7226 Ecore_X_Window **wins, int *num)
7227 {
7228 Ecore_X_Window t, *children, *w;
7229 int n, i;
7230
7231 children = ecore_x_window_children_get(base, &n);
7232 if (children)
7233 {
7234 for (i = 0; i < n; i++)
7235 {
7236 if (children[i] != transient)
7237 {
7238 t = ecore_x_icccm_transient_for_get(children[i]);
7239 if (t == transient)
7240 {
7241 (*num)++;
7242 w = realloc(*wins, *num * sizeof(Ecore_X_Window));
7243 if (w)
7244 {
7245 *wins = w;
7246 (*wins)[*num - 1] = children[i];
7247 }
7248 }
7249 _x_transients_for_list(children[i], transient, wins, num);
7250 }
7251 }
7252 free(children);
7253 }
7254 }
7255 #endif
7256
7257 EOLIAN static void
_efl_ui_win_stack_pop_to(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd)7258 _efl_ui_win_stack_pop_to(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
7259 {
7260 if (!sd->stack_master_id) return;
7261 #ifdef HAVE_ELEMENTARY_X
7262 if (sd->x.xwin)
7263 {
7264 Ecore_X_Window *wins = NULL;
7265 int i, num = 0;
7266 Eina_Bool del = EINA_FALSE;
7267
7268 _internal_elm_win_xwindow_get(sd);
7269 ecore_x_grab();
7270 _x_transients_for_list
7271 (ecore_x_window_root_get(sd->x.xwin),
7272 ecore_x_icccm_transient_for_get(sd->x.xwin),
7273 &wins, &num);
7274 if (wins)
7275 {
7276 for (i = 0; i < num; i++)
7277 {
7278 if (del) ecore_x_window_delete_request_send(wins[i]);
7279 if (wins[i] == sd->x.xwin) del = EINA_TRUE;
7280 }
7281 free(wins);
7282 }
7283 ecore_x_ungrab();
7284 }
7285 else
7286 #endif
7287 {
7288 int num = ecore_evas_aux_hint_id_get(sd->ee, "stack_pop_to");
7289 if (num >= 0) ecore_evas_aux_hint_val_set(sd->ee, num, "1");
7290 else ecore_evas_aux_hint_add(sd->ee, "stack_pop_to", "1");
7291 }
7292 // win32/osx ?
7293 }
7294
7295 EAPI Eina_Bool
elm_win_trap_set(const Elm_Win_Trap * t)7296 elm_win_trap_set(const Elm_Win_Trap *t)
7297 {
7298 DBG("old %p, new %p", trap, t);
7299
7300 if ((t) && (t->version != ELM_WIN_TRAP_VERSION))
7301 {
7302 CRI("trying to set a trap version %lu while %lu was expected!",
7303 t->version, ELM_WIN_TRAP_VERSION);
7304 return EINA_FALSE;
7305 }
7306
7307 trap = t;
7308 return EINA_TRUE;
7309 }
7310
7311 EAPI void
elm_win_floating_mode_set(Evas_Object * obj,Eina_Bool floating)7312 elm_win_floating_mode_set(Evas_Object *obj, Eina_Bool floating)
7313 {
7314 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
7315 if (!sd) return;
7316
7317 floating = !!floating;
7318 if (floating == sd->floating) return;
7319 sd->floating = floating;
7320 #ifdef HAVE_ELEMENTARY_X
7321 _internal_elm_win_xwindow_get(sd);
7322 if (sd->x.xwin)
7323 {
7324 _internal_elm_win_xwindow_get(sd);
7325 if (sd->floating)
7326 ecore_x_e_illume_window_state_set
7327 (sd->x.xwin, ECORE_X_ILLUME_WINDOW_STATE_FLOATING);
7328 else
7329 ecore_x_e_illume_window_state_set
7330 (sd->x.xwin, ECORE_X_ILLUME_WINDOW_STATE_NORMAL);
7331 }
7332 #endif
7333 }
7334
7335 EAPI Eina_Bool
elm_win_floating_mode_get(const Evas_Object * obj)7336 elm_win_floating_mode_get(const Evas_Object *obj)
7337 {
7338 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
7339 if (!sd) return EINA_FALSE;
7340
7341 return sd->floating;
7342 }
7343
7344 void
_elm_win_focus_highlight_in_theme_update(Evas_Object * obj,Eina_Bool in_theme)7345 _elm_win_focus_highlight_in_theme_update(Evas_Object *obj, Eina_Bool in_theme)
7346 {
7347 ELM_WIN_DATA_GET(obj, sd);
7348 sd->focus_highlight.cur.in_theme = !!in_theme;
7349 }
7350
7351 void
_elm_win_focus_highlight_start(Evas_Object * obj)7352 _elm_win_focus_highlight_start(Evas_Object *obj)
7353 {
7354 ELM_WIN_DATA_GET(obj, sd);
7355
7356 if (!(sd->focus_highlight.enabled) && !(sd->focus_highlight.auto_enabled)) return;
7357 sd->focus_highlight.cur.visible = EINA_TRUE;
7358 sd->focus_highlight.geometry_changed = EINA_TRUE;
7359 _elm_win_focus_highlight_reconfigure_job(obj);
7360 }
7361
7362 void
_elm_win_focus_auto_show(Evas_Object * obj)7363 _elm_win_focus_auto_show(Evas_Object *obj)
7364 {
7365 ELM_WIN_DATA_GET(obj, sd);
7366 Eina_Bool pfocus = (sd->focus_highlight.enabled) || (sd->focus_highlight.auto_enabled);
7367 sd->focus_highlight.auto_enabled = _elm_config->win_auto_focus_enable;
7368 sd->focus_highlight.auto_animate = _elm_config->win_auto_focus_animate;
7369 if (pfocus != ((sd->focus_highlight.enabled) || (sd->focus_highlight.auto_enabled)))
7370 {
7371 if ((sd->focus_highlight.enabled) || (sd->focus_highlight.auto_enabled))
7372 _elm_win_focus_highlight_init(sd);
7373 }
7374 }
7375
7376 void
_elm_win_focus_auto_hide(Evas_Object * obj)7377 _elm_win_focus_auto_hide(Evas_Object *obj)
7378 {
7379 ELM_WIN_DATA_GET(obj, sd);
7380 Eina_Bool pfocus = (sd->focus_highlight.enabled) || (sd->focus_highlight.auto_enabled);
7381 sd->focus_highlight.auto_enabled = EINA_FALSE;
7382 sd->focus_highlight.auto_animate = EINA_FALSE;
7383 if (pfocus != ((sd->focus_highlight.enabled) || (sd->focus_highlight.auto_enabled)))
7384 {
7385 if (!((sd->focus_highlight.enabled) || (sd->focus_highlight.auto_enabled)))
7386 _elm_win_focus_highlight_shutdown(sd);
7387 }
7388 }
7389
7390 static void
_on_atspi_bus_connected(void * data EINA_UNUSED,const Efl_Event * event EINA_UNUSED)7391 _on_atspi_bus_connected(void *data EINA_UNUSED, const Efl_Event *event EINA_UNUSED)
7392 {
7393 Evas_Object *win;
7394 Eina_List *l;
7395
7396 EINA_LIST_FOREACH(_elm_win_list, l, win)
7397 {
7398 /**
7399 * Reemit accessibility events when AT-SPI2 connection is begin
7400 * established. This assures that Assistive Technology clients will
7401 * receive all org.a11y.window events and could keep track of active
7402 * windows whithin system.
7403 */
7404 efl_access_window_created_signal_emit(win);
7405 if (elm_win_focus_get(win))
7406 {
7407 Evas_Object *target;
7408 efl_access_window_activated_signal_emit(win);
7409 /** Reemit focused event to inform atspi clients about currently
7410 * focused object **/
7411 {
7412 Efl_Ui_Focus_Manager *m;
7413
7414 m = win;
7415
7416 while (efl_ui_focus_manager_redirect_get(m))
7417 m = efl_ui_focus_manager_redirect_get(m);
7418
7419 target = efl_ui_focus_manager_focus_get(m);
7420 }
7421 if (target)
7422 efl_access_state_changed_signal_emit(target, EFL_ACCESS_STATE_TYPE_FOCUSED, EINA_TRUE);
7423 }
7424 else
7425 efl_access_window_deactivated_signal_emit(win);
7426 }
7427 }
7428
7429 EOLIAN static void
_efl_ui_win_class_constructor(Efl_Class * klass EINA_UNUSED)7430 _efl_ui_win_class_constructor(Efl_Class *klass EINA_UNUSED)
7431 {
7432 if (_elm_config->atspi_mode)
7433 {
7434 Eo *bridge = _elm_atspi_bridge_get();
7435 if (bridge)
7436 efl_event_callback_add(bridge, ELM_ATSPI_BRIDGE_EVENT_CONNECTED, _on_atspi_bus_connected, NULL);
7437 }
7438 }
7439
7440 EOLIAN static void
_efl_ui_win_efl_object_debug_name_override(Eo * obj,Efl_Ui_Win_Data * pd,Eina_Strbuf * sb)7441 _efl_ui_win_efl_object_debug_name_override(Eo *obj, Efl_Ui_Win_Data *pd, Eina_Strbuf *sb)
7442 {
7443 efl_debug_name_override(efl_super(obj, MY_CLASS), sb);
7444 eina_strbuf_append_printf(sb, ":'%s':'%s'", pd->name, pd->title);
7445 }
7446
7447 EOLIAN static const Efl_Access_Action_Data*
_efl_ui_win_efl_access_widget_action_elm_actions_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd EINA_UNUSED)7448 _efl_ui_win_efl_access_widget_action_elm_actions_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd EINA_UNUSED)
7449 {
7450 static Efl_Access_Action_Data atspi_actions[] = {
7451 { "move,previous", "move", "previous", _key_action_move},
7452 { "move,next", "move", "next", _key_action_move},
7453 { "move,left", "move", "left", _key_action_move},
7454 { "move,right", "move", "right", _key_action_move},
7455 { "move,up", "move", "up", _key_action_move},
7456 { "move,down", "move", "down", _key_action_move},
7457 { NULL, NULL, NULL, NULL }
7458 };
7459 return &atspi_actions[0];
7460 }
7461
7462 EOLIAN static Efl_Access_State_Set
_efl_ui_win_efl_access_object_state_set_get(const Eo * obj,Efl_Ui_Win_Data * sd EINA_UNUSED)7463 _efl_ui_win_efl_access_object_state_set_get(const Eo *obj, Efl_Ui_Win_Data *sd EINA_UNUSED)
7464 {
7465 Efl_Access_State_Set ret;
7466 ret = efl_access_object_state_set_get(efl_super(obj, MY_CLASS));
7467
7468 if (elm_win_focus_get(obj))
7469 STATE_TYPE_SET(ret, EFL_ACCESS_STATE_TYPE_ACTIVE);
7470
7471 return ret;
7472 }
7473
7474 EOLIAN static const char*
_efl_ui_win_efl_access_object_i18n_name_get(const Eo * obj,Efl_Ui_Win_Data * sd EINA_UNUSED)7475 _efl_ui_win_efl_access_object_i18n_name_get(const Eo *obj, Efl_Ui_Win_Data *sd EINA_UNUSED)
7476 {
7477 const char *ret;
7478 ret = efl_access_object_i18n_name_get(efl_super(obj, EFL_UI_WIN_CLASS));
7479 if (ret) return ret;
7480 const char *name = elm_win_title_get(obj);
7481 return name;
7482 }
7483
7484 EOLIAN static Eina_Rect
_efl_ui_win_efl_access_component_extents_get(const Eo * obj,Efl_Ui_Win_Data * _pd EINA_UNUSED,Eina_Bool screen_coords)7485 _efl_ui_win_efl_access_component_extents_get(const Eo *obj, Efl_Ui_Win_Data *_pd EINA_UNUSED, Eina_Bool screen_coords)
7486 {
7487 Eina_Rect r;
7488 int ee_x, ee_y;
7489
7490 r = efl_gfx_entity_geometry_get(obj);
7491 r.x = r.y = 0;
7492 if (screen_coords)
7493 {
7494 Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
7495 if (ee)
7496 {
7497 ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL);
7498 r.x += ee_x;
7499 r.y += ee_y;
7500 }
7501 }
7502 return r;
7503 }
7504
7505 EOLIAN static Eina_Bool
_efl_ui_win_efl_input_state_modifier_enabled_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * pd,Efl_Input_Modifier mod,const Efl_Input_Device * seat)7506 _efl_ui_win_efl_input_state_modifier_enabled_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *pd,
7507 Efl_Input_Modifier mod, const Efl_Input_Device *seat)
7508 {
7509 const Evas_Modifier *m = evas_key_modifier_get(pd->evas);
7510 const char *name = _efl_input_modifier_to_string(mod);
7511 return evas_seat_key_modifier_is_set(m, name, seat);
7512 }
7513
7514 EOLIAN static Eina_Bool
_efl_ui_win_efl_input_state_lock_enabled_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * pd,Efl_Input_Lock lock,const Efl_Input_Device * seat)7515 _efl_ui_win_efl_input_state_lock_enabled_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *pd,
7516 Efl_Input_Lock lock, const Efl_Input_Device *seat)
7517 {
7518 const Evas_Lock *m = evas_key_lock_get(pd->evas);
7519 const char *name = _efl_input_lock_to_string(lock);
7520 return evas_seat_key_lock_is_set(m, name, seat);
7521 }
7522
7523 EOLIAN static Efl_Object *
_efl_ui_win_efl_object_provider_find(const Eo * obj,Efl_Ui_Win_Data * pd EINA_UNUSED,const Efl_Object * klass)7524 _efl_ui_win_efl_object_provider_find(const Eo *obj,
7525 Efl_Ui_Win_Data *pd EINA_UNUSED,
7526 const Efl_Object *klass)
7527 {
7528 if (klass == EFL_UI_WIN_CLASS)
7529 return (Eo *)obj;
7530
7531 // attach all kinds of windows directly to ATSPI application root object
7532 if (klass == EFL_ACCESS_OBJECT_MIXIN) return efl_access_object_access_root_get();
7533
7534 if (klass == EFL_UI_FOCUS_PARENT_PROVIDER_INTERFACE)
7535 return pd->provider;
7536
7537 return efl_provider_find(efl_super(obj, MY_CLASS), klass);
7538 }
7539
7540 // See evas_inline.x
7541 #define _EVAS_COLOR_CLAMP(x, y) do { \
7542 if (x > y) { x = y; bad = 1; } \
7543 if (x < 0) { x = 0; bad = 1; } } while (0)
7544
7545 #define EVAS_COLOR_SANITIZE(r, g, b, a) \
7546 ({ int bad = 0; \
7547 _EVAS_COLOR_CLAMP(a, 255); \
7548 _EVAS_COLOR_CLAMP(r, a); \
7549 _EVAS_COLOR_CLAMP(g, a); \
7550 _EVAS_COLOR_CLAMP(b, a); \
7551 bad; })
7552
7553 /* Efl.Part APIs */
7554
7555 #define WIN_PART_ERR(part) ERR("No such part in window: '%s'. Supported parts are: 'content' and 'background'.", part);
7556
7557 static Eina_Bool
_elm_win_bg_set(Efl_Ui_Win_Data * sd,Eo * bg)7558 _elm_win_bg_set(Efl_Ui_Win_Data *sd, Eo *bg)
7559 {
7560 ELM_SAFE_DEL(sd->bg);
7561 if (!bg) return EINA_TRUE;
7562
7563 if (!elm_widget_sub_object_add(sd->obj, bg))
7564 return EINA_FALSE;
7565 if (elm_widget_is_legacy(sd->obj))
7566 {
7567 if (!_elm_config->win_no_border)
7568 {
7569 if (!edje_object_part_swallow(sd->frame_obj, "elm.swallow.background", bg))
7570 return EINA_FALSE;
7571 }
7572 else
7573 {
7574 if (!edje_object_part_swallow(sd->legacy.edje, "elm.swallow.background", bg))
7575 return EINA_FALSE;
7576 }
7577 }
7578 else
7579 {
7580 if (!_elm_config->win_no_border)
7581 {
7582 if (!edje_object_part_swallow(sd->frame_obj, "efl.background", bg))
7583 return EINA_FALSE;
7584 }
7585 else
7586 {
7587 if (!edje_object_part_swallow(sd->legacy.edje, "efl.background", bg))
7588 return EINA_FALSE;
7589 }
7590 }
7591 efl_gfx_entity_visible_set(bg, 1);
7592 efl_gfx_hint_fill_set(bg, EINA_TRUE, EINA_TRUE);
7593 efl_gfx_hint_weight_set(bg, 1, 1);
7594 efl_wref_add(bg, &sd->bg);
7595 return EINA_TRUE;
7596 }
7597
7598 /* Legacy theme compatibility */
7599 static Eina_Bool
_elm_win_bg_must_swallow(Efl_Ui_Win_Data * sd,Eo ** bg)7600 _elm_win_bg_must_swallow(Efl_Ui_Win_Data *sd, Eo **bg)
7601 {
7602 if (EINA_UNLIKELY(!sd->legacy.bg_must_swallow_init))
7603 {
7604 /* Overkill: check which theme version the standard elm_bg uses */
7605 Elm_Widget_Smart_Data *wd;
7606 const char *version;
7607 int v;
7608
7609 sd->legacy.bg_must_swallow = 1;
7610 sd->legacy.bg_must_swallow_init = 1;
7611
7612 if (sd->legacy.ctor)
7613 *bg = elm_bg_add(sd->obj);
7614 else
7615 {
7616 // Note: This code path is probably not necessary (custom legacy
7617 // theme but efl_add'ed window -- all efl_add'ed widgets would
7618 // use default theme)
7619 *bg = efl_add(EFL_UI_BG_CLASS, sd->obj);
7620 }
7621 wd = efl_data_scope_get(*bg, EFL_UI_WIDGET_CLASS);
7622 if (wd)
7623 {
7624 version = edje_object_data_get(wd->resize_obj, "version");
7625 v = version ? atoi(version) : 0;
7626 if (v >= FRAME_OBJ_THEME_MIN_VERSION)
7627 sd->legacy.bg_must_swallow = 0;
7628 }
7629 }
7630
7631 return sd->legacy.bg_must_swallow;
7632 }
7633
7634 void
_elm_win_standard_init(Eo * obj)7635 _elm_win_standard_init(Eo *obj)
7636 {
7637 /* Support for elm_util_win_standard_add() and Efl.Ui.Win.Standard */
7638 Efl_Ui_Win_Data *sd = efl_data_scope_get(obj, MY_CLASS);
7639 Eo *bg = NULL;
7640
7641 ELM_SAFE_DEL(sd->bg);
7642
7643 sd->csd.need_bg_standard = 1;
7644 if (!_elm_win_bg_must_swallow(sd, &bg))
7645 {
7646 sd->csd.need_bg_solid = EINA_TRUE;
7647 evas_object_del(bg);
7648 }
7649 else
7650 {
7651 /* Legacy theme compatibility */
7652 DBG("Detected legacy theme used for elm_bg. Swallowing object.");
7653 sd->csd.need_bg_solid = EINA_FALSE;
7654
7655 if (!bg)
7656 {
7657 if (sd->legacy.ctor)
7658 bg = elm_bg_add(obj);
7659 else
7660 {
7661 // Note: This code path is probably not necessary (custom legacy
7662 // theme but efl_add'ed window -- all efl_add'ed widgets would
7663 // use default theme)
7664 bg = efl_add(EFL_UI_BG_CLASS, obj);
7665 }
7666 }
7667 _elm_win_bg_set(sd, bg);
7668 }
7669
7670 _elm_win_frame_style_update(sd, 0, 1);
7671 }
7672
7673 static Eina_Bool
_efl_ui_win_content_set(Eo * obj,Efl_Ui_Win_Data * sd,const char * part,Eo * content)7674 _efl_ui_win_content_set(Eo *obj, Efl_Ui_Win_Data *sd, const char *part, Eo *content)
7675 {
7676 sd->legacy.forbidden = EINA_TRUE;
7677 if (eina_streq(part, "content"))
7678 {
7679 if (sd->content == content) return EINA_TRUE;
7680 if (content && !elm_widget_sub_object_add(obj, content))
7681 goto err;
7682 /* FIXME: Switch to swallow inside the frame
7683 if (!edje_object_part_swallow(sd->frame_obj, "elm.swallow.client", content))
7684 goto err;
7685 */
7686 evas_object_box_append(sd->legacy.box, content);
7687 evas_object_show(content);
7688 efl_wref_add(content, &sd->content);
7689 return EINA_TRUE;
7690 }
7691 else if (eina_streq(part, "background"))
7692 {
7693 sd->csd.need_bg_standard = 0;
7694 if (sd->bg == content) return EINA_TRUE;
7695 if (!_elm_win_bg_set(sd, content))
7696 goto err;
7697 return EINA_TRUE;
7698 }
7699
7700 WIN_PART_ERR(part);
7701 return EINA_FALSE;
7702
7703 err:
7704 ERR("Failed to set object %p as %s for window %p", content, part, obj);
7705 return EINA_FALSE;
7706 }
7707
7708 static Efl_Canvas_Object *
_efl_ui_win_content_get(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,const char * part)7709 _efl_ui_win_content_get(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, const char *part)
7710 {
7711 sd->legacy.forbidden = EINA_TRUE;
7712 if (eina_streq(part, "content"))
7713 return sd->content;
7714 else if (eina_streq(part, "background"))
7715 return sd->bg;
7716
7717 WIN_PART_ERR(part);
7718 return NULL;
7719 }
7720
7721 static Efl_Canvas_Object *
_efl_ui_win_content_unset(Eo * obj,Efl_Ui_Win_Data * sd,const char * part)7722 _efl_ui_win_content_unset(Eo *obj, Efl_Ui_Win_Data *sd, const char *part)
7723 {
7724 Eo *content;
7725
7726 sd->legacy.forbidden = EINA_TRUE;
7727 content = _efl_ui_win_content_get(obj, sd, part);
7728 if (!content) return NULL;
7729
7730 efl_ref(content);
7731 _efl_ui_win_content_set(obj, sd, part, NULL);
7732 return content;
7733 }
7734
7735 static Eina_Bool
_efl_ui_win_part_color_set(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,const char * part,int r,int g,int b,int a)7736 _efl_ui_win_part_color_set(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, const char *part, int r, int g, int b, int a)
7737 {
7738 sd->legacy.forbidden = EINA_TRUE;
7739 if (eina_streq(part, "background"))
7740 {
7741 sd->csd.need_bg_solid = EINA_TRUE;
7742 edje_object_color_class_set(sd->frame_obj, "elm/win/background", r, g, b, a, 0, 0, 0, 0, 0, 0, 0, 0);
7743 _elm_win_frame_style_update(sd, 0, 1);
7744 return EINA_TRUE;
7745 }
7746
7747 WIN_PART_ERR(part);
7748 return EINA_FALSE;
7749 }
7750
7751 static Eina_Bool
_efl_ui_win_part_color_get(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,const char * part,int * r,int * g,int * b,int * a)7752 _efl_ui_win_part_color_get(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, const char *part, int *r, int *g, int *b, int *a)
7753 {
7754 sd->legacy.forbidden = EINA_TRUE;
7755 if (eina_streq(part, "background"))
7756 {
7757 edje_object_color_class_get(sd->frame_obj, "elm/win/background", r, g, b, a, 0, 0, 0, 0, 0, 0, 0, 0);
7758 return EINA_TRUE;
7759 }
7760
7761 WIN_PART_ERR(part);
7762 return EINA_FALSE;
7763 }
7764
7765 static void
_efl_ui_win_part_file_unload(Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,Eo * part_obj EINA_UNUSED,const char * part)7766 _efl_ui_win_part_file_unload(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, Eo *part_obj EINA_UNUSED, const char *part)
7767 {
7768 sd->legacy.forbidden = EINA_TRUE;
7769 if (eina_streq(part, "background"))
7770 {
7771 _elm_win_bg_set(sd, NULL);
7772 return;
7773 }
7774
7775 WIN_PART_ERR(part);
7776 }
7777
7778 static Eina_Error
_efl_ui_win_part_file_load(Eo * obj,Efl_Ui_Win_Data * sd,Eo * part_obj,const char * part)7779 _efl_ui_win_part_file_load(Eo *obj, Efl_Ui_Win_Data *sd, Eo *part_obj, const char *part)
7780 {
7781 const char *file, *key;
7782
7783 sd->legacy.forbidden = EINA_TRUE;
7784 if (efl_file_loaded_get(part_obj)) return 0;
7785 file = efl_file_get(part_obj);
7786 key = efl_file_key_get(part_obj);
7787 if (eina_streq(part, "background"))
7788 {
7789 Eina_Bool ok = EINA_TRUE;
7790 Eo *bg = NULL;
7791
7792 if (file)
7793 {
7794 bg = efl_add(EFL_UI_IMAGE_CLASS, obj);
7795 efl_gfx_image_scale_method_set(bg, EFL_GFX_IMAGE_SCALE_METHOD_EXPAND);
7796 ok = efl_file_simple_load(bg, file, key);
7797 if (!ok) ELM_SAFE_DEL(bg);
7798 _elm_win_bg_set(sd, bg);
7799 }
7800 else
7801 {
7802 _elm_win_standard_init(obj);
7803 }
7804
7805 return ok;
7806 }
7807
7808 WIN_PART_ERR(part);
7809 return EINA_FALSE;
7810 }
7811
7812 static const char *
_efl_ui_win_part_file_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,const Eo * part_obj,const char * part EINA_UNUSED)7813 _efl_ui_win_part_file_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, const Eo *part_obj, const char *part EINA_UNUSED)
7814 {
7815 sd->legacy.forbidden = EINA_TRUE;
7816 return efl_file_get(efl_super(part_obj, EFL_UI_WIN_PART_CLASS));
7817 #if 0
7818
7819 if (eina_streq(part, "background"))
7820 {
7821 const Eo *bg = _efl_ui_win_content_get(obj, sd, "background");
7822 return efl_file_get(bg);
7823 }
7824
7825 WIN_PART_ERR(part);
7826 return NULL;
7827 #endif
7828 }
7829
7830 static const char *
_efl_ui_win_part_file_key_get(const Eo * obj EINA_UNUSED,Efl_Ui_Win_Data * sd,const Eo * part_obj,const char * part EINA_UNUSED)7831 _efl_ui_win_part_file_key_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, const Eo *part_obj, const char *part EINA_UNUSED)
7832 {
7833 sd->legacy.forbidden = EINA_TRUE;
7834 return efl_file_key_get(efl_super(part_obj, EFL_UI_WIN_PART_CLASS));
7835 /* NOTE; if more than one part is ever supported here then this section is needed */
7836 #if 0
7837
7838 if (eina_streq(part, "background"))
7839 {
7840 const Eo *bg = _efl_ui_win_content_get(obj, sd, "background");
7841 return efl_file_get(bg);
7842 }
7843
7844 WIN_PART_ERR(part);
7845 return NULL;
7846 #endif
7847 }
7848
7849 /* Efl.Part begin */
7850
7851 static void
_efl_ui_win_part_efl_gfx_color_color_set(Eo * obj,void * _pd EINA_UNUSED,int r,int g,int b,int a)7852 _efl_ui_win_part_efl_gfx_color_color_set(Eo *obj, void *_pd EINA_UNUSED, int r, int g, int b, int a)
7853 {
7854 Elm_Part_Data *pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
7855 Efl_Ui_Win_Data *sd = efl_data_scope_get(pd->obj, MY_CLASS);
7856
7857 if (EVAS_COLOR_SANITIZE(r, g, b, a))
7858 ERR("Evas only handles premultiplied colors (0 <= R,G,B <= A <= 255)");
7859
7860 _efl_ui_win_part_color_set(pd->obj, sd, pd->part, r, g, b, a);
7861 }
7862
7863 static void
_efl_ui_win_part_efl_gfx_color_color_get(const Eo * obj,void * _pd EINA_UNUSED,int * r,int * g,int * b,int * a)7864 _efl_ui_win_part_efl_gfx_color_color_get(const Eo *obj, void *_pd EINA_UNUSED, int *r, int *g, int *b, int *a)
7865 {
7866 Elm_Part_Data *pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
7867 Efl_Ui_Win_Data *sd = efl_data_scope_get(pd->obj, MY_CLASS);
7868 _efl_ui_win_part_color_get(pd->obj, sd, pd->part, r, g, b, a);
7869 }
7870
7871 EOLIAN static const char *
_efl_ui_win_part_efl_file_file_get(const Eo * obj,void * _pd EINA_UNUSED)7872 _efl_ui_win_part_efl_file_file_get(const Eo *obj, void *_pd EINA_UNUSED)
7873 {
7874 Elm_Part_Data *pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
7875 Efl_Ui_Win_Data *sd = efl_data_scope_get(pd->obj, MY_CLASS);
7876 return _efl_ui_win_part_file_get(pd->obj, sd, obj, pd->part);
7877 }
7878
7879 EOLIAN static const char *
_efl_ui_win_part_efl_file_key_get(const Eo * obj,void * _pd EINA_UNUSED)7880 _efl_ui_win_part_efl_file_key_get(const Eo *obj, void *_pd EINA_UNUSED)
7881 {
7882 Elm_Part_Data *pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
7883 Efl_Ui_Win_Data *sd = efl_data_scope_get(pd->obj, MY_CLASS);
7884 return _efl_ui_win_part_file_key_get(pd->obj, sd, obj, pd->part);
7885 }
7886
7887 EOLIAN static void
_efl_ui_win_part_efl_file_unload(Eo * obj,void * _pd EINA_UNUSED)7888 _efl_ui_win_part_efl_file_unload(Eo *obj, void *_pd EINA_UNUSED)
7889 {
7890 Elm_Part_Data *pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
7891 Efl_Ui_Win_Data *sd = efl_data_scope_get(pd->obj, MY_CLASS);
7892 return _efl_ui_win_part_file_unload(pd->obj, sd, obj, pd->part);
7893 }
7894
7895 EOLIAN static Eina_Error
_efl_ui_win_part_efl_file_load(Eo * obj,void * _pd EINA_UNUSED)7896 _efl_ui_win_part_efl_file_load(Eo *obj, void *_pd EINA_UNUSED)
7897 {
7898 Elm_Part_Data *pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
7899 Efl_Ui_Win_Data *sd = efl_data_scope_get(pd->obj, MY_CLASS);
7900 return _efl_ui_win_part_file_load(pd->obj, sd, obj, pd->part);
7901 }
7902
7903
ELM_PART_OVERRIDE(efl_ui_win,EFL_UI_WIN,Efl_Ui_Win_Data)7904 ELM_PART_OVERRIDE(efl_ui_win, EFL_UI_WIN, Efl_Ui_Win_Data)
7905 ELM_PART_OVERRIDE_CONTENT_SET(efl_ui_win, EFL_UI_WIN, Efl_Ui_Win_Data)
7906 ELM_PART_OVERRIDE_CONTENT_GET(efl_ui_win, EFL_UI_WIN, Efl_Ui_Win_Data)
7907 ELM_PART_OVERRIDE_CONTENT_UNSET(efl_ui_win, EFL_UI_WIN, Efl_Ui_Win_Data)
7908 ELM_PART_CONTENT_DEFAULT_GET(efl_ui_win, "content")
7909 ELM_PART_CONTENT_DEFAULT_IMPLEMENT(efl_ui_win, Efl_Ui_Win_Data)
7910 #include "efl_ui_win_part.eo.c"
7911
7912 /* Efl.Part end */
7913
7914 EOLIAN static Eina_Bool
7915 _efl_ui_win_move_resize_start(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, Efl_Ui_Win_Move_Resize_Mode mode)
7916 {
7917 // 1. move_resize can only be started after mouse down event
7918 if (evas_event_down_count_get(sd->evas) <= 0)
7919 {
7920 ERR("move_resize_start can only be called when a pointer is pressed.");
7921 return EINA_FALSE;
7922 }
7923 return _win_move_resize_start(sd, mode);
7924 }
7925
7926 EAPI Evas_Object *
elm_win_get(Evas_Object * obj)7927 elm_win_get(Evas_Object *obj)
7928 {
7929 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
7930 return ecore_evas_data_get(ecore_evas_ecore_evas_get(evas_object_evas_get(obj)), "elm_win");
7931 }
7932
7933 /* windowing specific calls - shall we do this differently? */
7934
7935 EAPI Ecore_X_Window
elm_win_xwindow_get(const Evas_Object * obj)7936 elm_win_xwindow_get(const Evas_Object *obj)
7937 {
7938 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
7939 if (!sd) return 0;
7940
7941 #ifdef HAVE_ELEMENTARY_X
7942 _internal_elm_win_xwindow_get(sd);
7943 if (sd->x.xwin) return sd->x.xwin;
7944 if (sd->parent) return elm_win_xwindow_get(sd->parent);
7945 #endif
7946 return 0;
7947 }
7948
7949 EAPI Ecore_Wl2_Window *
elm_win_wl_window_get(const Evas_Object * obj)7950 elm_win_wl_window_get(const Evas_Object *obj)
7951 {
7952 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
7953
7954 if (!sd) return NULL;
7955
7956 if (!evas_object_smart_type_check_ptr(obj, MY_CLASS_NAME_LEGACY))
7957 {
7958 Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
7959 return _elm_ee_wlwin_get(ee);
7960 }
7961
7962 #if HAVE_ELEMENTARY_WL2
7963 if (sd->wl.win) return sd->wl.win;
7964 if (sd->parent) return elm_win_wl_window_get(sd->parent);
7965 #endif
7966
7967 return NULL;
7968 }
7969
7970 EAPI Ecore_Cocoa_Window *
elm_win_cocoa_window_get(const Evas_Object * obj)7971 elm_win_cocoa_window_get(const Evas_Object *obj)
7972 {
7973 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
7974 if (!sd) return NULL;
7975
7976 #if HAVE_ELEMENTARY_COCOA
7977 if (sd->cocoa.win) return sd->cocoa.win;
7978 if (sd->ee) return _elm_ee_cocoa_win_get(sd->ee);
7979 if (sd->parent) return elm_win_cocoa_window_get(sd->parent);
7980 #endif
7981
7982 Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
7983 return _elm_ee_cocoa_win_get(ee);
7984
7985 return NULL;
7986 }
7987
7988 EAPI Ecore_Win32_Window *
elm_win_win32_window_get(const Evas_Object * obj)7989 elm_win_win32_window_get(const Evas_Object *obj)
7990 {
7991 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
7992 const char *engine_name;
7993
7994 if (!sd) return NULL;
7995 engine_name = ecore_evas_engine_name_get(sd->ee);
7996 if (!(engine_name &&
7997 ((!strcmp(engine_name, ELM_SOFTWARE_WIN32)) ||
7998 (!strcmp(engine_name, ELM_SOFTWARE_DDRAW)))))
7999 return NULL;
8000
8001 if (!evas_object_smart_type_check_ptr(obj, MY_CLASS_NAME_LEGACY))
8002 {
8003 Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
8004 return _elm_ee_win32win_get(ee);
8005 }
8006
8007 Ecore_Win32_Window *ret = NULL;
8008
8009 #if HAVE_ELEMENTARY_WIN32
8010 if (sd->win32.win) ret = sd->win32.win;
8011 if (sd->parent) ret = elm_win_win32_window_get(sd->parent);
8012 #endif
8013
8014 return ret;
8015 }
8016
8017 EAPI void *
elm_win_trap_data_get(const Evas_Object * obj)8018 elm_win_trap_data_get(const Evas_Object *obj)
8019 {
8020 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8021 if (!sd) return NULL;
8022
8023 return sd->trap_data;
8024 }
8025
8026 EAPI void
elm_win_override_set(Evas_Object * obj,Eina_Bool override)8027 elm_win_override_set(Evas_Object *obj, Eina_Bool override)
8028 {
8029 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8030 if (!sd) return;
8031
8032 TRAP(sd, override_set, override);
8033 #ifdef HAVE_ELEMENTARY_X
8034 _elm_win_xwin_update(sd);
8035 #endif
8036 }
8037
8038 EAPI Eina_Bool
elm_win_override_get(const Evas_Object * obj)8039 elm_win_override_get(const Evas_Object *obj)
8040 {
8041 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8042 if (!sd) return EINA_FALSE;
8043
8044 return ecore_evas_override_get(sd->ee);
8045 }
8046
8047 EAPI void
elm_win_lower(Evas_Object * obj)8048 elm_win_lower(Evas_Object *obj)
8049 {
8050 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8051 if (!sd) return;
8052
8053 TRAP(sd, lower);
8054 }
8055
8056 EAPI void
elm_win_quickpanel_set(Evas_Object * obj,Eina_Bool quickpanel)8057 elm_win_quickpanel_set(Evas_Object *obj, Eina_Bool quickpanel)
8058 {
8059 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8060 if (!sd) return;
8061
8062 #ifdef HAVE_ELEMENTARY_X
8063 _internal_elm_win_xwindow_get(sd);
8064 if (sd->x.xwin)
8065 {
8066 _internal_elm_win_xwindow_get(sd);
8067 ecore_x_e_illume_quickpanel_set(sd->x.xwin, quickpanel);
8068 if (quickpanel)
8069 {
8070 Ecore_X_Window_State states[2];
8071
8072 states[0] = ECORE_X_WINDOW_STATE_SKIP_TASKBAR;
8073 states[1] = ECORE_X_WINDOW_STATE_SKIP_PAGER;
8074 ecore_x_netwm_window_state_set(sd->x.xwin, states, 2);
8075 ecore_x_icccm_hints_set(sd->x.xwin, 0, 0, 0, 0, 0, 0, 0);
8076 }
8077 }
8078 #else
8079 (void)sd;
8080 (void)quickpanel;
8081 #endif
8082 }
8083
8084 EAPI Eina_Bool
elm_win_quickpanel_get(const Evas_Object * obj)8085 elm_win_quickpanel_get(const Evas_Object *obj)
8086 {
8087 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8088 if (!sd) return EINA_FALSE;
8089
8090 #ifdef HAVE_ELEMENTARY_X
8091 _internal_elm_win_xwindow_get(sd);
8092 if (sd->x.xwin)
8093 {
8094 _internal_elm_win_xwindow_get(sd);
8095 return ecore_x_e_illume_quickpanel_get(sd->x.xwin);
8096 }
8097 #else
8098 (void)sd;
8099 #endif
8100
8101 return EINA_FALSE;
8102 }
8103
8104 EAPI void
elm_win_quickpanel_priority_major_set(Evas_Object * obj,int priority)8105 elm_win_quickpanel_priority_major_set(Evas_Object *obj, int priority)
8106 {
8107 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8108 if (!sd) return;
8109
8110 #ifdef HAVE_ELEMENTARY_X
8111 _internal_elm_win_xwindow_get(sd);
8112 if (sd->x.xwin)
8113 {
8114 _internal_elm_win_xwindow_get(sd);
8115 ecore_x_e_illume_quickpanel_priority_major_set(sd->x.xwin, priority);
8116 }
8117 #else
8118 (void)sd;
8119 (void)priority;
8120 #endif
8121 }
8122
8123 EAPI int
elm_win_quickpanel_priority_major_get(const Evas_Object * obj)8124 elm_win_quickpanel_priority_major_get(const Evas_Object *obj)
8125 {
8126 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8127 if (!sd) return -1;
8128
8129 #ifdef HAVE_ELEMENTARY_X
8130 _internal_elm_win_xwindow_get(sd);
8131 if (sd->x.xwin)
8132 {
8133 _internal_elm_win_xwindow_get(sd);
8134 return ecore_x_e_illume_quickpanel_priority_major_get(sd->x.xwin);
8135 }
8136 #else
8137 (void)sd;
8138 #endif
8139
8140 return -1;
8141 }
8142
8143 EAPI void
elm_win_quickpanel_priority_minor_set(Evas_Object * obj,int priority)8144 elm_win_quickpanel_priority_minor_set(Evas_Object *obj, int priority)
8145 {
8146 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8147 if (!sd) return;
8148
8149 #ifdef HAVE_ELEMENTARY_X
8150 _internal_elm_win_xwindow_get(sd);
8151 if (sd->x.xwin)
8152 {
8153 _internal_elm_win_xwindow_get(sd);
8154 ecore_x_e_illume_quickpanel_priority_minor_set(sd->x.xwin, priority);
8155 }
8156 #else
8157 (void)sd;
8158 (void)priority;
8159 #endif
8160 }
8161
8162 EAPI int
elm_win_quickpanel_priority_minor_get(const Evas_Object * obj)8163 elm_win_quickpanel_priority_minor_get(const Evas_Object *obj)
8164 {
8165 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8166 if (!sd) return -1;
8167
8168 #ifdef HAVE_ELEMENTARY_X
8169 _internal_elm_win_xwindow_get(sd);
8170 if (sd->x.xwin)
8171 {
8172 _internal_elm_win_xwindow_get(sd);
8173 return ecore_x_e_illume_quickpanel_priority_minor_get(sd->x.xwin);
8174 }
8175 #else
8176 (void)sd;
8177 #endif
8178
8179 return -1;
8180 }
8181
8182 EAPI void
elm_win_quickpanel_zone_set(Evas_Object * obj,int zone)8183 elm_win_quickpanel_zone_set(Evas_Object *obj, int zone)
8184 {
8185 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8186 if (!sd) return;
8187
8188 #ifdef HAVE_ELEMENTARY_X
8189 _internal_elm_win_xwindow_get(sd);
8190 if (sd->x.xwin)
8191 {
8192 _internal_elm_win_xwindow_get(sd);
8193 ecore_x_e_illume_quickpanel_zone_set(sd->x.xwin, zone);
8194 }
8195 #else
8196 (void)sd;
8197 (void)zone;
8198 #endif
8199 }
8200
8201 EAPI int
elm_win_quickpanel_zone_get(const Evas_Object * obj)8202 elm_win_quickpanel_zone_get(const Evas_Object *obj)
8203 {
8204 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8205 if (!sd) return 0;
8206
8207 #ifdef HAVE_ELEMENTARY_X
8208 _internal_elm_win_xwindow_get(sd);
8209 if (sd->x.xwin)
8210 {
8211 _internal_elm_win_xwindow_get(sd);
8212 return ecore_x_e_illume_quickpanel_zone_get(sd->x.xwin);
8213 }
8214 #else
8215 (void)sd;
8216 #endif
8217
8218 return 0;
8219 }
8220
8221 EAPI void
elm_win_indicator_mode_set(Evas_Object * obj,Elm_Win_Indicator_Mode mode)8222 elm_win_indicator_mode_set(Evas_Object *obj, Elm_Win_Indicator_Mode mode)
8223 {
8224 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8225 if (!sd) return;
8226 if (sd->legacy.forbidden)
8227 {
8228 CRI("Use of this API is forbidden after calling an EO API on this "
8229 "window. Fix your code!");
8230 return;
8231 }
8232
8233 if (mode == sd->legacy.indmode) return;
8234 #ifdef HAVE_ELEMENTARY_X
8235 _internal_elm_win_xwindow_get(sd);
8236 #endif
8237 sd->legacy.indmode = mode;
8238 #ifdef HAVE_ELEMENTARY_X
8239 if (sd->x.xwin)
8240 {
8241 _internal_elm_win_xwindow_get(sd);
8242 if (sd->legacy.indmode == ELM_WIN_INDICATOR_SHOW)
8243 ecore_x_e_illume_indicator_state_set
8244 (sd->x.xwin, ECORE_X_ILLUME_INDICATOR_STATE_ON);
8245 else if (sd->legacy.indmode == ELM_WIN_INDICATOR_HIDE)
8246 ecore_x_e_illume_indicator_state_set
8247 (sd->x.xwin, ECORE_X_ILLUME_INDICATOR_STATE_OFF);
8248 }
8249 #endif
8250 efl_event_callback_legacy_call
8251 (obj, EFL_UI_WIN_EVENT_INDICATOR_PROP_CHANGED, NULL);
8252 }
8253
8254 EAPI Elm_Win_Indicator_Mode
elm_win_indicator_mode_get(const Evas_Object * obj)8255 elm_win_indicator_mode_get(const Evas_Object *obj)
8256 {
8257 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8258 if (!sd) return ELM_WIN_INDICATOR_UNKNOWN;
8259 if (sd->legacy.forbidden)
8260 {
8261 CRI("Use of this API is forbidden after calling an EO API on this "
8262 "window. Fix your code!");
8263 return ELM_WIN_INDICATOR_UNKNOWN;
8264 }
8265
8266 return sd->legacy.indmode;
8267 }
8268
8269 EAPI void
elm_win_indicator_opacity_set(Evas_Object * obj,Elm_Win_Indicator_Opacity_Mode mode)8270 elm_win_indicator_opacity_set(Evas_Object *obj, Elm_Win_Indicator_Opacity_Mode mode)
8271 {
8272 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8273 if (!sd) return;
8274 if (sd->legacy.forbidden)
8275 {
8276 CRI("Use of this API is forbidden after calling an EO API on this "
8277 "window. Fix your code!");
8278 return;
8279 }
8280
8281 if (mode == sd->legacy.ind_o_mode) return;
8282 sd->legacy.ind_o_mode = mode;
8283 #ifdef HAVE_ELEMENTARY_X
8284 _internal_elm_win_xwindow_get(sd);
8285 if (sd->x.xwin)
8286 {
8287 _internal_elm_win_xwindow_get(sd);
8288 if (sd->legacy.ind_o_mode == ELM_WIN_INDICATOR_OPAQUE)
8289 ecore_x_e_illume_indicator_opacity_set
8290 (sd->x.xwin, ECORE_X_ILLUME_INDICATOR_OPAQUE);
8291 else if (sd->legacy.ind_o_mode == ELM_WIN_INDICATOR_TRANSLUCENT)
8292 ecore_x_e_illume_indicator_opacity_set
8293 (sd->x.xwin, ECORE_X_ILLUME_INDICATOR_TRANSLUCENT);
8294 else if (sd->legacy.ind_o_mode == ELM_WIN_INDICATOR_TRANSPARENT)
8295 ecore_x_e_illume_indicator_opacity_set
8296 (sd->x.xwin, ECORE_X_ILLUME_INDICATOR_TRANSPARENT);
8297 }
8298 #endif
8299 efl_event_callback_legacy_call
8300 (obj, EFL_UI_WIN_EVENT_INDICATOR_PROP_CHANGED, NULL);
8301 }
8302
8303 EAPI Elm_Win_Indicator_Opacity_Mode
elm_win_indicator_opacity_get(const Evas_Object * obj)8304 elm_win_indicator_opacity_get(const Evas_Object *obj)
8305 {
8306 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8307 if (!sd) return ELM_WIN_INDICATOR_OPACITY_UNKNOWN;
8308 if (sd->legacy.forbidden)
8309 {
8310 CRI("Use of this API is forbidden after calling an EO API on this "
8311 "window. Fix your code!");
8312 return ELM_WIN_INDICATOR_OPACITY_UNKNOWN;
8313 }
8314
8315 return sd->legacy.ind_o_mode;
8316 }
8317
8318 EAPI void
elm_win_keyboard_win_set(Evas_Object * obj,Eina_Bool is_keyboard)8319 elm_win_keyboard_win_set(Evas_Object *obj, Eina_Bool is_keyboard)
8320 {
8321 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8322 if (!sd) return;
8323
8324 #ifdef HAVE_ELEMENTARY_X
8325 _internal_elm_win_xwindow_get(sd);
8326 if (sd->x.xwin)
8327 {
8328 _internal_elm_win_xwindow_get(sd);
8329 ecore_x_e_virtual_keyboard_set(sd->x.xwin, is_keyboard);
8330 }
8331 #else
8332 (void)sd;
8333 (void)is_keyboard;
8334 #endif
8335 }
8336
8337 EAPI Eina_Bool
elm_win_keyboard_win_get(const Evas_Object * obj)8338 elm_win_keyboard_win_get(const Evas_Object *obj)
8339 {
8340 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8341 if (!sd) return EINA_FALSE;
8342
8343 #ifdef HAVE_ELEMENTARY_X
8344 _internal_elm_win_xwindow_get(sd);
8345 if (sd->x.xwin)
8346 {
8347 _internal_elm_win_xwindow_get(sd);
8348 return ecore_x_e_virtual_keyboard_get(sd->x.xwin);
8349 }
8350 #else
8351 (void)sd;
8352 #endif
8353 return EINA_FALSE;
8354 }
8355
8356 EAPI void
elm_win_conformant_set(Evas_Object * obj,Eina_Bool conformant)8357 elm_win_conformant_set(Evas_Object *obj, Eina_Bool conformant)
8358 {
8359 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8360 if (!sd) return;
8361
8362 #ifdef HAVE_ELEMENTARY_X
8363 _internal_elm_win_xwindow_get(sd);
8364 if (sd->x.xwin)
8365 {
8366 _internal_elm_win_xwindow_get(sd);
8367 ecore_x_e_illume_conformant_set(sd->x.xwin, conformant);
8368 }
8369 #else
8370 (void)sd;
8371 (void)conformant;
8372 #endif
8373 }
8374
8375 EAPI Eina_Bool
elm_win_conformant_get(const Evas_Object * obj)8376 elm_win_conformant_get(const Evas_Object *obj)
8377 {
8378 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8379 if (!sd) return EINA_FALSE;
8380
8381 #ifdef HAVE_ELEMENTARY_X
8382 _internal_elm_win_xwindow_get(sd);
8383 if (sd->x.xwin)
8384 {
8385 _internal_elm_win_xwindow_get(sd);
8386 return ecore_x_e_illume_conformant_get(sd->x.xwin);
8387 }
8388 #else
8389 (void)sd;
8390 #endif
8391
8392 return EINA_FALSE;
8393 }
8394
8395 EAPI void
elm_win_wm_rotation_manual_rotation_done_set(Evas_Object * obj,Eina_Bool set)8396 elm_win_wm_rotation_manual_rotation_done_set(Evas_Object *obj, Eina_Bool set)
8397 {
8398 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8399 if (!sd) return;
8400
8401 if (!sd->wm_rot.use) return;
8402 ecore_evas_wm_rotation_manual_rotation_done_set(sd->ee, set);
8403 }
8404
8405 EAPI Eina_Bool
elm_win_wm_rotation_manual_rotation_done_get(const Evas_Object * obj)8406 elm_win_wm_rotation_manual_rotation_done_get(const Evas_Object *obj)
8407 {
8408 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8409 if (!sd) return EINA_FALSE;
8410
8411 if (!sd->wm_rot.use) return EINA_FALSE;
8412 return ecore_evas_wm_rotation_manual_rotation_done_get(sd->ee);
8413 }
8414
8415 EAPI void
elm_win_wm_rotation_manual_rotation_done(Evas_Object * obj)8416 elm_win_wm_rotation_manual_rotation_done(Evas_Object *obj)
8417 {
8418 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8419 if (!sd) return;
8420
8421 if (!sd->wm_rot.use) return;
8422 ecore_evas_wm_rotation_manual_rotation_done(sd->ee);
8423 }
8424
8425 /*
8426 * This API does not resize the internal window (ex: X window).
8427 * But this resizes evas_output, elm window, and its contents.
8428 */
8429 EAPI void
elm_win_rotation_with_resize_set(Evas_Object * obj,int rotation)8430 elm_win_rotation_with_resize_set(Evas_Object *obj, int rotation)
8431 {
8432 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8433 if (!sd) return;
8434
8435 _win_rotate(obj, sd, rotation, EINA_TRUE);
8436 }
8437
8438 EAPI int
elm_win_wm_rotation_preferred_rotation_get(const Evas_Object * obj)8439 elm_win_wm_rotation_preferred_rotation_get(const Evas_Object *obj)
8440 {
8441 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8442 if (!sd) return -1;
8443
8444 return sd->wm_rot.preferred_rot;
8445 }
8446
8447 EAPI Eina_Bool
elm_win_wm_rotation_supported_get(const Evas_Object * obj)8448 elm_win_wm_rotation_supported_get(const Evas_Object *obj)
8449 {
8450 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8451 if (!sd) return EINA_FALSE;
8452
8453 return sd->wm_rot.wm_supported;
8454 }
8455
8456 EAPI void
elm_win_wm_rotation_preferred_rotation_set(Evas_Object * obj,int rotation)8457 elm_win_wm_rotation_preferred_rotation_set(Evas_Object *obj, int rotation)
8458 {
8459 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8460 int rot;
8461
8462 if (!sd) return;
8463 if (!sd->wm_rot.use)
8464 sd->wm_rot.use = EINA_TRUE;
8465
8466 // '-1' means that elm_win doesn't use preferred rotation.
8467 if (rotation == -1)
8468 rot = -1;
8469 else
8470 rot = _win_rotation_degree_check(rotation);
8471
8472 if (sd->wm_rot.preferred_rot == rot) return;
8473 sd->wm_rot.preferred_rot = rot;
8474
8475 ecore_evas_wm_rotation_preferred_rotation_set(sd->ee, rot);
8476 }
8477
8478 EAPI void
elm_win_screen_size_get(const Evas_Object * obj,int * x,int * y,int * w,int * h)8479 elm_win_screen_size_get(const Evas_Object *obj, int *x, int *y, int *w, int *h)
8480 {
8481 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8482 if (!sd) return;
8483
8484 ecore_evas_screen_geometry_get(sd->ee, x, y, w, h);
8485 }
8486
8487 EAPI void
elm_win_screen_position_get(const Evas_Object * obj,int * x,int * y)8488 elm_win_screen_position_get(const Evas_Object *obj, int *x, int *y)
8489 {
8490 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8491 if (!sd) return;
8492
8493 if (x) *x = sd->screen.x;
8494 if (y) *y = sd->screen.y;
8495 }
8496
8497 EAPI void
elm_win_screen_dpi_get(const Evas_Object * obj,int * xdpi,int * ydpi)8498 elm_win_screen_dpi_get(const Evas_Object *obj, int *xdpi, int *ydpi)
8499 {
8500 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8501 if (!sd) return;
8502
8503 ecore_evas_screen_dpi_get(sd->ee, xdpi, ydpi);
8504 }
8505
8506 EAPI void
elm_win_icon_name_set(Evas_Object * obj,const char * icon_name)8507 elm_win_icon_name_set(Evas_Object *obj, const char *icon_name)
8508 {
8509 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8510 if (!sd) return;
8511
8512 if (!icon_name) return;
8513 eina_stringshare_replace(&(sd->icon_name), icon_name);
8514 #ifdef HAVE_ELEMENTARY_X
8515 _elm_win_xwin_update(sd);
8516 #endif
8517 }
8518
8519 EAPI const char*
elm_win_icon_name_get(const Evas_Object * obj)8520 elm_win_icon_name_get(const Evas_Object *obj)
8521 {
8522 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8523 if (!sd) return NULL;
8524
8525 return sd->icon_name;
8526 }
8527
8528 EAPI void
elm_win_withdrawn_set(Evas_Object * obj,Eina_Bool withdrawn)8529 elm_win_withdrawn_set(Evas_Object *obj, Eina_Bool withdrawn)
8530 {
8531 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8532 if (!sd) return;
8533
8534 // sd->withdrawn = withdrawn;
8535 TRAP(sd, withdrawn_set, withdrawn);
8536 #ifdef HAVE_ELEMENTARY_X
8537 _elm_win_xwin_update(sd);
8538 #endif
8539 }
8540
8541 EAPI Eina_Bool
elm_win_withdrawn_get(const Evas_Object * obj)8542 elm_win_withdrawn_get(const Evas_Object *obj)
8543 {
8544 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8545 if (!sd) return EINA_FALSE;
8546
8547 return sd->withdrawn;
8548 }
8549
8550 EAPI void
elm_win_urgent_set(Evas_Object * obj,Eina_Bool urgent)8551 elm_win_urgent_set(Evas_Object *obj, Eina_Bool urgent)
8552 {
8553 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8554 if (!sd) return;
8555
8556 if (sd->urgent == urgent)
8557 return;
8558 sd->urgent = urgent;
8559 TRAP(sd, urgent_set, urgent);
8560 #ifdef HAVE_ELEMENTARY_X
8561 _elm_win_xwin_update(sd);
8562 #endif
8563 }
8564
8565 EAPI Eina_Bool
elm_win_urgent_get(const Evas_Object * obj)8566 elm_win_urgent_get(const Evas_Object *obj)
8567 {
8568 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8569 if (!sd) return EINA_FALSE;
8570
8571 return sd->urgent;
8572 }
8573
8574 EAPI void
elm_win_demand_attention_set(Evas_Object * obj,Eina_Bool demand_attention)8575 elm_win_demand_attention_set(Evas_Object *obj, Eina_Bool demand_attention)
8576 {
8577 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8578 if (!sd) return;
8579
8580 sd->demand_attention = demand_attention;
8581 TRAP(sd, demand_attention_set, demand_attention);
8582 #ifdef HAVE_ELEMENTARY_X
8583 _elm_win_xwin_update(sd);
8584 #endif
8585 }
8586
8587 EAPI Eina_Bool
elm_win_demand_attention_get(const Evas_Object * obj)8588 elm_win_demand_attention_get(const Evas_Object *obj)
8589 {
8590 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8591 if (!sd) return EINA_FALSE;
8592
8593 return sd->demand_attention;
8594 }
8595
8596 EAPI void
elm_win_modal_set(Evas_Object * obj,Eina_Bool modal)8597 elm_win_modal_set(Evas_Object *obj, Eina_Bool modal)
8598 {
8599 Efl_Ui_Win_Modal_Mode modality;
8600
8601 modality = modal ? EFL_UI_WIN_MODAL_MODE_MODAL : EFL_UI_WIN_MODAL_MODE_NONE;
8602 efl_ui_win_modal_set(obj, modality);
8603 }
8604
8605 EAPI Eina_Bool
elm_win_modal_get(const Evas_Object * obj)8606 elm_win_modal_get(const Evas_Object *obj)
8607 {
8608 Efl_Ui_Win_Modal_Mode modality;
8609
8610 modality = efl_ui_win_modal_get(obj);
8611 return (modality != EFL_UI_WIN_MODAL_MODE_NONE);
8612 }
8613
8614 EAPI void
elm_win_shaped_set(Evas_Object * obj,Eina_Bool shaped)8615 elm_win_shaped_set(Evas_Object *obj, Eina_Bool shaped)
8616 {
8617 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8618 if (!sd) return;
8619
8620 shaped = !!shaped;
8621
8622 #ifdef HAVE_ELEMENTARY_X
8623 if (sd->x.shaped == shaped) return;
8624 sd->x.shaped = shaped;
8625 TRAP(sd, shaped_set, shaped);
8626 #endif
8627 }
8628
8629 EAPI Eina_Bool
elm_win_shaped_get(const Evas_Object * obj)8630 elm_win_shaped_get(const Evas_Object *obj)
8631 {
8632 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8633 if (!sd) return EINA_FALSE;
8634
8635 return ecore_evas_shaped_get(sd->ee);
8636 }
8637
8638 EAPI void
elm_win_title_set(Evas_Object * obj,const char * title)8639 elm_win_title_set(Evas_Object *obj, const char *title)
8640 {
8641 efl_text_set(obj, title);
8642 }
8643
8644 EAPI const char*
elm_win_title_get(const Evas_Object * obj)8645 elm_win_title_get(const Evas_Object *obj)
8646 {
8647 return efl_text_get(obj);
8648 }
8649
8650 EAPI void
elm_win_size_base_set(Evas_Object * obj,int w,int h)8651 elm_win_size_base_set(Evas_Object *obj, int w, int h)
8652 {
8653 efl_ui_win_hint_base_set(obj, EINA_SIZE2D(w, h));
8654 }
8655
8656 EAPI void
elm_win_size_base_get(const Evas_Object * obj,int * w,int * h)8657 elm_win_size_base_get(const Evas_Object *obj, int *w, int *h)
8658 {
8659 Eina_Size2D sz;
8660 sz = efl_ui_win_hint_base_get(obj);
8661 if (w) *w = sz.w;
8662 if (h) *h = sz.h;
8663 }
8664
8665 EAPI void
elm_win_size_step_set(Evas_Object * obj,int w,int h)8666 elm_win_size_step_set(Evas_Object *obj, int w, int h)
8667 {
8668 efl_ui_win_hint_step_set(obj, EINA_SIZE2D(w, h));
8669 }
8670
8671 EAPI void
elm_win_size_step_get(const Evas_Object * obj,int * w,int * h)8672 elm_win_size_step_get(const Evas_Object *obj, int *w, int *h)
8673 {
8674 Eina_Size2D sz;
8675 sz = efl_ui_win_hint_step_get(obj);
8676 if (w) *w = sz.w;
8677 if (h) *h = sz.h;
8678 }
8679
8680 EAPI void
elm_win_illume_command_send(Evas_Object * obj,Elm_Illume_Command command,void * params EINA_UNUSED)8681 elm_win_illume_command_send(Evas_Object *obj, Elm_Illume_Command command, void *params EINA_UNUSED)
8682 {
8683 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8684 if (!sd) return;
8685
8686 #ifdef HAVE_ELEMENTARY_X
8687 _internal_elm_win_xwindow_get(sd);
8688 if (sd->x.xwin)
8689 {
8690 _internal_elm_win_xwindow_get(sd);
8691 switch (command)
8692 {
8693 case ELM_ILLUME_COMMAND_FOCUS_BACK:
8694 ecore_x_e_illume_focus_back_send(sd->x.xwin);
8695 break;
8696
8697 case ELM_ILLUME_COMMAND_FOCUS_FORWARD:
8698 ecore_x_e_illume_focus_forward_send(sd->x.xwin);
8699 break;
8700
8701 case ELM_ILLUME_COMMAND_FOCUS_HOME:
8702 ecore_x_e_illume_focus_home_send(sd->x.xwin);
8703 break;
8704
8705 case ELM_ILLUME_COMMAND_CLOSE:
8706 ecore_x_e_illume_close_send(sd->x.xwin);
8707 break;
8708
8709 default:
8710 break;
8711 }
8712 }
8713 #else
8714 (void)sd;
8715 (void)command;
8716 #endif
8717 }
8718
8719 EAPI void
elm_win_profile_set(Evas_Object * obj,const char * profile)8720 elm_win_profile_set(Evas_Object *obj, const char *profile)
8721 {
8722 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8723 if (!sd) return;
8724
8725 /* check to see if a given profile is present in an available profiles */
8726 if (profile && eina_array_count(sd->profile.available))
8727 {
8728 if (!_profile_exists(sd, profile))
8729 return;
8730 }
8731
8732 if (ecore_evas_window_profile_supported_get(sd->ee))
8733 {
8734 if (!profile) _elm_win_profile_del(sd);
8735 ecore_evas_window_profile_set(sd->ee, profile);
8736 }
8737 else
8738 {
8739 if (_internal_elm_win_profile_set(sd, profile))
8740 _elm_win_profile_update(sd);
8741 }
8742 }
8743
8744 EAPI const char*
elm_win_profile_get(const Evas_Object * obj)8745 elm_win_profile_get(const Evas_Object *obj)
8746 {
8747 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8748 if (!sd) return NULL;
8749
8750 return sd->profile.name;
8751 }
8752
8753 EAPI void
elm_win_layer_set(Evas_Object * obj,int layer)8754 elm_win_layer_set(Evas_Object *obj, int layer)
8755 {
8756 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8757 if (!sd) return;
8758
8759 TRAP(sd, layer_set, layer);
8760 #ifdef HAVE_ELEMENTARY_X
8761 _elm_win_xwin_update(sd);
8762 #endif
8763 }
8764
8765 EAPI int
elm_win_layer_get(const Evas_Object * obj)8766 elm_win_layer_get(const Evas_Object *obj)
8767 {
8768 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8769 if (!sd) return 0;
8770
8771 return ecore_evas_layer_get(sd->ee);
8772 }
8773
8774 EAPI Evas_Object*
elm_win_inlined_image_object_get(const Evas_Object * obj)8775 elm_win_inlined_image_object_get(const Evas_Object *obj)
8776 {
8777 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8778 if (!sd) return NULL;
8779
8780 return sd->img_obj;
8781 }
8782
8783 static Ecore_Window
_elm_win_window_id_get(Efl_Ui_Win_Data * sd)8784 _elm_win_window_id_get(Efl_Ui_Win_Data *sd)
8785 {
8786 #if HAVE_ELEMENTARY_WL2
8787 if (sd->wl.win)
8788 return (Ecore_Window)sd->wl.win;
8789 if (sd->parent)
8790 {
8791 Ecore_Wl2_Window *parent;
8792
8793 parent = elm_win_wl_window_get(sd->parent);
8794 if (parent)
8795 return (Ecore_Window)parent;
8796 }
8797 #endif
8798 #ifdef HAVE_ELEMENTARY_X
8799 _internal_elm_win_xwindow_get(sd);
8800 if (sd->x.xwin)
8801 {
8802 _internal_elm_win_xwindow_get(sd);
8803 return (Ecore_Window)sd->x.xwin;
8804 }
8805 if (sd->parent)
8806 {
8807 Ecore_Window xwin = elm_win_xwindow_get(sd->parent);
8808 if (xwin) return xwin;
8809 }
8810 #endif
8811 #ifdef HAVE_ELEMENTARY_COCOA
8812 if (sd->cocoa.win) return (Ecore_Window)(sd->cocoa.win);
8813 if (sd->parent)
8814 {
8815 Ecore_Cocoa_Window *pwin;
8816 pwin = elm_win_cocoa_window_get(sd->parent);
8817 if (pwin) return (Ecore_Window)pwin;
8818 }
8819 #endif
8820 #ifdef HAVE_ELEMENTARY_WIN32
8821 _internal_elm_win_win32window_get(sd);
8822 if (sd->win32.win) return (Ecore_Window)sd->win32.win;
8823 if (sd->parent)
8824 {
8825 Ecore_Window wwin = (Ecore_Window)elm_win_win32_window_get(sd->parent);
8826 if (wwin) return wwin;
8827 }
8828 #endif
8829
8830 return 0;
8831 }
8832
8833 EAPI Ecore_Window
elm_win_window_id_get(const Evas_Object * obj)8834 elm_win_window_id_get(const Evas_Object *obj)
8835 {
8836 Efl_Ui_Win_Data *sd;
8837 if (!obj) return 0;
8838
8839 if (!evas_object_smart_type_check_ptr(obj, MY_CLASS_NAME_LEGACY))
8840 {
8841 Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
8842 if (!ee) return 0;
8843 return ecore_evas_window_get(ee);
8844 }
8845
8846 sd = efl_data_scope_safe_get(obj, MY_CLASS);
8847 if (!sd) return 0;
8848 return _elm_win_window_id_get(sd);
8849 }
8850
8851 EAPI Evas_Object *
elm_win_main_menu_get(Evas_Object * obj)8852 elm_win_main_menu_get(Evas_Object *obj)
8853 {
8854 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8855 if (!sd) return NULL;
8856
8857 #ifdef HAVE_ELEMENTARY_X
8858 Eina_Bool use_dbus = EINA_FALSE;
8859 #endif
8860
8861 if (sd->main_menu) goto end;
8862
8863 sd->main_menu = elm_menu_add(obj);
8864 _elm_menu_menu_bar_set(sd->main_menu, EINA_TRUE);
8865
8866 #ifdef HAVE_ELEMENTARY_X
8867 if (!_elm_config->disable_external_menu && sd->x.xwin) use_dbus = EINA_TRUE;
8868 #endif
8869
8870 #ifdef HAVE_ELEMENTARY_X
8871 if (use_dbus && _elm_dbus_menu_register(sd->main_menu))
8872 {
8873 _internal_elm_win_xwindow_get(sd);
8874 _elm_dbus_menu_app_menu_register(sd->x.xwin, sd->main_menu,
8875 _dbus_menu_set, obj);
8876 }
8877 else
8878 #endif
8879 _dbus_menu_set(EINA_FALSE, obj);
8880
8881 end:
8882 return sd->main_menu;
8883 }
8884
8885 EAPI void
elm_win_aspect_set(Eo * obj,double aspect)8886 elm_win_aspect_set(Eo *obj, double aspect)
8887 {
8888 Eina_Size2D sz = { 0, 0 };
8889
8890 if (aspect > DBL_EPSILON)
8891 sz = EINA_SIZE2D(1000 * aspect, 1000);
8892
8893 efl_gfx_hint_aspect_set(obj, EFL_GFX_HINT_ASPECT_NONE, sz);
8894 }
8895
8896 EAPI double
elm_win_aspect_get(const Eo * obj)8897 elm_win_aspect_get(const Eo *obj)
8898 {
8899 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8900 if (!sd) return 0.0;
8901 return _win_aspect_get(sd);
8902 }
8903
8904 /* legacy APIs */
8905
8906 static void
_fake_canvas_set(Evas_Object * obj,Ecore_Evas * oee)8907 _fake_canvas_set(Evas_Object *obj, Ecore_Evas *oee)
8908 {
8909 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8910 if (!sd) return;
8911
8912 sd->ee = oee;
8913 _elm_win_need_frame_adjust(sd, ecore_evas_engine_name_get(oee));
8914 }
8915
8916 /**
8917 * @internal
8918 *
8919 * Recalculate the size of window considering its resize objects' weight and
8920 * min size. If any of its resize objects' weight equals to 0.0, window
8921 * layout's weight will be set to 0.0.
8922 *
8923 * @param o box object
8924 * @param p box's private data
8925 * @param data window object
8926 */
8927 static void
_window_layout_stack(Evas_Object * o,Evas_Object_Box_Data * p,void * data)8928 _window_layout_stack(Evas_Object *o, Evas_Object_Box_Data *p, void *data)
8929 {
8930 const Eina_List *l;
8931 Evas_Object *child;
8932 Evas_Object_Box_Option *opt;
8933 Evas_Coord x, y, w, h, menuw = 0;
8934 double wx, wy;
8935 Evas_Coord minw = -1, minh = -1;
8936 double weight_x = EVAS_HINT_EXPAND;
8937 double weight_y = EVAS_HINT_EXPAND;
8938
8939 ELM_WIN_DATA_GET(data, sd);
8940 if (sd->main_menu && efl_gfx_entity_visible_get(sd->main_menu))
8941 evas_object_size_hint_combined_min_get(sd->main_menu, &menuw, NULL);
8942
8943 EINA_LIST_FOREACH(p->children, l, opt)
8944 {
8945 child = opt->obj;
8946 efl_gfx_hint_weight_get(child, &wx, &wy);
8947 if (EINA_DBL_EQ(wx, 0.0)) weight_x = 0;
8948 if (EINA_DBL_EQ(wy, 0.0)) weight_y = 0;
8949
8950 evas_object_size_hint_combined_min_get(child, &w, &h);
8951 if (w > minw) minw = w;
8952 if (h > minh) minh = h;
8953 }
8954
8955 if (minw < menuw) minw = menuw;
8956 efl_gfx_hint_size_restricted_min_set(o, EINA_SIZE2D(minw, minh));
8957 evas_object_geometry_get(o, &x, &y, &w, &h);
8958 if (w < minw) w = minw;
8959 if (h < minh) h = minh;
8960 evas_object_resize(o, w, h);
8961
8962 EINA_LIST_FOREACH(p->children, l, opt)
8963 {
8964 child = opt->obj;
8965 evas_object_geometry_set(child, x, y, w, h);
8966 }
8967
8968 efl_gfx_hint_weight_set(sd->legacy.edje, weight_x, weight_y);
8969 //evas_object_smart_changed(sd->legacy.edje);
8970 }
8971
8972 static void
_elm_win_legacy_init(Efl_Ui_Win_Data * sd)8973 _elm_win_legacy_init(Efl_Ui_Win_Data *sd)
8974 {
8975 sd->legacy.edje = edje_object_add(sd->evas);
8976 _elm_win_theme_internal(sd->obj, sd);
8977
8978 sd->legacy.box = evas_object_box_add(sd->evas);
8979 evas_object_box_layout_set(sd->legacy.box, _window_layout_stack, sd->obj, NULL);
8980
8981 if (elm_widget_is_legacy(sd->obj))
8982 edje_object_part_swallow(sd->legacy.edje, "elm.swallow.contents", sd->legacy.box);
8983 else
8984 edje_object_part_swallow(sd->legacy.edje, "efl.contents", sd->legacy.box);
8985
8986 if (sd->type != EFL_UI_WIN_TYPE_FAKE)
8987 {
8988 edje_object_update_hints_set(sd->legacy.edje, EINA_TRUE);
8989 evas_object_event_callback_add(sd->legacy.edje, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
8990 _elm_win_on_resize_obj_changed_size_hints, sd->obj);
8991 }
8992 }
8993
8994 EAPI void
elm_win_resize_object_add(Eo * obj,Evas_Object * subobj)8995 elm_win_resize_object_add(Eo *obj, Evas_Object *subobj)
8996 {
8997 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
8998 Eina_Bool ret;
8999
9000 if (!sd) return;
9001 if (sd->legacy.forbidden)
9002 {
9003 CRI("Use of this API is forbidden after calling an EO API on this "
9004 "window. Fix your code!");
9005 return;
9006 }
9007
9008 // Little hack for E
9009 if (evas_obj_box_count(sd->legacy.box) > 0)
9010 sd->single_edje_content = 0;
9011 else if (efl_isa(subobj, EFL_CANVAS_LAYOUT_CLASS))
9012 sd->single_edje_content = 1;
9013
9014 ret = elm_widget_sub_object_add(obj, subobj);
9015 ret &= (evas_object_box_append(sd->legacy.box, subobj) != NULL);
9016
9017 if (!ret)
9018 ERR("could not add sub object %p to window %p", subobj, obj);
9019 }
9020
9021 EAPI void
elm_win_resize_object_del(Eo * obj,Evas_Object * subobj)9022 elm_win_resize_object_del(Eo *obj, Evas_Object *subobj)
9023 {
9024 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
9025 Eina_Bool ret;
9026
9027 if (!sd) return;
9028 if (sd->legacy.forbidden)
9029 {
9030 CRI("Use of this API is forbidden after calling an EO API on this "
9031 "window. Fix your code!");
9032 return;
9033 }
9034
9035 ret = elm_widget_sub_object_del(obj, subobj);
9036 ret &= evas_object_box_remove(sd->legacy.box, subobj);
9037
9038 if (!ret)
9039 ERR("could not remove sub object %p from window %p", subobj, obj);
9040 }
9041
9042 EAPI Eina_Bool
elm_win_keygrab_set(Elm_Win * obj,const char * key,Evas_Modifier_Mask modifiers EINA_UNUSED,Evas_Modifier_Mask not_modifiers EINA_UNUSED,int priority EINA_UNUSED,Elm_Win_Keygrab_Mode grab_mode)9043 elm_win_keygrab_set(Elm_Win *obj, const char *key,
9044 Evas_Modifier_Mask modifiers EINA_UNUSED,
9045 Evas_Modifier_Mask not_modifiers EINA_UNUSED,
9046 int priority EINA_UNUSED, Elm_Win_Keygrab_Mode grab_mode)
9047 {
9048 // Note: Not converting modifiers as they are not used in the implementation
9049 Eina_Bool ret = EINA_FALSE;
9050 #ifdef HAVE_ELEMENTARY_X
9051 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
9052 EINA_SAFETY_ON_NULL_RETURN_VAL(sd, EINA_FALSE);
9053 _internal_elm_win_xwindow_get(sd);
9054 if (sd->x.xwin)
9055 {
9056 _internal_elm_win_xwindow_get(sd);
9057 Ecore_X_Win_Keygrab_Mode x_grab_mode;
9058 switch (grab_mode)
9059 {
9060 case ELM_WIN_KEYGRAB_SHARED:
9061 x_grab_mode = ECORE_X_WIN_KEYGRAB_SHARED;
9062 break;
9063 case ELM_WIN_KEYGRAB_TOPMOST:
9064 x_grab_mode = ECORE_X_WIN_KEYGRAB_TOPMOST;
9065 break;
9066 case ELM_WIN_KEYGRAB_EXCLUSIVE:
9067 x_grab_mode = ECORE_X_WIN_KEYGRAB_EXCLUSIVE;
9068 break;
9069 case ELM_WIN_KEYGRAB_OVERRIDE_EXCLUSIVE:
9070 x_grab_mode = ECORE_X_WIN_KEYGRAB_OVERRIDE_EXCLUSIVE;
9071 break;
9072 default:
9073 return ret;
9074 }
9075 ret = ecore_x_window_keygrab_set(sd->x.xwin, key, 0, 0, 0, x_grab_mode);
9076 }
9077 #else
9078 (void)obj;
9079 (void)key;
9080 (void)grab_mode;
9081 #endif
9082 return ret;
9083 }
9084
9085 EAPI Eina_Bool
elm_win_keygrab_unset(Elm_Win * obj,const char * key,Evas_Modifier_Mask modifiers EINA_UNUSED,Evas_Modifier_Mask not_modifiers EINA_UNUSED)9086 elm_win_keygrab_unset(Elm_Win *obj, const char *key,
9087 Evas_Modifier_Mask modifiers EINA_UNUSED,
9088 Evas_Modifier_Mask not_modifiers EINA_UNUSED)
9089 {
9090 // Note: Not converting modifiers as they are not used in the implementation
9091 Eina_Bool ret = EINA_FALSE;
9092 #ifdef HAVE_ELEMENTARY_X
9093 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
9094 EINA_SAFETY_ON_NULL_RETURN_VAL(sd, EINA_FALSE);
9095 _internal_elm_win_xwindow_get(sd);
9096 if (sd->x.xwin)
9097 {
9098 _internal_elm_win_xwindow_get(sd);
9099 ret = ecore_x_window_keygrab_unset(sd->x.xwin, key, 0, 0);
9100 }
9101 #else
9102 (void)obj;
9103 (void)key;
9104 #endif
9105 return ret;
9106 }
9107
9108 EAPI Eina_Bool
elm_win_socket_listen(Efl_Ui_Win * obj,const char * svcname,int svcnum,Eina_Bool svcsys)9109 elm_win_socket_listen(Efl_Ui_Win *obj, const char *svcname, int svcnum, Eina_Bool svcsys)
9110 {
9111 return efl_ui_win_socket_listen(obj, svcname, svcnum, svcsys);
9112 }
9113
9114 EAPI Eina_Bool
elm_win_focus_get(const Efl_Ui_Win * obj)9115 elm_win_focus_get(const Efl_Ui_Win *obj)
9116 {
9117 EINA_SAFETY_ON_FALSE_RETURN_VAL(efl_isa(obj, MY_CLASS), EINA_FALSE);
9118 return efl_ui_focus_object_focus_get(obj);
9119 }
9120
9121 EAPI Eina_Bool
elm_win_available_profiles_get(const Elm_Win * obj,char *** profiles,unsigned int * count)9122 elm_win_available_profiles_get(const Elm_Win *obj, char ***profiles, unsigned int *count)
9123 {
9124 const Eina_Array *ar;
9125
9126 if (!efl_isa(obj, MY_CLASS)) return EINA_FALSE;
9127 ar = efl_ui_win_wm_available_profiles_get(obj);
9128 if (!ar)
9129 {
9130 if (profiles) *profiles = NULL;
9131 if (count) *count = 0;
9132 return EINA_FALSE;
9133 }
9134
9135 if (profiles) *profiles = (char **) ar->data;
9136 if (count) *count = ar->count;
9137 return EINA_TRUE;
9138 }
9139
9140 EAPI void
elm_win_available_profiles_set(Elm_Win * obj,const char ** profiles,unsigned int count)9141 elm_win_available_profiles_set(Elm_Win *obj, const char **profiles, unsigned int count)
9142 {
9143 if (!efl_isa(obj, MY_CLASS)) return;
9144 if ((count > 0) && (profiles))
9145 {
9146 Eina_Array *ar;
9147 unsigned int i;
9148
9149 ar = eina_array_new(count);
9150 if (ar)
9151 {
9152 for (i = 0; i < count; i++)
9153 eina_array_push(ar, profiles[i]);
9154 efl_ui_win_wm_available_profiles_set(obj, ar);
9155 eina_array_free(ar);
9156 }
9157 }
9158 else efl_ui_win_wm_available_profiles_set(obj, NULL);
9159 }
9160
9161 // deprecated
9162
9163 EAPI void
elm_win_fake_canvas_set(Evas_Object * obj EINA_UNUSED,Ecore_Evas * oee EINA_UNUSED)9164 elm_win_fake_canvas_set(Evas_Object *obj EINA_UNUSED, Ecore_Evas *oee EINA_UNUSED)
9165 {
9166 ERR("Calling deprecrated function '%s'", __func__);
9167 }
9168
9169 EAPI void
elm_win_name_set(Evas_Object * obj,const char * name)9170 elm_win_name_set(Evas_Object *obj, const char *name)
9171 {
9172 ERR("Calling deprecrated function '%s'", __func__);
9173 efl_ui_win_name_set(obj, name);
9174 }
9175
9176 EAPI void
elm_win_type_set(Evas_Object * obj,Elm_Win_Type type)9177 elm_win_type_set(Evas_Object *obj, Elm_Win_Type type)
9178 {
9179 ERR("Calling deprecrated function '%s'", __func__);
9180 efl_ui_win_type_set(obj, _elm_win_type_to_efl_ui_win_type(type));
9181 }
9182
9183 EAPI void
elm_win_teamwork_uri_preload(Efl_Ui_Win * obj EINA_UNUSED,const char * uri EINA_UNUSED)9184 elm_win_teamwork_uri_preload(Efl_Ui_Win *obj EINA_UNUSED, const char *uri EINA_UNUSED)
9185 {
9186 ERR("Calling deprecrated function '%s'", __func__);
9187 }
9188
9189 EAPI void
elm_win_teamwork_uri_show(Efl_Ui_Win * obj EINA_UNUSED,const char * uri EINA_UNUSED)9190 elm_win_teamwork_uri_show(Efl_Ui_Win *obj EINA_UNUSED, const char *uri EINA_UNUSED)
9191 {
9192 ERR("Calling deprecrated function '%s'", __func__);
9193 }
9194
9195 EAPI void
elm_win_teamwork_uri_hide(Efl_Ui_Win * obj EINA_UNUSED)9196 elm_win_teamwork_uri_hide(Efl_Ui_Win *obj EINA_UNUSED)
9197 {
9198 ERR("Calling deprecrated function '%s'", __func__);
9199 }
9200
9201 EAPI void
elm_win_teamwork_uri_open(Efl_Ui_Win * obj EINA_UNUSED,const char * uri EINA_UNUSED)9202 elm_win_teamwork_uri_open(Efl_Ui_Win *obj EINA_UNUSED, const char *uri EINA_UNUSED)
9203 {
9204 ERR("Calling deprecrated function '%s'", __func__);
9205 }
9206
9207 /* What here follows is code that implements the glue between ecore evas and efl_ui* side */
9208 typedef struct {
9209 Eo *obj;
9210 Eina_Bool currently_inside;
9211 } Ui_Dnd_Target;
9212
9213 static inline Efl_Ui_Cnp_Buffer
_ui_buffer_get(Ecore_Evas_Selection_Buffer buffer)9214 _ui_buffer_get(Ecore_Evas_Selection_Buffer buffer)
9215 {
9216 if (buffer == ECORE_EVAS_SELECTION_BUFFER_SELECTION_BUFFER)
9217 return EFL_UI_CNP_BUFFER_SELECTION;
9218 else if (buffer == ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER)
9219 return EFL_UI_CNP_BUFFER_COPY_AND_PASTE;
9220
9221 return -1;
9222 }
9223
9224 void
_register_selection_changed(Efl_Ui_Selection * selection)9225 _register_selection_changed(Efl_Ui_Selection *selection)
9226 {
9227 ELM_WIN_DATA_GET(efl_provider_find(selection, EFL_UI_WIN_CLASS), pd);
9228
9229 eina_array_push(pd->planned_changes, selection);
9230 }
9231
9232 static Eina_Bool
_remove_object(void * data,void * gdata)9233 _remove_object(void *data, void *gdata)
9234 {
9235 if (data == gdata)
9236 return EINA_FALSE;
9237 return EINA_TRUE;
9238 }
9239
9240 static void
_selection_changed_cb(Ecore_Evas * ee,unsigned int seat,Ecore_Evas_Selection_Buffer selection)9241 _selection_changed_cb(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer selection)
9242 {
9243 Efl_Ui_Win_Data *pd = _elm_win_associate_get(ee);
9244 Efl_Ui_Wm_Selection_Changed changed = {
9245 .seat = seat,
9246 .buffer = _ui_buffer_get(selection),
9247 .caused_by = eina_array_count(pd->planned_changes) > 0 ? eina_array_data_get(pd->planned_changes, 0) : NULL,
9248 };
9249
9250 for (unsigned int i = 0; i < eina_array_count(pd->selection_changed); ++i)
9251 {
9252 Eo *obj = eina_array_data_get(pd->selection_changed, i);
9253
9254 efl_event_callback_call(obj, EFL_UI_SELECTION_EVENT_WM_SELECTION_CHANGED, &changed);
9255 }
9256
9257 if (changed.caused_by)
9258 eina_array_remove(pd->planned_changes, _remove_object, changed.caused_by);
9259 }
9260
9261 static void
_motion_cb(Ecore_Evas * ee,unsigned int seat,Eina_Position2D p)9262 _motion_cb(Ecore_Evas *ee, unsigned int seat, Eina_Position2D p)
9263 {
9264 Efl_Ui_Win_Data *pd = _elm_win_associate_get(ee);
9265 for (unsigned int i = 0; i < eina_inarray_count(pd->drop_target); ++i)
9266 {
9267 Ui_Dnd_Target *target = eina_inarray_nth(pd->drop_target, i);
9268 Eina_Rect rect = efl_gfx_entity_geometry_get(target->obj);
9269 Eina_Bool inside = eina_rectangle_coords_inside(&rect.rect, p.x, p.y);
9270 Efl_Ui_Drop_Event ev = {p, seat, ecore_evas_drop_available_types_get(ee, seat)};
9271
9272 if (target->currently_inside && !inside)
9273 {
9274 target->currently_inside = EINA_FALSE;
9275 efl_event_callback_call(target->obj, EFL_UI_DND_EVENT_DROP_LEFT, &ev);
9276 ecore_evas_dnd_mark_motion_used(ee, seat);
9277 }
9278 else if (!target->currently_inside && inside)
9279 {
9280 target->currently_inside = EINA_TRUE;
9281 efl_event_callback_call(target->obj, EFL_UI_DND_EVENT_DROP_ENTERED, &ev);
9282 ecore_evas_dnd_mark_motion_used(ee, seat);
9283 }
9284 else if (target->currently_inside && inside)
9285 {
9286 efl_event_callback_call(target->obj, EFL_UI_DND_EVENT_DROP_POSITION_CHANGED, &ev);
9287 ecore_evas_dnd_mark_motion_used(ee, seat);
9288 }
9289 eina_accessor_free(ev.available_types);
9290 }
9291 }
9292
9293 static void
_enter_state_change_cb(Ecore_Evas * ee,unsigned int seat EINA_UNUSED,Eina_Position2D p,Eina_Bool move_inside)9294 _enter_state_change_cb(Ecore_Evas *ee, unsigned int seat EINA_UNUSED, Eina_Position2D p, Eina_Bool move_inside)
9295 {
9296 Efl_Ui_Win_Data *pd = _elm_win_associate_get(ee);
9297 for (unsigned int i = 0; i < eina_inarray_count(pd->drop_target); ++i)
9298 {
9299 Ui_Dnd_Target *target = eina_inarray_nth(pd->drop_target, i);
9300 Eina_Rect rect = efl_gfx_entity_geometry_get(target->obj);
9301 Eina_Bool inside = eina_rectangle_coords_inside(&rect.rect, p.x, p.y);
9302 Efl_Ui_Drop_Event ev = {p, seat, ecore_evas_drop_available_types_get(ee, seat)};
9303
9304 if (inside && move_inside)
9305 {
9306 target->currently_inside = EINA_TRUE;
9307 efl_event_callback_call(target->obj, EFL_UI_DND_EVENT_DROP_ENTERED, &ev);
9308 }
9309 else if (!move_inside && !target->currently_inside)
9310 {
9311 target->currently_inside = EINA_FALSE;
9312 efl_event_callback_call(target->obj, EFL_UI_DND_EVENT_DROP_LEFT, &ev);
9313 }
9314 }
9315 }
9316
9317 static void
_drop_cb(Ecore_Evas * ee,unsigned int seat EINA_UNUSED,Eina_Position2D p,const char * action)9318 _drop_cb(Ecore_Evas *ee, unsigned int seat EINA_UNUSED, Eina_Position2D p, const char *action)
9319 {
9320 Eina_List *itr, *top_objects_list = NULL;
9321 Efl_Ui_Win_Data *pd = _elm_win_associate_get(ee);
9322 Eina_Array *tmp = eina_array_new(10);
9323 Eo *top_obj;
9324
9325 for (unsigned int i = 0; i < eina_inarray_count(pd->drop_target); ++i)
9326 {
9327 Ui_Dnd_Target *target = eina_inarray_nth(pd->drop_target, i);
9328 Eina_Rect rect = efl_gfx_entity_geometry_get(target->obj);
9329 Eina_Bool inside = eina_rectangle_coords_inside(&rect.rect, p.x, p.y);
9330
9331 if (inside)
9332 {
9333 EINA_SAFETY_ON_FALSE_GOTO(target->currently_inside, end);
9334 eina_array_push(tmp, target->obj);
9335 }
9336 }
9337
9338 /* We retrieve the (non-smart) objects pointed by (px, py) */
9339 top_objects_list = evas_tree_objects_at_xy_get(ecore_evas_get(ee), NULL, p.x, p.y);
9340 /* We walk on this list from the last because if the list contains more than one
9341 * element, all but the last will repeat events. The last one can repeat events
9342 * or not. Anyway, this last one is the first that has to be taken into account
9343 * for the determination of the drop target.
9344 */
9345 EINA_LIST_REVERSE_FOREACH(top_objects_list, itr, top_obj)
9346 {
9347 Evas_Object *object = top_obj;
9348 /* We search for the dropable data into the object. If not found, we search into its parent.
9349 * For example, if a button is a drop target, the first object will be an (internal) image.
9350 * The drop target is attached to the button, i.e to image's parent. That's why we need to
9351 * walk on the parents until NULL.
9352 * If we find this dropable data, we found our drop target.
9353 */
9354 while (object)
9355 {
9356 unsigned int out_idx;
9357 if (!eina_array_find(tmp, object, &out_idx))
9358 {
9359 object = evas_object_smart_parent_get(object);
9360 }
9361 else
9362 {
9363 Efl_Ui_Drop_Dropped_Event ev = {{p, seat, ecore_evas_drop_available_types_get(ee, seat)}, action};
9364 efl_event_callback_call(object, EFL_UI_DND_EVENT_DROP_DROPPED, &ev);
9365 goto end;
9366 }
9367 }
9368 }
9369 end:
9370 eina_list_free(top_objects_list);
9371 eina_array_free(tmp);
9372 }
9373
9374 static void
_ee_backbone_init(Efl_Ui_Win * obj EINA_UNUSED,Efl_Ui_Win_Data * pd)9375 _ee_backbone_init(Efl_Ui_Win *obj EINA_UNUSED, Efl_Ui_Win_Data *pd)
9376 {
9377 pd->selection_changed = eina_array_new(1);
9378 pd->drop_target = eina_inarray_new(sizeof(Ui_Dnd_Target), 1);
9379
9380 ecore_evas_callback_selection_changed_set(pd->ee, _selection_changed_cb);
9381 ecore_evas_callback_drop_drop_set(pd->ee, _drop_cb);
9382 ecore_evas_callback_drop_motion_set(pd->ee, _motion_cb);
9383 ecore_evas_callback_drop_state_changed_set(pd->ee, _enter_state_change_cb);
9384 }
9385
9386 static void
_ee_backbone_shutdown(Efl_Ui_Win * obj EINA_UNUSED,Efl_Ui_Win_Data * pd)9387 _ee_backbone_shutdown(Efl_Ui_Win *obj EINA_UNUSED, Efl_Ui_Win_Data *pd)
9388 {
9389 ecore_evas_callback_selection_changed_set(pd->ee, NULL);
9390 ecore_evas_callback_drop_drop_set(pd->ee, NULL);
9391 ecore_evas_callback_drop_motion_set(pd->ee, NULL);
9392 ecore_evas_callback_drop_state_changed_set(pd->ee, NULL);
9393
9394 eina_array_free(pd->selection_changed);
9395 pd->selection_changed = NULL;
9396 eina_inarray_free(pd->drop_target);
9397 pd->drop_target = NULL;
9398
9399 }
9400
9401 static Eina_Bool
_remove(void * data,void * gdata)9402 _remove(void *data, void *gdata)
9403 {
9404 if (data == gdata)
9405 return EINA_FALSE;
9406 return EINA_TRUE;
9407 }
9408
9409 Efl_Ui_Win*
efl_ui_win_get(Evas_Object * obj)9410 efl_ui_win_get(Evas_Object *obj)
9411 {
9412 Efl_Ui_Win *win = efl_provider_find(obj, MY_CLASS);
9413 if (!win)
9414 {
9415 Evas *e = evas_object_evas_get(obj);
9416 Ecore_Evas *ee = ecore_evas_ecore_evas_get(e);
9417
9418 win = ecore_evas_data_get(ee, "elm_win");
9419 }
9420 EINA_SAFETY_ON_NULL_RETURN_VAL(win, NULL);
9421 return win;
9422 }
9423
9424 static Efl_Ui_Win_Data*
_fetch_win_data_from_arbitary_obj(Efl_Canvas_Object * obj)9425 _fetch_win_data_from_arbitary_obj(Efl_Canvas_Object *obj)
9426 {
9427 Efl_Ui_Win *win = efl_ui_win_get(obj);
9428 EINA_SAFETY_ON_NULL_RETURN_VAL(win, NULL);
9429 Efl_Ui_Win_Data *pd = efl_data_scope_safe_get(win, MY_CLASS);
9430 EINA_SAFETY_ON_NULL_RETURN_VAL(pd, NULL);
9431 return pd;
9432 }
9433
9434 void
_drop_event_register(Eo * obj)9435 _drop_event_register(Eo *obj)
9436 {
9437 Ui_Dnd_Target target = {obj, EINA_FALSE};
9438 Efl_Ui_Win_Data *pd = _fetch_win_data_from_arbitary_obj(obj);
9439 if (!pd) return;
9440
9441 eina_inarray_push(pd->drop_target, &target);
9442 }
9443
9444 void
_drop_event_unregister(Eo * obj)9445 _drop_event_unregister(Eo *obj)
9446 {
9447 int idx = -1;
9448
9449 Efl_Ui_Win_Data *pd = _fetch_win_data_from_arbitary_obj(obj);
9450 if (!pd) return;
9451
9452 for (unsigned int i = 0; i < eina_inarray_count(pd->drop_target); ++i)
9453 {
9454 Ui_Dnd_Target *target = eina_inarray_nth(pd->drop_target, i);
9455 if (target->obj == obj)
9456 {
9457 //FIXME emit drop
9458 target->currently_inside = EINA_FALSE;
9459 idx = i;
9460 }
9461 }
9462 if (idx != -1)
9463 eina_inarray_remove_at(pd->drop_target, idx);
9464 }
9465
9466 void
_selection_changed_event_register(Eo * obj)9467 _selection_changed_event_register(Eo *obj)
9468 {
9469 Efl_Ui_Win_Data *pd = _fetch_win_data_from_arbitary_obj(obj);
9470 if (!pd) return;
9471
9472 eina_array_push(pd->selection_changed, obj);
9473 }
9474 void
_selection_changed_event_unregister(Eo * obj)9475 _selection_changed_event_unregister(Eo *obj)
9476 {
9477 Efl_Ui_Win_Data *pd = _fetch_win_data_from_arbitary_obj(obj);
9478 if (!pd) return;
9479
9480 eina_array_remove(pd->selection_changed, _remove, obj);
9481 }
9482 /* Internal EO APIs and hidden overrides */
9483
ELM_WIDGET_KEY_DOWN_DEFAULT_IMPLEMENT(efl_ui_win,Efl_Ui_Win_Data)9484 ELM_WIDGET_KEY_DOWN_DEFAULT_IMPLEMENT(efl_ui_win, Efl_Ui_Win_Data)
9485
9486 /* Internal EO APIs and hidden overrides */
9487
9488 #define EFL_UI_WIN_EXTRA_OPS \
9489 EFL_CANVAS_GROUP_ADD_DEL_OPS(efl_ui_win), \
9490 ELM_PART_CONTENT_DEFAULT_OPS(efl_ui_win), \
9491 EFL_OBJECT_OP_FUNC(efl_canvas_object_legacy_ctor, _efl_ui_win_efl_canvas_object_legacy_ctor)
9492
9493 #include "efl_ui_win.eo.c"
9494
9495 static void
9496 _efl_ui_win_legacy_class_constructor(Efl_Class *klass)
9497 {
9498 evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
9499 }
9500
9501 EOLIAN static Eo *
_efl_ui_win_legacy_efl_object_finalize(Eo * obj,void * pd EINA_UNUSED)9502 _efl_ui_win_legacy_efl_object_finalize(Eo *obj, void *pd EINA_UNUSED)
9503 {
9504 obj = efl_finalize(efl_super(obj, EFL_UI_WIN_LEGACY_CLASS));
9505 efl_canvas_object_type_set(obj, MY_CLASS_NAME_LEGACY);
9506 return obj;
9507 }
9508
9509
9510 Efl_Object *_efl_ui_win_legacy_efl_object_finalize(Eo *obj, void *pd);
9511
9512
9513 static Eina_Bool
_efl_ui_win_legacy_class_initializer(Efl_Class * klass)9514 _efl_ui_win_legacy_class_initializer(Efl_Class *klass)
9515 {
9516 const Efl_Object_Ops *opsp = NULL;
9517
9518 const Efl_Object_Property_Reflection_Ops *ropsp = NULL;
9519
9520 #ifndef EFL_UI_WIN_LEGACY_EXTRA_OPS
9521 #define EFL_UI_WIN_LEGACY_EXTRA_OPS
9522 #endif
9523
9524 EFL_OPS_DEFINE(ops,
9525 EFL_OBJECT_OP_FUNC(efl_finalize, _efl_ui_win_legacy_efl_object_finalize),
9526 EFL_UI_WIN_LEGACY_EXTRA_OPS
9527 );
9528 opsp = &ops;
9529
9530 return efl_class_functions_set(klass, opsp, ropsp);
9531 }
9532
9533 static const Efl_Class_Description _efl_ui_win_legacy_class_desc = {
9534 EO_VERSION,
9535 "Efl.Ui.Win_Legacy",
9536 EFL_CLASS_TYPE_REGULAR,
9537 0,
9538 _efl_ui_win_legacy_class_initializer,
9539 _efl_ui_win_legacy_class_constructor,
9540 NULL
9541 };
9542
9543 EFL_DEFINE_CLASS(efl_ui_win_legacy_class_get, &_efl_ui_win_legacy_class_desc, EFL_UI_WIN_CLASS, EFL_UI_LEGACY_INTERFACE, NULL);
9544
9545
9546 EAPI Evas_Object *
elm_win_add(Evas_Object * parent,const char * name,Elm_Win_Type type)9547 elm_win_add(Evas_Object *parent, const char *name, Elm_Win_Type type)
9548 {
9549 const Efl_Class *klass = EFL_UI_WIN_LEGACY_CLASS;
9550
9551 switch ((int) type)
9552 {
9553 case ELM_WIN_INLINED_IMAGE:
9554 klass = EFL_UI_WIN_INLINED_LEGACY_CLASS;
9555 break;
9556 case ELM_WIN_SOCKET_IMAGE:
9557 klass = EFL_UI_WIN_SOCKET_LEGACY_CLASS;
9558 break;
9559 default:
9560 break;
9561 }
9562
9563 return elm_legacy_add(klass, parent,
9564 efl_ui_win_name_set(efl_added, name),
9565 efl_ui_win_type_set(efl_added, (Efl_Ui_Win_Type)type));
9566 }
9567
9568
9569 EAPI Evas_Object *
elm_win_fake_add(Ecore_Evas * ee)9570 elm_win_fake_add(Ecore_Evas *ee)
9571 {
9572 return elm_legacy_add(EFL_UI_WIN_LEGACY_CLASS, NULL,
9573 _fake_canvas_set(efl_added, ee),
9574 efl_ui_win_name_set(efl_added, NULL),
9575 efl_ui_win_type_set(efl_added, EFL_UI_WIN_TYPE_FAKE));
9576 }
9577
9578 EAPI Evas_Object *
elm_win_util_standard_add(const char * name,const char * title)9579 elm_win_util_standard_add(const char *name, const char *title)
9580 {
9581 Evas_Object *win;
9582
9583 win = elm_legacy_add(EFL_UI_WIN_LEGACY_CLASS, NULL,
9584 efl_text_set(efl_added, title),
9585 efl_ui_win_name_set(efl_added, name),
9586 efl_ui_win_type_set(efl_added, EFL_UI_WIN_TYPE_BASIC));
9587 if (!win) return NULL;
9588
9589 _elm_win_standard_init(win);
9590 return win;
9591 }
9592
9593 EAPI Evas_Object *
elm_win_util_dialog_add(Evas_Object * parent,const char * name,const char * title)9594 elm_win_util_dialog_add(Evas_Object *parent, const char *name, const char *title)
9595 {
9596 Evas_Object *win;
9597
9598 win = elm_legacy_add(EFL_UI_WIN_LEGACY_CLASS, parent,
9599 efl_text_set(efl_added, title),
9600 efl_ui_win_name_set(efl_added, name),
9601 efl_ui_win_type_set(efl_added, EFL_UI_WIN_TYPE_DIALOG_BASIC));
9602 if (!win) return NULL;
9603
9604 _elm_win_standard_init(win);
9605 return win;
9606 }
9607
9608
9609 EAPI void
elm_win_keyboard_mode_set(Evas_Object * obj,Elm_Win_Keyboard_Mode mode)9610 elm_win_keyboard_mode_set(Evas_Object *obj, Elm_Win_Keyboard_Mode mode)
9611 {
9612 efl_ui_win_keyboard_mode_set(obj, (Efl_Ui_Win_Keyboard_Mode)mode);
9613 }
9614
9615 EAPI Elm_Win_Keyboard_Mode
elm_win_keyboard_mode_get(const Evas_Object * obj)9616 elm_win_keyboard_mode_get(const Evas_Object *obj)
9617 {
9618 return (Elm_Win_Keyboard_Mode)efl_ui_win_keyboard_mode_get(obj);
9619 }
9620
9621 EAPI void
elm_win_screen_constrain_set(Evas_Object * obj,Eina_Bool constrain)9622 elm_win_screen_constrain_set(Evas_Object *obj, Eina_Bool constrain)
9623 {
9624 efl_ui_win_screen_constrain_set(obj, constrain);
9625 }
9626
9627 EAPI Eina_Bool
elm_win_screen_constrain_get(const Evas_Object * obj)9628 elm_win_screen_constrain_get(const Evas_Object *obj)
9629 {
9630 return efl_ui_win_screen_constrain_get(obj);
9631 }
9632
9633 EAPI void
elm_win_prop_focus_skip_set(Evas_Object * obj,Eina_Bool skip)9634 elm_win_prop_focus_skip_set(Evas_Object *obj, Eina_Bool skip)
9635 {
9636 efl_ui_win_prop_focus_skip_set(obj, skip);
9637 }
9638
9639 EAPI void
elm_win_autohide_set(Evas_Object * obj,Eina_Bool autohide)9640 elm_win_autohide_set(Evas_Object *obj, Eina_Bool autohide)
9641 {
9642 efl_ui_win_autohide_set(obj, autohide);
9643 }
9644
9645 EAPI Eina_Bool
elm_win_autohide_get(const Evas_Object * obj)9646 elm_win_autohide_get(const Evas_Object *obj)
9647 {
9648 return efl_ui_win_autohide_get(obj);
9649 }
9650
9651 EAPI void
elm_win_exit_on_close_set(Evas_Object * obj,const Eina_Value * exit_code)9652 elm_win_exit_on_close_set(Evas_Object *obj, const Eina_Value *exit_code)
9653 {
9654 efl_ui_win_exit_on_close_set(obj, exit_code);
9655 }
9656
9657 EAPI const Eina_Value *
elm_win_exit_on_close_get(const Evas_Object * obj)9658 elm_win_exit_on_close_get(const Evas_Object *obj)
9659 {
9660 return efl_ui_win_exit_on_close_get(obj);
9661 }
9662
9663 EAPI void
elm_win_icon_object_set(Evas_Object * obj,Evas_Object * icon)9664 elm_win_icon_object_set(Evas_Object *obj, Evas_Object *icon)
9665 {
9666 efl_ui_win_icon_object_set(obj, icon);
9667 }
9668
9669 EAPI const Evas_Object *
elm_win_icon_object_get(const Evas_Object * obj)9670 elm_win_icon_object_get(const Evas_Object *obj)
9671 {
9672 return efl_ui_win_icon_object_get(obj);
9673 }
9674
9675 EAPI void
elm_win_iconified_set(Evas_Object * obj,Eina_Bool iconified)9676 elm_win_iconified_set(Evas_Object *obj, Eina_Bool iconified)
9677 {
9678 efl_ui_win_minimized_set(obj, iconified);
9679 }
9680
9681 EAPI Eina_Bool
elm_win_iconified_get(const Evas_Object * obj)9682 elm_win_iconified_get(const Evas_Object *obj)
9683 {
9684 return efl_ui_win_minimized_get(obj);
9685 }
9686
9687 EAPI void
elm_win_maximized_set(Evas_Object * obj,Eina_Bool maximized)9688 elm_win_maximized_set(Evas_Object *obj, Eina_Bool maximized)
9689 {
9690 efl_ui_win_maximized_set(obj, maximized);
9691 }
9692
9693 EAPI Eina_Bool
elm_win_maximized_get(const Evas_Object * obj)9694 elm_win_maximized_get(const Evas_Object *obj)
9695 {
9696 return efl_ui_win_maximized_get(obj);
9697 }
9698
9699 EAPI void
elm_win_fullscreen_set(Evas_Object * obj,Eina_Bool fullscreen)9700 elm_win_fullscreen_set(Evas_Object *obj, Eina_Bool fullscreen)
9701 {
9702 efl_ui_win_fullscreen_set(obj, fullscreen);
9703 }
9704
9705 EAPI Eina_Bool
elm_win_fullscreen_get(const Evas_Object * obj)9706 elm_win_fullscreen_get(const Evas_Object *obj)
9707 {
9708 return efl_ui_win_fullscreen_get(obj);
9709 }
9710
9711 EAPI void
elm_win_sticky_set(Evas_Object * obj,Eina_Bool sticky)9712 elm_win_sticky_set(Evas_Object *obj, Eina_Bool sticky)
9713 {
9714 efl_ui_win_sticky_set(obj, sticky);
9715 }
9716
9717 EAPI Eina_Bool
elm_win_sticky_get(const Evas_Object * obj)9718 elm_win_sticky_get(const Evas_Object *obj)
9719 {
9720 return efl_ui_win_sticky_get(obj);
9721 }
9722
9723 EAPI void
elm_win_noblank_set(Evas_Object * obj,Eina_Bool noblank)9724 elm_win_noblank_set(Evas_Object *obj, Eina_Bool noblank)
9725 {
9726 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
9727 EINA_SAFETY_ON_NULL_RETURN(sd);
9728 noblank = !!noblank;
9729 if (sd->noblank == noblank) return;
9730 sd->noblank = noblank;
9731 _win_noblank_eval();
9732 }
9733
9734 EAPI Eina_Bool
elm_win_noblank_get(const Evas_Object * obj)9735 elm_win_noblank_get(const Evas_Object *obj)
9736 {
9737 Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
9738 EINA_SAFETY_ON_NULL_RETURN_VAL(sd, EINA_FALSE);
9739 return sd->noblank;
9740 }
9741
9742 EAPI void
elm_win_borderless_set(Evas_Object * obj,Eina_Bool borderless)9743 elm_win_borderless_set(Evas_Object *obj, Eina_Bool borderless)
9744 {
9745 efl_ui_win_borderless_set(obj, borderless);
9746 }
9747
9748 EAPI Eina_Bool
elm_win_borderless_get(const Evas_Object * obj)9749 elm_win_borderless_get(const Evas_Object *obj)
9750 {
9751 return efl_ui_win_borderless_get(obj);
9752 }
9753
9754 EAPI void
elm_win_role_set(Evas_Object * obj,const char * role)9755 elm_win_role_set(Evas_Object *obj, const char *role)
9756 {
9757 efl_ui_win_role_set(obj, role);
9758 }
9759
9760 EAPI const char *
elm_win_role_get(const Evas_Object * obj)9761 elm_win_role_get(const Evas_Object *obj)
9762 {
9763 return efl_ui_win_role_get(obj);
9764 }
9765
9766 EAPI const char *
elm_win_name_get(const Evas_Object * obj)9767 elm_win_name_get(const Evas_Object *obj)
9768 {
9769 return efl_ui_win_name_get(obj);
9770 }
9771
9772 EAPI Elm_Win_Type
elm_win_type_get(const Evas_Object * obj)9773 elm_win_type_get(const Evas_Object *obj)
9774 {
9775 if (!(efl_isa(obj, EFL_UI_WIN_CLASS) ||
9776 efl_isa(obj, EFL_UI_WIN_LEGACY_CLASS) ||
9777 efl_isa(obj, EFL_UI_WIN_INLINED_CLASS))) return ELM_WIN_UNKNOWN;
9778
9779 return _efl_ui_win_type_to_elm_win_type(efl_ui_win_type_get(obj));
9780 }
9781
9782 EAPI const char *
elm_win_accel_preference_get(const Evas_Object * obj)9783 elm_win_accel_preference_get(const Evas_Object *obj)
9784 {
9785 return efl_ui_win_accel_preference_get(obj);
9786 }
9787
9788 EAPI void
elm_win_alpha_set(Evas_Object * obj,Eina_Bool alpha)9789 elm_win_alpha_set(Evas_Object *obj, Eina_Bool alpha)
9790 {
9791 efl_ui_win_alpha_set(obj, alpha);
9792 }
9793
9794 EAPI Eina_Bool
elm_win_alpha_get(const Evas_Object * obj)9795 elm_win_alpha_get(const Evas_Object *obj)
9796 {
9797 return efl_ui_win_alpha_get(obj);
9798 }
9799
9800 EAPI void
elm_win_activate(Evas_Object * obj)9801 elm_win_activate(Evas_Object *obj)
9802 {
9803 efl_ui_win_activate(obj);
9804 }
9805
9806 EAPI void
elm_win_center(Evas_Object * obj,Eina_Bool h,Eina_Bool v)9807 elm_win_center(Evas_Object *obj, Eina_Bool h, Eina_Bool v)
9808 {
9809 efl_ui_win_center(obj, h, v);
9810 }
9811
9812 EAPI Eina_Bool
elm_win_move_resize_start(Evas_Object * obj,Elm_Win_Move_Resize_Mode mode)9813 elm_win_move_resize_start(Evas_Object *obj, Elm_Win_Move_Resize_Mode mode)
9814 {
9815 return efl_ui_win_move_resize_start(obj, (Efl_Ui_Win_Move_Resize_Mode)mode);
9816 }
9817
9818 EAPI void
elm_win_focus_highlight_animate_set(Efl_Ui_Win * obj,Eina_Bool animate)9819 elm_win_focus_highlight_animate_set(Efl_Ui_Win *obj, Eina_Bool animate)
9820 {
9821 efl_ui_win_focus_highlight_animate_set(obj, animate);
9822 }
9823
9824 EAPI Eina_Bool
elm_win_focus_highlight_animate_get(const Efl_Ui_Win * obj)9825 elm_win_focus_highlight_animate_get(const Efl_Ui_Win *obj)
9826 {
9827 return efl_ui_win_focus_highlight_animate_get(obj);
9828 }
9829
9830 EAPI void
elm_win_focus_highlight_enabled_set(Efl_Ui_Win * obj,Eina_Bool enabled)9831 elm_win_focus_highlight_enabled_set(Efl_Ui_Win *obj, Eina_Bool enabled)
9832 {
9833 efl_ui_win_focus_highlight_enabled_set(obj, enabled);
9834 }
9835
9836 EAPI Eina_Bool
elm_win_focus_highlight_enabled_get(const Efl_Ui_Win * obj)9837 elm_win_focus_highlight_enabled_get(const Efl_Ui_Win *obj)
9838 {
9839 return efl_ui_win_focus_highlight_enabled_get(obj);
9840 }
9841
9842 EAPI Eina_Bool
elm_win_focus_highlight_style_set(Efl_Ui_Win * obj,const char * style)9843 elm_win_focus_highlight_style_set(Efl_Ui_Win *obj, const char *style)
9844 {
9845 return efl_ui_win_focus_highlight_style_set(obj, style);
9846 }
9847
9848 EAPI const char *
elm_win_focus_highlight_style_get(const Efl_Ui_Win * obj)9849 elm_win_focus_highlight_style_get(const Efl_Ui_Win *obj)
9850 {
9851 return efl_ui_win_focus_highlight_style_get(obj);
9852 }
9853
9854 EAPI Efl_Ui_Shared_Win_Data*
efl_ui_win_shared_data_get(Efl_Ui_Win * obj)9855 efl_ui_win_shared_data_get(Efl_Ui_Win *obj)
9856 {
9857 Efl_Ui_Win_Data *pd = efl_data_scope_safe_get(obj, MY_CLASS);
9858 EINA_SAFETY_ON_NULL_RETURN_VAL(pd, NULL);
9859
9860 return &pd->spd;
9861 }
9862
9863 EAPI void
efl_ui_win_autodel_set(Efl_Ui_Win * obj,Eina_Bool autodel)9864 efl_ui_win_autodel_set(Efl_Ui_Win *obj, Eina_Bool autodel)
9865 {
9866 elm_win_autodel_set(obj, autodel);
9867 }
9868
9869 EAPI Eina_Bool
efl_ui_win_autodel_get(const Efl_Ui_Win * obj)9870 efl_ui_win_autodel_get(const Efl_Ui_Win *obj)
9871 {
9872 return elm_win_autodel_get(obj);
9873 }
9874