diff --git a/data/elementary/themes/colorclasses.edc b/data/elementary/themes/colorclasses.edc index f273d3458e..5c2a572237 100644 --- a/data/elementary/themes/colorclasses.edc +++ b/data/elementary/themes/colorclasses.edc @@ -390,6 +390,10 @@ color_classes { color: 64 64 64 255; desc: "Background color of a standard window"; } + color_class { "elm/win/blocker"; + color: 32 32 32 128; + desc: "Overlay color for windows with modal children (blocked)"; + } // modules color_class { name: "module_label"; diff --git a/data/elementary/themes/edc/elm/border.edc b/data/elementary/themes/edc/elm/border.edc index 481dc930bf..5b2b6bce22 100644 --- a/data/elementary/themes/edc/elm/border.edc +++ b/data/elementary/themes/edc/elm/border.edc @@ -114,6 +114,7 @@ group { name: "elm/border/base/default"; fixed: 0 1; } } + /* application contents - spacer and clipper (without main menu) */ spacer { "client_spacer"; desc { "default"; @@ -129,6 +130,7 @@ group { name: "elm/border/base/default"; rel.to: "client_spacer"; } } + /* application contents */ swallow { "elm.swallow.client"; clip: "client_clip"; @@ -136,6 +138,26 @@ group { name: "elm/border/base/default"; rel.to: "client_spacer"; } } + + /* modal window blocker */ + rect { "elm.rect.blocker"; + required; + desc { "default"; + rel1.to: "top_clip"; + rel1.relative: 0.0 1.0; + rel2.to: "bottom_clip"; + rel2.relative: 1.0 0.0; + color: 0 0 0 0; + hid; + } + desc { "visible"; + inherit: "default"; + color_class: "elm/win/blocker"; + color: 255 255 255 255; + vis; + } + } + /* top title bar - spacer and clipper */ rect { "top_clip"; //nomouse; desc { "default"; @@ -793,6 +815,20 @@ group { name: "elm/border/base/default"; target: "elm.swallow.menu"; } + /* modal windows */ + program { name: "hide_blocker"; + signal: "elm,action,hide_blocker"; source: "elm"; + action: STATE_SET "default" 0.0; + target: "elm.rect.blocker"; + transition: DECELERATE 0.2; + } + program { name: "show_blocker"; + signal: "elm,action,show_blocker"; source: "elm"; + action: STATE_SET "visible" 0.0; + target: "elm.rect.blocker"; + transition: DECELERATE 0.2; + } + /* minimize, maximize & close buttons */ program { signal: "mouse,down,*"; source: "elm.event.close"; diff --git a/data/elementary/themes/edc/elm/win.edc b/data/elementary/themes/edc/elm/win.edc index 44ae634386..8c6a08dd83 100644 --- a/data/elementary/themes/edc/elm/win.edc +++ b/data/elementary/themes/edc/elm/win.edc @@ -1,39 +1,13 @@ group { name: "elm/win/base/default"; + data.item: "elm_win_version" "119"; parts { rect { "client_clip"; nomouse; desc { "default"; - rel1.to_y: "elm.swallow.contents"; - rel2.to_y: "elm.swallow.contents"; + rel.to: "elm.swallow.contents"; } } swallow { "elm.swallow.contents"; clip_to: "client_clip"; } - rect { "blocker"; - desc { "default"; - rel1.relative : 0.0 0.0; - rel2.relative : 1.0 1.0; - color: 64 64 64 150; - visible: 0; - } - desc { "visible"; - inherit: "default"; - visible: 1; - } - } - } - programs { - program { name: "hide_blocker"; - signal: "elm,action,hide_blocker"; - source: "elm"; - action: STATE_SET "default" 0.0; - target: "blocker"; - } - program { name: "show_blocker"; - signal: "elm,action,show_blocker"; - source: "elm"; - action: STATE_SET "visible" 0.0; - target: "blocker"; - } } } diff --git a/src/lib/elementary/efl_ui_win.c b/src/lib/elementary/efl_ui_win.c index d7a4296ff9..20481d48e8 100644 --- a/src/lib/elementary/efl_ui_win.c +++ b/src/lib/elementary/efl_ui_win.c @@ -56,38 +56,6 @@ static const Elm_Win_Trap *trap = NULL; if (!obj || !efl_isa(obj, MY_CLASS)) \ return -#define DECREMENT_MODALITY() \ - EINA_LIST_FOREACH(_elm_win_list, l, current) \ - { \ - ELM_WIN_DATA_GET_OR_RETURN(current, cursd); \ - if ((obj != current) && (cursd->modal_count > 0)) \ - { \ - cursd->modal_count--; \ - } \ - if (cursd->modal_count == 0) \ - { \ - edje_object_signal_emit(cursd->legacy.edje, \ - "elm,action,hide_blocker", "elm"); \ - efl_event_callback_legacy_call(cursd->main_menu, ELM_MENU_EVENT_ELM_ACTION_UNBLOCK_MENU, NULL); \ - } \ - } - -#define INCREMENT_MODALITY() \ - EINA_LIST_FOREACH(_elm_win_list, l, current) \ - { \ - ELM_WIN_DATA_GET_OR_RETURN(current, cursd); \ - if (obj != current) \ - { \ - cursd->modal_count++; \ - } \ - if (cursd->modal_count > 0) \ - { \ - edje_object_signal_emit(cursd->legacy.edje, \ - "elm,action,show_blocker", "elm"); \ - efl_event_callback_legacy_call(cursd->main_menu, EFL_UI_WIN_EVENT_ELM_ACTION_BLOCK_MENU, NULL); \ - } \ - } - #define ENGINE_GET() (_elm_preferred_engine ? _elm_preferred_engine : _elm_config->engine) typedef struct _Efl_Ui_Win_Data Efl_Ui_Win_Data; @@ -2140,6 +2108,64 @@ _deferred_ecore_evas_free(void *data) _elm_win_deferred_free--; } +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"); + int v = version ? atoi(version) : 0; + if (v < 119) + { + DBG("Detected legacy theme (<1.19) for modal window blocker."); + return sd->legacy.edje; + } + return sd->frame_obj; +} + +static void +_elm_win_modality_increment(Efl_Ui_Win_Data *modalsd) +{ + Efl_Ui_Win *current; + Eina_List *l; + + EINA_LIST_FOREACH(_elm_win_list, l, current) + { + ELM_WIN_DATA_GET_OR_RETURN(current, cursd); + if (modalsd != cursd) + cursd->modal_count++; + if (cursd->modal_count > 0) + { + Edje_Object *ed = _elm_win_modal_blocker_edje_get(cursd); + edje_object_signal_emit(ed, "elm,action,show_blocker", "elm"); + efl_event_callback_legacy_call + (cursd->main_menu, EFL_UI_WIN_EVENT_ELM_ACTION_BLOCK_MENU, NULL); + _elm_win_frame_style_update(cursd, 0, 1); + } + } +} + +static void +_elm_win_modality_decrement(Efl_Ui_Win_Data *modalsd) +{ + Efl_Ui_Win *current; + Eina_List *l; + + EINA_LIST_FOREACH(_elm_win_list, l, current) + { + ELM_WIN_DATA_GET_OR_RETURN(current, cursd); + if ((modalsd != cursd) && (cursd->modal_count > 0)) + cursd->modal_count--; + if (cursd->modal_count == 0) + { + Edje_Object *ed = _elm_win_modal_blocker_edje_get(cursd); + edje_object_signal_emit(ed, "elm,action,hide_blocker", "elm"); + efl_event_callback_legacy_call + (cursd->main_menu, ELM_MENU_EVENT_ELM_ACTION_UNBLOCK_MENU, NULL); + _elm_win_frame_style_update(cursd, 0, 1); + } + } +} + static void _efl_ui_win_show(Eo *obj, Efl_Ui_Win_Data *sd) { @@ -2156,11 +2182,7 @@ _efl_ui_win_show(Eo *obj, Efl_Ui_Win_Data *sd) } if ((sd->modal) && (!evas_object_visible_get(obj))) - { - const Eina_List *l; - Evas_Object *current; - INCREMENT_MODALITY() - } + _elm_win_modality_increment(sd); if (!evas_object_visible_get(obj)) do_eval = EINA_TRUE; efl_gfx_visible_set(efl_super(obj, MY_CLASS), EINA_TRUE); @@ -2208,11 +2230,7 @@ _efl_ui_win_hide(Eo *obj, Efl_Ui_Win_Data *sd) _elm_win_state_eval_queue(); if ((sd->modal) && (evas_object_visible_get(obj))) - { - const Eina_List *l; - Evas_Object *current; - DECREMENT_MODALITY() - } + _elm_win_modality_decrement(sd); efl_gfx_visible_set(efl_super(obj, MY_CLASS), EINA_FALSE); TRAP(sd, hide); @@ -2654,13 +2672,8 @@ _elm_win_img_callbacks_del(Evas_Object *obj, Evas_Object *imgobj) EOLIAN static void _efl_ui_win_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Win_Data *sd) { - const Eina_List *l; - Evas_Object *current; - if ((sd->modal) && (evas_object_visible_get(obj))) - { - DECREMENT_MODALITY() - } + _elm_win_modality_decrement(sd); if ((sd->modal) && (sd->modal_count > 0)) ERR("Deleted modal win was blocked by another modal win which was created after creation of that win."); @@ -5482,17 +5495,10 @@ _efl_ui_win_modal_set(Eo *obj, Efl_Ui_Win_Data *sd, Efl_Ui_Win_Modal_Mode modal) if (sd->modal_count) return; - const Eina_List *l; - Evas_Object *current; - if ((modal_tmp) && (!sd->modal) && (evas_object_visible_get(obj))) - { - INCREMENT_MODALITY() - } + _elm_win_modality_increment(sd); else if ((!modal_tmp) && (sd->modal) && (evas_object_visible_get(obj))) - { - DECREMENT_MODALITY() - } + _elm_win_modality_decrement(sd); sd->modal = modal_tmp; TRAP(sd, modal_set, modal_tmp);