efl_ui_win - add window "view stack" api's and ability

this adds the a stack of windows (view stack, something like naviframe
but using multiple windows instead) to elementary allowing windows to
be put into a stack and treated as one "application" when ijn such a
stack with the newest window on top being the active/focused one (or
should be). this allows for special show/hide animations as well as
possibly special sizing policies and placement policies.

@feature
This commit is contained in:
Carsten Haitzler 2016-12-08 17:49:23 +09:00
parent 489815457b
commit 48ac4747b1
2 changed files with 114 additions and 9 deletions

View File

@ -155,6 +155,8 @@ struct _Efl_Ui_Win_Data
const char *title;
const char *icon_name;
const char *role;
const char *stack_id;
const char *stack_master_id;
Eina_Stringshare *name;
Eina_Stringshare *accel_pref;
@ -256,6 +258,7 @@ struct _Efl_Ui_Win_Data
Eina_Bool application_alpha : 1; /**< alpha value set by an elm_win_alpha_set() api. this has lower priority than theme_alpha */
Eina_Bool tmp_updating_hints : 1;
Eina_Bool single_edje_content: 1; /* hack for E */
Eina_Bool shown : 1;
};
struct _Input_Pointer_Iterator
@ -2213,6 +2216,7 @@ _efl_ui_win_show(Eo *obj, Efl_Ui_Win_Data *sd)
{
Eina_Bool do_eval = EINA_FALSE;
sd->shown = EINA_TRUE;
if (sd->modal_count)
{
/* FIXME FIXME FIXME
@ -2794,6 +2798,8 @@ _efl_ui_win_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Win_Data *sd)
eina_stringshare_del(sd->role);
eina_stringshare_del(sd->name);
eina_stringshare_del(sd->accel_pref);
eina_stringshare_del(sd->stack_id);
eina_stringshare_del(sd->stack_master_id);
evas_object_del(sd->icon);
evas_object_del(sd->main_menu);
@ -3138,18 +3144,24 @@ _elm_win_xwin_update(Efl_Ui_Win_Data *sd)
if (sd->type == ELM_WIN_FAKE) return;
_internal_elm_win_xwindow_get(sd);
if (sd->parent)
{
ELM_WIN_DATA_GET(sd->parent, sdp);
if (sdp)
{
if (sd->x.xwin)
ecore_x_icccm_transient_for_set(sd->x.xwin, sdp->x.xwin);
}
}
if (!sd->x.xwin) return; /* nothing more to do */
if (sd->stack_master_id)
{
Ecore_X_Window win = atoi(sd->stack_master_id);
if (win) ecore_x_icccm_transient_for_set(sd->x.xwin, win);
// XXX: set property saying we are a stack window
}
else
{
if (sd->parent)
{
ELM_WIN_DATA_GET(sd->parent, sdp);
if (sdp) ecore_x_icccm_transient_for_set(sd->x.xwin, sdp->x.xwin);
}
}
s = sd->title;
if (!s) s = _elm_appname;
if (!s) s = "";
@ -6117,6 +6129,40 @@ _efl_ui_win_focus_highlight_animate_get(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd
return sd->focus_highlight.animate;
}
EOLIAN static const char *
_efl_ui_win_stack_id_get(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
{
return sd->stack_id;
}
EOLIAN static void
_efl_ui_win_stack_master_id_set(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, const char *id)
{
if (sd->shown) return;
eina_stringshare_replace(&(sd->stack_master_id), id);
#ifdef HAVE_ELEMENTARY_X
_elm_win_xwin_update(sd);
#endif
}
EOLIAN static const char *
_efl_ui_win_stack_master_id_get(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
{
return sd->stack_master_id;
}
EOLIAN static void
_efl_ui_win_stack_pop_to_id(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd EINA_UNUSED, const char *id EINA_UNUSED)
{
// if in e (x11+wl), ask e to nuke all windows in stack above this
// or
// in x11 - find all windows in the window tree with a transient
// for that have the SAME stack master as this one and that are
// stacked above this window, and delete them from bottom to top
//
// win32/osx ?
}
EOLIAN static Eina_Bool
_efl_ui_win_socket_listen(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, const char *svcname, int svcnum, Eina_Bool svcsys)
{

View File

@ -729,6 +729,65 @@ class Efl.Ui.Win (Elm.Widget, Efl.Canvas, Elm.Interface.Atspi.Window,
$false otherwise.]]
}
}
@property stack_id {
get {
[[Get the stack ID string of the window as an opaque string.
This ID is immutable and can never be modified. It will be
an opaque string that has no specific desfined format or
content other than it being a string (no character with a
value of 0).
This string is intended for use as a stack master ID to be
use by other windows to make this window part of a stack
of windows to be placed on top of eachother as if they are
a series of dialogs or questions one after the other and
that you may go back through history.
@since 1.19]]
}
values {
id: string; [[An opaque string that has no specific format,
but identified a specific unique window on the
display.]]
}
}
@property stack_master_id {
set {
[[Set the window stack ID to use as the master top-level.
This sets the ID string to be used as the master top-level
window as the base of a stack of windows. This must be set
before the first time the window is shown and should never
be changed after that point in time ever again.
@since 1.19]]
}
get {
[[Get the stack master Id that has been set.]]
}
values {
id: string; [[An opaque string that has no specific format,
but identified a specific unique window on the
display.]]
}
}
stack_pop_to_id {
[[Pop (delete) all windows in the stack above this window.
This will try and delete all the windows in the stack that
are above the window with the given stack ID given as the
ID string to ensure that this window is visible on top of
this stack and would be the active (focused) window if
the stack was active/focused.
@since 1.19]]
params {
@in id: string; [[An opaque string that has no specific format,
but identified a specific unique window on the
display.]]
}
}
socket_listen {
[[Create a socket to provide the service for Plug widget.]]
return: bool; [[$true on success, $false otherwise]]