From 40ab40d832f5db1b0deeb0c5b10007f2c67c4669 Mon Sep 17 00:00:00 2001 From: Mike Lowis Date: Mon, 6 Mar 2023 14:57:31 -0500 Subject: [PATCH] started reworking to use bitmap allocator for clients --- bin/winmgr/anvil.h | 119 ++++++++----- bin/winmgr/client.c | 94 +++++++++++ bin/winmgr/keys.c | 4 + bin/winmgr/mons.c | 392 ++++++++++++++++++------------------------- bin/winmgr/mouse.c | 48 ++---- bin/winmgr/revised.h | 70 -------- bin/winmgr/tile.c | 82 ++------- bin/winmgr/winmgr.c | 255 +++++++++++++++------------- 8 files changed, 506 insertions(+), 558 deletions(-) delete mode 100644 bin/winmgr/revised.h diff --git a/bin/winmgr/anvil.h b/bin/winmgr/anvil.h index e7eae01..2b46b27 100644 --- a/bin/winmgr/anvil.h +++ b/bin/winmgr/anvil.h @@ -18,6 +18,27 @@ #include #include +#define MIN_COLUMN_FACTOR 0.10 +#define MAX_COLUMNS 10 +#define MAX_COLUMN_CLIENTS 256 +#define MAX_FLOATING_CLIENTS 256 +#define NUM_WORKSPACES 10 +#define MAX_MONITORS 4 + +/* calculate the size of the client pool */ +#define MAX_WSPACE_CLIENTS (MAX_COLUMNS * MAX_COLUMN_CLIENTS + MAX_FLOATING_CLIENTS) +#define MAX_MONITOR_CLIENTS (NUM_WORKSPACES * MAX_WSPACE_CLIENTS) +#define MAX_CLIENTS (MAX_MONITORS * MAX_MONITOR_CLIENTS) + +#define BORDER_WIDTH 5 +#define TITLE_HEIGHT (X.font_ext->max_logical_extent.height) +#define MIN_HEIGHT (TITLE_HEIGHT+BORDER_WIDTH) +#define MIN_COL_FACT 0.20 +#define FONT_NAME "-*-lucida-bold-r-normal-sans-14-*-*-*-p-*-iso10646-1" +#define MODKEY Mod4Mask +#define FRAME_HEIGHT_SUM (2*BORDER_WIDTH + TITLE_HEIGHT) +#define FRAME_WIDTH_SUM (2*BORDER_WIDTH) + #define min(a,b) (a < b ? a : b) #define max(a,b) (a > b ? a : b) @@ -63,8 +84,21 @@ typedef struct Node { struct Node* next; } Node; -typedef struct Client { - struct Client* next; +typedef struct Client Client; +typedef struct Column Column; +typedef struct Workspace Workspace; +typedef struct Monitor Monitor; +typedef struct Location Location; + +struct Client { + Client* next; + + /* location data */ + Monitor* monitor; + Workspace* workspace; + Column* column; + + /* attributes */ char* name; Window frame, win; int flags, x, y, w, h; @@ -72,34 +106,31 @@ typedef struct Client { XSizeHints hints; Pixmap pixmap; Visual visual; -} Client; +}; -typedef struct Column { - struct Column* next; +struct Column { int width; - Client* focused; Client* clients; -} Column; +}; -typedef struct Workspace { - struct Workspace* next; +struct Workspace { Client* floating; - Column* columns; -} Workspace; + int ncolumns; + Column columns[MAX_COLUMNS]; +}; -typedef struct Monitor { - struct Monitor* next; +struct Monitor { int x, y, w, h, midx, midy; - Workspace* wspaces; + Workspace wspaces[NUM_WORKSPACES]; Workspace* cspace; -} Monitor; +}; -typedef struct Location { +struct Location { Monitor* monitor; Workspace* workspace; Column* column; Client* client; -} Location; +}; typedef union { int i; @@ -113,22 +144,31 @@ typedef struct { Arg arg; } Key; -#define BORDER_WIDTH 5 -#define TITLE_HEIGHT (X.font_ext->max_logical_extent.height) -#define MIN_HEIGHT (TITLE_HEIGHT+BORDER_WIDTH) -#define MIN_COL_FACT 0.20 -#define FONT_NAME "-*-lucida-bold-r-normal-sans-14-*-*-*-p-*-iso10646-1" -#ifdef __APPLE__ -#define MODKEY Mod1Mask -#else -#define MODKEY Mod4Mask -#endif -#define FRAME_HEIGHT_SUM (2*BORDER_WIDTH + TITLE_HEIGHT) -#define FRAME_WIDTH_SUM (2*BORDER_WIDTH) - /* anvil.c */ extern XConf X; + +Client* Client_Find(Window win); +Client* Client_Add(Window win, XWindowAttributes* attr); +void Client_Del(Client* client); +void Client_AdjustSize(Client* client); +void Client_SetActive(Window win); +void Client_ReadProps(Client* client); +void Client_Draw(Client* client); +void Client_Focus(Client* client); + +void Mouse_ToCorner(Client* client); +void Mouse_Down(XButtonEvent* ev, Client* client); +void Mouse_Up(XButtonEvent* ev, Client* client); +void Mouse_Drag(XMotionEvent* ev, Client* client); + +void Keys_Run(XKeyEvent* ev); + + + + + + /* list.c */ int list_length(void* list); void* list_del(void* list, void* node); @@ -144,11 +184,14 @@ void keys_init(void); void keys_run(XKeyEvent* ev); /* mons.c */ -extern Monitor* Monitors; +extern Monitor Monitors[MAX_MONITORS]; + void mons_init(void); +void mons_delclient(Location* loc); +void mons_activate(Window win); + void mons_layer(Monitor* mon); void mons_addclient(Client* c); -void mons_delclient(Location* loc); void mons_togglefloat(Location* loc); int mons_find(Window win, Location* loc); void mons_place(Client* c); @@ -160,7 +203,6 @@ void mons_colsplit(void); void mons_coljoin(void); void mons_coladjust(Monitor* mon, Column* col, int wdiff); void mons_tilemove(Location* loc, int hdiff); -void mons_activate(Window win); /* client.c */ extern Client* Focused; @@ -186,13 +228,10 @@ void mouse_totitle(Client* c); void mouse_get(int* ptrx, int* ptry); /* tile.c */ -void monocled_add(Location* loc); -void monocled_del(Location* loc); -void monocled_raise(Location* loc); -void stacked_add(Location* loc); -void stacked_del(Location* loc); -void stacked_set(Location* loc); -void stacked_addheight(Location* loc, int amount); +void tile_add(Location* loc); +void tile_del(Location* loc); +void tile_set(Location* loc); +void tile_addheight(Location* loc, int amount); /* error.c */ extern int (*error_default)(Display* disp, XErrorEvent* ev); diff --git a/bin/winmgr/client.c b/bin/winmgr/client.c index 3960f8e..a9170a3 100644 --- a/bin/winmgr/client.c +++ b/bin/winmgr/client.c @@ -1,7 +1,101 @@ #include "anvil.h" +#define NUM_BITMAP_CELLS (MAX_CLIENTS / sizeof(unsigned long) + 1) +#define CELL_IS_FULL ((unsigned long)-1) + +/* Client allocation bitmap */ +static unsigned long Client_Bitmap[NUM_BITMAP_CELLS]; + +/* Client allocation buffer */ +static Client Client_Buffer[MAX_CLIENTS]; + +/* The currently focused client */ Client* Focused = NULL; +Client* Client_Find(Window win) +{ + Client* client = NULL; + for (int i = 0; i < MAX_CLIENTS; i++) + { + unsigned long cell = i / sizeof(unsigned long); + unsigned long bit = i % sizeof(unsigned long); + int allocated = ((Client_Bitmap[cell] & (1 << bit)) != 0); + + /* if the client is allocated and matches frame or window id, return it */ + if (allocated && ((Client_Buffer[i].win == win) || (Client_Buffer[i].frame == win))) + { + client = &Client_Buffer[i]; + break; + } + } + return client; +} + +Client* Client_Add(Window win, XWindowAttributes* attr) +{ + Client* client = NULL; + + for (int i = 0; i < NUM_BITMAP_CELLS; i++) + { + if (Client_Bitmap[i] != CELL_IS_FULL) + { + unsigned long bit_index = __builtin_ctz(~Client_Bitmap[i]); + Client_Bitmap[i] |= (1 << bit_index); + client = &Client_Buffer[i + bit_index]; + break; + } + } + + return client; +} + +void Client_Del(Client* client) +{ + /* cleanup stuff here... */ + + /* now deallocate it */ + unsigned long client_index = (client - &Client_Buffer[0]) / sizeof(Client); + unsigned long cell = client_index / sizeof(unsigned long); + unsigned long bit = client_index % sizeof(unsigned long); + Client_Bitmap[cell] &= ~(1 << bit); +} + +void Client_AdjustSize(Client* client) +{ +} + +void Client_SetActive(Window win) +{ +} + +void Client_ReadProps(Client* client) +{ +} + +void Client_Draw(Client* client) +{ +} + +void Client_Focus(Client* client) +{ +} + + + + + + + + + + + + + + + + + void client_initall(void) { unsigned int nwins; diff --git a/bin/winmgr/keys.c b/bin/winmgr/keys.c index 5c21ebb..f0b4089 100644 --- a/bin/winmgr/keys.c +++ b/bin/winmgr/keys.c @@ -144,3 +144,7 @@ void keys_run(XKeyEvent* ev) } } } + +void Keys_Run(XKeyEvent* ev) +{ +} diff --git a/bin/winmgr/mons.c b/bin/winmgr/mons.c index 671b89a..2ee1eb6 100644 --- a/bin/winmgr/mons.c +++ b/bin/winmgr/mons.c @@ -9,103 +9,72 @@ static void client_visibility(Workspace* wspace, int show); static Client* client_find(Client* clients, Window win); static void add_client(Monitor* mon, Client* c, int ptrx); static void remove_client(Location* loc, Client* c); -static void adjust_all(Column* col, int xoff); +//static void adjust_all(Column* col, int xoff); static void change_wspace(Monitor* mon, Workspace* wspace); -Monitor* Monitors = NULL; +Monitor Monitors[MAX_MONITORS]; -static int min_col_width(Monitor* mon) -{ - return (int)(mon->w * MIN_COL_FACT); -} +//static int min_col_width(Monitor* mon) +//{ +// return (int)(mon->w * MIN_COL_FACT); +//} void mons_init(void) { int nmons; check( XineramaIsActive(X.disp), "Xinerama extension is required"); XineramaScreenInfo* mons = XineramaQueryScreens(X.disp, &nmons); - for (int i = 0; i < nmons; i++) + for (int i = 0; i < nmons && i < MAX_MONITORS; i++) { - Monitor* m = ecalloc(1, sizeof(Monitor)); + Monitor* m = &Monitors[i]; m->x = mons[i].x_org; m->y = mons[i].y_org; m->w = mons[i].width; m->h = mons[i].height; m->midx = m->x + m->w/2; m->midy = m->y + m->h/2; - m->next = Monitors; - Monitors = m; for (int i = 0; i < 10; i++) { - Column* col = ecalloc(1, sizeof(Column)); - col->width = m->w; - Workspace* wspace = ecalloc(1, sizeof(Workspace)); - wspace->columns = col; - wspace->next = m->wspaces; - m->wspaces = wspace; + m->wspaces[i].ncolumns = 1; + m->wspaces[i].columns[0].width = m->w; } m->cspace = m->wspaces; } xfree(mons); - - Monitor* m = Monitors; - while (m) - { - printf("x: %d y: %d w: %d h: %d\n", m->x, m->y, m->w, m->h); - Workspace* w = m->wspaces; - while (w) - { - printf(" wspace %p\n", (void*)w); - Column* c = w->columns; - while (c) - { - printf(" col %p %d\n", (void*)c, c->width); - c = c->next; - } - w = w->next; - } - m = m->next; - } - } -void mons_layer(Monitor* mon) +int mons_find(Window win, Location* loc) { - int nwins = 0; - Window* wins = NULL; - Client* c; - Column* col; - LIST_FOR_EACH(c, mon->cspace->floating) + for (int m = 0; m < MAX_MONITORS; m++) { - wins = realloc(wins, ++nwins * sizeof(Window)); - wins[nwins-1] = c->frame; - } - /* add in the monocled windows first */ - LIST_FOR_EACH(col, mon->cspace->columns) - { - if (col->focused) + for (int i = 0; i < NUM_WORKSPACES; i++) { - wins = realloc(wins, ++nwins * sizeof(Window)); - wins[nwins-1] = col->focused->frame; - } - } - /* now lower all of the tiled windows */ - LIST_FOR_EACH(col, mon->cspace->columns) - { - LIST_FOR_EACH(c, col->clients) - { - if (col->focused != c) + Workspace* wspace = &(Monitors[m].wspaces[i]); + Column* column = NULL; + Client* client = client_find(wspace->floating, win); + if (!client) { - wins = realloc(wins, ++nwins * sizeof(Window)); - wins[nwins-1] = c->frame; + for (int i =0; i < wspace->ncolumns; i++) + { + Column* column = &wspace->columns[i]; + if ( (client = client_find(column->clients, win)) ) + { + break; + } + } + } + /* return the client location if we found it */ + if (client) + { + loc->monitor = &Monitors[m]; + loc->workspace = wspace; + loc->column = column; + loc->client = client; + return 1; } } } - if (nwins) - { - XRestackWindows(X.disp, wins, nwins); - } - xfree(wins); + return 0; } /* adds a new client to the most appropriate monitor */ @@ -128,6 +97,35 @@ void mons_delclient(Location* loc) free(loc->client); } +void mons_layer(Monitor* mon) +{ + int nwins = 0; + Window* wins = NULL; + Client* c; + Column* col; + LIST_FOR_EACH(c, mon->cspace->floating) + { + wins = realloc(wins, ++nwins * sizeof(Window)); + wins[nwins-1] = c->frame; + } + + /* first lower all of the tiled windows */ + for (int i =0; i < mon->cspace->ncolumns; i++) + { + col = &mon->cspace->columns[i]; + LIST_FOR_EACH(c, col->clients) + { + wins = realloc(wins, ++nwins * sizeof(Window)); + wins[nwins-1] = c->frame; + } + } + if (nwins) + { + XRestackWindows(X.disp, wins, nwins); + } + xfree(wins); +} + void mons_togglefloat(Location* loc) { remove_client(loc, loc->client); @@ -142,40 +140,6 @@ void mons_togglefloat(Location* loc) mons_addclient(loc->client); } -int mons_find(Window win, Location* loc) -{ - Monitor* mon; - Workspace* wspace; - LIST_FOR_EACH(mon, Monitors) - { - LIST_FOR_EACH(wspace, mon->wspaces) - { - Column* column = NULL; - Client* client = client_find(wspace->floating, win); - if (!client) - { - LIST_FOR_EACH(column, wspace->columns) - { - if ( (client = client_find(column->clients, win)) ) - { - break; - } - } - } - /* return the client location if we found it */ - if (client) - { - loc->monitor = mon; - loc->workspace = wspace; - loc->column = column; - loc->client = client; - return 1; - } - } - } - return 0; -} - /* find the best monitor to own the window by calculating the overlap */ void mons_place(Client* c) { @@ -188,8 +152,9 @@ void mons_place(Client* c) { int maxarea = 0; Monitor *mon = NULL, *closest = NULL; - LIST_FOR_EACH(mon, Monitors) + for (int m = 0; m < MAX_MONITORS; m++) { + mon = &Monitors[m]; int left = max(cleft, mon->x); int right = min(cright, mon->x + mon->w); int top = max(ctop, mon->y); @@ -265,84 +230,76 @@ void mons_lower(Monitor* mon, Client* c) void mons_colsplit(void) { - Monitor* mon = pickmon(); - Column* col = pickcol(mon->cspace->columns, PtrX - mon->x); - int next_empty = (col->next && !col->next->clients); - if (col->clients && !next_empty && col->width >= 2*min_col_width(mon)) - { - Column* newcol = ecalloc(1, sizeof(Column)); - newcol->width = col->width/2; - col->width -= newcol->width; - newcol->next = col->next; - col->next = newcol; - adjust_all(col, 0); - } +// Monitor* mon = pickmon(); +// Column* col = pickcol(mon->cspace->columns, PtrX - mon->x); +// int next_empty = (col->next && !col->next->clients); +// if (col->clients && !next_empty && col->width >= 2*min_col_width(mon)) +// { +// Column* newcol = ecalloc(1, sizeof(Column)); +// newcol->width = col->width/2; +// col->width -= newcol->width; +// newcol->next = col->next; +// col->next = newcol; +// adjust_all(col, 0); +// } } void mons_coljoin(void) { - Monitor* mon = pickmon(); - Column* dest = pickcol(mon->cspace->columns, PtrX - mon->x); - Column* dead = dest->next; - if (!dead) - { - dead = dest; - dest = list_prev(mon->cspace->columns, dead); - } - - if (dest && dead) - { - /* add the clients to the current col */ - for (Client* c = dead->clients; c;) - { - Client* next = c->next; - if (dest->focused) - { - - monocled_add(&(Location){mon, NULL, dest, c}); - } - else - { - stacked_add(&(Location){mon, NULL, dest, c}); - } - c = next; - } - dest->next = dead->next; - dest->width += dead->width; - free(dead); - adjust_all(dest, 0); - } +// Monitor* mon = pickmon(); +// Column* dest = pickcol(mon->cspace->columns, PtrX - mon->x); +// Column* dead = dest->next; +// if (!dead) +// { +// dead = dest; +// dest = list_prev(mon->cspace->columns, dead); +// } +// +// if (dest && dead) +// { +// /* add the clients to the current col */ +// for (Client* c = dead->clients; c;) +// { +// Client* next = c->next; +// tile_add(&(Location){mon, NULL, dest, c}); +// c = next; +// } +// dest->next = dead->next; +// dest->width += dead->width; +// free(dead); +// adjust_all(dest, 0); +// } } void mons_coladjust(Monitor* mon, Column* col, int wdiff) { - Column* neighbor = col->next; - int minwidth = min_col_width(mon); - if (X.edge == E_LEFT && mon->cspace->columns != col) - { - for (neighbor = mon->cspace->columns; neighbor && neighbor->next != col; neighbor = neighbor->next); - int minadj = -(neighbor->width - minwidth); - int maxadj = (col->width - minwidth); - wdiff = min(max(minadj, wdiff), maxadj); - neighbor->width += wdiff; - col->width -= wdiff; - adjust_all(col, wdiff); - adjust_all(neighbor, 0); - } - else if (X.edge == E_RIGHT && col->next) - { - int minadj = -(col->width - minwidth); - int maxadj = (neighbor->width - minwidth); - wdiff = min(max(minadj, wdiff), maxadj); - col->width += wdiff; - neighbor->width -= wdiff; - adjust_all(col, 0); - adjust_all(neighbor, wdiff); - } - else - { - /* invalid edge */ - } +// Column* neighbor = col->next; +// int minwidth = min_col_width(mon); +// if (X.edge == E_LEFT && mon->cspace->columns != col) +// { +// for (neighbor = mon->cspace->columns; neighbor && neighbor->next != col; neighbor = neighbor->next); +// int minadj = -(neighbor->width - minwidth); +// int maxadj = (col->width - minwidth); +// wdiff = min(max(minadj, wdiff), maxadj); +// neighbor->width += wdiff; +// col->width -= wdiff; +// adjust_all(col, wdiff); +// adjust_all(neighbor, 0); +// } +// else if (X.edge == E_RIGHT && col->next) +// { +// int minadj = -(col->width - minwidth); +// int maxadj = (neighbor->width - minwidth); +// wdiff = min(max(minadj, wdiff), maxadj); +// col->width += wdiff; +// neighbor->width -= wdiff; +// adjust_all(col, 0); +// adjust_all(neighbor, wdiff); +// } +// else +// { +// /* invalid edge */ +// } } void mons_tilemove(Location* loc, int hdiff) @@ -355,18 +312,11 @@ void mons_tilemove(Location* loc, int hdiff) client_setshade(loc->client, 0); loc->monitor = mon; loc->column = col; - if (col->focused) - { - monocled_add(loc); - } - else - { - stacked_add(loc); - } + tile_add(loc); } else { - stacked_addheight(loc, hdiff); + tile_addheight(loc, hdiff); } mouse_totitle(loc->client); } @@ -377,12 +327,7 @@ void mons_activate(Window win) if (mons_find(win, &loc)) { change_wspace(loc.monitor, loc.workspace); - if (loc.column && loc.column->focused) - { - monocled_raise(&loc); - mons_layer(loc.monitor); - } - else if (!loc.column) + if (!loc.column) { mons_raise(loc.monitor, loc.client); } @@ -392,12 +337,18 @@ void mons_activate(Window win) static Monitor* pickmon(void) { mouse_get(&PtrX, &PtrY); + int m = 0; Monitor* mon; - LIST_FOR_EACH_UNTIL(mon, Monitors, - (mon->x <= PtrX && PtrX < mon->x+mon->w) && - (mon->y <= PtrY && PtrY < mon->y+mon->h) - ); - mon = (mon ? mon : Monitors); + for (; m < MAX_MONITORS; m++) + { + mon = &Monitors[m]; + if ((mon->x <= PtrX && PtrX < mon->x+mon->w) && + (mon->y <= PtrY && PtrY < mon->y+mon->h)) + { + break; + } + } + mon = (m < MAX_MONITORS ? mon : &Monitors[0]); return mon; } @@ -406,8 +357,9 @@ static Column* pickcol(Column* cols, int relx) Column* col; int left = 0, right = 0; printf("cols %p\n", (void*)cols); - LIST_FOR_EACH(col, cols) + for (int i = 0; i < MAX_COLUMNS; i++) { + col = &(cols[i]); printf("curr = %p\n", (void*)col); left = right, right += col->width; printf("%d <= %d < %d\n", left, relx, right); @@ -423,10 +375,7 @@ static Column* pickcol(Column* cols, int relx) static Workspace* pickws(Monitor* mon, int wsid) { - Workspace* wspace; - int i = 0; - LIST_FOR_EACH_UNTIL(wspace, mon->wspaces, (i++ == wsid)); - return wspace; + return &(mon->wspaces[wsid]); } static void client_visibility(Workspace* wspace, int show) @@ -437,8 +386,9 @@ static void client_visibility(Workspace* wspace, int show) { client_show(client, show); } - LIST_FOR_EACH(col, wspace->columns) + for (int i = 0; i < wspace->ncolumns; i++) { + col = &(wspace->columns[i]); LIST_FOR_EACH(client, col->clients) { client_show(client, show); @@ -466,27 +416,17 @@ static void add_client(Monitor* mon, Client* c, int ptrx) } else { - /* find first empty column, and fill that first */ + /* find first empty column, and fill that first, otherwise use the last column we find */ Column* col = NULL; - LIST_FOR_EACH_UNTIL(col, mon->cspace->columns, col->clients == NULL); - if (!col) + for (int i = 0; i < mon->cspace->ncolumns; i++) { - /* otherwise pick the column to the right or the current column */ - col = pickcol(mon->cspace->columns, ptrx - mon->x); - if (col->next) + col = &(mon->cspace->columns[i]); + if (col->clients == NULL) { - col = col->next; + break; } } - /* add in monocled or stacked mode */ - if (col->focused) - { - monocled_add(&(Location){mon, NULL, col, c}); - } - else - { - stacked_add(&(Location){mon, NULL, col, c}); - } + tile_add(&(Location){mon, NULL, col, c}); } mons_layer(mon); } @@ -497,26 +437,22 @@ static void remove_client(Location* loc, Client* c) { loc->workspace->floating = list_del(loc->workspace->floating, c); } - else if (loc->column->focused) - { - monocled_del(loc); - } else { - stacked_del(loc); + tile_del(loc); } } -static void adjust_all(Column* col, int xoff) -{ - Client* c; - LIST_FOR_EACH(c, col->clients) - { - c->x += xoff; - c->w = col->width; - client_adjust(c); - } -} +//static void adjust_all(Column* col, int xoff) +//{ +// Client* c; +// LIST_FOR_EACH(c, col->clients) +// { +// c->x += xoff; +// c->w = col->width; +// client_adjust(c); +// } +//} static void change_wspace(Monitor* mon, Workspace* wspace) { diff --git a/bin/winmgr/mouse.c b/bin/winmgr/mouse.c index fbd8973..1f1e8de 100644 --- a/bin/winmgr/mouse.c +++ b/bin/winmgr/mouse.c @@ -55,20 +55,7 @@ static void raise_client(Location* loc) static void stack_clients(Location* loc) { - stacked_set(loc); -} - -static void rotate_client(Location* loc) -{ - Client *tail, *client = loc->column->clients; - if (client->next) - { - loc->column->clients = client->next; - tail = list_last(loc->column->clients); - client->next = NULL; - tail->next = client; - monocled_raise(loc); - } + tile_set(loc); } static void reposition_tile(Location* loc) @@ -77,11 +64,6 @@ static void reposition_tile(Location* loc) X.mode = (X.edge == E_TOP ? M_TILE_RESIZE : M_COL_RESIZE); } -static void monocle_client(Location* loc) -{ - monocled_raise(loc); -} - MouseAct Floating[] = { { 0, Button1, ButtonPress, resize_frame }, { MODKEY|ShiftMask, Button2, ButtonPress, toggle_float }, @@ -91,19 +73,11 @@ MouseAct Floating[] = { { 0, Button5, ButtonPress, raise_client } }; -MouseAct Monocled[] = { - { 0, Button1, ButtonPress, stack_clients }, - { MODKEY|ShiftMask, Button2, ButtonPress, toggle_float }, - { MODKEY, Button2, ButtonPress, close_client }, - { 0, Button3, ButtonPress, rotate_client }, -}; - MouseAct Stacked[] = { { 0, Button1, ButtonPress, reposition_tile }, { MODKEY|ShiftMask, Button2, ButtonPress, toggle_float }, { MODKEY, Button2, ButtonPress, close_client }, { 0, Button2, ButtonPress, stack_clients }, - { 0, Button3, ButtonPress, monocle_client }, }; static void process(XButtonEvent* ev, Location* loc, MouseAct* actions, int nactions) @@ -131,10 +105,6 @@ void mouse_down(XButtonEvent* ev, Location* loc) { process(ev, loc, Floating, sizeof(Floating)/sizeof(Floating[0])); } - else if (loc->column->focused) - { - process(ev, loc, Monocled, sizeof(Monocled)/sizeof(Monocled[0])); - } else { process(ev, loc, Stacked, sizeof(Stacked)/sizeof(Stacked[0])); @@ -202,3 +172,19 @@ void mouse_get(int* ptrx, int* ptry) XQueryPointer(X.disp, X.root, &root, &child, ptrx, ptry, &winx, &winy, (unsigned int*)&mask); } +void Mouse_ToCorner(Client* client) +{ +} + +void Mouse_Down(XButtonEvent* ev, Client* client) +{ +} + +void Mouse_Up(XButtonEvent* ev, Client* client) +{ +} + +void Mouse_Drag(XMotionEvent* ev, Client* client) +{ +} + diff --git a/bin/winmgr/revised.h b/bin/winmgr/revised.h deleted file mode 100644 index 047efec..0000000 --- a/bin/winmgr/revised.h +++ /dev/null @@ -1,70 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -typedef struct { - Display* disp; - int screen, mode, edge, start_x, start_y, last_x, last_y; - Window root; - unsigned long clr_bg, clr_bdr, clr_urgent; - Cursor csr_root, csr_point, csr_move; - XFontSet font; - XFontSetExtents *font_ext; - Visual* visual; - void (*eventfns[LASTEvent])(XEvent*); -} XConf; - -#define MIN_COLUMN_FACTOR 0.10 -#define MAX_COLUMNS 10 -#define MAX_COLUMN_CLIENTS 128 -#define MAX_FLOATING_CLIENTS 128 -#define NUM_WORKSPACES 10 -#define MAX_MONITORS 4 - -/* calculate the size of the client pool */ -#define MAX_WSPACE_CLIENTS (MAX_COLUMNS * MAX_COLUMN_CLIENTS + MAX_FLOATING_CLIENTS) -#define MAX_MONITOR_CLIENTS (NUM_WORKSPACES * MAX_WSPACE_CLIENTS) -#define MAX_CLIENTS (MAX_MONITORS * MAX_MONITOR_CLIENTS) - -typedef struct Client { - char* name; - Window frame, win; - int flags, x, y, w, h; - long hint_flags, wm_flags; - XSizeHints hints; - Pixmap pixmap; - Visual visual; -} Client; - -typedef struct Column { - int width, focused; - Client* clients[MAX_COLUMN_CLIENTS]; -} Column; - -typedef struct Workspace { - Client* floating[MAX_FLOATING_CLIENTS]; - Column columns[MAX_COLUMNS]; -} Workspace; - -typedef struct Monitor { - int x, y, w, h, midx, midy, cspace; - Workspace wspaces[NUM_WORKSPACES]; -} Monitor; - -typedef struct Location { - Monitor* monitor; - Workspace* workspace; - Column* column; - Client* client; -} Location; diff --git a/bin/winmgr/tile.c b/bin/winmgr/tile.c index 6da1d8e..a78c645 100644 --- a/bin/winmgr/tile.c +++ b/bin/winmgr/tile.c @@ -4,64 +4,16 @@ static void coldims(Monitor *mon, Column *col, int *x, int *y, int *w, int *h) { Column* c; *x = mon->x, *y = mon->y, *w = col->width, *h = mon->h; - LIST_FOR_EACH_UNTIL(c, mon->cspace->columns, (c == col)) - { - *x += c->width; - } -} -void monocled_add(Location* loc) -{ - Client* c = loc->client; - coldims(loc->monitor, loc->column, &(c->x), &(c->y), &(c->w), &(c->h)); - client_setshade(c, 0); - client_adjust(c); - c->next = loc->column->clients; - loc->column->clients = c; - loc->column->focused = c; -} - -void monocled_del(Location* loc) -{ - Client* c = loc->client; - loc->column->clients = list_del(loc->column->clients, c); - loc->column->focused = loc->column->clients; - c = loc->column->clients; - if (c) + int curr = (col - &mon->cspace->columns[0]) / sizeof(Column); + for (int i = 0; i < curr; i++) { - coldims(loc->monitor, loc->column, &(c->x), &(c->y), &(c->w), &(c->h)); - client_setshade(c, 0); - client_adjust(c); + c = &mon->cspace->columns[i]; + *x += c->width; } } -void monocled_raise(Location* loc) -{ - loc->column->clients = list_del(loc->column->clients, loc->client); - loc->client->next = loc->column->clients; - loc->column->clients = loc->client; - loc->column->focused = loc->client; - coldims(loc->monitor, loc->column, - &(loc->client->x), &(loc->client->y), &(loc->client->w), &(loc->client->h)); - client_setshade(loc->client, 0); - client_adjust(loc->client); - mons_layer(loc->monitor); -} - -void monocled_set(Location* loc) -{ - loc->column->clients = list_del(loc->column->clients, loc->client); - loc->client->next = loc->column->clients; - loc->column->clients = loc->client; - loc->column->focused = loc->client; - coldims(loc->monitor, loc->column, - &(loc->client->x), &(loc->client->y), &(loc->client->w), &(loc->client->h)); - client_setshade(loc->client, 0); - client_adjust(loc->client); - mons_layer(loc->monitor); -} - -void stacked_add(Location* loc) +void tile_add(Location* loc) { Client* c = loc->client; coldims(loc->monitor, loc->column, &(c->x), &(c->y), &(c->w), &(c->h)); @@ -77,18 +29,11 @@ void stacked_add(Location* loc) } if (max->h < 3*MIN_HEIGHT) { - if (loc->column->next) - { - stacked_add(loc); - } - else - { - c->next = loc->monitor->cspace->floating; - loc->monitor->cspace->floating = c; - c->x = loc->monitor->midx - c->w/2; - c->y = loc->monitor->midy - c->h/2; - client_adjust(c); - } + c->next = loc->monitor->cspace->floating; + loc->monitor->cspace->floating = c; + c->x = loc->monitor->midx - c->w/2; + c->y = loc->monitor->midy - c->h/2; + client_adjust(c); } else { @@ -110,7 +55,7 @@ void stacked_add(Location* loc) } } -void stacked_del(Location* loc) +void tile_del(Location* loc) { Client* c = loc->client; if (loc->column->clients == c) @@ -134,10 +79,9 @@ void stacked_del(Location* loc) } } -void stacked_set(Location* loc) +void tile_set(Location* loc) { Client *curr, *c = loc->client; - loc->column->focused = NULL; int starty = loc->monitor->y; /* stack the windows before the target */ LIST_FOR_EACH_UNTIL(curr, loc->column->clients, curr == c) @@ -167,7 +111,7 @@ void stacked_set(Location* loc) } } -void stacked_addheight(Location* loc, int amount) +void tile_addheight(Location* loc, int amount) { Client* c = loc->client; Client* prev = list_prev(loc->column->clients, c); diff --git a/bin/winmgr/winmgr.c b/bin/winmgr/winmgr.c index d039546..bb68e1e 100644 --- a/bin/winmgr/winmgr.c +++ b/bin/winmgr/winmgr.c @@ -3,6 +3,7 @@ XConf X = {0}; +/* Checks if another window manager is already running */ static void check_for_wm(void) { error_default = XSetErrorHandler(error_init); @@ -12,79 +13,61 @@ static void check_for_wm(void) XSync(X.disp, False); } -static void xbtnpress(XEvent* e) +/* Handles newly mapped windows. */ +static void xmaprequest(XEvent* e) { - XButtonEvent* ev = &(e->xbutton); - XGrabPointer(X.disp, ev->window, False, - ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, - GrabModeAsync, GrabModeAsync, None, X.csr_move, CurrentTime); - //printf("BTN_DN(w: 0x%lx s: %d x: %d y: %d rx: %d ry: %d)\n", ev->window, ev->state, ev->x, ev->y, ev->x_root, ev->y_root); - X.start_x = ev->x_root, X.start_y = ev->y_root; - X.last_x = ev->x_root, X.last_y = ev->y_root; - Location loc = {0}; - if (mons_find(ev->window, &loc) && (loc.client->frame == ev->window)) + XMapRequestEvent* ev = &(e->xmaprequest); + //printf("MAP(w: 0x%lx)\n", ev->window); + XWindowAttributes attr; + + /* if no record of this window exists, add it to our managed list */ + if (!Client_Find(ev->window)) { - Client* c = loc.client; - if (ev->y < MIN_HEIGHT) - { - X.edge = E_TOP; - } - else if (ev->y_root > (c->y + c->h - BORDER_WIDTH)) - { - X.edge = E_BOTTOM; - } - else if (ev->x < BORDER_WIDTH) - { - X.edge = E_LEFT; - } - else if (ev->x_root > (c->x + c->w - BORDER_WIDTH)) + if (XGetWindowAttributes(X.disp, ev->window, &attr) && !attr.override_redirect) { - X.edge = E_RIGHT; + Client_Add(ev->window, &attr); } - else - { - X.edge = E_NONE; - } - mouse_down(ev, &loc); } } -static void xbtnrelease(XEvent* e) +/* Handle unmap events for window we manage. + TODO: This is probably busted right now. mplab x windows have a habit of being + remapped since they don't get destroyed. Probably need an explicit state + for that (ex. withdrawn) +*/ +static void xunmapnotify(XEvent* e) { - XButtonEvent* ev = &(e->xbutton); - //printf("BTN_UP(w: 0x%lx x: %d y: %d rx: %d ry: %d)\n", ev->window, ev->x, ev->y, ev->x_root, ev->y_root); - Location loc = {0}; - if (mons_find(ev->window, &loc) && (loc.client->frame == ev->window)) - { - mouse_up(ev, &loc); - } - X.mode = M_IDLE; - XUngrabPointer(X.disp, CurrentTime); -} + XUnmapEvent* ev = &(e->xunmap); + //printf("UNMAP(e: 0x%lx w: 0x%lx %d)\n", ev->event, ev->window, ev->from_configure); -static void xbtnmotion(XEvent* e) -{ - /* make sure we get just the latest event */ - XMotionEvent *ev = &e->xmotion; - //printf("BTN_MV(w: 0x%lx x: %d y: %d rx: %d ry: %d)\n", ev->window, ev->x, ev->y, ev->x_root, ev->y_root); - while (XCheckTypedWindowEvent(X.disp, ev->window, ev->type, e)); - Location loc = {0}; - if (mons_find(ev->window, &loc) && (loc.client->frame == ev->window)) + Client* client = Client_Find(ev->window); + if (client) { - mouse_drag(ev, &loc); + if (ev->event == X.root) + { + Client_Del(client); + } + else if ( !(client->flags & F_SHADED) ) + { + XUnmapWindow(X.disp, client->frame); + } } - X.last_x = ev->x_root, X.last_y = ev->y_root; } -static void xconfignotify(XEvent* e) +/* Handle closed/destroyed windows */ +static void xdestroynotify(XEvent* e) { - XConfigureEvent* ev = &(e->xconfigure); - if (ev->window == X.root) + XDestroyWindowEvent* ev = &(e->xdestroywindow); + //printf("DESTROY(w: 0x%lx)\n", ev->window); + + Client* client = Client_Find(ev->window); + if (client) { - puts("root window resized"); + Client_Del(client); } } +/* Handle window resize requests. Ignore them for tiled windows. */ static void xconfigrequest(XEvent* e) { XConfigureRequestEvent* ev = &(e->xconfigurerequest); @@ -97,20 +80,22 @@ static void xconfigrequest(XEvent* e) wc.border_width = ev->border_width; wc.sibling = ev->above; wc.stack_mode = ev->detail; - Location loc = {0}; - if (mons_find(ev->window, &loc)) + + Client* client = Client_Find(ev->window); + if (client) { /* only allow floating clients to resize on their own */ - if ((loc.client->win == ev->window) && !loc.column) + if ((client->win == ev->window) && !client->column) { - loc.client->w = wc.width + FRAME_WIDTH_SUM; - loc.client->h = wc.height + FRAME_HEIGHT_SUM; - client_adjust(loc.client); - if (X.mode == M_RESIZE && Focused == loc.client) + client->w = wc.width + FRAME_WIDTH_SUM; + client->h = wc.height + FRAME_HEIGHT_SUM; + Client_AdjustSize(client); + if (X.mode == M_RESIZE && Focused == client) { - mouse_tocorner(loc.client); + mouse_tocorner(client); } } + } else { @@ -118,102 +103,133 @@ static void xconfigrequest(XEvent* e) } } -static void xmaprequest(XEvent* e) -{ - XMapRequestEvent* ev = &(e->xmaprequest); - //printf("MAP(w: 0x%lx)\n", ev->window); - XWindowAttributes attr; - Location loc = {0}; - if (!mons_find(ev->window, &loc)) - { - if (XGetWindowAttributes(X.disp, ev->window, &attr) && !attr.override_redirect) - { - (void)client_add(ev->window, &attr); - } - } -} - -static void xunmapnotify(XEvent* e) -{ - XUnmapEvent* ev = &(e->xunmap); - //printf("UNMAP(e: 0x%lx w: 0x%lx %d)\n", ev->event, ev->window, ev->from_configure); - Location loc = {0}; - if (mons_find(ev->window, &loc))// && loc.client->win == ev->window) - { - if (ev->event == X.root && ev->window == loc.client->win) - { - mons_delclient(&loc); - } - else if ( !(loc.client->flags & F_SHADED) ) - { - XUnmapWindow(X.disp, loc.client->frame); - } - } -} - -static void xdestroynotify(XEvent* e) -{ - XDestroyWindowEvent* ev = &(e->xdestroywindow); - //printf("DESTROY(w: 0x%lx)\n", ev->window); - Location loc = {0}; - if (mons_find(ev->window, &loc)) - { - mons_delclient(&loc); - } -} - +/* Handle client messages. ICCM and EWMH stuff. */ static void xclientmsg(XEvent* e) { XClientMessageEvent* ev = &(e->xclient); //printf("CLIENT_MSG(w: 0x%lx a: '%s')\n", ev->window, XGetAtomName(X.disp, ev->message_type)); + if (ev->message_type == atom("_NET_ACTIVE_WINDOW")) { - mons_activate(ev->window); + Client_SetActive(ev->window); } } +/* Handle window properties */ static void xpropnotify(XEvent* e) { XPropertyEvent* ev = &(e->xproperty); //printf("PROP_NOTIFY(w: 0x%lx)\n", ev->window); - Location loc = {0}; - if (mons_find(ev->window, &loc)) + + Client* client = Client_Find(ev->window); + if (client) { - client_readprops(loc.client); - client_draw(loc.client); + Client_ReadProps(client); + Client_Draw(client); } } +/* Handle window focus. Focus follows mouse */ static void xenternotify(XEvent* e) { XCrossingEvent* ev = &(e->xcrossing); - Location loc = {0}; //printf("ENTER(w: 0x%lx s: %d m: %d d: %d)\n", ev->window, ev->state, ev->mode, ev->detail); - if (mons_find(ev->window, &loc)) + + Client* client = Client_Find(ev->window); + if (client) { - client_focus(loc.client); + Client_Focus(client); } } +/* Handle redraw events */ static void xexpose(XEvent* e) { XExposeEvent* ev = &(e->xexpose); if (ev->count == 0) { //printf("EXPOSE(w: 0x%lx)\n", ev->window); - Location loc = {0}; - if (mons_find(ev->window, &loc)) + Client* client = Client_Find(ev->window); + if (client) { - client_draw(loc.client); + Client_Draw(client); } } } +static void xbtnpress(XEvent* e) +{ + XButtonEvent* ev = &(e->xbutton); + XGrabPointer(X.disp, ev->window, False, + ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, + GrabModeAsync, GrabModeAsync, None, X.csr_move, CurrentTime); + //printf("BTN_DN(w: 0x%lx s: %d x: %d y: %d rx: %d ry: %d)\n", ev->window, ev->state, ev->x, ev->y, ev->x_root, ev->y_root); + X.start_x = ev->x_root, X.start_y = ev->y_root; + X.last_x = ev->x_root, X.last_y = ev->y_root; + + + Client* client = Client_Find(ev->window); + if (client && (client->frame == ev->window)) + { + if (ev->y < MIN_HEIGHT) + { + X.edge = E_TOP; + } + else if (ev->y_root > (client->y + client->h - BORDER_WIDTH)) + { + X.edge = E_BOTTOM; + } + else if (ev->x < BORDER_WIDTH) + { + X.edge = E_LEFT; + } + else if (ev->x_root > (client->x + client->w - BORDER_WIDTH)) + { + X.edge = E_RIGHT; + } + else + { + X.edge = E_NONE; + } + Mouse_Down(ev, client); + } +} + +static void xbtnrelease(XEvent* e) +{ + XButtonEvent* ev = &(e->xbutton); + //printf("BTN_UP(w: 0x%lx x: %d y: %d rx: %d ry: %d)\n", ev->window, ev->x, ev->y, ev->x_root, ev->y_root); + + Client* client = Client_Find(ev->window); + if (client && (client->frame == ev->window)) + { + Mouse_Up(ev, client); + } + X.mode = M_IDLE; + XUngrabPointer(X.disp, CurrentTime); +} + +static void xbtnmotion(XEvent* e) +{ + /* make sure we get just the latest event */ + XMotionEvent *ev = &e->xmotion; + //printf("BTN_MV(w: 0x%lx x: %d y: %d rx: %d ry: %d)\n", ev->window, ev->x, ev->y, ev->x_root, ev->y_root); + + while (XCheckTypedWindowEvent(X.disp, ev->window, ev->type, e)); + Client* client = Client_Find(ev->window); + if (client && (client->frame == ev->window)) + { + Mouse_Drag(ev, client); + } + X.last_x = ev->x_root, X.last_y = ev->y_root; +} + static void xkeypress(XEvent* e) { XKeyEvent* ev = &(e->xkey); //printf("KEY_DN(w: 0x%lx)\n", ev->window); - keys_run(ev); + + Keys_Run(ev); } static void init_cursors(void) @@ -281,7 +297,6 @@ int main(void) X.eventfns[ButtonRelease] = xbtnrelease; X.eventfns[MotionNotify] = xbtnmotion; X.eventfns[KeyPress] = xkeypress; - X.eventfns[ConfigureNotify] = xconfignotify; X.eventfns[ConfigureRequest] = xconfigrequest; X.eventfns[MapRequest] = xmaprequest; X.eventfns[UnmapNotify] = xunmapnotify; -- 2.52.0