giant comp rejiggering commit #3
authordiscomfitor <discomfitor@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Tue, 19 Feb 2013 08:09:05 +0000 (08:09 +0000)
committerMike Blumenkrantz <m.blumenkran@samsung.com>
Mon, 11 Mar 2013 05:20:52 +0000 (05:20 +0000)
* 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
NEWS
data/themes/edc/menu.edc
src/bin/e_comp.c
src/bin/e_menu.c
src/bin/e_menu.h

index 770da18..b040cf5 100644 (file)
--- 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 61805dd..d8cf3ac 100644 (file)
--- 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.
index dd8097f..d926f05 100644 (file)
@@ -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;
index 787eeb1..e2b9ce0 100644 (file)
@@ -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;
index d6d6a08..eb57f1b 100644 (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_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);
@@ -1424,6 +1368,15 @@ _e_menu_cb_intercept_container_resize(void *data, Evas_Object *o, Evas_Coord w,
 }
 
 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)
 {
    Evas_Object *o;
@@ -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 */
@@ -2833,19 +2727,6 @@ _e_menu_auto_place(E_Menu *m, int x, int y, int w, int h)
 }
 
 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__)
 {
    E_Menu_Item *mi;
@@ -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)
 {
index f0ef738..8c4d05c 100644 (file)
@@ -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