From: Michael D. Lowis Date: Sun, 18 Aug 2019 03:19:54 +0000 (-0400) Subject: added workspace handling X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=64438291fd3c292bb9dee25ba14aaa47cbc7a90b;p=projs%2Ftide.git added workspace handling --- diff --git a/Rsconscript b/Rsconscript index 6ce25f4..a27ba91 100644 --- a/Rsconscript +++ b/Rsconscript @@ -6,9 +6,11 @@ end build do env = Environment.new env["CC"] = "./acc" - env["CFLAGS"] << "-g" + env["CFLAGS"] += ["-g", "-fsanitize=undefined,address"] + env["LDFLAGS"] += ["-g", "-fsanitize=undefined,address"] env["CPPPATH"] += %w[. inc /usr/X11/include] env["LIBPATH"] += %w[. /usr/X11/lib] + #env["LIBS"] << "asan" # Build library and binaries env.Library("libtide.a", glob("src/lib/**/*.c")) diff --git a/src/anvil.c b/src/anvil.c index 8c5ba56..f13ed58 100644 --- a/src/anvil.c +++ b/src/anvil.c @@ -20,6 +20,12 @@ #define MCLIENT(c) \ container_of(c, Client, mnode) +#define Tiled_Clients \ + (Desktops[Desktop].tiled) + +#define Floated_Clients \ + (Desktops[Desktop].floated) + enum { TOO_SMALL = (1 << 0), FLOATING = (1 << 1), @@ -55,17 +61,13 @@ typedef struct Column { struct { Node *floated, *tiled; } Desktops[10] = {{0},{0},{0},{0},{0},{0},{0},{0},{0},{0}}; -int Desktop = 0; - +int Desktop = 1; XConf X = {0}; Node* All_Clients = NULL; Cursor Move_Cursor; Cursor Main_Cursor; int StartY = 0; -#define Tiled_Clients (Desktops[Desktop].tiled) -#define Floated_Clients (Desktops[Desktop].floated) - /* configuration */ uint32_t BorderWidth = 1; uint32_t BorderColor = 0xFF0000; @@ -92,18 +94,16 @@ void change_desktop(const Arg arg); void client_to_desktop(const Arg arg); #define MOD Mod1Mask - -// Avoid multiple paste #define DESKTOPCHANGE(K,N) \ { MOD, K, change_desktop, {.i = N}}, \ { MOD|ShiftMask, K, client_to_desktop, {.i = N}}, -// Shortcuts static struct key keys[] = { // MOD KEY FUNCTION ARGS -// { MOD, XK_c, spawn, {.com = lockcmd}}, -// { MOD, XK_p, spawn, {.com = dmenucmd}}, -// { MOD|ShiftMask, XK_Return, spawn, {.com = urxvtcmd}}, +// { MOD, XK_c, spawn, {.com = lockcmd}}, +// { MOD, XK_p, spawn, {.com = dmenucmd}}, +// { MOD|ShiftMask, XK_Return, spawn, {.com = urxvtcmd}}, +// { MOD|ShiftMask, XK_q, quit, {NULL}} DESKTOPCHANGE( XK_0, 0) DESKTOPCHANGE( XK_1, 1) DESKTOPCHANGE( XK_2, 2) @@ -114,17 +114,8 @@ static struct key keys[] = { DESKTOPCHANGE( XK_7, 7) DESKTOPCHANGE( XK_8, 8) DESKTOPCHANGE( XK_9, 9) -// { MOD, XK_q, quit, {NULL}} }; -void change_desktop(const Arg arg) { - Desktop = arg.i; -} - -void client_to_desktop(const Arg arg) { - printf("send to desktop %d\n", arg.i); -} - /* Utility Functions *****************************************************************************/ void die(char* errstr) { @@ -181,6 +172,7 @@ size_t list_count(Node* curr) { /* Client Handling *****************************************************************************/ void client_reconfig(XConf* xs, Client* c); +void client_config(XConf* xs, Client* c, int x, int y, int w, int h); void* biggest(Node* node, void* accum) { if (!accum || TCLIENT(node)->h > ((Client*)accum)->h) @@ -213,20 +205,44 @@ int client_flags(Client* c, int mask) { return (c->flags & mask); } -void client_add(Client* parent, Client* c) { +void client_raise(XConf* x, Client* c) { + XMapRaised(x->display, c->frame); + XMapRaised(x->display, c->win); +} + +void client_add(Client* c, int dtop) { list_add(&All_Clients, NULL, &(c->mnode)); - if (!client_flags(c, FLOATING)) - list_add(&Tiled_Clients, (parent ? &(parent->tnode) : NULL), &(c->tnode)); - else - list_add(&Floated_Clients, NULL, &(c->tnode)); + if (!client_flags(c, FLOATING)) { + Client* parent = list_reduce(Desktops[dtop].tiled, biggest, NULL); + list_add(&Desktops[dtop].tiled, (parent ? &(parent->tnode) : NULL), &(c->tnode)); + if (parent) { + c->h = (parent->h - (parent->h / 2)); + parent->h /= 2; + c->y = parent->y + parent->h; + client_config(&X, parent, parent->x, parent->y, parent->w, parent->h); + } + } else { + list_add(&Desktops[dtop].floated, NULL, &(c->tnode)); + } } void client_del(Client* c) { list_del(&All_Clients, &(c->mnode)); - if (!client_flags(c, FLOATING)) + if (!client_flags(c, FLOATING)) { list_del(&Tiled_Clients, &(c->tnode)); - else + int y = c->y, h = c->h; + Node* nsucc = (c->tnode.prev ? c->tnode.prev : c->tnode.next); + if (nsucc) { + Client* succ = TCLIENT(nsucc); + succ->h += h; + if (nsucc == c->tnode.next) + succ->y = y; + client_config(&X, succ, succ->x, succ->y, succ->w, succ->h); + client_raise(&X, succ); + } + } else { list_del(&Floated_Clients, &(c->tnode)); + } } void client_redraw(XConf* x, Client* c) { @@ -264,11 +280,6 @@ void client_config(XConf* xs, Client* c, int x, int y, int w, int h) { client_redraw(xs, c); } -void client_raise(XConf* x, Client* c) { - XMapRaised(x->display, c->frame); - XMapRaised(x->display, c->win); -} - void client_initprops(XConf* x, Client* c) { int nprops = 0; Atom* props = XListProperties(x->display, c->win, &nprops); @@ -276,9 +287,7 @@ void client_initprops(XConf* x, Client* c) { int format; void* data = 0; size_t ndata; - printf("props(%x) { \n", (int)c->win); for (int i = 0; i < nprops; i++) { - printf(" %s\n", XGetAtomName(x->display, props[i])); if (props[i] == XA_NET_WM_WINDOW_TYPE) { if (Success == get_prop(x, c->win, props[i], &type, &format, &data, &ndata)) if (((Atom*)data)[0] == XA_NET_WM_WINDOW_TYPE_DIALOG) @@ -288,7 +297,6 @@ void client_initprops(XConf* x, Client* c) { } data = xfree(data); } - printf("}\n"); } void client_create(XConf* x, Window win) { @@ -324,17 +332,7 @@ void client_create(XConf* x, Window win) { EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask); /* position the window and frame */ - Client* parent = NULL; - if (!client_flags(c, FLOATING)) { - parent = list_reduce(Tiled_Clients, biggest, NULL); - if (parent) { - c->h = (parent->h - (parent->h / 2)); - parent->h /= 2; - c->y = parent->y + parent->h; - client_config(x, parent, parent->x, parent->y, parent->w, parent->h); - } - } - client_add(parent, c); + client_add(c, Desktop); client_config(x, c, c->x, c->y, c->w, c->h); client_redraw(x, c); client_raise(x, c); @@ -393,6 +391,50 @@ void client_maximize(XConf* xs, Client* c) { c->y = y, c->h = h; } +/* Desktop Management + *****************************************************************************/ +void* hide_wins(Node* node, void* data) { + Client* c = TCLIENT(node); + XUnmapWindow(X.display, c->frame); + XUnmapWindow(X.display, c->win); + return data; +} + +void* show_wins(Node* node, void* data) { + Client* c = TCLIENT(node); + XMapWindow(X.display, c->frame); + XMapWindow(X.display, c->win); + client_redraw(&X, c); + return data; +} + +void change_desktop(const Arg arg) { + XGrabServer(X.display); + list_reduce(Tiled_Clients, hide_wins, NULL); + list_reduce(Floated_Clients, hide_wins, NULL); + Desktop = arg.i; + list_reduce(Tiled_Clients, show_wins, NULL); + list_reduce(Floated_Clients, show_wins, NULL); + XUngrabServer(X.display); + XSync(X.display, True); +} + +void client_to_desktop(const Arg arg) { + int bar; + Window foo, win; + do{ + (void)XQueryPointer(X.display, DefaultRootWindow(X.display), + &foo, &win, &bar, &bar, &bar, &bar, (unsigned int*)&bar); + } while (win <= 0); + Client* c = client_find(win); + if (!c) return; + client_del(c); + XUnmapWindow(X.display, c->frame); + XUnmapWindow(X.display, c->win); + XSync(X.display, True); + client_add(c, arg.i); +} + /* X11 Event Handling *****************************************************************************/ @@ -410,7 +452,6 @@ void client_maximize(XConf* xs, Client* c) { */ static void xbtnpress(XConf* x, XEvent* e) { - printf("btn\n"); Client* c = client_find(e->xbutton.window); if (!c || c->frame != e->xbutton.window || client_flags(c, FLOATING)) return; @@ -431,14 +472,12 @@ static void xbtnpress(XConf* x, XEvent* e) { } static void xbtnrelease(XConf* x, XEvent* e) { - printf("btn\n"); Client* c = client_find(e->xbutton.window); if (!c || c->frame != e->xbutton.window || client_flags(c, FLOATING)) return; if (Button1 == e->xbutton.button) { XUndefineCursor(X.display, e->xbutton.window); - printf("moved: %d\n", e->xbutton.y - StartY); client_resize(x, c, e->xbutton.y - StartY); } @@ -446,7 +485,6 @@ static void xbtnrelease(XConf* x, XEvent* e) { } static void xconfigrequest(XConf* x, XEvent* e) { - printf("config\n"); /* Check if it's a window we care about. If it is, and it's floating, just grant the request. Otherwise, deny it as we have it tiled already. All @@ -467,7 +505,6 @@ static void xconfigrequest(XConf* x, XEvent* e) { } static void xmaprequest(XConf* x, XEvent* e) { - printf("map\n"); static XWindowAttributes attr = {0}; if (XGetWindowAttributes(x->display, e->xmaprequest.window, &attr)) { if (attr.override_redirect) return; /* ignore certain windows (like frames) */ @@ -477,32 +514,15 @@ static void xmaprequest(XConf* x, XEvent* e) { } static void xunmapnotify(XConf* x, XEvent* e) { - printf("unmap\n"); } static void xdestroynotify(XConf* x, XEvent* e) { - printf("destroy\n"); /* This is where we cleanup windows we care about. destroy them and their frames. */ Client* c = client_find(e->xdestroywindow.window); - if (c) { - if (!client_flags(c, FLOATING)) { - int y = c->y, h = c->h; - Node* nsucc = (c->tnode.prev ? c->tnode.prev : c->tnode.next); - if (nsucc) { - Client* succ = TCLIENT(nsucc); - succ->h += h; - if (nsucc == c->tnode.next) - succ->y = y; - client_config(x, succ, succ->x, succ->y, succ->w, succ->h); - client_raise(x, succ); - } - } - client_destroy(x, c); - } + if (c) client_destroy(x, c); } static void xclientmsg(XConf* x, XEvent* e) { - printf("client\n"); } static void xpropnotify(XConf* x, XEvent* e) { @@ -518,14 +538,12 @@ static void xpropnotify(XConf* x, XEvent* e) { } static void xenternotify(XConf* x, XEvent* e) { - printf("enter\n"); /* Handle focus follows mouse here. */ } static void xexpose(XConf* x, XEvent* e) { - printf("expose\n"); Client* c = client_find(e->xexpose.window); if (c && e->xexpose.count == 0) client_redraw(x, c);