forked from enlightenment/enlightenment
Exe error dialog. Still needs some work, but it's good enough for testing
by the wider community. Currently only e_app started exe's get this. SVN revision: 19948
This commit is contained in:
parent
70c0aa895b
commit
4b77796724
|
@ -208,6 +208,7 @@ e_widget_table.c \
|
||||||
e_widget_entry.c \
|
e_widget_entry.c \
|
||||||
e_widget_image.c \
|
e_widget_image.c \
|
||||||
e_config_dialog.c \
|
e_config_dialog.c \
|
||||||
|
e_apps_error.c \
|
||||||
e_int_config_focus.c \
|
e_int_config_focus.c \
|
||||||
e_icon_grid.c \
|
e_icon_grid.c \
|
||||||
e_icon_canvas.c \
|
e_icon_canvas.c \
|
||||||
|
|
|
@ -13,6 +13,9 @@
|
||||||
* - clean up the add app functions. To much similar code.
|
* - clean up the add app functions. To much similar code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
extern void _e_app_error_dialog(E_Container *con, E_App_Autopsy *app);
|
||||||
|
|
||||||
|
|
||||||
/* local subsystem functions */
|
/* local subsystem functions */
|
||||||
typedef struct _E_App_Change_Info E_App_Change_Info;
|
typedef struct _E_App_Change_Info E_App_Change_Info;
|
||||||
typedef struct _E_App_Callback E_App_Callback;
|
typedef struct _E_App_Callback E_App_Callback;
|
||||||
|
@ -417,7 +420,8 @@ e_app_exec(E_App *a, int launch_id)
|
||||||
* the eapp file */
|
* the eapp file */
|
||||||
inst = E_NEW(E_App_Instance, 1);
|
inst = E_NEW(E_App_Instance, 1);
|
||||||
if (!inst) return 0;
|
if (!inst) return 0;
|
||||||
exe = ecore_exe_run(a->exe, inst);
|
/* We want the stdout and stderr as lines for the error dialog if it exits abnormally. */
|
||||||
|
exe = ecore_exe_pipe_run(a->exe, ECORE_EXE_PIPE_AUTO| ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_ERROR | ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_PIPE_ERROR_LINE_BUFFERED, inst);
|
||||||
if (!exe)
|
if (!exe)
|
||||||
{
|
{
|
||||||
free(inst);
|
free(inst);
|
||||||
|
@ -429,6 +433,8 @@ e_app_exec(E_App *a, int launch_id)
|
||||||
a->exe);
|
a->exe);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
/* 20 lines at start and end, 20x100 limit on bytes at each end. */
|
||||||
|
ecore_exe_auto_limits_set(exe, 2000, 2000, 20, 20);
|
||||||
ecore_exe_tag_set(exe, "E/app");
|
ecore_exe_tag_set(exe, "E/app");
|
||||||
inst->app = a;
|
inst->app = a;
|
||||||
inst->exe = exe;
|
inst->exe = exe;
|
||||||
|
@ -1854,13 +1860,25 @@ _e_apps_cb_exit(void *data, int type, void *event)
|
||||||
a = ai->app;
|
a = ai->app;
|
||||||
if (!a) return 1;
|
if (!a) return 1;
|
||||||
|
|
||||||
/* FIXME: maybe we could capture stdout/stderr and display it here? */
|
if ( (ev->exited) && (ev->exit_code == 127) ) /* /bin/sh uses this if cmd not found */
|
||||||
if (ev->exit_code == 127) /* /bin/sh uses this if cmd not found */
|
{
|
||||||
e_error_dialog_show(_("Run Error"),
|
e_error_dialog_show(_("Run Error"),
|
||||||
_("Enlightenment was unable to run the program:\n"
|
_("Enlightenment was unable to run the program:\n"
|
||||||
"\n"
|
"\n"
|
||||||
"%s\n"),
|
"%s\n"),
|
||||||
a->exe);
|
a->exe);
|
||||||
|
}
|
||||||
|
else if ( ! ((ev->exited) && (ev->exit_code == EXIT_SUCCESS)) ) /* Let's hope that everyhing returns this properly. */
|
||||||
|
{ /* Show the error dialog with details from the exe. */
|
||||||
|
E_App_Autopsy *aut;
|
||||||
|
|
||||||
|
aut = E_NEW(E_App_Autopsy, 1);
|
||||||
|
aut->app = a;
|
||||||
|
aut->del = *ev;
|
||||||
|
aut->read = ecore_exe_event_data_get(ai->exe, ECORE_FD_READ);
|
||||||
|
aut->error = ecore_exe_event_data_get(ai->exe, ECORE_FD_ERROR);
|
||||||
|
_e_app_error_dialog(NULL, aut);
|
||||||
|
}
|
||||||
if (ai->expire_timer) ecore_timer_del(ai->expire_timer);
|
if (ai->expire_timer) ecore_timer_del(ai->expire_timer);
|
||||||
free(ai);
|
free(ai);
|
||||||
a->instances = evas_list_remove(a->instances, ai);
|
a->instances = evas_list_remove(a->instances, ai);
|
||||||
|
|
|
@ -17,6 +17,7 @@ typedef enum _E_App_Change
|
||||||
|
|
||||||
typedef struct _E_App E_App;
|
typedef struct _E_App E_App;
|
||||||
typedef struct _E_App_Instance E_App_Instance;
|
typedef struct _E_App_Instance E_App_Instance;
|
||||||
|
typedef struct _E_App_Autopsy E_App_Autopsy;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#ifndef E_APPS_H
|
#ifndef E_APPS_H
|
||||||
|
@ -76,6 +77,15 @@ struct _E_App_Instance
|
||||||
Ecore_Timer *expire_timer;
|
Ecore_Timer *expire_timer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct _E_App_Autopsy
|
||||||
|
{
|
||||||
|
E_App *app;
|
||||||
|
|
||||||
|
Ecore_Exe_Event_Del del;
|
||||||
|
E_Config_Dialog *error_dialog;
|
||||||
|
Ecore_Exe_Event_Data *error, *read;
|
||||||
|
};
|
||||||
|
|
||||||
EAPI int e_app_init (void);
|
EAPI int e_app_init (void);
|
||||||
EAPI int e_app_shutdown (void);
|
EAPI int e_app_shutdown (void);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,259 @@
|
||||||
|
/*
|
||||||
|
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
|
||||||
|
*/
|
||||||
|
#include "e.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct _E_Config_Dialog_Data
|
||||||
|
{
|
||||||
|
char *label;
|
||||||
|
char *exit;
|
||||||
|
char *signal;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Protos */
|
||||||
|
static void * _e_app_error_dialog_create_data(E_Config_Dialog *cfd);
|
||||||
|
static void _e_app_error_dialog_free_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
|
||||||
|
static Evas_Object *_e_app_error_dialog_basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata);
|
||||||
|
static Evas_Object *_e_app_error_dialog_advanced_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata);
|
||||||
|
|
||||||
|
void
|
||||||
|
_e_app_error_dialog(E_Container *con, E_App_Autopsy *app)
|
||||||
|
{
|
||||||
|
E_Config_Dialog *cfd;
|
||||||
|
E_Config_Dialog_View v;
|
||||||
|
|
||||||
|
/* Dialog Methods */
|
||||||
|
v.create_cfdata = _e_app_error_dialog_create_data;
|
||||||
|
v.free_cfdata = _e_app_error_dialog_free_data;
|
||||||
|
v.basic.apply_cfdata = NULL;
|
||||||
|
v.basic.create_widgets = _e_app_error_dialog_basic_create_widgets;
|
||||||
|
v.advanced.apply_cfdata = NULL;
|
||||||
|
v.advanced.create_widgets = _e_app_error_dialog_advanced_create_widgets;
|
||||||
|
|
||||||
|
/* Create The Dialog */
|
||||||
|
cfd = e_config_dialog_new(con, _("Run error"), NULL, 0, &v, app);
|
||||||
|
app->error_dialog = cfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_e_app_error_dialog_fill_data(E_App_Autopsy *app, E_Config_Dialog_Data *cfdata)
|
||||||
|
{
|
||||||
|
int length;
|
||||||
|
|
||||||
|
length = strlen(app->app->name);
|
||||||
|
if (!cfdata->label)
|
||||||
|
{
|
||||||
|
cfdata->label = malloc((length + 20) * sizeof(char));
|
||||||
|
if (cfdata->label)
|
||||||
|
sprintf(cfdata->label, "%s may have crashed.", app->app->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
length = strlen(app->app->exe);
|
||||||
|
if ((app->del.exited) && (!cfdata->exit))
|
||||||
|
{
|
||||||
|
cfdata->exit = malloc((length + 64) * sizeof(char));
|
||||||
|
if (cfdata->exit)
|
||||||
|
sprintf(cfdata->exit, "An exit code of %i was return from %s", app->del.exit_code, app->app->exe);
|
||||||
|
}
|
||||||
|
if ((app->del.signalled) && (!cfdata->signal))
|
||||||
|
{
|
||||||
|
cfdata->signal = malloc((length + 64) * sizeof(char));
|
||||||
|
if (cfdata->signal)
|
||||||
|
sprintf(cfdata->signal, "%s was interupted by signal %i", app->app->exe, app->del.exit_signal); /* FIXME: add a description of the signal. */
|
||||||
|
/* FIXME: Add sigchld_info stuff
|
||||||
|
* app->del.data
|
||||||
|
* siginfo_t
|
||||||
|
* {
|
||||||
|
* int si_signo; Signal number
|
||||||
|
* int si_errno; An errno value
|
||||||
|
* int si_code; Signal code
|
||||||
|
* pid_t si_pid; Sending process ID
|
||||||
|
* uid_t si_uid; Real user ID of sending process
|
||||||
|
* int si_status; Exit value or signal
|
||||||
|
* clock_t si_utime; User time consumed
|
||||||
|
* clock_t si_stime; System time consumed
|
||||||
|
* sigval_t si_value; Signal value
|
||||||
|
* int si_int; POSIX.1b signal
|
||||||
|
* void * si_ptr; POSIX.1b signal
|
||||||
|
* void * si_addr; Memory location which caused fault
|
||||||
|
* int si_band; Band event
|
||||||
|
* int si_fd; File descriptor
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
_e_app_error_dialog_create_data(E_Config_Dialog *cfd)
|
||||||
|
{
|
||||||
|
E_Config_Dialog_Data *cfdata;
|
||||||
|
E_App_Autopsy *app;
|
||||||
|
|
||||||
|
app = cfd->data;
|
||||||
|
cfdata = E_NEW(E_Config_Dialog_Data, 1);
|
||||||
|
_e_app_error_dialog_fill_data(app, cfdata);
|
||||||
|
return cfdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_e_app_error_dialog_free_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
|
||||||
|
{
|
||||||
|
E_App_Autopsy *app;
|
||||||
|
|
||||||
|
app = cfd->data;
|
||||||
|
|
||||||
|
if(app)
|
||||||
|
{
|
||||||
|
app->error_dialog = NULL;
|
||||||
|
if (app->error)
|
||||||
|
ecore_exe_event_data_free(app->error);
|
||||||
|
if (app->read)
|
||||||
|
ecore_exe_event_data_free(app->read);
|
||||||
|
free(app);
|
||||||
|
}
|
||||||
|
if (cfdata->label)
|
||||||
|
free(cfdata->signal);
|
||||||
|
if (cfdata->label)
|
||||||
|
free(cfdata->exit);
|
||||||
|
if (cfdata->label)
|
||||||
|
free(cfdata->label);
|
||||||
|
|
||||||
|
free(cfdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_e_app_error_dialog_resize(void *data, Evas *e, Evas_Object *obj, void *event_info)
|
||||||
|
{
|
||||||
|
Evas_Coord mw, mh, vw, vh, w, h;
|
||||||
|
|
||||||
|
e_scrollframe_child_viewport_size_get(obj, &vw, &vh);
|
||||||
|
e_widget_min_size_get(data, &mw, &mh);
|
||||||
|
evas_object_geometry_get(data, NULL, NULL, &w, &h);
|
||||||
|
if (vw >= mw)
|
||||||
|
{
|
||||||
|
if (w != vw) evas_object_resize(data, vw, h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Evas_Object *
|
||||||
|
_e_app_error_dialog_scrolltext_create(Evas *evas, char *title, Ecore_Exe_Event_Data_Line *lines)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
Evas_Object *obj, *os;
|
||||||
|
|
||||||
|
os = e_widget_framelist_add(evas, _(title), 0);
|
||||||
|
|
||||||
|
obj = e_widget_ilist_add(evas, 0, 0, NULL);
|
||||||
|
|
||||||
|
for (i = 0; lines[i].line != NULL; i++)
|
||||||
|
e_widget_ilist_append(obj, NULL, lines[i].line, NULL, NULL, NULL);
|
||||||
|
e_widget_min_size_set(obj, 100, 100);
|
||||||
|
|
||||||
|
e_widget_framelist_object_append(os, obj);
|
||||||
|
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Evas_Object *
|
||||||
|
_e_app_error_dialog_basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata)
|
||||||
|
{
|
||||||
|
int error_length = 0;
|
||||||
|
Evas_Object *o, *o2, *of, *ob, *os;
|
||||||
|
E_App_Autopsy *app;
|
||||||
|
|
||||||
|
app = cfd->data;
|
||||||
|
_e_app_error_dialog_fill_data(app, cfdata);
|
||||||
|
|
||||||
|
o = e_widget_list_add(evas, 0, 0);
|
||||||
|
|
||||||
|
ob = e_widget_label_add(evas, cfdata->label);
|
||||||
|
e_widget_list_object_append(o, ob, 1, 1, 0.5);
|
||||||
|
|
||||||
|
if (app->error)
|
||||||
|
error_length = app->error->size;
|
||||||
|
if (error_length)
|
||||||
|
{
|
||||||
|
os = _e_app_error_dialog_scrolltext_create(evas, "Error", app->error->lines);
|
||||||
|
e_widget_list_object_append(o, os, 1, 1, 0.5);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ob = e_widget_label_add(evas, _("There was no error message."));
|
||||||
|
e_widget_list_object_append(o, ob, 1, 1, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Evas_Object *
|
||||||
|
_e_app_error_dialog_advanced_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata)
|
||||||
|
{
|
||||||
|
int read_length = 0;
|
||||||
|
int error_length = 0;
|
||||||
|
Evas_Object *o, *of, *ob, *ot, *os;
|
||||||
|
E_App_Autopsy *app;
|
||||||
|
|
||||||
|
app = cfd->data;
|
||||||
|
_e_app_error_dialog_fill_data(app, cfdata);
|
||||||
|
|
||||||
|
o = e_widget_list_add(evas, 0, 0);
|
||||||
|
ot = e_widget_table_add(evas, 0);
|
||||||
|
|
||||||
|
ob = e_widget_label_add(evas, cfdata->label);
|
||||||
|
e_widget_list_object_append(o, ob, 1, 1, 0.5);
|
||||||
|
|
||||||
|
if (cfdata->exit)
|
||||||
|
{
|
||||||
|
of = e_widget_framelist_add(evas, _("Exit code"), 0);
|
||||||
|
ob = e_widget_label_add(evas, _(cfdata->exit));
|
||||||
|
e_widget_framelist_object_append(of, ob);
|
||||||
|
e_widget_list_object_append(o, of, 1, 1, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfdata->signal)
|
||||||
|
{
|
||||||
|
of = e_widget_framelist_add(evas, _("Signal"), 0);
|
||||||
|
ob = e_widget_label_add(evas, _(cfdata->signal));
|
||||||
|
e_widget_framelist_object_append(of, ob);
|
||||||
|
e_widget_list_object_append(o, of, 1, 1, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (app->read)
|
||||||
|
read_length = app->read->size;
|
||||||
|
|
||||||
|
if (read_length)
|
||||||
|
{
|
||||||
|
of = _e_app_error_dialog_scrolltext_create(evas, "Output", app->read->lines);
|
||||||
|
/* FIXME: Add stdout "start". */
|
||||||
|
/* FIXME: Add stdout "end". */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
of = e_widget_framelist_add(evas, _("Output"), 0);
|
||||||
|
ob = e_widget_label_add(evas, _("There was no output."));
|
||||||
|
e_widget_framelist_object_append(of, ob);
|
||||||
|
}
|
||||||
|
e_widget_table_object_append(ot, of, 0, 0, 1, 1, 1, 1, 1, 1);
|
||||||
|
|
||||||
|
if (app->error)
|
||||||
|
error_length = app->error->size;
|
||||||
|
if (error_length)
|
||||||
|
{
|
||||||
|
of = _e_app_error_dialog_scrolltext_create(evas, "Error", app->error->lines);
|
||||||
|
/* FIXME: Add stderr "start". */
|
||||||
|
/* FIXME: Add stderr "end". */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
of = e_widget_framelist_add(evas, _("Error"), 0);
|
||||||
|
ob = e_widget_label_add(evas, _("There was no error message."));
|
||||||
|
e_widget_framelist_object_append(of, ob);
|
||||||
|
}
|
||||||
|
e_widget_table_object_append(ot, of, 1, 0, 1, 1, 1, 1, 1, 1);
|
||||||
|
|
||||||
|
e_widget_list_object_append(o, ot, 1, 1, 0.5);
|
||||||
|
|
||||||
|
return o;
|
||||||
|
}
|
Loading…
Reference in New Issue