giant comp rejiggering commit #3

* e menus are now drawn directly onto the compositor canvas

* menu theme now requires at least one part which allows mouse events in every menu group (YOUR MENUS WILL NOT WORK IF YOU ARE USING A THEME WHICH LACKS THIS!!!!!!!)

* menus now also report dangling/zombie menus with slightly more accuracy now
This commit is contained in:
discomfitor 2013-02-19 08:09:05 +00:00 committed by Mike Blumenkrantz
parent 7d0c1182c8
commit 0d16ba68cd
6 changed files with 168 additions and 281 deletions

View File

@ -1,3 +1,7 @@
2013-03-11 Mike Blumenkrantz
* menus are now drawn directly on the compositor canvas
2013-03-11 Dieter Roelants 2013-03-11 Dieter Roelants
* portability: Don't rely on bash or zsh behavior when starting enlightenment_init and tempget. * portability: Don't rely on bash or zsh behavior when starting enlightenment_init and tempget.

1
NEWS
View File

@ -122,6 +122,7 @@ Improvements:
* DND canvas merged to compositor * DND canvas merged to compositor
* shelf gadcon can no longer resize smaller than 16x16, ensuring dnd success * shelf gadcon can no longer resize smaller than 16x16, ensuring dnd success
* Don't rely on bash or zsh behavior when starting enlightenment_init and tempget. * Don't rely on bash or zsh behavior when starting enlightenment_init and tempget.
* menus are now drawn directly on the compositor canvas
Fixes: Fixes:
* IBar menu didn't allow to configure different icon sources, show contents menu even on empty IBar. * IBar menu didn't allow to configure different icon sources, show contents menu even on empty IBar.

View File

@ -193,6 +193,11 @@ group { name: "e/widgets/menu/default/item_bg";
visible: 1; visible: 1;
} }
} }
part { name: "events"; type: RECT;
description { state: "default";
color: 0 0 0 0;
}
}
} }
programs { programs {
program { program {
@ -216,7 +221,7 @@ group { name: "e/widgets/menu/default/item_bg";
group { name: "e/widgets/menu/default/icon"; group { name: "e/widgets/menu/default/icon";
parts { parts {
part { name: "clip"; type: RECT; part { name: "clip"; type: RECT; mouse_events: 0;
description { state: "default" 0.0; description { state: "default" 0.0;
color: 255 255 255 255; color: 255 255 255 255;
} }
@ -249,6 +254,11 @@ group { name: "e/widgets/menu/default/icon";
group { name: "e/widgets/menu/default/label"; group { name: "e/widgets/menu/default/label";
parts { parts {
part { name: "base"; type: RECT;
description { state: "default";
color: 0 0 0 0;
}
}
part { name: "e.text.label"; type: TEXT; mouse_events: 0; part { name: "e.text.label"; type: TEXT; mouse_events: 0;
effect: SHADOW BOTTOM; effect: SHADOW BOTTOM;
scale: 1; scale: 1;
@ -364,7 +374,7 @@ group { name: "e/widgets/menu/default/submenu";
images.image: "sym_right_glow_normal.png" COMP; images.image: "sym_right_glow_normal.png" COMP;
images.image: "vertical_separated_bar_glow.png" COMP; images.image: "vertical_separated_bar_glow.png" COMP;
parts { parts {
part { name: "base"; mouse_events: 0; part { name: "base";
description { state: "default" 0.0; description { state: "default" 0.0;
image.normal: "sym_right_light_normal.png"; image.normal: "sym_right_light_normal.png";
rel2.offset: -2 -1; rel2.offset: -2 -1;
@ -413,7 +423,7 @@ group { name: "e/widgets/menu/default/check";
images.image: "bevel_in.png" COMP; images.image: "bevel_in.png" COMP;
images.image: "sym_check_alum.png" COMP; images.image: "sym_check_alum.png" COMP;
parts { parts {
part { name: "base"; type: RECT; mouse_events: 0; part { name: "base"; type: RECT;
description { state: "default" 0.0; description { state: "default" 0.0;
rel1.offset: 1 1; rel1.offset: 1 1;
rel1.to: "inset"; rel1.to: "inset";
@ -478,7 +488,7 @@ group { name: "e/widgets/menu/default/radio";
images.image: "inset_shadow_circle_tiny.png" COMP; images.image: "inset_shadow_circle_tiny.png" COMP;
images.image: "sym_radio_alum.png" COMP; images.image: "sym_radio_alum.png" COMP;
parts { parts {
part { name: "base"; mouse_events: 0; part { name: "base";
description { state: "default" 0.0; description { state: "default" 0.0;
image.normal: "inset_shadow_circle_tiny.png"; image.normal: "inset_shadow_circle_tiny.png";
min: 13 13; min: 13 13;

View File

@ -476,8 +476,8 @@ _e_comp_win_geometry_update(E_Comp_Win *cw)
w = cw->pw, h = cw->ph; w = cw->pw, h = cw->ph;
if (cw->not_in_layout) if (cw->not_in_layout)
{ {
evas_object_move(cw->shobj, x, y);
evas_object_resize(cw->shobj, w, h); evas_object_resize(cw->shobj, w, h);
evas_object_move(cw->shobj, x, y);
} }
else else
{ {
@ -1507,6 +1507,7 @@ _e_comp_object_del(void *data, void *obj)
} }
else if (obj == cw->menu) else if (obj == cw->menu)
{ {
cw->menu->cw = NULL;
cw->menu = NULL; cw->menu = NULL;
evas_object_data_del(cw->shobj, "menu"); evas_object_data_del(cw->shobj, "menu");
} }
@ -1958,10 +1959,13 @@ _e_comp_win_dummy_add(E_Comp *c, Evas_Object *obj, E_Object *eobj, Eina_Bool nol
cw->dfn = e_object_delfn_add(E_OBJECT(cw->pop), _e_comp_object_del, cw); cw->dfn = e_object_delfn_add(E_OBJECT(cw->pop), _e_comp_object_del, cw);
cw->show_ready = cw->pop->visible; cw->show_ready = cw->pop->visible;
break; break;
//case E_MENU_TYPE: case E_MENU_TYPE:
//cw->menu = eobj; cw->menu = (void*)eobj;
//cw->menu->cw = cw; cw->menu->cw = cw;
//break; cw->shape = cw->menu->shape;
cw->dfn = e_object_delfn_add(E_OBJECT(cw->menu), _e_comp_object_del, cw);
cw->show_ready = cw->menu->cur.visible;
break;
default: default:
CRI("UNHANDLED"); CRI("UNHANDLED");
} }
@ -2035,12 +2039,7 @@ _e_comp_win_add(E_Comp *c, Ecore_X_Window win)
// _e_comp_win_sync_setup(cw, cw->bd->client.win); // _e_comp_win_sync_setup(cw, cw->bd->client.win);
} }
/* popups handled in _dummy_add */ /* popups handled in _dummy_add */
else if ((cw->menu = e_menu_find_by_window(cw->win))) /* menus handled in _dummy_add */
{
cw->dfn = e_object_delfn_add(E_OBJECT(cw->menu), _e_comp_object_del, cw);
cw->show_ready = 1;
cw->shape = cw->menu->shape;
}
// fixme: could use bd/pop/menu for this too // fixme: could use bd/pop/menu for this too
memset((&att), 0, sizeof(Ecore_X_Window_Attributes)); memset((&att), 0, sizeof(Ecore_X_Window_Attributes));
if (!ecore_x_window_attributes_get(cw->win, &att)) if (!ecore_x_window_attributes_get(cw->win, &att))
@ -2270,6 +2269,7 @@ _e_comp_win_del(E_Comp_Win *cw)
else if (cw->menu) else if (cw->menu)
{ {
e_object_delfn_del(E_OBJECT(cw->menu), cw->dfn); e_object_delfn_del(E_OBJECT(cw->menu), cw->dfn);
cw->menu->cw = NULL;
cw->menu = NULL; cw->menu = NULL;
} }
cw->dfn = NULL; cw->dfn = NULL;
@ -3613,10 +3613,8 @@ _e_comp_shapes_update_comp_win_shape_comp_helper(E_Comp_Win *cw, Eina_Tiler *tb)
x = cw->bd->x, y = cw->bd->y, w = cw->bd->w, h = cw->bd->h; x = cw->bd->x, y = cw->bd->y, w = cw->bd->w, h = cw->bd->h;
else if (cw->pop) else if (cw->pop)
x = cw->pop->x + cw->pop->zone->x, y = cw->pop->y + cw->pop->zone->y, w = cw->pop->w, h = cw->pop->h; x = cw->pop->x + cw->pop->zone->x, y = cw->pop->y + cw->pop->zone->y, w = cw->pop->w, h = cw->pop->h;
/* //else if (cw->menu)
else if (cw->menu) //x = cw->menu->x + cw->menu->zone->x, y = cw->menu->y + cw->menu->zone->y, w = cw->menu->w, h = cw->menu->h;
x = cw->menu->cur.x, y = cw->menu->cur.y, w = cw->menu->cur.w, h = cw->menu->cur.h;
*/
else else
x = cw->x, y = cw->y, w = cw->w, h = cw->h; x = cw->x, y = cw->y, w = cw->w, h = cw->h;
#ifdef SHAPE_DEBUG #ifdef SHAPE_DEBUG
@ -4888,6 +4886,8 @@ e_comp_get(void *o)
E_Border *bd; E_Border *bd;
E_Popup *pop; E_Popup *pop;
E_Shelf *es; E_Shelf *es;
E_Menu *m;
E_Menu_Item *mi;
E_Object *obj = o; E_Object *obj = o;
E_Zone *zone = NULL; E_Zone *zone = NULL;
E_Container *con = NULL; E_Container *con = NULL;
@ -4911,6 +4911,16 @@ e_comp_get(void *o)
obj = (void*)pop->zone; obj = (void*)pop->zone;
EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL); EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
break; break;
case E_MENU_TYPE:
m = (E_Menu*)obj;
obj = (void*)m->zone;
EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
break;
case E_MENU_ITEM_TYPE:
mi = (E_Menu_Item*)obj;
obj = (void*)mi->menu->zone;
EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
break;
case E_SHELF_TYPE: case E_SHELF_TYPE:
es = (E_Shelf*)obj; es = (E_Shelf*)obj;
obj = (void*)es->zone; obj = (void*)es->zone;

View File

@ -70,7 +70,6 @@ static void _e_menu_cb_intercept_item_move(void *data, Evas_Object *o, E
static void _e_menu_cb_intercept_item_resize(void *data, Evas_Object *o, Evas_Coord w, Evas_Coord h); static void _e_menu_cb_intercept_item_resize(void *data, Evas_Object *o, Evas_Coord w, Evas_Coord h);
static void _e_menu_cb_intercept_container_move(void *data, Evas_Object *o, Evas_Coord x, Evas_Coord y); static void _e_menu_cb_intercept_container_move(void *data, Evas_Object *o, Evas_Coord x, Evas_Coord y);
static void _e_menu_cb_intercept_container_resize(void *data, Evas_Object *o, Evas_Coord w, Evas_Coord h); static void _e_menu_cb_intercept_container_resize(void *data, Evas_Object *o, Evas_Coord w, Evas_Coord h);
static void _e_menu_cb_ecore_evas_resize(Ecore_Evas *ee);
static void _e_menu_cb_item_in(void *data, Evas *evas, Evas_Object *obj, void *event_info); static void _e_menu_cb_item_in(void *data, Evas *evas, Evas_Object *obj, void *event_info);
static void _e_menu_cb_item_out(void *data, Evas *evas, Evas_Object *obj, void *event_info); static void _e_menu_cb_item_out(void *data, Evas *evas, Evas_Object *obj, void *event_info);
static Eina_Bool _e_menu_cb_key_down(void *data, int type, void *event); static Eina_Bool _e_menu_cb_key_down(void *data, int type, void *event);
@ -80,14 +79,12 @@ static Eina_Bool _e_menu_cb_mouse_up(void *data, int type, void *event);
static Eina_Bool _e_menu_cb_mouse_move(void *data, int type, void *event); static Eina_Bool _e_menu_cb_mouse_move(void *data, int type, void *event);
static Eina_Bool _e_menu_cb_mouse_wheel(void *data, int type, void *event); static Eina_Bool _e_menu_cb_mouse_wheel(void *data, int type, void *event);
static Eina_Bool _e_menu_cb_scroll_animator(void *data); static Eina_Bool _e_menu_cb_scroll_animator(void *data);
static Eina_Bool _e_menu_cb_window_shape(void *data, int ev_type, void *ev);
static void _e_menu_cb_item_submenu_post_default(void *data, E_Menu *m, E_Menu_Item *mi); static void _e_menu_cb_item_submenu_post_default(void *data, E_Menu *m, E_Menu_Item *mi);
static Eina_Bool _e_menu_categories_free_cb(const Eina_Hash *hash, const void *key, void *data, void *fdata); static Eina_Bool _e_menu_categories_free_cb(const Eina_Hash *hash, const void *key, void *data, void *fdata);
/* local subsystem globals */ /* local subsystem globals */
static Ecore_X_Window _e_menu_win = 0; static Ecore_X_Window _e_menu_win = 0;
static Eina_List *_e_active_menus = NULL; static Eina_List *_e_active_menus = NULL;
static Eina_Hash *_e_menu_hash = NULL;
static E_Menu_Item *_e_active_menu_item = NULL; static E_Menu_Item *_e_active_menu_item = NULL;
static E_Menu_Item *_e_prev_active_menu_item = NULL; static E_Menu_Item *_e_prev_active_menu_item = NULL;
/*static Eina_Hash *_e_menu_category_items = NULL;*/ /*static Eina_Hash *_e_menu_category_items = NULL;*/
@ -109,7 +106,6 @@ static Ecore_Event_Handler *_e_menu_mouse_down_handler = NULL;
static Ecore_Event_Handler *_e_menu_mouse_up_handler = NULL; static Ecore_Event_Handler *_e_menu_mouse_up_handler = NULL;
static Ecore_Event_Handler *_e_menu_mouse_move_handler = NULL; static Ecore_Event_Handler *_e_menu_mouse_move_handler = NULL;
static Ecore_Event_Handler *_e_menu_mouse_wheel_handler = NULL; static Ecore_Event_Handler *_e_menu_mouse_wheel_handler = NULL;
static Ecore_Event_Handler *_e_menu_window_shape_handler = NULL;
static Eina_Bool _e_menu_lock = EINA_FALSE; static Eina_Bool _e_menu_lock = EINA_FALSE;
static Eina_List * static Eina_List *
@ -178,12 +174,8 @@ e_menu_init(void)
_e_menu_mouse_wheel_handler = _e_menu_mouse_wheel_handler =
ecore_event_handler_add(ECORE_EVENT_MOUSE_WHEEL, ecore_event_handler_add(ECORE_EVENT_MOUSE_WHEEL,
_e_menu_cb_mouse_wheel, NULL); _e_menu_cb_mouse_wheel, NULL);
_e_menu_window_shape_handler =
ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHAPE,
_e_menu_cb_window_shape, NULL);
_e_menu_categories = eina_hash_string_superfast_new(NULL); _e_menu_categories = eina_hash_string_superfast_new(NULL);
if (!_e_menu_hash) _e_menu_hash = eina_hash_string_superfast_new(NULL);
e_int_menus_init(); e_int_menus_init();
return 1; return 1;
} }
@ -199,7 +191,6 @@ e_menu_shutdown(void)
E_FREE_FUNC(_e_menu_mouse_up_handler, ecore_event_handler_del); E_FREE_FUNC(_e_menu_mouse_up_handler, ecore_event_handler_del);
E_FREE_FUNC(_e_menu_mouse_move_handler, ecore_event_handler_del); E_FREE_FUNC(_e_menu_mouse_move_handler, ecore_event_handler_del);
E_FREE_FUNC(_e_menu_mouse_wheel_handler, ecore_event_handler_del); E_FREE_FUNC(_e_menu_mouse_wheel_handler, ecore_event_handler_del);
E_FREE_FUNC(_e_menu_window_shape_handler, ecore_event_handler_del);
if (!x_fatal) if (!x_fatal)
{ {
@ -219,11 +210,6 @@ e_menu_shutdown(void)
_e_menu_categories = NULL; _e_menu_categories = NULL;
} }
if (_e_menu_hash)
{
eina_hash_free(_e_menu_hash);
_e_menu_hash = NULL;
}
_e_menu_lock = EINA_FALSE; _e_menu_lock = EINA_FALSE;
e_int_menus_shutdown(); e_int_menus_shutdown();
@ -760,17 +746,20 @@ e_menu_item_submenu_set(E_Menu_Item *mi, E_Menu *sub)
{ {
Eina_Bool submenu = EINA_FALSE; Eina_Bool submenu = EINA_FALSE;
Evas_Object *o; Evas_Object *o;
Eina_List *tmp = NULL;
int ww, hh; int ww, hh;
E_OBJECT_CHECK(mi); E_OBJECT_CHECK(mi);
E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE); E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE);
tmp = _e_active_menus_copy_ref();
submenu = !!mi->submenu; submenu = !!mi->submenu;
if (mi->submenu) e_object_unref(E_OBJECT(mi->submenu)); if (mi->submenu) e_object_unref(E_OBJECT(mi->submenu));
if (sub) e_object_ref(E_OBJECT(sub)); if (sub) e_object_ref(E_OBJECT(sub));
mi->submenu = sub; mi->submenu = sub;
mi->changed = 1; mi->changed = 1;
mi->menu->changed = 1; mi->menu->changed = 1;
if (!!sub == submenu) return; if (!!sub == submenu) goto out;
if (!mi->bg_object) return; if (!mi->bg_object) goto out;
if (sub) e_object_ref(E_OBJECT(sub)); if (sub) e_object_ref(E_OBJECT(sub));
_e_menu_lock = EINA_TRUE; _e_menu_lock = EINA_TRUE;
if ((mi->submenu) || (mi->submenu_pre_cb.func)) if ((mi->submenu) || (mi->submenu_pre_cb.func))
@ -792,7 +781,7 @@ e_menu_item_submenu_set(E_Menu_Item *mi, E_Menu *sub)
ww, hh, /* min */ ww, hh, /* min */
-1, -1 /* max */ -1, -1 /* max */
); );
return; goto out;
} }
evas_object_del(mi->submenu_object); evas_object_del(mi->submenu_object);
} }
@ -841,11 +830,13 @@ e_menu_item_submenu_set(E_Menu_Item *mi, E_Menu *sub)
{ {
if (e_theme_edje_object_set(mi->bg_object, "base/theme/menus", if (e_theme_edje_object_set(mi->bg_object, "base/theme/menus",
"e/widgets/menu/default/submenu_bg")) "e/widgets/menu/default/submenu_bg"))
return; goto out;
} }
e_theme_edje_object_set(mi->bg_object, "base/theme/menus", e_theme_edje_object_set(mi->bg_object, "base/theme/menus",
"e/widgets/menu/default/item_bg"); "e/widgets/menu/default/item_bg");
out:
_e_menu_list_free_unref(tmp);
} }
EAPI void EAPI void
@ -1005,6 +996,8 @@ e_menu_item_drag_callback_set(E_Menu_Item *mi, void (*func)(void *data, E_Menu *
EAPI void EAPI void
e_menu_item_active_set(E_Menu_Item *mi, int active) e_menu_item_active_set(E_Menu_Item *mi, int active)
{ {
Eina_List *tmp = NULL;
E_OBJECT_CHECK(mi); E_OBJECT_CHECK(mi);
E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE); E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE);
if (mi->separator) return; if (mi->separator) return;
@ -1016,7 +1009,10 @@ e_menu_item_active_set(E_Menu_Item *mi, int active)
pmi = _e_menu_item_active_get(); pmi = _e_menu_item_active_get();
if (mi == pmi) return; if (mi == pmi) return;
if (pmi) if (pmi)
e_menu_item_active_set(pmi, 0); {
tmp = _e_active_menus_copy_ref();
e_menu_item_active_set(pmi, 0);
}
if (_e_prev_active_menu_item && (mi != _e_prev_active_menu_item)) if (_e_prev_active_menu_item && (mi != _e_prev_active_menu_item))
{ {
if (_e_prev_active_menu_item != mi->menu->parent_item) if (_e_prev_active_menu_item != mi->menu->parent_item)
@ -1049,6 +1045,7 @@ e_menu_item_active_set(E_Menu_Item *mi, int active)
} }
else if ((!active) && (mi->active)) else if ((!active) && (mi->active))
{ {
tmp = _e_active_menus_copy_ref();
mi->active = 0; mi->active = 0;
_e_prev_active_menu_item = mi; _e_prev_active_menu_item = mi;
_e_active_menu_item = NULL; _e_active_menu_item = NULL;
@ -1074,6 +1071,7 @@ e_menu_item_active_set(E_Menu_Item *mi, int active)
} }
edje_object_signal_emit(mi->menu->bg_object, "e,state,unselected", "e"); edje_object_signal_emit(mi->menu->bg_object, "e,state,unselected", "e");
} }
_e_menu_list_free_unref(tmp);
} }
EAPI E_Menu_Item * EAPI E_Menu_Item *
@ -1135,8 +1133,7 @@ e_menu_idler_before(void)
if ((!m->cur.visible) && (m->prev.visible)) if ((!m->cur.visible) && (m->prev.visible))
{ {
m->prev.visible = m->cur.visible; m->prev.visible = m->cur.visible;
ecore_evas_hide(m->ecore_evas); if (m->cw) e_comp_win_hide(m->cw);
e_container_shape_hide(m->shape);
} }
} }
/* phase 2. move & reisze all the menus that want to moves/resized */ /* phase 2. move & reisze all the menus that want to moves/resized */
@ -1155,8 +1152,8 @@ e_menu_idler_before(void)
m->prev.h = m->cur.h; m->prev.h = m->cur.h;
w = m->cur.w; w = m->cur.w;
h = m->cur.h; h = m->cur.h;
ecore_evas_resize(m->ecore_evas, w, h); if (m->cw)
e_container_shape_resize(m->shape, w, h); e_comp_win_resize(m->cw, w, h);
} }
if (((m->cur.x) != (m->prev.x)) || if (((m->cur.x) != (m->prev.x)) ||
((m->cur.y) != (m->prev.y))) ((m->cur.y) != (m->prev.y)))
@ -1179,8 +1176,9 @@ e_menu_idler_before(void)
} }
m->prev.x = m->cur.x; m->prev.x = m->cur.x;
m->prev.y = m->cur.y; m->prev.y = m->cur.y;
ecore_evas_move(m->ecore_evas, m->cur.x, m->cur.y); if (m->cw)
e_container_shape_move(m->shape, m->cur.x, m->cur.y); e_comp_win_move(m->cw, m->cur.x, m->cur.y);
} }
} }
} }
@ -1192,17 +1190,22 @@ e_menu_idler_before(void)
if ((m->cur.visible) && (!m->prev.visible)) if ((m->cur.visible) && (!m->prev.visible))
{ {
m->prev.visible = m->cur.visible; m->prev.visible = m->cur.visible;
ecore_evas_raise(m->ecore_evas); if (!m->cw)
ecore_evas_show(m->ecore_evas); {
if (!m->shaped) e_container_shape_show(m->shape); evas_object_move(m->bg_object, m->cur.x, m->cur.y);
evas_object_resize(m->bg_object, m->cur.w, m->cur.h);
E_LAYER_SET(m->bg_object, E_COMP_CANVAS_LAYER_MENU);
}
e_comp_win_show(m->cw);
} }
} }
/* phase 4. de-activate... */ /* phase 4. de-activate... */
EINA_LIST_FOREACH(_e_active_menus, l, m) EINA_LIST_REVERSE_FOREACH(_e_active_menus, l, m)
{ {
if (!m->active) if (!m->active)
{ {
_e_menu_unrealize(m); if (m->cw) e_comp_win_del(m->cw);
else _e_menu_unrealize(m);
removals = eina_list_append(removals, m); removals = eina_list_append(removals, m);
} }
} }
@ -1215,59 +1218,6 @@ e_menu_idler_before(void)
e_object_unref(E_OBJECT(m)); e_object_unref(E_OBJECT(m));
} }
} }
/* phase 5. shapes... */
EINA_LIST_FOREACH(_e_active_menus, l, m)
{
if (m->need_shape_export)
{
Ecore_X_Rectangle *rects, *orects;
int num = 0;
rects = ecore_x_window_shape_rectangles_get(m->evas_win, &num);
if (rects)
{
int changed = 1;
if ((num == m->shape_rects_num) && (m->shape_rects))
{
int i = 0;
orects = m->shape_rects;
for (i = 0; i < num; i++)
{
if ((orects[i].x != rects[i].x) ||
(orects[i].y != rects[i].y) ||
(orects[i].width != rects[i].width) ||
(orects[i].height != rects[i].height))
{
changed = 1;
break;
}
}
// TODO: This is meaningless
changed = 0;
}
if (changed)
{
E_FREE(m->shape_rects);
m->shape_rects = rects;
m->shape_rects_num = num;
e_container_shape_rects_set(m->shape, rects, num);
}
else
free(rects);
}
else
{
E_FREE(m->shape_rects);
m->shape_rects = NULL;
m->shape_rects_num = 0;
e_container_shape_rects_set(m->shape, NULL, 0);
}
m->need_shape_export = 0;
if (m->cur.visible) e_container_shape_show(m->shape);
}
}
/* del refcount to all menus we worked with */ /* del refcount to all menus we worked with */
_e_menu_list_free_unref(tmp); _e_menu_list_free_unref(tmp);
@ -1275,8 +1225,7 @@ e_menu_idler_before(void)
{ {
if (_e_menu_win) if (_e_menu_win)
{ {
ecore_x_window_free(_e_menu_win); e_grabinput_release(0, _e_menu_win);
e_grabinput_release(_e_menu_win, _e_menu_win);
_e_menu_win = 0; _e_menu_win = 0;
} }
} }
@ -1288,18 +1237,13 @@ e_menu_grab_window_get(void)
return _e_menu_win; return _e_menu_win;
} }
EAPI E_Menu * /* local subsystem functions */
e_menu_find_by_window(Ecore_X_Window win) static void
_e_menu_dangling_cb(void *data)
{ {
E_Menu *m; WRN("DANGLING SUBMENU: REF(%d)||MENU(%p)", e_object_ref_get(data), data);
m = eina_hash_find(_e_menu_hash, e_util_winid_str_get(win));
if ((m) && (m->evas_win != win))
return NULL;
return m;
} }
/* local subsystem functions */
static void static void
_e_menu_free(E_Menu *m) _e_menu_free(E_Menu *m)
{ {
@ -1320,16 +1264,14 @@ _e_menu_free(E_Menu *m)
} }
if (m->parent_item) if (m->parent_item)
m->parent_item->submenu = NULL; m->parent_item->submenu = NULL;
_e_menu_unrealize(m); /* del callback causes this to unrealize the menu */
E_FREE(m->shape_rects); if (m->bg_object) evas_object_del(m->bg_object);
m->shape_rects_num = 0;
EINA_LIST_FOREACH_SAFE(m->items, l, l_next, mi) EINA_LIST_FOREACH_SAFE(m->items, l, l_next, mi)
e_object_del(E_OBJECT(mi)); e_object_del(E_OBJECT(mi));
if (m->in_active_list) if (m->in_active_list)
{ {
_e_active_menus = eina_list_remove(_e_active_menus, m); _e_active_menus = eina_list_remove(_e_active_menus, m);
m->in_active_list = 0; m->in_active_list = 0;
e_object_unref(E_OBJECT(m));
} }
if (m->header.title) eina_stringshare_del(m->header.title); if (m->header.title) eina_stringshare_del(m->header.title);
if (m->header.icon_file) eina_stringshare_del(m->header.icon_file); if (m->header.icon_file) eina_stringshare_del(m->header.icon_file);
@ -1358,7 +1300,11 @@ _e_menu_item_free(E_Menu_Item *mi)
e_object_unref(E_OBJECT(mi->submenu)); e_object_unref(E_OBJECT(mi->submenu));
} }
if (ref) if (ref)
WRN("DANGLING SUBMENU FOR %s: REF(%d)||MENU(%p)", mi->label, ref, mi->submenu); {
if (!mi->submenu->dangling_job)
mi->submenu->dangling_job = ecore_job_add(_e_menu_dangling_cb, mi->submenu);
mi->submenu->parent_item = NULL;
}
} }
if (mi->menu->realized) _e_menu_item_unrealize(mi); if (mi->menu->realized) _e_menu_item_unrealize(mi);
mi->menu->items = eina_list_remove(mi->menu->items, mi); mi->menu->items = eina_list_remove(mi->menu->items, mi);
@ -1376,7 +1322,6 @@ _e_menu_cb_intercept_item_move(void *data, Evas_Object *o, Evas_Coord x, Evas_Co
mi = data; mi = data;
mi->x = x; mi->x = x;
mi->y = y; mi->y = y;
evas_object_move(mi->event_object, x, y);
evas_object_move(o, x, y); evas_object_move(o, x, y);
if ((mi->submenu) && (mi->submenu->parent_item)) if ((mi->submenu) && (mi->submenu->parent_item))
{ {
@ -1393,7 +1338,6 @@ _e_menu_cb_intercept_item_resize(void *data, Evas_Object *o, Evas_Coord w, Evas_
mi = data; mi = data;
mi->w = w; mi->w = w;
mi->h = h; mi->h = h;
evas_object_resize(mi->event_object, w, h);
evas_object_resize(o, w, h); evas_object_resize(o, w, h);
if ((mi->submenu) && (mi->submenu->parent_item)) if ((mi->submenu) && (mi->submenu->parent_item))
_e_menu_reposition(mi->submenu); _e_menu_reposition(mi->submenu);
@ -1423,6 +1367,15 @@ _e_menu_cb_intercept_container_resize(void *data, Evas_Object *o, Evas_Coord w,
evas_object_resize(o, w, h); evas_object_resize(o, w, h);
} }
static void
_e_menu_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
E_Menu *m = data;
m->bg_object = NULL;
_e_menu_unrealize(m);
}
static void static void
_e_menu_item_realize(E_Menu_Item *mi) _e_menu_item_realize(E_Menu_Item *mi)
{ {
@ -1446,9 +1399,12 @@ _e_menu_item_realize(E_Menu_Item *mi)
{ {
o = edje_object_add(mi->menu->evas); o = edje_object_add(mi->menu->evas);
mi->bg_object = o; mi->bg_object = o;
evas_object_name_set(o, "mi->bg_object");
evas_object_data_set(o, "e_menu_item", mi);
evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_IN, _e_menu_cb_item_in, mi);
evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_OUT, _e_menu_cb_item_out, mi);
evas_object_intercept_move_callback_add(o, _e_menu_cb_intercept_item_move, mi); evas_object_intercept_move_callback_add(o, _e_menu_cb_intercept_item_move, mi);
evas_object_intercept_resize_callback_add(o, _e_menu_cb_intercept_item_resize, mi); evas_object_intercept_resize_callback_add(o, _e_menu_cb_intercept_item_resize, mi);
if ((mi->submenu) || (mi->submenu_pre_cb.func)) if ((mi->submenu) || (mi->submenu_pre_cb.func))
{ {
if (!e_theme_edje_object_set(mi->bg_object, "base/theme/menus", if (!e_theme_edje_object_set(mi->bg_object, "base/theme/menus",
@ -1464,6 +1420,7 @@ no_submenu_item:
evas_object_show(o); evas_object_show(o);
o = e_box_add(mi->menu->evas); o = e_box_add(mi->menu->evas);
evas_object_name_set(o, "mi->container_object");
e_box_homogenous_set(o, 0); e_box_homogenous_set(o, 0);
mi->container_object = o; mi->container_object = o;
e_box_orientation_set(o, 1); e_box_orientation_set(o, 1);
@ -1474,10 +1431,10 @@ no_submenu_item:
if (mi->check) if (mi->check)
{ {
o = edje_object_add(mi->menu->evas); o = edje_object_add(mi->menu->evas);
evas_object_name_set(o, "mi->toggle_object");
mi->toggle_object = o; mi->toggle_object = o;
e_theme_edje_object_set(o, "base/theme/menus", e_theme_edje_object_set(o, "base/theme/menus",
"e/widgets/menu/default/check"); "e/widgets/menu/default/check");
evas_object_pass_events_set(o, 1);
evas_object_show(o); evas_object_show(o);
e_box_pack_end(mi->container_object, o); e_box_pack_end(mi->container_object, o);
edje_object_size_min_calc(mi->toggle_object, &ww, &hh); edje_object_size_min_calc(mi->toggle_object, &ww, &hh);
@ -1494,10 +1451,10 @@ no_submenu_item:
else if (mi->radio) else if (mi->radio)
{ {
o = edje_object_add(mi->menu->evas); o = edje_object_add(mi->menu->evas);
evas_object_name_set(o, "mi->toggle_object");
mi->toggle_object = o; mi->toggle_object = o;
e_theme_edje_object_set(o, "base/theme/menus", e_theme_edje_object_set(o, "base/theme/menus",
"e/widgets/menu/default/radio"); "e/widgets/menu/default/radio");
evas_object_pass_events_set(o, 1);
evas_object_show(o); evas_object_show(o);
e_box_pack_end(mi->container_object, o); e_box_pack_end(mi->container_object, o);
edje_object_size_min_calc(mi->toggle_object, &ww, &hh); edje_object_size_min_calc(mi->toggle_object, &ww, &hh);
@ -1514,9 +1471,9 @@ no_submenu_item:
else else
{ {
o = evas_object_rectangle_add(mi->menu->evas); o = evas_object_rectangle_add(mi->menu->evas);
evas_object_name_set(o, "mi->toggle_object");
mi->toggle_object = o; mi->toggle_object = o;
evas_object_color_set(o, 0, 0, 0, 0); evas_object_color_set(o, 0, 0, 0, 0);
evas_object_pass_events_set(o, 1);
e_box_pack_end(mi->container_object, o); e_box_pack_end(mi->container_object, o);
} }
if ((!e_config->menu_icons_hide) && ((mi->icon) || (mi->realize_cb.func))) if ((!e_config->menu_icons_hide) && ((mi->icon) || (mi->realize_cb.func)))
@ -1527,6 +1484,7 @@ no_submenu_item:
if (e_theme_edje_object_set(o, "base/theme/menus", if (e_theme_edje_object_set(o, "base/theme/menus",
"e/widgets/menu/default/icon")) "e/widgets/menu/default/icon"))
{ {
evas_object_name_set(o, "mi->icon_bg_object");
mi->icon_bg_object = o; mi->icon_bg_object = o;
evas_object_show(o); evas_object_show(o);
} }
@ -1535,6 +1493,7 @@ no_submenu_item:
evas_object_del(o); evas_object_del(o);
o = NULL; o = NULL;
} }
//if (o) evas_object_pass_events_set(o, 1);
/* FIXME: Not sure why there are two different tries to get the icon size, surely only the last one si needed. */ /* FIXME: Not sure why there are two different tries to get the icon size, surely only the last one si needed. */
/* FIXME: Do it this way later, when e_app_icon_add() just registers a request for an icon to be filled in when it's ready. /* FIXME: Do it this way later, when e_app_icon_add() just registers a request for an icon to be filled in when it's ready.
@ -1557,6 +1516,7 @@ no_submenu_item:
if (edje_object_file_set(o, mi->icon, mi->icon_key)) if (edje_object_file_set(o, mi->icon, mi->icon_key))
{ {
mi->icon_object = o; mi->icon_object = o;
evas_object_name_set(o, "mi->icon_object");
edje_object_size_max_get(o, &iww, &ihh); edje_object_size_max_get(o, &iww, &ihh);
icon_w = iww; icon_w = iww;
icon_h = ihh; icon_h = ihh;
@ -1570,6 +1530,7 @@ no_submenu_item:
if (!mi->icon_object) if (!mi->icon_object)
{ {
o = e_icon_add(mi->menu->evas); o = e_icon_add(mi->menu->evas);
evas_object_name_set(o, "mi->icon_object");
mi->icon_object = o; mi->icon_object = o;
e_icon_scale_size_set(o, e_util_icon_size_normalize(24 * e_scale)); e_icon_scale_size_set(o, e_util_icon_size_normalize(24 * e_scale));
e_icon_preload_set(mi->icon_object, 1); e_icon_preload_set(mi->icon_object, 1);
@ -1585,7 +1546,6 @@ no_submenu_item:
e_icon_size_get(o, &icon_w, &icon_h); e_icon_size_get(o, &icon_w, &icon_h);
} }
evas_object_pass_events_set(o, 1);
evas_object_show(o); evas_object_show(o);
if (mi->icon_bg_object) if (mi->icon_bg_object)
@ -1609,6 +1569,7 @@ no_submenu_item:
else else
{ {
o = edje_object_add(mi->menu->evas); o = edje_object_add(mi->menu->evas);
evas_object_name_set(o, "mi->icon_bg_object");
e_icon_size_get(mi->icon_object, &icon_w, &icon_h); e_icon_size_get(mi->icon_object, &icon_w, &icon_h);
mi->icon_w = icon_w; mi->icon_w = icon_w;
mi->icon_h = icon_h; mi->icon_h = icon_h;
@ -1625,21 +1586,21 @@ no_submenu_item:
else else
{ {
o = evas_object_rectangle_add(mi->menu->evas); o = evas_object_rectangle_add(mi->menu->evas);
evas_object_name_set(o, "mi->icon_object");
mi->icon_object = o; mi->icon_object = o;
evas_object_color_set(o, 0, 0, 0, 0); evas_object_color_set(o, 0, 0, 0, 0);
evas_object_pass_events_set(o, 1);
e_box_pack_end(mi->container_object, o); e_box_pack_end(mi->container_object, o);
} }
if (mi->label) if (mi->label)
{ {
o = edje_object_add(mi->menu->evas); o = edje_object_add(mi->menu->evas);
evas_object_name_set(o, "mi->label_object");
mi->label_object = o; mi->label_object = o;
e_theme_edje_object_set(o, "base/theme/menus", e_theme_edje_object_set(o, "base/theme/menus",
"e/widgets/menu/default/label"); "e/widgets/menu/default/label");
/* default label */ /* default label */
edje_object_part_text_set(o, "e.text.label", mi->label); edje_object_part_text_set(o, "e.text.label", mi->label);
evas_object_pass_events_set(o, 1);
evas_object_show(o); evas_object_show(o);
e_box_pack_end(mi->container_object, o); e_box_pack_end(mi->container_object, o);
edje_object_size_min_calc(mi->label_object, &ww, &hh); edje_object_size_min_calc(mi->label_object, &ww, &hh);
@ -1656,18 +1617,18 @@ no_submenu_item:
else else
{ {
o = evas_object_rectangle_add(mi->menu->evas); o = evas_object_rectangle_add(mi->menu->evas);
evas_object_name_set(o, "mi->label_object");
mi->label_object = o; mi->label_object = o;
evas_object_color_set(o, 0, 0, 0, 0); evas_object_color_set(o, 0, 0, 0, 0);
evas_object_pass_events_set(o, 1);
e_box_pack_end(mi->container_object, o); e_box_pack_end(mi->container_object, o);
} }
if ((mi->submenu) || (mi->submenu_pre_cb.func)) if ((mi->submenu) || (mi->submenu_pre_cb.func))
{ {
o = edje_object_add(mi->menu->evas); o = edje_object_add(mi->menu->evas);
evas_object_name_set(o, "mi->submenu_object");
mi->submenu_object = o; mi->submenu_object = o;
e_theme_edje_object_set(o, "base/theme/menus", e_theme_edje_object_set(o, "base/theme/menus",
"e/widgets/menu/default/submenu"); "e/widgets/menu/default/submenu");
evas_object_pass_events_set(o, 1);
evas_object_show(o); evas_object_show(o);
e_box_pack_end(mi->container_object, o); e_box_pack_end(mi->container_object, o);
edje_object_size_min_calc(mi->submenu_object, &ww, &hh); edje_object_size_min_calc(mi->submenu_object, &ww, &hh);
@ -1684,26 +1645,15 @@ no_submenu_item:
else else
{ {
o = evas_object_rectangle_add(mi->menu->evas); o = evas_object_rectangle_add(mi->menu->evas);
evas_object_name_set(o, "mi->submenu_object");
mi->submenu_object = o; mi->submenu_object = o;
evas_object_color_set(o, 0, 0, 0, 0); evas_object_color_set(o, 0, 0, 0, 0);
evas_object_pass_events_set(o, 1);
e_box_pack_end(mi->container_object, o); e_box_pack_end(mi->container_object, o);
} }
edje_object_part_swallow(mi->bg_object, "e.swallow.content", edje_object_part_swallow(mi->bg_object, "e.swallow.content",
mi->container_object); mi->container_object);
o = evas_object_rectangle_add(mi->menu->evas);
evas_object_color_set(o, 0, 0, 0, 0);
//evas_object_layer_set(o, 1); FIXME: COMP
evas_object_repeat_events_set(o, 1);
evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_IN,
_e_menu_cb_item_in, mi);
evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_OUT,
_e_menu_cb_item_out, mi);
evas_object_show(o);
mi->event_object = o;
e_box_pack_end(mi->menu->container_object, mi->bg_object); e_box_pack_end(mi->menu->container_object, mi->bg_object);
e_box_thaw(mi->container_object); e_box_thaw(mi->container_object);
} }
@ -1718,72 +1668,32 @@ _e_menu_realize(E_Menu *m)
Evas_Object *o; Evas_Object *o;
Eina_List *l; Eina_List *l;
E_Menu_Item *mi; E_Menu_Item *mi;
int ok = 0;
int w, h;
if (m->realized || (!m->items)) return; if (m->realized || (!m->items)) return;
m->realized = 1; m->realized = 1;
m->ecore_evas = e_canvas_new(m->zone->container->win,
m->cur.x, m->cur.y, m->cur.w, m->cur.h, 1, 1,
&(m->evas_win));
e_canvas_add(m->ecore_evas);
eina_hash_add(_e_menu_hash, e_util_winid_str_get(m->evas_win), m);
m->shape = e_container_shape_add(m->zone->container);
e_container_shape_move(m->shape, m->cur.x, m->cur.y);
ecore_evas_callback_resize_set(m->ecore_evas, _e_menu_cb_ecore_evas_resize); if (m->parent_item && m->parent_item->menu)
m->evas = ecore_evas_get(m->ecore_evas); m->zone = m->parent_item->menu->zone;
m->evas = e_comp_get(m)->evas;
m->shape = e_container_shape_add(m->zone->container);
evas_event_freeze(m->evas); evas_event_freeze(m->evas);
/* move cursor out to avoid event cycles during setup */
evas_event_feed_mouse_in(m->evas, ecore_x_current_time_get(), NULL);
evas_event_feed_mouse_move(m->evas, -1000000, -1000000,
ecore_x_current_time_get(), NULL);
ecore_x_window_shape_events_select(m->evas_win, 1);
ecore_evas_name_class_set(m->ecore_evas, "E", "_e_menu_window");
ecore_evas_title_set(m->ecore_evas, "E Menu");
o = edje_object_add(m->evas); o = edje_object_add(m->evas);
evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_menu_del_cb, m);
m->bg_object = o; m->bg_object = o;
evas_object_name_set(o, "menu/background"); evas_object_name_set(o, "menu->bg_object");
evas_object_data_set(o, "e_menu", m); evas_object_data_set(o, "e_menu", m);
evas_object_move(o, 0, 0); evas_object_data_set(o, "eobj", m);
ok = e_theme_edje_object_set(o, "base/theme/menus", e_theme_edje_object_set(o, "base/theme/menus", "e/widgets/menu/default/background");
"e/widgets/menu/default/background");
if (ok)
{
const char *shape_option;
shape_option = edje_object_data_get(o, "shaped");
if (shape_option)
{
if (!strcmp(shape_option, "1")) m->shaped = 1;
}
}
if (m->header.title) if (m->header.title)
{ {
edje_object_part_text_set(o, "e.text.title", m->header.title); edje_object_part_text_set(o, "e.text.title", m->header.title);
edje_object_signal_emit(o, "e,action,show,title", "e"); edje_object_signal_emit(o, "e,action,show,title", "e");
edje_object_message_signal_process(o); edje_object_message_signal_process(o);
} }
evas_object_show(o);
if (m->shaped)
{
if (!e_config->use_shaped_win)
{
ecore_evas_alpha_set(m->ecore_evas, m->shaped);
eina_hash_del(_e_menu_hash, e_util_winid_str_get(m->evas_win), m);
m->evas_win = ecore_evas_software_x11_window_get(m->ecore_evas);
eina_hash_add(_e_menu_hash, e_util_winid_str_get(m->evas_win), m);
}
else
ecore_evas_shaped_set(m->ecore_evas, m->shaped);
}
ecore_x_netwm_window_type_set(m->evas_win, ECORE_X_WINDOW_TYPE_MENU);
o = e_box_add(m->evas); o = e_box_add(m->evas);
evas_object_name_set(o, "menu->container_object");
m->container_object = o; m->container_object = o;
evas_object_intercept_move_callback_add(o, _e_menu_cb_intercept_container_move, m); evas_object_intercept_move_callback_add(o, _e_menu_cb_intercept_container_move, m);
evas_object_intercept_resize_callback_add(o, _e_menu_cb_intercept_container_resize, m); evas_object_intercept_resize_callback_add(o, _e_menu_cb_intercept_container_resize, m);
@ -1797,10 +1707,7 @@ _e_menu_realize(E_Menu *m)
_e_menu_items_layout_update(m); _e_menu_items_layout_update(m);
e_box_thaw(m->container_object); e_box_thaw(m->container_object);
w = m->cur.w;
h = m->cur.h;
e_container_shape_resize(m->shape, w, h);
evas_object_resize(m->bg_object, w, h);
evas_event_thaw(m->evas); evas_event_thaw(m->evas);
} }
@ -2035,8 +1942,6 @@ _e_menu_item_unrealize(E_Menu_Item *mi)
mi->label_object = NULL; mi->label_object = NULL;
if (mi->submenu_object) evas_object_del(mi->submenu_object); if (mi->submenu_object) evas_object_del(mi->submenu_object);
mi->submenu_object = NULL; mi->submenu_object = NULL;
if (mi->event_object) evas_object_del(mi->event_object);
mi->event_object = NULL;
} }
static void static void
@ -2046,10 +1951,9 @@ _e_menu_unrealize(E_Menu *m)
E_Menu_Item *mi; E_Menu_Item *mi;
if (!m->realized) return; if (!m->realized) return;
evas_event_freeze(m->evas); /* freeze+thaw here breaks the universe. don't do it. */
e_container_shape_hide(m->shape); //evas_event_freeze(m->evas);
e_object_del(E_OBJECT(m->shape)); E_FREE_FUNC(m->shape, e_object_del);
m->shape = NULL;
e_box_freeze(m->container_object); e_box_freeze(m->container_object);
EINA_LIST_FOREACH(m->items, l, mi) EINA_LIST_FOREACH(m->items, l, mi)
_e_menu_item_unrealize(mi); _e_menu_item_unrealize(mi);
@ -2063,12 +1967,9 @@ _e_menu_unrealize(E_Menu *m)
m->prev.visible = 0; m->prev.visible = 0;
m->realized = 0; m->realized = 0;
m->zone = NULL; m->zone = NULL;
e_canvas_del(m->ecore_evas); m->cw = NULL;
ecore_evas_free(m->ecore_evas); //evas_event_thaw(m->evas);
m->ecore_evas = NULL;
m->evas = NULL; m->evas = NULL;
eina_hash_del(_e_menu_hash, e_util_winid_str_get(m->evas_win), m);
m->evas_win = 0;
} }
static void static void
@ -2083,13 +1984,9 @@ _e_menu_activate_internal(E_Menu *m, E_Zone *zone)
m->pending_new_submenu = 0; m->pending_new_submenu = 0;
if (!_e_menu_win) if (!_e_menu_win)
{ {
_e_menu_win = ecore_x_window_input_new(zone->container->win, _e_menu_win = e_comp_get(zone)->ee_win;
zone->x, zone->y, if (!e_grabinput_get(0, 0, _e_menu_win))
zone->w, zone->h);
ecore_x_window_show(_e_menu_win);
if (!e_grabinput_get(_e_menu_win, 1, _e_menu_win))
{ {
ecore_x_window_free(_e_menu_win);
_e_menu_win = 0; _e_menu_win = 0;
return; return;
} }
@ -2105,15 +2002,12 @@ _e_menu_activate_internal(E_Menu *m, E_Zone *zone)
/* this remove is in case the menu is marked as inactive but hasn't */ /* this remove is in case the menu is marked as inactive but hasn't */
/* been removed from the list yet */ /* been removed from the list yet */
if (m->in_active_list) if (m->in_active_list)
{ _e_active_menus = eina_list_remove(_e_active_menus, m);
_e_active_menus = eina_list_remove(_e_active_menus, m);
m->in_active_list = 0;
e_object_unref(E_OBJECT(m));
}
_e_active_menus = eina_list_append(_e_active_menus, m); _e_active_menus = eina_list_append(_e_active_menus, m);
if (!m->in_active_list)
e_object_ref(E_OBJECT(m));
m->in_active_list = 1; m->in_active_list = 1;
m->active = 1; m->active = 1;
e_object_ref(E_OBJECT(m));
} }
/* the foreign menu items */ /* the foreign menu items */
if (m->category) if (m->category)
@ -2213,7 +2107,7 @@ _e_menu_reposition(E_Menu *m)
if (!m->parent_item) return; if (!m->parent_item) return;
m->cur.x = m->parent_item->menu->cur.x + m->parent_item->menu->cur.w; m->cur.x = m->parent_item->menu->cur.x + m->parent_item->menu->cur.w;
parent_item_bottom = m->parent_item->menu->cur.y + m->parent_item->y; parent_item_bottom = m->parent_item->y;
if (m->cur.h > m->zone->h) if (m->cur.h > m->zone->h)
{ {
/* menu is larger than screen */ /* menu is larger than screen */
@ -2227,12 +2121,12 @@ _e_menu_reposition(E_Menu *m)
else else
{ {
/* menu is smaller than screen */ /* menu is smaller than screen */
if (((parent_item_bottom + m->cur.h - m->container_y) > m->zone->h) && if (((parent_item_bottom + m->cur.h) > m->zone->h) &&
(parent_item_bottom > (m->zone->h / 2))) (parent_item_bottom > (m->zone->h / 2)))
/* menu is partially out of screen and more is shown if menu goes up */ /* menu is partially out of screen and more is shown if menu goes up */
m->cur.y = (parent_item_bottom - (m->container_h + 1)) + m->parent_item->h; m->cur.y = parent_item_bottom - m->cur.h + m->parent_item->h;
else else
m->cur.y = parent_item_bottom - m->container_y; m->cur.y = parent_item_bottom;
} }
/* FIXME: this will suck for big menus */ /* FIXME: this will suck for big menus */
@ -2832,19 +2726,6 @@ _e_menu_auto_place(E_Menu *m, int x, int y, int w, int h)
return 0; return 0;
} }
static void
_e_menu_cb_ecore_evas_resize(Ecore_Evas *ee)
{
Evas *evas;
Evas_Object *o;
Evas_Coord w, h;
evas = ecore_evas_get(ee);
evas_output_viewport_get(evas, NULL, NULL, &w, &h);
o = evas_object_name_find(evas, "menu/background");
evas_object_resize(o, w, h);
}
static void static void
_e_menu_cb_item_in(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) _e_menu_cb_item_in(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{ {
@ -2953,7 +2834,11 @@ _e_menu_cb_mouse_down(void *data __UNUSED__, int type __UNUSED__, void *event)
Ecore_Event_Mouse_Button *ev; Ecore_Event_Mouse_Button *ev;
ev = event; ev = event;
if (ev->window != _e_menu_win) return ECORE_CALLBACK_PASS_ON; if (ev->window != _e_menu_win)
{
_e_menu_deactivate_all();
return ECORE_CALLBACK_PASS_ON;
}
/* Only allow dragging from floating menus for now. /* Only allow dragging from floating menus for now.
* The reason for this is that for non floating menus, * The reason for this is that for non floating menus,
@ -2974,7 +2859,7 @@ _e_menu_cb_mouse_up(void *data __UNUSED__, int type __UNUSED__, void *event)
int ret = 0; int ret = 0;
ev = event; ev = event;
if (ev->window != _e_menu_win) return ECORE_CALLBACK_PASS_ON; if (ev->window != _e_menu_win) return ECORE_CALLBACK_RENEW;
t = ev->timestamp - _e_menu_activate_time; t = ev->timestamp - _e_menu_activate_time;
if ((_e_menu_activate_time != 0) && if ((_e_menu_activate_time != 0) &&
@ -2991,7 +2876,13 @@ _e_menu_cb_mouse_up(void *data __UNUSED__, int type __UNUSED__, void *event)
*/ */
} }
else else
ret = _e_menu_active_call(); {
E_Menu_Item *mi;
mi = _e_menu_item_active_get();
if ((!mi) || (E_INSIDE(ev->root.x, ev->root.y, mi->x, mi->y, mi->w, mi->h)))
ret = _e_menu_active_call();
}
_e_menu_activate_maybe_drag = 0; _e_menu_activate_maybe_drag = 0;
_e_menu_activate_dragging = 0; _e_menu_activate_dragging = 0;
if (ret == 1) if (ret == 1)
@ -3033,27 +2924,22 @@ _e_menu_cb_mouse_move(void *data __UNUSED__, int type __UNUSED__, void *event)
EINA_LIST_FOREACH(_e_active_menus, l, m) EINA_LIST_FOREACH(_e_active_menus, l, m)
{ {
if ((m->realized) && (m->cur.visible)) if ((!m->realized) || (!m->cur.visible)) continue;
if (is_fast)
m->fast_mouse = 1;
else if (dt > 0.0)
{ {
if (is_fast) m->fast_mouse = 0;
m->fast_mouse = 1; if (m->pending_new_submenu)
else if (dt > 0.0)
{ {
m->fast_mouse = 0; E_Menu_Item *mi;
if (m->pending_new_submenu)
{
E_Menu_Item *mi;
mi = _e_menu_item_active_get(); mi = _e_menu_item_active_get();
if (mi) if (mi)
_e_menu_submenu_activate(mi); _e_menu_submenu_activate(mi);
}
} }
evas_event_feed_mouse_move(m->evas,
ev->x - m->cur.x + m->zone->x,
ev->y - m->cur.y + m->zone->y,
ev->timestamp, NULL);
} }
evas_event_feed_mouse_move(m->evas, ev->x, ev->y, ev->timestamp, NULL);
} }
_e_menu_list_free_unref(tmp); _e_menu_list_free_unref(tmp);
@ -3139,22 +3025,6 @@ _e_menu_cb_scroll_animator(void *data __UNUSED__)
return 1; return 1;
} }
static Eina_Bool
_e_menu_cb_window_shape(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
{
Eina_List *l;
Ecore_X_Event_Window_Shape *e;
E_Menu *m;
e = ev;
EINA_LIST_FOREACH(_e_active_menus, l, m)
{
if (m->evas_win == e->win)
m->need_shape_export = 1;
}
return ECORE_CALLBACK_PASS_ON;
}
static void static void
_e_menu_cb_item_submenu_post_default(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi) _e_menu_cb_item_submenu_post_default(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi)
{ {

View File

@ -52,15 +52,13 @@ struct _E_Menu
E_Menu_Item *parent_item; E_Menu_Item *parent_item;
/* only useful if realized != 0 (ie menu is ACTUALLY realized) */ /* only useful if realized != 0 (ie menu is ACTUALLY realized) */
Ecore_Evas *ecore_evas; E_Comp_Win *cw;
Evas *evas; E_Container_Shape *shape;
Ecore_X_Window evas_win; Ecore_Job *dangling_job;
Evas *evas;
Evas_Object *bg_object; Evas_Object *bg_object;
Evas_Object *container_object; Evas_Object *container_object;
Evas_Coord container_x, container_y, container_w, container_h; Evas_Coord container_x, container_y, container_w, container_h;
E_Container_Shape *shape;
int shape_rects_num;
Ecore_X_Rectangle *shape_rects;
struct { struct {
void *data; void *data;
@ -74,8 +72,6 @@ struct _E_Menu
Eina_Bool pending_new_submenu : 1; Eina_Bool pending_new_submenu : 1;
Eina_Bool have_submenu : 1; Eina_Bool have_submenu : 1;
Eina_Bool in_active_list : 1; Eina_Bool in_active_list : 1;
Eina_Bool shaped : 1;
Eina_Bool need_shape_export : 1;
}; };
struct _E_Menu_Item struct _E_Menu_Item
@ -99,8 +95,6 @@ struct _E_Menu_Item
Evas_Object *label_object; Evas_Object *label_object;
Evas_Object *submenu_object; Evas_Object *submenu_object;
Evas_Object *event_object;
Eina_List *list_position; Eina_List *list_position;
int label_w, label_h; int label_w, label_h;
@ -212,7 +206,5 @@ EAPI void e_menu_idler_before(void);
EAPI Ecore_X_Window e_menu_grab_window_get(void); EAPI Ecore_X_Window e_menu_grab_window_get(void);
EAPI E_Menu *e_menu_find_by_window(Ecore_X_Window win);
#endif #endif
#endif #endif