1
0
mirror of https://github.com/gryf/wmaker.git synced 2025-12-18 20:10:29 +01:00

Set missing WM_COMMAND using pid given from libXRes

For apps which are not setting the window WM_COMMAND property like those old
apps using Motif toolkit (I am thinking of NEdit for example)
it's bringing some issues in windowmaker which is relying on it for a few interactions.
Especially,
*an app without WM_COMMAND will not be saved during the workspace state
(so session restore is not working for them)
*when added to the dock, the settings parameters are empty and need to be filled
*cannot autostart from the dock (even if the settings are manually filled and saved)
*right click on the app titlebar, and choosing Launch has no effect

Most of the time, those apps are also not setting the X11_NET_WM_PID property.
With the pid we could have a chance to find the running program.
To link a window to a pid, there is the X11 Resource extension library (libXRes).
After checking, gnome and xfce are also using the same method to handle such issues.

The patch is checking if the libXRes is present on the system (but it's not mandatory to compile).
Then, it adds a layer on top of wNETWMGetPidForWindow to not only check the window property
but if necessary to get the underlying pid from libXRes if available.
That's solving the points mentioned above.
This commit is contained in:
David Maciejak
2023-02-20 20:02:28 +08:00
committed by Carlos R. Mafra
parent 5ee19c2308
commit d902477efd
4 changed files with 93 additions and 6 deletions

View File

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

View File

@@ -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 <X11/extensions/XRes.h>
], [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
# --------------------
#

View File

@@ -56,6 +56,7 @@
#include "dialog.h"
#include "main.h"
#include "monitor.h"
#include "misc.h"
#include <WINGs/WUtil.h>
@@ -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;

View File

@@ -29,6 +29,9 @@
#ifdef KEEP_XKB_LOCK_STATUS
#include <X11/XKBlib.h>
#endif /* KEEP_XKB_LOCK_STATUS */
#ifdef USE_XRES
#include <X11/extensions/XRes.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -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