From 07f6885df7950cba8322715fa2e3eb60c9c2dc26 Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Wed, 14 Sep 2005 06:39:59 +0000 Subject: [PATCH] use startup notify... see ibar in default. SVN revision: 16708 --- data/themes/default_ibar.edc | 106 ++++++++++++++++++++++---- src/bin/e_apps.c | 138 +++++++++++++++++++++++++++++++--- src/bin/e_apps.h | 15 +++- src/bin/e_border.h | 2 + src/bin/e_hints.c | 18 +++++ src/bin/e_main.c | 14 ++-- src/bin/e_startup.c | 2 +- src/bin/e_zone.c | 6 +- src/modules/ibar/e_mod_main.c | 48 +++++++++++- 9 files changed, 310 insertions(+), 39 deletions(-) diff --git a/data/themes/default_ibar.edc b/data/themes/default_ibar.edc index ca52eae27..719d158d2 100644 --- a/data/themes/default_ibar.edc +++ b/data/themes/default_ibar.edc @@ -269,10 +269,24 @@ group { // item: "item_list" "item item2 item3"; } parts { + part { + name: "item_clip"; + type: RECT; + mouse_events: 0; + description { + state: "default" 0.0; + color: 255 255 255 255; + } + description { + state: "faded" 0.0; + color: 255 255 255 64; + } + } part { name: "item"; type: SWALLOW; mouse_events: 0; + clip_to: "item_clip"; description { state: "default" 0.0; rel1 { @@ -287,6 +301,32 @@ group { } } } + programs { + program { + name: "exec_start"; + signal: "start"; + source: ""; + action: STATE_SET "faded" 0.0; + transition: LINEAR 0.5; + target: "item_clip"; + } + program { + name: "exec_exec"; + signal: "exec"; + source: ""; + action: STATE_SET "faded" 0.0; + transition: LINEAR 0.5; + target: "item_clip"; + after: "exec_stop"; + } + program { + name: "exec_stop"; + signal: "stop"; + source: ""; + action: STATE_SET "default" 0.0; + target: "item_clip"; + } + } } group { @@ -302,11 +342,9 @@ group { description { state: "default" 0.0; rel1 { - relative: 0.0 0.0; offset: 4 4; } rel2 { - relative: 1.0 1.0; offset: -5 -5; } color: 255 255 255 0; @@ -320,13 +358,9 @@ group { state: "default" 0.0; visible: 0; rel1 { - relative: 0.0 0.0; - offset: 0 0; to: "base"; } rel2 { - relative: 1.0 1.0; - offset: -1 -1; to: "base"; } color: 255 255 255 0; @@ -335,13 +369,9 @@ group { state: "visible" 0.0; visible: 1; rel1 { - relative: 0.0 0.0; - offset: 0 0; to: "base"; } rel2 { - relative: 1.0 1.0; - offset: -1 -1; to: "base"; } color: 255 255 255 255; @@ -351,12 +381,23 @@ group { visible: 1; rel1 { relative: -0.5 -0.5; - offset: 0 0; to: "base"; } rel2 { relative: 1.5 1.5; - offset: -1 -1; + to: "base"; + } + color: 255 255 255 0; + } + description { + state: "huge" 0.0; + visible: 1; + rel1 { + relative: -2.0 -2.0; + to: "base"; + } + rel2 { + relative: 3.0 3.0; to: "base"; } color: 255 255 255 0; @@ -370,13 +411,9 @@ group { description { state: "default" 0.0; rel1 { - relative: 0.0 0.0; - offset: 0 0; to: "background"; } rel2 { - relative: 1.0 1.0; - offset: -1 -1; to: "background"; } color: 0 0 0 0; @@ -417,6 +454,43 @@ group { action: STATE_SET "default" 0.0; target: "background"; } + program { + name: "go_big"; + action: STATE_SET "visible" 0.0; + target: "background"; + after: "go_big2"; + } + program { + name: "go_big2"; + action: STATE_SET "huge" 0.0; + transition: LINEAR 0.5; + target: "background"; + } + program { + name: "exec_start"; + signal: "start"; + source: ""; + action: ACTION_STOP; + target: "go_active"; + target: "go_active2"; + target: "go_passive"; + target: "go_passive2"; + target: "go_big"; + target: "go_big2"; + after: "go_big"; + } + program { + name: "exec_exec"; + signal: "exec"; + source: ""; + after: "exec_start"; + } + program { + name: "exec_stop"; + signal: "stop"; + source: ""; +// action: SIGNAL_EMIT "active" 0.0; + } } } diff --git a/src/bin/e_apps.c b/src/bin/e_apps.c index 683990659..45f615629 100644 --- a/src/bin/e_apps.c +++ b/src/bin/e_apps.c @@ -42,6 +42,8 @@ static void _e_app_subdir_rescan (E_App *app); static int _e_app_is_eapp (const char *path); static int _e_app_copy (E_App *dst, E_App *src); static void _e_app_save_order (E_App *app); +static int _e_app_cb_event_border_add(void *data, int type, void *event); +static int _e_app_cb_expire_timer (void *data); /* local subsystem globals */ static Evas_Hash *_e_apps = NULL; @@ -50,10 +52,12 @@ static int _e_apps_callbacks_walking = 0; static int _e_apps_callbacks_delete_me = 0; static Evas_List *_e_apps_change_callbacks = NULL; static Ecore_Event_Handler *_e_apps_exit_handler = NULL; +static Ecore_Event_Handler *_e_apps_border_add_handler = NULL; static Evas_List *_e_apps_repositories = NULL; static E_App *_e_apps_all = NULL; static char *_e_apps_path_all = NULL; static char *_e_apps_path_trash = NULL; +static Evas_List *_e_apps_start_pending = NULL; /* externally accessible functions */ int @@ -70,6 +74,7 @@ e_app_init(void) free(home); _e_apps_repositories = evas_list_append(_e_apps_repositories, strdup(buf)); _e_apps_exit_handler = ecore_event_handler_add(ECORE_EVENT_EXE_EXIT, _e_apps_cb_exit, NULL); + _e_apps_border_add_handler = ecore_event_handler_add(E_EVENT_BORDER_ADD, _e_app_cb_event_border_add, NULL); _e_apps_all = e_app_new(buf, 1); return 1; } @@ -77,6 +82,7 @@ e_app_init(void) int e_app_shutdown(void) { + _e_apps_start_pending = evas_list_free(_e_apps_start_pending); if (_e_apps_all) { e_object_unref(E_OBJECT(_e_apps_all)); @@ -92,6 +98,11 @@ e_app_shutdown(void) ecore_event_handler_del(_e_apps_exit_handler); _e_apps_exit_handler = NULL; } + if (_e_apps_border_add_handler) + { + ecore_event_handler_del(_e_apps_border_add_handler); + _e_apps_border_add_handler = NULL; + } free(_e_apps_path_trash); free(_e_apps_path_all); { @@ -255,9 +266,10 @@ e_app_subdir_scan(E_App *a, int scan_subdirs) } int -e_app_exec(E_App *a) +e_app_exec(E_App *a, int launch_id) { Ecore_Exe *exe; + E_App_Instance *inst; E_OBJECT_CHECK_RETURN(a, 0); E_OBJECT_TYPE_CHECK_RETURN(a, E_APP_TYPE, 0); @@ -275,10 +287,17 @@ e_app_exec(E_App *a) a->exe); return 0; } - a->instances = evas_list_append(a->instances, exe); + 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)); 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; } @@ -672,14 +691,26 @@ e_app_exe_find(char *exe) static void _e_app_free(E_App *a) { + while (evas_list_find(_e_apps_start_pending, a)) + _e_apps_start_pending = evas_list_remove(_e_apps_start_pending, a); if (a->orig) { while (a->instances) { - Ecore_Exe *exe; + E_App_Instance *inst; - exe = a->instances->data; - ecore_exe_free(exe); + 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); a->instances = evas_list_remove_list(a->instances, a->instances); } /* If this is a copy, it shouldn't have any references! */ @@ -695,10 +726,20 @@ _e_app_free(E_App *a) { while (a->instances) { - Ecore_Exe *exe; + E_App_Instance *inst; - exe = a->instances->data; - ecore_exe_free(exe); + 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); a->instances = evas_list_remove_list(a->instances, a->instances); } while (a->subapps) @@ -1024,6 +1065,8 @@ _e_apps_cb_exit(void *data, int type, void *event) 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" @@ -1031,8 +1074,25 @@ _e_apps_cb_exit(void *data, int type, void *event) "%s\n" "\n" "The command was not found\n"), - a->exe); - a->instances = evas_list_remove(a->instances, ev->exe); + 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)); } @@ -1361,3 +1421,61 @@ _e_app_save_order(E_App *app) } fclose(f); } + +static int +_e_app_cb_event_border_add(void *data, int type, void *event) +{ + E_Event_Border_Add *ev; + Evas_List *l, *ll, *removes = NULL; + E_App *a; + E_App_Instance *inst; + + ev = event; + printf("BD ADD %i\n", ev->border->client.netwm.e_start_launch_id); + if (ev->border->client.netwm.e_start_launch_id <= 0) return 1; + for (l = _e_apps_start_pending; l; l = l->next) + { + a = l->data; + for (ll = a->instances; ll; ll = ll->next) + { + inst = ll->data; + printf("%i == %i\n", inst->launch_id, ev->border->client.netwm.e_start_launch_id); + if (inst->launch_id == ev->border->client.netwm.e_start_launch_id) + { + if (inst->expire_timer) + { + ecore_timer_del(inst->expire_timer); + inst->expire_timer = NULL; + } + removes = evas_list_append(removes, a); + e_object_ref(E_OBJECT(a)); + break; + } + } + } + while (removes) + { + a = removes->data; + printf("APP [%s] popped up!\n", a->exe); + _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)); + } + return 1; +} + +static int +_e_app_cb_expire_timer(void *data) +{ + E_App_Instance *inst; + E_App *a; + + inst = data; + a = inst->app; + printf("APP [%s] expired!\n", a->exe); + _e_apps_start_pending = evas_list_remove(_e_apps_start_pending, a); + inst->expire_timer = NULL; + _e_app_change(a, E_APP_READY_EXPIRE); + return 0; +} diff --git a/src/bin/e_apps.h b/src/bin/e_apps.h index 1dcfe16b2..5aadd02f6 100644 --- a/src/bin/e_apps.h +++ b/src/bin/e_apps.h @@ -11,10 +11,12 @@ typedef enum _E_App_Change E_APP_ORDER, E_APP_EXEC, E_APP_READY, - E_APP_EXIT + E_APP_EXIT, + E_APP_READY_EXPIRE } E_App_Change; typedef struct _E_App E_App; +typedef struct _E_App_Instance E_App_Instance; #else #ifndef E_APPS_H @@ -61,13 +63,22 @@ struct _E_App unsigned char deleted : 1; /* this app's file is deleted from disk */ }; +struct _E_App_Instance +{ + E_App *app; + Ecore_Exe *exe; + int launch_id; + double launch_time; + Ecore_Timer *expire_timer; +}; + EAPI int e_app_init(void); EAPI int e_app_shutdown(void); EAPI E_App *e_app_new(const char *path, int scan_subdirs); EAPI int e_app_is_parent(E_App *parent, E_App *app); EAPI void e_app_subdir_scan(E_App *a, int scan_subdirs); -EAPI int e_app_exec(E_App *a); +EAPI int e_app_exec(E_App *a, int launch_id); EAPI int e_app_starting_get(E_App *a); EAPI int e_app_running_get(E_App *a); EAPI void e_app_prepend_relative(E_App *add, E_App *before); diff --git a/src/bin/e_border.h b/src/bin/e_border.h index c7270476b..ffb129e13 100644 --- a/src/bin/e_border.h +++ b/src/bin/e_border.h @@ -243,6 +243,8 @@ struct _E_Border Ecore_X_Window_Type type; + int e_start_launch_id; + struct { unsigned char name : 1; unsigned char icon_name : 1; diff --git a/src/bin/e_hints.c b/src/bin/e_hints.c index 67db5b84a..8799efb23 100644 --- a/src/bin/e_hints.c +++ b/src/bin/e_hints.c @@ -395,6 +395,24 @@ e_hints_window_init(E_Border *bd) } #endif + { + char *str = NULL; + + if ( + (ecore_x_netwm_startup_id_get(bd->client.win, &str) && (str)) || + ((bd->client.icccm.client_leader > 0) && ecore_x_netwm_startup_id_get(bd->client.icccm.client_leader, &str) && (str)) + ) + { + if (!strncmp(str, "E_START|", 8)) + { + int id; + + id = atoi(str + 8); + if (id > 0) bd->client.netwm.e_start_launch_id = id; + } + free(str); + } + } /* It's ok not to have fetch flag, should only be set on startup * and not changed. */ if (!ecore_x_netwm_pid_get(bd->client.win, &bd->client.netwm.pid)) diff --git a/src/bin/e_main.c b/src/bin/e_main.c index 113b5c7dc..984510bc1 100644 --- a/src/bin/e_main.c +++ b/src/bin/e_main.c @@ -424,13 +424,6 @@ main(int argc, char **argv) e_font_apply(); e_canvas_recache(); - /* init app system */ - if (!e_app_init()) - { - e_error_message_show(_("Enlightenment cannot set up its app system.")); - _e_main_shutdown(-1); - } - _e_main_shutdown_push(e_app_shutdown); /* init theme system */ if (!e_theme_init()) { @@ -456,6 +449,13 @@ main(int argc, char **argv) "failed. Perhaps another window manager is running?\n")); _e_main_shutdown(-1); } + /* init app system */ + if (!e_app_init()) + { + e_error_message_show(_("Enlightenment cannot set up its app system.")); + _e_main_shutdown(-1); + } + _e_main_shutdown_push(e_app_shutdown); /* do remember stuff */ if (!e_remember_init()) { diff --git a/src/bin/e_startup.c b/src/bin/e_startup.c index fc573300e..115102d44 100644 --- a/src/bin/e_startup.c +++ b/src/bin/e_startup.c @@ -64,7 +64,7 @@ _e_startup(void) e_init_done(); return; } - e_app_exec(a); + e_app_exec(a, 0); snprintf(buf, sizeof(buf), _("Starting %s"), a->name); e_init_status_set((const char *)buf); e_init_icons_app_add(a); diff --git a/src/bin/e_zone.c b/src/bin/e_zone.c index a99f959f3..dde243ae8 100644 --- a/src/bin/e_zone.c +++ b/src/bin/e_zone.c @@ -585,10 +585,12 @@ e_zone_app_exec(E_Zone *zone, E_App *a) e_util_env_set("LD_PRELOAD_PATH", buf); snprintf(buf, sizeof(buf), "%s/enlightenment/preload/e_hack.so", e_prefix_lib_get()); */ - launch_id++; + snprintf(buf, sizeof(buf), "E_START|%i", launch_id); + e_util_env_set("DESKTOP_STARTUP_ID", buf); if (launch_id == 0) launch_id = 1; /* execute */ - if (!e_app_exec(a)) launch_id = 0; + if (!e_app_exec(a, launch_id)) launch_id = 0; + launch_id++; /* reset env vars */ if (penv_display) diff --git a/src/modules/ibar/e_mod_main.c b/src/modules/ibar/e_mod_main.c index eb65146aa..45fd89dd0 100644 --- a/src/modules/ibar/e_mod_main.c +++ b/src/modules/ibar/e_mod_main.c @@ -406,10 +406,56 @@ _ibar_app_change(void *data, E_App *a, E_App_Change ch) } break; case E_APP_EXEC: + if (e_app_is_parent(ib->apps, a)) + { + IBar_Icon *ic; + + ic = _ibar_icon_find(ibb, a); + if (ic) + { + Evas_List *l; + + if (a->startup_notify) + { + edje_object_signal_emit(ic->icon_object, "start", ""); + for (ll = ic->extra_icons; ll; ll = ll->next) edje_object_signal_emit(ll->data, "start", ""); + edje_object_signal_emit(ic->bg_object, "start", ""); + edje_object_signal_emit(ic->overlay_object, "start", ""); + edje_object_signal_emit(ic->ibb->overlay_object, "start", ""); + } + else + { + edje_object_signal_emit(ic->icon_object, "exec", ""); + for (ll = ic->extra_icons; ll; ll = ll->next) edje_object_signal_emit(ll->data, "exec", ""); + edje_object_signal_emit(ic->bg_object, "exec", ""); + edje_object_signal_emit(ic->overlay_object, "exec", ""); + edje_object_signal_emit(ic->ibb->overlay_object, "exec", ""); + } + } + } break; case E_APP_READY: - break; + case E_APP_READY_EXPIRE: case E_APP_EXIT: + if (e_app_is_parent(ib->apps, a)) + { + if (a->startup_notify) + { + IBar_Icon *ic; + + ic = _ibar_icon_find(ibb, a); + if (ic) + { + Evas_List *l; + + edje_object_signal_emit(ic->icon_object, "stop", ""); + for (ll = ic->extra_icons; ll; ll = ll->next) edje_object_signal_emit(ll->data, "stop", ""); + edje_object_signal_emit(ic->bg_object, "stop", ""); + edje_object_signal_emit(ic->overlay_object, "stop", ""); + edje_object_signal_emit(ic->ibb->overlay_object, "stop", ""); + } + } + } break; default: break;