From 0d16ba68cd24b9c4fd28abf9c1d5873d6f284f19 Mon Sep 17 00:00:00 2001 From: discomfitor Date: Tue, 19 Feb 2013 08:09:05 +0000 Subject: [PATCH] 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 --- ChangeLog | 4 + NEWS | 1 + data/themes/edc/menu.edc | 18 +- src/bin/e_comp.c | 40 +++-- src/bin/e_menu.c | 370 +++++++++++++-------------------------- src/bin/e_menu.h | 16 +- 6 files changed, 168 insertions(+), 281 deletions(-) diff --git a/ChangeLog b/ChangeLog index 770da189b..b040cf5d9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-03-11 Mike Blumenkrantz + + * menus are now drawn directly on the compositor canvas + 2013-03-11 Dieter Roelants * portability: Don't rely on bash or zsh behavior when starting enlightenment_init and tempget. diff --git a/NEWS b/NEWS index 61805dd29..d8cf3ac99 100644 --- a/NEWS +++ b/NEWS @@ -122,6 +122,7 @@ Improvements: * DND canvas merged to compositor * 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. + * menus are now drawn directly on the compositor canvas Fixes: * IBar menu didn't allow to configure different icon sources, show contents menu even on empty IBar. diff --git a/data/themes/edc/menu.edc b/data/themes/edc/menu.edc index dd8097fc6..d926f0524 100644 --- a/data/themes/edc/menu.edc +++ b/data/themes/edc/menu.edc @@ -193,6 +193,11 @@ group { name: "e/widgets/menu/default/item_bg"; visible: 1; } } + part { name: "events"; type: RECT; + description { state: "default"; + color: 0 0 0 0; + } + } } programs { program { @@ -216,7 +221,7 @@ group { name: "e/widgets/menu/default/item_bg"; group { name: "e/widgets/menu/default/icon"; parts { - part { name: "clip"; type: RECT; + part { name: "clip"; type: RECT; mouse_events: 0; description { state: "default" 0.0; color: 255 255 255 255; } @@ -249,6 +254,11 @@ group { name: "e/widgets/menu/default/icon"; group { name: "e/widgets/menu/default/label"; parts { + part { name: "base"; type: RECT; + description { state: "default"; + color: 0 0 0 0; + } + } part { name: "e.text.label"; type: TEXT; mouse_events: 0; effect: SHADOW BOTTOM; scale: 1; @@ -364,7 +374,7 @@ group { name: "e/widgets/menu/default/submenu"; images.image: "sym_right_glow_normal.png" COMP; images.image: "vertical_separated_bar_glow.png" COMP; parts { - part { name: "base"; mouse_events: 0; + part { name: "base"; description { state: "default" 0.0; image.normal: "sym_right_light_normal.png"; rel2.offset: -2 -1; @@ -413,7 +423,7 @@ group { name: "e/widgets/menu/default/check"; images.image: "bevel_in.png" COMP; images.image: "sym_check_alum.png" COMP; parts { - part { name: "base"; type: RECT; mouse_events: 0; + part { name: "base"; type: RECT; description { state: "default" 0.0; rel1.offset: 1 1; rel1.to: "inset"; @@ -478,7 +488,7 @@ group { name: "e/widgets/menu/default/radio"; images.image: "inset_shadow_circle_tiny.png" COMP; images.image: "sym_radio_alum.png" COMP; parts { - part { name: "base"; mouse_events: 0; + part { name: "base"; description { state: "default" 0.0; image.normal: "inset_shadow_circle_tiny.png"; min: 13 13; diff --git a/src/bin/e_comp.c b/src/bin/e_comp.c index 787eeb115..e2b9ce07b 100644 --- a/src/bin/e_comp.c +++ b/src/bin/e_comp.c @@ -476,8 +476,8 @@ _e_comp_win_geometry_update(E_Comp_Win *cw) w = cw->pw, h = cw->ph; if (cw->not_in_layout) { - evas_object_move(cw->shobj, x, y); evas_object_resize(cw->shobj, w, h); + evas_object_move(cw->shobj, x, y); } else { @@ -1507,6 +1507,7 @@ _e_comp_object_del(void *data, void *obj) } else if (obj == cw->menu) { + cw->menu->cw = NULL; cw->menu = NULL; 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->show_ready = cw->pop->visible; break; - //case E_MENU_TYPE: - //cw->menu = eobj; - //cw->menu->cw = cw; - //break; + case E_MENU_TYPE: + cw->menu = (void*)eobj; + cw->menu->cw = cw; + 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: 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); } /* popups handled in _dummy_add */ - else if ((cw->menu = e_menu_find_by_window(cw->win))) - { - cw->dfn = e_object_delfn_add(E_OBJECT(cw->menu), _e_comp_object_del, cw); - cw->show_ready = 1; - cw->shape = cw->menu->shape; - } + /* menus handled in _dummy_add */ // fixme: could use bd/pop/menu for this too memset((&att), 0, sizeof(Ecore_X_Window_Attributes)); 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) { e_object_delfn_del(E_OBJECT(cw->menu), cw->dfn); + cw->menu->cw = NULL; cw->menu = 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; 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; - /* - else if (cw->menu) - x = cw->menu->cur.x, y = cw->menu->cur.y, w = cw->menu->cur.w, h = cw->menu->cur.h; - */ + //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; else x = cw->x, y = cw->y, w = cw->w, h = cw->h; #ifdef SHAPE_DEBUG @@ -4888,6 +4886,8 @@ e_comp_get(void *o) E_Border *bd; E_Popup *pop; E_Shelf *es; + E_Menu *m; + E_Menu_Item *mi; E_Object *obj = o; E_Zone *zone = NULL; E_Container *con = NULL; @@ -4911,6 +4911,16 @@ e_comp_get(void *o) obj = (void*)pop->zone; EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL); 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: es = (E_Shelf*)obj; obj = (void*)es->zone; diff --git a/src/bin/e_menu.c b/src/bin/e_menu.c index d6d6a0895..eb57f1bda 100644 --- a/src/bin/e_menu.c +++ b/src/bin/e_menu.c @@ -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_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_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_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); @@ -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_wheel(void *data, int type, void *event); 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 Eina_Bool _e_menu_categories_free_cb(const Eina_Hash *hash, const void *key, void *data, void *fdata); /* local subsystem globals */ static Ecore_X_Window _e_menu_win = 0; 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_prev_active_menu_item = 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_move_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_List * @@ -178,12 +174,8 @@ e_menu_init(void) _e_menu_mouse_wheel_handler = ecore_event_handler_add(ECORE_EVENT_MOUSE_WHEEL, _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); - if (!_e_menu_hash) _e_menu_hash = eina_hash_string_superfast_new(NULL); e_int_menus_init(); 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_move_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) { @@ -219,11 +210,6 @@ e_menu_shutdown(void) _e_menu_categories = NULL; } - if (_e_menu_hash) - { - eina_hash_free(_e_menu_hash); - _e_menu_hash = NULL; - } _e_menu_lock = EINA_FALSE; 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; Evas_Object *o; + Eina_List *tmp = NULL; int ww, hh; E_OBJECT_CHECK(mi); E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE); + + tmp = _e_active_menus_copy_ref(); submenu = !!mi->submenu; if (mi->submenu) e_object_unref(E_OBJECT(mi->submenu)); if (sub) e_object_ref(E_OBJECT(sub)); mi->submenu = sub; mi->changed = 1; mi->menu->changed = 1; - if (!!sub == submenu) return; - if (!mi->bg_object) return; + if (!!sub == submenu) goto out; + if (!mi->bg_object) goto out; if (sub) e_object_ref(E_OBJECT(sub)); _e_menu_lock = EINA_TRUE; 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 */ -1, -1 /* max */ ); - return; + goto out; } 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", "e/widgets/menu/default/submenu_bg")) - return; + goto out; } e_theme_edje_object_set(mi->bg_object, "base/theme/menus", "e/widgets/menu/default/item_bg"); +out: + _e_menu_list_free_unref(tmp); } EAPI void @@ -1005,6 +996,8 @@ e_menu_item_drag_callback_set(E_Menu_Item *mi, void (*func)(void *data, E_Menu * EAPI void e_menu_item_active_set(E_Menu_Item *mi, int active) { + Eina_List *tmp = NULL; + E_OBJECT_CHECK(mi); E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE); 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(); if (mi == pmi) return; 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->menu->parent_item) @@ -1049,6 +1045,7 @@ e_menu_item_active_set(E_Menu_Item *mi, int active) } else if ((!active) && (mi->active)) { + tmp = _e_active_menus_copy_ref(); mi->active = 0; _e_prev_active_menu_item = mi; _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"); } + _e_menu_list_free_unref(tmp); } EAPI E_Menu_Item * @@ -1135,8 +1133,7 @@ e_menu_idler_before(void) if ((!m->cur.visible) && (m->prev.visible)) { m->prev.visible = m->cur.visible; - ecore_evas_hide(m->ecore_evas); - e_container_shape_hide(m->shape); + if (m->cw) e_comp_win_hide(m->cw); } } /* 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; w = m->cur.w; h = m->cur.h; - ecore_evas_resize(m->ecore_evas, w, h); - e_container_shape_resize(m->shape, w, h); + if (m->cw) + e_comp_win_resize(m->cw, w, h); } if (((m->cur.x) != (m->prev.x)) || ((m->cur.y) != (m->prev.y))) @@ -1179,8 +1176,9 @@ e_menu_idler_before(void) } m->prev.x = m->cur.x; m->prev.y = m->cur.y; - ecore_evas_move(m->ecore_evas, m->cur.x, m->cur.y); - e_container_shape_move(m->shape, m->cur.x, m->cur.y); + if (m->cw) + 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)) { m->prev.visible = m->cur.visible; - ecore_evas_raise(m->ecore_evas); - ecore_evas_show(m->ecore_evas); - if (!m->shaped) e_container_shape_show(m->shape); + if (!m->cw) + { + 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... */ - EINA_LIST_FOREACH(_e_active_menus, l, m) + EINA_LIST_REVERSE_FOREACH(_e_active_menus, l, m) { 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); } } @@ -1215,59 +1218,6 @@ e_menu_idler_before(void) 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 */ _e_menu_list_free_unref(tmp); @@ -1275,8 +1225,7 @@ e_menu_idler_before(void) { if (_e_menu_win) { - ecore_x_window_free(_e_menu_win); - e_grabinput_release(_e_menu_win, _e_menu_win); + e_grabinput_release(0, _e_menu_win); _e_menu_win = 0; } } @@ -1288,18 +1237,13 @@ e_menu_grab_window_get(void) return _e_menu_win; } -EAPI E_Menu * -e_menu_find_by_window(Ecore_X_Window win) +/* local subsystem functions */ +static void +_e_menu_dangling_cb(void *data) { - E_Menu *m; - - m = eina_hash_find(_e_menu_hash, e_util_winid_str_get(win)); - if ((m) && (m->evas_win != win)) - return NULL; - return m; + WRN("DANGLING SUBMENU: REF(%d)||MENU(%p)", e_object_ref_get(data), data); } -/* local subsystem functions */ static void _e_menu_free(E_Menu *m) { @@ -1320,16 +1264,14 @@ _e_menu_free(E_Menu *m) } if (m->parent_item) m->parent_item->submenu = NULL; - _e_menu_unrealize(m); - E_FREE(m->shape_rects); - m->shape_rects_num = 0; + /* del callback causes this to unrealize the menu */ + if (m->bg_object) evas_object_del(m->bg_object); EINA_LIST_FOREACH_SAFE(m->items, l, l_next, mi) e_object_del(E_OBJECT(mi)); if (m->in_active_list) { _e_active_menus = eina_list_remove(_e_active_menus, m); m->in_active_list = 0; - e_object_unref(E_OBJECT(m)); } if (m->header.title) eina_stringshare_del(m->header.title); 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)); } 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); 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->x = x; mi->y = y; - evas_object_move(mi->event_object, x, y); evas_object_move(o, x, y); 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->w = w; mi->h = h; - evas_object_resize(mi->event_object, w, h); evas_object_resize(o, w, h); if ((mi->submenu) && (mi->submenu->parent_item)) _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); } +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 _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); 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_resize_callback_add(o, _e_menu_cb_intercept_item_resize, mi); - if ((mi->submenu) || (mi->submenu_pre_cb.func)) { if (!e_theme_edje_object_set(mi->bg_object, "base/theme/menus", @@ -1464,6 +1420,7 @@ no_submenu_item: evas_object_show(o); o = e_box_add(mi->menu->evas); + evas_object_name_set(o, "mi->container_object"); e_box_homogenous_set(o, 0); mi->container_object = o; e_box_orientation_set(o, 1); @@ -1474,10 +1431,10 @@ no_submenu_item: if (mi->check) { o = edje_object_add(mi->menu->evas); + evas_object_name_set(o, "mi->toggle_object"); mi->toggle_object = o; e_theme_edje_object_set(o, "base/theme/menus", "e/widgets/menu/default/check"); - evas_object_pass_events_set(o, 1); evas_object_show(o); e_box_pack_end(mi->container_object, o); edje_object_size_min_calc(mi->toggle_object, &ww, &hh); @@ -1494,10 +1451,10 @@ no_submenu_item: else if (mi->radio) { o = edje_object_add(mi->menu->evas); + evas_object_name_set(o, "mi->toggle_object"); mi->toggle_object = o; e_theme_edje_object_set(o, "base/theme/menus", "e/widgets/menu/default/radio"); - evas_object_pass_events_set(o, 1); evas_object_show(o); e_box_pack_end(mi->container_object, o); edje_object_size_min_calc(mi->toggle_object, &ww, &hh); @@ -1514,9 +1471,9 @@ no_submenu_item: else { o = evas_object_rectangle_add(mi->menu->evas); + evas_object_name_set(o, "mi->toggle_object"); mi->toggle_object = o; evas_object_color_set(o, 0, 0, 0, 0); - evas_object_pass_events_set(o, 1); e_box_pack_end(mi->container_object, o); } 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", "e/widgets/menu/default/icon")) { + evas_object_name_set(o, "mi->icon_bg_object"); mi->icon_bg_object = o; evas_object_show(o); } @@ -1535,6 +1493,7 @@ no_submenu_item: evas_object_del(o); 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: 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)) { mi->icon_object = o; + evas_object_name_set(o, "mi->icon_object"); edje_object_size_max_get(o, &iww, &ihh); icon_w = iww; icon_h = ihh; @@ -1570,6 +1530,7 @@ no_submenu_item: if (!mi->icon_object) { o = e_icon_add(mi->menu->evas); + evas_object_name_set(o, "mi->icon_object"); mi->icon_object = o; e_icon_scale_size_set(o, e_util_icon_size_normalize(24 * e_scale)); e_icon_preload_set(mi->icon_object, 1); @@ -1585,7 +1546,6 @@ no_submenu_item: e_icon_size_get(o, &icon_w, &icon_h); } - evas_object_pass_events_set(o, 1); evas_object_show(o); if (mi->icon_bg_object) @@ -1609,6 +1569,7 @@ no_submenu_item: else { 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); mi->icon_w = icon_w; mi->icon_h = icon_h; @@ -1625,21 +1586,21 @@ no_submenu_item: else { o = evas_object_rectangle_add(mi->menu->evas); + evas_object_name_set(o, "mi->icon_object"); mi->icon_object = o; evas_object_color_set(o, 0, 0, 0, 0); - evas_object_pass_events_set(o, 1); e_box_pack_end(mi->container_object, o); } if (mi->label) { o = edje_object_add(mi->menu->evas); + evas_object_name_set(o, "mi->label_object"); mi->label_object = o; e_theme_edje_object_set(o, "base/theme/menus", "e/widgets/menu/default/label"); /* default label */ edje_object_part_text_set(o, "e.text.label", mi->label); - evas_object_pass_events_set(o, 1); evas_object_show(o); e_box_pack_end(mi->container_object, o); edje_object_size_min_calc(mi->label_object, &ww, &hh); @@ -1656,18 +1617,18 @@ no_submenu_item: else { o = evas_object_rectangle_add(mi->menu->evas); + evas_object_name_set(o, "mi->label_object"); mi->label_object = o; evas_object_color_set(o, 0, 0, 0, 0); - evas_object_pass_events_set(o, 1); e_box_pack_end(mi->container_object, o); } if ((mi->submenu) || (mi->submenu_pre_cb.func)) { o = edje_object_add(mi->menu->evas); + evas_object_name_set(o, "mi->submenu_object"); mi->submenu_object = o; e_theme_edje_object_set(o, "base/theme/menus", "e/widgets/menu/default/submenu"); - evas_object_pass_events_set(o, 1); evas_object_show(o); e_box_pack_end(mi->container_object, o); edje_object_size_min_calc(mi->submenu_object, &ww, &hh); @@ -1684,26 +1645,15 @@ no_submenu_item: else { o = evas_object_rectangle_add(mi->menu->evas); + evas_object_name_set(o, "mi->submenu_object"); mi->submenu_object = o; evas_object_color_set(o, 0, 0, 0, 0); - evas_object_pass_events_set(o, 1); e_box_pack_end(mi->container_object, o); } edje_object_part_swallow(mi->bg_object, "e.swallow.content", 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_thaw(mi->container_object); } @@ -1718,72 +1668,32 @@ _e_menu_realize(E_Menu *m) Evas_Object *o; Eina_List *l; E_Menu_Item *mi; - int ok = 0; - int w, h; if (m->realized || (!m->items)) return; 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); - m->evas = ecore_evas_get(m->ecore_evas); + if (m->parent_item && m->parent_item->menu) + 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); - /* 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); + evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_menu_del_cb, m); 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_move(o, 0, 0); - ok = e_theme_edje_object_set(o, "base/theme/menus", - "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; - } - } + evas_object_data_set(o, "eobj", m); + e_theme_edje_object_set(o, "base/theme/menus", "e/widgets/menu/default/background"); if (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_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); + evas_object_name_set(o, "menu->container_object"); m->container_object = o; 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); @@ -1797,10 +1707,7 @@ _e_menu_realize(E_Menu *m) _e_menu_items_layout_update(m); 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); } @@ -2035,8 +1942,6 @@ _e_menu_item_unrealize(E_Menu_Item *mi) mi->label_object = NULL; if (mi->submenu_object) evas_object_del(mi->submenu_object); mi->submenu_object = NULL; - if (mi->event_object) evas_object_del(mi->event_object); - mi->event_object = NULL; } static void @@ -2046,10 +1951,9 @@ _e_menu_unrealize(E_Menu *m) E_Menu_Item *mi; if (!m->realized) return; - evas_event_freeze(m->evas); - e_container_shape_hide(m->shape); - e_object_del(E_OBJECT(m->shape)); - m->shape = NULL; + /* freeze+thaw here breaks the universe. don't do it. */ + //evas_event_freeze(m->evas); + E_FREE_FUNC(m->shape, e_object_del); e_box_freeze(m->container_object); EINA_LIST_FOREACH(m->items, l, mi) _e_menu_item_unrealize(mi); @@ -2063,12 +1967,9 @@ _e_menu_unrealize(E_Menu *m) m->prev.visible = 0; m->realized = 0; m->zone = NULL; - e_canvas_del(m->ecore_evas); - ecore_evas_free(m->ecore_evas); - m->ecore_evas = NULL; + m->cw = NULL; + //evas_event_thaw(m->evas); m->evas = NULL; - eina_hash_del(_e_menu_hash, e_util_winid_str_get(m->evas_win), m); - m->evas_win = 0; } static void @@ -2083,13 +1984,9 @@ _e_menu_activate_internal(E_Menu *m, E_Zone *zone) m->pending_new_submenu = 0; if (!_e_menu_win) { - _e_menu_win = ecore_x_window_input_new(zone->container->win, - zone->x, zone->y, - zone->w, zone->h); - ecore_x_window_show(_e_menu_win); - if (!e_grabinput_get(_e_menu_win, 1, _e_menu_win)) + _e_menu_win = e_comp_get(zone)->ee_win; + if (!e_grabinput_get(0, 0, _e_menu_win)) { - ecore_x_window_free(_e_menu_win); _e_menu_win = 0; 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 */ /* been removed from the list yet */ if (m->in_active_list) - { - _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_remove(_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->active = 1; - e_object_ref(E_OBJECT(m)); } /* the foreign menu items */ if (m->category) @@ -2213,7 +2107,7 @@ _e_menu_reposition(E_Menu *m) if (!m->parent_item) return; 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) { /* menu is larger than screen */ @@ -2227,12 +2121,12 @@ _e_menu_reposition(E_Menu *m) else { /* 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))) /* 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 - m->cur.y = parent_item_bottom - m->container_y; + m->cur.y = parent_item_bottom; } /* 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; } -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 _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; 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. * 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; 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; if ((_e_menu_activate_time != 0) && @@ -2991,7 +2876,13 @@ _e_menu_cb_mouse_up(void *data __UNUSED__, int type __UNUSED__, void *event) */ } 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_dragging = 0; 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) { - 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 = 1; - else if (dt > 0.0) + m->fast_mouse = 0; + if (m->pending_new_submenu) { - m->fast_mouse = 0; - if (m->pending_new_submenu) - { - E_Menu_Item *mi; + E_Menu_Item *mi; - mi = _e_menu_item_active_get(); - if (mi) - _e_menu_submenu_activate(mi); - } + mi = _e_menu_item_active_get(); + if (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); @@ -3139,22 +3025,6 @@ _e_menu_cb_scroll_animator(void *data __UNUSED__) 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 _e_menu_cb_item_submenu_post_default(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi) { diff --git a/src/bin/e_menu.h b/src/bin/e_menu.h index f0ef7383c..8c4d05c29 100644 --- a/src/bin/e_menu.h +++ b/src/bin/e_menu.h @@ -52,15 +52,13 @@ struct _E_Menu E_Menu_Item *parent_item; /* only useful if realized != 0 (ie menu is ACTUALLY realized) */ - Ecore_Evas *ecore_evas; - Evas *evas; - Ecore_X_Window evas_win; + E_Comp_Win *cw; + E_Container_Shape *shape; + Ecore_Job *dangling_job; + Evas *evas; Evas_Object *bg_object; Evas_Object *container_object; Evas_Coord container_x, container_y, container_w, container_h; - E_Container_Shape *shape; - int shape_rects_num; - Ecore_X_Rectangle *shape_rects; struct { void *data; @@ -74,8 +72,6 @@ struct _E_Menu Eina_Bool pending_new_submenu : 1; Eina_Bool have_submenu : 1; Eina_Bool in_active_list : 1; - Eina_Bool shaped : 1; - Eina_Bool need_shape_export : 1; }; struct _E_Menu_Item @@ -99,8 +95,6 @@ struct _E_Menu_Item Evas_Object *label_object; Evas_Object *submenu_object; - Evas_Object *event_object; - Eina_List *list_position; 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 E_Menu *e_menu_find_by_window(Ecore_X_Window win); - #endif #endif