From 485f1e2a6c1c0a212f8a209741aa29be7ec96087 Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Mon, 26 Sep 2005 09:13:44 +0000 Subject: [PATCH] I have cleaned up app instance trackign a little. it's a bit complex really, but works better now, and e now falls back to lookign for startup info and app instances etc. to try find an icon, and finally uses the icon provided by the app itself (netwm icon only) :) SVN revision: 16951 --- src/bin/e_apps.c | 160 ++++++++++++++++++++-------------- src/bin/e_apps.h | 1 + src/bin/e_border.c | 115 +++++++++++++++--------- src/bin/e_icon.c | 10 +++ src/bin/e_icon.h | 3 +- src/modules/ibar/e_mod_main.c | 4 +- 6 files changed, 182 insertions(+), 111 deletions(-) diff --git a/src/bin/e_apps.c b/src/bin/e_apps.c index 2894acf85..d77d60338 100644 --- a/src/bin/e_apps.c +++ b/src/bin/e_apps.c @@ -297,6 +297,7 @@ _e_app_cache_new(E_App_Cache *ac, char *path, int scan_subdirs) a3->parent = a; a->subapps = evas_list_append(a->subapps, a3); a2->references = evas_list_append(a2->references, a3); + _e_apps_list = evas_list_prepend(_e_apps_list, a3); } else e_object_del(E_OBJECT(a3)); @@ -476,6 +477,7 @@ e_app_subdir_scan(E_App *a, int scan_subdirs) a3->parent = a; a->subapps = evas_list_append(a->subapps, a3); a2->references = evas_list_append(a2->references, a3); + _e_apps_list = evas_list_prepend(_e_apps_list, a3); } else e_object_del(E_OBJECT(a3)); @@ -503,9 +505,11 @@ e_app_exec(E_App *a, int launch_id) if (!a->exe) return 0; /* FIXME: set up locale, encoding and input method env vars if they are in * the eapp file */ - exe = ecore_exe_run(a->exe, a); + inst = calloc(1, sizeof(E_App_Instance)); + exe = ecore_exe_run(a->exe, inst); if (!exe) { + free(inst); e_error_dialog_show(_("Run Error"), _("Enlightenment was unable fork a child process:\n" "\n" @@ -514,17 +518,16 @@ e_app_exec(E_App *a, int launch_id) a->exe); return 0; } - inst = calloc(1, sizeof(E_App_Instance)); inst->app = a; inst->exe = exe; inst->launch_id = launch_id; inst->launch_time = ecore_time_get(); inst->expire_timer = ecore_timer_add(10.0, _e_app_cb_expire_timer, inst); a->instances = evas_list_append(a->instances, inst); - e_object_ref(E_OBJECT(a)); +// e_object_ref(E_OBJECT(a)); + _e_apps_start_pending = evas_list_append(_e_apps_start_pending, a); if (a->startup_notify) a->starting = 1; _e_app_change(a, E_APP_EXEC); - _e_apps_start_pending = evas_list_append(_e_apps_start_pending, a); return 1; } @@ -765,6 +768,33 @@ e_app_change_callback_del(void (*func) (void *data, E_App *a, E_App_Change ch), } } +E_App * +e_app_launch_id_pid_find(int launch_id, pid_t pid) +{ + Evas_List *l, *ll; + + for (l = _e_apps_list; l; l = l->next) + { + E_App *a; + + a = l->data; + for (ll = a->instances; ll; ll = ll->next) + { + E_App_Instance *ai; + + ai = ll->data; + if (((launch_id > 0) && (ai->launch_id > 0) && (ai->launch_id == launch_id)) || + ((pid > 1) && (ai->exe) && (ecore_exe_pid_get(ai->exe) == pid))) + { + _e_apps_list = evas_list_remove_list(_e_apps_list, l); + _e_apps_list = evas_list_prepend(_e_apps_list, a); + return a; + } + } + } + return NULL; +} + E_App * e_app_window_name_class_title_role_find(const char *name, const char *class, const char *title, const char *role) @@ -927,18 +957,10 @@ _e_app_free(E_App *a) E_App_Instance *inst; inst = a->instances->data; - if (inst->expire_timer) - { - ecore_timer_del(inst->expire_timer); - inst->expire_timer = NULL; - } - if (inst->exe) - { - ecore_exe_free(inst->exe); - inst->exe = NULL; - } - free(inst); + inst->app = a->orig; + a->orig->instances = evas_list_append(a->orig->instances, inst); a->instances = evas_list_remove_list(a->instances, a->instances); + _e_apps_start_pending = evas_list_append(_e_apps_start_pending, a->orig); } /* If this is a copy, it shouldn't have any references! */ if (a->references) @@ -946,6 +968,7 @@ _e_app_free(E_App *a) if (a->parent) a->parent->subapps = evas_list_remove(a->parent->subapps, a); a->orig->references = evas_list_remove(a->orig->references, a); + _e_apps_list = evas_list_remove(_e_apps_list, a); e_object_unref(E_OBJECT(a->orig)); free(a); } @@ -1277,56 +1300,6 @@ _e_app_change(E_App *a, E_App_Change ch) } } -static int -_e_apps_cb_exit(void *data, int type, void *event) -{ - Ecore_Event_Exe_Exit *ev; - E_App *a; - - /* FIXME: Check if we launched this exe, else it isn't sure that - * the exe data is an E_App! - */ - ev = event; - if (ev->exe) - { - a = ecore_exe_data_get(ev->exe); - if (a) - { - Evas_List *l; - - if (ev->exit_code == 127) /* /bin/sh uses this if cmd not found */ - e_error_dialog_show(_("Run Error"), - _("Enlightenment was unable run the program:\n" - "\n" - "%s\n" - "\n" - "The command was not found\n"), - a->exe); - for (l = a->instances; l; l = l->next) - { - E_App_Instance *inst; - - inst = l->data; - if (ev->exe == inst->exe) - { - if (inst->expire_timer) - { - ecore_timer_del(inst->expire_timer); - inst->expire_timer = NULL; - } - inst->exe = NULL; - a->instances = evas_list_remove_list(a->instances, l); - free(inst); - break; - } - } - _e_app_change(a, E_APP_EXIT); - e_object_unref(E_OBJECT(a)); - } - } - return 1; -} - static void _e_app_cb_monitor(void *data, Ecore_File_Monitor *em, Ecore_File_Event event, const char *path) @@ -1524,6 +1497,7 @@ _e_app_subdir_rescan(E_App *app) subapps = evas_list_append(subapps, a3); a2->references = evas_list_append(a2->references, a3); + _e_apps_list = evas_list_prepend(_e_apps_list, a3); } else e_object_del(E_OBJECT(a3)); @@ -1660,6 +1634,60 @@ _e_app_save_order(E_App *app) fclose(f); } +static int +_e_apps_cb_exit(void *data, int type, void *event) +{ + Ecore_Event_Exe_Exit *ev; + E_App *a; + + /* FIXME: Check if we launched this exe, else it isn't sure that + * the exe data is an E_App! + */ + ev = event; + if (ev->exe) + { + E_App_Instance *ai; + + ai = ecore_exe_data_get(ev->exe); + a = ai->app; + if (a) + { + Evas_List *l; + + if (ev->exit_code == 127) /* /bin/sh uses this if cmd not found */ + e_error_dialog_show(_("Run Error"), + _("Enlightenment was unable run the program:\n" + "\n" + "%s\n" + "\n" + "The command was not found\n"), + a->exe); + for (l = a->instances; l; l = l->next) + { + E_App_Instance *inst; + + inst = l->data; + if (ev->exe == inst->exe) + { + if (inst->expire_timer) + { + ecore_timer_del(inst->expire_timer); + inst->expire_timer = NULL; + } + inst->exe = NULL; + a->instances = evas_list_remove_list(a->instances, l); + free(inst); + _e_apps_start_pending = evas_list_remove(_e_apps_start_pending, a); +// e_object_unref(E_OBJECT(a)); + break; + } + } + _e_app_change(a, E_APP_EXIT); + } + } + return 1; +} + static int _e_app_cb_event_border_add(void *data, int type, void *event) { @@ -1694,8 +1722,8 @@ _e_app_cb_event_border_add(void *data, int type, void *event) a = removes->data; _e_app_change(a, E_APP_READY); _e_apps_start_pending = evas_list_remove(_e_apps_start_pending, a); - removes = evas_list_remove_list(removes, removes); e_object_unref(E_OBJECT(a)); + removes = evas_list_remove_list(removes, removes); } return 1; } diff --git a/src/bin/e_apps.h b/src/bin/e_apps.h index 462c49fa5..f9eee0b81 100644 --- a/src/bin/e_apps.h +++ b/src/bin/e_apps.h @@ -90,6 +90,7 @@ EAPI void e_app_remove(E_App *remove); EAPI void e_app_change_callback_add(void (*func) (void *data, E_App *a, E_App_Change ch), void *data); EAPI void e_app_change_callback_del(void (*func) (void *data, E_App *a, E_App_Change ch), void *data); +EAPI E_App *e_app_launch_id_pid_find(int launch_id, pid_t pid); EAPI E_App *e_app_window_name_class_title_role_find(const char *name, const char *class, const char *title, const char *role); EAPI E_App *e_app_file_find(char *file); diff --git a/src/bin/e_border.c b/src/bin/e_border.c index 22f3e29a4..dd43e3f17 100644 --- a/src/bin/e_border.c +++ b/src/bin/e_border.c @@ -2077,11 +2077,11 @@ Evas_Object * e_border_icon_add(E_Border *bd, Evas *evas) { Evas_Object *o; + E_App *a = NULL; o = NULL; if ((bd->client.icccm.name) && (bd->client.icccm.class)) { - E_App *a; char *title = ""; if (bd->client.netwm.name) title = bd->client.netwm.name; @@ -2090,11 +2090,18 @@ e_border_icon_add(E_Border *bd, Evas *evas) bd->client.icccm.class, title, bd->client.icccm.window_role); - if (a) + } + if (!a) + { + a = e_app_launch_id_pid_find(bd->client.netwm.e_start_launch_id, + bd->client.netwm.pid); + } + if (a) + { + o = edje_object_add(evas); + if (!e_util_edje_icon_list_set(o, a->icon_class)) { - o = edje_object_add(evas); - if (!e_util_edje_icon_list_set(o, a->icon_class)) - edje_object_file_set(o, a->path, "icon"); + edje_object_file_set(o, a->path, "icon"); } } else if (bd->client.netwm.icons) @@ -2792,9 +2799,9 @@ _e_border_cb_window_hide(void *data, int ev_type, void *ev) return 1; } /* Don't delete hidden or iconified windows */ - if ((bd->iconic) || (!bd->visible) || (bd->await_hide_event)) + if ((bd->iconic) || (!bd->visible) || (bd->await_hide_event > 0)) { - if (bd->await_hide_event) + if (bd->await_hide_event > 0) bd->await_hide_event--; /* Only hide the border if it is visible */ if (bd->visible) @@ -4083,17 +4090,38 @@ _e_border_cb_mouse_move(void *data, int type, void *event) if (bd->icon_object) { E_Drag *drag; - Evas_Object *o; + Evas_Object *o = NULL; Evas_Coord x, y, w, h; - const char *file, *part; + const char *file = NULL, *part = NULL; evas_object_geometry_get(bd->icon_object, &x, &y, &w, &h); drag = e_drag_new(bd->zone->container, bd->x + x, bd->y + y, "enlightenment/border", bd, NULL); - o = edje_object_add(drag->evas); edje_object_file_get(bd->icon_object, &file, &part); - edje_object_file_set(o, file, part); + if ((file) && (part)) + { + o = edje_object_add(drag->evas); + edje_object_file_set(o, file, part); + } + else + { + int iw, ih; + void *data; + + data = e_icon_data_get(bd->icon_object, &iw, &ih); + if (data) + { + o = e_icon_add(drag->evas); + e_icon_data_set(o, data, iw, ih); + } + } + if (!o) + { + /* FIXME: fallback icon for drag */ + o = evas_object_rectangle_add(drag->evas); + evas_object_color_set(o, 255, 255, 255, 255); + } e_drag_object_set(drag, o); e_drag_resize(drag, w, h); @@ -4478,37 +4506,6 @@ _e_border_eval(E_Border *bd) bd->client.netwm.update.state = 0; } - if (bd->changes.icon) - { - if (bd->icon_object) - { - evas_object_del(bd->icon_object); - bd->icon_object = NULL; - } - - bd->icon_object = e_border_icon_add(bd, bd->bg_evas); - if (bd->bg_object) - { - evas_object_show(bd->icon_object); - edje_object_part_swallow(bd->bg_object, "icon_swallow", bd->icon_object); - } - else - { - evas_object_hide(bd->icon_object); - } - - { - E_Event_Border_Icon_Change *ev; - - ev = calloc(1, sizeof(E_Event_Border_Icon_Change)); - ev->border = bd; - e_object_ref(E_OBJECT(bd)); -// e_object_breadcrumb_add(E_OBJECT(bd), "border_icon_change_event"); - ecore_event_add(E_EVENT_BORDER_ICON_CHANGE, ev, - _e_border_event_border_icon_change_free, NULL); - } - bd->changes.icon = 0; - } if (bd->changes.shape) { Ecore_X_Rectangle *rects; @@ -5029,7 +5026,7 @@ _e_border_eval(E_Border *bd) e_border_zone_set(bd, zone); } } - + /* effect changes to the window border itself */ if ((bd->changes.shading)) { @@ -5361,6 +5358,38 @@ _e_border_eval(E_Border *bd) } bd->changes.visible = 0; } + + if (bd->changes.icon) + { + if (bd->icon_object) + { + evas_object_del(bd->icon_object); + bd->icon_object = NULL; + } + bd->icon_object = e_border_icon_add(bd, bd->bg_evas); + if (bd->bg_object) + { + evas_object_show(bd->icon_object); + edje_object_part_swallow(bd->bg_object, "icon_swallow", bd->icon_object); + } + else + { + evas_object_hide(bd->icon_object); + } + + { + E_Event_Border_Icon_Change *ev; + + ev = calloc(1, sizeof(E_Event_Border_Icon_Change)); + ev->border = bd; + e_object_ref(E_OBJECT(bd)); +// e_object_breadcrumb_add(E_OBJECT(bd), "border_icon_change_event"); + ecore_event_add(E_EVENT_BORDER_ICON_CHANGE, ev, + _e_border_event_border_icon_change_free, NULL); + } + bd->changes.icon = 0; + } + bd->new_client = 0; bd->changed = 0; diff --git a/src/bin/e_icon.c b/src/bin/e_icon.c index d731c3fbb..079243134 100644 --- a/src/bin/e_icon.c +++ b/src/bin/e_icon.c @@ -140,6 +140,16 @@ e_icon_data_set(Evas_Object *obj, void *data, int w, int h) evas_object_image_data_copy_set(sd->obj, data); } +void * +e_icon_data_get(Evas_Object *obj, int *w, int *h) +{ + E_Smart_Data *sd; + + sd = evas_object_smart_data_get(obj); + evas_object_image_size_get(sd->obj, w, h); + return evas_object_image_data_get(sd->obj, 0); +} + /* local subsystem globals */ static void _e_icon_smart_reconfigure(E_Smart_Data *sd) diff --git a/src/bin/e_icon.h b/src/bin/e_icon.h index c544bc743..64f592450 100644 --- a/src/bin/e_icon.h +++ b/src/bin/e_icon.h @@ -17,6 +17,7 @@ EAPI void e_icon_size_get (Evas_Object *obj, int *w, int *h); EAPI int e_icon_fill_inside_get (Evas_Object *obj); EAPI void e_icon_fill_inside_set (Evas_Object *obj, int fill_inside); EAPI void e_icon_data_set (Evas_Object *obj, void *data, int w, int h); - +EAPI void *e_icon_data_get (Evas_Object *obj, int *w, int *h); + #endif #endif diff --git a/src/modules/ibar/e_mod_main.c b/src/modules/ibar/e_mod_main.c index 00013e57b..151217730 100644 --- a/src/modules/ibar/e_mod_main.c +++ b/src/modules/ibar/e_mod_main.c @@ -795,7 +795,9 @@ _ibar_icon_find(IBar_Bar *ibb, E_App *a) IBar_Icon *ic; ic = l->data; - if (ic->app == a) return ic; + if ((ic->app == a) || (ic->app->orig == a) || + (ic->app == a->orig) || (ic->app->orig == a->orig)) + return ic; } return NULL; }