added several other stuff

This commit is contained in:
Anselm R. Garbe 2006-07-10 22:16:48 +02:00
parent 2de59d0f09
commit 439e15d09f
12 changed files with 476 additions and 39 deletions

View file

@ -3,11 +3,11 @@
include config.mk include config.mk
WMSRC = wm.c draw.c util.c WMSRC = bar.c client.c draw.c event.c util.c wm.c
WMOBJ = ${WMSRC:.c=.o} WMOBJ = ${WMSRC:.c=.o}
MENSRC = menu.c draw.c util.c MENSRC = menu.c draw.c util.c
MENOBJ = ${MENSRC:.c=.o} MENOBJ = ${MENSRC:.c=.o}
MAN = gridwm.1 MAN1 = gridwm.1 gridmenu.1
BIN = gridwm gridmenu BIN = gridwm gridmenu
all: config gridwm gridmenu all: config gridwm gridmenu

18
bar.c Normal file
View file

@ -0,0 +1,18 @@
/*
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include "wm.h"
void
draw_bar()
{
brush.rect = barrect;
brush.rect.x = brush.rect.y = 0;
draw(dpy, &brush, False, 0);
XCopyArea(dpy, brush.drawable, barwin, brush.gc, 0, 0, barrect.width,
barrect.height, 0, 0);
XFlush(dpy);
}

89
client.c Normal file
View file

@ -0,0 +1,89 @@
/*
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include <string.h>
#include <X11/Xatom.h>
#include "util.h"
#include "wm.h"
static void
update_client_name(Client *c)
{
XTextProperty name;
int n;
char **list = 0;
name.nitems = 0;
c->name[0] = 0;
XGetTextProperty(dpy, c->win, &name, net_atom[NetWMName]);
if(!name.nitems)
XGetWMName(dpy, c->win, &name);
if(!name.nitems)
return;
if(name.encoding == XA_STRING)
strncpy(c->name, (char *)name.value, sizeof(c->name));
else {
if(XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success
&& n > 0 && *list)
{
strncpy(c->name, *list, sizeof(c->name));
XFreeStringList(list);
}
}
XFree(name.value);
}
Client *
create_client(Window w, XWindowAttributes *wa)
{
Client *c;
XSetWindowAttributes twa;
long msize;
c = emallocz(sizeof(Client));
c->win = w;
c->r[RFloat].x = wa->x;
c->r[RFloat].y = wa->y;
c->r[RFloat].width = wa->width;
c->r[RFloat].height = wa->height;
c->border = wa->border_width;
XSetWindowBorderWidth(dpy, c->win, 0);
c->proto = win_proto(c->win);
XGetTransientForHint(dpy, c->win, &c->trans);
if(!XGetWMNormalHints(dpy, c->win, &c->size, &msize) || !c->size.flags)
c->size.flags = PSize;
c->fixedsize =
(c->size.flags & PMinSize && c->size.flags & PMaxSize
&& c->size.min_width == c->size.max_width
&& c->size.min_height == c->size.max_height);
XAddToSaveSet(dpy, c->win);
update_client_name(c);
twa.override_redirect = 1;
twa.background_pixmap = ParentRelative;
twa.event_mask = ExposureMask;
c->title = XCreateWindow(dpy, root, c->r[RFloat].x, c->r[RFloat].y,
c->r[RFloat].width, barrect.height, 0,
DefaultDepth(dpy, screen), CopyFromParent,
DefaultVisual(dpy, screen),
CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa);
XFlush(dpy);
#if 0
for(t=&client, i=0; *t; t=&(*t)->next, i++);
c->next = *t; /* *t == nil */
*t = c;
#endif
return c;
}
void
manage(Client *c)
{
XMapRaised(dpy, c->win);
XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
XFlush(dpy);
}

View file

@ -4,6 +4,6 @@
*/ */
#define FONT "-*-terminus-medium-*-*-*-14-*-*-*-*-*-iso10646-*" #define FONT "-*-terminus-medium-*-*-*-14-*-*-*-*-*-iso10646-*"
#define FGCOLOR "#000000" #define BGCOLOR "#000000"
#define BGCOLOR "#ffaa00" #define FGCOLOR "#ffaa00"
#define BORDERCOLOR "#000000" #define BORDERCOLOR "#000000"

6
draw.c
View file

@ -162,3 +162,9 @@ loadfont(Display *dpy, Fnt *font, const char *fontstr)
} }
font->height = font->ascent + font->descent; font->height = font->ascent + font->descent;
} }
unsigned int
labelheight(Fnt *font)
{
return font->height + 4;
}

1
draw.h
View file

@ -33,3 +33,4 @@ extern void loadcolors(Display *dpy, int screen, Brush *b,
extern void loadfont(Display *dpy, Fnt *font, const char *fontstr); extern void loadfont(Display *dpy, Fnt *font, const char *fontstr);
extern unsigned int textwidth_l(Fnt *font, char *text, unsigned int len); extern unsigned int textwidth_l(Fnt *font, char *text, unsigned int len);
extern unsigned int textwidth(Fnt *font, char *text); extern unsigned int textwidth(Fnt *font, char *text);
extern unsigned int labelheight(Fnt *font);

264
event.c Normal file
View file

@ -0,0 +1,264 @@
/*
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <X11/keysym.h>
#include "wm.h"
/* local functions */
static void configurerequest(XEvent *e);
static void destroynotify(XEvent *e);
static void enternotify(XEvent *e);
static void leavenotify(XEvent *e);
static void expose(XEvent *e);
static void keypress(XEvent *e);
static void keymapnotify(XEvent *e);
static void maprequest(XEvent *e);
static void propertynotify(XEvent *e);
static void unmapnotify(XEvent *e);
void (*handler[LASTEvent]) (XEvent *) = {
[ConfigureRequest] = configurerequest,
[DestroyNotify] = destroynotify,
[EnterNotify] = enternotify,
[LeaveNotify] = leavenotify,
[Expose] = expose,
[KeyPress] = keypress,
[KeymapNotify] = keymapnotify,
[MapRequest] = maprequest,
[PropertyNotify] = propertynotify,
[UnmapNotify] = unmapnotify
};
unsigned int
flush_masked_events(long even_mask)
{
XEvent ev;
unsigned int n = 0;
while(XCheckMaskEvent(dpy, even_mask, &ev)) n++;
return n;
}
static void
configurerequest(XEvent *e)
{
#if 0
XConfigureRequestEvent *ev = &e->xconfigurerequest;
XWindowChanges wc;
XRectangle *frect;
Client *c;
c = client_of_win(ev->window);
ev->value_mask &= ~CWSibling;
if(c) {
gravitate_client(c, True);
if(ev->value_mask & CWX)
c->rect.x = ev->x;
if(ev->value_mask & CWY)
c->rect.y = ev->y;
if(ev->value_mask & CWWidth)
c->rect.width = ev->width;
if(ev->value_mask & CWHeight)
c->rect.height = ev->height;
if(ev->value_mask & CWBorderWidth)
c->border = ev->border_width;
gravitate_client(c, False);
if(c->frame) {
if(c->sel->area->floating)
frect=&c->sel->rect;
else
frect=&c->sel->revert;
if(c->rect.width >= screen->rect.width && c->rect.height >= screen->rect.height) {
frect->y = wc.y = -height_of_bar();
frect->x = wc.x = -def.border;
}
else {
frect->y = wc.y = c->rect.y - height_of_bar();
frect->x = wc.x = c->rect.x - def.border;
}
frect->width = wc.width = c->rect.width + 2 * def.border;
frect->height = wc.height = c->rect.height + def.border
+ height_of_bar();
wc.border_width = 1;
wc.sibling = None;
wc.stack_mode = ev->detail;
if(c->sel->area->view != screen->sel)
wc.x += 2 * screen->rect.width;
if(c->sel->area->floating) {
XConfigureWindow(dpy, c->framewin, ev->value_mask, &wc);
configure_client(c);
}
}
}
wc.x = ev->x;
wc.y = ev->y;
wc.width = ev->width;
wc.height = ev->height;
if(c && c->frame) {
wc.x = def.border;
wc.y = height_of_bar();
wc.width = c->sel->rect.width - 2 * def.border;
wc.height = c->sel->rect.height - def.border - height_of_bar();
}
wc.border_width = 0;
wc.sibling = None;
wc.stack_mode = Above;
ev->value_mask &= ~CWStackMode;
ev->value_mask |= CWBorderWidth;
XConfigureWindow(dpy, ev->window, ev->value_mask, &wc);
XFlush(dpy);
#endif
}
static void
destroynotify(XEvent *e)
{
#if 0
Client *c;
XDestroyWindowEvent *ev = &e->xdestroywindow;
if((c = client_of_win(ev->window)))
destroy_client(c);
#endif
}
static void
enternotify(XEvent *e)
{
#if 0
XCrossingEvent *ev = &e->xcrossing;
Client *c;
if(ev->mode != NotifyNormal || ev->detail == NotifyInferior)
return;
if((c = client_of_win(ev->window))) {
Frame *f = c->sel;
Area *a = f->area;
if(a->mode == Colmax)
c = a->sel->client;
focus(c, False);
}
else if(ev->window == root) {
sel_screen = True;
draw_frames();
}
#endif
}
static void
leavenotify(XEvent *e)
{
XCrossingEvent *ev = &e->xcrossing;
if((ev->window == root) && !ev->same_screen) {
sel_screen = True;
/*draw_frames();*/
}
}
static void
expose(XEvent *e)
{
XExposeEvent *ev = &e->xexpose;
if(ev->count == 0) {
if(ev->window == barwin)
draw_bar();
}
}
static void
keypress(XEvent *e)
{
#if 0
XKeyEvent *ev = &e->xkey;
KeySym k = 0;
char buf[32];
int n;
static Frame *f;
ev->state &= valid_mask;
if((f = frame_of_win(ev->window))) {
buf[0] = 0;
n = XLookupString(ev, buf, sizeof(buf), &k, 0);
if(IsFunctionKey(k) || IsKeypadKey(k) || IsMiscFunctionKey(k)
|| IsPFKey(k) || IsPrivateKeypadKey(k))
return;
buf[n] = 0;
blitz_kpress_input(&f->tagbar, ev->state, k, buf);
}
else
key(root, ev->state, (KeyCode) ev->keycode);
#endif
}
static void
keymapnotify(XEvent *e)
{
#if 0
update_keys();
#endif
}
static void
maprequest(XEvent *e)
{
#if 0
XMapRequestEvent *ev = &e->xmaprequest;
static XWindowAttributes wa;
if(!XGetWindowAttributes(dpy, ev->window, &wa))
return;
if(wa.override_redirect) {
XSelectInput(dpy, ev->window,
(StructureNotifyMask | PropertyChangeMask));
return;
}
if(!client_of_win(ev->window))
manage_client(create_client(ev->window, &wa));
#endif
}
static void
propertynotify(XEvent *e)
{
#if 0
XPropertyEvent *ev = &e->xproperty;
Client *c;
if(ev->state == PropertyDelete)
return; /* ignore */
if((c = client_of_win(ev->window)))
prop_client(c, ev);
#endif
}
static void
unmapnotify(XEvent *e)
{
#if 0
Client *c;
XUnmapEvent *ev = &e->xunmap;
if((c = client_of_win(ev->window)))
destroy_client(c);
#endif
}

9
menu.c
View file

@ -53,7 +53,7 @@ static const int seek = 30; /* 30px */
static Brush brush = {0}; static Brush brush = {0};
static void draw_menu(void); static void draw_menu();
static void kpress(XKeyEvent * e); static void kpress(XKeyEvent * e);
static char version[] = "gridmenu - " VERSION ", (C)opyright MMVI Anselm R. Garbe\n"; static char version[] = "gridmenu - " VERSION ", (C)opyright MMVI Anselm R. Garbe\n";
@ -397,11 +397,10 @@ main(int argc, char *argv[])
wa.override_redirect = 1; wa.override_redirect = 1;
wa.background_pixmap = ParentRelative; wa.background_pixmap = ParentRelative;
wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask;
| SubstructureRedirectMask | SubstructureNotifyMask;
rect.width = DisplayWidth(dpy, screen); rect.width = DisplayWidth(dpy, screen);
rect.height = brush.font.height + 4; rect.height = labelheight(&brush.font);
rect.y = DisplayHeight(dpy, screen) - rect.height; rect.y = DisplayHeight(dpy, screen) - rect.height;
rect.x = 0; rect.x = 0;
@ -413,7 +412,7 @@ main(int argc, char *argv[])
XFlush(dpy); XFlush(dpy);
/* pixmap */ /* pixmap */
brush.gc = XCreateGC(dpy, win, 0, 0); brush.gc = XCreateGC(dpy, root, 0, 0);
brush.drawable = XCreatePixmap(dpy, win, rect.width, rect.height, brush.drawable = XCreatePixmap(dpy, win, rect.width, rect.height,
DefaultDepth(dpy, screen)); DefaultDepth(dpy, screen));
XFlush(dpy); XFlush(dpy);

23
util.c
View file

@ -7,6 +7,11 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include "util.h"
void void
error(char *errstr, ...) { error(char *errstr, ...) {
@ -75,3 +80,21 @@ swap(void **p1, void **p2)
*p1 = *p2; *p1 = *p2;
*p2 = tmp; *p2 = tmp;
} }
void
spawn(Display *dpy, const char *shell, const char *cmd)
{
if(!cmd || !shell)
return;
if(fork() == 0) {
if(fork() == 0) {
if(dpy)
close(ConnectionNumber(dpy));
execl(shell, shell, "-c", cmd, (const char *)0);
fprintf(stderr, "gridwm: execl %s", shell);
perror(" failed");
}
exit (0);
}
wait(0);
}

6
util.h
View file

@ -2,6 +2,7 @@
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details. * See LICENSE file for license details.
*/ */
#include <X11/Xlib.h>
extern void error(char *errstr, ...); extern void error(char *errstr, ...);
extern void *emallocz(unsigned int size); extern void *emallocz(unsigned int size);
@ -12,5 +13,6 @@ extern char *estrdup(const char *str);
if(!(a)) \ if(!(a)) \
failed_assert(#a, __FILE__, __LINE__); \ failed_assert(#a, __FILE__, __LINE__); \
} while (0) } while (0)
void failed_assert(char *a, char *file, int line); extern void failed_assert(char *a, char *file, int line);
void swap(void **p1, void **p2); extern void swap(void **p1, void **p2);
extern void spawn(Display *dpy, const char *shell, const char *cmd);

51
wm.c
View file

@ -15,15 +15,15 @@
/* X structs */ /* X structs */
Display *dpy; Display *dpy;
Window root; Window root, barwin;
XRectangle rect; Atom wm_atom[WMLast], net_atom[NetLast];
Pixmap pmap;
Atom wm_atom[WMLast];
Atom net_atom[NetLast];
Cursor cursor[CurLast]; Cursor cursor[CurLast];
XRectangle rect, barrect;
Bool running = True;
char *bartext, *shell;
int screen, sel_screen; int screen, sel_screen;
unsigned int kmask, numlock_mask; unsigned int lock_mask, numlock_mask;
/* draw structs */ /* draw structs */
Brush brush = {0}; Brush brush = {0};
@ -166,7 +166,7 @@ init_lock_keys()
} }
XFreeModifiermap(modmap); XFreeModifiermap(modmap);
kmask = 255 & ~(numlock_mask | LockMask); lock_mask = 255 & ~(numlock_mask | LockMask);
} }
static void static void
@ -187,6 +187,7 @@ main(int argc, char *argv[])
XSetWindowAttributes wa; XSetWindowAttributes wa;
unsigned int mask; unsigned int mask;
Window w; Window w;
XEvent ev;
/* command line args */ /* command line args */
for(i = 1; (i < argc) && (argv[i][0] == '-'); i++) { for(i = 1; (i < argc) && (argv[i][0] == '-'); i++) {
@ -218,6 +219,9 @@ main(int argc, char *argv[])
if(other_wm_running) if(other_wm_running)
error("gridwm: another window manager is already running\n"); error("gridwm: another window manager is already running\n");
if(!(shell = getenv("SHELL")))
shell = "/bin/sh";
rect.x = rect.y = 0; rect.x = rect.y = 0;
rect.width = DisplayWidth(dpy, screen); rect.width = DisplayWidth(dpy, screen);
rect.height = DisplayHeight(dpy, screen); rect.height = DisplayHeight(dpy, screen);
@ -244,19 +248,42 @@ main(int argc, char *argv[])
init_lock_keys(); init_lock_keys();
pmap = XCreatePixmap(dpy, root, rect.width, rect.height, brush.drawable = XCreatePixmap(dpy, root, rect.width, rect.height,
DefaultDepth(dpy, screen)); DefaultDepth(dpy, screen));
brush.gc = XCreateGC(dpy, root, 0, 0);
wa.event_mask = SubstructureRedirectMask | EnterWindowMask | LeaveWindowMask;
wa.cursor = cursor[CurNormal];
XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa);
/* style */ /* style */
loadcolors(dpy, screen, &brush, BGCOLOR, FGCOLOR, BORDERCOLOR); loadcolors(dpy, screen, &brush, BGCOLOR, FGCOLOR, BORDERCOLOR);
loadfont(dpy, &brush.font, FONT); loadfont(dpy, &brush.font, FONT);
wa.override_redirect = 1;
wa.background_pixmap = ParentRelative;
wa.event_mask = ExposureMask;
barrect = rect;
barrect.height = labelheight(&brush.font);
barrect.y = rect.height - barrect.height;
barwin = XCreateWindow(dpy, root, barrect.x, barrect.y,
barrect.width, barrect.height, 0, DefaultDepth(dpy, screen),
CopyFromParent, DefaultVisual(dpy, screen),
CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);
bartext = 0;
XDefineCursor(dpy, barwin, cursor[CurNormal]);
XMapRaised(dpy, barwin);
draw_bar();
wa.event_mask = SubstructureRedirectMask | EnterWindowMask | LeaveWindowMask;
wa.cursor = cursor[CurNormal];
XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa);
scan_wins(); scan_wins();
while(running) {
XNextEvent(dpy, &ev);
if(handler[ev.type])
(handler[ev.type]) (&ev); /* call handler */
}
cleanup(); cleanup();
XCloseDisplay(dpy); XCloseDisplay(dpy);

40
wm.h
View file

@ -9,16 +9,14 @@
#include <X11/Xutil.h> #include <X11/Xutil.h>
/* WM atoms */ /* atoms */
enum { WMState, WMProtocols, WMDelete, WMLast }; enum { WMState, WMProtocols, WMDelete, WMLast };
/* NET atoms */
enum { NetSupported, NetWMName, NetLast }; enum { NetSupported, NetWMName, NetLast };
/* Cursor */ /* cursor */
enum { CurNormal, CurResize, CurMove, CurInput, CurLast }; enum { CurNormal, CurResize, CurMove, CurInput, CurLast };
/* Rects */ /* rects */
enum { RFloat, RGrid, RLast }; enum { RFloat, RGrid, RLast };
typedef struct Client Client; typedef struct Client Client;
@ -28,35 +26,45 @@ struct Client {
Tag *tag; Tag *tag;
char name[256]; char name[256];
int proto; int proto;
unsigned int border;
Bool fixedsize;
Window win; Window win;
Window trans; Window trans;
Window title; Window title;
GC gc;
XSizeHints size; XSizeHints size;
XRectangle r[RLast]; XRectangle r[RLast];
Client *next; Client *next;
Client *tnext; Client *snext;
Client *tprev;
}; };
struct Tag { struct Tag {
char name[256]; char name[256];
Client *clients; Client *stack;
Client *sel;
XRectangle r; XRectangle r;
Tag *next;
Tag *cnext;
}; };
extern Display *dpy; extern Display *dpy;
extern Window root; extern Window root, barwin;
extern XRectangle rect; extern Atom wm_atom[WMLast], net_atom[NetLast];
extern Atom wm_atom[WMLast];
extern Atom net_atom[NetLast];
extern Cursor cursor[CurLast]; extern Cursor cursor[CurLast];
extern Pixmap pmap; extern XRectangle rect, barrect;
extern Bool running;
extern void (*handler[LASTEvent]) (XEvent *);
extern int screen, sel_screen; extern int screen, sel_screen;
extern unsigned int kmask, numlock_mask; extern unsigned int lock_mask, numlock_mask;
extern char *bartext, *shell;
extern Brush brush; extern Brush brush;
/* bar.c */
extern void draw_bar();
/* client.c */
extern Client *create_client(Window w, XWindowAttributes *wa);
extern void manage(Client *c);
/* wm.c */ /* wm.c */
extern int win_proto(Window w);