diff --git a/data/themes/images/e17_clock_fg.png b/data/themes/images/e17_clock_fg.png index 0ba423817..b48a591a7 100644 Binary files a/data/themes/images/e17_clock_fg.png and b/data/themes/images/e17_clock_fg.png differ diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am index e9fc9f4c6..a8d7e6173 100644 --- a/src/bin/Makefile.am +++ b/src/bin/Makefile.am @@ -50,7 +50,8 @@ e_theme.h \ e_dnd.h \ e_bindings.h \ e_moveresize.h \ -e_actions.h +e_actions.h \ +e_popup.h enlightenment_SOURCES = \ e_main.c \ @@ -94,6 +95,7 @@ e_dnd.c \ e_bindings.c \ e_moveresize.c \ e_actions.c \ +e_popup.c \ $(ENLIGHTENMENTHEADERS) enlightenment_LDFLAGS = -export-dynamic @e_libs@ @dlopen_libs@ diff --git a/src/bin/e_includes.h b/src/bin/e_includes.h index 5ea2514eb..66e217dee 100644 --- a/src/bin/e_includes.h +++ b/src/bin/e_includes.h @@ -40,3 +40,4 @@ #include "e_bindings.h" #include "e_moveresize.h" #include "e_actions.h" +#include "e_popup.h" diff --git a/src/bin/e_main.c b/src/bin/e_main.c index 18f1bdc0b..588a9e912 100644 --- a/src/bin/e_main.c +++ b/src/bin/e_main.c @@ -277,6 +277,13 @@ main(int argc, char **argv) _e_main_shutdown(-1); } _e_main_shutdown_push(e_bindings_shutdown); + /* init popup system */ + if (!e_popup_init()) + { + e_error_message_show(_("Enlightenment cannot set up its popup system.")); + _e_main_shutdown(-1); + } + _e_main_shutdown_push(e_popup_shutdown); /* setup edje to animate @ e_config->framerate frames per sec. */ edje_frametime_set(1.0 / e_config->framerate); @@ -784,6 +791,7 @@ _e_main_cb_idler_before(void *data __UNUSED__) e_menu_idler_before(); e_focus_idler_before(); e_border_idler_before(); + e_popup_idler_before(); for (l = _e_main_idler_before_list; l; l = l->next) { E_Before_Idler *eb; diff --git a/src/bin/e_menu.c b/src/bin/e_menu.c index ee6770c10..b27960d7f 100644 --- a/src/bin/e_menu.c +++ b/src/bin/e_menu.c @@ -12,7 +12,6 @@ * * support alignment (x, y) as well as spawn direction * * need different menu style support for different menus * * add menu icon/title support - * * support shaped menu windows * * use event timestamps not clock for "click and release" detect * * menu icons can set if/how they will be scaled * * support move/resize of "box" that spawned the menu @@ -21,8 +20,7 @@ * * allow menus to stretch width/height to fit spawner widget/box * * allow menus to auto-shrink (horizontally) if forced to * * support auto left/right direction spawn - * * support menu icons supplied as edjes, not just image files - * * support obscures to indicate offs-creen/not visible menu parts + * * support obscures to indicate offscreen/not visible menu parts */ /* local subsystem functions */ @@ -31,13 +29,13 @@ static void _e_menu_item_free (E_Menu_Item *mi); static void _e_menu_item_realize (E_Menu_Item *mi); static void _e_menu_realize (E_Menu *m); static void _e_menu_items_layout_update (E_Menu *m); -static void _e_menu_item_unrealize (E_Menu_Item *mi); +static void _e_menu_item_unrealize (E_Menu_Item *mi); static void _e_menu_unrealize (E_Menu *m); static void _e_menu_activate_internal (E_Menu *m, E_Zone *zone); static void _e_menu_deactivate_all (void); static void _e_menu_deactivate_above (E_Menu *m); static void _e_menu_submenu_activate (E_Menu_Item *mi); -static void _e_menu_submenu_deactivate (E_Menu_Item *mi); +static void _e_menu_submenu_deactivate (E_Menu_Item *mi); static void _e_menu_reposition (E_Menu *m); static int _e_menu_active_call (void); static void _e_menu_item_activate_next (void); @@ -68,7 +66,7 @@ static int _e_menu_cb_mouse_wheel (void *data, int type, void *e static int _e_menu_cb_scroll_timer (void *data); static int _e_menu_cb_window_shape (void *data, int ev_type, void *ev); -static void _e_menu_item_submenu_post_cb_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); /* local subsystem globals */ static Ecore_X_Window _e_menu_win = 0; @@ -513,7 +511,7 @@ e_menu_item_submenu_pre_callback_set(E_Menu_Item *mi, void (*func) (void *data, mi->submenu_pre_cb.func = func; mi->submenu_pre_cb.data = data; if (!mi->submenu_post_cb.func) - mi->submenu_post_cb.func = _e_menu_item_submenu_post_cb_default; + mi->submenu_post_cb.func = _e_menu_cb_item_submenu_post_default; } void @@ -715,6 +713,7 @@ static void _e_menu_free(E_Menu *m) { Evas_List *l, *tmp; + _e_menu_unrealize(m); for (l = m->items; l;) { @@ -2211,7 +2210,7 @@ _e_menu_cb_window_shape(void *data, int ev_type, void *ev) } static void -_e_menu_item_submenu_post_cb_default(void *data, E_Menu *m, E_Menu_Item *mi) +_e_menu_cb_item_submenu_post_default(void *data, E_Menu *m, E_Menu_Item *mi) { E_Menu *subm; @@ -2219,6 +2218,5 @@ _e_menu_item_submenu_post_cb_default(void *data, E_Menu *m, E_Menu_Item *mi) subm = mi->submenu; e_menu_item_submenu_set(mi, NULL); - printf("Delete submenu: %d\n", E_OBJECT(subm)->references); e_object_del(E_OBJECT(subm)); } diff --git a/src/bin/e_popup.c b/src/bin/e_popup.c new file mode 100644 index 000000000..9a306da20 --- /dev/null +++ b/src/bin/e_popup.c @@ -0,0 +1,208 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#include "e.h" + +/* local subsystem functions */ +static void _e_popup_free(E_Popup *pop); +static int _e_popup_cb_window_shape(void *data, int ev_type, void *ev); + +/* local subsystem globals */ +static Ecore_Event_Handler *_e_popup_window_shape_handler = NULL; +static Evas_List *_e_popup_list = NULL; + +/* externally accessible functions */ + +int +e_popup_init(void) +{ + _e_popup_window_shape_handler = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHAPE, _e_popup_cb_window_shape, NULL); + return 1; +} + +int +e_popup_shutdown(void) +{ + E_FN_DEL(ecore_event_handler_del, _e_popup_window_shape_handler); + return 1; +} + +E_Popup * +e_popup_new(E_Zone *zone, int x, int y, int w, int h) +{ + E_Popup *pop; + + pop = E_OBJECT_ALLOC(E_Popup, E_POPUP_TYPE, _e_popup_free); + if (!pop) return NULL; + pop->zone = zone; + pop->x = x; + pop->y = y; + pop->w = w; + pop->h = h; + pop->layer = 250; + pop->ecore_evas = ecore_evas_software_x11_new(NULL, + pop->zone->container->win, + pop->zone->x + pop->x, + pop->zone->y + pop->y, + pop->w, pop->h); + ecore_evas_software_x11_direct_resize_set(pop->ecore_evas, 1); + e_canvas_add(pop->ecore_evas); + pop->shape = e_container_shape_add(pop->zone->container); + e_container_shape_move(pop->shape, pop->zone->x + pop->x, pop->zone->y + pop->y); + e_container_shape_resize(pop->shape, pop->w, pop->h); + pop->evas = ecore_evas_get(pop->ecore_evas); + pop->evas_win = ecore_evas_software_x11_window_get(pop->ecore_evas); + e_container_window_raise(pop->zone->container, pop->evas_win, pop->layer); + ecore_x_window_shape_events_select(pop->evas_win, 1); + ecore_evas_name_class_set(pop->ecore_evas, "E", "_e_popup_window"); + ecore_evas_title_set(pop->ecore_evas, "E Popup"); + e_object_ref(E_OBJECT(pop->zone)); + pop->zone->popups = evas_list_append(pop->zone->popups, pop); + _e_popup_list = evas_list_append(_e_popup_list, pop); + return pop; +} + +void +e_popup_show(E_Popup *pop) +{ + if (pop->visible) return; + pop->visible = 1; + ecore_evas_show(pop->ecore_evas); + e_container_shape_show(pop->shape); +} + +void +e_popup_hide(E_Popup *pop) +{ + if (!pop->visible) return; + pop->visible = 0; + ecore_evas_hide(pop->ecore_evas); + e_container_shape_hide(pop->shape); +} + +void +e_popup_move(E_Popup *pop, int x, int y) +{ + if ((pop->x == x) && (pop->y == y)) return; + pop->x = x; + pop->y = y; + ecore_evas_move(pop->ecore_evas, + pop->zone->x + pop->x, + pop->zone->y + pop->y); + e_container_shape_move(pop->shape, + pop->zone->x + pop->x, + pop->zone->y + pop->y); +} + +void +e_popup_resize(E_Popup *pop, int w, int h) +{ + if ((pop->w == w) && (pop->h == h)) return; + pop->w = w; + pop->h = h; + ecore_evas_resize(pop->ecore_evas, pop->w, pop->h); + e_container_shape_resize(pop->shape, pop->w, pop->h); +} + +void +e_popup_move_resize(E_Popup *pop, int x, int y, int w, int h) +{ + if ((pop->x == x) && (pop->y == y) && + (pop->w == w) && (pop->h == h)) return; + pop->x = x; + pop->y = y; + pop->w = w; + pop->h = h; + ecore_evas_move_resize(pop->ecore_evas, + pop->zone->x + pop->x, + pop->zone->y + pop->y, + pop->w, pop->h); + e_container_shape_move(pop->shape, + pop->zone->x + pop->x, + pop->zone->y + pop->y); + e_container_shape_resize(pop->shape, pop->w, pop->h); +} + +void +e_popup_edje_bg_object_set(E_Popup *pop, Evas_Object *o) +{ + const char *shape_option; + + shape_option = edje_object_data_get(o, "shaped"); + if (shape_option) + { + if (!strcmp(shape_option, "1")) + pop->shaped = 1; + else + pop->shaped = 0; + ecore_evas_shaped_set(pop->ecore_evas, pop->shaped); + } +} + +void +e_popup_layer_set(E_Popup *pop, int layer) +{ + pop->layer = layer; + e_container_window_raise(pop->zone->container, pop->evas_win, pop->layer); +} + +void +e_popup_idler_before(void) +{ + Evas_List *l; + + for (l = _e_popup_list; l; l = l->next) + { + E_Popup *pop; + + pop = l->data; + if (pop->need_shape_export) + { + Ecore_X_Rectangle *rects; + int num; + + rects = ecore_x_window_shape_rectangles_get(pop->evas_win, &num); + if (rects) + { + e_container_shape_rects_set(pop->shape, rects, num); + free(rects); + } + pop->need_shape_export = 0; + if (pop->visible) + e_container_shape_show(pop->shape); + } + } +} + +/* local subsystem functions */ + +static void +_e_popup_free(E_Popup *pop) +{ + e_container_shape_hide(pop->shape); + e_object_del(E_OBJECT(pop->shape)); + e_canvas_del(pop->ecore_evas); + ecore_evas_free(pop->ecore_evas); + e_object_unref(E_OBJECT(pop->zone)); + pop->zone->popups = evas_list_remove(pop->zone->popups, pop); + _e_popup_list = evas_list_remove(_e_popup_list, pop); + free(pop); +} + +static int +_e_popup_cb_window_shape(void *data, int ev_type, void *ev) +{ + Evas_List *l; + Ecore_X_Event_Window_Shape *e; + + e = ev; + for (l = _e_popup_list; l; l = l->next) + { + E_Popup *pop; + + pop = l->data; + if (pop->evas_win == e->win) + pop->need_shape_export = 1; + } + return 1; +} diff --git a/src/bin/e_popup.h b/src/bin/e_popup.h new file mode 100644 index 000000000..bc6bbd3dc --- /dev/null +++ b/src/bin/e_popup.h @@ -0,0 +1,46 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#ifdef E_TYPEDEFS + +typedef struct _E_Popup E_Popup; + +#else +#ifndef E_POPUP_H +#define E_POPUP_H + +#define E_POPUP_TYPE 0xE0b0100e + +struct _E_Popup +{ + E_Object e_obj_inherit; + + int x, y, w, h; + int layer; + unsigned char visible : 1; + unsigned char shaped : 1; + unsigned char need_shape_export : 1; + + Ecore_Evas *ecore_evas; + Evas *evas; + Ecore_X_Window evas_win; + E_Container_Shape *shape; + E_Zone *zone; +}; + +EAPI int e_popup_init(void); +EAPI int e_popup_shutdown(void); + +EAPI E_Popup *e_popup_new(E_Zone *zone, int x, int y, int w, int h); +EAPI void e_popup_show(E_Popup *pop); +EAPI void e_popup_hide(E_Popup *pop); +EAPI void e_popup_move(E_Popup *pop, int x, int y); +EAPI void e_popup_resize(E_Popup *pop, int w, int h); +EAPI void e_popup_move_resize(E_Popup *pop, int x, int y, int w, int h); +EAPI void e_popup_(E_Popup *pop, int x, int y); +EAPI void e_popup_edje_bg_object_set(E_Popup *pop, Evas_Object *o); +EAPI void e_popup_layer_set(E_Popup *pop, int layer); +EAPI void e_popup_idler_before(void); + +#endif +#endif diff --git a/src/bin/e_zone.h b/src/bin/e_zone.h index 25dde243c..98f9d6318 100644 --- a/src/bin/e_zone.h +++ b/src/bin/e_zone.h @@ -41,6 +41,7 @@ struct _E_Zone } flip; E_Action *cur_mouse_action; + Evas_List *popups; }; struct _E_Event_Zone_Desk_Count_Set