efl window stacks - implement pop to for x11 in the portable way

This commit is contained in:
Carsten Haitzler 2016-12-22 15:11:02 +09:00
parent 176b0c8d03
commit cc5dd2bd87
7 changed files with 135 additions and 20 deletions

View File

@ -4,7 +4,9 @@
#include <Elementary.h>
static int level = 0;
static Evas_Object *popto_win = NULL;
static void _bt_popto(void *data, Evas_Object *obj, void *event_info);
static void _bt_pressed(void *data, Evas_Object *obj, void *event_info);
static Evas_Object *
@ -19,6 +21,8 @@ _win_new(Evas_Object *stack_top, const char *title)
elm_win_title_set(win, title);
elm_win_autodel_set(win, EINA_TRUE);
if (level == 3) popto_win = win;
bg = elm_bg_add(win);
evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_win_resize_object_add(win, bg);
@ -36,6 +40,17 @@ _win_new(Evas_Object *stack_top, const char *title)
elm_box_pack_end(bx, lb);
evas_object_show(lb);
if (level > 7)
{
bt = elm_button_add(win);
elm_object_text_set(bt, "Pop to level 3");
evas_object_smart_callback_add(bt, "clicked", _bt_popto, NULL);
evas_object_size_hint_fill_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
elm_box_pack_end(bx, bt);
evas_object_show(bt);
}
bt = elm_button_add(win);
elm_object_text_set(bt, "Push");
evas_object_smart_callback_add(bt, "clicked", _bt_pressed, stack_top);
@ -48,6 +63,12 @@ _win_new(Evas_Object *stack_top, const char *title)
return win;
}
static void
_bt_popto(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
elm_win_stack_pop_to(popto_win);
}
static void
_bt_pressed(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{

View File

@ -1387,6 +1387,15 @@ typedef enum _Ecore_X_Stack_Type
ECORE_X_STACK_LAST
} Ecore_X_Stack_Type;
typedef enum _Ecore_X_Stack_Position
{
ECORE_X_STACK_POSITION_NONE = 0,
ECORE_X_STACK_POSITION_BOTTOM = 1,
ECORE_X_STACK_POSITION_MIDDLE,
ECORE_X_STACK_POSITION_TOP,
ECORE_X_STACK_POSITION_LAST
} Ecore_X_Stack_Position;
/* Window layer constants */
#define ECORE_X_WINDOW_LAYER_BELOW 2
#define ECORE_X_WINDOW_LAYER_NORMAL 4
@ -2749,6 +2758,8 @@ EAPI Eina_Bool ecore_x_e_keyrouter_get(Ecore_X_Windo
EAPI void ecore_x_e_stack_type_set(Ecore_X_Window win, Ecore_X_Stack_Type stack_type);
EAPI Ecore_X_Stack_Type ecore_x_e_stack_type_get(Ecore_X_Window win);
EAPI void ecore_x_e_stack_position_set(Ecore_X_Window win, Ecore_X_Stack_Position stack_position);
EAPI Ecore_X_Stack_Position ecore_x_e_stack_position_get(Ecore_X_Window win);
#include <Ecore_X_Atoms.h>
#include <Ecore_X_Cursor.h>

View File

@ -313,6 +313,7 @@ EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_SLIDING_WIN_GEOMETRY;
/* for window stacks */
EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_STACK_TYPE;
EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_STACK_POSITION;
/* for SDB(Samsung Debug Bridge) */
EAPI extern Ecore_X_Atom ECORE_X_ATOM_SDB_SERVER_CONNECT;

View File

@ -329,6 +329,7 @@ EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_SLIDING_WIN_GEOMETRY = 0;
/* for window stacks */
EAPI Ecore_X_Atom ECORE_X_ATOM_E_STACK_TYPE = 0;
EAPI Ecore_X_Atom ECORE_X_ATOM_E_STACK_POSITION = 0;
/* for SDB(Samsung Debug Bridge) */
EAPI Ecore_X_Atom ECORE_X_ATOM_SDB_SERVER_CONNECT = 0;
@ -693,6 +694,7 @@ const Atom_Item atom_items[] =
{ "_E_WINDOW_PROFILE_CHANGE_DONE", &ECORE_X_ATOM_E_WINDOW_PROFILE_CHANGE_DONE },
{ "_E_STACK_TYPE", &ECORE_X_ATOM_E_STACK_TYPE },
{ "_E_STACK_POSITION", &ECORE_X_ATOM_E_STACK_POSITION },
{ "_E_DEICONIFY_APPROVE", &ECORE_X_ATOM_E_DEICONIFY_APPROVE },

View File

@ -2404,6 +2404,7 @@ EAPI void
ecore_x_e_stack_type_set(Ecore_X_Window win,
Ecore_X_Stack_Type stack_type)
{
unsigned int val = stack_type;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
EINA_SAFETY_ON_NULL_RETURN(_ecore_x_disp);
@ -2412,7 +2413,7 @@ ecore_x_e_stack_type_set(Ecore_X_Window win,
ecore_x_window_prop_property_del(win, ECORE_X_ATOM_E_STACK_TYPE);
else
ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_E_STACK_TYPE,
&stack_type, 1);
&val, 1);
}
EAPI Ecore_X_Stack_Type
@ -2430,3 +2431,35 @@ ecore_x_e_stack_type_get(Ecore_X_Window win)
if (val >= ECORE_X_STACK_LAST) val = ECORE_X_STACK_STANDARD;
return (Ecore_X_Stack_Type)val;
}
EAPI void
ecore_x_e_stack_position_set(Ecore_X_Window win,
Ecore_X_Stack_Position stack_position)
{
unsigned int val = stack_position;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
EINA_SAFETY_ON_NULL_RETURN(_ecore_x_disp);
if (stack_position == ECORE_X_STACK_POSITION_NONE)
ecore_x_window_prop_property_del(win, ECORE_X_ATOM_E_STACK_POSITION);
else
ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_E_STACK_POSITION,
&val, 1);
}
EAPI Ecore_X_Stack_Position
ecore_x_e_stack_position_get(Ecore_X_Window win)
{
int ret;
unsigned int val;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_x_disp, ECORE_X_STACK_NONE);
ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_E_STACK_POSITION,
&val, 1);
if (ret != 1) return ECORE_X_STACK_POSITION_NONE;
if (val >= ECORE_X_STACK_POSITION_LAST) val = ECORE_X_STACK_POSITION_BOTTOM;
return (Ecore_X_Stack_Position)val;
}

View File

@ -6150,7 +6150,7 @@ _efl_ui_win_stack_master_id_set(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, const
if (sd->shown) return;
eina_stringshare_replace(&(sd->stack_master_id), id);
#ifdef HAVE_ELEMENTARY_X
_elm_win_xwin_update(sd);
if (sd->x.xwin) _elm_win_xwin_update(sd);
#endif
}
@ -6173,15 +6173,70 @@ _efl_ui_win_stack_base_get(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
return sd->stack_base;
}
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)
#ifdef HAVE_ELEMENTARY_X
// list transient from bottom to top by recursive walking
static void
_x_transients_for_list(Ecore_X_Window base, Ecore_X_Window transient,
Ecore_X_Window **wins, int *num)
{
// 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
//
Ecore_X_Window t, *children, *w;
int n, i;
children = ecore_x_window_children_get(base, &n);
if (children)
{
for (i = 0; i < n; i++)
{
if (children[i] != transient)
{
t = ecore_x_icccm_transient_for_get(children[i]);
if (t == transient)
{
(*num)++;
w = realloc(*wins, *num * sizeof(Ecore_X_Window));
if (w)
{
*wins = w;
(*wins)[*num - 1] = children[i];
}
}
_x_transients_for_list(children[i], transient, wins, num);
}
}
free(children);
}
}
#endif
EOLIAN static void
_efl_ui_win_stack_pop_to(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
{
if (!sd->stack_master_id) return;
#ifdef HAVE_ELEMENTARY_X
if (sd->x.xwin)
{
Ecore_X_Window *wins = NULL;
int i, num = 0;
Eina_Bool del = EINA_FALSE;
ecore_x_grab();
_x_transients_for_list
(ecore_x_window_root_get(sd->x.xwin),
ecore_x_icccm_transient_for_get(sd->x.xwin),
&wins, &num);
if (wins)
{
for (i = 0; i < num; i++)
{
if (del) ecore_x_window_delete_request_send(wins[i]);
if (wins[i] == sd->x.xwin) del = EINA_TRUE;
}
free(wins);
}
ecore_x_ungrab();
}
#endif
// wayland - needs to be a special compositor request
// win32/osx ?
}

View File

@ -793,21 +793,13 @@ class Efl.Ui.Win (Elm.Widget, Efl.Canvas, Elm.Interface.Atspi.Window,
otherwise.]]
}
}
stack_pop_to_id {
stack_pop_to {
[[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.
are above the window.
@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.]]