mirror of
https://git.suckless.org/dwm
synced 2024-12-27 03:16:32 +00:00
added protocol killing stuff
This commit is contained in:
parent
272e15c4b7
commit
3399650076
6 changed files with 153 additions and 36 deletions
33
client.c
33
client.c
|
@ -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
14
cmd.c
|
@ -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
50
event.c
|
@ -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
2
menu.c
|
@ -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
66
wm.c
|
@ -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
24
wm.h
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue