discomfitor pushed a commit to branch master.
commit fa7744b4de1a694630b703e32295598c963a1572
Author: Mike Blumenkrantz <[email protected]>
Date: Fri Jul 26 14:42:48 2013 +0100
fix ibar client menu to track multiple windows per exe
---
src/bin/e_border.c | 51 +++++++------
src/bin/e_exec.c | 21 ++++--
src/bin/e_exec.h | 4 +-
src/modules/ibar/e_mod_main.c | 170 ++++++++++++++++++++++++++++++------------
4 files changed, 169 insertions(+), 77 deletions(-)
diff --git a/src/bin/e_border.c b/src/bin/e_border.c
index a22962a..ae0802d 100644
--- a/src/bin/e_border.c
+++ b/src/bin/e_border.c
@@ -4899,10 +4899,10 @@ _e_border_del(E_Border *bd)
if (bd->exe_inst)
{
- if (bd->exe_inst->phony)
+ if (bd->exe_inst->phony && (eina_list_count(bd->exe_inst->borders) ==
1))
e_exec_phony_del(bd->exe_inst);
else
- bd->exe_inst->bd = NULL;
+ bd->exe_inst->borders = eina_list_remove(bd->exe_inst->borders, bd);
bd->exe_inst = NULL;
}
@@ -7999,30 +7999,35 @@ _e_border_eval0(E_Border *bd)
{
inst =
e_exec_startup_id_pid_instance_find(bd->client.netwm.startup_id,
bd->client.netwm.pid);
- if ((inst) && (inst->used == 0))
+ if (inst)
{
- E_Zone *zone;
- E_Desk *desk;
-
- inst->used++;
- zone = e_container_zone_number_get(bd->zone->container,
- inst->screen);
- if (zone) e_border_zone_set(bd, zone);
- desk = e_desk_at_xy_get(bd->zone, inst->desk_x,
- inst->desk_y);
- if (desk) e_border_desk_set(bd, desk);
- if (bd->client.netwm.pid != ecore_exe_pid_get(inst->exe))
+ Eina_Bool found;
+ if (inst->used == 0)
{
- /* most likely what has happened here is that the
.desktop launcher
- * has spawned a process which then created this
border, meaning the
- * E_Exec instance will be deleted in a moment, and we
will be unable to track it.
- * to prevent this, we convert our instance to a phony
- */
- inst->phony = 1;
+ E_Zone *zone;
+ E_Desk *desk;
+
+ inst->used++;
+ zone = e_container_zone_number_get(bd->zone->container,
+ inst->screen);
+ if (zone) e_border_zone_set(bd, zone);
+ desk = e_desk_at_xy_get(bd->zone, inst->desk_x,
+ inst->desk_y);
+ if (desk) e_border_desk_set(bd, desk);
+ if (bd->client.netwm.pid !=
ecore_exe_pid_get(inst->exe))
+ {
+ /* most likely what has happened here is that the
.desktop launcher
+ * has spawned a process which then created this
border, meaning the
+ * E_Exec instance will be deleted in a moment,
and we will be unable to track it.
+ * to prevent this, we convert our instance to a
phony
+ */
+ inst->phony = 1;
+ }
}
- inst->bd = bd;
- bd->exe_inst = inst;
- e_exec_instance_found(inst);
+ found = !!inst->borders;
+ e_exec_instance_client_add(inst, bd);
+ if (!found)
+ e_exec_instance_found(inst);
}
else if (!inst)
e_exec_phony(bd);
diff --git a/src/bin/e_exec.c b/src/bin/e_exec.c
index 25f9eab..5ea76f1 100644
--- a/src/bin/e_exec.c
+++ b/src/bin/e_exec.c
@@ -77,6 +77,7 @@ static E_Exec_Instance *(*_e_exec_executor_func)(void *data,
E_Zone * zone, Efre
static void *_e_exec_executor_data = NULL;
EAPI int E_EVENT_EXEC_NEW = -1;
+EAPI int E_EVENT_EXEC_NEW_CLIENT = -1;
EAPI int E_EVENT_EXEC_DEL = -1;
/* externally accessible functions */
@@ -93,6 +94,7 @@ e_exec_init(void)
#endif
E_EVENT_EXEC_NEW = ecore_event_type_new();
+ E_EVENT_EXEC_NEW_CLIENT = ecore_event_type_new();
E_EVENT_EXEC_DEL = ecore_event_type_new();
return 1;
}
@@ -257,7 +259,7 @@ e_exec_phony(E_Border *bd)
}
inst->used = 1;
bd->exe_inst = inst;
- inst->bd = bd;
+ inst->borders = eina_list_append(inst->borders, bd);
if (bd->zone) inst->screen = bd->zone->num;
if (bd->desk)
{
@@ -342,6 +344,15 @@ e_exec_instance_found(E_Exec_Instance *inst)
}
EAPI void
+e_exec_instance_client_add(E_Exec_Instance *inst, E_Border *bd)
+{
+ inst->borders = eina_list_append(inst->borders, bd);
+ bd->exe_inst = inst;
+ inst->ref++;
+ ecore_event_add(E_EVENT_EXEC_NEW_CLIENT, inst, _e_exec_cb_exec_new_free,
inst);
+}
+
+EAPI void
e_exec_instance_watcher_add(E_Exec_Instance *inst, void (*func)(void *data,
E_Exec_Instance *inst, E_Exec_Watch_Type type), const void *data)
{
E_Exec_Watch *iw;
@@ -618,6 +629,7 @@ static void
_e_exec_instance_free(E_Exec_Instance *inst)
{
Eina_List *instances;
+ E_Border *bd;
if (inst->ref) return;
E_FREE_LIST(inst->watchers, free);
@@ -644,11 +656,8 @@ _e_exec_instance_free(E_Exec_Instance *inst)
e_exec_start_pending = eina_list_remove(e_exec_start_pending,
inst->desktop);
if (inst->expire_timer) ecore_timer_del(inst->expire_timer);
- if (inst->bd)
- {
- inst->bd->exe_inst = NULL;
- inst->bd = NULL;
- }
+ EINA_LIST_FREE(inst->borders, bd)
+ bd->exe_inst = NULL;
if (inst->desktop) efreet_desktop_free(inst->desktop);
free(inst);
}
diff --git a/src/bin/e_exec.h b/src/bin/e_exec.h
index 9cc3966..86090b8 100644
--- a/src/bin/e_exec.h
+++ b/src/bin/e_exec.h
@@ -9,7 +9,7 @@ typedef struct _E_Exec_Instance E_Exec_Instance;
struct _E_Exec_Instance
{
Efreet_Desktop *desktop;
- E_Border *bd;
+ Eina_List *borders;
const char *key;
Ecore_Exe *exe;
int startup_id;
@@ -46,9 +46,11 @@ EAPI void e_exec_instance_watcher_del(E_Exec_Instance *inst,
void (*func) (void
EAPI const Eina_List *e_exec_desktop_instances_find(const Efreet_Desktop
*desktop);
EAPI const Eina_Hash *e_exec_instances_get(void);
+EAPI void e_exec_instance_client_add(E_Exec_Instance *inst, E_Border *bd);
/* sends E_Exec_Instance */
EAPI extern int E_EVENT_EXEC_NEW;
+EAPI extern int E_EVENT_EXEC_NEW_CLIENT;
EAPI extern int E_EVENT_EXEC_DEL;
#endif
diff --git a/src/modules/ibar/e_mod_main.c b/src/modules/ibar/e_mod_main.c
index 7c70d7c..5cf91c5 100644
--- a/src/modules/ibar/e_mod_main.c
+++ b/src/modules/ibar/e_mod_main.c
@@ -524,8 +524,18 @@ _ibar_fill(IBar *b)
{
EINA_LIST_FOREACH(l, ll, exe)
{
+ E_Border *bd;
+ Eina_List *lll;
+ Eina_Bool skip = EINA_TRUE;
+
if (!exe->desktop) continue;
- if (exe->bd && exe->bd->client.netwm.state.skip_taskbar)
continue;
+ EINA_LIST_FOREACH(exe->borders, lll, bd)
+ if (!bd->client.netwm.state.skip_taskbar)
+ {
+ skip = EINA_FALSE;
+ break;
+ }
+ if (skip) continue;
ic = eina_hash_find(b->icon_hash,
_desktop_name_get(exe->desktop));
if (ic)
{
@@ -1025,6 +1035,7 @@ _ibar_cb_icon_menu_img_del(void *data, Evas *e
EINA_UNUSED, Evas_Object *obj EIN
IBar_Icon *ic = evas_object_data_del(data, "ibar_icon");
if (!ic) return; //menu is closing
+ if (!ic->menu) return; //who knows
edje_object_part_box_remove(ic->menu->o_bg, "e.box", data);
evas_object_del(data);
if (eina_list_count(ic->exes) < 2)
@@ -1071,33 +1082,37 @@ _ibar_icon_menu(IBar_Icon *ic)
{
Evas_Object *img;
const char *txt;
+ Eina_List *ll;
+ E_Border *bd;
- if (!exe->bd) continue; //WTF
- it = edje_object_add(e);
- e_popup_object_add(ic->menu->win, it);
- e_theme_edje_object_set(it, "base/theme/modules/ibar",
- "e/modules/ibar/menu/item");
- img = e_comp_win_image_mirror_add(exe->bd->cw);
- evas_object_event_callback_add(img, EVAS_CALLBACK_DEL,
- _ibar_cb_icon_menu_img_del, it);
- txt = exe->bd->client.netwm.name ?:
- (exe->bd->client.icccm.title ?: exe->bd->client.icccm.name);
- w = exe->bd->cw->pw;
- h = exe->bd->cw->ph;
- e_popup_object_add(ic->menu->win, img);
- evas_object_show(img);
- edje_extern_object_aspect_set(img, EDJE_ASPECT_CONTROL_BOTH, w, h);
- edje_object_part_swallow(it, "e.swallow.icon", img);
- edje_object_part_text_set(it, "e.text.title", txt);
- edje_object_calc_force(it);
- edje_object_size_min_calc(it, &w, &h);
- edje_extern_object_min_size_set(it, w, h);
- evas_object_size_hint_min_set(it, w, h);
- evas_object_show(it);
- evas_object_event_callback_add(it, EVAS_CALLBACK_MOUSE_UP,
- _ibar_cb_icon_menu_mouse_up, exe->bd);
- evas_object_data_set(it, "ibar_icon", ic);
- edje_object_part_box_append(o, "e.box", it);
+ EINA_LIST_FOREACH(exe->borders, ll, bd)
+ {
+ if (bd->client.netwm.state.skip_taskbar) continue;
+ it = edje_object_add(e);
+ e_popup_object_add(ic->menu->win, it);
+ e_theme_edje_object_set(it, "base/theme/modules/ibar",
+ "e/modules/ibar/menu/item");
+ img = e_comp_win_image_mirror_add(bd->cw);
+ evas_object_event_callback_add(img, EVAS_CALLBACK_DEL,
+ _ibar_cb_icon_menu_img_del, it);
+ txt = e_border_name_get(bd);
+ w = bd->cw->pw;
+ h = bd->cw->ph;
+ e_popup_object_add(ic->menu->win, img);
+ evas_object_show(img);
+ edje_extern_object_aspect_set(img, EDJE_ASPECT_CONTROL_BOTH, w,
h);
+ edje_object_part_swallow(it, "e.swallow.icon", img);
+ edje_object_part_text_set(it, "e.text.title", txt);
+ edje_object_calc_force(it);
+ edje_object_size_min_calc(it, &w, &h);
+ edje_extern_object_min_size_set(it, w, h);
+ evas_object_size_hint_min_set(it, w, h);
+ evas_object_show(it);
+ evas_object_event_callback_add(it, EVAS_CALLBACK_MOUSE_UP,
+ _ibar_cb_icon_menu_mouse_up, bd);
+ evas_object_data_set(it, "ibar_icon", ic);
+ edje_object_part_box_append(o, "e.box", it);
+ }
}
if (!ic->menu->win->objects)
{
@@ -1293,35 +1308,56 @@ _ibar_cb_icon_reset(void *data)
static void
_ibar_cb_icon_wheel(void *data, Evas *e __UNUSED__, Evas_Object *obj
__UNUSED__, void *event_info)
{
- Evas_Event_Mouse_Wheel *ev;
+ Evas_Event_Mouse_Wheel *ev = event_info;
E_Exec_Instance *exe;
- IBar_Icon *ic;
+ IBar_Icon *ic = data;
+ E_Border *cur, *sel = NULL;
+ Eina_List *l;
- ev = event_info;
- ic = data;
-
if (!ic->exes) return;
+ cur = e_border_focused_get();
if (!ic->exe_current)
- ic->exe_current = eina_list_nth_list(ic->exes, 0);
-
+ ic->exe_current = ic->exes;
+
+ exe = eina_list_data_get(ic->exe_current);
if (ev->z < 0)
- {
- ic->exe_current = eina_list_next(ic->exe_current);
- if (!ic->exe_current)
- ic->exe_current = eina_list_nth_list(ic->exes, 0);
+ {
+ if (cur->exe_inst == exe)
+ {
+ l = eina_list_data_find_list(exe->borders, cur);
+ if (l) sel = eina_list_data_get(eina_list_next(l));
+ }
+ if (!sel)
+ {
+ ic->exe_current = eina_list_next(ic->exe_current);
+ if (!ic->exe_current)
+ ic->exe_current = ic->exes;
+ }
}
else if (ev->z > 0)
{
- ic->exe_current = eina_list_prev(ic->exe_current);
- if (!ic->exe_current)
- ic->exe_current = eina_list_last(ic->exes);
+ if (cur->exe_inst == exe)
+ {
+ l = eina_list_data_find_list(exe->borders, cur);
+ if (l) sel = eina_list_data_get(eina_list_prev(l));
+ }
+ if (!sel)
+ {
+ ic->exe_current = eina_list_prev(ic->exe_current);
+ if (!ic->exe_current)
+ ic->exe_current = eina_list_last(ic->exes);
+ }
+ }
+
+ if (!sel)
+ {
+ exe = eina_list_data_get(ic->exe_current);
+ sel = eina_list_data_get(exe->borders);
}
- exe = eina_list_data_get(ic->exe_current);
-
- if (!exe->bd) return;
- e_border_activate(exe->bd, 1);
+ if (sel)
+ e_border_activate(sel, 1);
}
static void
@@ -2237,14 +2273,52 @@ _ibar_cb_exec_del(void *d EINA_UNUSED, int t
EINA_UNUSED, E_Exec_Instance *exe)
}
static Eina_Bool
-_ibar_cb_exec_new(void *d EINA_UNUSED, int t EINA_UNUSED, E_Exec_Instance *exe)
+_ibar_cb_exec_new_client(void *d EINA_UNUSED, int t EINA_UNUSED,
E_Exec_Instance *exe)
{
IBar *b;
+ E_Border *bd;
Eina_List *l;
Eina_Bool skip;
if (!exe->desktop) return ECORE_CALLBACK_RENEW; //can't do anything here :(
- skip = exe->bd && exe->bd->client.netwm.state.skip_taskbar;
+ bd = eina_list_last_data_get(exe->borders); //only care about last (new) one
+ skip = bd->client.netwm.state.skip_taskbar;
+ EINA_LIST_FOREACH(ibars, l, b)
+ {
+ IBar_Icon *ic;
+
+ ic = eina_hash_find(b->icon_hash, _desktop_name_get(exe->desktop));
+ if (ic)
+ {
+ _ibar_icon_signal_emit(ic, "e,state,started", "e");
+ if (!ic->exes) _ibar_icon_signal_emit(ic, "e,state,on", "e");
+ if (skip) continue;
+ if (!eina_list_data_find(ic->exes, exe))
+ ic->exes = eina_list_append(ic->exes, exe);
+ }
+ else if (!b->inst->ci->dont_add_nonorder)
+ {
+ if (skip) continue;
+ _ibar_sep_create(b);
+ ic = _ibar_icon_notinorder_new(b, exe);
+ _ibar_resize_handle(b);
+ }
+ }
+ return ECORE_CALLBACK_RENEW;
+}
+
+static Eina_Bool
+_ibar_cb_exec_new(void *d EINA_UNUSED, int t EINA_UNUSED, E_Exec_Instance *exe)
+{
+ IBar *b;
+ E_Border *bd;
+ Eina_List *l;
+ Eina_Bool skip = EINA_TRUE;
+
+ if (!exe->desktop) return ECORE_CALLBACK_RENEW; //can't do anything here :(
+ EINA_LIST_FOREACH(exe->borders, l, bd)
+ if (!bd->client.netwm.state.skip_taskbar)
+ skip = EINA_FALSE;
EINA_LIST_FOREACH(ibars, l, b)
{
IBar_Icon *ic;
@@ -2325,6 +2399,8 @@ e_modapi_init(E_Module *m)
_ibar_cb_config_icons, NULL);
E_LIST_HANDLER_APPEND(ibar_config->handlers, E_EVENT_EXEC_NEW,
_ibar_cb_exec_new, NULL);
+ E_LIST_HANDLER_APPEND(ibar_config->handlers, E_EVENT_EXEC_NEW_CLIENT,
+ _ibar_cb_exec_new_client, NULL);
E_LIST_HANDLER_APPEND(ibar_config->handlers, E_EVENT_EXEC_DEL,
_ibar_cb_exec_del, NULL);
E_LIST_HANDLER_APPEND(ibar_config->handlers, E_EVENT_BORDER_PROPERTY,
--
------------------------------------------------------------------------------
See everything from the browser to the database with AppDynamics
Get end-to-end visibility with application monitoring from AppDynamics
Isolate bottlenecks and diagnose root cause in seconds.
Start your free trial of AppDynamics Pro today!
http://pubads.g.doubleclick.net/gampad/clk?id=48808831&iu=/4140/ostg.clktrk