From eefa2034ad0f5c2ef5eb478984cfc53a6a40c6b7 Mon Sep 17 00:00:00 2001 From: Andy Spencer Date: Thu, 29 Sep 2011 05:59:12 +0000 Subject: [PATCH] Cleanup and lots of commenting --- main.c | 17 ++++++ makefile | 35 +++++------- sys-win32.c | 67 +++++++++++++--------- sys-x11.c | 55 ++++++++++++------ sys.h | 97 +++++++++++++++++++++++--------- util.c | 18 ++++++ util.h | 21 ++++++- wm-wmii.c | 159 ++++++++++++++++++++++++++++++++++++---------------- wm.h | 38 ++++++++++++- 9 files changed, 365 insertions(+), 142 deletions(-) diff --git a/main.c b/main.c index 2d81508..8fbec9c 100644 --- a/main.c +++ b/main.c @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2011 Andy Spencer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + #include #include diff --git a/makefile b/makefile index 2920b48..651cf2c 100644 --- a/makefile +++ b/makefile @@ -1,27 +1,18 @@ -WM=wmii +WM ?= wmii +SYS ?= x11 +CFLAGS ?= -g -Wall -Werror -SYS=x11 -CC=gcc -PROG=wmpus -CFLAGS=-g -Werror -Wall -LIBS=-Wl,--as-needed -lX11 -lXinerama -TEST=DISPLAY=:2.0 - -WIN32?= -ifdef WIN32 -SYS=win32 -CC=i686-pc-mingw32-gcc -CFLAGS=-g -Werror -Wall -D_NO_OLDNAMES -DMARGIN=15 -LIBS= -PROG=wmpus.exe -TEST=cp -t /t/htdocs/temp +ifeq ($(SYS),x11) +CC = gcc +LIBS += -lX11 -lXinerama +PROG = wmpus endif -test: $(PROG) - $(TEST) ./$< - -debug: $(PROG) - $(TEST) gdb ./$< +ifeq ($(SYS),win32) +CC = i686-pc-mingw32-gcc +CFLAGS += -D_NO_OLDNAMES -DMARGIN=15 +PROG = wmpus.exe +endif $(PROG): main.o util.o sys-$(SYS).o wm-$(WM).o $(CC) $(CFLAGS) -o $@ $+ $(LIBS) @@ -30,4 +21,4 @@ $(PROG): main.o util.o sys-$(SYS).o wm-$(WM).o $(CC) --std=gnu99 $(CFLAGS) -c -o $@ $< clean: - rm -f $(PROG) *.o + rm -f wmpus *.exe *.o diff --git a/sys-win32.c b/sys-win32.c index 1edc5d2..04e4ef4 100644 --- a/sys-win32.c +++ b/sys-win32.c @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2011 Andy Spencer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + #include #include #include @@ -99,7 +116,7 @@ static ptr_t getptr(void) return (ptr_t){-1, -1, wptr.x, wptr.y}; } -/* Helpers */ +/* Window functions */ static win_t *win_new(HWND hwnd, int checkwin) { if (checkwin) { @@ -259,9 +276,27 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) return DefWindowProc(hwnd, msg, wParam, lParam); } -/***************** - * Sys functions * - *****************/ +BOOL CALLBACK MonProc(HMONITOR mon, HDC dc, LPRECT rect, LPARAM _screens) +{ + MONITORINFO info = {.cbSize=sizeof(MONITORINFO)}; + GetMonitorInfo(mon, &info); + RECT *work = &info.rcWork; + + list_t **screens = (list_t**)_screens; + win_t *screen = new0(win_t); + screen->x = work->left; + screen->y = work->top; + screen->w = work->right - work->left; + screen->h = work->bottom - work->top; + *screens = list_append(*screens, screen); + printf("mon_proc: %d,%d %dx%d\n", + screen->x, screen->y, screen->w, screen->h); + return TRUE; +} + +/******************** + * System functions * + ********************/ void sys_move(win_t *win, int x, int y, int w, int h) { printf("sys_move: %p - %d,%d %dx%d\n", win, x, y, w, h); @@ -286,8 +321,8 @@ void sys_focus(win_t *win) printf("sys_focus: %p\n", win); /* Windows prevents a thread from using SetForegroundInput under - * certain circumstnaces and instead flashes the windows toolbar icon. - * Attaching the htread input queues avoids this behavior */ + * certain circumstances and instead flashes the windows toolbar icon. + * Attaching the thread input queues avoids this behavior */ DWORD oldId = GetWindowThreadProcessId(GetForegroundWindow(), NULL); DWORD newId = GetWindowThreadProcessId(win->sys->hwnd, NULL); AttachThreadInput(oldId, newId, TRUE); @@ -324,28 +359,10 @@ void sys_unwatch(win_t *win, Key_t key, mod_t mod) //printf("sys_unwatch: %p\n", win); } -BOOL CALLBACK Mon(HMONITOR mon, HDC dc, LPRECT rect, LPARAM _screens) -{ - MONITORINFO info = {.cbSize=sizeof(MONITORINFO)}; - GetMonitorInfo(mon, &info); - RECT *work = &info.rcWork; - - list_t **screens = (list_t**)_screens; - win_t *screen = new0(win_t); - screen->x = work->left; - screen->y = work->top; - screen->w = work->right - work->left; - screen->h = work->bottom - work->top; - *screens = list_append(*screens, screen); - printf("mon_proc: %d,%d %dx%d\n", - screen->x, screen->y, screen->w, screen->h); - return TRUE; -} - list_t *sys_info(win_t *win) { list_t *screens = NULL; - EnumDisplayMonitors(NULL, NULL, Mon, (LPARAM)&screens); + EnumDisplayMonitors(NULL, NULL, MonProc, (LPARAM)&screens); return screens; } diff --git a/sys-x11.c b/sys-x11.c index 92eb870..4157421 100644 --- a/sys-x11.c +++ b/sys-x11.c @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2011 Andy Spencer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + #include #include #include @@ -133,8 +150,10 @@ static Window getfocus(win_t *root, XEvent *event) return focus; } -/* Helpers */ -static int copy_strut(win_t *to, win_t *from, int scale) +/* Strut functions + * Struts are spaces at the edges of the screen that are used by + * toolbars and statusbars such as dzen. */ +static int strut_copy(win_t *to, win_t *from, int scale) { int left = from->sys->strut.left; int right = from->sys->strut.right; @@ -149,7 +168,7 @@ static int copy_strut(win_t *to, win_t *from, int scale) return 1; } -static int add_strut(win_t *root, win_t *win) +static int strut_add(win_t *root, win_t *win) { /* Get X11 strut data */ Atom ret_type; @@ -167,15 +186,15 @@ static int add_strut(win_t *root, win_t *win) win->sys->strut.top = ((int*)xdata)[2]; win->sys->strut.bottom = ((int*)xdata)[3]; for (list_t *cur = screens; cur; cur = cur->next) - copy_strut(cur->data, win, 1); - return copy_strut(root, win, 1); + strut_copy(cur->data, win, 1); + return strut_copy(root, win, 1); } -static int del_strut(win_t *root, win_t *win) +static int strut_del(win_t *root, win_t *win) { for (list_t *cur = screens; cur; cur = cur->next) - copy_strut(cur->data, win, -1); - return copy_strut(root, win, -1); + strut_copy(cur->data, win, -1); + return strut_copy(root, win, -1); } /* Window functions */ @@ -241,7 +260,7 @@ static int win_viewable(win_t *win) } /* Drawing functions */ -unsigned long get_color(Display *dpy, const char *name) +static unsigned long get_color(Display *dpy, const char *name) { XColor color; int screen = DefaultScreen(dpy); @@ -322,7 +341,7 @@ static void process_event(int type, XEvent *ev, win_t *root) else if (type == UnmapNotify) { if ((win = win_find(dpy,ev->xunmap.window,0)) && win->sys->state == st_show) { - if (!del_strut(root, win)) + if (!strut_del(root, win)) wm_remove(win); else wm_update(); @@ -346,7 +365,7 @@ static void process_event(int type, XEvent *ev, win_t *root) .height = cre->height, }); - /* This seems necessasairy for, but causes flicker + /* This seems necessary for, but causes flicker * there could be a better way to do this */ if ((win = win_find(dpy,ev->xmaprequest.window,0))) sys_move(win, win->x, win->y, win->w, win->h); @@ -354,7 +373,7 @@ static void process_event(int type, XEvent *ev, win_t *root) else if (type == MapRequest) { printf("map_req: %d\n", type); if ((win = win_find(dpy,ev->xmaprequest.window,1))) { - if (!add_strut(root, win)) + if (!strut_add(root, win)) wm_insert(win); else wm_update(); @@ -381,9 +400,9 @@ static int xerror(Display *dpy, XErrorEvent *err) return xerrorxlib(dpy, err); } -/***************** - * Sys functions * - *****************/ +/******************** + * System functions * + ********************/ void sys_move(win_t *win, int x, int y, int w, int h) { //printf("sys_move: %p - %d,%d %dx%d\n", win, x, y, w, h); @@ -393,7 +412,7 @@ void sys_move(win_t *win, int x, int y, int w, int h) w = MAX(w-b,1); h = MAX(h-b,1); XMoveResizeWindow(win->sys->dpy, win->sys->xid, x, y, w, h); - /* Flush events, so moving window doesn't cuase re-focus + /* Flush events, so moving window doesn't cause re-focus * There's probably a better way to do this */ XEvent ev; XSync(win->sys->dpy, False); @@ -529,7 +548,7 @@ win_t *sys_init(void) colors[clr_urgent] = get_color(dpy, "#ff0000"); printf("colors = #%06lx #%06lx #%06lx\n", colors[0], colors[1], colors[2]); - /* Selec Window Managmenet events */ + /* Select window management events */ XSelectInput(dpy, xid, SubstructureRedirectMask|SubstructureNotifyMask); XSetInputFocus(dpy, None, RevertToNone, CurrentTime); xerrorxlib = XSetErrorHandler(xerror); @@ -546,7 +565,7 @@ void sys_run(win_t *root) &par, &xid, &kids, &nkids)) for(int i = 0; i < nkids; i++) { win_t *win = win_find(root->sys->dpy, kids[i], 1); - if (win && win_viewable(win) && !add_strut(root,win)) + if (win && win_viewable(win) && !strut_add(root,win)) wm_insert(win); } wm_update(); // For struts diff --git a/sys.h b/sys.h index 01a1734..0c6dfe6 100644 --- a/sys.h +++ b/sys.h @@ -1,3 +1,32 @@ +/* + * Copyright (C) 2011 Andy Spencer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* Windowing system interface: + * + * The sys provides input to the window manager. It creates + * the main loop and responds to input events from the user, + * generally by converting them to a system independent form + * and then passing them to the wm. + * + * The sys also provides the API used by the wm to position + * and control windows. */ + + +/* Basic window type */ typedef struct win_sys win_sys_t; typedef struct win_wm win_wm_t; typedef struct { @@ -7,20 +36,21 @@ typedef struct { win_wm_t *wm; } win_t; +/* Generic key codes, also used for some other events + * Keys map to their Unicode value */ typedef enum { - // 'char' = unicode, - key_alert = '\a', // Bell (alert) - key_backspace = '\b', // Backspace - key_formfeed = '\f', // Formfeed - key_newline = '\n', // New line - key_return = '\r', // Carriage return - key_tab = '\t', // Horizontal tab - key_vtab = '\v', // Vertical tab - key_singlequote = '\'', // Single quotation mark - key_doublequote = '\"', // Double quotation mark - key_backslash = '\\', // Backslash - key_question = '\?', // Literal question mark - key_none = 0xF0000, // unused unicode space + key_alert = '\a', + key_backspace = '\b', + key_formfeed = '\f', + key_newline = '\n', + key_return = '\r', + key_tab = '\t', + key_vtab = '\v', + key_singlequote = '\'', + key_doublequote = '\"', + key_backslash = '\\', + key_question = '\?', + key_none = 0xF0000, // unused Unicode space key_mouse0, key_mouse1, key_mouse2, key_mouse3, key_mouse4, key_mouse5, key_mouse6, key_mouse7, key_left, key_right, key_up, key_down, @@ -32,47 +62,62 @@ typedef enum { key_enter, key_leave, key_focus, key_unfocus, } Key_t; +/* Key modifiers, up is for button release */ typedef struct { unsigned char alt : 1; unsigned char ctrl : 1; unsigned char shift : 1; unsigned char win : 1; unsigned char up : 1; - unsigned char spare : 3; } mod_t; -#define MOD(...) ((mod_t){__VA_ARGS__}) +#define MOD(...) ((mod_t){__VA_ARGS__}) #define mod2int(mod) (*((unsigned char*)&(mod))) +/* Mouse movement */ typedef struct { int x, y; int rx, ry; } ptr_t; #define PTR(...) ((ptr_t){__VA_ARGS__}) +/* Window states */ typedef enum { - st_show, - st_full, - st_shade, - st_icon, - st_hide, + st_show, // show as regular window + st_full, // fullscreen/maximized + st_shade, // show titlebar only + st_icon, // iconified/minimized + st_hide, // completely hidden } state_t; -void sys_watch(win_t *win, Key_t key, mod_t mod); - -void sys_unwatch(win_t *win, Key_t key, mod_t mod); +/* Move the window to the specified location and set it's + * geometry. The position and size include borders and + * window decorations. */ void sys_move(win_t *win, int x, int y, int w, int h); +/* Rise the window above all other windows */ void sys_raise(win_t *win); +/* Give keyboard focus to the window and update window + * decorations. */ void sys_focus(win_t *win); -void sys_foreach(win_t *win); - +/* Set the windows drawing state */ void sys_show(win_t *win, state_t st); -list_t *sys_info(win_t *win); +/* Start watching for a key events. The sys subsequently + * calls wm_handle_key whenever the event occurs. */ +void sys_watch(win_t *win, Key_t key, mod_t mod); + +/* Stop watching a key event */ +void sys_unwatch(win_t *win, Key_t key, mod_t mod); + +/* Return a list of windows representing the geometry of the + * physical displays attached to the computer. */ +list_t *sys_info(win_t *root); +/* First call, calls wm_insert for each existing window */ win_t *sys_init(void); +/* Starts the main loop */ void sys_run(win_t *root); diff --git a/util.c b/util.c index 18f98dc..325c2a2 100644 --- a/util.c +++ b/util.c @@ -1,9 +1,27 @@ +/* + * Copyright (C) 2011 Andy Spencer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + #include #include #include #include "util.h" +/* Doubly linked lists */ list_t *list_insert(list_t *next, void *data) { list_t *node = new0(list_t); diff --git a/util.h b/util.h index 005dba6..2468ebe 100644 --- a/util.h +++ b/util.h @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2011 Andy Spencer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* Various utility functions */ + /* Misc macros */ #define MAX(a,b) ((a) > (b) ? (a) : (b)) #define MIN(a,b) ((a) < (b) ? (a) : (b)) @@ -6,7 +25,7 @@ #define countof(x) (sizeof(x)/sizeof((x)[0])) -/* Constant lenght map functitons */ +/* Constant length map functions */ #define map_getg(map, test) ({ \ int i; \ for (i = 0; i < countof(map) && !(test); i++); \ diff --git a/wm-wmii.c b/wm-wmii.c index 82363ef..2cebd9f 100644 --- a/wm-wmii.c +++ b/wm-wmii.c @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2011 Andy Spencer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + #include #include @@ -24,50 +41,56 @@ typedef enum { split, stack, max, tab } mode_t; - /* Window structure types */ struct win_wm { }; typedef struct { - win_t *win; - int height; + win_t *win; // the window + int height; // win height in _this_ tag } row_t; typedef struct { - list_t *rows; // of row_t - row_t *row; - int width; - mode_t mode; + list_t *rows; // of row_t + row_t *row; // focused row + int width; // column width + mode_t mode; // display mode } col_t; typedef struct { - list_t *cols; // of col_t - col_t *col; - win_t *geom; + list_t *cols; // of col_t + col_t *col; // focused col + win_t *geom; // display size and position } dpy_t; typedef struct { - list_t *dpys; // of dpy_t - dpy_t *dpy; - int name; + list_t *dpys; // of dpy_t + dpy_t *dpy; // focused dpy + int name; // tag name } tag_t; typedef struct { - list_t *tags; // of tag_t - tag_t *tag; - win_t *root; - list_t *screens; + list_t *tags; // of tag_t + tag_t *tag; // focused tag + win_t *root; // root/background window + list_t *screens; // display geometry } wm_t; -/* Mouse drag data */ -static drag_t move_mode; -static list_t *move_lrow; -static list_t *move_lcol; -static ptr_t move_prev; -static struct { int v, h; } move_dir; +#define WIN(node) ((win_t*)(node)->data) +#define ROW(node) ((row_t*)(node)->data) +#define COL(node) ((col_t*)(node)->data) +#define DPY(node) ((dpy_t*)(node)->data) +#define TAG(node) ((tag_t*)(node)->data) + +#define tag_foreach(tag, dpy, col, row, win) \ + for (list_t *dpy = tag ->dpys; dpy; dpy = dpy->next) \ + for (list_t *col = DPY(dpy)->cols; col; col = col->next) \ + for (list_t *row = COL(col)->rows; row; row = row->next) \ + for (win_t *win = ROW(row)->win; win; win = NULL) \ -/* Window management data */ -static wm_t *wm; +/* Window management data + * wm_* macros represent the currently focused item + * _only_ wm_focus protects against NULL pointers */ +static wm_t *wm; #define wm_win wm->tag->dpy->col->row->win #define wm_row wm->tag->dpy->col->row #define wm_col wm->tag->dpy->col @@ -75,19 +98,18 @@ static wm_t *wm; #define wm_tag wm->tag #define wm_focus (wm_tag && wm_dpy && wm_col && wm_row ? wm_win : NULL) -#define WIN(l) ((win_t*)(l)->data) -#define ROW(l) ((row_t*)(l)->data) -#define COL(l) ((col_t*)(l)->data) -#define DPY(l) ((dpy_t*)(l)->data) -#define TAG(l) ((tag_t*)(l)->data) - -#define tag_foreach(tag, dpy, col, row, win) \ - for (list_t *dpy = tag ->dpys; dpy; dpy = dpy->next) \ - for (list_t *col = DPY(dpy)->cols; col; col = col->next) \ - for (list_t *row = COL(col)->rows; row; row = row->next) \ - for (win_t *win = ROW(row)->win; win; win = NULL) \ +/* Mouse drag data */ +static drag_t move_mode; +static list_t *move_lrow; +static list_t *move_lcol; +static ptr_t move_prev; +static struct { int v, h; } move_dir; -/* Helper functions */ +/******************** + * Helper functions * + ********************/ +/* Search for the target window in a given tag + * win may exist in other tags as well */ static int searchl(tag_t *tag, win_t *target, list_t **_dpy, list_t **_col, list_t **_row) { @@ -115,6 +137,7 @@ static int search(tag_t *tag, win_t *target, return 0; } +/* Set the mode for the windows column in the current tag */ static void set_mode(win_t *win, mode_t mode) { col_t *col; @@ -131,6 +154,8 @@ static void set_mode(win_t *win, mode_t mode) wm_update(); } +/* Focus the window in the current tag and record + * it as the currently focused window */ static void set_focus(win_t *win) { if (win == NULL || win == wm->root) { @@ -157,6 +182,7 @@ static void set_focus(win_t *win) sys_focus(win); } +/* Save mouse start location when moving/resizing windows */ static void set_move(win_t *win, ptr_t ptr, drag_t drag) { printf("set_move: %d - %p@%d,%d\n", @@ -165,13 +191,15 @@ static void set_move(win_t *win, ptr_t ptr, drag_t drag) if (drag == move || drag == resize) { searchl(wm_tag, win, NULL, &move_lcol, &move_lrow); move_prev = ptr; - int my = win->y + (win->h/2); - int mx = win->x + (win->w/2); - move_dir.v = ptr.ry < my ? -1 : +1; - move_dir.h = ptr.rx < mx ? -1 : +1; + int midy = win->y + (win->h/2); + int midx = win->x + (win->w/2); + move_dir.v = ptr.ry < midy ? -1 : +1; + move_dir.h = ptr.rx < midx ? -1 : +1; } } +/* Print a text representation of the window layout + * Quite useful for debugging */ static void print_txt(void) { for (list_t *ltag = wm->tags; ltag; ltag = ltag->next) { @@ -199,6 +227,9 @@ static void print_txt(void) } } } } } +/* Cleanly remove a window from a tag + * Determines the new focused row/col + * Prunes empty lists */ static void cut_win(tag_t *tag, win_t *win) { list_t *ldpy, *lcol, *lrow; @@ -218,6 +249,9 @@ static void cut_win(tag_t *tag, win_t *win) } } +/* Insert a window at a given location + * The window is added immediately after the + * columns currently focused row */ static void put_win(win_t *win, tag_t *tag, dpy_t *dpy, col_t *col) { row_t *row = new0(row_t); @@ -246,6 +280,9 @@ static void put_win(win_t *win, tag_t *tag, dpy_t *dpy, col_t *col) } } +/* Move a window up, down, left, or right + * This handles moving with a column, between + * columns, and between multiple monitors. */ static void shift_window(win_t *win, int col, int row) { if (!win) return; @@ -257,6 +294,7 @@ static void shift_window(win_t *win, int col, int row) return; dpy_t *dpy = ldpy->data; if (row != 0) { + /* Move with a column, just swap rows */ list_t *src = lrow, *dst = NULL; if (row < 0) dst = src->prev; if (row > 0) dst = src->next; @@ -268,18 +306,24 @@ static void shift_window(win_t *win, int col, int row) goto update; } } else { + /* Moving between columns */ int onlyrow = !lrow->prev && !lrow->next; list_t *src = lcol, *dst = NULL; if (col < 0) { if (src->prev) { + /* Normal move between columns */ dst = src->prev; } else if (!onlyrow) { + /* Create new column */ dpy->cols = list_insert(dpy->cols, new0(col_t)); dst = src->prev; } else if (ldpy->prev) { + /* Move to next monitor */ dpy = ldpy->prev->data; dst = list_last(dpy->cols); } else { + /* We, shall, not, be, + * we shall not be moved */ return; } } @@ -305,6 +349,7 @@ update: wm_update(); } +/* Get next/prev item, with wraparound */ static list_t *get_next(list_t *list, int forward) { list_t *next = forward ? list->next : list->prev; @@ -315,10 +360,13 @@ static list_t *get_next(list_t *list, int forward) } return next; } + +/* Move keyboard focus in a given direction */ static void shift_focus(int cols, int rows) { printf("shift_focus: %+d,%+d\n", cols, rows); if (rows != 0 && wm_focus) { + /* Move focus up/down */ list_t *dpy, *col, *row; if (!searchl(wm_tag, wm_focus, &dpy, &col, &row)) return; @@ -328,15 +376,19 @@ static void shift_focus(int cols, int rows) wm_update(); } if (cols != 0) { + /* Move focus left/right */ list_t *dpy, *col, *row, *ndpy, *ncol = NULL; if (wm_focus) { + /* Currently focused on a window */ if (!searchl(wm_tag, wm_focus, &dpy, &col, &row)) return; ncol = cols > 0 ? col->next : col->prev; } else { + /* Currently focused on an empty display */ dpy = list_find(wm_tag->dpys, wm_dpy); } if (ncol == NULL) { + /* Moving focus to a different display */ ndpy = get_next(dpy, cols > 0); ncol = cols > 0 ? DPY(ndpy)->cols : list_last(DPY(ndpy)->cols); @@ -349,6 +401,7 @@ static void shift_focus(int cols, int rows) } } +/* Allocate a new tag */ static tag_t *tag_new(list_t *screens, int name) { tag_t *tag = new0(tag_t); @@ -362,6 +415,9 @@ static tag_t *tag_new(list_t *screens, int name) return tag; } +/* Search for a tag + * If it does not exist it is based on the + * display geometry in wm->screens */ static tag_t *tag_find(int name) { tag_t *tag = NULL; @@ -377,6 +433,8 @@ static tag_t *tag_find(int name) return tag; } +/* Move the window from the current tag to the new tag + * Unlike wmii, only remove the current tag, not all tags */ static void tag_set(win_t *win, int name) { printf("tag_set: %p %d\n", win, name); @@ -388,6 +446,7 @@ static void tag_set(win_t *win, int name) set_focus(wm_focus); } +/* Switch to a different tag */ static void tag_switch(int name) { printf("tag_switch: %d\n", name); @@ -397,13 +456,15 @@ static void tag_switch(int name) wm_tag = tag_find(name); } -/* Window management functions */ -void wm_update_dpy(dpy_t *dpy) +/* Tile all windows in the given display + * This performs all the actual window tiling + * Currently supports split, stack and maximized modes */ +static void wm_update_dpy(dpy_t *dpy) { int x=0, y=0; // Current window top-left position - int tx=0, ty=0; // Total x/y size - int mx=0, my=0; // Maximum x/y size (screen size) - int sy=0; // Size of focused stack window + int tx=0, ty=0; // Total size (sum of initial col widths and row heights w/o margin) + int mx=0, my=0; // Maximum usable size (screen size minus margins) + int sy=0; // Stack size (height of focused stack window) /* Scale horizontally */ x = dpy->geom->x; @@ -458,6 +519,9 @@ void wm_update_dpy(dpy_t *dpy) } } +/******************************* + * Window management functions * + *******************************/ void wm_update(void) { /* Show/hide tags */ @@ -468,7 +532,7 @@ void wm_update(void) if (tag->data != wm_tag) sys_show(win, st_hide); - /* Refrsh the display */ + /* Refresh the display */ for (list_t *ldpy = wm_tag->dpys; ldpy; ldpy = ldpy->next) wm_update_dpy(ldpy->data); if (wm_focus) @@ -636,7 +700,6 @@ void wm_remove(win_t *win) wm_update(); print_txt(); } - void wm_init(win_t *root) { printf("wm_init: %p\n", root); diff --git a/wm.h b/wm.h index d25750d..10b319e 100644 --- a/wm.h +++ b/wm.h @@ -1,11 +1,45 @@ -void wm_init(win_t *root); +/* + * Copyright (C) 2011 Andy Spencer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* Window manager interface: + * + * The window manager receives input events from the system + * and responds by using the system to arrange the windows + * according to it's layout. + * + * The window provided to these function is generally the + * window with the keyboard or mouse focus. */ + +/* Refresh the window layout */ +void wm_update(void); +/* Called for each watched key press. + * This is currently used for some other events such + * as focus-in and focus-out as well. */ int wm_handle_key(win_t *win, Key_t key, mod_t mod, ptr_t ptr); +/* Called for each mouse movement */ int wm_handle_ptr(win_t *win, ptr_t ptr); +/* Begin managing a window, called for each new window */ void wm_insert(win_t *win); +/* Stop managing a window and free data */ void wm_remove(win_t *win); -void wm_update(void); +/* First call, sets up key bindings, etc */ +void wm_init(win_t *root); -- 2.43.2