elm: Prepare new API for windows, including CSD on X11

This series of patches include:
1. Add experimental Client-Side Decorations (CSD) mode for
   windows on X11 (enabled with EFL_WIN_FRAME_MODE=on).
2. Use Efl.Part to set the content and background of a window.
3. Begin moving elm_win_resize_object APIs to a legacy-only
   set of features.
4. Add a new stacked box class.
5. Fix modal windows.

More patches will follow, to implement support for the conformant
features right inside elm_win, as well as polish existing features.

I am merging this now in order to spot and fix compatibility issues
as early as possible. This patch indeed reworks a lot how the
window and its edje groups work together.

Unfortunately, unless we created a new Window class, the complexity
of the code inside efl_ui_win.c has to increase. On the other hand,
all windows now have a frame object, except fake windows, which
redudes some of the differences between X11 and Wayland.

CSD are not used by default, as their support is still not complete
on X, and totally unimplemented on other platforms (OSX, MS Windows,
etc...). Eventually we could think of moving all windows to use CSD
mode like GTK3 does nowadays.

Note: The theme ABI is changed A LOT, so this may break compatibility
with older themes (I have tested a bit, though^^).

@feature
This commit is contained in:
Jean-Philippe Andre 2016-11-23 13:07:18 +09:00
commit 5173b0d59e
34 changed files with 2527 additions and 1730 deletions

View File

@ -106,6 +106,7 @@ elementary/themes/edc/elm/cursor.edc \
elementary/themes/edc/elm/dayselector.edc \
elementary/themes/edc/elm/diskselector.edc \
elementary/themes/edc/elm/entry.edc \
elementary/themes/edc/elm/ews.edc \
elementary/themes/edc/elm/fileselector.edc \
elementary/themes/edc/elm/flipselector.edc \
elementary/themes/edc/elm/focus.edc \

View File

@ -386,6 +386,14 @@ color_classes {
color: FN_COL_DISABLE;
desc: "Text of a disabled multibuttonentry item";
}
color_class { "elm/win/background";
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";

View File

@ -4,7 +4,7 @@ externals.external: "elm";
// theme api version. from 1.10 on we will check version to avoid
// compat issues
data.item: "version" "110";
data.item: "version" "119";
collections {
#include "fonts.edc"
@ -73,6 +73,7 @@ collections {
#include "edc/elm/hover.edc"
#include "edc/elm/cursor.edc"
#include "edc/elm/code.edc"
#include "edc/elm/ews.edc"
// desktop in general
#include "edc/wallpaper.edc"

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,722 @@
group { name: "elm/ews/background/default";
images.image: "bg_radgrad.png" COMP;
images.image: "dot_pattern.png" COMP;
parts {
part { name: "bg";
description { state: "default" 0.0;
image.normal: "bg_radgrad.png";
image.scale_hint: STATIC;
fill.smooth: 0;
ASPECT_FILL((1024/653))
}
}
part { name: "pat";
description { state: "default" 0.0;
image.normal: "dot_pattern.png";
TILED_PATTERN(256, 256)
}
}
}
}
group { name: "elm/ews/decoration/default";
images.image: "win_shadow.png" COMP;
images.image: "win_glow.png" COMP;
images.image: "vgrad_med_lighter.png" COMP;
images.image: "vgrad_med_dark.png" COMP;
images.image: "bevel_out.png" COMP;
images.image: "shine.png" COMP;
images.image: "bevel_dark_out.png" COMP;
images.image: "sym_close_dark_normal.png" COMP;
images.image: "sym_close_dark_selected.png" COMP;
images.image: "sym_close_light_normal.png" COMP;
images.image: "sym_close_light_selected.png" COMP;
images.image: "sym_down_dark_normal.png" COMP;
images.image: "sym_down_dark_selected.png" COMP;
images.image: "sym_down_light_normal.png" COMP;
images.image: "sym_down_light_selected.png" COMP;
images.image: "sym_up_dark_normal.png" COMP;
images.image: "sym_up_dark_selected.png" COMP;
images.image: "sym_up_light_normal.png" COMP;
images.image: "sym_up_light_selected.png" COMP;
images.image: "glow_round_corners_small.png" COMP;
images.image: "knob_round_small_busy.png" COMP;
parts {
part { name: "shadow"; mouse_events: 0;
description { state: "default" 0.0;
rel1.to: "top";
rel2.to: "bottom";
WIN_SHADOW;
}
description { state: "hidden" 0.0;
inherit: "default" 0.0;
visible: 0;
}
}
part { name: "glow"; mouse_events: 0;
description { state: "default" 0.0;
image.normal: "win_glow.png";
image.border: 9 9 9 9;
image.middle: 0;
rel1.offset: -5 -5;
rel1.to: "top";
rel2.offset: 4 4;
rel2.to: "bottom";
fill.smooth: 0;
color: 255 255 255 0;
visible: 0;
}
description { state: "focused" 0.0;
inherit: "default" 0.0;
color: 255 255 255 255;
visible: 1;
}
}
part { name: "top";
description { state: "default" 0.0;
color_class: "border_top";
image.normal: "vgrad_med_lighter.png";
rel1.to_y: "title2";
rel1.offset: -1 0;
rel2.relative: 1.0 0.0;
fill.smooth: 0;
TILED_HORIZ(120)
}
description { state: "focused" 0.0;
inherit: "default" 0.0;
image.normal: "vgrad_med_dark.png";
}
}
part { name: "bevel"; mouse_events: 0;
description { state: "default" 0.0;
image.normal: "bevel_out.png";
image.border: 1 1 1 1;
image.middle: 0;
rel1.to: "top";
rel2.to: "top";
fill.smooth: 0;
}
}
part { name: "elm.text.title"; type: TEXT;
scale: 1; nomouse;
effect: SHADOW BOTTOM;
description { state: "default" 0.0;
color_class: "border_title";
rel1.relative: 1.0 0.0;
rel1.offset: 1 -3;
rel1.to_x: "e.event.icon";
rel2.relative: 0.0 0.0;
rel2.offset: -2 -3;
rel2.to_x: "e.event.minimize";
align: 0.5 0.0;
color_class: "border_title";
color3: 255 255 255 255;
text { font: FNBD; size: 10;
text_class: "title_bar";
align: 0.5 0.0;
min: 0 1;
}
fixed: 0 1;
}
description { state: "focused" 0.0;
inherit: "default" 0.0;
visible: 0;
}
}
part { name: "title2"; type: TEXT;
scale: 1; nomouse;
effect: SOFT_SHADOW BOTTOM;
description { state: "default" 0.0;
color_class: "border_title_active";
rel1.relative: 1.0 0.0;
rel1.offset: 1 2;
rel1.to_x: "e.event.icon";
rel2.relative: 0.0 0.0;
rel2.offset: -1 2;
rel2.to_x: "e.event.minimize";
align: 0.5 0.0;
color_class: "border_title_active";
color3: 255 255 255 255;
text { font: FNBD; size: 10;
text_source: "elm.text.title";
text_class: "title_bar";
align: 0.5 0.0;
min: 0 1;
}
fixed: 0 1;
visible: 0;
}
description { state: "focused" 0.0;
inherit: "default" 0.0;
visible: 1;
}
}
part { name: "icon"; type: SPACER;
description { state: "default" 0.0;
rel1.to: "e.event.icon";
rel2.to: "e.event.icon";
}
description { state: "bounce1" 0.0;
inherit: "default" 0.0;
rel1.relative: 0.0 0.15;
rel2.relative: 1.0 1.15;
}
description { state: "bounce2" 0.0;
inherit: "default" 0.0;
rel1.relative: 0.0 -0.15;
rel2.relative: 1.0 0.85;
}
}
part { name: "e.swallow.icon"; type: SWALLOW; nomouse;
description { state: "default" 0.0;
rel1.to: "icon";
rel1.relative: 0.15 0.15;
rel2.to: "icon";
rel2.relative: 0.85 0.85;
rel2.offset: 0 0;
}
}
part { name: "knob"; mouse_events: 0;
description { state: "default" 0.0;
fixed: 1 1;
image.normal: "knob_round_small_busy.png";
aspect: 1.0 1.0; aspect_preference: BOTH;
max: 20 20;
rel1.to: "e.event.icon";
rel2.to: "e.event.icon";
fixed: 1 1;
}
}
part { name: "clip1"; type: RECT;
description { state: "default" 0.0;
rel1.to: "top";
rel2.to: "top";
}
description { state: "focused" 0.0;
inherit: "default" 0.0;
visible: 0;
}
}
part { name: "clip2"; type: RECT;
description { state: "default" 0.0;
rel1.to: "top";
rel2.to: "top";
visible: 0;
}
description { state: "focused" 0.0;
inherit: "default" 0.0;
visible: 1;
}
}
part { name: "close1"; nomouse;
clip_to: "clip1";
description { state: "default" 0.0;
image.normal: "sym_close_dark_normal.png";
rel1.to: "e.event.close";
rel2.to: "e.event.close";
min: 15 15;
max: 15 15;
fixed: 1 1;
}
description { state: "selected" 0.0;
inherit: "default" 0.0;
image.normal: "sym_close_dark_selected.png";
}
}
part { name: "max1"; nomouse;
clip_to: "clip1";
description { state: "default" 0.0;
image.normal: "sym_up_dark_normal.png";
rel1.to: "e.event.maximize";
rel2.to: "e.event.maximize";
min: 15 15;
max: 15 15;
fixed: 1 1;
}
description { state: "selected" 0.0;
inherit: "default" 0.0;
image.normal: "sym_up_dark_selected.png";
}
}
part { name: "min1"; nomouse;
clip_to: "clip1";
description { state: "default" 0.0;
image.normal: "sym_down_dark_normal.png";
rel1.to: "e.event.minimize";
rel2.to: "e.event.minimize";
min: 15 15;
max: 15 15;
fixed: 1 1;
}
description { state: "selected" 0.0;
inherit: "default" 0.0;
image.normal: "sym_down_dark_selected.png";
}
}
part { name: "close2"; nomouse;
clip_to: "clip2";
description { state: "default" 0.0;
image.normal: "sym_close_light_normal.png";
rel1.to: "e.event.close";
rel2.to: "e.event.close";
min: 15 15;
max: 15 15;
fixed: 1 1;
}
description { state: "selected" 0.0;
inherit: "default" 0.0;
image.normal: "sym_close_light_selected.png";
}
}
part { name: "max2"; nomouse;
clip_to: "clip2";
description { state: "default" 0.0;
image.normal: "sym_up_light_normal.png";
rel1.to: "e.event.maximize";
rel2.to: "e.event.maximize";
min: 15 15;
max: 15 15;
fixed: 1 1;
}
description { state: "selected" 0.0;
inherit: "default" 0.0;
image.normal: "sym_up_light_selected.png";
}
}
part { name: "min2"; nomouse;
clip_to: "clip2";
description { state: "default" 0.0;
image.normal: "sym_down_light_normal.png";
rel1.to: "e.event.minimize";
rel2.to: "e.event.minimize";
min: 15 15;
max: 15 15;
fixed: 1 1;
}
description { state: "selected" 0.0;
inherit: "default" 0.0;
image.normal: "sym_down_light_selected.png";
}
}
part { name: "e.event.icon"; type: RECT;
description { state: "default" 0.0;
rel1.relative: 0.0 0.0;
rel1.to_y: "top";
rel2.relative: 0.0 0.0;
align: 0.0 0.5;
aspect: 1.0 1.0; aspect_preference: VERTICAL;
color: 0 0 0 0;
}
}
program {
signal: "mouse,clicked,1"; source: "e.event.icon";
action: SIGNAL_EMIT "elm,action,menu" "elm";
}
part { name: "e.event.titlebar"; type: RECT;
description { state: "default" 0.0;
rel1.to_y: "top";
rel1.relative: 1.0 0.0;
rel1.to_x: "e.event.icon";
rel2.relative: 0.0 0.0;
rel2.to_x: "e.event.minimize";
color: 0 0 0 0;
}
}
program {
signal: "mouse,down,1"; source: "e.event.titlebar";
action: SIGNAL_EMIT "elm,action,move,start" "elm";
}
program {
signal: "mouse,up,1"; source: "e.event.titlebar";
action: SIGNAL_EMIT "elm,action,move,stop" "elm";
}
part { name: "e.event.close"; type: RECT;
description { state: "default" 0.0;
rel1.relative: 1.0 0.0;
rel1.to_y: "top";
rel2.relative: 1.0 0.0;
align: 1.0 0.5;
aspect: 1.0 1.0; aspect_preference: VERTICAL;
color: 0 0 0 0;
}
}
program {
signal: "mouse,clicked,1"; source: "e.event.close";
action: SIGNAL_EMIT "elm,action,close" "elm";
}
part { name: "e.event.maximize"; type: RECT;
description { state: "default" 0.0;
rel1.to_y: "top";
rel1.relative: -0.25 0.0;
rel1.offset: -1 0;
rel1.to_x: "e.event.close";
rel2.relative: -0.25 0.0;
rel2.to_x: "e.event.close";
align: 1.0 0.5;
aspect: 1.0 1.0; aspect_preference: VERTICAL;
color: 0 0 0 0;
}
description { state: "max" 0.0;
inherit: "default" 0.0;
visible: 0;
}
}
part { name: "e.event.maximize2"; type: RECT;
description { state: "default" 0.0;
rel1.to: "e.event.maximize";
rel2.to: "e.event.maximize";
color: 0 0 0 0;
visible: 0;
}
description { state: "max" 0.0;
inherit: "default" 0.0;
visible: 1;
}
}
program {
signal: "mouse,clicked,1"; source: "e.event.maximize";
action: SIGNAL_EMIT "elm,action,maximize" "elm";
}
program {
signal: "mouse,clicked,1"; source: "e.event.maximize2";
action: SIGNAL_EMIT "elm,action,restore" "elm";
}
part { name: "e.event.minimize"; type: RECT;
description { state: "default" 0.0;
rel1.to_y: "top";
rel1.relative: 0.0 0.0;
rel1.offset: -1 0;
rel1.to_x: "e.event.maximize";
rel2.relative: 0.0 0.0;
rel2.to_x: "e.event.maximize";
align: 1.0 0.5;
aspect: 1.0 1.0; aspect_preference: VERTICAL;
color: 0 0 0 0;
}
}
program {
signal: "mouse,clicked,1"; source: "e.event.minimize";
action: SIGNAL_EMIT "elm,action,iconify" "elm";
}
part { name: "e.event.resize.tl"; type: RECT;
description { state: "default" 0.0;
rel2.relative: 0.0 0.0;
min: 32 4;
align: 0.0 0.0;
color: 0 0 0 0;
}
}
part { name: "e.event.resize.t"; type: RECT;
description { state: "default" 0.0;
rel1.relative: 1.0 0.0;
rel1.to_x: "e.event.resize.tl";
rel2.relative: 0.0 0.0;
rel2.to_x: "e.event.resize.tr";
min: 0 4;
align: 0.5 0.0;
color: 0 0 0 0;
}
}
part { name: "e.event.resize.tr"; type: RECT;
description { state: "default" 0.0;
rel1.relative: 1.0 0.0;
rel2.relative: 1.0 0.0;
min: 32 4;
align: 1.0 0.0;
color: 0 0 0 0;
}
}
part { name: "bottom"; type: RECT;
description { state: "default" 0.0;
color_class: "border_bottom";
rel1.relative: 0.0 1.0;
rel2.relative: 1.0 1.0;
rel2.offset: -1 4;
min: 0 5;
color: 64 64 64 255;
fixed: 0 1;
}
description { state: "shaded" 0.0;
inherit: "default" 0.0;
min: 0 0;
visible: 0;
}
description { state: "max" 0.0;
inherit: "default" 0.0;
min: 0 0;
visible: 0;
}
}
part { name: "bevel2"; nomouse;
description { state: "default" 0.0;
image.normal: "bevel_dark_out.png";
image.border: 1 1 1 1;
image.middle: 0;
rel1.to: "bottom";
rel2.to: "bottom";
fill.smooth: 0;
}
description { state: "shaded" 0.0;
inherit: "default" 0.0;
visible: 0;
}
description { state: "max" 0.0;
inherit: "default" 0.0;
visible: 0;
}
}
part { name: "e.event.resize.bl"; type: RECT;
description { state: "default" 0.0;
rel1.relative: 0.0 1.0;
rel2.relative: 0.0 1.0;
min: 32 5;
align: 0.0 1.0;
color: 0 0 0 0;
fixed: 1 1;
}
description { state: "shaded" 0.0;
inherit: "default" 0.0;
min: 0 0;
visible: 0;
}
description { state: "max" 0.0;
inherit: "default" 0.0;
min: 0 0;
visible: 0;
}
}
part { name: "e.event.resize.b"; type: RECT;
description { state: "default" 0.0;
rel1.relative: 1.0 1.0;
rel1.to_x: "e.event.resize.tl";
rel2.relative: 0.0 1.0;
rel2.to_x: "e.event.resize.tr";
min: 0 5;
align: 0.5 1.0;
color: 0 0 0 0;
fixed: 0 1;
}
description { state: "shaded" 0.0;
inherit: "default" 0.0;
min: 0 0;
visible: 0;
}
description { state: "max" 0.0;
inherit: "default" 0.0;
min: 0 0;
visible: 0;
}
}
part { name: "e.event.resize.br"; type: RECT;
description { state: "default" 0.0;
rel1.relative: 1.0 1.0;
rel2.relative: 1.0 1.0;
min: 32 5;
align: 1.0 1.0;
color: 0 0 0 0;
fixed: 1 1;
}
description { state: "shaded" 0.0;
inherit: "default" 0.0;
min: 0 0;
visible: 0;
}
description { state: "max" 0.0;
inherit: "default" 0.0;
min: 0 0;
visible: 0;
}
}
part { name: "shine"; mouse_events: 0;
description { state: "default" 0.0;
image.normal: "shine.png";
rel1.offset: 0 -2;
rel1.to: "top";
rel2.relative: 1.0 0.0;
rel2.offset: -1 2;
rel2.to: "top";
FIXED_SIZE(69, 5)
}
}
part { name: "focus"; type: RECT; repeat_events: 1;
description { state: "default" 0.0;
rel1.to: "top";
rel2.to: "bottom";
color: 0 0 0 0;
}
description { state: "focused" 0.0;
inherit: "default" 0.0;
visible: 0;
}
}
program {
signal: "mouse,down,1"; source: "focus";
action: SIGNAL_EMIT "elm,action,focus" "elm";
}
program {
signal: "elm,state,focus,on"; source: "elm";
action: STATE_SET "focused" 0.0;
transition: SINUSOIDAL 0.1;
target: "glow";
target: "focus";
after: "focus2";
}
program { name: "focus2";
action: STATE_SET "default" 0.0;
transition: SINUSOIDAL 0.4;
target: "glow";
}
program {
signal: "elm,state,focus,off"; source: "elm";
action: STATE_SET "default" 0.0;
transition: SINUSOIDAL 0.1;
target: "focus";
target: "glow";
}
program {
signal: "elm,state,focus,on"; source: "elm";
action: STATE_SET "focused" 0.0;
target: "top";
target: "elm.text.title";
target: "title2";
target: "clip1";
target: "clip2";
}
program {
signal: "elm,state,focus,off"; source: "elm";
action: STATE_SET "default" 0.0;
target: "top";
target: "elm.text.title";
target: "title2";
target: "clip1";
target: "clip2";
}
program {
signal: "elm,state,maximized,on"; source: "elm";
action: STATE_SET "max" 0.0;
target: "e.event.maximize";
target: "e.event.maximize2";
target: "bottom";
target: "bevel2";
target: "e.event.resize.bl";
target: "e.event.resize.b";
target: "e.event.resize.br";
}
program {
signal: "elm,state,maximized,off"; source: "elm";
action: STATE_SET "default" 0.0;
target: "e.event.maximize";
target: "e.event.maximize2";
target: "bottom";
target: "bevel2";
target: "e.event.resize.bl";
target: "e.event.resize.b";
target: "e.event.resize.br";
}
program {
signal: "mouse,down,*"; source: "e.event.close";
action: STATE_SET "selected" 0.0;
target: "close1";
target: "close2";
}
program {
signal: "mouse,up,*"; source: "e.event.close";
action: STATE_SET "default" 0.0;
target: "close1";
target: "close2";
}
program {
signal: "mouse,down,*"; source: "e.event.maximize*";
action: STATE_SET "selected" 0.0;
target: "max1";
target: "max2";
}
program {
signal: "mouse,up,*"; source: "e.event.maximize*";
action: STATE_SET "default" 0.0;
target: "max1";
target: "max2";
}
program {
signal: "mouse,down,*"; source: "e.event.minimize";
action: STATE_SET "selected" 0.0;
target: "min1";
target: "min2";
}
program {
signal: "mouse,up,*"; source: "e.event.minimize";
action: STATE_SET "default" 0.0;
target: "min1";
target: "min2";
}
}
}
group { name: "elm/ews/decoration/borderless";
images.image: "win_shadow.png" COMP;
images.image: "win_glow.png" COMP;
parts {
part { name: "shadow"; mouse_events: 0;
description { state: "default" 0.0;
WIN_SHADOW;
}
description { state: "hidden" 0.0;
inherit: "default" 0.0;
visible: 0;
}
}
part { name: "glow"; mouse_events: 0;
description { state: "default" 0.0;
image.normal: "win_glow.png";
image.border: 9 9 9 9;
image.middle: 0;
rel1.offset: -5 -5;
rel2.offset: 4 4;
fill.smooth: 0;
color: 255 255 255 0;
visible: 0;
}
description { state: "focused" 0.0;
inherit: "default" 0.0;
color: 255 255 255 255;
visible: 1;
}
}
part { name: "focus"; type: RECT; repeat_events: 1;
description { state: "default" 0.0;
color: 0 0 0 0;
}
description { state: "focused" 0.0;
inherit: "default" 0.0;
visible: 0;
}
}
program {
signal: "mouse,down,1"; source: "focus";
action: SIGNAL_EMIT "elm,action,focus" "elm";
}
program {
signal: "elm,state,focus,on"; source: "elm";
action: STATE_SET "focused" 0.0;
transition: SINUSOIDAL 0.1;
target: "glow";
target: "focus";
after: "focus2";
}
program { name: "focus2";
action: STATE_SET "default" 0.0;
transition: SINUSOIDAL 0.4;
target: "glow";
}
program {
signal: "elm,state,focus,off"; source: "elm";
action: STATE_SET "default" 0.0;
transition: SINUSOIDAL 0.1;
target: "focus";
target: "glow";
}
}
}

View File

@ -1,77 +1,13 @@
group { name: "elm/win/base/default";
data.item: "elm_win_version" "119";
parts {
part { name: "menu_bg"; type: RECT;
description { state: "default" 0.0;
color: 64 64 64 255;
align: 0.5 0;
rel2.to: "elm.swallow.menu";
rect { "client_clip"; nomouse;
desc { "default";
rel.to: "elm.swallow.contents";
}
}
part { name: "elm.swallow.menu"; type: SWALLOW;
description { state: "default" 0.0;
rel2.relative: 1.0 0.0;
visible: 0;
align: 0.5 0;
fixed: 1 1;
}
description { state: "visible" 0.0;
inherit: "default" 0.0;
visible: 1;
fixed: 0 1;
}
}
part { name: "client_clip"; type: RECT; mouse_events: 0;
description { state: "default" 0.0;
rel1.to_y: "elm.swallow.contents";
rel2.to_y: "elm.swallow.contents";
}
}
part { name: "elm.swallow.contents"; type: SWALLOW;
swallow { "elm.swallow.contents";
clip_to: "client_clip";
description { state: "default" 0.0;
rel1 {
to_y: "elm.swallow.menu";
relative: 0.0 1.0;
}
}
}
part { name: "blocker"; type: RECT;
description { state: "default" 0.0;
rel1.relative : 0.0 0.0;
rel2.relative : 1.0 1.0;
color: 64 64 64 150;
visible: 0;
}
description { state: "visible" 0.0;
inherit: "default" 0.0;
visible: 1;
}
}
}
programs {
program { name: "show_menu";
signal: "elm,action,show_menu";
source: "elm";
action: STATE_SET "visible" 0.0;
target: "elm.swallow.menu";
}
program { name: "hide_menu";
signal: "elm,action,hide";
source: "elm";
action: STATE_SET "default" 0.0;
target: "elm.swallow.menu";
}
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";
}
}
}

View File

@ -90,6 +90,7 @@ elm_public_eolian_files = \
lib/elementary/elm_popup_item.eo \
lib/elementary/efl_ui_box.eo \
lib/elementary/efl_ui_box_flow.eo \
lib/elementary/efl_ui_box_stack.eo \
lib/elementary/efl_ui_grid.eo \
lib/elementary/efl_ui_grid_static.eo \
lib/elementary/efl_ui_layout_internal_box.eo \
@ -121,6 +122,7 @@ elm_public_eolian_files = \
# Private classes (not exposed or shipped)
elm_private_eolian_files = \
lib/elementary/efl_ui_internal_text_interactive.eo \
lib/elementary/efl_ui_win_internal_part.eo \
$(NULL)
# Legacy classes - not part of public EO API
@ -652,6 +654,7 @@ lib_elementary_libelementary_la_SOURCES = \
lib/elementary/elu_ews_wm.c \
lib/elementary/efl_ui_box.c \
lib/elementary/efl_ui_box_flow.c \
lib/elementary/efl_ui_box_stack.c \
lib/elementary/efl_ui_box_layout.c \
lib/elementary/efl_ui_box_private.h \
lib/elementary/efl_ui_grid.c \
@ -833,6 +836,7 @@ bin/elementary/test_win_plug.c \
bin/elementary/test_win_state.c \
bin/elementary/test_win_wm_rotation.c \
bin/elementary/test_win_dialog.c \
bin/elementary/test_win_modal.c \
bin/elementary/test.h
bin_elementary_elementary_test_LDADD = @USE_ELEMENTARY_LIBS@

View File

@ -16,6 +16,7 @@ void test_access3(void *data, Evas_Object *obj, void *event_info);
void test_bg_plain(void *data, Evas_Object *obj, void *event_info);
void test_bg_image(void *data, Evas_Object *obj, void *event_info);
void test_bg_options(void *data, Evas_Object *obj, void *event_info);
void test_bg_window(void *data, Evas_Object *obj, void *event_info);
void test_icon(void *data, Evas_Object *obj, void *event_info);
void test_icon_transparent(void *data, Evas_Object *obj, void *event_info);
void test_icon_standard(void *data, Evas_Object *obj, void *event_info);
@ -26,6 +27,7 @@ void test_box_horiz(void *data, Evas_Object *obj, void *event_info);
void test_box_homo(void *data, Evas_Object *obj, void *event_info);
void test_box_transition(void *data, Evas_Object *obj, void *event_info);
void test_box_align(void *data, Evas_Object *obj, void *event_info);
void test_box_stack(void *data, Evas_Object *obj, void *event_info);
void test_ui_box(void *data, Evas_Object *obj, void *event_info);
void test_button(void *data, Evas_Object *obj, void *event_info);
void test_cnp(void *data, Evas_Object *obj, void *event_info);
@ -281,6 +283,7 @@ void test_dnd_multi_features(void *data, Evas_Object *obj, void *event_info);
void test_dnd_types(void *data, Evas_Object *obj, void *event_info);
void test_task_switcher(void *data, Evas_Object *obj, void *event_info);
void test_win_dialog(void *data, Evas_Object *obj, void *event_info);
void test_win_modal(void *data, Evas_Object *obj, void *event_info);
void test_box_disable(void *data, Evas_Object *obj, void *event_info);
void test_layout_disable(void *data, Evas_Object *obj, void *event_info);
@ -629,6 +632,7 @@ add_tests:
ADD_TEST(NULL, "Window / Background", "Bg Plain", test_bg_plain);
ADD_TEST(NULL, "Window / Background", "Bg Image", test_bg_image);
ADD_TEST(NULL, "Window / Background", "Bg Options", test_bg_options);
ADD_TEST(NULL, "Window / Background", "Bg EOAPI (Efl.Ui.Win)", test_bg_window);
ADD_TEST(NULL, "Window / Background", "Window States", test_win_state);
ADD_TEST(NULL, "Window / Background", "Window States 2", test_win_state2);
ADD_TEST(NULL, "Window / Background", "Inwin", test_inwin);
@ -639,6 +643,7 @@ add_tests:
ADD_TEST(NULL, "Window / Background", "Window WM Rotation", test_win_wm_rotation);
ADD_TEST(NULL, "Window / Background", "Window Standard/Dialog", test_win_dialog);
ADD_TEST(NULL, "Window / Background", "Window Keygrab Set", test_win_keygrab);
ADD_TEST(NULL, "Window / Background", "Window Modal", test_win_modal);
//------------------------------//
ADD_TEST(NULL, "Images", "Icon", test_icon);
@ -664,6 +669,7 @@ add_tests:
ADD_TEST(NULL, "Containers", "Box Homogeneous", test_box_homo);
ADD_TEST(NULL, "Containers", "Box Transition", test_box_transition);
ADD_TEST(NULL, "Containers", "Box Align", test_box_align);
ADD_TEST(NULL, "Containers", "Box Stack", test_box_stack);
ADD_TEST(NULL, "Containers", "Table", test_table);
ADD_TEST(NULL, "Containers", "Table Homogeneous", test_table2);
ADD_TEST(NULL, "Containers", "Table 3", test_table3);

View File

@ -268,3 +268,108 @@ test_bg_options(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *even
evas_object_resize(win, 320, 320);
evas_object_show(win);
}
static void
_colorsel_cb(void *data, const Efl_Event *ev)
{
Efl_Ui_Win *win = data;
int r, g, b, a;
// Solid color API
elm_colorselector_color_get(ev->object, &r, &g, &b, &a);
efl_gfx_color_set(efl_part(win, "background"), r, g, b, a);
efl_gfx_color_get(efl_part(win, "background"), &r, &g, &b, &a);
printf("bg color: %d %d %d %d\n", r, g, b, a);
fflush(stdout);
}
static void
_file_cb(void *data, const Efl_Event *ev)
{
Efl_Ui_Win *win = data;
const char *f, *k;
// File API
efl_file_get(efl_part(win, "background"), &f, &k);
if (f)
{
efl_file_set(efl_part(win, "background"), NULL, NULL);
}
else
{
efl_file_get(ev->object, &f, &k);
efl_file_set(efl_part(win, "background"), f, k);
}
}
static void
_image_cb(void *data, const Efl_Event *ev)
{
Efl_Ui_Win *win = data, *o;
const char *f, *k;
// Content API
if (efl_content_get(efl_part(win, "background")))
efl_content_set(efl_part(win, "background"), NULL);
else
{
efl_file_get(ev->object, &f, &k);
o = efl_add(EFL_UI_IMAGE_CLASS, win,
efl_ui_image_scale_type_set(efl_added, EFL_UI_IMAGE_SCALE_TYPE_FIT_OUTSIDE),
efl_file_set(efl_added, f, k)
);
efl_content_set(efl_part(win, "background"), o);
}
}
void
test_bg_window(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Evas_Object *win, *box;
char buf[PATH_MAX];
win = efl_add(EFL_UI_WIN_STANDARD_CLASS, NULL,
efl_text_set(efl_added, "Bg EOAPI (Efl.Ui.Win)"),
efl_ui_win_autodel_set(efl_added, EINA_TRUE),
efl_ui_win_alpha_set(efl_added, 1));
box = efl_add(EFL_UI_BOX_CLASS, win,
efl_gfx_size_hint_weight_set(efl_added, 1, 1),
efl_pack(win, efl_added), // FIXME / use content set
efl_gfx_visible_set(efl_added, 1));
efl_add(ELM_COLORSELECTOR_CLASS, win,
elm_colorselector_mode_set(efl_added, ELM_COLORSELECTOR_PALETTE),
elm_colorselector_palette_color_add(efl_added, 64, 64, 64, 255),
elm_colorselector_palette_color_add(efl_added, 255, 128, 128, 255),
elm_colorselector_palette_color_add(efl_added, 0, 64, 64, 64),
elm_colorselector_palette_color_add(efl_added, 0, 0, 0, 0),
efl_event_callback_add(efl_added, ELM_COLORSELECTOR_EVENT_COLOR_ITEM_SELECTED, _colorsel_cb, win),
efl_gfx_size_hint_weight_set(efl_added, 1.0, 1.0),
efl_pack(box, efl_added),
efl_gfx_visible_set(efl_added, 1)
);
snprintf(buf, sizeof(buf), "%s/images/plant_01.jpg", elm_app_data_dir_get());
efl_add(EFL_UI_IMAGE_CLASS, win,
efl_file_set(efl_added, buf, NULL),
efl_gfx_size_hint_min_set(efl_added, 64, 64),
efl_gfx_size_hint_weight_set(efl_added, 1.0, 1.0),
efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED, _file_cb, win),
efl_pack(box, efl_added),
efl_gfx_visible_set(efl_added, 1)
);
snprintf(buf, sizeof(buf), "%s/images/sky_04.jpg", elm_app_data_dir_get());
efl_add(EFL_UI_IMAGE_CLASS, win,
efl_file_set(efl_added, buf, NULL),
efl_gfx_size_hint_min_set(efl_added, 64, 64),
efl_gfx_size_hint_weight_set(efl_added, 1.0, 1.0),
efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED, _image_cb, win),
efl_pack(box, efl_added),
efl_gfx_visible_set(efl_added, 1)
);
efl_gfx_size_set(win, 300, 200);
efl_gfx_visible_set(win, 1);
}

View File

@ -857,6 +857,7 @@ _align_box_add(Evas_Object *bx_out, Box_Align_Data *bdata)
elm_box_pack_end(bx, bt);
evas_object_show(bt);
}
void
test_box_align(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
@ -880,3 +881,55 @@ test_box_align(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
evas_object_resize(win, 300, 400);
evas_object_show(win);
}
void
test_box_stack(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
Evas_Object *win, *bx, *o;
char buf[PATH_MAX];
win = efl_add(EFL_UI_WIN_CLASS, NULL,
efl_text_set(efl_added, "Efl.Ui.Box.Stack"),
efl_ui_win_autodel_set(efl_added, EINA_TRUE));
efl_gfx_color_set(efl_part(win, "background"), 24, 24, 64, 255);
/* stacked box, with items in the center-bottom */
bx = efl_add(EFL_UI_BOX_STACK_CLASS, win,
efl_pack_align_set(efl_added, 0.5, 1.0));
efl_content_set(win, bx);
/* stretched rectangle */
o = efl_add(EFL_CANVAS_RECTANGLE_CLASS, win,
efl_gfx_color_set(efl_added, 0, 64, 128, 255),
efl_gfx_size_hint_align_set(efl_added, EFL_GFX_SIZE_HINT_FILL, EFL_GFX_SIZE_HINT_FILL),
efl_gfx_size_hint_weight_set(efl_added, EFL_GFX_SIZE_HINT_EXPAND, EFL_GFX_SIZE_HINT_EXPAND),
efl_gfx_visible_set(efl_added, EINA_TRUE));
efl_pack(bx, o);
/* rectangle with a max size */
o = efl_add(EFL_CANVAS_RECTANGLE_CLASS, win,
efl_gfx_color_set(efl_added, 64, 128, 64, 255),
efl_gfx_size_hint_align_set(efl_added, EFL_GFX_SIZE_HINT_FILL, EFL_GFX_SIZE_HINT_FILL),
efl_gfx_size_hint_weight_set(efl_added, EFL_GFX_SIZE_HINT_EXPAND, EFL_GFX_SIZE_HINT_EXPAND),
efl_gfx_size_hint_max_set(efl_added, 128, 20),
efl_gfx_visible_set(efl_added, EINA_TRUE));
efl_pack(bx, o);
/* image with a forced min size */
snprintf(buf, sizeof(buf), "%s/images/logo.png", elm_app_data_dir_get());
o = efl_add(EFL_UI_IMAGE_CLASS, win,
efl_gfx_size_hint_align_set(efl_added, EFL_GFX_SIZE_HINT_FILL, EFL_GFX_SIZE_HINT_FILL),
efl_gfx_size_hint_weight_set(efl_added, EFL_GFX_SIZE_HINT_EXPAND, EFL_GFX_SIZE_HINT_EXPAND),
efl_gfx_size_hint_min_set(efl_added, 64, 64),
efl_file_set(efl_added, buf, NULL),
efl_gfx_visible_set(efl_added, EINA_TRUE));
efl_pack(bx, o);
/* make window resizable: add a weight to its content */
efl_gfx_size_hint_weight_set(bx, EFL_GFX_SIZE_HINT_EXPAND, EFL_GFX_SIZE_HINT_EXPAND);
efl_gfx_size_set(win, 300, 300);
efl_gfx_visible_set(win, EINA_TRUE);
}

View File

@ -5,7 +5,7 @@
void
static void
_bt_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Evas_Object *dia, *lb;
@ -24,6 +24,34 @@ _bt_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_U
evas_object_show(dia);
}
static void
_bt2_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Efl_Canvas_Object *dia, *lb, *parent = data;
dia = efl_add(EFL_UI_WIN_STANDARD_CLASS, parent,
efl_ui_win_type_set(efl_added, EFL_UI_WIN_DIALOG_BASIC),
efl_ui_win_name_set(efl_added, "window-dia-2"),
efl_ui_win_autodel_set(efl_added, EINA_TRUE),
efl_text_set(efl_added, "A Fixed Size Dialog"));
// Notes:
// - All objects have 0 weight, this makes the window not resizable.
// - With EO APIs, efl_gfx_size_hint_min_set() is safe to call as EFL will
// only set the restricted min size (and combine them for calculation).
lb = efl_add(EFL_UI_TEXT_CLASS, dia,
efl_text_set(efl_added, "This is a non-resizable dialog."),
efl_gfx_size_hint_min_set(efl_added, 300, 150),
efl_gfx_size_hint_max_set(efl_added, 300, 150),
efl_gfx_size_hint_weight_set(efl_added, 0, 0));
// Swallow in the label as the default content, this will make it visible.
efl_content_set(dia, lb);
efl_gfx_visible_set(dia, EINA_TRUE);
}
void
test_win_dialog(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
@ -36,13 +64,19 @@ test_win_dialog(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *even
evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_win_resize_object_add(win, box);
evas_object_show(box);
bt = elm_button_add(win);
elm_object_text_set(bt, "Create a new dialog");
evas_object_smart_callback_add(bt, "clicked", _bt_clicked_cb, win);
elm_box_pack_end(box, bt);
evas_object_show(bt);
bt = elm_button_add(win);
elm_object_text_set(bt, "Create a new unresizable dialog");
evas_object_smart_callback_add(bt, "clicked", _bt2_clicked_cb, win);
elm_box_pack_end(box, bt);
evas_object_show(bt);
evas_object_resize(win, 400, 400);
evas_object_show(win);
}

View File

@ -0,0 +1,78 @@
#ifdef HAVE_CONFIG_H
# include "elementary_config.h"
#endif
#include <Elementary.h>
static Evas_Object *
_parent_win_get(Evas_Object *obj)
{
Evas_Object *parent = obj;
while ((parent = elm_object_parent_widget_get(obj)) != NULL)
obj = parent;
return obj;
}
static void
_close(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Evas_Object *win = data;
evas_object_del(win);
}
void
test_win_modal(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
{
Evas_Object *parent_win, *win, *bg, *txt, *bx, *bt;
parent_win = _parent_win_get(obj);
win = elm_win_add(parent_win, "modal", ELM_WIN_BASIC);
elm_win_title_set(win, "Window Modal");
elm_win_autodel_set(win, EINA_TRUE);
bg = elm_bg_add(win);
elm_win_resize_object_add(win, bg);
evas_object_size_hint_align_set(bg, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_show(bg);
bx = elm_box_add(win);
elm_win_resize_object_add(win, bx);
evas_object_size_hint_align_set(bx, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_show(bx);
txt = elm_label_add(win);
elm_object_text_set(txt, "This is a modal window.<br>"
"It will block all inputs on all the other opened windows.");
evas_object_size_hint_align_set(txt, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_size_hint_weight_set(txt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_label_line_wrap_set(txt, ELM_WRAP_WORD);
elm_box_pack_end(bx, txt);
evas_object_show(txt);
bt = elm_button_add(win);
elm_object_text_set(bt, "Open another modal window");
evas_object_size_hint_align_set(bt, 0.5, 0.5);
evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0);
evas_object_smart_callback_add(bt, "clicked", test_win_modal, NULL);
elm_box_pack_end(bx, bt);
evas_object_show(bt);
bt = elm_button_add(win);
elm_object_text_set(bt, "Close");
evas_object_size_hint_align_set(bt, 0.5, 0.5);
evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0);
evas_object_smart_callback_add(bt, "clicked", _close, win);
elm_box_pack_end(bx, bt);
evas_object_show(bt);
/* make the window modal */
elm_win_modal_set(win, EINA_TRUE);
evas_object_resize(win, 250, 150);
evas_object_show(win);
}

View File

@ -2307,6 +2307,15 @@ EAPI void ecore_evas_screen_dpi_get(const Ecore_Evas *ee, int *xdpi, int
EAPI void ecore_evas_draw_frame_set(Ecore_Evas *ee, Eina_Bool draw_frame) EINA_DEPRECATED;
EAPI Eina_Bool ecore_evas_draw_frame_get(const Ecore_Evas *ee) EINA_DEPRECATED;
/**
* @brief Set shadow geometry for client-side decorations
*
* Note that the framespace contains both a shadow or glow around the window,
* and the window borders (title bar, etc...).
*/
EAPI void ecore_evas_shadow_geometry_set(Ecore_Evas *ee, int x, int y, int w, int h);
EAPI void ecore_evas_shadow_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int *h);
/**
* @brief Associate the given object to this ecore evas.
*

View File

@ -2236,6 +2236,33 @@ ecore_evas_draw_frame_get(const Ecore_Evas *ee EINA_UNUSED)
return EINA_FALSE;
}
EAPI void
ecore_evas_shadow_geometry_set(Ecore_Evas *ee, int l, int r, int t, int b)
{
ECORE_EVAS_CHECK(ee);
if ((ee->shadow.l == l) && (ee->shadow.r == r) &&
(ee->shadow.t == t) && (ee->shadow.b == b)) return;
ee->shadow.l = l;
ee->shadow.r = r;
ee->shadow.t = t;
ee->shadow.b = b;
ee->shadow.changed = EINA_TRUE;
}
EAPI void
ecore_evas_shadow_geometry_get(const Ecore_Evas *ee, int *l, int *r, int *t, int *b)
{
if (l) *l = 0;
if (r) *r = 0;
if (t) *t = 0;
if (b) *b = 0;
ECORE_EVAS_CHECK(ee);
if (l) *l = ee->shadow.l;
if (r) *r = ee->shadow.r;
if (t) *t = ee->shadow.t;
if (b) *b = ee->shadow.b;
}
EAPI void
ecore_evas_pointer_xy_get(const Ecore_Evas *ee, Evas_Coord *x, Evas_Coord *y)
{

View File

@ -205,6 +205,11 @@ struct _Ecore_Evas
int x, y, w, h;
} req;
struct {
int l, r, t, b;
int changed : 1;
} shadow;
struct {
int x, y;
} mouse;

View File

@ -348,4 +348,7 @@ EAPI extern Ecore_X_Atom ECORE_X_ATOM_TEAMWORK_OPEN; /**< @since 1.18 */
EAPI extern Ecore_X_Atom ECORE_X_ATOM_TEAMWORK_COMPLETED; /**< @since 1.18 */
EAPI extern Ecore_X_Atom ECORE_X_ATOM_TEAMWORK_PROGRESS; /**< @since 1.18 */
EAPI extern Ecore_X_Atom ECORE_X_ATOM_TEAMWORK_STARTED; /**< @since 1.18 */
/* Client-Side Decorations */
EAPI extern Ecore_X_Atom ECORE_X_ATOM_GTK_FRAME_EXTENTS; /**< @since 1.19 */
#endif /* _ECORE_X_ATOMS_H */

View File

@ -378,6 +378,10 @@ EAPI Ecore_X_Atom ECORE_X_ATOM_TEAMWORK_COMPLETED = 0;
EAPI Ecore_X_Atom ECORE_X_ATOM_TEAMWORK_PROGRESS = 0;
EAPI Ecore_X_Atom ECORE_X_ATOM_TEAMWORK_STARTED = 0;
/* Client-Side Decorations */
EAPI Ecore_X_Atom ECORE_X_ATOM_GTK_FRAME_EXTENTS = 0;
//EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_OPAQUE_REGION = 0;
typedef struct _Atom_Item Atom_Item;
struct _Atom_Item
@ -706,5 +710,8 @@ const Atom_Item atom_items[] =
{ "_TEAMWORK_COMPLETED", &ECORE_X_ATOM_TEAMWORK_COMPLETED },
{ "_TEAMWORK_PROGRESS", &ECORE_X_ATOM_TEAMWORK_PROGRESS },
{ "_TEAMWORK_STARTED", &ECORE_X_ATOM_TEAMWORK_STARTED },
{ "_GTK_FRAME_EXTENTS", &ECORE_X_ATOM_GTK_FRAME_EXTENTS },
//{ "_NET_WM_OPAQUE_REGION", &ECORE_X_ATOM_NET_WM_OPAQUE_REGION },
};

View File

@ -255,6 +255,7 @@ EAPI extern Elm_Version *elm_version;
# include <efl_config_global.eo.h>
# include <efl_ui_box.eo.h>
# include <efl_ui_box_flow.eo.h>
# include <efl_ui_box_stack.eo.h>
# include <efl_ui_grid.eo.h>
# include <efl_ui_grid_static.eo.h>
# include <efl_ui_image.eo.h>

View File

@ -0,0 +1,46 @@
#define EFL_GFX_SIZE_HINT_PROTECTED
#include "efl_ui_box_private.h"
#define MY_CLASS EFL_UI_BOX_STACK_CLASS
EOLIAN static Eo *
_efl_ui_box_stack_efl_object_constructor(Eo *obj, void *_pd EINA_UNUSED)
{
efl_constructor(efl_super(obj, MY_CLASS));
efl_pack_layout_engine_set(obj, MY_CLASS, NULL);
return obj;
}
EOLIAN static void
_efl_ui_box_stack_efl_pack_layout_layout_do(Efl_Class *klass EINA_UNUSED,
void *_pd EINA_UNUSED, Eo *obj,
const void *data EINA_UNUSED)
{
Evas_Object_Box_Option *opt;
Evas_Object_Box_Data *bd;
int minw = 0, minh = 0;
Eina_List *l;
EINA_SAFETY_ON_FALSE_RETURN(efl_isa(obj, EFL_UI_BOX_CLASS));
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
bd = efl_data_scope_get(wd->resize_obj, EVAS_BOX_CLASS);
evas_object_box_layout_stack(wd->resize_obj, bd, NULL);
/* Note: legacy evas_object_box_layout_stack sets the box min size to be
* the MAX() of the children's sizes, rather than their min sizes. By fixing
* that, we can implement elm_win_resize_object_add() with a Efl.Ui.Box. */
EINA_LIST_FOREACH(bd->children, l, opt)
{
Evas_Object *child = opt->obj;
int mw = 0, mh = 0;
efl_gfx_size_hint_combined_min_get(child, &mw, &mh);
if (mw > minw) minw = mw;
if (mh > minh) minh = mh;
}
efl_gfx_size_hint_restricted_min_set(obj, minw, minh);
}
#include "efl_ui_box_stack.eo.c"

View File

@ -0,0 +1,12 @@
class Efl.Ui.Box.Stack (Efl.Ui.Box, Efl.Pack.Layout)
{
[[A custom layout engine for @Efl.Ui.Box that stacks items.
Items will be stacked on top of each other (in the Z direction).
]]
data: null;
implements {
Efl.Object.constructor;
Efl.Pack.Layout.layout_do;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -172,9 +172,10 @@ enum Efl.Ui.Win.Move_Resize_Mode
}
class Efl.Ui.Win (Elm.Widget, Efl.Canvas, Elm.Interface.Atspi.Window,
Elm.Interface.Atspi_Widget_Action, Efl.Pack,
Elm.Interface.Atspi_Widget_Action, Efl.Container,
Efl.Input.State, Efl.Input.Interface, Efl.Screen,
Efl.Gfx.Size.Hint, Efl.Text, Efl.Config.Global)
Efl.Gfx.Size.Hint, Efl.Text, Efl.Config.Global,
Efl.Part)
{
[[Efl UI window class]]
legacy_prefix: elm_win;
@ -908,11 +909,6 @@ class Efl.Ui.Win (Elm.Widget, Efl.Canvas, Elm.Interface.Atspi.Window,
Elm.Interface.Atspi_Accessible.state_set.get;
Elm.Interface.Atspi_Accessible.name.get;
Elm.Interface.Atspi_Widget_Action.elm_actions.get;
Efl.Container.content_remove;
Efl.Container.content_iterate;
Efl.Container.content_count;
Efl.Pack.unpack;
Efl.Pack.pack;
Efl.Input.State.modifier_enabled.get;
Efl.Input.State.lock_enabled.get;
Efl.Screen.screen_dpi.get;
@ -935,6 +931,10 @@ class Efl.Ui.Win (Elm.Widget, Efl.Canvas, Elm.Interface.Atspi.Window,
Efl.Canvas.object_top_at_xy_get;
Efl.Canvas.objects_in_rectangle_get;
Efl.Canvas.object_top_in_rectangle_get;
Efl.Container.content.set;
Efl.Container.content.get;
Efl.Container.content_unset;
Efl.Part.part;
}
constructors {
.name;

View File

@ -0,0 +1,14 @@
class Efl.Ui.Win.Internal.Part (Efl.Object, Efl.Container, Efl.Gfx, Efl.File)
{
data: Elm_Part_Data;
implements {
Efl.Object.destructor;
Efl.Container.content.set;
Efl.Container.content.get;
Efl.Container.content_unset;
Efl.Gfx.color.set;
Efl.Gfx.color.get;
Efl.File.file.set;
Efl.File.file.get;
}
}

View File

@ -16,20 +16,9 @@ EOLIAN static Eo *
_efl_ui_win_standard_efl_object_finalize(Eo *obj, void *pd EINA_UNUSED)
{
obj = efl_finalize(efl_super(obj, MY_CLASS));
if (!obj)
return NULL;
Evas_Object *bg = efl_add(ELM_BG_CLASS, obj);
if (!bg)
{
ERR("Cannot create background.");
evas_object_del(obj);
return NULL;
}
efl_gfx_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
efl_pack(obj, bg);
efl_gfx_visible_set(bg, EINA_TRUE);
if (!obj) return NULL;
_elm_win_standard_init(obj);
return obj;
}

View File

@ -782,8 +782,7 @@ EAPI Evas_Object *
elm_menu_add(Evas_Object *parent)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
Evas_Object *obj = efl_add(MY_CLASS, parent);
return obj;
return efl_add(MY_CLASS, parent);
}
EOLIAN static Eo *

View File

@ -174,6 +174,7 @@ extern const char *_elm_engines[];
#define ELM_SAFE_FREE(_h, _fn) do { _fn((void*)_h); _h = NULL; } while (0)
#define ELM_SAFE_DEL(_h) do { efl_del(_h); _h = NULL; } while (0)
#define ELM_PRIV_STATIC_VARIABLE_DECLARE(name, signal, type) \
static const char name[] = signal;
@ -381,6 +382,7 @@ void _elm_win_rescale(Elm_Theme *th,
void _elm_win_access(Eina_Bool is_access);
void _elm_win_translate(void);
void _elm_win_focus_reconfigure(void);
void _elm_win_standard_init(Eo *win);
Ecore_X_Window _elm_ee_xwin_get(const Ecore_Evas *ee);

View File

@ -33,6 +33,14 @@ _elm_theme_item_finalize(Elm_Theme_Files *files,
Eina_Bool prepend,
Eina_Bool istheme)
{
/* Theme version history:
* <110: legacy, had no version tag
* 110: first supported version
* 119: switched windows to always use border
* win group has no menu, no blocker
* border group has all required swallows (conformant, bg, win)
* data: "elm_bg_version" matches "version" ("119")
*/
if (!f) return;
if (istheme)
{

View File

@ -543,10 +543,7 @@ _elm_cursor_cur_set(Elm_Cursor *cur)
}
}
Evas_Coord x, y, w, h, px, py;
evas_object_geometry_get(cur->eventarea, &x, &y, &w, &h);
evas_pointer_canvas_xy_get(cur->evas, &px, &py);
if (IS_INSIDE(px, py, x, y, w, h))
if (efl_canvas_object_pointer_in_get(cur->eventarea))
_elm_cursor_set(cur);
}

View File

@ -42,6 +42,20 @@ abstract Efl.Canvas.Object (Efl.Object, Efl.Gfx, Efl.Gfx.Stack, Efl.Animator,
pointer_mode: Efl.Input.Object_Pointer_Mode; [[Input pointer mode]]
}
}
@property pointer_in {
[[Read-only value indicating whether the main pointer is in the object.
This shall be true between pointer,in and pointer,out events (coming
in matching numbers). Note that group objects may receive multiple
pointer,in in a row.
@since 1.19
]]
get{}
values {
in: bool; [[If $true the main pointer has entered this object.]]
}
}
@property render_op {
[[Render mode to be used for compositing the Evas object.

View File

@ -3304,6 +3304,41 @@ _efl_canvas_object_pointer_mode_get(Eo *eo_obj EINA_UNUSED, Evas_Object_Protecte
return obj->pointer_mode;
}
EOLIAN Eina_Bool
_efl_canvas_object_pointer_in_get(Eo *eo_obj, Evas_Object_Protected_Data *obj)
{
Evas_Object_Protected_Data *in, *parent;
Eo *eo_in, *eo_parent;
Eina_List *l;
EVAS_OBJECT_DATA_ALIVE_CHECK(obj, EINA_FALSE);
if (!obj->is_smart)
return obj->mouse_in;
/* For smart objects, this is a bit expensive obj->mouse_in will not be set.
* Alternatively we could count the number of in and out events propagated
* to the smart object, assuming they always match. */
EINA_LIST_FOREACH(obj->layer->evas->pointer.object.in, l, eo_in)
{
if (EINA_UNLIKELY(eo_in == eo_obj))
return EINA_TRUE;
in = EVAS_OBJECT_DATA_GET(eo_in);
if (!EVAS_OBJECT_DATA_ALIVE(in)) continue;
eo_parent = in->smart.parent;
while (eo_parent)
{
if ((eo_parent == eo_obj) && !in->no_propagate)
return EINA_TRUE;
parent = EVAS_OBJECT_DATA_GET(eo_parent);
if (!EVAS_OBJECT_DATA_ALIVE(parent)) break;
eo_parent = parent->smart.parent;
}
}
return EINA_FALSE;
}
EAPI void
evas_event_refeed_event(Eo *eo_e, void *event_copy, Evas_Callback_Type event_type)
{

View File

@ -1632,6 +1632,11 @@ _evas_box_layout_stack(Eo *o, Evas_Object_Box_Data *priv, Evas_Object_Box_Data *
if ((new_w != child_w) || (new_h != child_h))
evas_object_resize(child, new_w, new_h);
if (priv->align.h >= 0.0)
off_x += (ow - new_w) * priv->align.h;
if (priv->align.v >= 0.0)
off_y += (oh - new_h) * priv->align.v;
evas_object_move(child, ox + off_x, oy + off_y);
if (old_child)

View File

@ -13,6 +13,8 @@
if (EINA_UNLIKELY(!EVAS_OBJECT_DATA_VALID(o))) return __VA_ARGS__; } while (0)
#define EVAS_OBJECT_DATA_ALIVE_CHECK(o, ...) do { \
if (EINA_UNLIKELY(!EVAS_OBJECT_DATA_ALIVE(o))) return __VA_ARGS__; } while (0)
#define EVAS_OBJECT_DATA_GET(eo_o) \
efl_data_scope_get((eo_o), EFL_CANVAS_OBJECT_CLASS)
#define EVAS_OBJECT_DATA_SAFE_GET(eo_o) \
(((eo_o) && efl_isa((eo_o), EFL_CANVAS_OBJECT_CLASS)) ? efl_data_scope_get((eo_o), EFL_CANVAS_OBJECT_CLASS) : NULL)

View File

@ -152,6 +152,8 @@ static void _transparent_do(Ecore_Evas *, int);
static void _avoid_damage_do(Ecore_Evas *, int);
static void _rotation_do(Ecore_Evas *, int, int);
#define SWAP_INT(a, b) do { a ^= b; b ^= a; a ^= b; } while (0)
static void
_ecore_evas_x_hints_update(Ecore_Evas *ee)
{
@ -835,16 +837,19 @@ _resize_shape_do(Ecore_Evas *ee)
if (einfo)
{
unsigned int foreground;
int fw = 0, fh = 0;
Ecore_X_GC gc;
evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
if (edata->mask) ecore_x_pixmap_free(edata->mask);
edata->mask = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, 1);
edata->mask = ecore_x_pixmap_new(ee->prop.window, ee->w + fw, ee->h + fh, 1);
foreground = 0;
gc = ecore_x_gc_new(edata->mask,
ECORE_X_GC_VALUE_MASK_FOREGROUND,
&foreground);
ecore_x_drawable_rectangle_fill(edata->mask, gc,
0, 0, ee->w, ee->h);
0, 0, ee->w + fw, ee->h + fh);
ecore_x_gc_free(gc);
einfo->info.mask = edata->mask;
if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
@ -1603,12 +1608,25 @@ _ecore_evas_x_event_window_destroy(void *data EINA_UNUSED, int type EINA_UNUSED,
return ECORE_CALLBACK_PASS_ON;
}
static inline void
_ecore_evas_x_shadow_update(Ecore_Evas *ee)
{
if (EINA_LIKELY(!ee->shadow.changed)) return;
int shadow[4] = { ee->shadow.l, ee->shadow.r, ee->shadow.t, ee->shadow.b };
ee->shadow.changed = EINA_FALSE;
ecore_x_window_prop_property_set(ee->prop.window,
ECORE_X_ATOM_GTK_FRAME_EXTENTS,
ECORE_X_ATOM_CARDINAL, 32, shadow, 4);
}
static Eina_Bool
_ecore_evas_x_event_window_configure(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
{
Ecore_Evas *ee;
Ecore_X_Event_Window_Configure *e;
Ecore_Evas_Engine_Data_X11 *edata;
int fw = 0, fh = 0, w, h;
e = event;
ee = ecore_event_window_match(e->win);
@ -1631,11 +1649,19 @@ _ecore_evas_x_event_window_configure(void *data EINA_UNUSED, int type EINA_UNUSE
if (ee->func.fn_move) ee->func.fn_move(ee);
}
}
if ((ee->w != e->w) || (ee->h != e->h) ||
(ee->req.w != e->w) || (ee->req.h != e->h))
_ecore_evas_x_shadow_update(ee);
evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
if (!ECORE_EVAS_PORTRAIT(ee))
SWAP_INT(fw, fh);
if (((ee->w + fw) != e->w) || ((ee->h + fh) != e->h) ||
((ee->req.w + fw) != e->w) || ((ee->req.h + fh) != e->h))
{
ee->w = e->w;
ee->h = e->h;
w = e->w;
h = e->h;
ee->w = w - fw;
ee->h = h - fh;
if (edata->configure_reqs == 0)
{
ee->req.w = ee->w;
@ -1643,13 +1669,13 @@ _ecore_evas_x_event_window_configure(void *data EINA_UNUSED, int type EINA_UNUSE
}
if (ECORE_EVAS_PORTRAIT(ee))
{
evas_output_size_set(ee->evas, ee->w, ee->h);
evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
evas_output_size_set(ee->evas, w, h);
evas_output_viewport_set(ee->evas, 0, 0, w, h);
}
else
{
evas_output_size_set(ee->evas, ee->h, ee->w);
evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
evas_output_size_set(ee->evas, h, w);
evas_output_viewport_set(ee->evas, 0, 0, h, w);
}
if (ee->prop.avoid_damage)
{
@ -2156,6 +2182,12 @@ _ecore_evas_x_resize(Ecore_Evas *ee, int w, int h)
{
Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data;
Eina_Bool changed = EINA_FALSE;
int fw = 0, fh = 0;
evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
if (ECORE_EVAS_PORTRAIT(ee)) SWAP_INT(fw, fh);
w -= fw;
h -= fh;
if ((ee->req.w != w) || (ee->req.h != h))
{
@ -2178,6 +2210,7 @@ _ecore_evas_x_resize(Ecore_Evas *ee, int w, int h)
}
}
_ecore_evas_x_shadow_update(ee);
if (edata->direct_resize)
{
if ((ee->w == w) && (ee->h == h)) return;
@ -2212,7 +2245,7 @@ _ecore_evas_x_resize(Ecore_Evas *ee, int w, int h)
{
edata->configure_coming = 1;
if (changed) edata->configure_reqs++;
if (ee->prop.window) ecore_x_window_resize(ee->prop.window, w, h);
if (ee->prop.window) ecore_x_window_resize(ee->prop.window, w + fw, h + fh);
}
}
@ -2310,10 +2343,16 @@ _ecore_evas_x_rotation_set_internal(Ecore_Evas *ee, int rotation, int resize,
{
int rot_dif;
Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data;
int fw = 0, fh = 0;
rot_dif = ee->rotation - rotation;
if (rot_dif < 0) rot_dif = -rot_dif;
evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
if (!PORTRAIT_CHECK(rotation))
SWAP_INT(fw, fh);
if (rot_dif != 180)
{
int minw, minh, maxw, maxh, basew, baseh, stepw, steph;
@ -2328,11 +2367,11 @@ _ecore_evas_x_rotation_set_internal(Ecore_Evas *ee, int rotation, int resize,
edata->configure_coming = 1;
if (!ee->prop.fullscreen)
{
ecore_x_window_resize(ee->prop.window, ee->req.h, ee->req.w);
ecore_x_window_resize(ee->prop.window, ee->req.h + fw, ee->req.w + fh);
ee->expecting_resize.w = ee->h;
ee->expecting_resize.h = ee->w;
evas_output_size_set(ee->evas, ee->req.h, ee->req.w);
evas_output_viewport_set(ee->evas, 0, 0, ee->req.h, ee->req.w);
evas_output_size_set(ee->evas, ee->req.h + fw, ee->req.w + fh);
evas_output_viewport_set(ee->evas, 0, 0, ee->req.h + fw, ee->req.w + fh);
}
else
{
@ -2351,11 +2390,12 @@ _ecore_evas_x_rotation_set_internal(Ecore_Evas *ee, int rotation, int resize,
evas_output_viewport_set(ee->evas, 0, 0, ee->req.h, ee->req.w);
}
if (ee->func.fn_resize) ee->func.fn_resize(ee);
fw = fh = 0;
}
if (PORTRAIT_CHECK(rotation))
evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.w, ee->req.h);
evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.w + fw, ee->req.h + fh);
else
evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.h, ee->req.w);
evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.h + fw, ee->req.w + fh);
}
else
{
@ -2402,9 +2442,9 @@ _ecore_evas_x_rotation_set_internal(Ecore_Evas *ee, int rotation, int resize,
if (ee->func.fn_resize) ee->func.fn_resize(ee);
if (ECORE_EVAS_PORTRAIT(ee))
evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
evas_damage_rectangle_add(ee->evas, 0, 0, ee->w + fw, ee->h + fh);
else
evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
evas_damage_rectangle_add(ee->evas, 0, 0, ee->h + fw, ee->w + fh);
}
}