From ef5bfbad2647dbc990465e0d71c559f1605f8c04 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Thu, 11 Jun 2015 11:35:44 -0400 Subject: [PATCH] add compositor visibility effects and matching configuration these are specific types of animation for use when toggling window visibility. they combine with existing compositor window animations to provide nicer integration for very specific types of windows see https://www.youtube.com/watch?v=hIVdd0Z2K00 for a demo --- src/bin/e_comp_cfdata.c | 2 ++ src/bin/e_comp_cfdata.h | 1 + src/bin/e_comp_object.c | 27 ++++++++++++++++-- src/bin/e_int_config_comp_match.c | 60 +++++++++++++++++++++++++++++++++++++-- 4 files changed, 85 insertions(+), 5 deletions(-) diff --git a/src/bin/e_comp_cfdata.c b/src/bin/e_comp_cfdata.c index 1b022c3..b315ff0 100644 --- a/src/bin/e_comp_cfdata.c +++ b/src/bin/e_comp_cfdata.c @@ -24,6 +24,7 @@ e_comp_cfdata_edd_init(E_Config_DD **conf_edd, E_Config_DD **match_edd) E_CONFIG_VAL(D, T, urgent, CHAR); E_CONFIG_VAL(D, T, no_shadow, CHAR); E_CONFIG_VAL(D, T, shadow_style, STR); + E_CONFIG_VAL(D, T, effect, STR); *conf_edd = E_CONFIG_DD_NEW("Comp_Config", E_Comp_Config); #undef T @@ -204,6 +205,7 @@ e_comp_cfdata_match_free(E_Comp_Match *m) eina_stringshare_del(m->clas); eina_stringshare_del(m->role); eina_stringshare_del(m->shadow_style); + eina_stringshare_del(m->effect); free(m); } diff --git a/src/bin/e_comp_cfdata.h b/src/bin/e_comp_cfdata.h index f9558e4..b50454b 100644 --- a/src/bin/e_comp_cfdata.h +++ b/src/bin/e_comp_cfdata.h @@ -62,6 +62,7 @@ struct _E_Comp_Match const char *role; // glob - used for borders const char *shadow_style; // shadow style to use + const char *effect; // effect to use when showing and hiding int primary_type; // Ecore_X_Window_Type - used for borders, overrides, first one found - ECORE_X_WINDOW_TYPE_UNKNOWN if not to be used char borderless; // used for borders, 0 == dont use, 1 == borderless, -1 == not borderless diff --git a/src/bin/e_comp_object.c b/src/bin/e_comp_object.c index fa9d7ee..6690398 100644 --- a/src/bin/e_comp_object.c +++ b/src/bin/e_comp_object.c @@ -75,6 +75,7 @@ typedef struct _E_Comp_Object Eina_Stringshare *frame_theme; Eina_Stringshare *frame_name; + Eina_Stringshare *effect; //effect when toggling visibility Evas_Object *smart_obj; // smart object Evas_Object *clip; // clipper over effect object @@ -503,6 +504,8 @@ _e_comp_object_shadow_setup(E_Comp_Object *cw) if (!ok) ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf); } + if (ok && m->effect) + eina_stringshare_refplace(&cw->effect, m->effect); if (ok) break; } } @@ -654,14 +657,16 @@ _e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char * if (cw->animating) { cw->animating--; - e_comp->animating--; + if (!cw->animating) + e_comp->animating--; /* remove ref from animation start, account for possibility of deletion from unref */ if (!e_object_unref(E_OBJECT(cw->ec))) return; } + if (cw->animating) return; /* hide only after animation finishes to guarantee a full run of the animation */ - if (cw->defer_hide && (!strcmp(emission, "e,action,hide,done"))) + if (cw->defer_hide && ((!strcmp(emission, "e,action,hide,done")) || (!strcmp(emission, "e,action,done")))) evas_object_hide(cw->smart_obj); - else if (!cw->animating) + else e_comp_shape_queue(); } @@ -1291,6 +1296,14 @@ _e_comp_intercept_hide(void *data, Evas_Object *obj) e_comp->animating++; cw->animating++; e_object_ref(E_OBJECT(cw->ec)); + if (cw->effect) + { + cw->animating++; + e_object_ref(E_OBJECT(cw->ec)); + e_comp_object_effect_set(obj, cw->effect); + e_comp_object_effect_params_set(obj, 0, (int[]){0}, 1); + e_comp_object_effect_start(obj, _e_comp_object_done_defer, cw); + } } cw->defer_hide = !!cw->animating; if (!cw->animating) @@ -2026,6 +2039,14 @@ _e_comp_smart_show(Evas_Object *obj) e_comp->animating++; cw->animating++; e_object_ref(E_OBJECT(cw->ec)); + if (cw->effect) + { + cw->animating++; + e_object_ref(E_OBJECT(cw->ec)); + e_comp_object_effect_set(obj, cw->effect); + e_comp_object_effect_params_set(obj, 0, (int[]){1}, 1); + e_comp_object_effect_start(obj, _e_comp_object_done_defer, cw); + } } /* ensure some random effect doesn't lock the client offscreen */ if (!cw->animating) diff --git a/src/bin/e_int_config_comp_match.c b/src/bin/e_int_config_comp_match.c index 80a4013..4d7c763 100644 --- a/src/bin/e_int_config_comp_match.c +++ b/src/bin/e_int_config_comp_match.c @@ -8,6 +8,7 @@ typedef struct _Match_Config char *title, *name, *clas, *role; int borderless, dialog, accepts_focus; int argb, fullscreen, modal, primary_type; + int effect_type; } Match_Config; struct _E_Config_Dialog_Data @@ -17,6 +18,7 @@ struct _E_Config_Dialog_Data Eina_List *overrides; // used for client menus, tooltips etc. Eina_List *menus; // used for e menus Eina_List *objects; // used for e objects + Eina_List *comp_effects; // list of visibility effects int changed; Evas_Object *edit_il; @@ -39,6 +41,7 @@ _match_dup(E_Comp_Match *m, Match_Config *m2) m2->primary_type = m2->match.primary_type; m2->match.shadow_style = eina_stringshare_ref(m2->match.shadow_style); + m2->match.effect = eina_stringshare_ref(m2->match.effect); } static void @@ -49,6 +52,7 @@ _match_free(Match_Config *m) eina_stringshare_del(m->match.clas); eina_stringshare_del(m->match.role); eina_stringshare_del(m->match.shadow_style); + eina_stringshare_del(m->match.effect); free(m->title); free(m->name); free(m->clas); @@ -65,6 +69,7 @@ _match_dup2(Match_Config *m2, E_Comp_Match *m) m->clas = eina_stringshare_add(m->clas); m->role = eina_stringshare_add(m->role); m->shadow_style = eina_stringshare_add(m->shadow_style); + m->effect = eina_stringshare_add(m->effect); } static const char * @@ -147,6 +152,12 @@ _match_label_get(Match_Config *m) eina_strbuf_append(buf, _("Style:")); eina_strbuf_append(buf, m->match.shadow_style); } + if (m->match.effect) + { + eina_strbuf_append(buf, _(" / ")); + eina_strbuf_append(buf, _("Effect:")); + eina_strbuf_append(buf, m->match.effect); + } if (!eina_strbuf_length_get(buf)) return _("Unknown"); @@ -236,7 +247,8 @@ _edit_ok(void *d1, void *d2) Evas_Object *dia, *bg, *of = d2; Evas_Object *il; - if (m->title || m->name || m->clas || m->role || (m->primary_type != m->match.primary_type)) + if (m->title || m->name || m->clas || m->role || (m->primary_type != m->match.primary_type) || + (eina_list_nth(m->cfd->cfdata->comp_effects, m->effect_type) != m->match.effect)) { m->cfd->cfdata->changed = 1; e_config_dialog_changed_set(m->cfd, 1); @@ -271,6 +283,9 @@ _edit_ok(void *d1, void *d2) m->match.fullscreen = m->fullscreen; m->match.modal = m->modal; m->match.primary_type = m->primary_type; + eina_stringshare_refplace(&m->match.effect, eina_list_nth(m->cfd->cfdata->comp_effects, m->effect_type)); + if (eina_streq(m->match.effect, "none")) + eina_stringshare_replace(&m->match.effect, NULL); il = m->cfd->cfdata->edit_il; { const Eina_List *l; @@ -322,7 +337,9 @@ _create_edit_frame(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdat { Evas_Object *of, *oi, *lb, *en, *bt, *tb, *tab2, *o, *sf, *li; E_Radio_Group *rg; - int row; + Eina_List *l; + Eina_Stringshare *s; + int row, mode = 0; int x, y, w, h, mw, mh; o = edje_object_add(evas); @@ -534,6 +551,32 @@ _create_edit_frame(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdat e_widget_toolbook_page_append(tb, NULL, _("Style"), oi, 1, 1, 1, 1, 0.5, 0.0); + oi = e_widget_list_add(evas, 1, 0); + EINA_LIST_FOREACH(cfdata->comp_effects->next, l, s) + { + m->effect_type++; + if (s == m->match.effect) + break; + } + if (!s) m->effect_type = 0; + rg = e_widget_radio_group_new(&(m->effect_type)); + EINA_LIST_FOREACH(cfdata->comp_effects, l, s) + { + char *p; + const char *pp; + char buf[PATH_MAX]; + + pp = strchr(s, '/'); + pp = pp ? pp + 1 : s; + p = memcpy(buf, pp, strlen(pp) + 1); + p[0] = toupper(p[0]); + o = e_widget_radio_add(evas, _(p), mode, rg); + e_widget_list_object_append(oi, o, 1, 0, 0.5); + mode++; + } + e_widget_toolbook_page_append(tb, NULL, _("Effect"), oi, + 1, 1, 1, 1, 0.5, 0.0); + e_widget_frametable_object_append(of, tb, 0, 0, 1, 1, 1, 1, 1, 1); e_widget_toolbook_page_show(tb, 0); @@ -823,6 +866,7 @@ _create_data(E_Config_Dialog *cfd) { E_Config_Dialog_Data *cfdata; Eina_List *l; + Eina_Stringshare *grp; E_Comp_Match *m; Match_Config *m2; E_Comp_Config *conf = e_comp_config_get(); @@ -868,7 +912,19 @@ _create_data(E_Config_Dialog *cfd) m2->cfd = cfd; cfdata->objects = eina_list_append(cfdata->objects, m2); } + cfdata->comp_effects = e_theme_collection_items_find("base/theme/borders", "e/comp/effects/visibility"); + /* comp effects must be prefixed with "visibility" or they won't work and things will break! */ + EINA_LIST_FOREACH(cfdata->comp_effects, l, grp) + { + Eina_Stringshare *g; + char buf[1024]; + snprintf(buf, sizeof(buf), "visibility/%s", grp); + g = eina_stringshare_add(buf); + eina_stringshare_del(grp); + eina_list_data_set(l, g); + } + cfdata->comp_effects = eina_list_prepend(cfdata->comp_effects, eina_stringshare_add("none")); return cfdata; } -- 2.7.4