mirror of
https://github.com/gryf/wmaker.git
synced 2025-12-19 12:28:22 +01:00
- Removed legacy OFFIX_DND support code
- Fixed the signal handler for crashes (ie, removed it) and made wmaker restarting be made automatically by a monitoring process. - Made NetWM support be enabled by default - Removed old code to store/restore workspace state (now relies on netwm)
This commit is contained in:
@@ -152,7 +152,11 @@ Changes since version 0.80.2:
|
||||
has. (This also is to fix problems with KDE 3.3.0 apps, but not only them).
|
||||
- Fixed bug with autostart and exit scripts not being executed if user
|
||||
GNUstep path was different from ~/GNUstep (when setting GNUSTEP_USER_ROOT)
|
||||
|
||||
- Removed legacy OFFIX_DND support code
|
||||
- Fixed the signal handler for crashes (ie, removed it) and made wmaker
|
||||
restarting be made automatically by a monitoring process.
|
||||
- Made NetWM support be enabled by default
|
||||
- Removed old code to store/restore workspace state (now relies on netwm)
|
||||
|
||||
Changes since version 0.80.1:
|
||||
.............................
|
||||
|
||||
18
configure.ac
18
configure.ac
@@ -412,14 +412,6 @@ AC_ARG_ENABLE(openlook,
|
||||
fi])
|
||||
|
||||
|
||||
AC_ARG_ENABLE(netwm,
|
||||
[ --enable-netwm enable support for FreeDesktop hints ],
|
||||
[if test x$enableval = xyes; then
|
||||
AC_DEFINE(NETWM_HINTS, 1, [define if you want NETWM hints support])
|
||||
netwm_on=yes
|
||||
fi])
|
||||
|
||||
|
||||
AC_ARG_ENABLE(vdesktop,
|
||||
[ --enable-vdesktop enable virtual desktop],
|
||||
[if test x$enableval = xyes; then
|
||||
@@ -1137,15 +1129,11 @@ if test "$openlook_on" = "yes"; then
|
||||
extrasupport="OpenLook $extrasupport"
|
||||
fi
|
||||
if test "$gnome_on" = "yes"; then
|
||||
extrasupport="Gnome $extrasupport"
|
||||
extrasupport="Gnome-1.x $extrasupport"
|
||||
fi
|
||||
if test "$kde_on" = "yes"; then
|
||||
extrasupport="KDE $extrasupport"
|
||||
extrasupport="KDE-1.x $extrasupport"
|
||||
fi
|
||||
if test "$netwm_on" = "yes"; then
|
||||
extrasupport="NetWM $extrasupport"
|
||||
fi
|
||||
|
||||
if test "x$extrasupport" = "x"; then
|
||||
extrasupport="None"
|
||||
fi
|
||||
@@ -1162,7 +1150,7 @@ echo "Use inline MMX(tm) x86 assembly : $mmx_support"
|
||||
echo "Antialiased text support in WINGs : $xft"
|
||||
echo "Xinerama extension support : $xinerama"
|
||||
echo "Virtual desktop support : $vdesktop_on"
|
||||
echo "Additionally supported environments : $extrasupport"
|
||||
echo "Supported legacy environments : $extrasupport"
|
||||
echo "Translated message files to install : $mof"
|
||||
dnl echo "Supported languages beside English : $languages"
|
||||
if test "x$MOFILES" != "x"; then
|
||||
|
||||
@@ -50,6 +50,7 @@ wmaker_SOURCES = \
|
||||
menu.c \
|
||||
menu.h \
|
||||
misc.c \
|
||||
monitor.c \
|
||||
motif.c \
|
||||
motif.h \
|
||||
moveres.c \
|
||||
|
||||
@@ -481,6 +481,7 @@ typedef struct WPreferences {
|
||||
unsigned int norestore:1; /* don't restore session */
|
||||
unsigned int create_stdcmap:1; /* create std colormap */
|
||||
unsigned int nopolling:1; /* don't poll for defaults changes */
|
||||
unsigned int restarting:2;
|
||||
} flags; /* internal flags */
|
||||
} WPreferences;
|
||||
|
||||
|
||||
@@ -193,7 +193,7 @@ wAppIconDestroy(WAppIcon *aicon)
|
||||
wIconDestroy(aicon->icon);
|
||||
if (aicon->command)
|
||||
wfree(aicon->command);
|
||||
#ifdef OFFIX_DND
|
||||
#ifdef XDND
|
||||
if (aicon->dnd_command)
|
||||
wfree(aicon->dnd_command);
|
||||
#endif
|
||||
|
||||
@@ -45,7 +45,7 @@ typedef struct WAppIcon {
|
||||
|
||||
char *command; /* command used to launch app */
|
||||
|
||||
#ifdef OFFIX_DND
|
||||
#ifdef XDND
|
||||
char *dnd_command; /* command to use when something is */
|
||||
/* dropped on us */
|
||||
#endif
|
||||
|
||||
45
src/dock.c
45
src/dock.c
@@ -81,10 +81,6 @@ extern WPreferences wPreferences;
|
||||
|
||||
extern XContext wWinContext;
|
||||
|
||||
#ifdef OFFIX_DND
|
||||
extern Atom _XA_DND_PROTOCOL;
|
||||
#endif
|
||||
|
||||
|
||||
#define MOD_MASK wPreferences.modifier_mask
|
||||
|
||||
@@ -97,7 +93,7 @@ extern void appIconMouseDown(WObjDescriptor *desc, XEvent *event);
|
||||
|
||||
static WMPropList *dCommand=NULL;
|
||||
static WMPropList *dPasteCommand=NULL;
|
||||
#ifdef OFFIX_DND
|
||||
#ifdef XDND /* XXX was OFFIX */
|
||||
static WMPropList *dDropCommand=NULL;
|
||||
#endif
|
||||
static WMPropList *dAutoLaunch, *dLock;
|
||||
@@ -142,22 +138,6 @@ static void clipAutoRaise(void *cdata);
|
||||
|
||||
static void showClipBalloon(WDock *dock, int workspace);
|
||||
|
||||
#ifdef OFFIX_DND
|
||||
|
||||
#define DndNotDnd -1
|
||||
#define DndUnknown 0
|
||||
#define DndRawData 1
|
||||
#define DndFile 2
|
||||
#define DndFiles 3
|
||||
#define DndText 4
|
||||
#define DndDir 5
|
||||
#define DndLink 6
|
||||
#define DndExe 7
|
||||
|
||||
#define DndEND 8
|
||||
|
||||
#endif /* OFFIX_DND */
|
||||
|
||||
|
||||
|
||||
static void
|
||||
@@ -168,7 +148,9 @@ make_keys()
|
||||
|
||||
dCommand = WMRetainPropList(WMCreatePLString("Command"));
|
||||
dPasteCommand = WMRetainPropList(WMCreatePLString("PasteCommand"));
|
||||
#ifdef XDND
|
||||
dDropCommand = WMRetainPropList(WMCreatePLString("DropCommand"));
|
||||
#endif
|
||||
dLock = WMRetainPropList(WMCreatePLString("Lock"));
|
||||
dAutoLaunch = WMRetainPropList(WMCreatePLString("AutoLaunch"));
|
||||
dName = WMRetainPropList(WMCreatePLString("Name"));
|
||||
@@ -1402,13 +1384,13 @@ make_icon_state(WAppIcon *btn)
|
||||
(btn->xindex != 0 || btn->yindex != 0))
|
||||
WMPutInPLDictionary(node, dOmnipresent, omnipresent);
|
||||
|
||||
#ifdef OFFIX_DND
|
||||
#ifdef XDND /* was OFFIX */
|
||||
if (btn->dnd_command) {
|
||||
command = WMCreatePLString(btn->dnd_command);
|
||||
WMPutInPLDictionary(node, dDropCommand, command);
|
||||
WMReleasePropList(command);
|
||||
}
|
||||
#endif /* OFFIX_DND */
|
||||
#endif /* XDND */
|
||||
|
||||
if (btn->paste_command) {
|
||||
command = WMCreatePLString(btn->paste_command);
|
||||
@@ -1625,7 +1607,7 @@ restore_icon_state(WScreen *scr, WMPropList *info, int type, int index)
|
||||
aicon->icon->core->descriptor.parent = aicon;
|
||||
|
||||
|
||||
#ifdef OFFIX_DND
|
||||
#ifdef XDND /* was OFFIX */
|
||||
cmd = WMGetFromPLDictionary(info, dDropCommand);
|
||||
if (cmd)
|
||||
aicon->dnd_command = wstrdup(WMGetFromPLString(cmd));
|
||||
@@ -1732,7 +1714,7 @@ wClipRestoreState(WScreen *scr, WMPropList *clip_state)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef OFFIX_DND
|
||||
#ifdef XDND /* was OFFIX */
|
||||
value = WMGetFromPLDictionary(clip_state, dDropCommand);
|
||||
if (value && WMIsPLString(value))
|
||||
icon->dnd_command = wstrdup(WMGetFromPLString(value));
|
||||
@@ -2042,7 +2024,7 @@ wDockDoAutoLaunch(WDock *dock, int workspace)
|
||||
}
|
||||
|
||||
|
||||
#ifdef OFFIX_DND
|
||||
#ifdef XDND /* was OFFIX */
|
||||
static WDock*
|
||||
findDock(WScreen *scr, XEvent *event, int *icon_pos)
|
||||
{
|
||||
@@ -2130,7 +2112,7 @@ wDockReceiveDNDDrop(WScreen *scr, XEvent *event)
|
||||
}
|
||||
return False;
|
||||
}
|
||||
#endif /* OFFIX_DND */
|
||||
#endif /* XDND */
|
||||
|
||||
|
||||
|
||||
@@ -2225,7 +2207,7 @@ wDockAttachIcon(WDock *dock, WAppIcon *icon, int x, int y)
|
||||
if (wPreferences.auto_arrange_icons)
|
||||
wArrangeIcons(dock->screen_ptr, True);
|
||||
|
||||
#ifdef OFFIX_DND
|
||||
#ifdef XDND /* was OFFIX */
|
||||
if (icon->command && !icon->dnd_command) {
|
||||
int len = strlen(icon->command)+8;
|
||||
icon->dnd_command = wmalloc(len);
|
||||
@@ -2407,7 +2389,7 @@ wDockDetach(WDock *dock, WAppIcon *icon)
|
||||
wfree(icon->command);
|
||||
icon->command = NULL;
|
||||
}
|
||||
#ifdef OFFIX_DND
|
||||
#ifdef XDND /* was OFFIX */
|
||||
if (icon->dnd_command) {
|
||||
wfree(icon->dnd_command);
|
||||
icon->dnd_command = NULL;
|
||||
@@ -3337,9 +3319,12 @@ trackDeadProcess(pid_t pid, unsigned char status, WDock *dock)
|
||||
char msg[PATH_MAX];
|
||||
char *cmd;
|
||||
|
||||
#ifdef XDND
|
||||
if (icon->drop_launch)
|
||||
cmd = icon->dnd_command;
|
||||
else if (icon->paste_launch)
|
||||
else
|
||||
#endif
|
||||
if (icon->paste_launch)
|
||||
cmd = icon->paste_command;
|
||||
else
|
||||
cmd = icon->command;
|
||||
|
||||
@@ -92,7 +92,7 @@ WAppIcon *wDockFindIconForWindow(WDock *dock, Window window);
|
||||
void wDockDoAutoLaunch(WDock *dock, int workspace);
|
||||
void wDockLaunchWithState(WDock *dock, WAppIcon *btn, WSavedState *state);
|
||||
|
||||
#ifdef OFFIX_DND
|
||||
#ifdef XDND
|
||||
int wDockReceiveDNDDrop(WScreen *scr, XEvent *event);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ updatePasteCommand(WAppIcon *icon, char *command)
|
||||
|
||||
|
||||
|
||||
#ifdef OFFIX_DND
|
||||
#ifdef XDND
|
||||
static void
|
||||
updateDNDCommand(WAppIcon *icon, char *command)
|
||||
{
|
||||
@@ -131,7 +131,7 @@ updateDNDCommand(WAppIcon *icon, char *command)
|
||||
}
|
||||
icon->dnd_command = command;
|
||||
}
|
||||
#endif /* OFFIX_DND */
|
||||
#endif /* XDND */
|
||||
|
||||
|
||||
static void
|
||||
@@ -258,7 +258,7 @@ panelBtnCallback(WMWidget *self, void *data)
|
||||
text = NULL;
|
||||
}
|
||||
updateCommand(panel->editedIcon, text);
|
||||
#ifdef OFFIX_DND
|
||||
#ifdef XDND
|
||||
/* cannot free text from this, because it will be not be duplicated
|
||||
* in updateDNDCommand */
|
||||
text = WMGetTextFieldText(panel->dndCommandField);
|
||||
@@ -385,7 +385,7 @@ ShowDockAppSettingsPanel(WAppIcon *aicon)
|
||||
panel->dndCommandLabel = WMCreateLabel(panel->dndCommandFrame);
|
||||
WMResizeWidget(panel->dndCommandLabel, 256, 18);
|
||||
WMMoveWidget(panel->dndCommandLabel, 10, 45);
|
||||
#ifdef OFFIX_DND
|
||||
#ifdef XDND
|
||||
WMSetTextFieldText(panel->dndCommandField, aicon->dnd_command);
|
||||
WMSetLabelText(panel->dndCommandLabel,
|
||||
_("%d will be replaced with the file name"));
|
||||
|
||||
13
src/event.c
13
src/event.c
@@ -95,10 +95,6 @@ extern Atom _XA_GNUSTEP_TITLEBAR_STATE;
|
||||
extern Atom _XA_WINDOWMAKER_WM_FUNCTION;
|
||||
extern Atom _XA_WINDOWMAKER_COMMAND;
|
||||
|
||||
#ifdef OFFIX_DND
|
||||
extern Atom _XA_DND_PROTOCOL;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef SHAPE
|
||||
extern Bool wShapeSupported;
|
||||
@@ -1017,16 +1013,7 @@ handleClientMessage(XEvent *event)
|
||||
} else if (wXDNDProcessClientMessage(&event->xclient)) {
|
||||
/* do nothing */
|
||||
#endif /* XDND */
|
||||
#ifdef OFFIX_DND
|
||||
} else if (event->xclient.message_type==_XA_DND_PROTOCOL) {
|
||||
WScreen *scr = wScreenForWindow(event->xclient.window);
|
||||
if (scr && wDockReceiveDNDDrop(scr,event))
|
||||
goto redirect_message;
|
||||
#endif /* OFFIX_DND */
|
||||
} else {
|
||||
#ifdef OFFIX_DND
|
||||
redirect_message:
|
||||
#endif
|
||||
/*
|
||||
* Non-standard thing, but needed by OffiX DND.
|
||||
* For when the icon frame gets a ClientMessage
|
||||
|
||||
@@ -1076,7 +1076,7 @@ wFrameWindowPaint(WFrameWindow *fwin)
|
||||
break;
|
||||
}
|
||||
|
||||
y = *fwin->title_clearance + TITLEBAR_EXTEND_SPACE;
|
||||
y = *fwin->title_clearance + TITLEBAR_EXTEND_SPACE - 1;
|
||||
h = WMFontHeight(*fwin->font);
|
||||
|
||||
/* We use a w+2 buffer to have an extra pixel on the left and
|
||||
|
||||
52
src/main.c
52
src/main.c
@@ -115,11 +115,6 @@ Atom _XA_WINDOWMAKER_ICON_SIZE;
|
||||
Atom _XA_WINDOWMAKER_ICON_TILE;
|
||||
|
||||
|
||||
#ifdef OFFIX_DND
|
||||
Atom _XA_DND_PROTOCOL;
|
||||
Atom _XA_DND_SELECTION;
|
||||
#endif
|
||||
|
||||
/* cursors */
|
||||
Cursor wCursor[WCUR_LAST];
|
||||
|
||||
@@ -148,7 +143,6 @@ char WDelayedActionSet = 0;
|
||||
int wVisualID = -1;
|
||||
|
||||
|
||||
|
||||
/* notifications */
|
||||
const char *WMNManaged = "WMNManaged";
|
||||
const char *WMNUnmanaged = "WMNUnmanaged";
|
||||
@@ -175,6 +169,7 @@ static int ArgCount;
|
||||
|
||||
extern void EventLoop();
|
||||
extern void StartUp();
|
||||
extern int MonitorLoop(int argc, char **argv);
|
||||
|
||||
static Bool multiHead = True;
|
||||
|
||||
@@ -182,6 +177,8 @@ static Bool multiHead = True;
|
||||
static int LogStdIn = -1, LogStdOut = -1, LogStdErr = -1;
|
||||
|
||||
|
||||
static int real_main(int argc, char **argv);
|
||||
|
||||
void
|
||||
Exit(int status)
|
||||
{
|
||||
@@ -226,7 +223,7 @@ Restart(char *manager, Bool abortOnFailure)
|
||||
wsyserror(_("could not exec %s"), prog);
|
||||
}
|
||||
if (abortOnFailure)
|
||||
exit(-1);
|
||||
exit(7);
|
||||
}
|
||||
|
||||
|
||||
@@ -583,8 +580,32 @@ getFullPath(char *path)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
int i_am_the_monitor= 1;
|
||||
|
||||
for (i= 1; i < argc; i++)
|
||||
{
|
||||
if (strncmp(argv[i], "--for-real", strlen("--for-real"))==0)
|
||||
{
|
||||
i_am_the_monitor= 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i_am_the_monitor)
|
||||
return MonitorLoop(argc, argv);
|
||||
else
|
||||
return real_main(argc, argv);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
real_main(int argc, char **argv)
|
||||
{
|
||||
int i, restart=0;
|
||||
char *str, *alt;
|
||||
@@ -601,8 +622,13 @@ main(int argc, char **argv)
|
||||
str = wstrconcat("WMAKER_BIN_NAME=", argv[0]);
|
||||
putenv(str);
|
||||
|
||||
ArgCount = argc;
|
||||
Arguments = argv;
|
||||
ArgCount = argc+1;
|
||||
Arguments = wmalloc(sizeof(char*)*(ArgCount+2));
|
||||
for (i= 0; i < argc; i++)
|
||||
Arguments[i]= argv[i];
|
||||
/* add the extra option to signal that we're just restarting wmaker */
|
||||
Arguments[argc]= "--for-real=";
|
||||
Arguments[argc+1]= NULL;
|
||||
|
||||
WMInitializeApplication("WindowMaker", &argc, argv);
|
||||
|
||||
@@ -638,7 +664,13 @@ main(int argc, char **argv)
|
||||
wPreferences.flags.nocpp=1;
|
||||
} else
|
||||
#endif
|
||||
if (strcmp(argv[i], "-no-autolaunch")==0
|
||||
if (strcmp(argv[i], "--for-real")==0) {
|
||||
wPreferences.flags.restarting = 0;
|
||||
} else if (strcmp(argv[i], "--for-real=")==0) {
|
||||
wPreferences.flags.restarting = 1;
|
||||
} else if (strcmp(argv[i], "--for-real-")==0) {
|
||||
wPreferences.flags.restarting = 2;
|
||||
} else if (strcmp(argv[i], "-no-autolaunch")==0
|
||||
|| strcmp(argv[i], "--no-autolaunch")==0) {
|
||||
wPreferences.flags.noautolaunch = 1;
|
||||
} else if (strcmp(argv[i], "-dont-restore")==0
|
||||
|
||||
@@ -67,6 +67,12 @@ extern WPreferences wPreferences;
|
||||
|
||||
/***** Local Stuff ******/
|
||||
|
||||
|
||||
#define WSS_ROOTMENU (1<<0)
|
||||
#define WSS_SWITCHMENU (1<<1)
|
||||
#define WSS_WSMENU (1<<2)
|
||||
|
||||
|
||||
static struct {
|
||||
int steps;
|
||||
int delay;
|
||||
|
||||
85
src/misc.c
85
src/misc.c
@@ -56,10 +56,6 @@ extern WPreferences wPreferences;
|
||||
|
||||
extern Time LastTimestamp;
|
||||
|
||||
#ifdef OFFIX_DND
|
||||
extern Atom _XA_DND_SELECTION;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef USECPP
|
||||
static void
|
||||
@@ -705,44 +701,6 @@ getuserinput(WScreen *scr, char *line, int *ptr)
|
||||
}
|
||||
|
||||
|
||||
#ifdef OFFIX_DND
|
||||
static char*
|
||||
get_dnd_selection(WScreen *scr)
|
||||
{
|
||||
XTextProperty text_ret;
|
||||
int result;
|
||||
char **list;
|
||||
char *flat_string;
|
||||
int count;
|
||||
|
||||
result=XGetTextProperty(dpy, scr->root_win, &text_ret, _XA_DND_SELECTION);
|
||||
|
||||
if (result==0 || text_ret.value==NULL || text_ret.encoding==None
|
||||
|| text_ret.format==0 || text_ret.nitems == 0) {
|
||||
wwarning(_("unable to get dropped data from DND drop"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
XTextPropertyToStringList(&text_ret, &list, &count);
|
||||
|
||||
if (!list || count<1) {
|
||||
XFree(text_ret.value);
|
||||
wwarning(_("error getting dropped data from DND drop"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
flat_string = wtokenjoin(list, count);
|
||||
if (!flat_string) {
|
||||
wwarning(_("out of memory while getting data from DND drop"));
|
||||
}
|
||||
|
||||
XFreeStringList(list);
|
||||
XFree(text_ret.value);
|
||||
return flat_string;
|
||||
}
|
||||
#endif /* OFFIX_DND */
|
||||
|
||||
|
||||
#define S_NORMAL 0
|
||||
#define S_ESCAPE 1
|
||||
#define S_OPTION 2
|
||||
@@ -768,7 +726,7 @@ ExpandOptions(WScreen *scr, char *cmdline)
|
||||
char *out, *nout;
|
||||
char *selection=NULL;
|
||||
char *user_input=NULL;
|
||||
#if defined(OFFIX_DND) || defined(XDND)
|
||||
#ifdef XDND
|
||||
char *dropped_thing=NULL;
|
||||
#endif
|
||||
char tmpbuf[TMPBUFSIZE];
|
||||
@@ -879,13 +837,11 @@ ExpandOptions(WScreen *scr, char *cmdline)
|
||||
}
|
||||
break;
|
||||
|
||||
#if defined(OFFIX_DND) || defined(XDND)
|
||||
case 'd':
|
||||
#ifdef XDND
|
||||
case 'd':
|
||||
if(scr->xdestring) {
|
||||
dropped_thing = wstrdup(scr->xdestring);
|
||||
}
|
||||
#endif
|
||||
if (!dropped_thing) {
|
||||
dropped_thing = get_dnd_selection(scr);
|
||||
}
|
||||
@@ -904,7 +860,7 @@ ExpandOptions(WScreen *scr, char *cmdline)
|
||||
strcat(out,dropped_thing);
|
||||
optr+=slen;
|
||||
break;
|
||||
#endif /* OFFIX_DND */
|
||||
#endif /* XDND */
|
||||
|
||||
case 's':
|
||||
if (!selection) {
|
||||
@@ -1262,41 +1218,6 @@ StrConcatDot(char *a, char *b)
|
||||
}
|
||||
|
||||
|
||||
#ifndef NETWM_HINTS
|
||||
|
||||
static Atom net_wm_pid = None;
|
||||
|
||||
int
|
||||
GetPidForWindow(Window win)
|
||||
{
|
||||
Atom type_ret;
|
||||
int fmt_ret;
|
||||
unsigned long nitems_ret;
|
||||
unsigned long bytes_after_ret;
|
||||
long *data = 0;
|
||||
int pid;
|
||||
|
||||
if (net_wm_pid == None) {
|
||||
net_wm_pid = XInternAtom(dpy, "_NET_WM_PID", False);
|
||||
}
|
||||
|
||||
if (XGetWindowProperty(dpy, win, net_wm_pid, 0, 1, False,
|
||||
XA_CARDINAL, &type_ret, &fmt_ret, &nitems_ret,
|
||||
&bytes_after_ret,
|
||||
(unsigned char**)&data)==Success && data) {
|
||||
|
||||
pid = *data;
|
||||
XFree(data);
|
||||
} else {
|
||||
pid = 0;
|
||||
}
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Bool
|
||||
GetCommandForPid(int pid, char ***argv, int *argc)
|
||||
{
|
||||
|
||||
152
src/monitor.c
Normal file
152
src/monitor.c
Normal file
@@ -0,0 +1,152 @@
|
||||
/* monitor.c - monitors the wmaker process
|
||||
*
|
||||
* Window Maker window manager
|
||||
*
|
||||
* Copyright (c) 1997-2004 Alfredo K. Kojima
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include "wconfig.h"
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
#include <sys/wait.h>
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/signal.h>
|
||||
#endif
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xproto.h>
|
||||
|
||||
#include "WindowMaker.h"
|
||||
#include "screen.h"
|
||||
#include "window.h"
|
||||
#include "dialog.h"
|
||||
#include "funcs.h"
|
||||
|
||||
/****** Global Variables ******/
|
||||
|
||||
extern WPreferences wPreferences;
|
||||
|
||||
extern int wScreenCount;
|
||||
|
||||
|
||||
|
||||
|
||||
int showCrashDialog(int sig)
|
||||
{
|
||||
int crashAction;
|
||||
Display *dpy;
|
||||
|
||||
dpy = XOpenDisplay("");
|
||||
if (dpy) {
|
||||
/* XXX TODO make sure that window states are saved and restored via netwm */
|
||||
|
||||
XGrabServer(dpy);
|
||||
crashAction = wShowCrashingDialogPanel(sig);
|
||||
XCloseDisplay(dpy);
|
||||
dpy = NULL;
|
||||
} else {
|
||||
wsyserror(_("cannot open connection for crashing dialog panel. Aborting."));
|
||||
crashAction = WMAbort;
|
||||
}
|
||||
|
||||
if (crashAction == WMRestart)
|
||||
{
|
||||
int i;
|
||||
|
||||
wmessage(_("trying to start alternate window manager..."));
|
||||
|
||||
for (i=0; i<WMGetArrayItemCount(wPreferences.fallbackWMs); i++) {
|
||||
Restart(WMGetFromArray(wPreferences.fallbackWMs, i), False);
|
||||
}
|
||||
|
||||
wfatal(_("failed to start alternate window manager. Aborting."));
|
||||
|
||||
return 0;
|
||||
}
|
||||
else if (crashAction == WMAbort)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int MonitorLoop(int argc, char **argv)
|
||||
{
|
||||
pid_t pid;
|
||||
char **child_argv= wmalloc(sizeof(char*)*(argc+2));
|
||||
int i, status;
|
||||
time_t last_start;
|
||||
|
||||
for (i= 0; i < argc; i++)
|
||||
child_argv[i]= argv[i];
|
||||
child_argv[i++]= "--for-real";
|
||||
child_argv[i]= NULL;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
last_start= time(NULL);
|
||||
|
||||
/* Start Window Maker */
|
||||
pid= fork();
|
||||
if (pid == 0)
|
||||
{
|
||||
execvp(child_argv[0], child_argv);
|
||||
wsyserror(_("Error respawning Window Maker"));
|
||||
exit(1);
|
||||
}
|
||||
else if (pid < 0)
|
||||
{
|
||||
wsyserror(_("Error respawning Window Maker"));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (waitpid(pid, &status, 0) < 0)
|
||||
{
|
||||
wsyserror(_("Error during monitoring of Window Maker process."));
|
||||
break;
|
||||
}
|
||||
|
||||
child_argv[argc]= "--for-real-";
|
||||
|
||||
/* Check if the wmaker process exited due to a crash */
|
||||
if (WIFSIGNALED(status) &&
|
||||
(WTERMSIG(status) == SIGSEGV ||
|
||||
WTERMSIG(status) == SIGBUS ||
|
||||
WTERMSIG(status) == SIGILL ||
|
||||
WTERMSIG(status) == SIGFPE))
|
||||
{
|
||||
/* If so, we check when was the last restart.
|
||||
* If it was less than 5s ago, it's a bad sign, so we show
|
||||
* the crash panel and ask the user what to do */
|
||||
if (time(NULL) - last_start < 5)
|
||||
{
|
||||
if (showCrashDialog(WTERMSIG(status)) == 0)
|
||||
return 1;
|
||||
}
|
||||
wwarning(_("Window Maker exited due to a crash (signal %i) and will be restarted."),
|
||||
WTERMSIG(status));
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1204,14 +1204,6 @@ wScreenSaveState(WScreen *scr)
|
||||
|
||||
make_keys();
|
||||
|
||||
/* Save current workspace, so can go back to it upon restart. */
|
||||
data[0] = scr->current_workspace;
|
||||
data[1] = WFLAGS_NONE;
|
||||
|
||||
XChangeProperty(dpy, scr->root_win, _XA_WINDOWMAKER_STATE,
|
||||
_XA_WINDOWMAKER_STATE, 32, PropModeReplace,
|
||||
(unsigned char *) data, 2);
|
||||
|
||||
/* save state of windows */
|
||||
wwin = scr->focused_window;
|
||||
while (wwin) {
|
||||
|
||||
10
src/screen.h
10
src/screen.h
@@ -335,16 +335,6 @@ typedef struct _WScreen {
|
||||
} WScreen;
|
||||
|
||||
|
||||
#define WSS_ROOTMENU (1<<0)
|
||||
#define WSS_SWITCHMENU (1<<1)
|
||||
#define WSS_WSMENU (1<<2)
|
||||
|
||||
/* changes must update wSaveScreenState/getWorkspaceState */
|
||||
typedef struct WWorkspaceState {
|
||||
int flags;
|
||||
int workspace;
|
||||
} WWorkspaceState;
|
||||
|
||||
|
||||
WScreen *wScreenInit(int screen_number);
|
||||
void wScreenSaveState(WScreen *scr);
|
||||
|
||||
169
src/startup.c
169
src/startup.c
@@ -138,11 +138,6 @@ extern Atom _XA_WINDOWMAKER_ICON_TILE;
|
||||
extern Atom _XA_GNUSTEP_WM_MINIATURIZE_WINDOW;
|
||||
extern Atom _XA_GNUSTEP_TITLEBAR_STATE;
|
||||
|
||||
#ifdef OFFIX_DND
|
||||
extern Atom _XA_DND_PROTOCOL;
|
||||
extern Atom _XA_DND_SELECTION;
|
||||
#endif
|
||||
|
||||
|
||||
/* cursors */
|
||||
extern Cursor wCursor[WCUR_LAST];
|
||||
@@ -311,25 +306,10 @@ dummyHandler(int sig)
|
||||
static RETSIGTYPE
|
||||
handleSig(int sig)
|
||||
{
|
||||
static int already_crashed = 0;
|
||||
int dumpcore = 0;
|
||||
#ifndef NO_EMERGENCY_AUTORESTART
|
||||
int crashAction, i;
|
||||
char *argv[2];
|
||||
|
||||
argv[1] = NULL;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* No functions that potentially do Xlib calls should be called from
|
||||
* here. Xlib calls are not reentrant so the integrity of Xlib is
|
||||
* not guaranteed if a Xlib call is made from a signal handler.
|
||||
*/
|
||||
|
||||
#ifdef SYS_SIGLIST_DECLARED
|
||||
wfatal(_("got signal %i (%s)\n"), sig, sys_siglist[sig]);
|
||||
wfatal("got signal %i (%s)\n", sig, sys_siglist[sig]);
|
||||
#else
|
||||
wfatal(_("got signal %i\n"), sig);
|
||||
wfatal("got signal %i\n", sig);
|
||||
#endif
|
||||
|
||||
/* Setting the signal behaviour back to default and then reraising the
|
||||
@@ -339,95 +319,12 @@ handleSig(int sig)
|
||||
*/
|
||||
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."));
|
||||
signal(sig, SIG_DFL);
|
||||
kill(getpid(), sig);
|
||||
return;
|
||||
}
|
||||
already_crashed = 1;
|
||||
|
||||
dumpcore = 1;
|
||||
|
||||
/*
|
||||
* Yeah, we shouldn't do this, but it's already crashed anyway :P
|
||||
*/
|
||||
|
||||
#ifndef NO_EMERGENCY_AUTORESTART
|
||||
/* 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.
|
||||
*/
|
||||
if (dpy)
|
||||
XCloseDisplay(dpy);
|
||||
dpy = XOpenDisplay("");
|
||||
if (dpy) {
|
||||
CARD32 data[2];
|
||||
WWindow *wwin;
|
||||
|
||||
XGrabServer(dpy);
|
||||
crashAction = wShowCrashingDialogPanel(sig);
|
||||
|
||||
/*
|
||||
* Save current workspace, so can go back to it if restarting.
|
||||
* Also add hint that we crashed, so that windows will be placed
|
||||
* correctly upon restart.
|
||||
*/
|
||||
for (i=0; i<wScreenCount; i++) {
|
||||
data[0] = wScreen[i]->current_workspace; /* workspace number */
|
||||
data[1] = WFLAGS_CRASHED; /* signal that we crashed */
|
||||
|
||||
XChangeProperty(dpy, wScreen[i]->root_win,
|
||||
_XA_WINDOWMAKER_STATE, _XA_WINDOWMAKER_STATE,
|
||||
32, PropModeReplace, (unsigned char*) data, 2);
|
||||
|
||||
/* save state of windows */
|
||||
wwin = wScreen[i]->focused_window;
|
||||
while (wwin) {
|
||||
wWindowSaveState(wwin);
|
||||
wwin = wwin->prev;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
XCloseDisplay(dpy);
|
||||
dpy = NULL;
|
||||
} else {
|
||||
wsyserror(_("cannot open connection for crashing dialog panel. Aborting."));
|
||||
crashAction = WMAbort;
|
||||
}
|
||||
|
||||
if (crashAction == WMAbort) {
|
||||
signal(sig, SIG_DFL);
|
||||
kill(getpid(), sig);
|
||||
return;
|
||||
}
|
||||
|
||||
if (crashAction == WMRestart) {
|
||||
/* we try to restart Window Maker */
|
||||
wmessage(_("trying to restart Window Maker..."));
|
||||
Restart(NULL, False);
|
||||
/* fallback to alternate window manager then */
|
||||
}
|
||||
|
||||
wmessage(_("trying to start alternate window manager..."));
|
||||
|
||||
for (i=0; i<WMGetArrayItemCount(wPreferences.fallbackWMs); i++) {
|
||||
Restart(WMGetFromArray(wPreferences.fallbackWMs, i), False);
|
||||
}
|
||||
|
||||
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);
|
||||
kill(getpid(), sig);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
wAbort(dumpcore);
|
||||
wAbort(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -462,34 +359,6 @@ buryChild(int foo)
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
getWorkspaceState(Window root, WWorkspaceState **state)
|
||||
{
|
||||
Atom type_ret;
|
||||
int fmt_ret;
|
||||
unsigned long nitems_ret;
|
||||
unsigned long bytes_after_ret;
|
||||
CARD32 *data;
|
||||
|
||||
if (XGetWindowProperty(dpy, root, _XA_WINDOWMAKER_STATE, 0, 2,
|
||||
True, _XA_WINDOWMAKER_STATE,
|
||||
&type_ret, &fmt_ret, &nitems_ret, &bytes_after_ret,
|
||||
(unsigned char **)&data)!=Success || !data)
|
||||
return 0;
|
||||
|
||||
*state = wmalloc(sizeof(WWorkspaceState));
|
||||
(*state)->workspace = data[0];
|
||||
(*state)->flags = data[1];
|
||||
|
||||
XFree(data);
|
||||
|
||||
if (*state && type_ret==_XA_WINDOWMAKER_STATE)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
getOffendingModifiers()
|
||||
{
|
||||
@@ -735,7 +604,6 @@ static char *atomNames[] = {
|
||||
void
|
||||
StartUp(Bool defaultScreenOnly)
|
||||
{
|
||||
WWorkspaceState *ws_state;
|
||||
struct sigaction sig_action;
|
||||
int j, max;
|
||||
Atom atom[sizeof(atomNames)/sizeof(char*)];
|
||||
@@ -797,10 +665,6 @@ StartUp(Bool defaultScreenOnly)
|
||||
_XA_GNUSTEP_WM_MINIATURIZE_WINDOW = atom[18];
|
||||
_XA_GNUSTEP_TITLEBAR_STATE = atom[19];
|
||||
|
||||
#ifdef OFFIX_DND
|
||||
_XA_DND_SELECTION = XInternAtom(dpy, "DndSelection", False);
|
||||
_XA_DND_PROTOCOL = XInternAtom(dpy, "DndProtocol", False);
|
||||
#endif
|
||||
#ifdef XDND
|
||||
wXDNDInitializeAtoms();
|
||||
#endif
|
||||
@@ -843,10 +707,14 @@ StartUp(Bool defaultScreenOnly)
|
||||
|
||||
sig_action.sa_flags = SA_RESTART;
|
||||
sigaction(SIGQUIT, &sig_action, NULL);
|
||||
/* instead of catching these, we let the default handler abort the
|
||||
* program. The new monitor process will take appropriate action
|
||||
* when it detects the crash.
|
||||
sigaction(SIGSEGV, &sig_action, NULL);
|
||||
sigaction(SIGBUS, &sig_action, NULL);
|
||||
sigaction(SIGFPE, &sig_action, NULL);
|
||||
sigaction(SIGABRT, &sig_action, NULL);
|
||||
*/
|
||||
|
||||
sig_action.sa_handler = handleExitSig;
|
||||
|
||||
@@ -971,12 +839,9 @@ StartUp(Bool defaultScreenOnly)
|
||||
|
||||
/* initialize/restore state for the screens */
|
||||
for (j = 0; j < wScreenCount; j++) {
|
||||
int crashed;
|
||||
int lastDesktop;
|
||||
|
||||
/* restore workspace state */
|
||||
if (!getWorkspaceState(wScreen[j]->root_win, &ws_state)) {
|
||||
ws_state = NULL;
|
||||
}
|
||||
lastDesktop= wNETWMGetCurrentDesktopFromHint(wScreen[j]);
|
||||
|
||||
wScreenRestoreState(wScreen[j]);
|
||||
|
||||
@@ -984,18 +849,13 @@ StartUp(Bool defaultScreenOnly)
|
||||
if (!wPreferences.flags.nodock && wScreen[j]->dock)
|
||||
wScreen[j]->last_dock = wScreen[j]->dock;
|
||||
|
||||
if (ws_state && (ws_state->flags & WFLAGS_CRASHED)!=0)
|
||||
crashed = 1;
|
||||
else
|
||||
crashed = 0;
|
||||
|
||||
manageAllWindows(wScreen[j], crashed);
|
||||
manageAllWindows(wScreen[j], wPreferences.flags.restarting==2);
|
||||
|
||||
/* restore saved menus */
|
||||
wMenuRestoreState(wScreen[j]);
|
||||
|
||||
/* If we're not restarting restore session */
|
||||
if (ws_state == NULL && !wPreferences.flags.norestore)
|
||||
/* If we're not restarting, restore session */
|
||||
if (wPreferences.flags.restarting==0 && !wPreferences.flags.norestore)
|
||||
wSessionRestoreState(wScreen[j]);
|
||||
|
||||
if (!wPreferences.flags.noautolaunch) {
|
||||
@@ -1017,9 +877,8 @@ StartUp(Bool defaultScreenOnly)
|
||||
}
|
||||
|
||||
/* go to workspace where we were before restart */
|
||||
if (ws_state) {
|
||||
wWorkspaceForceChange(wScreen[j], ws_state->workspace);
|
||||
wfree(ws_state);
|
||||
if (lastDesktop >= 0) {
|
||||
wWorkspaceForceChange(wScreen[j], lastDesktop);
|
||||
} else {
|
||||
wSessionRestoreLastWorkspace(wScreen[j]);
|
||||
}
|
||||
|
||||
@@ -62,10 +62,8 @@
|
||||
|
||||
/* #define CPP_PATH @CPP_PATH@ */
|
||||
|
||||
/*
|
||||
* support for OffiX DND drag and drop in the Dock
|
||||
*/
|
||||
#define OFFIX_DND
|
||||
|
||||
#define NETWM_HINTS
|
||||
|
||||
/*
|
||||
* support for XDND drop in the Dock. Experimental
|
||||
|
||||
@@ -574,7 +574,7 @@ fixLeaderProperties(WWindow *wwin)
|
||||
|
||||
classHint = XAllocClassHint();
|
||||
clientHints = XGetWMHints(dpy, wwin->client_win);
|
||||
pid = GetPidForWindow(wwin->client_win);
|
||||
pid = wNETWMGetPidForWindow(wwin->client_win);
|
||||
if (pid > 0) {
|
||||
haveCommand = GetCommandForPid(pid, &argv, &argc);
|
||||
} else {
|
||||
|
||||
20
src/wmspec.c
20
src/wmspec.c
@@ -40,6 +40,7 @@
|
||||
#include "icon.h"
|
||||
#include "stacking.h"
|
||||
#include "xinerama.h"
|
||||
#include "properties.h"
|
||||
|
||||
|
||||
#ifdef DEBUG_WMSPEC
|
||||
@@ -348,6 +349,24 @@ wNETWMUpdateDesktop(WScreen *scr)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
wNETWMGetCurrentDesktopFromHint(WScreen *scr)
|
||||
{
|
||||
int count;
|
||||
unsigned char *prop;
|
||||
|
||||
prop= PropGetCheckProperty(scr->root_win, net_current_desktop, XA_CARDINAL,
|
||||
0, 1, &count);
|
||||
if (prop)
|
||||
{
|
||||
int desktop= *(CARD32*)prop;
|
||||
XFree(prop);
|
||||
return desktop;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
updateIconImage(WScreen *scr, WWindow *wwin)
|
||||
{
|
||||
@@ -509,7 +528,6 @@ wNETWMInitStuff(WScreen *scr)
|
||||
updateClientList(scr);
|
||||
updateClientListStacking(scr, NULL);
|
||||
updateWorkspaceCount(scr);
|
||||
updateCurrentWorkspace(scr);
|
||||
updateWorkspaceNames(scr);
|
||||
updateShowDesktop(scr, False);
|
||||
|
||||
|
||||
@@ -41,5 +41,5 @@ void wNETWMUpdateActions(WWindow *wwin, Bool del);
|
||||
void wNETWMUpdateDesktop(WScreen *scr);
|
||||
void wNETWMPositionSplash(WWindow *wwin, int *x, int *y, int width, int height);
|
||||
int wNETWMGetPidForWindow(Window window);
|
||||
|
||||
int wNETWMGetCurrentDesktopFromHint(WScreen *scr);
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user