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, &centered, 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