use startup notify... see ibar in default.

SVN revision: 16708
This commit is contained in:
Carsten Haitzler 2005-09-14 06:39:59 +00:00
parent ce45d0f7c5
commit 07f6885df7
9 changed files with 310 additions and 39 deletions

View File

@ -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;
}
}
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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))

View File

@ -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())
{

View File

@ -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);

View File

@ -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)

View File

@ -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;