foo-wm

(Archived) Experimental Zooming IPC-based WM
git clone http://milesalan.com/git/foo-wm
Log | Files | Refs | Mirror | README | LICENSE

commit c17b19a2b5e5d3f6744e5b3ffa3af76f83f3ea16
parent dcd4a04f2cb134aee7c358301fcb7d589b42cc49
Author: Miles Sandlar <miles.sandlar@gmail.com>
Date:   Sun,  1 Jul 2012 20:02:36 -0400

Rework of tree. Uses one struct called Node now.
Type of Node (client/container) is inferred from its attributes
If the Node has children it is a container, no children a client
Addition of view command to FIFO

Diffstat:
MMakefile | 2+-
Mconfig/.xbindkeysrc | 8++++++++
Dsrc/client.c | 38--------------------------------------
Dsrc/client.h | 1-
Msrc/commands.c | 63++++++++++++++++++++++++++++++++++-----------------------------
Msrc/events.c | 46+++++++++++++++++++++++++++-------------------
Msrc/fifo-wm.c | 7++++++-
Msrc/fifo-wm.h | 3+++
Msrc/structs.h | 18+++++++++++++++++-
Msrc/tree.c | 269+++++++++++++++++++++++++------------------------------------------------------
Msrc/tree.h | 13++++++-------
11 files changed, 186 insertions(+), 282 deletions(-)

diff --git a/Makefile b/Makefile @@ -3,7 +3,7 @@ CFLAGS=-Wall -lX11 -g VPATH=./src all:fifo-wm -fifo-wm: events.o tree.o commands.o util.o window.o client.o +fifo-wm: events.o tree.o commands.o util.o window.o clean: rm -rf fifo-wm *.o diff --git a/config/.xbindkeysrc b/config/.xbindkeysrc @@ -41,6 +41,14 @@ m:0x40 + c:24 Mod4 + q +"echo 'view parent set' > /home/mil/fifos/wm-fifo" + m:0x40 + c:20 + Mod4 + minus + +"echo 'view child set' > /home/mil/fifos/wm-fifo" + m:0x40 + c:21 + Mod4 + equal + "dmenu-suggestions.rb | dmenu -h 60 -x 100 -y 400 -w 1200 -fn 'Envy Code R-20' -sb '#ffffff' -nf '#00ffd5' -nb '#1f1f1f' -sf '#000000' -b -p 'Command:' | xargs -0 -I INPUT handler INPUT" m:0x40 + c:40 diff --git a/src/client.c b/src/client.c @@ -1,38 +0,0 @@ -#include <X11/Xlib.h> -#include <stdio.h> - -#include "fifo-wm.h" -#include "client.h" - - -void focusClient(Client *client) { - - fprintf(stderr, "Focusing client window %p\n", &client -> window); - - Client *c; - for (c = (client -> parent) -> client; c != NULL; c = c -> next) { - if (client == c) { - XSetWindowBorder(display, client -> window, focusedColor); - } else { - XSetWindowBorder(display, c -> window, unfocusedColor); - } - } - - currentContainer = client -> parent; - (client -> parent) -> focus = client; - - //Focuses window - XSelectInput( - display, client -> window, - FocusChangeMask | KeyPressMask | - ButtonPressMask | LeaveWindowMask | OwnerGrabButtonMask - ); - XGrabButton( - display, AnyButton, AnyModifier, client -> window, False, - OwnerGrabButtonMask | ButtonPressMask, - GrabModeSync, GrabModeSync, None, None - ); - - XRaiseWindow(display, client -> window); - XSetInputFocus(display, client -> window, RevertToPointerRoot, CurrentTime); -} diff --git a/src/client.h b/src/client.h @@ -1 +0,0 @@ -void focusClient(Client *client); diff --git a/src/commands.c b/src/commands.c @@ -5,11 +5,11 @@ #include "fifo-wm.h" #include "commands.h" #include "tree.h" -#include "client.h" void focus(int direction) { //Direction: 0 - Previous, 1 - Next, 2 - Parent + /* if (direction == 0) { if ((currentContainer -> focus) -> next != NULL) { focusClient((currentContainer -> focus) -> next); @@ -34,8 +34,7 @@ void focus(int direction) { currentContainer -> width, currentContainer -> height); } } - - + */ } void handleCommand(char* request) { @@ -51,21 +50,15 @@ void handleCommand(char* request) { fprintf(stderr, "Adding Token %s\n", token); } - if (!strcmp(tokens[0], "dump")) { dumpTree(); } else if (!strcmp(tokens[0], "layout")) { fprintf(stderr, "Setting layout to: %s", tokens[1]); - if (!strcmp(tokens[1], "vertical")) { - currentContainer -> layout = 0; - - } else if (!strcmp(tokens[1], "horizontal")) { - currentContainer -> layout = 1; - } - placeContainer(currentContainer, - currentContainer -> x, currentContainer -> y, - currentContainer -> width, currentContainer -> height); - + if (!strcmp(tokens[1], "vertical")) { activeNode -> layout = 0; + } else if (!strcmp(tokens[1], "horizontal")) { activeNode -> layout = 1; } + placeNode(activeNode, + activeNode -> x, activeNode -> y, + activeNode -> width, activeNode -> height); } else if (!strcmp(tokens[0], "focus")) { if (!strcmp(tokens[1], "next")) @@ -76,24 +69,34 @@ void handleCommand(char* request) { focus(2); } else if (!strcmp(tokens[0], "containerize")) { - if ( - (((currentContainer -> focus) -> previous != NULL) || - ((currentContainer -> focus) -> next != NULL)) || - (currentContainer -> child != NULL) - ) { - fprintf(stderr, "Containerizing!"); - Container * newContainer = malloc(sizeof(Container)); - parentClient((currentContainer -> focus) , newContainer); - parentContainer(newContainer, currentContainer); - currentContainer = newContainer; - placeContainer(currentContainer, - currentContainer -> x, currentContainer -> y, - currentContainer -> width, currentContainer -> height); + if ((activeNode -> focus) -> previous != NULL) { + fprintf(stderr,"Containerizing"); + Node * newContainer = malloc(sizeof(Node)); + parentNode(activeNode -> focus, newContainer); + parentNode(newContainer, activeNode); + activeNode = newContainer; + placeNode(viewNode, 0, 0, + DisplayWidth(display, activeScreen), + DisplayHeight(display, activeScreen)); + } else { + fprintf(stderr, "Containerize called but alone in contianer"); + } - } else { - fprintf(stderr, "Containerize called but already alone in a container..."); + } else if (!strcmp(tokens[0], "view")) { + if (!strcmp(tokens[1], "parent")) { + viewNode = viewNode -> parent; + placeNode(viewNode, 0, 0, + DisplayWidth(display, activeScreen), + DisplayHeight(display, activeScreen)); + + } else if (!strcmp(tokens[1], "child")) { + viewNode = activeNode; + placeNode(viewNode, 0, 0, + DisplayWidth(display, activeScreen), + DisplayHeight(display, activeScreen)); } } else if (!strcmp(tokens[0], "kill")) { + /* if (!strcmp(tokens[1], "client")) { @@ -113,5 +116,7 @@ void handleCommand(char* request) { destroyContainer(currentContainer); dumpTree(); } + + */ } } diff --git a/src/events.c b/src/events.c @@ -8,29 +8,30 @@ #include "events.h" #include "tree.h" #include "window.h" -#include "client.h" void eMapRequest(XEvent *event) { - Client *newClient; - newClient = malloc(sizeof(Client)); - newClient -> window = event -> xmaprequest.window; fprintf(stderr, "Got a map request\n"); + Node *newNode; + newNode = malloc(sizeof(Node)); + newNode -> window = event -> xmaprequest.window; + + if (activeNode == NULL) { + } else { + fprintf(stderr, "The activeNode's layout is %d", activeNode -> layout); + parentNode(newNode, activeNode); + } - parentClient(newClient, currentContainer); - - //Update view - placeContainer( - rootContainer, 0, 0, - DisplayWidth (display, activeScreen), - DisplayHeight (display, activeScreen) + //Update the view + placeNode( + viewNode, 0, 0, + DisplayWidth(display, activeScreen), + DisplayHeight(display, activeScreen) ); - focusClient(newClient); - //Add Client and window to lookup list Lookup *entry = malloc(sizeof(Lookup)); - entry -> client = newClient; + entry -> node= newNode; int win = event -> xmaprequest.window; entry -> window = win; entry -> previous = lookup; @@ -40,12 +41,14 @@ void eMapRequest(XEvent *event) { void eDestroyNotify(XEvent *event) { fprintf(stderr, "DESTROY NOTIFY RECIEVED"); - Client *c = getClientByWindow(&(event -> xdestroywindow.window)); - destroyClient(c); + Node *n = getNodeByWindow(&(event -> xdestroywindow.window)); + if (n == NULL) { return; } + fprintf(stderr, "YO it aint null mofo\n"); + destroyNode(n); //Update view - placeContainer( - rootContainer, 0, 0, + placeNode( + viewNode, 0, 0, DisplayWidth (display, activeScreen), DisplayHeight (display, activeScreen) ); @@ -53,6 +56,8 @@ void eDestroyNotify(XEvent *event) { void eConfigureRequest(XEvent *event) { fprintf(stderr, "Receiveced a Resize Request EVENT\n"); + + /* Client *c = getClientByWindow(&(event -> xconfigurerequest.window)); XConfigureRequestEvent *configure = &(event -> xconfigurerequest); @@ -62,6 +67,8 @@ void eConfigureRequest(XEvent *event) { XConfigureWindow(display, c -> window, configure -> value_mask, &changes); XMoveResizeWindow(display, c-> window, c -> x, c -> y, c -> width, c -> height); XMapWindow(display, c -> window); + + */ } @@ -71,8 +78,10 @@ void eButtonPress(XEvent *event) { //Root Window if (event -> xbutton.subwindow == None) { return; } + /* Client *c = getClientByWindow(&(event -> xbutton.subwindow)); focusClient(c); + */ } void handleXEvent(XEvent *event) { @@ -84,4 +93,3 @@ void handleXEvent(XEvent *event) { default: break; } } - diff --git a/src/fifo-wm.c b/src/fifo-wm.c @@ -52,12 +52,17 @@ void handleEvents() { int main() { layout = CONTAINER_DEFAULT_LAYOUT; padding = CONTAINER_PADDING; - spawn = 0; + /* rootContainer = malloc(sizeof(Container)); rootContainer -> layout = layout; currentContainer = rootContainer; + */ + + activeNode = malloc(sizeof(Node)); + activeNode -> layout = layout; + viewNode = activeNode; display = XOpenDisplay(NULL); assert(display); diff --git a/src/fifo-wm.h b/src/fifo-wm.h @@ -15,5 +15,8 @@ struct timeval tv; long unfocusedColor; long focusedColor; +Node *activeNode; //Active Input / New clients launch as brother +Node *viewNode; // Currently viewed node on the screen + void handleCommand(char* request); void handleEvents(); diff --git a/src/structs.h b/src/structs.h @@ -1,4 +1,20 @@ #include <X11/Xlib.h> +typedef struct Node Node; +struct Node { + int layout; + int x, y, width, height; + + Node *parent; + Node *next; + Node *previous; + + /* If a Container */ + Node *child; + Node *focus; + + /* If a Client */ + Window window; +}; typedef struct Client Client; @@ -31,6 +47,6 @@ struct Container { typedef struct Lookup Lookup; struct Lookup { int window; - Client *client; + Node *node; Lookup *previous; }; diff --git a/src/tree.c b/src/tree.c @@ -5,232 +5,131 @@ #include "fifo-wm.h" #include "tree.h" -/* Tracks the current container */ -void crawlContainer(Container * container, int level) { - Container *c; - for (c = container; c != NULL; c = c -> next) { +void crawlNode(Node * node, int level) { + Node *n; + for (n = node; n != NULL; n = n -> next) { int j; - for (j = level; j > 0; j--) { fprintf(stderr, " | "); } - char *or = c -> layout == 0 ? "Vertical" : "Horizontal"; - fprintf(stderr, "=> Container %p (%s)", c, or); - if (c == currentContainer) { fprintf(stderr, " [ACTIVE CONTAINER]"); } - fprintf(stderr, "\n"); - - if (c -> client != NULL) { - Client *d; - for (d = c -> client; d != NULL; d = d -> next) { - int h; - for (h = level + 1; h > 0; h--) { fprintf(stderr, " | "); } - - fprintf(stderr, "-> Client %p", d); - if (d == c -> focus) { fprintf(stderr, " [ACTIVE]"); } - fprintf(stderr, "\n"); - } - } - if (c -> child != NULL) { - crawlContainer(c -> child, level + 1); + for (j = level; j > 0; j--) { fprintf(stderr, "|\t"); } + + if (n -> child == NULL) { + fprintf(stderr, "Client\n"); + } else { + char *or = n -> layout == 0 ? "Vertical" : "Horizontal"; + fprintf(stderr, "Container %s\n", or); + crawlNode(n -> child, level + 1); } } } - void dumpTree() { fprintf(stderr, "Printing the tree\n"); - crawlContainer(rootContainer, 0); + crawlNode(viewNode, 0); } -void unparentClient(Client *c) { - if (c -> parent != NULL) { - - if (c -> next != NULL) { - (c -> next) -> previous = c -> previous; - (c -> parent) -> focus = c -> next; - } +void destroyNode(Node * n) { + if (n == NULL) { return; } - if (c -> previous != NULL) { - (c -> previous) -> next = c -> next; - (c -> parent) -> focus = c -> previous; - } - XUnmapWindow(display, c -> window); - c -> parent = NULL; + //Recursivly destroy all children of the node + Node * child; + for (child = n -> child; child != NULL; child -> next) { + destroyNode(child); } -} -void unparentContainer(Container *c) { - if (c -> parent == NULL) { return; } + //Unparent the node + unparentNode(n); - //Pop the container out of its linked list - if (c -> next == NULL && c -> previous == NULL) { - (c -> parent) -> child = NULL; - } else { - if (c -> next != NULL) { (c -> next) -> previous = c -> previous; } - if (c -> previous != NULL) { (c -> previous) -> next = c -> next; } + if (n -> window != (Window)NULL) { + XUnmapWindow(display, n -> window); } - - - //Destroy Children Clients - if (c -> client != NULL) { - Client *client; - for (client = c -> client; client != NULL; client = client -> next) { - unparentClient(client); - } - } - - //Destroy Children Containers - if (c -> child != NULL) { - Container *container; - for (container = c -> child; container != NULL; container = container -> next) { - unparentContainer(container); - } - } - - c -> parent = NULL; + free(n); } -void destroyContainer(Container *c) { - if (c != NULL) { - fprintf(stderr, "Destorying Container %p\n", c); - unparentContainer(c); - } -} -void destroyClient(Client *c) { - //Check if client alone, if so destroy the container - if (c == NULL) { return; } +void unparentNode(Node *node) { + if (node -> parent == NULL) { return; } - fprintf(stderr, "c->next = %p\nc->previous = %p\n", c->next, c->previous); - if (c -> next == NULL && (c -> parent) -> client == c) { - destroyContainer(c -> parent); - } else { - fprintf(stderr, "Destroying Client %p\n", c); - unparentClient(c); - XUnmapWindow(display, c -> window); - free(c); + if ((node -> parent) -> focus == node) { + if (node-> next != NULL) { (node -> parent) -> focus = node -> next; } + if (node-> previous != NULL) { (node -> parent) -> focus = node -> previous; } } -} - - - -int parentClient(Client * child, Container * parent) { - /* First client to be added to container */ - if (parent == NULL) { return 0; } - //Moving the client - unparentClient(child); - child -> parent = parent; - - if (parent -> client == NULL) { - fprintf(stderr, "Addng client\n"); - parent -> client = child; + if (node -> next != NULL) { + (node -> next) -> previous = node -> previous; + } - } else { - Client *c = parent -> client; - while (c -> next != NULL) { c = c -> next; } - c -> next = child; - fprintf(stderr, "c->next set to %p\n", c->next); - child -> previous = c; - child -> parent = parent; + if (node -> previous != NULL) { + (node -> previous) -> next = node -> next; } - return 1; } -int parentContainer(Container * child, Container * parent) { - if (parent == NULL) { return 0; } +void parentNode(Node *node, Node *parent) { + /* First client to be added to container */ + if (parent == NULL) { return; } + + //Unparent then set the parent to new parent + unparentNode(node); - child -> parent = parent; + node -> parent = parent; + parent -> focus = node; + //Find last in children of parent, add to end if (parent -> child == NULL) { - parent -> child = child; - + parent -> child = node; } else { - Container *c = parent -> child; - while (c -> next != NULL) { c = c -> next; } - c -> next = child; - child -> previous = c; - child -> parent = parent; + Node *n = parent -> child; + while (n -> next != NULL) { n = n -> next; } + node -> previous = n; + n -> next = node; } - - return 1; } -int placeContainer(Container * container, int x, int y, int width, int height) { - container -> x = x; container -> y = y; - container -> width = width; container -> height = height; - - //Count up children - int children = 0; - Client *a = malloc(sizeof(Client)); - Container *b = malloc(sizeof(Container)); - for (a = container -> client; a != NULL; a = a -> next) { children++; } - for (b = container -> child; b != NULL; b = b -> next) { children++; } - - - /* Recursive call to placeContainer */ - int i = 0; - for (b = container -> child; b != NULL; b = b -> next, i++) { - switch (container -> layout) { - case 0: - placeContainer(b, - x + (i * (width/children)) + padding, y + padding, - (width / children) - (padding * 2), height - (padding * 2)); - break; - - case 1: - placeContainer(b, - x, y + (i * (height/children)), - width, (height / children)); - break; - - default: - break; + +void placeNode(Node * node, int x, int y, int width, int height) { + node -> x = x; node -> y = y; + node -> width = width; node -> height = height; + fprintf(stderr, "Place Node XY:[%d, %d], WH:[%d, %d]\n", x, y, width, height); + + //if (node -> window != (Window)NULL) { + if (node -> focus == NULL) { + XMapWindow(display, node -> window); + XMoveResizeWindow(display, node -> window, x, y, width, height); + XSetWindowBorderWidth(display, node -> window, 1); + if ((node -> parent) -> focus == node) { + XSetWindowBorder(display, node -> window, focusedColor); + } else { + XSetWindowBorder(display, node -> window, unfocusedColor); } - } - for (a = container -> client; a != NULL; a = a -> next, i++) { - - XMapWindow(display, a -> window); - XSetWindowBorderWidth(display, a -> window, 1); - if (container -> focus == a) - XSetWindowBorder(display, a -> window, focusedColor); - else - XSetWindowBorder(display, a -> window, unfocusedColor); - - - switch (container -> layout) { - case 0: - a -> x = x + (i * (width / children)); - a -> y = y + padding; - a -> width = width / children; - a -> height = height; - break; - case 1: - a -> x = x; - a -> y = y + (i * (height / children)); - a -> width = width; - a -> height = height / children; - break; - default: - break; + } else { + //Count up children prior to loop + int children = 0; int i = 0; Node *a; + for (a = node -> child; a != NULL; a = a -> next) { children++; } + for (a = node -> child; a != NULL; a = a -> next, i++) { + switch (node -> layout) { + case 0: + a -> x = x + (i * (width / children)); a -> y = y + padding; + a -> width = width / children; a -> height = height; + break; + + case 1: + a -> x = x; a -> y = y + (i * (height / children)); + a -> width = width; a -> height = height / children; + break; + } + placeNode(a, a -> x, a -> y, a -> width, a -> height); } - XMoveResizeWindow(display, a -> window, - a -> x, a -> y, a -> width, a-> height); - } - - free(a), free(b); - return 0; } - //Returns the client associated with given window -Client * getClientByWindow(Window * window) { - Lookup *node; +Node * getNodeByWindow(Window * window) { + Lookup *entry; int win = *window; - for (node = lookup; node != NULL; node = node -> previous) { - if (win == node -> window) - return node -> client; + for (entry= lookup; entry != NULL; entry = entry -> previous) { + if (win == entry -> window) + return entry -> node; } return NULL; diff --git a/src/tree.h b/src/tree.h @@ -1,8 +1,7 @@ -void crawlContainer(Container * container, int level); +void crawlNode(Node * node, int level); void dumpTree(); -int parentClient(Client * child, Container * parent); -void destroyClient(Client * c); -void destroyContainer(Container * c); -int parentContainer(Container * child, Container * parent); -int placeContainer(Container * container, int x, int y, int width, int height); -Client * getClientByWindow(Window * window); +void destroyNode(Node * n); +void unparentNode(Node * node); +void parentNode(Node * node, Node * parent); +void placeNode(Node * node, int x, int y, int width, int height); +Node * getNodeByWindow(Window * window);