From ffcb25ea12864ca549562e74fde7e1da4d783a47 Mon Sep 17 00:00:00 2001 From: rephorm Date: Thu, 24 Jan 2002 08:12:12 +0000 Subject: [PATCH] E_EVENT system is now a bit map, allowing one observer to watch MANY events, for instance: E_EVENT_BORDER_ICONIFY | E_EVENT_BORDER_UNICONIFY | E_EVENT_BORDER_NEW, etc. I also made it so that the current event is passed when notifying, so that if watching multiple events, you can do different things for each. added an e_observer_notify_all_observees() to notify all existing observees of things, such as the creation of a border. This way, an observer can watch for E_EVENT_BORDER_NEW events and register all new borders. Iconification! Click that iconify button. Then click the middle button on the desktop to get a menu of iconified apps to uniconify. This menu is a decent example of using the observer code to avoid polling or rebuilding more than necessary. Next, maybe instead of completely rebuilding each time something changes, maybe it should dynamically add or remove the respective menu items? SVN revision: 5854 --- src/actions.c | 6 +++++- src/border.c | 15 ++++++++------- src/delayed.c | 2 +- src/delayed.h | 2 +- src/epplet.c | 6 +++--- src/epplet.h | 2 +- src/menu.c | 14 ++++++++------ src/menubuild.c | 25 ++++++++++++++++++------- src/observer.c | 35 ++++++++++++++++++++++++++++++++--- src/observer.h | 37 +++++++++++++++++++++++++++++-------- src/view.c | 2 +- 11 files changed, 107 insertions(+), 39 deletions(-) diff --git a/src/actions.c b/src/actions.c index 7c1a723b7..9868bbbfd 100644 --- a/src/actions.c +++ b/src/actions.c @@ -1658,7 +1658,7 @@ e_act_iconify_start (E_Object *object, E_Action *a, void *data, int x, int y, in E_Border *b; D_ENTER; -#if 0 +#if 1 b = (E_Border*) object; if (!b) b = e_border_current_focused(); if (!b) D_RETURN; @@ -1707,6 +1707,8 @@ e_act_max_start (E_Object *object, E_Action *a, void *data, int x, int y, int rx b->current.requested.y = b->current.y; b->current.requested.w = b->current.w; b->current.requested.h = b->current.h; + + e_observee_notify_observers(E_OBSERVEE(b), E_EVENT_BORDER_UNMAXIMIZE); } else { @@ -1725,6 +1727,8 @@ e_act_max_start (E_Object *object, E_Action *a, void *data, int x, int y, int rx b->current.requested.y = b->current.y; b->current.requested.w = b->current.w; b->current.requested.h = b->current.h; + + e_observee_notify_observers(E_OBSERVEE(b), E_EVENT_BORDER_MAXIMIZE); } D_RETURN; diff --git a/src/border.c b/src/border.c index d311d967b..a9dc03828 100644 --- a/src/border.c +++ b/src/border.c @@ -453,7 +453,7 @@ e_focus_in(Ecore_Event * ev) e_border_focus_grab_ended(); b->current.selected = 1; b->changed = 1; - e_observee_notify_observers(E_OBSERVEE(b), E_EVENT_WINDOW_FOCUS_IN); + e_observee_notify_observers(E_OBSERVEE(b), E_EVENT_BORDER_FOCUS_IN); g = b->click_grab; if (g) { @@ -1619,7 +1619,7 @@ e_border_new(void) b = NEW(E_Border, 1); ZERO(b, E_Border, 1); - e_object_init(E_OBJECT(b), (E_Cleanup_Func) e_border_cleanup); + e_observee_init(E_OBSERVEE(b), (E_Cleanup_Func) e_border_cleanup); e_observer_register_observee(E_OBSERVER(delayed_window_raise), E_OBSERVEE(b)); @@ -1746,6 +1746,8 @@ e_border_new(void) e_border_attach_mouse_grabs(b); borders = evas_list_prepend(borders, b); + + e_observee_notify_all_observers(E_OBSERVEE(b), E_EVENT_BORDER_NEW); D_RETURN_(b); } @@ -1754,14 +1756,12 @@ void e_border_iconify(E_Border *b) { D_ENTER; - D("iconfy window!\n"); b->client.iconified = 1; b->current.requested.visible = 0; e_icccm_state_iconified(b->win.client); b->changed = 1; e_border_update(b); - D("notify observers of iconification\n"); - e_observee_notify_observers(E_OBSERVEE(b), E_EVENT_WINDOW_ICONIFY); + e_observee_notify_observers(E_OBSERVEE(b), E_EVENT_BORDER_ICONIFY); D_RETURN; } @@ -1771,11 +1771,12 @@ e_border_uniconify(E_Border *b) { b->client.iconified = 0; b->current.requested.visible = 1; + b->client.desk = e_desktops_get_current(); e_icccm_state_mapped(b->win.client); b->changed = 1; e_border_update(b); /* should be UNICONIFY */ - e_observee_notify_observers(E_OBSERVEE(b), E_EVENT_WINDOW_ICONIFY); + e_observee_notify_observers(E_OBSERVEE(b), E_EVENT_BORDER_ICONIFY); } void @@ -2674,7 +2675,7 @@ e_border_init(void) ecore_event_filter_idle_handler_add(e_idle, NULL); delayed_window_raise = - e_delayed_action_new(E_EVENT_WINDOW_FOCUS_IN, + e_delayed_action_new(E_EVENT_BORDER_FOCUS_IN, raise_delay, e_border_raise_delayed); ecore_add_event_timer("e_border_poll()", 1.00, e_border_poll, 0, NULL); diff --git a/src/delayed.c b/src/delayed.c index 76acbb39b..d80b84b96 100644 --- a/src/delayed.c +++ b/src/delayed.c @@ -36,7 +36,7 @@ e_delayed_action_new(E_Event_Type event, void -e_delayed_action_start(E_Observer *obs, E_Observee *obj) +e_delayed_action_start(E_Observer *obs, E_Observee *obj, E_Event_Type event) { char event_name[PATH_MAX]; E_Delayed_Action *eda = (E_Delayed_Action*) obs; diff --git a/src/delayed.h b/src/delayed.h index 32f495e7f..9bf3e02ca 100644 --- a/src/delayed.h +++ b/src/delayed.h @@ -19,7 +19,7 @@ typedef struct _e_delayed_action E_Delayed_Action *e_delayed_action_new(E_Event_Type event, double delay, E_Delay_Func delay_func); -void e_delayed_action_start(E_Observer *obs, E_Observee *obj); +void e_delayed_action_start(E_Observer *obs, E_Observee *obj, E_Event_Type event); void e_delayed_action_cancel(E_Delayed_Action *eda); #endif diff --git a/src/epplet.c b/src/epplet.c index 41545621f..e486c984b 100644 --- a/src/epplet.c +++ b/src/epplet.c @@ -548,11 +548,11 @@ e_epplet_observer_new(FeriteScript *script, char *func_name, FeriteObject *data, (E_Cleanup_Func)e_epplet_observer_cleanup); #if 0 else if (!strcmp(event_type, "ICONIFY")) - e_observer_init(E_OBSERVER(obs), E_EVENT_WINDOW_ICONIFY, + e_observer_init(E_OBSERVER(obs), E_EVENT_BORDER_ICONIFY, e_epplet_border_observer_func, (E_Cleanup_Func)e_epplet_observer_cleanup); else if (!strcmp(event_type, "UNICONIFY")) - e_observer_init(E_OBSERVER(obs), E_EVENT_WINDOW_UNICONIFY, + e_observer_init(E_OBSERVER(obs), E_EVENT_BORDER_UNICONIFY, e_epplet_border_observer_func, (E_Cleanup_Func)e_epplet_observer_cleanup); else @@ -618,7 +618,7 @@ e_epplet_observer_register_borders(E_Epplet_Observer *obs) #endif void -e_epplet_desktop_observer_func(E_Observer *observer, E_Observee *observee) +e_epplet_desktop_observer_func(E_Observer *observer, E_Observee *observee, E_Event_Type event) { E_Epplet_Observer *obs; E_Desktop *desk; diff --git a/src/epplet.h b/src/epplet.h index 95dc6fc19..d1ce0fe38 100644 --- a/src/epplet.h +++ b/src/epplet.h @@ -92,7 +92,7 @@ void e_epplet_timer_func(int val, void *data); E_Epplet_Observer *e_epplet_observer_new( FeriteScript *script, char *func_name, FeriteObject *data, char *event_type); void e_epplet_observer_register_desktops(E_Epplet_Observer *obs); -void e_epplet_desktop_observer_func(E_Observer *observer, E_Observee *observee); +void e_epplet_desktop_observer_func(E_Observer *observer, E_Observee *observee, E_Event_Type event); /*void e_epplet_border_observer_func(E_Observer *observer, E_Observee *observee);*/ #endif diff --git a/src/menu.c b/src/menu.c index 736855519..5ac3ae50c 100644 --- a/src/menu.c +++ b/src/menu.c @@ -564,12 +564,14 @@ static void e_menu_item_unselect (E_Menu_Item *mi) { D_ENTER; -D("mi unselect\n"); - if ((mi))// && (mi->menu->selected == mi)) + D("mi unselect\n"); + if ((mi) && (mi->menu->selected == mi)) { -D("mi && mi->menu->selected == mi\n"); - mi->menu->selected = curr_selected_item = NULL; - mi->selected = 0; + D("mi && mi->menu->selected == mi\n"); + mi->menu->selected = curr_selected_item = NULL; + D("after setting it NULL\n"); + + mi->selected = 0; mi->menu->redo_sel = 1; mi->menu->changed = 1; } @@ -589,7 +591,7 @@ e_menu_item_select (E_Menu_Item *mi) { D_ENTER; - e_menu_item_unselect(curr_selected_item); + // e_menu_item_unselect(curr_selected_item); if (mi) { mi->menu->selected = mi; diff --git a/src/menubuild.c b/src/menubuild.c index e03f35a74..94d034fd6 100644 --- a/src/menubuild.c +++ b/src/menubuild.c @@ -26,7 +26,7 @@ static void e_build_menu_gnome_apps_poll(int val, void *data); static void e_build_menu_gnome_apps_build(E_Build_Menu *bm); static E_Menu *e_build_menu_iconified_borders_build(E_Build_Menu *bm); -static void e_build_menu_iconified_borders_rebuild(E_Observer *observer, E_Observee *observee); +static void e_build_menu_iconified_borders_rebuild(E_Observer *observer, E_Observee *observee, E_Event_Type event); /* ------------ various callbacks ---------------------- */ @@ -524,7 +524,7 @@ e_build_menu_new_from_iconified_borders() bm = NEW(E_Build_Menu, 1); ZERO(bm, E_Build_Menu, 1); - e_observer_init(E_OBSERVER(bm), E_EVENT_WINDOW_ICONIFY, e_build_menu_iconified_borders_rebuild, (E_Cleanup_Func) e_build_menu_cleanup); + e_observer_init(E_OBSERVER(bm), E_EVENT_BORDER_ICONIFY | E_EVENT_BORDER_UNICONIFY | E_EVENT_BORDER_NEW, e_build_menu_iconified_borders_rebuild, (E_Cleanup_Func) e_build_menu_cleanup); for (l = e_border_get_borders_list(); l; l = l->next) { @@ -539,16 +539,27 @@ e_build_menu_new_from_iconified_borders() } static void -e_build_menu_iconified_borders_rebuild(E_Observer *observer, E_Observee *observee) +e_build_menu_iconified_borders_rebuild(E_Observer *observer, E_Observee *observee, E_Event_Type event) { E_Build_Menu *bm; D_ENTER; - D("catch iconify, rebuild menu"); - bm = (E_Build_Menu *)observer; + + if (event & E_EVENT_BORDER_NEW) + { + D("catch new border, register it\n"); + e_observer_register_observee(E_OBSERVER(observer), E_OBSERVEE(observee)); + } + + if (event & (E_EVENT_BORDER_ICONIFY | E_EVENT_BORDER_UNICONIFY)) + { + D("catch iconify, rebuild menu\n"); + bm = (E_Build_Menu *)observer; - e_build_menu_unbuild(bm); - bm->menu = e_build_menu_iconified_borders_build(bm); + e_build_menu_unbuild(bm); + bm->menu = e_build_menu_iconified_borders_build(bm); + } + D_RETURN; } diff --git a/src/observer.c b/src/observer.c index 87e68101c..ccb1396ea 100644 --- a/src/observer.c +++ b/src/observer.c @@ -3,6 +3,8 @@ #include "debug.h" #include "observer.h" +static Evas_List observers; + void e_observer_init(E_Observer *obs, E_Event_Type event, E_Notify_Func notify_func, @@ -21,6 +23,8 @@ e_observer_init(E_Observer *obs, E_Event_Type event, e_object_init(E_OBJECT(obs), cleanup_func); + observers = evas_list_append(observers, obs); + D_RETURN; } @@ -40,6 +44,7 @@ e_observer_cleanup(E_Observer *obs) e_observer_unregister_observee(obs, o); } + evas_list_remove(observers, obs); /* Call the destructor of the base class */ e_object_cleanup(E_OBJECT(obs)); @@ -107,16 +112,40 @@ e_observee_notify_observers(E_Observee *o, E_Event_Type event) { obs = E_OBSERVER(obs_list->data); - if (obs->event == E_EVENT_MAX || - obs->event == event) + /* check bit mask */ + if (obs->event & event) { - obs->notify_func(obs, o); + obs->notify_func(obs, o, event); } } D_RETURN; } +void +e_observee_notify_all_observers(E_Observee *o, E_Event_Type event) +{ + Evas_List obs_list = NULL; + E_Observer *obs = NULL; + + D_ENTER; + + if (!o) + D_RETURN; + + for (obs_list = observers; obs_list; obs_list = obs_list->next) + { + obs = E_OBSERVER(obs_list->data); + + /* check bit mask */ + if (obs->event & event) + { + obs->notify_func(obs, o, event); + } + } + + D_RETURN; +} void e_observee_cleanup(E_Observee *obs) diff --git a/src/observer.h b/src/observer.h index ee60c8806..c27eab981 100644 --- a/src/observer.h +++ b/src/observer.h @@ -12,18 +12,24 @@ typedef struct _e_observer E_Observer; typedef struct _e_observee E_Observee; -typedef void(*E_Notify_Func)(E_Observer *observer, E_Observee *observee); - typedef enum _e_event_type { - E_EVENT_WINDOW_FOCUS_IN, - E_EVENT_WINDOW_ICONIFY, - E_EVENT_WINDOW_UNICONIFY, - E_EVENT_WINDOW_MAXIMIZE, - E_EVENT_DESKTOP_SWITCH, - E_EVENT_MAX + E_EVENT_BORDER_NEW = 1 << 0, + E_EVENT_BORDER_RELEASE = 1 << 1, + E_EVENT_BORDER_FOCUS_IN = 1 << 2, + E_EVENT_BORDER_ICONIFY = 1 << 3, + E_EVENT_BORDER_UNICONIFY = 1 << 4, + E_EVENT_BORDER_MAXIMIZE = 1 << 5, + E_EVENT_BORDER_UNMAXIMIZE = 1 << 6, + + E_EVENT_DESKTOP_SWITCH = 1 << 10, + + + E_EVENT_MAX = 0xFFFFFFFF } E_Event_Type; +typedef void(*E_Notify_Func)(E_Observer *observer, E_Observee *observee, E_Event_Type event); + struct _e_observer { E_Object obj; @@ -114,4 +120,19 @@ void e_observee_cleanup(E_Observee *obs); void e_observee_notify_observers(E_Observee *o, E_Event_Type event); +/** + * e_observee_notify_all_observers - Notify all observers of a given E event + * regardless of whether they are registered or not. + * + * @o: The observee which notifies the observers + * @event: The event by which to filter the observers + * + * This function scans ALL observers in the observee + * and calls the notify_func() of the observers that are + * responsible for the given @event. Useful for situations where the observee + * is just being created and you want to notify observers of its existence. + * If they are looking for this type of NEW event, then they can register + * it as a legitimate observee. + */ +void e_observee_notify_all_observers(E_Observee *o, E_Event_Type event); #endif diff --git a/src/view.c b/src/view.c index bfd18b988..aead77779 100644 --- a/src/view.c +++ b/src/view.c @@ -432,7 +432,7 @@ e_bg_up_cb(void *_data, Evas _e, Evas_Object _o, int _b, int _x, int _y) } else if (_b == 2) { -#if 0 +#if 1 static E_Build_Menu *buildmenu = NULL; if (!buildmenu)