diff --git a/configure.ac b/configure.ac index 211689d2..25a83628 100644 --- a/configure.ac +++ b/configure.ac @@ -580,6 +580,18 @@ AS_IF([test "x$enable_wmreplace" = "xyes"], [define to support ICCCM protocol for window manager replacement]) supported_xext="$supported_xext WMReplace"]) +dnl XRes support +dnl ============== +m4_divert_push([INIT_PREPARE])dnl +AC_ARG_ENABLE([res], + [AS_HELP_STRING([--disable-res], [disable resource window extension support])], + [AS_CASE(["$enableval"], + [yes|no], [], + [AC_MSG_ERROR([bad value $enableval for --enable-res]) ]) ], + [enable_res=auto]) +m4_divert_pop([INIT_PREPARE])dnl + +WM_XEXT_CHECK_XRES dnl XShape support dnl ============== diff --git a/m4/wm_xext_check.m4 b/m4/wm_xext_check.m4 index 9503af2c..751d8314 100644 --- a/m4/wm_xext_check.m4 +++ b/m4/wm_xext_check.m4 @@ -16,6 +16,33 @@ # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# WM_XEXT_CHECK_XRES +# -------------------- +# +# Check for the X Resource Window extension +# The check depends on variable 'enable_xshape' being either: +# yes - detect, fail if not found +# no - do not detect, disable support +# auto - detect, disable if not found +# +# When found, append appropriate stuff in XLIBS, and append info to +# the variable 'supported_xext' +# When not found, append info to variable 'unsupported' +AC_DEFUN_ONCE([WM_XEXT_CHECK_XRES], +[WM_LIB_CHECK([XRes], [-lXRes], [XResQueryClientIds], [$XLIBS], + [wm_save_CFLAGS="$CFLAGS" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([dnl +@%:@include +], [dnl + + XResQueryClientIds(NULL, 0, NULL, NULL, NULL);])] + [], + [AC_MSG_ERROR([found $CACHEVAR but cannot compile using XRes header])]) + CFLAGS="$wm_save_CFLAGS"], + [supported_xext], [XLIBS], [enable_res], [-])dnl +]) dnl AC_DEFUN + + # WM_XEXT_CHECK_XSHAPE # -------------------- # diff --git a/src/main.c b/src/main.c index bf5b1a0a..998bbcc5 100644 --- a/src/main.c +++ b/src/main.c @@ -56,6 +56,7 @@ #include "dialog.h" #include "main.h" #include "monitor.h" +#include "misc.h" #include @@ -354,11 +355,19 @@ Bool RelaunchWindow(WWindow *wwin) char **argv; int argc; + char *command = NULL; - if (! XGetCommand(dpy, wwin->client_win, &argv, &argc) || argc == 0 || argv == NULL) { + command = GetCommandForWindow(wwin->client_win); + if (!command) { +#ifdef USE_XRES + werror("cannot relaunch the application because no associated process found"); +#else werror("cannot relaunch the application because no WM_COMMAND property is set"); +#endif return False; - } + } else + wtokensplit(command, &argv, &argc); + pid_t pid = fork(); @@ -384,18 +393,19 @@ Bool RelaunchWindow(WWindow *wwin) } else if (pid < 0) { werror("cannot fork a new process"); - XFreeStringList(argv); + wfree(argv); + wfree(command); return False; } else { _tuple *data = wmalloc(sizeof(_tuple)); data->scr = wwin->screen_ptr; - data->command = wtokenjoin(argv, argc); + data->command = command; /* not actually a shell command */ wAddDeathHandler(pid, shellCommandHandler, data); - XFreeStringList(argv); + wfree(argv); } return True; diff --git a/src/window.c b/src/window.c index 59721b39..ef85f3d4 100644 --- a/src/window.c +++ b/src/window.c @@ -29,6 +29,9 @@ #ifdef KEEP_XKB_LOCK_STATUS #include #endif /* KEEP_XKB_LOCK_STATUS */ +#ifdef USE_XRES +#include +#endif #include #include #include @@ -475,6 +478,41 @@ Bool wWindowObscuresWindow(WWindow *wwin, WWindow *obscured) return True; } +/* Get the corresponding Process Identification Number of the active window */ +static pid_t getWindowPid(Window win) +{ + pid_t pid = -1; + + pid = wNETWMGetPidForWindow(win); +#ifdef USE_XRES + if (pid > 0) + return pid; + else { + XResClientIdSpec spec; + int status; + long i, num_ids = 0; + XResClientIdValue *client_ids = NULL; + + spec.client = win; + spec.mask = XRES_CLIENT_ID_PID_MASK; + + status = XResQueryClientIds(dpy, 1, &spec, &num_ids, &client_ids); + + if (status != Success) + return -1; + + for (i = 0; i < num_ids; i++) { + if (client_ids[i].spec.mask == XRES_CLIENT_ID_PID_MASK) { + pid = XResGetClientPid(&client_ids[i]); + break; + } + } + XResClientIdsDestroy(num_ids, client_ids); + } +#endif + return pid; +} + static void fixLeaderProperties(WWindow *wwin) { XClassHint *classHint; @@ -487,7 +525,7 @@ static void fixLeaderProperties(WWindow *wwin) classHint = XAllocClassHint(); clientHints = XGetWMHints(dpy, wwin->client_win); - pid = wNETWMGetPidForWindow(wwin->client_win); + pid = getWindowPid(wwin->client_win); if (pid > 0) haveCommand = GetCommandForPid(pid, &argv, &argc); else