win: Implement stronger theme compatibility for frame_obj
authorJean-Philippe Andre <jp.andre@samsung.com>
Wed, 7 Dec 2016 10:27:05 +0000 (19:27 +0900)
committerJean-Philippe Andre <jp.andre@samsung.com>
Thu, 8 Dec 2016 07:13:32 +0000 (16:13 +0900)
The frame object requires a theme of version 119 or more. In fact
I think until we are totally happy with the window API (for EO) we
might want to bump that version regularly. That would indeed disallow
theme customization for border.edc until it's done.

This patch uses a pretty brute force way to set the theme file to
the default file from EFL installation. elm_config is not reliable
here.

This is very custom made and there may be a more generic way to force
a widget to use a minimum theme version. Yes that could mean ugly
widgets if we change the theme API but at least that would make them
work. Note that the border theme contains no visual elements, so the
colors of the background, etc... should all depend on the user
selected theme. But of course CSD (in Wayland) will have to use the
default theme -- and look grey.

Fixes D4976

data/elementary/themes/edc/elm/bg.edc
data/elementary/themes/edc/elm/border.edc
data/elementary/themes/edc/elm/win.edc
src/lib/elementary/efl_ui_win.c
src/lib/elementary/elm_priv.h
src/lib/elementary/elm_theme.c

index 0254099e6ef27277353e77f30d705deec8346d00..ed5034f92d038a1d9fd5cdb5f8ef1fc21f020863 100644 (file)
@@ -7,7 +7,7 @@
 */
 
 group { name: "elm/bg/base/default";
-   data.item: "elm_bg_version" "119";
+   data.item: "version" "119";
    images.image: "bevel_dark_out.png" COMP;
    parts {
       part { name: "base"; type: RECT;
index 3ff013b596fda5b28fecbf07ec2d9142f71908a4..18cc44b268dbf975139fe60d5c1b7b145f0c47c6 100644 (file)
@@ -30,6 +30,7 @@ group { name: "elm/border/base/default";
    images.image: "screen_circular_shadow.png" COMP;
    images.image: "win_shadow.png" COMP;
    data.item: "shadow" "1";
+   data.item: "version" "119";
    parts {
       /* opaque region of the window, to inform the compositor */
       spacer { "elm.spacer.opaque";
index 8c6a08dd833feccd1f8f0bd58a23c5321c4efe64..a9c98a0bfa4b2c45855807b9c6814e4e1cd982b1 100644 (file)
@@ -1,5 +1,5 @@
 group { name: "elm/win/base/default";
-   data.item: "elm_win_version" "119";
+   data.item: "version" "119";
    parts {
       rect { "client_clip"; nomouse;
          desc { "default";
index 75aa1d0c7cac41201e0f8f829b0405c2a2934ed8..1dab8de4c0d350d9097ffe3382639ee587c0b93b 100644 (file)
@@ -28,6 +28,8 @@
 #define MY_CLASS_NAME "Efl.Ui.Win"
 #define MY_CLASS_NAME_LEGACY "elm_win"
 
+#define FRAME_OBJ_THEME_MIN_VERSION 119
+
 static const Elm_Win_Trap *trap = NULL;
 
 #define TRAP(sd, name, ...)                                             \
@@ -2150,9 +2152,9 @@ static inline Edje_Object *
 _elm_win_modal_blocker_edje_get(Efl_Ui_Win_Data *sd)
 {
    /* Legacy theme compatibility */
-   const char *version = edje_object_data_get(sd->legacy.edje, "elm_win_version");
+   const char *version = edje_object_data_get(sd->legacy.edje, "version");
    int v = version ? atoi(version) : 0;
-   if (v < 119)
+   if (v < FRAME_OBJ_THEME_MIN_VERSION)
      {
         DBG("Detected legacy theme (<1.19) for modal window blocker.");
         return sd->legacy.edje;
@@ -4071,22 +4073,79 @@ _elm_object_part_cursor_set(Evas_Object *obj, Evas_Object *edj,
    elm_object_sub_cursor_set(sub, obj, cursor);
 }
 
+static char *
+_efl_system_theme_path_get(void)
+{
+   // Find the default theme from EFL install. Quite ugly.
+   const char *sysdir;
+   char *version;
+   char path[PATH_MAX];
+   int v;
+
+   sysdir = elm_theme_system_dir_get();
+   if (!sysdir) return NULL;
+
+   eina_file_path_join(path, PATH_MAX, sysdir, "default.edj");
+   version = edje_file_data_get(path, "version");
+   v = version ? atoi(version) : 0;
+   free(version);
+   if (v < FRAME_OBJ_THEME_MIN_VERSION)
+     {
+        ERR("Default system theme is too old, something is wrong with your installation of EFL.");
+        return NULL;
+     }
+
+   return strdup(path);
+}
+
 static void
 _elm_win_frame_add(Efl_Ui_Win_Data *sd, const char *style)
 {
    Evas_Object *obj = sd->obj;
-   int w, h, mw, mh;
-   /* short layer; */
+   int w, h, mw, mh, v;
+   const char *version;
 
    if (sd->frame_obj) return;
+
    sd->frame_obj = edje_object_add(sd->evas);
-   /* layer = evas_object_layer_get(obj); */
-   /* evas_object_layer_set(sd->frame_obj, layer + 1); */
-   if (!elm_widget_theme_object_set
-       (sd->obj, sd->frame_obj, "border", "base", style))
+
+   // Verify theme version. Border requires an exact theme API.
+   version = elm_theme_data_get(elm_widget_theme_get(sd->obj), "version");
+   v = version ? atoi(version) : 0;
+   if (EINA_LIKELY(v >= FRAME_OBJ_THEME_MIN_VERSION))
      {
-        ELM_SAFE_FREE(sd->frame_obj, evas_object_del);
-        return;
+        if (!elm_widget_theme_object_set
+            (sd->obj, sd->frame_obj, "border", "base", style))
+          {
+             ERR("Failed to set main border theme for the window.");
+             ELM_SAFE_FREE(sd->frame_obj, evas_object_del);
+             return;
+          }
+
+        // Verify border.edc version as well
+        version = edje_object_data_get(sd->frame_obj, "version");
+        v = version ? atoi(version) : 0;
+     }
+
+   if (v < FRAME_OBJ_THEME_MIN_VERSION)
+     {
+        // Theme compatibility
+        const char *key = "elm/border/base/default"; // FIXME?
+        char *sys_theme;
+
+        WRN("Selected theme does not support the required border theme API "
+            "(version = %d, requires >= %d).",
+            v, FRAME_OBJ_THEME_MIN_VERSION);
+        sys_theme = _efl_system_theme_path_get();
+        if (!sys_theme ||
+            !edje_object_file_set(sd->frame_obj, sys_theme, key))
+          {
+             ERR("Failed to set main border theme for the window.");
+             ELM_SAFE_FREE(sd->frame_obj, evas_object_del);
+             free(sys_theme);
+             return;
+          }
+        free(sys_theme);
      }
 
    /* Small hack: The special value 2 means this is the top frame object.
@@ -6318,9 +6377,10 @@ _elm_win_bg_must_swallow(Efl_Ui_Win_Data *sd)
         wd = efl_data_scope_get(bg, ELM_WIDGET_CLASS);
         if (wd)
           {
-             version = edje_object_data_get(wd->resize_obj, "elm_bg_version");
+             version = edje_object_data_get(wd->resize_obj, "version");
              v = version ? atoi(version) : 0;
-             if (v >= 119) sd->legacy.bg_must_swallow = 0;
+             if (v >= FRAME_OBJ_THEME_MIN_VERSION)
+               sd->legacy.bg_must_swallow = 0;
           }
         evas_object_del(bg);
      }
index a50d2ed9fa4cdfb5fb68f271b33ffb18bd1178fa..320e775b1d306b1eca5482f3c257e58c7be092e0 100644 (file)
@@ -403,7 +403,7 @@ Eina_Bool            _elm_theme_icon_set(Elm_Theme *th,
                                          Evas_Object *o,
                                          const char *group,
                                          const char *style);
-Eina_Bool            _elm_theme_parse(Elm_Theme *th,
+void                 _elm_theme_parse(Elm_Theme *th,
                                       const char *theme);
 void                 _elm_theme_shutdown(void);
 
index 50f98684b45a1d22bbd33c730b35926cf73aaadb..f7a24514f3feb57ea022bc7f3597faa694b69f0e 100644 (file)
@@ -45,12 +45,14 @@ _elm_theme_item_finalize(Elm_Theme_Files *files,
    if (istheme)
      {
         char *version;
+        int v;
 
         if (!(version = edje_mmap_data_get(f, "version"))) return;
-        if (atoi(version) < 110) // bump this version number when we need to
+        v = atoi(version);
+        if (v < 110) // bump this version number when we need to
           {
+             WRN("Selected theme is too old (version = %d, needs >= 110)", v);
              free(version);
-             return;
           }
         free(version);
      }
@@ -321,7 +323,7 @@ _elm_theme_set(Elm_Theme *th, Evas_Object *o, const char *clas, const char *grou
         eina_hash_add(th->cache_style_load_failed, buf2, (void *)1);
      }
 
-   //Use the elementary default theme.
+   // Use the elementary default style.
    snprintf(buf2, sizeof(buf2), "elm/%s/%s/default", clas, group);
    if (!eina_hash_find(th->cache_style_load_failed, buf2))
      {
@@ -385,7 +387,7 @@ _elm_theme_icon_set(Elm_Theme *th,
    return w > 0;
 }
 
-Eina_Bool
+void
 _elm_theme_parse(Elm_Theme *th, const char *theme)
 {
    Eina_List *names = NULL;
@@ -459,7 +461,6 @@ _elm_theme_parse(Elm_Theme *th, const char *theme)
 
    EINA_LIST_FREE(names, p)
      _elm_theme_file_item_add(&th->themes, p, EINA_FALSE, EINA_TRUE);
-   return EINA_TRUE;
 }
 
 void