focus fixes, add focus on motion, add structs and functions for keyboard config, cleaned up keypress_handler

This commit is contained in:
Akos Horvath 2022-08-18 17:34:02 +02:00
parent ca69dc89d1
commit 30cf32f830
2 changed files with 346 additions and 227 deletions

524
wm.c
View File

@ -10,6 +10,7 @@
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
Monitor wm_monitor_open(Display *d, XineramaScreenInfo info)
{
@ -214,26 +215,17 @@ void wm_configure_handler(XConfigureRequestEvent e)
DEBUG_PRINT("ConfigureRequest handler: window %d has property %s\n",
(int)e.window, XGetAtomName(wm_display, ((Atom*)prop_ret)[i]));
if (strcmp(XGetAtomName(wm_display, ((Atom*)prop_ret)[i]),
"_NET_WM_WINDOW_TYPE_NORMAL") == 0) {
"_NET_WM_WINDOW_TYPE_NORMAL") == 0) {
is_normal = true;
} else if (strcmp(XGetAtomName(wm_display, ((Atom*)prop_ret)[i]),
"_NET_WM_WINDOW_TYPE_DOCK") == 0) {
"_NET_WM_WINDOW_TYPE_DOCK") == 0) {
wm_dock = e.window;
} else if (strcmp(XGetAtomName(wm_display, ((Atom*)prop_ret)[i]),
"_NET_WM_WINDOW_TYPE_DIALOG") == 0) {
c->is_floating = true;
}
}
/*
_NET_WM_WINDOW_TYPE_NORMAL indicates that this is a normal,
top-level window, [...] windows without _NET_WM_WINDOW_TYPE,
must be taken as this type [...]
https://specifications.freedesktop.org/wm-spec
*/
if (type == None) {
DEBUG_PRINT("Atom %s does not exist for window.\n", name)
// is_normal = true;
}
if (!is_normal) {
DEBUG_PRINT("configure handler: window %d is not normal, returning\n",
(int)e.window)
@ -241,38 +233,7 @@ void wm_configure_handler(XConfigureRequestEvent e)
return;
}
// wm_client_is_dock(nc);
wm_mstack(c->m);
// wm_client_is_dock(wm_client_find(e.window));
// Client *c;
// XWindowChanges ch;
// int cc_sws = 0;
// // for (c = wm_smon->clients; c; c = c->next) {
// // if (c->ws == wm_smon->selws) {
// // cc_sws++;
// // }
// // }
// c = wm_client_find(e.window);
// // // dynamic
// // if (cc_sws == 0) {
// // c->x = 0;
// // c->y = 0;
// // c->w = wm_smon->info.width;
// // c->h = wm_smon->info.height;
// // }
// // else {
// // // TODO
// // // c.x = m.h / cc_sws;
// // }
// // XConfigureWindow(wm_display, c->window, e.value_mask, &ch);
//
// wm_layout(c->m);
wm_layout(c->m);
}
void wm_keyrelease_handler(XKeyReleasedEvent e)
@ -284,98 +245,103 @@ void wm_keypress_handler(XKeyPressedEvent e)
{
DEBUG_PRINT("KeyPressed event, code: %d\n", e.keycode)
Client *c;
Keybind k;
// TODO: bad code below: need to implement key structure with keysyms,
// and functions to be ran for clarity and configurabilty
// TODO: fix focusing left from master!
switch (e.state) {
case (Mod4Mask):
DEBUG_PRINT("mod4\n")
// cant use switch
// if (e.keycode == XKeysymToKeycode(e.display, XK_C)) {
// DEBUG_PRINT("Kill key combination\n")
//
// if ((c = wm_client_get_focused()) != NULL) {
// DEBUG_PRINT("kill client: 0x%x\n", c);
// wm_client_kill(c);
// }
// }
switch (XLookupKeysym(&e, 0)) {
case XK_c:
DEBUG_PRINT("Kill key combination\n")
if ((c = wm_client_get_focused()) != NULL) {
DEBUG_PRINT("kill client: 0x%x\n", c);
wm_client_kill(c);
}
break;
case XK_Return:
if (fork() == 0) {
if (wm_display)
close(ConnectionNumber(wm_display));
setsid();
//char *arg[] = {"-t", "Terminal", NULL};
execvp("st", NULL);
exit(0);
}
break;
case XK_h:
wm_client_focus_dir(wm_client_get_focused(), LEFT);
break;
case XK_j:
wm_client_focus_dir(wm_client_get_focused(), DOWN);
break;
case XK_k:
wm_client_focus_dir(wm_client_get_focused(), UP);
break;
case XK_l:
wm_client_focus_dir(wm_client_get_focused(), RIGHT);
break;
case XK_1:
DEBUG_PRINT("wm_switch_ws keycode, ws: %d\n", 0)
wm_switch_ws(0);
break;
case XK_2:
DEBUG_PRINT("wm_switch_ws keycode, ws: %d\n", 1)
wm_switch_ws(1);
break;
case XK_3:
DEBUG_PRINT("wm_switch_ws keycode, ws: %d\n", 2)
wm_switch_ws(2);
break;
case XK_4:
DEBUG_PRINT("wm_switch_ws keycode, ws: %d\n", 3)
wm_switch_ws(3);
break;
case XK_5:
DEBUG_PRINT("wm_switch_ws keycode, ws: %d\n", 4)
wm_switch_ws(4);
break;
case XK_6:
DEBUG_PRINT("wm_switch_ws keycode, ws: %d\n", 5)
wm_switch_ws(5);
break;
case XK_7:
DEBUG_PRINT("wm_switch_ws keycode, ws: %d\n", 6)
wm_switch_ws(6);
break;
case XK_8:
DEBUG_PRINT("wm_switch_ws keycode, ws: %d\n", 7)
wm_switch_ws(7);
break;
case XK_9:
DEBUG_PRINT("wm_switch_ws keycode, ws: %d\n", 8)
wm_switch_ws(8);
break;
default:
DEBUG_PRINT("wm_handle_keys default\n")
char *buf;
KeySym k;
XLookupString(&e, buf, 50, &k, NULL);
DEBUG_PRINT("default keysym: %s\n", buf)
DEBUG_PRINT("default keysym i: %d\n", k)
}
break;
for (int i = 0; i < wm_cfg_kb_count; i++) {
k = wm_cfg_keybinds[i];
if (k.mask == e.state && k.keysym == XLookupKeysym(&e, 0))
{
(*k.func)(&k.args);
}
}
// switch (e.state) {
// case (Mod4Mask):
// DEBUG_PRINT("mod4\n")
// // cant use switch
// // if (e.keycode == XKeysymToKeycode(e.display, XK_C)) {
// // DEBUG_PRINT("Kill key combination\n")
// //
// // if ((c = wm_client_get_focused()) != NULL) {
// // DEBUG_PRINT("kill client: 0x%x\n", c);
// // wm_client_kill(c);
// // }
// // }
// switch (XLookupKeysym(&e, 0)) {
// case XK_c:
// DEBUG_PRINT("Kill key combination\n")
// if ((c = wm_client_get_focused()) != NULL) {
// DEBUG_PRINT("kill client: 0x%x\n", c);
// wm_client_kill(c);
// }
// break;
// case XK_Return:
// if (fork() == 0) {
// if (wm_display)
// close(ConnectionNumber(wm_display));
// setsid();
// //char *arg[] = {"-t", "Terminal", NULL};
// execvp("st", NULL);
// exit(0);
// }
// break;
// case XK_h:
// wm_client_focus_dir(wm_client_get_focused(), LEFT);
// break;
// case XK_j:
// wm_client_focus_dir(wm_client_get_focused(), DOWN);
// break;
// case XK_k:
// wm_client_focus_dir(wm_client_get_focused(), UP);
// break;
// case XK_l:
// wm_client_focus_dir(wm_client_get_focused(), RIGHT);
// break;
// case XK_1:
// DEBUG_PRINT("wm_switch_ws keycode, ws: %d\n", 0)
// wm_switch_ws(0);
// break;
// case XK_2:
// DEBUG_PRINT("wm_switch_ws keycode, ws: %d\n", 1)
// wm_switch_ws(1);
// break;
// case XK_3:
// DEBUG_PRINT("wm_switch_ws keycode, ws: %d\n", 2)
// wm_switch_ws(2);
// break;
// case XK_4:
// DEBUG_PRINT("wm_switch_ws keycode, ws: %d\n", 3)
// wm_switch_ws(3);
// break;
// case XK_5:
// DEBUG_PRINT("wm_switch_ws keycode, ws: %d\n", 4)
// wm_switch_ws(4);
// break;
// case XK_6:
// DEBUG_PRINT("wm_switch_ws keycode, ws: %d\n", 5)
// wm_switch_ws(5);
// break;
// case XK_7:
// DEBUG_PRINT("wm_switch_ws keycode, ws: %d\n", 6)
// wm_switch_ws(6);
// break;
// case XK_8:
// DEBUG_PRINT("wm_switch_ws keycode, ws: %d\n", 7)
// wm_switch_ws(7);
// break;
// case XK_9:
// DEBUG_PRINT("wm_switch_ws keycode, ws: %d\n", 8)
// wm_switch_ws(8);
// break;
// default:
// DEBUG_PRINT("wm_handle_keys default\n")
// char *buf;
// KeySym k;
// XLookupString(&e, buf, 50, &k, NULL);
// DEBUG_PRINT("default keysym: %s\n", buf)
// DEBUG_PRINT("default keysym i: %d\n", k)
// }
// break;
// }
}
void wm_maprequest_handler(XMapRequestEvent e)
@ -404,7 +370,18 @@ void wm_maprequest_handler(XMapRequestEvent e)
c = wm_client_create(e.window);
RETURN_IF_NULL(c)
//XMapWindow(wm_display, c->window);
wm_mstack(c->m);
wm_layout(c->m);
}
void wm_motion_handler(XMotionEvent e)
{
Client *c;
c = wm_client_find(e.window);
RETURN_IF_NULL(c)
if(!wm_client_is_focused(c) && wm_cfg_focus_on_motion)
wm_client_focus(c);
}
// TODO
@ -438,6 +415,10 @@ Client* wm_client_create(Window w)
{
Client *c = NULL;
Client *t;
XTextProperty xtp;
int strln;
XGetWMName(wm_display, w, &xtp);
c = malloc(sizeof(Client));
@ -445,6 +426,14 @@ Client* wm_client_create(Window w)
c->m = wm_smon;
c->ws = wm_smon->selws;
c->hidden = true;
c->is_floating = false;
if (xtp.value) {
strln = strlen((char*)xtp.value);
DEBUG_PRINT("%s allocating %d bytes for c->name", __func__, strln)
c->name = malloc(strln+1);
strcpy(c->name, (char*)xtp.value);
}
if (wm_smon->clients == NULL) {
wm_smon->clients = c;
@ -457,7 +446,10 @@ Client* wm_client_create(Window w)
c->next = NULL;
}
XSelectInput(wm_display, c->window, FocusChangeMask | EnterWindowMask);
XSelectInput(wm_display, c->window, FocusChangeMask | EnterWindowMask |
PointerMotionMask);
wm_client_set_atom(c, "_NET_WM_DESKTOP", (unsigned char*)&c->ws, XA_CARDINAL, 1);
return c;
}
@ -549,7 +541,7 @@ void wm_client_kill(Client *c)
XDestroyWindow(wm_display, c->window);
wm_client_free(c);
wm_mstack(m);
wm_layout(m);
}
void wm_client_set_atom(Client *c, const char* name, const unsigned char *data,
@ -652,7 +644,7 @@ Client* wm_client_get_dir_rel_c(Client *c, int dir)
for (r = c->m->clients; r; r = r->next) {
if ((x > r->x && x < r->x+r->w) && (y > r->y && y < r->y+r->h)) {
DEBUG_PRINT("%s ", __func__)
DEBUG_PRINT("found window %d in direction ", c->window)
DEBUG_PRINT("found window %d in direction ", (int)c->window)
DEBUG_PRINT("%d\n", dir)
return r;
}
@ -678,26 +670,19 @@ Client* wm_client_get_focused()
void wm_client_border(Client *c)
{
// DEBUG_PRINT("%s\n", __func__);
RETURN_IF_NULL(c);
// if (c->has_border)
// return;
// TODO: color config
XVisualInfo vinfo;
XColor color;
XColor fcolor;
Colormap cmap;
char *colorstr = "#555555";
char *focuscolorstr = "#FF0000";
XMatchVisualInfo(wm_display, DefaultScreen(wm_display), 32,
TrueColor, &vinfo);
cmap = XCreateColormap(wm_display, c->window, vinfo.visual, AllocNone);
XParseColor(wm_display, cmap, focuscolorstr, &fcolor);
XParseColor(wm_display, cmap, colorstr, &color);
XParseColor(wm_display, cmap, wm_cfg_focused_border_col, &fcolor);
XParseColor(wm_display, cmap, wm_cfg_border_col, &color);
XAllocColor(wm_display, cmap, &fcolor);
XAllocColor(wm_display, cmap, &color);
@ -707,18 +692,18 @@ void wm_client_border(Client *c)
// DEBUG_PRINT("wm_client_border window: %d\n", c->window)
}
XSetWindowBorderWidth(wm_display, c->window, wm_border_width);
XSetWindowBorderWidth(wm_display, c->window, wm_cfg_border_width);
// DEBUG_PRINT("drawing border for: %d\n", c->window);
if (wm_client_is_focused(c)) {
DEBUG_PRINT("drawing focused border for: %d\n", c->window);
DEBUG_PRINT("drawing focused border for: %d\n", (int)c->window);
XSetWindowBorder(wm_display, c->window, fcolor.pixel);
}
else
XSetWindowBorder(wm_display, c->window, color.pixel);
}
// TODO maybe merge two border functios
// FIXME probably unused
void wm_client_border_focused(Client *c)
{
RETURN_IF_NULL(c);
@ -727,18 +712,17 @@ void wm_client_border_focused(Client *c)
XVisualInfo vinfo;
XColor fcolor;
Colormap cmap;
char *focuscolorstr = "#FF0000";
XMatchVisualInfo(wm_display, DefaultScreen(wm_display), 32,
TrueColor, &vinfo);
cmap = XCreateColormap(wm_display, c->window, vinfo.visual, AllocNone);
XParseColor(wm_display, cmap, focuscolorstr, &fcolor);
XParseColor(wm_display, cmap, wm_cfg_focused_border_col, &fcolor);
XAllocColor(wm_display, cmap, &fcolor);
XSetWindowBorderWidth(wm_display, c->window, wm_border_width);
XSetWindowBorderWidth(wm_display, c->window, wm_cfg_border_width);
DEBUG_PRINT("drawing border for focused window: %d\n", c->window);
DEBUG_PRINT("drawing border for focused window: %d\n", (int)c->window);
XSetWindowBorder(wm_display, c->window, fcolor.pixel);
}
@ -844,7 +828,7 @@ void wm_switch_ws(int ws)
wm_smon->selws = ws;
wm_client_set_atom(c, "_NET_CURRENT_DESKTOP", (unsigned char*) &(ws),
wm_client_set_atom(&wm_root, "_NET_CURRENT_DESKTOP", (unsigned char*) &(ws),
XA_CARDINAL, 1);
// XChangeProperty(wm_display, wm_root.window,
// XInternAtom(wm_display, "_NET_CURRENT_DESKTOP", False), XA_CARDINAL,
@ -873,10 +857,13 @@ void wm_mstack(Monitor *m)
int sx = 0;
int sy = 0;
XTextProperty xt;
XEvent e;
unsigned int value_mask = CWX | CWY | CWWidth | CWHeight;
// TODO: function
// FIXME: &wm_root probably wrong
if (wm_dock != -1) {
XWindowAttributes x;
@ -889,7 +876,7 @@ void wm_mstack(Monitor *m)
}
for (c = m->clients; c; c = c->next) {
if (c->ws == m->selws && c != &wm_root) {
if (c->ws == m->selws && c != &wm_root && !c->is_floating) {
cc_sws++;
}
}
@ -898,13 +885,13 @@ void wm_mstack(Monitor *m)
// dynamic
if (cc_sws == 1) {
for (c = m->clients; c; c = c->next) {
if (c->ws == m->selws)
break;
if (c->ws == m->selws && c != &wm_root)
break;
}
c->x = 0;
c->y = sy;
c->w = wm_smon->info.width-wm_border_width*2;
c->h = (wm_smon->info.height-wm_border_width*2)-sy;
c->w = wm_smon->info.width-wm_cfg_border_width*2;
c->h = (wm_smon->info.height-wm_cfg_border_width*2)-sy;
ch = wm_client_to_xwchanges(*c);
// DEBUG_PRINT("mstack client: 0x%x\n", c);
// XGetWMName(wm_display, c->window, &xt);
@ -918,26 +905,20 @@ void wm_mstack(Monitor *m)
//wm_client_focus(c);
}
else {
// TODO
// FIXME not working with dock
for (c = m->clients; c; c = c->next) {
if (c->ws == m->selws && c != &wm_root) {
if (c->ws == m->selws && c != &wm_root && !c->is_floating) {
if (n == 0) {
c->x = 0;
c->y = sy;
c->w = m->info.width*wm_ms_p-wm_border_width*2;
c->h = (m->info.height-wm_border_width*2)-sy;
c->w = m->info.width*wm_cfg_ms_p-wm_cfg_border_width*2;
c->h = (m->info.height-wm_cfg_border_width*2)-sy;
} else {
c->x = (m->info.width*wm_ms_p);
c->x = (m->info.width*wm_cfg_ms_p);
c->y = ((n-1)*m->info.height/(cc_sws-1))+sy;
c->w = (m->info.width - m->info.width*wm_ms_p)-wm_border_width*2;
c->h = ((m->info.height-sy)/(cc_sws-1)-wm_border_width*2)+sy/cc_sws;
c->w = (m->info.width - m->info.width*wm_cfg_ms_p)-wm_cfg_border_width*2;
c->h = ((m->info.height)/(cc_sws-1)-wm_cfg_border_width*2);
}
// else {
// c->x = (m->info.width*wm_ms_p);
// c->y = ((n-1)*m->info.height/(cc_sws-1));
// c->w = (m->info.width - m->info.width*wm_ms_p)-wm_border_width*2;
// c->h = (m->info.height/(cc_sws-1)-wm_border_width*2)-sy;
// }
n++;
ch = wm_client_to_xwchanges(*c);
@ -965,6 +946,9 @@ void wm_mstack(Monitor *m)
}
}
XSync(wm_display, False);
while(XCheckMaskEvent(wm_display, EnterWindowMask, &e));
wm_monitor_clients_border(m);
}
@ -973,11 +957,12 @@ void wm_set_layout(void(*f)(Monitor*))
wm_active_layout = f;
}
// TODO: layout floating window, selected layout func p
void wm_layout(Monitor *m)
{
RETURN_IF_NULL(m);
(*wm_active_layout)(m);
wm_mstack(m);
}
Client *wm_get_last_client(Monitor m)
@ -1057,24 +1042,22 @@ void wm_mainloop()
case KeyPress:
wm_keypress_handler(e.xkey);
break;
case MotionNotify:
wm_motion_handler(e.xmotion);
break;
case FocusIn:
// TODO: draw focus window elsewhere
// DEBUG_PRINT("%d window focus in\n", e.xfocus.window);
// wm_monitor_clients_border(wm_client_find(e.xfocus.window)->m);
// wm_client_border_focused(wm_client_find(e.xfocus.window));
break;
case FocusOut:
// DEBUG_PRINT("%d window focus out\n", e.xfocus.window);
//wm_client_border(wm_client_find(e.xfocus.window));
break;
case EnterNotify:
DEBUG_PRINT("pointer entered window: %d\n",
e.xcrossing.window);
wm_client_focus(wm_client_find(e.xcrossing.window));
(int)e.xcrossing.window);
if (wm_cfg_focus_on_motion)
wm_client_focus(wm_client_find(e.xcrossing.window));
break;
case LeaveNotify:
DEBUG_PRINT("pointer left window: %d\n",
e.xcrossing.window);
(int)e.xcrossing.window);
break;
case ConfigureNotify:
DEBUG_PRINT("ConfigureNotify: %d\n", (int)e.xconfigure.window)
@ -1116,39 +1099,13 @@ void wm_init()
XChangeWindowAttributes(wm_display, wm_root.window, CWEventMask, &xa);
XSelectInput(wm_display, wm_root.window, xa.event_mask);
DEBUG_PRINT("root window id: %d\n", (wm_root.window))
// DEBUG_PRINT("root window id: %d\n", (wm_root.window))
// TODO: CONFIG KEYS!
XUngrabKey(wm_display, AnyKey, AnyModifier, wm_root.window);
// XUngrabKey(wm_display, AnyKey, AnyModifier, wm_root.window);
unsigned int modifiers[] = {0, LockMask, 0 | LockMask};
XGrabKey(wm_display, XK_C, Mod4Mask | LockMask, wm_root.window, True,
GrabModeAsync, GrabModeAsync);
XGrabKey(wm_display, XKeysymToKeycode(wm_display, XK_C), Mod4Mask,
wm_root.window, True, GrabModeAsync, GrabModeAsync);
XGrabKey(wm_display, XK_C, Mod4Mask | 0, wm_root.window, True,
GrabModeAsync, GrabModeAsync);
XGrabKey(wm_display, XKeysymToKeycode(wm_display, XK_Return), Mod4Mask,
wm_root.window, True, GrabModeAsync, GrabModeAsync);
// focus keys
XGrabKey(wm_display, XKeysymToKeycode(wm_display, XK_H), Mod4Mask,
wm_root.window, True, GrabModeAsync, GrabModeAsync);
XGrabKey(wm_display, XKeysymToKeycode(wm_display, XK_J), Mod4Mask,
wm_root.window, True, GrabModeAsync, GrabModeAsync);
XGrabKey(wm_display, XKeysymToKeycode(wm_display, XK_K), Mod4Mask,
wm_root.window, True, GrabModeAsync, GrabModeAsync);
XGrabKey(wm_display, XKeysymToKeycode(wm_display, XK_L), Mod4Mask,
wm_root.window, True, GrabModeAsync, GrabModeAsync);
// workspace switcher keys
int wskeys[] = {XK_1, XK_2, XK_3, XK_4, XK_5, XK_6, XK_7, XK_8, XK_9};
for (int i = 0; i < 9; i++) {
XGrabKey(wm_display, XKeysymToKeycode(wm_display, wskeys[i]), Mod4Mask,
wm_root.window, True, GrabModeAsync, GrabModeAsync);
}
// TODO: read config
wm_keybinds_init_def();
wm_grab_keys();
//XSetErrorHandler(&wm_other_wm_handler);
@ -1162,12 +1119,18 @@ void wm_init()
XInternAtom(wm_display, "_NET_NUMBER_OF_DESKTOPS", False), XA_CARDINAL,
32, PropModeReplace, (unsigned char *) &wm_smon->wscount, 1);
char *desktop_names[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9"};
wm_client_set_atom(&wm_root, "_NET_DESKTOP_NAMES",
(unsigned char*) desktop_names, XA_STRING, 9);
Atom wm_supp[] = {
XInternAtom(wm_display, "_NET_NUMBER_OF_DESKTOPS", False),
XInternAtom(wm_display, "_NET_DESKTOP_GEOMETRY", False),
XInternAtom(wm_display, "_NET_DESKTOP_VIEWPORT", False),
XInternAtom(wm_display, "_NET_CURRENT_DESKTOP", False),
XInternAtom(wm_display, "_NET_ACTIVE_WINDOW", False),
XInternAtom(wm_display, "_NET_DESKTOP_NAMES", False),
};
XChangeProperty(wm_display, wm_root.window,
@ -1176,13 +1139,132 @@ void wm_init()
//XSetErrorHandler(&wm_xerror_handler);
// TODO: config
wm_ms_p = 0.5;
wm_mainloop();
}
//TODO: avoid global vars
void wm_grab_keys()
{
RETURN_IF_NULL(wm_cfg_keybinds)
Keybind k;
for (int i = 0; i < wm_cfg_kb_count; i++) {
k = wm_cfg_keybinds[i];
XGrabKey(wm_display, XKeysymToKeycode(wm_display, k.keysym), k.mask,
wm_root.window, True, GrabModeAsync, GrabModeAsync);
}
}
void wm_kb_spawn(Arg *args)
{
RETURN_IF_NULL(args)
RETURN_IF_NULL(args->sl)
DEBUG_PRINT("args sl 1: %d\n", args->sl[args->count-1])
DEBUG_PRINT("args sl 0: %s\n", args->sl[0])
DEBUG_PRINT("args count: %d\n", args->count)
if (args->sl[args->count-1] != NULL) {
fprintf(stderr, "%s recieved non null-terminated args. Returning\n",
__func__);
}
if (fork() == 0) {
if (wm_display)
close(ConnectionNumber(wm_display));
setsid();
execvp(args->sl[0], &(args->sl[1]));
exit(0);
}
}
void wm_kb_kill(Arg *args)
{
Client *c;
c = wm_client_get_focused();
RETURN_IF_NULL(c)
wm_client_kill(c);
}
void wm_kb_switch_ws(Arg *args)
{
RETURN_IF_NULL(args)
wm_switch_ws(args->i);
}
void wm_kb_focus_dir(Arg *args)
{
RETURN_IF_NULL(args)
RETURN_IF_NULL(args->c)
wm_client_focus_dir(args->c, args->i);
}
void wm_keybinds_init_def()
{
char *st[] = {"st", NULL};
char **sth = malloc(sizeof(st));
memcpy(sth, st, sizeof(st));
int size;
Keybind k[] = {
(Keybind) {Mod4Mask, XK_Return, *wm_kb_spawn,
(Arg) {.sl = sth, .count = 2}},
(Keybind) {Mod4Mask, XK_c, *wm_kb_kill,
(Arg) {.c = NULL}},
(Keybind) {Mod4Mask, XK_1, *wm_kb_switch_ws,
(Arg) {.i = 0}},
(Keybind) {Mod4Mask, XK_2, *wm_kb_switch_ws,
(Arg) {.i = 1}},
(Keybind) {Mod4Mask, XK_3, *wm_kb_switch_ws,
(Arg) {.i = 2}},
(Keybind) {Mod4Mask, XK_4, *wm_kb_switch_ws,
(Arg) {.i = 3}},
(Keybind) {Mod4Mask, XK_5, *wm_kb_switch_ws,
(Arg) {.i = 4}},
(Keybind) {Mod4Mask, XK_6, *wm_kb_switch_ws,
(Arg) {.i = 5}},
(Keybind) {Mod4Mask, XK_7, *wm_kb_switch_ws,
(Arg) {.i = 6}},
(Keybind) {Mod4Mask, XK_8, *wm_kb_switch_ws,
(Arg) {.i = 7}},
(Keybind) {Mod4Mask, XK_9, *wm_kb_switch_ws,
(Arg) {.i = 8}},
(Keybind) {Mod4Mask, XK_h, *wm_kb_focus_dir,
(Arg) {.i = LEFT}},
(Keybind) {Mod4Mask, XK_j, *wm_kb_focus_dir,
(Arg) {.i = DOWN}},
(Keybind) {Mod4Mask, XK_k, *wm_kb_focus_dir,
(Arg) {.i = UP}},
(Keybind) {Mod4Mask, XK_l, *wm_kb_focus_dir,
(Arg) {.i = RIGHT}},
};
size = sizeof(k);
wm_cfg_kb_count = size / sizeof(Keybind);
DEBUG_PRINT("sizeof k: %d\n", size);
wm_cfg_keybinds = malloc(size);
memcpy(wm_cfg_keybinds, k, size);
}
struct sockaddr wm_socket_init()
{
struct sockaddr_un sock_addr;
@ -1242,7 +1324,7 @@ void wm_settings_message_parse(char *c, int len)
char *token;
char tokens[20][50];
char *settings[] = {"border-width", "border-color", "focused-border-color",
"msfact"};
"msfact", "focus-on-motion"};
while((token = strtok(c, " ")) != NULL) {
DEBUG_PRINT("message_parse token: %s\n", token)

49
wm.h
View File

@ -14,12 +14,12 @@
#include <sys/socket.h>
#include <sys/un.h>
// TODO: when only 1 window on ws it is not focused
// TODO: dont draw border on not normal windows, floating dialog window,
// window type/name/... atom member variable on Client struct
// TODO: get_atom probably not working correctly
// TODO: important: do not lay out non-regular windows
// TODO: important: code cleanliness, ewmh!!
// TODO: config command line utility(sockets), avoid global vars
// TODO: config command line utility(sockets), maybe avoid global vars
#define RETURN_IF_NULL(c) \
if (c == NULL) \
@ -35,6 +35,8 @@ if (c == NULL) \
typedef struct Client Client;
typedef struct Monitor Monitor;
typedef struct Keybind Keybind;
typedef struct Arg Arg;
enum Direction {
UP,
@ -63,11 +65,30 @@ struct Client {
Window window;
Client *prev;
Client *next;
char *name;
bool has_border;
bool is_floating;
// linked list is not sufficent for manual tiling.
// will propably need a tree.
};
struct Arg {
int i;
unsigned int ui;
Client *c;
char* s;
char **sl;
int count;
};
struct Keybind {
unsigned int mask;
KeySym keysym;
void (*func)(Arg*);
Arg args;
};
static Display *wm_display;
static Monitor *wm_monitors;
static Monitor *wm_smon;
@ -75,11 +96,17 @@ static int wm_mc;
static bool wm_other_wm;
static Client wm_root;
static Window wm_dock = -1;
/* global configuration variables */
// TODO: active layout not working
static void (*wm_active_layout)(Monitor*);
static float wm_ms_p;
static unsigned int wm_border_col = 0x222222;
static unsigned int wm_focused_border_col = 0x444444;
static unsigned char wm_border_width = 2;
static float wm_cfg_ms_p = 0.5;
static char wm_cfg_border_col[] = "#222222";
static char wm_cfg_focused_border_col[] = "#444444";
static unsigned char wm_cfg_border_width = 2;
static Keybind *wm_cfg_keybinds;
static int wm_cfg_kb_count;
static bool wm_cfg_focus_on_motion = true;
static int wm_socket_fd;
@ -92,6 +119,7 @@ void wm_configure_handler(XConfigureRequestEvent e);
void wm_keyrelease_handler(XKeyReleasedEvent e);
void wm_keypress_handler(XKeyPressedEvent e);
void wm_maprequest_handler(XMapRequestEvent e);
void wm_motion_handler(XMotionEvent e);
Monitor wm_monitor_open(Display *d, XineramaScreenInfo info);
void wm_monitors_open_all(Display *d);
@ -125,11 +153,20 @@ bool wm_window_is_dock(Window w);
XWindowChanges wm_client_to_xwchanges(Client c);
Client* wm_client_find(Window w);
void wm_spawn(char **str);
void wm_switch_ws(int ws);
void wm_mainloop();
void wm_init();
void wm_grab_keys();
void wm_kb_spawn(Arg *args);
void wm_kb_kill(Arg *args);
void wm_kb_switch_ws(Arg *args);
void wm_kb_focus_dir(Arg *args);
void wm_keybinds_init_def();
struct sockaddr wm_socket_init();
void wm_socket_cleanup();
void wm_settings_message_parse(char *c, int len);