added protocol killing stuff

This commit is contained in:
Anselm R. Garbe 2006-07-11 16:14:22 +02:00
parent 272e15c4b7
commit 3399650076
6 changed files with 153 additions and 36 deletions

View file

@ -10,8 +10,8 @@
#include "util.h" #include "util.h"
#include "wm.h" #include "wm.h"
static void void
update_client_name(Client *c) update_name(Client *c)
{ {
XTextProperty name; XTextProperty name;
int n; int n;
@ -37,6 +37,20 @@ update_client_name(Client *c)
XFree(name.value); XFree(name.value);
} }
void
focus(Client *c)
{
Client **l;
for(l=&stack; *l && *l != c; l=&(*l)->snext);
eassert(*l == c);
*l = c->snext;
c->snext = stack;
stack = c;
XRaiseWindow(dpy, c->win);
XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
XFlush(dpy);
}
void void
manage(Window w, XWindowAttributes *wa) manage(Window w, XWindowAttributes *wa)
{ {
@ -59,7 +73,7 @@ manage(Window w, XWindowAttributes *wa)
(c->size.flags & PMinSize && c->size.flags & PMaxSize (c->size.flags & PMinSize && c->size.flags & PMaxSize
&& c->size.min_width == c->size.max_width && c->size.min_width == c->size.max_width
&& c->size.min_height == c->size.max_height); && c->size.min_height == c->size.max_height);
update_client_name(c); update_name(c);
twa.override_redirect = 1; twa.override_redirect = 1;
twa.background_pixmap = ParentRelative; twa.background_pixmap = ParentRelative;
twa.event_mask = ExposureMask; twa.event_mask = ExposureMask;
@ -73,9 +87,10 @@ manage(Window w, XWindowAttributes *wa)
for(l=&clients; *l; l=&(*l)->next); for(l=&clients; *l; l=&(*l)->next);
c->next = *l; /* *l == nil */ c->next = *l; /* *l == nil */
*l = c; *l = c;
XMapRaised(dpy, c->win); c->snext = stack;
XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); stack = c;
XFlush(dpy); XMapWindow(dpy, c->win);
focus(c);
} }
static int static int
@ -98,12 +113,15 @@ unmanage(Client *c)
for(l=&clients; *l && *l != c; l=&(*l)->next); for(l=&clients; *l && *l != c; l=&(*l)->next);
eassert(*l == c); eassert(*l == c);
*l = c->next; *l = c->next;
for(l=&stack; *l && *l != c; l=&(*l)->snext);
eassert(*l == c);
*l = c->snext;
free(c); free(c);
XFlush(dpy); XFlush(dpy);
XSetErrorHandler(error_handler); XSetErrorHandler(error_handler);
XUngrabServer(dpy); XUngrabServer(dpy);
/*flush_masked_events(EnterWindowMask); ? */ flush_events(EnterWindowMask);
} }
@ -116,3 +134,4 @@ getclient(Window w)
return c; return c;
return NULL; return NULL;
} }

14
cmd.c
View file

@ -18,3 +18,17 @@ quit(char *arg)
fputs("quit\n", stderr); fputs("quit\n", stderr);
running = False; running = False;
} }
void
kill(char *arg)
{
Client *c = stack;
if(!c)
return;
if(c->proto & WM_PROTOCOL_DELWIN)
send_message(c->win, wm_atom[WMProtocols], wm_atom[WMDelete]);
else
XKillClient(dpy, c->win);
}

50
event.c
View file

@ -7,6 +7,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <X11/keysym.h> #include <X11/keysym.h>
#include <X11/Xatom.h>
#include "wm.h" #include "wm.h"
@ -35,7 +36,7 @@ void (*handler[LASTEvent]) (XEvent *) = {
}; };
unsigned int unsigned int
flush_masked_events(long even_mask) flush_events(long even_mask)
{ {
XEvent ev; XEvent ev;
unsigned int n = 0; unsigned int n = 0;
@ -91,25 +92,18 @@ destroynotify(XEvent *e)
static void static void
enternotify(XEvent *e) enternotify(XEvent *e)
{ {
#if 0
XCrossingEvent *ev = &e->xcrossing; XCrossingEvent *ev = &e->xcrossing;
Client *c; Client *c;
if(ev->mode != NotifyNormal || ev->detail == NotifyInferior) if(ev->mode != NotifyNormal || ev->detail == NotifyInferior)
return; return;
if((c = client_of_win(ev->window))) { if((c = getclient(ev->window)))
Frame *f = c->sel; focus(c);
Area *a = f->area;
if(a->mode == Colmax)
c = a->sel->client;
focus(c, False);
}
else if(ev->window == root) { else if(ev->window == root) {
sel_screen = True; sel_screen = True;
draw_frames(); /*draw_frames();*/
} }
#endif
} }
static void static void
@ -137,9 +131,7 @@ expose(XEvent *e)
static void static void
keymapnotify(XEvent *e) keymapnotify(XEvent *e)
{ {
#if 0
update_keys(); update_keys();
#endif
} }
static void static void
@ -164,16 +156,40 @@ maprequest(XEvent *e)
static void static void
propertynotify(XEvent *e) propertynotify(XEvent *e)
{ {
#if 0
XPropertyEvent *ev = &e->xproperty; XPropertyEvent *ev = &e->xproperty;
long msize;
Client *c; Client *c;
if(ev->state == PropertyDelete) if(ev->state == PropertyDelete)
return; /* ignore */ return; /* ignore */
if((c = client_of_win(ev->window))) if(ev->atom == wm_atom[WMProtocols]) {
prop_client(c, ev); c->proto = win_proto(c->win);
#endif return;
}
if((c = getclient(ev->window))) {
switch (ev->atom) {
default: break;
case XA_WM_TRANSIENT_FOR:
XGetTransientForHint(dpy, c->win, &c->trans);
break;
case XA_WM_NORMAL_HINTS:
if(!XGetWMNormalHints(dpy, c->win, &c->size, &msize)
|| !c->size.flags)
c->size.flags = PSize;
if(c->size.flags & PMinSize && c->size.flags & PMaxSize
&& c->size.min_width == c->size.max_width
&& c->size.min_height == c->size.max_height)
c->fixedsize = True;
else
c->fixedsize = False;
break;
}
if(ev->atom == XA_WM_NAME || ev->atom == net_atom[NetWMName]) {
update_name(c);
/*draw_frame(c->sel);*/
}
}
} }
static void static void

2
menu.c
View file

@ -304,7 +304,7 @@ kpress(XKeyEvent * e)
} }
break; break;
default: default:
if((num == 1) && !iscntrl((int) buf[0])) { if(num && !iscntrl((int) buf[0])) {
buf[num] = 0; buf[num] = 0;
if(len > 0) if(len > 0)
strncat(text, buf, sizeof(text)); strncat(text, buf, sizeof(text));

66
wm.c
View file

@ -16,18 +16,18 @@
/* X structs */ /* X structs */
Display *dpy; Display *dpy;
Window root, barwin; Window root, barwin;
Atom net_atom[NetLast]; Atom wm_atom[WMLast], net_atom[NetLast];
Cursor cursor[CurLast]; Cursor cursor[CurLast];
XRectangle rect, barrect; XRectangle rect, barrect;
Bool running = True; Bool running = True;
Bool sel_screen;
char *bartext, tag[256]; char *bartext, tag[256];
int screen, sel_screen; int screen;
Brush brush = {0}; Brush brush = {0};
Client *clients = NULL; Client *clients = NULL;
Client *stack = NULL;
enum { WM_PROTOCOL_DELWIN = 1 };
static Bool other_wm_running; static Bool other_wm_running;
static char version[] = "gridwm - " VERSION ", (C)opyright MMVI Anselm R. Garbe\n"; static char version[] = "gridwm - " VERSION ", (C)opyright MMVI Anselm R. Garbe\n";
@ -62,6 +62,62 @@ scan_wins()
XFree(wins); XFree(wins);
} }
static int
win_property(Window w, Atom a, Atom t, long l, unsigned char **prop)
{
Atom real;
int format;
unsigned long res, extra;
int status;
status = XGetWindowProperty(dpy, w, a, 0L, l, False, t, &real, &format,
&res, &extra, prop);
if(status != Success || *prop == 0) {
return 0;
}
if(res == 0) {
free((void *) *prop);
}
return res;
}
int
win_proto(Window w)
{
Atom *protocols;
long res;
int protos = 0;
int i;
res = win_property(w, wm_atom[WMProtocols], XA_ATOM, 20L,
((unsigned char **) &protocols));
if(res <= 0) {
return protos;
}
for(i = 0; i < res; i++) {
if(protocols[i] == wm_atom[WMDelete])
protos |= WM_PROTOCOL_DELWIN;
}
free((char *) protocols);
return protos;
}
void
send_message(Window w, Atom a, long value)
{
XEvent e;
e.type = ClientMessage;
e.xclient.window = w;
e.xclient.message_type = a;
e.xclient.format = 32;
e.xclient.data.l[0] = value;
e.xclient.data.l[1] = CurrentTime;
XSendEvent(dpy, w, False, NoEventMask, &e);
XFlush(dpy);
}
/* /*
* There's no way to check accesses to destroyed windows, thus * There's no way to check accesses to destroyed windows, thus
* those cases are ignored (especially on UnmapNotify's). * those cases are ignored (especially on UnmapNotify's).
@ -160,6 +216,8 @@ main(int argc, char *argv[])
x_error_handler = XSetErrorHandler(error_handler); x_error_handler = XSetErrorHandler(error_handler);
/* init atoms */ /* init atoms */
wm_atom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
wm_atom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
net_atom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); net_atom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
net_atom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); net_atom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);

24
wm.h
View file

@ -9,7 +9,10 @@
#include <X11/Xutil.h> #include <X11/Xutil.h>
#define WM_PROTOCOL_DELWIN 1
/* atoms */ /* atoms */
enum { WMProtocols, WMDelete, WMLast };
enum { NetSupported, NetWMName, NetLast }; enum { NetSupported, NetWMName, NetLast };
/* cursor */ /* cursor */
@ -25,6 +28,7 @@ struct Client {
char name[256]; char name[256];
char tag[256]; char tag[256];
unsigned int border; unsigned int border;
int proto;
Bool fixedsize; Bool fixedsize;
Window win; Window win;
Window trans; Window trans;
@ -44,18 +48,17 @@ struct Key {
extern Display *dpy; extern Display *dpy;
extern Window root, barwin; extern Window root, barwin;
extern Atom net_atom[NetLast]; extern Atom wm_atom[WMLast], net_atom[NetLast];
extern Cursor cursor[CurLast]; extern Cursor cursor[CurLast];
extern XRectangle rect, barrect; extern XRectangle rect, barrect;
extern Bool running; extern Bool running, sel_screen, grid;
extern Bool grid;
extern void (*handler[LASTEvent]) (XEvent *); extern void (*handler[LASTEvent]) (XEvent *);
extern int screen, sel_screen; extern int screen;
extern char *bartext, tag[256]; extern char *bartext, tag[256];
extern Brush brush; extern Brush brush;
extern Client *clients; extern Client *clients, *stack;
/* bar.c */ /* bar.c */
extern void draw_bar(); extern void draw_bar();
@ -66,8 +69,13 @@ extern void quit(char *arg);
/* client.c */ /* client.c */
extern void manage(Window w, XWindowAttributes *wa); extern void manage(Window w, XWindowAttributes *wa);
void unmanage(Client *c); extern void unmanage(Client *c);
extern Client * getclient(Window w); extern Client *getclient(Window w);
extern void focus(Client *c);
extern void update_name(Client *c);
/* event.c */
extern unsigned int flush_events(long even_mask);
/* key.c */ /* key.c */
extern void update_keys(); extern void update_keys();
@ -75,3 +83,5 @@ extern void keypress(XEvent *e);
/* wm.c */ /* wm.c */
extern int error_handler(Display *dpy, XErrorEvent *error); extern int error_handler(Display *dpy, XErrorEvent *error);
extern void send_message(Window w, Atom a, long value);
extern int win_proto(Window w);