win: Implement stronger theme compatibility for frame_obj

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
This commit is contained in:
Jean-Philippe Andre 2016-12-07 19:27:05 +09:00
parent be7e8f6513
commit bdb4977dda
6 changed files with 82 additions and 20 deletions

View File

@ -7,7 +7,7 @@
*/ */
group { name: "elm/bg/base/default"; group { name: "elm/bg/base/default";
data.item: "elm_bg_version" "119"; data.item: "version" "119";
images.image: "bevel_dark_out.png" COMP; images.image: "bevel_dark_out.png" COMP;
parts { parts {
part { name: "base"; type: RECT; part { name: "base"; type: RECT;

View File

@ -30,6 +30,7 @@ group { name: "elm/border/base/default";
images.image: "screen_circular_shadow.png" COMP; images.image: "screen_circular_shadow.png" COMP;
images.image: "win_shadow.png" COMP; images.image: "win_shadow.png" COMP;
data.item: "shadow" "1"; data.item: "shadow" "1";
data.item: "version" "119";
parts { parts {
/* opaque region of the window, to inform the compositor */ /* opaque region of the window, to inform the compositor */
spacer { "elm.spacer.opaque"; spacer { "elm.spacer.opaque";

View File

@ -1,5 +1,5 @@
group { name: "elm/win/base/default"; group { name: "elm/win/base/default";
data.item: "elm_win_version" "119"; data.item: "version" "119";
parts { parts {
rect { "client_clip"; nomouse; rect { "client_clip"; nomouse;
desc { "default"; desc { "default";

View File

@ -28,6 +28,8 @@
#define MY_CLASS_NAME "Efl.Ui.Win" #define MY_CLASS_NAME "Efl.Ui.Win"
#define MY_CLASS_NAME_LEGACY "elm_win" #define MY_CLASS_NAME_LEGACY "elm_win"
#define FRAME_OBJ_THEME_MIN_VERSION 119
static const Elm_Win_Trap *trap = NULL; static const Elm_Win_Trap *trap = NULL;
#define TRAP(sd, name, ...) \ #define TRAP(sd, name, ...) \
@ -2150,9 +2152,9 @@ static inline Edje_Object *
_elm_win_modal_blocker_edje_get(Efl_Ui_Win_Data *sd) _elm_win_modal_blocker_edje_get(Efl_Ui_Win_Data *sd)
{ {
/* Legacy theme compatibility */ /* 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; 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."); DBG("Detected legacy theme (<1.19) for modal window blocker.");
return sd->legacy.edje; 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); 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 static void
_elm_win_frame_add(Efl_Ui_Win_Data *sd, const char *style) _elm_win_frame_add(Efl_Ui_Win_Data *sd, const char *style)
{ {
Evas_Object *obj = sd->obj; Evas_Object *obj = sd->obj;
int w, h, mw, mh; int w, h, mw, mh, v;
/* short layer; */ const char *version;
if (sd->frame_obj) return; if (sd->frame_obj) return;
sd->frame_obj = edje_object_add(sd->evas); sd->frame_obj = edje_object_add(sd->evas);
/* layer = evas_object_layer_get(obj); */
/* evas_object_layer_set(sd->frame_obj, layer + 1); */ // Verify theme version. Border requires an exact theme API.
if (!elm_widget_theme_object_set version = elm_theme_data_get(elm_widget_theme_get(sd->obj), "version");
(sd->obj, sd->frame_obj, "border", "base", style)) v = version ? atoi(version) : 0;
if (EINA_LIKELY(v >= FRAME_OBJ_THEME_MIN_VERSION))
{ {
ELM_SAFE_FREE(sd->frame_obj, evas_object_del); if (!elm_widget_theme_object_set
return; (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. /* 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); wd = efl_data_scope_get(bg, ELM_WIDGET_CLASS);
if (wd) 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; 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); evas_object_del(bg);
} }

View File

@ -403,7 +403,7 @@ Eina_Bool _elm_theme_icon_set(Elm_Theme *th,
Evas_Object *o, Evas_Object *o,
const char *group, const char *group,
const char *style); const char *style);
Eina_Bool _elm_theme_parse(Elm_Theme *th, void _elm_theme_parse(Elm_Theme *th,
const char *theme); const char *theme);
void _elm_theme_shutdown(void); void _elm_theme_shutdown(void);

View File

@ -45,12 +45,14 @@ _elm_theme_item_finalize(Elm_Theme_Files *files,
if (istheme) if (istheme)
{ {
char *version; char *version;
int v;
if (!(version = edje_mmap_data_get(f, "version"))) return; 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); free(version);
return;
} }
free(version); 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); 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); snprintf(buf2, sizeof(buf2), "elm/%s/%s/default", clas, group);
if (!eina_hash_find(th->cache_style_load_failed, buf2)) if (!eina_hash_find(th->cache_style_load_failed, buf2))
{ {
@ -385,7 +387,7 @@ _elm_theme_icon_set(Elm_Theme *th,
return w > 0; return w > 0;
} }
Eina_Bool void
_elm_theme_parse(Elm_Theme *th, const char *theme) _elm_theme_parse(Elm_Theme *th, const char *theme)
{ {
Eina_List *names = NULL; Eina_List *names = NULL;
@ -459,7 +461,6 @@ _elm_theme_parse(Elm_Theme *th, const char *theme)
EINA_LIST_FREE(names, p) EINA_LIST_FREE(names, p)
_elm_theme_file_item_add(&th->themes, p, EINA_FALSE, EINA_TRUE); _elm_theme_file_item_add(&th->themes, p, EINA_FALSE, EINA_TRUE);
return EINA_TRUE;
} }
void void