...
 
Commits (11)
......@@ -129,6 +129,7 @@ client_create(Window win, bool viewable)
c->floating = false;
c->dialog = false;
client_query_window_type(c);
c->transient = c->transient_for = NULL;
/* state */
c->fullscreen = false;
......@@ -275,6 +276,23 @@ client_query_size_hints(struct client *c)
}
}
void
client_query_transient(struct client *c, struct state *state)
{
Window tr4win;
if (!XGetTransientForHint(x11.dpy, c->win, &tr4win))
return;
c->transient_for = state_locate_client(state, tr4win, NULL);
if (!c->transient_for) {
warn("Window %lu is transient for unmanaged window %lu",
c->win, tr4win);
return;
}
c->transient_for->transient = c;
}
void
client_query_window_state(struct client *c)
{
......
......@@ -19,8 +19,11 @@ struct client {
bool dirty;
struct workspace *ws;
bool focused;
struct client *transient, *transient_for;
};
#include "state.h"
struct client *client_create(Window win, bool viewable);
void client_destroy(struct client *c);
void client_kill(struct client *c);
......@@ -29,6 +32,7 @@ void client_moveresize(struct client *c, struct rectangle dimension);
void client_moveresize_fullscreen(struct client *c, struct rectangle dimension);
void client_query_name(struct client *c);
void client_query_size_hints(struct client *c);
void client_query_transient(struct client *c, struct state *state);
void client_query_window_state(struct client *c);
void client_query_window_type(struct client *c);
void client_resize(struct client *c, struct size size);
......
......@@ -1545,7 +1545,7 @@ stepwsmbox(union arg arg)
{
strcpy(state->wsmap->target->name, ws->name);
}
wsmbox_update(state->wsmap->target->wsmbox, state);
wsmbox_update(state->wsmap->target->wsmbox, state->wsmap);
wsmbox_render(state->wsmap->target->wsmbox);
}
......@@ -1614,8 +1614,8 @@ togglewsm(union arg arg)
/* create a box for each workspace */
LIST_FOR (state->workspaces, i, ws)
ws->wsmbox = wsmbox_create(ws, state);
state->wsmap->target->wsmbox = wsmbox_create(state->wsmap->target, state);
ws->wsmbox = wsmbox_create(ws, state->wsmap);
state->wsmap->target->wsmbox = wsmbox_create(state->wsmap->target, state->wsmap);
XRaiseWindow(x11.dpy, seat->selmon->selws->wsmbox->window);
XRaiseWindow(x11.dpy, state->wsmap->target->wsmbox->window);
......@@ -1808,29 +1808,24 @@ updategeom(void)
void
updatetransient(struct client *c)
{
struct workspace *ws = c->ws;
struct client *tc;
Window tfor=0;
if (!XGetTransientForHint(x11.dpy, c->win, &tfor))
return;
tc = state_locate_client(state, tfor, NULL);
if (!tc) {
debug("window %lu is transient for unmanaged window %lu",
c->win, tfor);
return;
}
debug("\033[33mwindow %lu is transient for %lu\033[0m", c->win, tfor);
setfloating(c, true);
if (tc->ws->mon && tc->ws != ws) {
workspace_detach_client(ws, c);
workspace_attach_client(tc->ws, c);
if (!ws->mon && workspace_isempty(ws)) {
state_detach_workspace(state, ws);
workspace_destroy(ws);
struct workspace *cws, *tr4ws;
client_query_transient(c, state);
if (c->transient_for) {
debug("Window %lu is transient for %lu",
c->win, c->transient_for->win);
cws = c->ws;
tr4ws = c->transient_for->ws;
if (cws != tr4ws) {
workspace_detach_client(cws, c);
c->floating = true;
if (workspace_isempty(cws) && !cws->mon) {
state_detach_workspace(state, cws);
workspace_destroy(cws);
}
workspace_attach_client(tr4ws, c);
}
workspace_set_floating(tr4ws, c, true);
}
}
......
......@@ -11,12 +11,12 @@ list_append(struct list *l, void *e)
}
bool
list_contains(struct list *l, void *e, bool (*f)(void *e1, void *e2))
list_contains(struct list *l, void *e, bool (*f)(void *le, void *e))
{
int unsigned i;
for (i = 0; i < l->size; ++i)
if (e == l->elements[i] || (f && f(e, l->elements[i])))
if (e == l->elements[i] || (f && f(l->elements[i], e)))
return true;
return false;
}
......@@ -44,12 +44,12 @@ list_destroy(struct list *l)
}
int unsigned
list_find_index(struct list *l, void *e, bool (*f)(void *e1, void *e2))
list_find_index(struct list *l, void *e, bool (*f)(void *le, void *e))
{
int unsigned i;
for (i = 0; i < l->size; ++i)
if (e == l->elements[i] || (f && f(e, l->elements[i])))
if (e == l->elements[i] || (f && f(l->elements[i], e)))
return i;
die("list_find_index() on element not contained in list");
}
......@@ -109,13 +109,13 @@ list_push(struct list *l, void *e)
}
void
list_remove(struct list *l, void *e, bool (*f)(void *e1, void *e2))
list_remove(struct list *l, void *e, bool (*f)(void *le, void *e))
{
int unsigned i;
/* determine index */
for (i = 0; i < l->size; ++i)
if (e == l->elements[i] || (f && f(e, l->elements[i])))
if (e == l->elements[i] || (f && f(l->elements[i], e)))
break;
if (i >= l->size)
die("Attempt to remove non-existing element from list");
......
......@@ -8,7 +8,7 @@
for (I = 0; I < L->size; ++I) \
for (E = L->elements[I]; E != NULL; E = NULL)
typedef bool (*list_eqfunc)(void *e1, void *e2);
typedef bool (*list_eqfunc)(void *le, void *e);
typedef int (*list_cmpfunc)(void *e1, void *e2);
struct list {
......@@ -17,15 +17,15 @@ struct list {
};
void list_append(struct list *l, void *e);
bool list_contains(struct list *l, void *e, bool (*f)(void *e1, void *e2));
bool list_contains(struct list *l, void *e, bool (*f)(void *le, void *e));
struct list *list_create(void);
void list_destroy(struct list *l);
int unsigned list_find_index(struct list *l, void *e,
bool (*f)(void *e1, void *e2));
bool (*f)(void *le, void *e));
void list_insert(struct list *l, void *e, int unsigned index);
void list_insert_sorted(struct list *l, void *e, int (*f)(void *e1, void *e2));
void list_prepend(struct list *l, void *e);
void list_push(struct list *l, void *e);
void list_remove(struct list *l, void *e, bool (*f)(void *e1, void *e2));
void list_remove(struct list *l, void *e, bool (*f)(void *le, void *e));
#endif /* ndef _KWM_LIST_H */
......@@ -32,6 +32,7 @@ workspace_attach_client(struct workspace *ws, struct client *c)
list_insert(list, c, pos);
c->ws = ws;
client_show(c, (bool) ws->mon);
workspace_focus_client(ws, c);
}
......
......@@ -8,8 +8,54 @@
#include <stdlib.h>
#include <string.h>
static void update(struct wsmbox *wb);
static void
update(struct wsmbox *wb)
{
struct config const *config = config_get();
uint32_t fg, bg, border;
int unsigned w, h;
w = config->wsmbox.size.width;
h = config->wsmbox.size.height;
switch (wb->type) {
case WSMBOX_SELECTED:
fg = config->wsmbox.selected.foreground.colour;
bg = config->wsmbox.selected.background.colour;
border = config->wsmbox.selected.border.colour;
break;
case WSMBOX_FOCUSED:
fg = config->wsmbox.focused.foreground.colour;
bg = config->wsmbox.focused.background.colour;
border = config->wsmbox.focused.border.colour;
break;
case WSMBOX_UNFOCUSED:
fg = config->wsmbox.unfocused.foreground.colour;
bg = config->wsmbox.unfocused.background.colour;
border = config->wsmbox.unfocused.border.colour;
break;
}
/* background */
XSetForeground(x11.dpy, x11.gc, bg);
XFillRectangle(x11.dpy, wb->pixmap, x11.gc, 0, 0, w, h);
/* foreground */
if (wb->workspace) {
XSetForeground(x11.dpy, x11.gc, fg);
Xutf8DrawString(x11.dpy, wb->pixmap, x11.font.xfontset, x11.gc,
2, (int signed) x11.font.ascent + 1,
wb->workspace->name,
(int signed) strlen(wb->workspace->name));
}
/* border */
XSetWindowBorder(x11.dpy, wb->window, border);
}
struct wsmbox *
wsmbox_create(struct workspace *ws, struct state *state)
wsmbox_create(struct workspace *ws, struct wsmap *wsm)
{
struct config const *config = config_get();
struct wsmbox *wb;
......@@ -26,6 +72,8 @@ wsmbox_create(struct workspace *ws, struct state *state)
/* workspace */
wb->workspace = ws;
wb->pos = (struct position) { 0, 0 };
wb->type = WSMBOX_UNFOCUSED;
/* pixmap */
wb->pixmap = XCreatePixmap(x11.dpy, x11.root, w, h, x11.sd);
......@@ -35,12 +83,14 @@ wsmbox_create(struct workspace *ws, struct state *state)
(int signed) x11.sd, CopyFromParent,
DefaultVisual(x11.dpy, x11.screen),
CWOverrideRedirect|CWBackPixmap|CWEventMask,
&state->wsmap->wa);
&wsm->wa);
XMapRaised(x11.dpy, wb->window);
XSetWindowBorderWidth(x11.dpy, wb->window, border);
/* TODO: call update() */
/* initial update and render, then return */
wsmbox_update(wb, state);
wsmbox_update(wb, wsm);
wsmbox_render(wb);
return wb;
}
......@@ -56,6 +106,18 @@ wsmbox_destroy(struct wsmbox *wb)
free(wb);
}
bool
wsmbox_manages_workspace(struct wsmbox *wb, struct workspace *ws)
{
return ws == wb->workspace;
}
void
wsmbox_move(struct wsmbox *wb, struct position pos)
{
XMoveWindow(x11.dpy, wb->window, pos.x, pos.y);
}
void
wsmbox_render(struct wsmbox *wb)
{
......@@ -65,19 +127,41 @@ wsmbox_render(struct wsmbox *wb)
warn("Trying to render NULL workspace map box");
return;
}
w = config_get()->wsmbox.size.width;
h = config_get()->wsmbox.size.height;
XCopyArea(x11.dpy, wb->pixmap, wb->window, x11.gc, 0, 0, w, h, 0, 0);
}
void
wsmbox_update(struct wsmbox *wb, struct state *state)
wsmbox_set_position(struct wsmbox *wb, struct position pos)
{
wb->pos = pos;
}
void
wsmbox_set_type(struct wsmbox *wb, enum wsmbox_type type)
{
wb->type = type;
update(wb);
}
void
wsmbox_show(struct wsmbox *wb, bool show)
{
if (show)
XMapRaised(x11.dpy, wb->window);
else
XUnmapWindow(x11.dpy, wb->window);
}
void
wsmbox_update(struct wsmbox *wb, struct wsmap *wsm)
{
struct config const *config = config_get();
struct workspace *ws = wb->workspace;
bool selws = ws->mon && ws == ws->mon->seat->selmon->selws;
bool target = ws == state->wsmap->target;
bool target = ws == wsm->target;
uint32_t fg = target ? config->wsmbox.selected.foreground.colour :
selws ? config->wsmbox.focused.foreground.colour :
......
......@@ -2,19 +2,30 @@
#define _KWM_WSMBOX_H
#include <X11/Xlib.h>
#include "position.h"
enum wsmbox_type { WSMBOX_SELECTED, WSMBOX_FOCUSED, WSMBOX_UNFOCUSED };
struct wsmbox {
Window window;
Pixmap pixmap;
struct workspace *workspace;
struct position pos;
enum wsmbox_type type;
};
#include "state.h"
#include "workspace.h"
#include "wsmap.h"
#include <stdbool.h>
struct wsmbox *wsmbox_create(struct workspace *ws, struct state *state);
struct wsmbox *wsmbox_create(struct workspace *ws, struct wsmap *map);
void wsmbox_destroy(struct wsmbox *wb);
bool wsmbox_manages_workspace(struct wsmbox *wb, struct workspace *ws);
void wsmbox_move(struct wsmbox *wb, struct position pos);
void wsmbox_render(struct wsmbox *wb);
void wsmbox_update(struct wsmbox *wb, struct state *state);
void wsmbox_set_position(struct wsmbox *wb, struct position pos);
void wsmbox_set_type(struct wsmbox *wb, enum wsmbox_type type);
void wsmbox_show(struct wsmbox *wb, bool show);
void wsmbox_update(struct wsmbox *wb, struct wsmap *map);
#endif /* ndef _KWM_WSMBOX_H */