Add APIs for floating mode (app-in-app)
[framework/uifw/elementary.git] / src / lib / elm_win.c
index 32cbc6e..3379763 100644 (file)
@@ -19,48 +19,53 @@ struct _Elm_Win
    Elm_Win_Type type;
    Elm_Win_Keyboard_Mode kbdmode;
    Elm_Win_Indicator_Mode indmode;
-   struct {
-      const char *info;
-      Ecore_Timer *timer;
-      int repeat_count;
-      int shot_counter;
-   } shot;
+   Elm_Win_Indicator_Opacity_Mode ind_o_mode;
+   struct
+     {
+        const char *info;
+        Ecore_Timer *timer;
+        int repeat_count;
+        int shot_counter;
+     } shot;
    int resize_location;
    int *autodel_clear, rot;
    int show_count;
-   struct {
-      int x, y;
-   } screen;
-   struct 
+   struct
+     {
+        int x, y;
+     } screen;
+   struct
      {
         Ecore_Evas *ee;
         Evas *evas;
         Evas_Object *obj, *hot_obj;
         int hot_x, hot_y;
      } pointer;
-   struct {
-      Evas_Object *top;
+   struct
+     {
+        Evas_Object *top;
 
-      struct {
-         Evas_Object *target;
-         Eina_Bool visible : 1;
-         Eina_Bool handled : 1;
-      } cur, prev;
+        struct
+          {
+             Evas_Object *target;
+             Eina_Bool visible : 1;
+             Eina_Bool handled : 1;
+          } cur, prev;
 
-      const char *style;
-      Ecore_Job *reconf_job;
+        const char *style;
+        Ecore_Job *reconf_job;
 
-      Eina_Bool enabled : 1;
-      Eina_Bool changed_theme : 1;
-      Eina_Bool top_animate : 1;
-      Eina_Bool geometry_changed : 1;
-   } focus_highlight;
+        Eina_Bool enabled : 1;
+        Eina_Bool changed_theme : 1;
+        Eina_Bool top_animate : 1;
+        Eina_Bool geometry_changed : 1;
+     } focus_highlight;
 
    Evas_Object *icon;
    const char *title;
    const char *icon_name;
    const char *role;
-   
+
    double aspect;
    Eina_Bool urgent : 1;
    Eina_Bool modal : 1;
@@ -74,6 +79,7 @@ struct _Elm_Win
    Eina_Bool fullscreen : 1;
    Eina_Bool maximized : 1;
    Eina_Bool skip_focus : 1;
+   Eina_Bool floating : 1;
 };
 
 static const char *widtype = NULL;
@@ -167,7 +173,7 @@ _shot_delay_get(Elm_Win *win)
                   *pd = *p;
                }
              *pd = 0;
-             v = atof(d);
+             v = _elm_atof(d);
              free(d);
              return v;
           }
@@ -351,7 +357,7 @@ _elm_win_resize(Ecore_Evas *ee)
    win->deferred_resize_job = ecore_job_add(_elm_win_resize_job, win);
 }
 
-static void 
+static void
 _elm_win_mouse_in(Ecore_Evas *ee)
 {
    Evas_Object *obj;
@@ -416,7 +422,7 @@ _elm_win_focus_out(Ecore_Evas *ee)
      }
 }
 
-static void 
+static void
 _elm_win_state_change(Ecore_Evas *ee)
 {
    Evas_Object *obj;
@@ -428,7 +434,7 @@ _elm_win_state_change(Ecore_Evas *ee)
    Eina_Bool ch_maximized = EINA_FALSE;
 
    if (!(obj = ecore_evas_object_associate_get(ee))) return;
-   
+
    if (!(win = elm_widget_data_get(obj))) return;
 
    if (win->withdrawn != ecore_evas_withdrawn_get(win->ee))
@@ -493,20 +499,19 @@ _elm_win_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_O
 {
    Elm_Win *wd = elm_widget_data_get(obj);
    const Eina_List *items;
+   const Eina_List *list;
    void *(*list_data_get) (const Eina_List *list);
 
    if (!wd)
      return EINA_FALSE;
+   list = elm_widget_sub_object_list_get(obj);
 
    /* Focus chain */
-   if (wd->subobjs)
+   if (list)
      {
         if (!(items = elm_widget_focus_custom_chain_get(obj)))
-          {
-             items = wd->subobjs;
-             if (!items)
-               return EINA_FALSE;
-          }
+          items = list;
+
         list_data_get = eina_list_data_get;
 
         elm_widget_focus_list_next_get(obj, items, list_data_get, dir, next);
@@ -514,7 +519,6 @@ _elm_win_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_O
         if (*next)
           return EINA_TRUE;
      }
-
    *next = (Evas_Object *)obj;
    return EINA_FALSE;
 }
@@ -547,22 +551,22 @@ _elm_win_event_cb(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_T
              return EINA_TRUE;
           }
         else if ((!strcmp(ev->keyname, "Left")) ||
-                 (!strcmp(ev->keyname, "KP_Left")))
+                 ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string)))
           {
              //TODO : woohyun jung
           }
         else if ((!strcmp(ev->keyname, "Right")) ||
-                 (!strcmp(ev->keyname, "KP_Right")))
+                 ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string)))
           {
              //TODO : woohyun jung
           }
         else if ((!strcmp(ev->keyname, "Up")) ||
-                 (!strcmp(ev->keyname, "KP_Up")))
+                 ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string)))
           {
              //TODO : woohyun jung
           }
         else if ((!strcmp(ev->keyname, "Down")) ||
-                 (!strcmp(ev->keyname, "KP_Down")))
+                 ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string)))
           {
              //TODO : woohyun jung
           }
@@ -611,7 +615,7 @@ static void
 _elm_win_obj_callback_del(void *data, Evas *e, Evas_Object *obj, void *event_info __UNUSED__)
 {
    Elm_Win *win = data;
-   Evas_Object *child;
+   Evas_Object *child, *child2 = NULL;
 
    if (win->parent)
      {
@@ -633,15 +637,36 @@ _elm_win_obj_callback_del(void *data, Evas *e, Evas_Object *obj, void *event_inf
    if (win->shot.timer) ecore_timer_del(win->shot.timer);
    evas_object_event_callback_del_full(win->win_obj, EVAS_CALLBACK_DEL,
                                        _elm_win_obj_callback_del, win);
-   while (((child = evas_object_bottom_get(win->evas))) &&
-          (child != obj))
-     {
-        evas_object_del(child);
-     }
-   while (((child = evas_object_top_get(win->evas))) &&
-          (child != obj))
+   child = evas_object_bottom_get(win->evas);
+   while (child)
      {
-        evas_object_del(child);
+        /* if the object we see *IS* the window object (because we are
+         * faking a parent object inside the canvas), then skip it and
+         * go to the next one */
+        if (child == obj)
+          {
+             child = evas_object_above_get(child);
+             if (!child) break;
+          }
+        /* if we are using the next object above from the previous loop */
+        if (child == child2)
+          {
+             /* this object has refcounts from the previous loop */
+             child2 = evas_object_above_get(child);
+             if (child2) evas_object_ref(child2);
+             evas_object_del(child);
+             /* so unref from previous loop */
+             evas_object_unref(child);
+             child = child2;
+          }
+        else
+          {
+             /* just delete as normal (probably only first object */
+             child2 = evas_object_above_get(child);
+             if (child2) evas_object_ref(child2);
+             evas_object_del(child);
+             child = child2;
+          }
      }
 #ifdef HAVE_ELEMENTARY_X
    if (win->client_message_handler)
@@ -675,7 +700,7 @@ _elm_win_obj_callback_del(void *data, Evas *e, Evas_Object *obj, void *event_inf
    if (win->icon_name) eina_stringshare_del(win->icon_name);
    if (win->role) eina_stringshare_del(win->role);
    if (win->icon) evas_object_del(win->icon);
-   
+
    free(win);
 
    if ((!_elm_win_list) &&
@@ -772,6 +797,8 @@ _elm_win_obj_callback_move(void *data, Evas *e __UNUSED__, Evas_Object *obj, voi
         evas_object_geometry_get(obj, &x, &y, NULL, NULL);
         win->screen.x = x;
         win->screen.y = y;
+
+        /* FIXME: We should update ecore_wl_window_location here !! */
      }
    else if (win->img_obj)
      {
@@ -912,7 +939,7 @@ static void
 _elm_win_xwin_update(Elm_Win *win)
 {
    const char *s;
-   
+
    _elm_win_xwindow_get(win);
    if (win->parent)
      {
@@ -937,7 +964,7 @@ _elm_win_xwin_update(Elm_Win *win)
 
    s = win->role;
    if (s) ecore_x_icccm_window_role_set(win->xwin, s);
-   
+
    // set window icon
    if (win->icon)
      {
@@ -950,16 +977,16 @@ _elm_win_xwin_update(Elm_Win *win)
              int w = 0, h = 0, stride, x, y;
              unsigned char *p;
              unsigned int *p2;
-             
+
              evas_object_image_size_get(win->icon, &w, &h);
              stride = evas_object_image_stride_get(win->icon);
-             if ((w > 0) && (h > 0) && 
+             if ((w > 0) && (h > 0) &&
                  (stride >= (int)(w * sizeof(unsigned int))))
                {
                   ic.width = w;
                   ic.height = h;
                   ic.data = malloc(w * h * sizeof(unsigned int));
-                  
+
                   if (ic.data)
                     {
                        p = (unsigned char *)data;
@@ -972,7 +999,7 @@ _elm_win_xwin_update(Elm_Win *win)
                                  p += sizeof(unsigned int);
                                  p2++;
                               }
-                            p += (stride - (w * sizeof(unsigned int))); 
+                            p += (stride - (w * sizeof(unsigned int)));
                          }
                        ecore_x_netwm_icons_set(win->xwin, &ic, 1);
                        free(ic.data);
@@ -981,7 +1008,7 @@ _elm_win_xwin_update(Elm_Win *win)
              evas_object_image_data_set(win->icon, data);
           }
      }
-   
+
    switch (win->type)
      {
       case ELM_WIN_BASIC:
@@ -1508,7 +1535,7 @@ the_end:
    win->focus_highlight.prev = win->focus_highlight.cur;
 }
 
-static void 
+static void
 _elm_win_frame_add(Elm_Win *win, const char *style)
 {
    evas_output_framespace_set(win->evas, 0, 22, 0, 26);
@@ -1519,19 +1546,19 @@ _elm_win_frame_add(Elm_Win *win, const char *style)
    evas_object_move(win->frame_obj, 0, 0);
    evas_object_resize(win->frame_obj, 1, 1);
 
-   edje_object_signal_callback_add(win->frame_obj, "elm,action,move,start", 
+   edje_object_signal_callback_add(win->frame_obj, "elm,action,move,start",
                                    "elm", _elm_win_frame_cb_move_start, win);
-   edje_object_signal_callback_add(win->frame_obj, "elm,action,resize,start", 
+   edje_object_signal_callback_add(win->frame_obj, "elm,action,resize,start",
                                    "*", _elm_win_frame_cb_resize_start, win);
-   edje_object_signal_callback_add(win->frame_obj, "elm,action,minimize", 
+   edje_object_signal_callback_add(win->frame_obj, "elm,action,minimize",
                                    "elm", _elm_win_frame_cb_minimize, win);
-   edje_object_signal_callback_add(win->frame_obj, "elm,action,maximize", 
+   edje_object_signal_callback_add(win->frame_obj, "elm,action,maximize",
                                    "elm", _elm_win_frame_cb_maximize, win);
-   edje_object_signal_callback_add(win->frame_obj, "elm,action,close", 
+   edje_object_signal_callback_add(win->frame_obj, "elm,action,close",
                                    "elm", _elm_win_frame_cb_close, win);
 }
 
-static void 
+static void
 _elm_win_frame_cb_move_start(void *data, Evas_Object *obj __UNUSED__, const char *sig __UNUSED__, const char *source __UNUSED__)
 {
    Elm_Win *win;
@@ -1539,11 +1566,16 @@ _elm_win_frame_cb_move_start(void *data, Evas_Object *obj __UNUSED__, const char
    if (!(win = data)) return;
    /* FIXME: Change mouse pointer */
 
-   /* NB: 0,0 are dummy values. Wayland handles the move by itself */
-   ecore_evas_move(win->ee, 0, 0);
+   /* NB: Wayland handles moving surfaces by itself so we cannot 
+    * specify a specific x/y we want. Instead, we will pass in the 
+    * existing x/y values so they can be recorded as 'previous' position. 
+    * The new position will get updated automatically when the move is 
+    * finished */
+
+   ecore_evas_wayland_move(win->ee, win->screen.x, win->screen.y);
 }
 
-static void 
+static void
 _elm_win_frame_cb_resize_start(void *data, Evas_Object *obj __UNUSED__, const char *sig __UNUSED__, const char *source)
 {
    Elm_Win *win;
@@ -1577,7 +1609,7 @@ _elm_win_frame_cb_resize_start(void *data, Evas_Object *obj __UNUSED__, const ch
      ecore_evas_wayland_resize(win->ee, win->resize_location);
 }
 
-static void 
+static void
 _elm_win_frame_cb_minimize(void *data, Evas_Object *obj __UNUSED__, const char *sig __UNUSED__, const char *source __UNUSED__)
 {
    Elm_Win *win;
@@ -1587,7 +1619,7 @@ _elm_win_frame_cb_minimize(void *data, Evas_Object *obj __UNUSED__, const char *
    ecore_evas_iconified_set(win->ee, EINA_TRUE);
 }
 
-static void 
+static void
 _elm_win_frame_cb_maximize(void *data, Evas_Object *obj __UNUSED__, const char *sig __UNUSED__, const char *source __UNUSED__)
 {
    Elm_Win *win;
@@ -1598,7 +1630,7 @@ _elm_win_frame_cb_maximize(void *data, Evas_Object *obj __UNUSED__, const char *
    ecore_evas_maximized_set(win->ee, win->maximized);
 }
 
-static void 
+static void
 _elm_win_frame_cb_close(void *data, Evas_Object *obj __UNUSED__, const char *sig __UNUSED__, const char *source __UNUSED__)
 {
    Elm_Win *win;
@@ -1608,7 +1640,7 @@ _elm_win_frame_cb_close(void *data, Evas_Object *obj __UNUSED__, const char *sig
 }
 
 /*
-static void 
+static void
 _elm_win_pointer_add(Elm_Win *win, const char *style)
 {
    int mw, mh;
@@ -1743,13 +1775,13 @@ elm_win_add(Evas_Object *parent, const char *name, Elm_Win_Type type)
          CRITICAL(engine " engine creation failed. Trying default.");   \
          win->ee = ecore_evas_new(NULL, 0, 0, 1, 1, NULL);              \
          if (win->ee)                                                   \
-            elm_engine_set(ecore_evas_engine_name_get(win->ee));        \
+            elm_config_preferred_engine_set(ecore_evas_engine_name_get(win->ee)); \
    } while (0)
 #define ENGINE_COMPARE(name) (_elm_preferred_engine && !strcmp(_elm_preferred_engine, name))
 
    win->kbdmode = ELM_WIN_KEYBOARD_UNKNOWN;
    win->indmode = ELM_WIN_INDICATOR_UNKNOWN;
-   
+
    switch (type)
      {
       case ELM_WIN_INLINED_IMAGE:
@@ -1891,7 +1923,7 @@ elm_win_add(Evas_Object *parent, const char *name, Elm_Win_Type type)
           {
              win->ee = ecore_evas_ews_new(0, 0, 1, 1);
           }
-        else if (ENGINE_COMPARE(ELM_WAYLAND_SHM)) 
+        else if (ENGINE_COMPARE(ELM_WAYLAND_SHM))
           {
              win->ee = ecore_evas_wayland_shm_new(NULL, 0, 0, 0, 1, 1, 0);
             win->evas = ecore_evas_get(win->ee);
@@ -1899,7 +1931,7 @@ elm_win_add(Evas_Object *parent, const char *name, Elm_Win_Type type)
              _elm_win_frame_add(win, "default");
 //             _elm_win_pointer_add(win, "default");
           }
-        else if (ENGINE_COMPARE(ELM_WAYLAND_EGL)) 
+        else if (ENGINE_COMPARE(ELM_WAYLAND_EGL))
           {
              win->ee = ecore_evas_wayland_egl_new(NULL, 0, 0, 0, 1, 1, 0);
             win->evas = ecore_evas_get(win->ee);
@@ -1955,7 +1987,7 @@ elm_win_add(Evas_Object *parent, const char *name, Elm_Win_Type type)
    evas_object_layer_set(win->win_obj, 50);
    evas_object_pass_events_set(win->win_obj, EINA_TRUE);
 
-   if (win->frame_obj) 
+   if (win->frame_obj)
      {
         evas_object_clip_set(win->win_obj, win->frame_obj);
         evas_object_stack_below(win->frame_obj, win->win_obj);
@@ -2103,7 +2135,7 @@ elm_win_title_set(Evas_Object *obj, const char *title)
    eina_stringshare_replace(&(win->title), title);
    ecore_evas_title_set(win->ee, win->title);
    if (win->frame_obj)
-     edje_object_part_text_set(win->frame_obj, "elm.text.title", win->title);
+     edje_object_part_text_escaped_set(win->frame_obj, "elm.text.title", win->title);
 }
 
 EAPI const char *
@@ -2362,46 +2394,6 @@ elm_win_alpha_get(const Evas_Object *obj)
    return ecore_evas_alpha_get(win->ee);
 }
 
-EINA_DEPRECATED EAPI void
-elm_win_transparent_set(Evas_Object *obj, Eina_Bool transparent)
-{
-   Elm_Win *win;
-   ELM_CHECK_WIDTYPE(obj, widtype);
-   win = elm_widget_data_get(obj);
-   if (!win) return;
-
-   if (win->frame_obj)
-     {
-     }
-   else if (win->img_obj)
-     {
-        evas_object_image_alpha_set(win->img_obj, transparent);
-     }
-   else
-     {
-#ifdef HAVE_ELEMENTARY_X
-        if (win->xwin)
-          {
-             ecore_evas_transparent_set(win->ee, transparent);
-             _elm_win_xwin_update(win);
-          }
-        else
-#endif
-           ecore_evas_transparent_set(win->ee, transparent);
-     }
-}
-
-EINA_DEPRECATED EAPI Eina_Bool
-elm_win_transparent_get(const Evas_Object *obj)
-{
-   Elm_Win *win;
-   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
-   win = elm_widget_data_get(obj);
-   if (!win) return EINA_FALSE;
-
-   return ecore_evas_transparent_get(win->ee);
-}
-
 EAPI void
 elm_win_override_set(Evas_Object *obj, Eina_Bool override)
 {
@@ -2794,6 +2786,13 @@ elm_win_keyboard_win_get(const Evas_Object *obj)
    return EINA_FALSE;
 }
 
+// WRAPPER: Temperary added.
+EAPI void
+elm_win_indicator_state_set(Evas_Object *obj, Elm_Win_Indicator_Mode mode)
+{
+   elm_win_indicator_mode_set(obj, mode);
+}
+
 EAPI void
 elm_win_indicator_mode_set(Evas_Object *obj, Elm_Win_Indicator_Mode mode)
 {
@@ -2819,6 +2818,13 @@ elm_win_indicator_mode_set(Evas_Object *obj, Elm_Win_Indicator_Mode mode)
 #endif
 }
 
+// WRAPPER: Temperary added.
+EAPI Elm_Win_Indicator_Mode
+elm_win_indicator_state_get(const Evas_Object *obj)
+{
+   return elm_win_indicator_mode_get(obj);
+}
+
 EAPI Elm_Win_Indicator_Mode
 elm_win_indicator_mode_get(const Evas_Object *obj)
 {
@@ -2830,6 +2836,43 @@ elm_win_indicator_mode_get(const Evas_Object *obj)
 }
 
 EAPI void
+elm_win_indicator_opacity_set(Evas_Object *obj, Elm_Win_Indicator_Opacity_Mode mode)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+   if (mode == win->ind_o_mode) return;
+   win->ind_o_mode = mode;
+#ifdef HAVE_ELEMENTARY_X
+   _elm_win_xwindow_get(win);
+   if (win->xwin)
+     {
+        if (win->ind_o_mode == ELM_WIN_INDICATOR_OPAQUE)
+          ecore_x_e_illume_indicator_opacity_set
+          (win->xwin, ECORE_X_ILLUME_INDICATOR_OPAQUE);
+        else if (win->ind_o_mode == ELM_WIN_INDICATOR_TRANSLUCENT)
+          ecore_x_e_illume_indicator_opacity_set
+          (win->xwin, ECORE_X_ILLUME_INDICATOR_TRANSLUCENT);
+        else if (win->ind_o_mode == ELM_WIN_INDICATOR_TRANSPARENT)
+          ecore_x_e_illume_indicator_opacity_set
+          (win->xwin, ECORE_X_ILLUME_INDICATOR_TRANSPARENT);
+
+     }
+#endif
+}
+
+EAPI Elm_Win_Indicator_Opacity_Mode
+elm_win_indicator_opacity_get(const Evas_Object *obj)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype) ELM_WIN_INDICATOR_OPACITY_UNKNOWN;
+   win = elm_widget_data_get(obj);
+   if (!win) return ELM_WIN_INDICATOR_OPACITY_UNKNOWN;
+   return win->ind_o_mode;
+}
+
+EAPI void
 elm_win_screen_position_get(const Evas_Object *obj, int *x, int *y)
 {
    Elm_Win *win;
@@ -3218,7 +3261,7 @@ _elm_inwin_text_set_hook(Evas_Object *obj, const char *item, const char *text)
    Widget_Data *wd = elm_widget_data_get(obj);
 
    if (!wd || !item) return;
-   edje_object_part_text_set(wd->frm, item, text);
+   edje_object_part_text_escaped_set(wd->frm, item, text);
    _sizing_eval(obj);
 }
 
@@ -3369,13 +3412,13 @@ elm_win_socket_listen(Evas_Object *obj, const char *svcname, int svcnum, Eina_Bo
    if (!win) return EINA_FALSE;
    if (!win->ee) return EINA_FALSE;
 
-   if(!ecore_evas_extn_socket_listen(win->ee, svcname, svcnum, svcsys))
+   if (!ecore_evas_extn_socket_listen(win->ee, svcname, svcnum, svcsys))
      return EINA_FALSE;
 
    return EINA_TRUE;
 }
 
-/* windowing spcific calls - shall we do this differently? */
+/* windowing specific calls - shall we do this differently? */
 
 static Ecore_X_Window
 _elm_ee_win_get(const Evas_Object *obj)
@@ -3405,3 +3448,40 @@ elm_win_xwindow_get(const Evas_Object *obj)
 #endif
    return 0;
 }
+
+EAPI void
+elm_win_floating_mode_set(Evas_Object *obj, Eina_Bool floating)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+   if (floating == win->floating) return;
+#ifdef HAVE_ELEMENTARY_X
+   _elm_win_xwindow_get(win);
+#endif
+   win->floating = floating;
+#ifdef HAVE_ELEMENTARY_X
+   if (win->xwin)
+     {
+        if (win->floating)
+          ecore_x_e_illume_window_state_set
+             (win->xwin, ECORE_X_ILLUME_WINDOW_STATE_FLOATING);
+        else
+          ecore_x_e_illume_window_state_set
+             (win->xwin, ECORE_X_ILLUME_WINDOW_STATE_NORMAL);
+     }
+#endif
+}
+
+EAPI Eina_Bool
+elm_win_floating_mode_get(const Evas_Object *obj)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   win = elm_widget_data_get(obj);
+   if (!win) return EINA_FALSE;
+
+   return win->floating;
+}
+