1
0
mirror of https://github.com/gryf/wmaker.git synced 2025-12-20 04:48:06 +01:00

Added the crash dialog panel

This commit is contained in:
dan
1999-04-16 01:12:45 +00:00
parent e96d9a99ee
commit c98f229d9c
18 changed files with 353 additions and 27 deletions

View File

@@ -20,6 +20,10 @@ Changes since version 0.52.0:
- added ResizebarBack and added appropriate backwards compat. hacks in setstyle
- applied ]d's patch to allow DEMATERIALIZE_ICON over windows
- made clip arrows gradiented
- added a crashing dialog panel to select what to do on crashes.
- fixed the problem with showing a window as focused in the window list menu
while it was on another workspace.
Changes since version 0.51.2:
.............................

16
NEWS
View File

@@ -33,6 +33,22 @@ will automatically hack it so that wmaker will make the theme work like
before.
New crash dialog panel
----------------------
From now on, whenever a fatal situation appears, Window Maker will display a
dialog panel to the user and let him choose what to do.
The options are:
- Abort and leave a core file (usefull for debugging and getting backtraces)
- Restart Window Maker (default behaviour)
- Start alternate window manager (the one defined as fallback, or if not
possible fvwm or twm in this order).
If it will not be able to restart or start the alternate window manager, it
will abort and leave the core file.
--- 0.52.0

View File

@@ -90,7 +90,7 @@ wprefsdir = @wprefsdir@
prefsdatadir = $(pkgdatadir)/Styles
prefsdata_DATA = Autumn.style Black.style BlackTexture.style Blue.style BlueDawn.style BlueishGreen.style Brown.style Chumbo.style Copper.style DarkBlue.style DarkRed.style Fire.style Food.style Golden.style Green.style GreyBlue.style Gtk.style LightBlue.style Pastel.style Purple.style Red.style RednBlue.style Summer.style Traditional.style VioletBlue.style
prefsdata_DATA = Autumn.style Black.style BlackTexture.style Blue.style BlueDawn.style BlueishGreen.style Brown.style Chumbo.style Copper.style DarkBlue.style DarkRed.style Fire.style Food.style Golden.style Green.style GreyBlue.style Gtk.style LightBlue.style Pastel.style Pink.style Pumpkin.style Purple.style Red.style RednBlue.style Summer.style Traditional.style VioletBlue.style
EXTRA_DIST = $(prefsdata_DATA)

2
configure vendored
View File

@@ -751,7 +751,7 @@ fi
PACKAGE=WindowMaker
VERSION=0.53.0
VERSION=0.52.1
if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
{ echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }

View File

@@ -3,6 +3,7 @@
* Window Maker window manager
*
* Copyright (c) 1997, 1998 Alfredo K. Kojima
* Copyright (c) 1998 Dan Pascu
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -1016,7 +1017,8 @@ wIconifyWindow(WWindow *wwin)
tmp = wwin->prev;
while (tmp) {
if (!WFLAGP(tmp, no_focusable)
&& !(tmp->flags.hidden||tmp->flags.miniaturized))
&& !(tmp->flags.hidden||tmp->flags.miniaturized)
&& (wwin->frame->workspace == tmp->frame->workspace))
break;
tmp = tmp->prev;
}

View File

@@ -3,6 +3,7 @@
* Window Maker window manager
*
* Copyright (c) 1997, 1998 Alfredo K. Kojima
* Copyright (c) 1998 Dan Pascu
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@@ -2,6 +2,7 @@
* Window Maker window manager
*
* Copyright (c) 1997, 1998 Alfredo K. Kojima
* Copyright (c) 1998 Dan Pascu
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@@ -3,6 +3,7 @@
* Window Maker window manager
*
* Copyright (c) 1997, 1998 Alfredo K. Kojima
* Copyright (c) 1998 Dan Pascu
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@@ -3,6 +3,7 @@
* Window Maker window manager
*
* Copyright (c) 1997, 1998 Alfredo K. Kojima
* Copyright (c) 1998, 1999 Dan Pascu
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@@ -3,6 +3,7 @@
* Window Maker window manager
*
* Copyright (c) 1997, 1998 Alfredo K. Kojima
* Copyright (c) 1998 Dan Pascu
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@@ -5,7 +5,8 @@
Author: Kresten Krab Thorup
Many modifications by Alfredo K. Kojima
Some fixes and additions by Dan Pascu
This file is part of GNU CC.

View File

@@ -58,6 +58,9 @@
Display *dpy;
char **Arguments;
int ArgCount;
char *ProgName;
unsigned int ValidModMask = 0xff;
@@ -148,8 +151,6 @@ int wVisualID = -1;
/******** End Global Variables *****/
static char *DisplayName = NULL;
static char **Arguments;
static int ArgCount;
extern void EventLoop();
extern void StartUp();
@@ -267,6 +268,9 @@ print_help()
*/
puts(_(" --visual-id visualid visual id of visual to use"));
puts(_(" --static do not update or save configurations"));
#ifdef DEBUG
puts(_(" --synchronous turn on synchronous display mode"));
#endif
puts(_(" --version print version and exit"));
puts(_(" --help show this message"));
}
@@ -342,6 +346,9 @@ main(int argc, char **argv)
Bool multiHead = True;
char *str;
int d, s;
#ifdef DEBUG
Bool doSync = False;
#endif
wsetabort(wAbort);
@@ -383,6 +390,10 @@ main(int argc, char **argv)
} else if (strcmp(argv[i], "--global_defaults_path")==0) {
puts(SYSCONFDIR);
exit(0);
#ifdef DEBUG
} else if (strcmp(argv[i], "--synchronous")==0) {
doSync = 1;
#endif
} else if (strcmp(argv[i], "-locale")==0
|| strcmp(argv[i], "--locale")==0) {
i++;
@@ -515,7 +526,8 @@ main(int argc, char **argv)
putenv(str);
#ifdef DEBUG
XSynchronize(dpy, True);
if (doSync)
XSynchronize(dpy, True);
#endif
wXModifierInitialize();

View File

@@ -3,6 +3,7 @@
* Window Maker window manager
*
* Copyright (c) 1997, 1998 Alfredo K. Kojima
* Copyright (c) 1997, 1998 Dan Pascu
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@@ -3,6 +3,7 @@
* Window Maker window manager
*
* Copyright (c) 1997, 1998 Alfredo K. Kojima
* Copyright (c) 1998 Dan Pascu
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@@ -2,6 +2,7 @@
* Window Maker window manager
*
* Copyright (c) 1997, 1998 Alfredo K. Kojima
* Copyright (c) 1998 Dan Pascu
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@@ -2,6 +2,7 @@
* Window Maker window manager
*
* Copyright (c) 1997, 1998 Alfredo K. Kojima
* Copyright (c) 1999 Dan Pascu
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -76,6 +77,8 @@ extern const char * const sys_siglist[];
/****** Global Variables ******/
extern char **Arguments;
extern WPreferences wPreferences;
extern WDDomain *WDWindowMaker;
@@ -154,6 +157,256 @@ static void manageAllWindows();
extern void NotifyDeadProcess(pid_t pid, unsigned char status);
typedef struct _CrashPanel {
WMWindow *win; /* main window */
WMLabel *iconL; /* application icon */
WMLabel *nameL; /* title of panel */
WMFrame *sepF; /* separator frame */
WMLabel *noteL; /* Title of note */
WMLabel *note2L; /* body of note with what happened */
WMFrame *whatF; /* "what to do next" frame */
WMPopUpButton *whatP; /* action selection popup button */
WMButton *okB; /* ok button */
Bool done; /* if finished with this dialog */
int action; /* what to do after */
KeyCode retKey;
} CrashPanel;
enum {
WMAbort=0,
WMRestart,
WMStartAlternate
};
static void
handleKeyPress(XEvent *event, void *clientData)
{
CrashPanel *panel = (CrashPanel*)clientData;
if (event->xkey.keycode == panel->retKey) {
WMPerformButtonClick(panel->okB);
}
}
static void
buttonCallback(void *self, void *clientData)
{
CrashPanel *panel = (CrashPanel*)clientData;
panel->done = True;
}
static void
setAction(void *self, void *clientData)
{
WMPopUpButton *pop = (WMPopUpButton*)self;
CrashPanel *panel = (CrashPanel*)clientData;
panel->action = WMGetPopUpButtonSelectedItem(pop);
}
static WMPixmap*
getWindowMakerIconImage(WMScreen *scr)
{
proplist_t dict, key, option, value=NULL;
WMPixmap *pix=NULL;
char *path;
PLSetStringCmpHook(NULL);
key = PLMakeString("Logo.WMPanel");
option = PLMakeString("Icon");
dict = PLGetDictionaryEntry(WDWindowAttributes->dictionary, key);
if (dict) {
value = PLGetDictionaryEntry(dict, option);
}
PLRelease(key);
PLRelease(option);
PLSetStringCmpHook(StringCompareHook);
if (value && PLIsString(value)) {
path = FindImage(wPreferences.icon_path, PLGetString(value));
if (path) {
RImage *image;
image = RLoadImage(WMScreenRContext(scr), path, 0);
if (image) {
pix = WMCreatePixmapFromRImage(scr, image, 0);
RDestroyImage(image);
}
free(path);
}
}
return pix;
}
#define PWIDTH 295
#define PHEIGHT 345
static int
showCrashPanel(int whatSig)
{
CrashPanel *panel;
WMScreen *scr;
WMFont *font;
WMPixmap *logo;
Display *newdpy;
int screen_no, scr_width, scr_height;
int action;
char buf[256];
panel = wmalloc(sizeof(CrashPanel));
memset(panel, 0, sizeof(CrashPanel));
/* Close the X connection and open a new one. This is to avoid messing
* Xlib because we call to Xlib functions in a signal handler.
*/
XCloseDisplay(dpy);
newdpy = XOpenDisplay("");
if (!newdpy) {
wfatal(_("cannot open connection for crashing dialog panel. Aborting."));
return WMAbort;
}
screen_no = DefaultScreen(newdpy);
scr_width = WidthOfScreen(ScreenOfDisplay(newdpy, screen_no));
scr_height = HeightOfScreen(ScreenOfDisplay(newdpy, screen_no));
scr = WMCreateScreen(newdpy, screen_no);
if (!scr) {
wfatal(_("cannot open connection for crashing dialog panel. Aborting."));
return WMAbort;
}
panel->retKey = XKeysymToKeycode(newdpy, XK_Return);
panel->win = WMCreateWindow(scr, "crashingDialog");
WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
WMMoveWidget(panel->win, (scr_width - PWIDTH)/2, (scr_height - PHEIGHT)/2);
logo = getWindowMakerIconImage(scr);
if (logo) {
panel->iconL = WMCreateLabel(panel->win);
WMResizeWidget(panel->iconL, 64, 64);
WMMoveWidget(panel->iconL, 10, 10);
WMSetLabelImagePosition(panel->iconL, WIPImageOnly);
WMSetLabelImage(panel->iconL, logo);
}
panel->nameL = WMCreateLabel(panel->win);
WMResizeWidget(panel->nameL, 190, 18);
WMMoveWidget(panel->nameL, 80, 35);
WMSetLabelTextAlignment(panel->nameL, WALeft);
font = WMBoldSystemFontOfSize(scr, 18);
WMSetLabelFont(panel->nameL, font);
WMReleaseFont(font);
WMSetLabelText(panel->nameL, _("Fatal error"));
panel->sepF = WMCreateFrame(panel->win);
WMResizeWidget(panel->sepF, PWIDTH+4, 2);
WMMoveWidget(panel->sepF, -2, 80);
panel->noteL = WMCreateLabel(panel->win);
WMResizeWidget(panel->noteL, PWIDTH-20, 40);
WMMoveWidget(panel->noteL, 10, 90);
WMSetLabelTextAlignment(panel->noteL, WAJustified);
#ifdef SYS_SIGLIST_DECLARED
sprintf(buf, _("Window Maker received signal %i\n(%s)."),
whatSig, sys_siglist[whatSig]);
#else
sprintf(buf, _("Window Maker received signal %i."), whatSig);
#endif
WMSetLabelText(panel->noteL, buf);
panel->note2L = WMCreateLabel(panel->win);
WMResizeWidget(panel->note2L, PWIDTH-20, 100);
WMMoveWidget(panel->note2L, 10, 130);
WMSetLabelTextAlignment(panel->note2L, WALeft);
WMSetLabelText(panel->note2L,
_(" This fatal error occured probably due to a bug."
" Please fill the included BUGFORM and "
"report it to bugs@windowmaker.org."));
panel->whatF = WMCreateFrame(panel->win);
WMResizeWidget(panel->whatF, PWIDTH-20, 50);
WMMoveWidget(panel->whatF, 10, 240);
WMSetFrameTitle(panel->whatF, _("What do you want to do now?"));
panel->whatP = WMCreatePopUpButton(panel->whatF);
WMResizeWidget(panel->whatP, PWIDTH-20-70, 20);
WMMoveWidget(panel->whatP, 35, 20);
WMSetPopUpButtonPullsDown(panel->whatP, False);
WMSetPopUpButtonText(panel->whatP, _("Select action"));
WMAddPopUpButtonItem(panel->whatP, _("Abort and leave a core file"));
WMAddPopUpButtonItem(panel->whatP, _("Restart Window Maker"));
WMAddPopUpButtonItem(panel->whatP, _("Start alternate window manager"));
WMSetPopUpButtonAction(panel->whatP, setAction, panel);
WMSetPopUpButtonSelectedItem(panel->whatP, WMRestart);
panel->action = WMRestart;
WMMapSubwidgets(panel->whatF);
panel->okB = WMCreateCommandButton(panel->win);
WMResizeWidget(panel->okB, 80, 26);
WMMoveWidget(panel->okB, 205, 309);
WMSetButtonText(panel->okB, _("OK"));
WMSetButtonImage(panel->okB, WMGetSystemPixmap(scr, WSIReturnArrow));
WMSetButtonAltImage(panel->okB, WMGetSystemPixmap(scr, WSIHighlightedReturnArrow));
WMSetButtonImagePosition(panel->okB, WIPRight);
WMSetButtonAction(panel->okB, buttonCallback, panel);
panel->done = 0;
WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask,
handleKeyPress, panel);
WMRealizeWidget(panel->win);
WMMapSubwidgets(panel->win);
WMMapWidget(panel->win);
XSetInputFocus(newdpy, WMWidgetXID(panel->win), RevertToParent, CurrentTime);
while (!panel->done) {
XEvent event;
WMNextEvent(newdpy, &event);
WMHandleEvent(&event);
}
action = panel->action;
WMUnmapWidget(panel->win);
WMDestroyWidget(panel->win);
free(panel);
XCloseDisplay(newdpy);
return action;
}
static int
catchXError(Display *dpy, XErrorEvent *error)
{
@@ -241,6 +494,7 @@ handleSig(int sig)
static int already_crashed = 0;
int dumpcore = 0;
#ifndef NO_EMERGENCY_AUTORESTART
int crashAction;
char *argv[2];
argv[1] = NULL;
@@ -259,7 +513,6 @@ handleSig(int sig)
#endif
WCHANGE_STATE(WSTATE_NEED_RESTART);
/* setup idle handler, so that this will be handled when
* the select() is returned becaused of the signal, even if
* there are no X events in the queue */
@@ -290,31 +543,41 @@ handleSig(int sig)
wfatal(_("got signal %i\n"), sig);
#endif
/* Setting the signal behaviour back to default and then reraising the
* signal is a cleaner way to make program exit and core dump than calling
* abort(), since it correctly returns from the signal handler and sets
* the flags accordingly. -Dan
*/
if (sig==SIGSEGV || sig==SIGFPE || sig==SIGBUS || sig==SIGILL
|| sig==SIGABRT) {
if (already_crashed) {
wfatal(_("crashed while trying to do some post-crash cleanup. Aborting immediatelly."));
#ifndef NO_EMERGENCY_AUTORESTART
exit(1);
#else
abort();
#endif
signal(sig, SIG_DFL);
raise(sig);
return;
}
already_crashed = 1;
dumpcore = 1;
wfatal(_("a fatal error has occured, probably due to a bug. "
"Please fill the included BUGFORM and report it."));
#ifndef NO_EMERGENCY_AUTORESTART
/* restart another window manager so that the X session doesn't
* go to space */
crashAction = showCrashPanel(sig);
wwarning(_("trying to start alternative window manager..."));
if (dpy)
XCloseDisplay(dpy);
dpy = NULL;
if (crashAction == WMAbort) {
signal(sig, SIG_DFL);
raise(sig);
return;
}
if (crashAction == WMRestart) {
/* we try to restart Window Maker */
wwarning(_("trying to restart Window Maker..."));
execvp(Arguments[0], Arguments);
wwarning(_("we failed to restart Window Maker."));
/* fallback to alternate window manager then */
}
wwarning(_("trying to start alternate window manager..."));
argv[0] = FALLBACK_WINDOWMANAGER;
execvp(FALLBACK_WINDOWMANAGER, argv);
@@ -323,8 +586,18 @@ handleSig(int sig)
execvp("fvwm", argv);
argv[0] = "twm";
execvp("twm", argv);
execvp("twm", argv);
wfatal(_("failed to start alternate window manager. Aborting."));
#else
wfatal(_("a fatal error has occured, probably due to a bug. "
"Please fill the included BUGFORM and report it."));
#endif /* !NO_EMERGENCY_AUTORESTART */
signal(sig, SIG_DFL);
raise(sig);
return;
}
wAbort(dumpcore);
@@ -702,9 +975,7 @@ StartUp(Bool defaultScreenOnly)
sigaction(SIGSEGV, &sig_action, NULL);
sigaction(SIGBUS, &sig_action, NULL);
sigaction(SIGFPE, &sig_action, NULL);
#ifndef NO_EMERGENCY_AUTORESTART
sigaction(SIGABRT, &sig_action, NULL);
#endif
/* Here we set SA_RESTART for safety, because SIGUSR1 may not be handled
* immediately.
@@ -722,6 +993,17 @@ StartUp(Bool defaultScreenOnly)
sig_action.sa_flags = SA_NOCLDSTOP|SA_RESTART;
sigaction(SIGCHLD, &sig_action, NULL);
/* Now we unblock all signals, that may have been blocked by the parent
* who exec()-ed us. This can happen for example if Window Maker crashes
* and restarts itself or another window manager from the signal handler.
* In this case, the new proccess inherits the blocked signal mask and
* will no longer react to that signal, until unblocked.
* This is because the signal handler of the proccess who crashed (parent)
* didn't return, and the signal remained blocked. -Dan
*/
sigfillset(&sig_action.sa_mask);
sigprocmask(SIG_UNBLOCK, &sig_action.sa_mask, NULL);
/* handle X shutdowns a such */
XSetIOErrorHandler(handleXIO);
@@ -761,7 +1043,6 @@ StartUp(Bool defaultScreenOnly)
XSetErrorHandler((XErrorHandler)catchXError);
/* Sound init */
#ifdef SHAPE
/* ignore j */
wShapeSupported = XShapeQueryExtension(dpy, &wShapeEventBase, &j);
@@ -781,7 +1062,7 @@ StartUp(Bool defaultScreenOnly)
if (defaultScreenOnly || max==1) {
wScreen[wScreenCount] = wScreenInit(DefaultScreen(dpy));
if (!wScreen[wScreenCount]) {
wfatal(_("it seems that there already is a window manager running"));
wfatal(_("it seems that there is already a window manager running"));
Exit(1);
}
} else {

View File

@@ -2,6 +2,7 @@
* Window Maker window manager
*
* Copyright (c) 1997, 1998 Alfredo K. Kojima
* Copyright (c) 1997, 1998 Dan Pascu
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@@ -3,6 +3,7 @@
* Window Maker window manager
*
* Copyright (c) 1997, 1998 Alfredo K. Kojima
* Copyright (c) 1998 Dan Pascu
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by