mirror of
https://github.com/0intro/wmii
synced 2024-11-22 22:02:30 +03:00
162 lines
3.2 KiB
C
162 lines
3.2 KiB
C
/* Copyright ©2008 Kris Maglione <fbsdaemon@gmail.com>
|
|
* See LICENSE file for license details.
|
|
*/
|
|
#include "hack.h"
|
|
#include <dlfcn.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <sys/time.h>
|
|
#include <sys/types.h>
|
|
#include <time.h>
|
|
#include <unistd.h>
|
|
|
|
#include "util.c"
|
|
#include "x11.c"
|
|
|
|
enum {
|
|
Timeout = 10,
|
|
};
|
|
|
|
static void* xlib;
|
|
|
|
static Window lastwin;
|
|
static long transient;
|
|
static Atom types[32];
|
|
static long ntypes;
|
|
static char** tags;
|
|
static long pid;
|
|
static long stime;
|
|
static char hostname[256];
|
|
static long nsec;
|
|
|
|
typedef Window (*mapfn)(Display*, Window);
|
|
|
|
static Window (*mapwindow)(Display*, Window);
|
|
static Window (*mapraised)(Display*, Window);
|
|
static Window (*unmapwindow)(Display*, Window);
|
|
static Window (*destroywindow)(Display*, Window);
|
|
|
|
static void
|
|
init(Display *d) { /* Hrm... assumes one display... */
|
|
char *toks[nelem(types)];
|
|
char *s, *p;
|
|
long n;
|
|
int i;
|
|
|
|
xlib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY);
|
|
if(xlib == nil)
|
|
return;
|
|
mapwindow = (mapfn)(uintptr_t)dlsym(xlib, "XMapWindow");
|
|
mapraised = (mapfn)(uintptr_t)dlsym(xlib, "XMapRaised");
|
|
unmapwindow = (mapfn)(uintptr_t)dlsym(xlib, "XUnmapWindow");
|
|
destroywindow = (mapfn)(uintptr_t)dlsym(xlib, "XDestroyWindow");
|
|
|
|
unsetenv("LD_PRELOAD");
|
|
|
|
if((s = getenv("WMII_HACK_TRANSIENT"))) {
|
|
if(getlong(s, &n))
|
|
transient = n;
|
|
unsetenv("WMII_HACK_TRANSIENT");
|
|
}
|
|
if((s = getenv("WMII_HACK_TYPE"))) {
|
|
s = strdup(s);
|
|
unsetenv("WMII_HACK_TYPE");
|
|
|
|
n = tokenize(toks, nelem(toks), s, ',');
|
|
for(i=0; i < n; i++) {
|
|
for(p=toks[i]; *p; p++)
|
|
if(*p >= 'a' && *p <= 'z')
|
|
*p += 'A' - 'a';
|
|
toks[i] = smprint("_NET_WM_WINDOW_TYPE_%s", toks[i]);
|
|
}
|
|
XInternAtoms(d, toks, n, False, types);
|
|
ntypes = n;
|
|
for(i=0; i < n; i++)
|
|
free(toks[i]);
|
|
free(s);
|
|
}
|
|
if((s = getenv("WMII_HACK_TAGS"))) {
|
|
s = strdup(s);
|
|
unsetenv("WMII_HACK_TAGS");
|
|
|
|
n = tokenize(toks, nelem(toks)-1, s, '+');
|
|
tags = strlistdup(toks, n);
|
|
free(s);
|
|
}
|
|
if((s = getenv("WMII_HACK_TIME"))) {
|
|
getlong(s, &stime);
|
|
unsetenv("WMII_HACK_TIME");
|
|
}
|
|
|
|
pid = getpid();
|
|
gethostname(hostname, sizeof hostname);
|
|
}
|
|
|
|
static void
|
|
setprops(Display *d, Window w) {
|
|
long *l;
|
|
|
|
if(!xlib)
|
|
init(d);
|
|
|
|
if(getprop_long(d, w, "_NET_WM_PID", "CARDINAL", 0L, &l, 1L))
|
|
free(l);
|
|
else {
|
|
changeprop_long(d, w, "_NET_WM_PID", "CARDINAL", &pid, 1);
|
|
changeprop_string(d, w, "WM_CLIENT_MACHINE", hostname);
|
|
}
|
|
|
|
/* Kludge. */
|
|
if(nsec == 0)
|
|
nsec = time(0);
|
|
else if(time(0) > nsec + Timeout)
|
|
return;
|
|
|
|
if(lastwin) {
|
|
free(tags);
|
|
getprop_textlist(d, lastwin, "_WMII_TAGS", &tags);
|
|
}
|
|
lastwin = w;
|
|
|
|
if(transient)
|
|
changeprop_long(d, w, "WM_TRANSIENT_FOR", "WINDOW", &transient, 1);
|
|
if(ntypes)
|
|
changeprop_long(d, w, "_NET_WM_WINDOW_TYPE", "ATOM", (long*)types, ntypes);
|
|
if(tags)
|
|
changeprop_textlist(d, w, "_WMII_TAGS", "UTF8_STRING", tags);
|
|
if(stime)
|
|
changeprop_long(d, w, "_WMII_LAUNCH_TIME", "CARDINAL", &stime, 1);
|
|
}
|
|
|
|
int
|
|
XMapWindow(Display *d, Window w) {
|
|
|
|
setprops(d, w);
|
|
return mapwindow(d, w);
|
|
}
|
|
|
|
int
|
|
XMapRaised(Display *d, Window w) {
|
|
|
|
setprops(d, w);
|
|
return mapraised(d, w);
|
|
}
|
|
|
|
/* These are not perfect. */
|
|
int
|
|
XUnmapWindow(Display *d, Window w) {
|
|
|
|
if(lastwin == w)
|
|
lastwin = 0;
|
|
return unmapwindow(d, w);
|
|
}
|
|
|
|
int
|
|
XDestroyWindow(Display *d, Window w) {
|
|
|
|
if(lastwin == w)
|
|
lastwin = 0;
|
|
return destroywindow(d, w);
|
|
}
|
|
|