#include "util.h"
#include "conf.h"
+#include "types.h"
#include "sys.h"
#include "wm.h"
typedef struct {
list_t *tags; // of tag_t
tag_t *tag; // focused tag
- win_t *root; // root/background window
list_t *screens; // display geometry
} wm_t;
* it as the currently focused window */
static void set_focus(win_t *win)
{
- if (win == NULL || win == wm->root) {
- sys_focus(wm->root);
+ if (win == NULL) {
+ sys_focus(NULL);
return;
}
{
row_t *row = new0(row_t);
row->win = win;
- row->state = win->state ?: ST_SHOW;
+ row->state = win->state;
if (col == NULL) {
col = new0(col_t);
if (ncol && COL(ncol) && COL(ncol)->row)
set_focus(COL(ncol)->row->win);
else
- sys_focus(wm->root);
+ sys_focus(NULL);
}
}
int mx=0, my=0; // Maximum usable size (screen size minus margins)
int sy=0; // Stack size (height of focused stack window)
+ float rx=0, ry=0; // Residuals for floating point round off
+
/* Scale horizontally */
x = dpy->geom->x;
mx = dpy->geom->w - (list_length(dpy->cols)+1)*margin;
for (list_t *lcol = dpy->cols; lcol; lcol = lcol->next)
tx += COL(lcol)->width;
for (list_t *lcol = dpy->cols; lcol; lcol = lcol->next)
- COL(lcol)->width *= (float)mx / tx;
+ COL(lcol)->width = residual(COL(lcol)->width * (float)mx/tx, &rx);
/* Scale each column vertically */
win_t *focus = get_focus();
}
win->h = ROW(lrow)->height;
state_t state = ST_SHOW;
- int height = 0;
switch (col->layout) {
case SPLIT:
- sys_move(win, x+margin, y+margin,
- col->width, win->h * ((float)my / ty));
- height = win->h;
- y += height + margin;
+ sys_move(win, x+margin, y+margin, col->width,
+ residual(win->h * ((float)my/ty), &ry));
+ y += win->h + margin;
break;
case STACK:
if (lrow->next && ROW(lrow->next)->win == col->row->win) {
for (list_t *tag = wm ->tags; tag; tag = tag->next)
if (tag->data != wm_tag) {
tag_foreach_col(TAG(tag), dpy, col, row, win)
- sys_show(win, ST_HIDE);
+ sys_show(win, ST_HIDE);
tag_foreach_flt(TAG(tag), dpy, flt, win)
- sys_show(win, ST_HIDE);
+ sys_show(win, ST_HIDE);
}
/* Set focused window */
*******************************/
int wm_handle_event(win_t *win, event_t ev, mod_t mod, ptr_t ptr)
{
- if (!win || win == wm_dpy->geom) return 0;
//printf("wm_handle_event: %p - %x %c%c%c%c%c\n", win, ev,
// mod.up ? '^' : 'v',
// mod.alt ? 'a' : '-',
// mod.win ? 'w' : '-');
/* Mouse events */
- if (EV_MOUSE0 <= ev && ev <= EV_MOUSE7) {
+ if (win && EV_MOUSE0 <= ev && ev <= EV_MOUSE7) {
if (ev == EV_MOUSE1 && !mod.MODKEY && !mod.up)
return raise_float(win), 0;
if ((ev == EV_MOUSE3 && mod.MODKEY && !mod.up) ||
/* Only handle key-down */
if (mod.up)
- return 0;
+ return mod.MODKEY || ev == EV_ALT;
/* Misc */
- if (mod.MODKEY) {
#ifdef DEBUG
+ if (win && mod.MODKEY) {
if (ev == EV_F1) return raise_float(win), 1;
if (ev == EV_F2) return set_focus(win), 1;
if (ev == EV_F3) return sys_show(win, ST_SHOW), 1;
if (ev == EV_F4) return sys_show(win, ST_HIDE), 1;
if (ev == EV_F7) return sys_show(win, ST_SHADE), 1;
+ }
#endif
+ if (mod.MODKEY) {
if (ev == EV_F5) return wm_update(), 1;
if (ev == EV_F6) return print_txt(), 1;
if (ev == 'q') return sys_exit(), 1;
+ }
+ if (win && mod.MODKEY) {
if (ev == 'f') return wm_handle_state(win, win->state,
win->state == ST_FULL ? ST_SHOW : ST_FULL);
+ if (ev == 'g') return wm_handle_state(win, win->state,
+ win->state == ST_MAX ? ST_SHOW : ST_MAX);
}
- if (mod.MODKEY && mod.shift) {
+ if (win && mod.MODKEY && mod.shift) {
if (ev == 'c') return sys_show(win, ST_CLOSE), 1;
}
/* Floating layer */
if (ev == ' ') {
- if (mod.MODKEY && mod.shift)
+ if (win && mod.MODKEY && mod.shift)
return set_layer(win), 1;
if (mod.MODKEY)
return switch_layer(), 1;
/* Tag switching */
if (mod.MODKEY && '0' <= ev && ev <= '9') {
char name[] = {ev, '\0'};
- if (mod.shift)
+ if (win && mod.shift)
tag_set(win, name);
- else
+ if (!mod.shift)
tag_switch(name);
wm_update();
}
/* Focus change */
- if (ev == EV_ENTER && win->state != ST_SHADE)
+ if (win && ev == EV_ENTER && win->state != ST_SHADE)
return set_focus(win), 1;
/* Reset focus after after focus change,
* not sure what is causing the focus change in the first place
* but preventing that would be a better solution */
if (ev == EV_FOCUS)
- sys_focus(wm_focus ?: wm->root);
+ sys_focus(wm_focus);
- return 0;
+ return mod.MODKEY;
}
int wm_handle_ptr(win_t *cwin, ptr_t ptr)
flt_t *flt = NULL;
printf("wm_handle_state - %p %x -> %x\n", win, prev, next);
+
search(wm_tag, win, NULL, NULL, &row, &flt);
+ if (!row && !flt && next == ST_SHOW)
+ return wm_insert(win), 1;
+ if ((row || flt) && (next == ST_HIDE || next == ST_ICON))
+ return wm_remove(win), 1;
+
if (row) row->state = next;
if (flt) flt->state = next;
void wm_insert(win_t *win)
{
printf("wm_insert: %p\n", win);
- print_txt();
+
+ /* Make sure it's visible */
+ if (win->state == ST_HIDE)
+ return;
/* Check for toolbars */
if (win->type == TYPE_TOOLBAR)
return wm_update();
+ print_txt();
+
/* Initialize window */
- win->wm = new0(win_wm_t);
sys_watch(win, EV_ENTER, MOD());
sys_watch(win, EV_FOCUS, MOD());
return wm_update();
for (list_t *tag = wm->tags; tag; tag = tag->next)
cut_win(win, tag->data);
- free(win->wm);
set_focus(wm_focus);
wm_update();
print_txt();
}
-void wm_init(win_t *root)
+void wm_init(void)
{
- printf("wm_init: %p\n", root);
+ printf("wm_init\n");
/* Load configuration */
margin = conf_get_int("main.margin", margin);
stack = conf_get_int("main.stack", stack);
wm = new0(wm_t);
- wm->root = root;
- wm->screens = list_sort(sys_info(root), 0, sort_win);
+ wm->screens = list_sort(sys_info(), 0, sort_win);
wm->tag = tag_new(wm->screens, "1");
wm->tags = list_insert(NULL, wm->tag);
event_t ev_s[] = {'h', 'j', 'k', 'l', 'c', 'q', ' ',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
EV_MOUSE1, EV_MOUSE3};
- event_t ev_m[] = {'h', 'j', 'k', 'l', 'd', 's', 'm', 't', 'f', ' ',
+ event_t ev_m[] = {'h', 'j', 'k', 'l', 'd', 's', 'm', 't', 'f', 'g', ' ',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
EV_F1, EV_F2, EV_F3, EV_F4, EV_F5, EV_F6,
EV_F7, EV_F8, EV_F9, EV_F10, EV_F11, EV_F12,
EV_MOUSE1, EV_MOUSE3};
for (int i = 0; i < countof(ev_e); i++)
- sys_watch(root, ev_e[i], MOD());
+ sys_watch(NULL, ev_e[i], MOD());
for (int i = 0; i < countof(ev_m); i++)
- sys_watch(root, ev_m[i], MOD(.MODKEY=1));
+ sys_watch(NULL, ev_m[i], MOD(.MODKEY=1));
for (int i = 0; i < countof(ev_s); i++)
- sys_watch(root, ev_s[i], MOD(.MODKEY=1,.shift=1));
+ sys_watch(NULL, ev_s[i], MOD(.MODKEY=1,.shift=1));
}
-void wm_free(win_t *root)
+void wm_free(void)
{
/* Re-show and free all windows */
while ( wm->tags) { tag_t *tag = wm->tags->data;
while (dpy->cols) { col_t *col = dpy->cols->data;
while (col->rows) { row_t *row = col->rows->data;
sys_show(row->win, ST_SHOW);
- free(row->win->wm);
col->rows = list_remove(col->rows, col->rows, 1); }
dpy->cols = list_remove(dpy->cols, dpy->cols, 1); }
while (dpy->flts) { flt_t *flt = dpy->flts->data;
sys_show(flt->win, ST_SHOW);
- free(flt->win->wm);
dpy->flts = list_remove(dpy->flts, dpy->flts, 1); }
tag->dpys = list_remove(tag->dpys, tag->dpys, 1); }
wm->tags = list_remove( wm->tags, wm->tags, 1); }