wc.sibling = ev->above;
wc.stack_mode = ev->detail;
Location loc = {0};
- if (mons_find(ev->window, &loc) && (loc.client->win == ev->window))
+ if (mons_find(ev->window, &loc))
{
- loc.client->w = wc.width;
- loc.client->h = wc.height;
- client_adjust(loc.client);
- if (X.mode == M_RESIZE && Focused == loc.client)
+ /* only allow floating clients to resize on their own */
+ if ((loc.client->win == ev->window) && !loc.column)
{
- mouse_tocorner(loc.client);
+ loc.client->w = wc.width;
+ loc.client->h = wc.height;
+ client_adjust(loc.client);
+ if (X.mode == M_RESIZE && Focused == loc.client)
+ {
+ mouse_tocorner(loc.client);
+ }
}
}
else
void mouse_get(int* ptrx, int* ptry);
/* tile.c */
-void monocled_add(Monitor* mon, Column* col, Client* c);
-void monocled_del(Monitor* mon, Column* col, Client* c);
-void monocled_raise(Monitor* mon, Column* col, Client* c);
-void monocled_set(Monitor* mon, Column* col, Client* c);
-void stacked_add(Monitor* mon, Column* col, Client* c);
-void stacked_del(Monitor* mon, Column* col, Client* c);
-void stacked_set(Monitor* mon, Column* col, Client* c);
-void stacked_addheight(Monitor* mon, Column* col, Client* c, int amount);
+void monocled_add(Location* loc);
+void monocled_del(Location* loc);
+void monocled_raise(Location* loc);
+void monocled_set(Location* loc);
+void stacked_add(Location* loc);
+void stacked_del(Location* loc);
+void stacked_set(Location* loc);
+void stacked_addheight(Location* loc, int amount);
/* error.c */
extern int (*error_default)(Display* disp, XErrorEvent* ev);
XWMHints* hints = XGetWMHints(X.disp, c->win);
if (hints)
{
- c->wm_flags = hints->flags;
+ int ignored = (Focused == c ? XUrgencyHint : 0);
+ c->wm_flags = (hints->flags & ~ignored);
}
xfree(hints);
}
Client* next = c->next;
if (dest->focused)
{
- monocled_add(mon, dest, c);
+
+ monocled_add(&(Location){mon, NULL, dest, c});
}
else
{
- stacked_add(mon, dest, c);
+ stacked_add(&(Location){mon, NULL, dest, c});
}
c = next;
}
{
remove_client(loc, loc->client);
client_setshade(loc->client, 0);
+ loc->monitor = mon;
+ loc->column = col;
if (col->focused)
{
- monocled_add(mon, col,loc->client);
+ monocled_add(loc);
}
else
{
- stacked_add(mon, col, loc->client);
+ stacked_add(loc);
}
}
else
{
- stacked_addheight(loc->monitor, loc->column, loc->client, hdiff);
+ stacked_addheight(loc, hdiff);
}
mouse_totitle(loc->client);
}
change_wspace(loc.monitor, loc.workspace);
if (loc.column && loc.column->focused)
{
- monocled_raise(loc.monitor, loc.column, loc.client);
+ monocled_raise(&loc);
mons_layer(loc.monitor);
}
else if (!loc.column)
/* add in monocled or stacked mode */
if (col->focused)
{
- monocled_add(mon, col, c);
+ monocled_add(&(Location){mon, NULL, col, c});
}
else
{
- stacked_add(mon, col, c);
+ stacked_add(&(Location){mon, NULL, col, c});
}
}
mons_layer(mon);
}
else if (loc->column->focused)
{
- monocled_del(loc->monitor, loc->column, loc->client);
+ monocled_del(loc);
}
else
{
- stacked_del(loc->monitor, loc->column, loc->client);
+ stacked_del(loc);
}
}
#include "anvil.h"
+static XEvent* Current = NULL;
+
static inline int PRESSED(int mods, int btn)
{
return ((mods & (1 << (btn + 7))) == (1 << (btn + 7)));
static inline int FLAGS_SET(int state, int flags)
{
- return ((state & flags) == flags);
+ return ((!flags && !state) || ((state & flags) == flags));
}
-static void float_click(XButtonEvent* ev, Location* loc)
+typedef struct {
+ int mods;
+ int btn;
+ int type;
+ void(*func)(Location* loc);
+} MouseAct;
+
+static void resize_frame(Location* loc)
{
- if ((ev->button == Button1) && (ev->y > MIN_HEIGHT))
+ if (Current->xbutton.y > MIN_HEIGHT)
{
X.mode = M_RESIZE;
mouse_tocorner(loc->client);
}
- else if (ev->button == Button2)
- {
- if (FLAGS_SET(ev->state, (MODKEY|ShiftMask)))
- {
- mons_togglefloat(loc);
- }
- else if (FLAGS_SET(ev->state, MODKEY))
- {
- client_close(loc->client);
- }
- else
- {
- /* nothing to do */
- }
- }
- else if (ev->button == Button3)
- {
- client_shade(loc->client);
- }
- else if (ev->button == Button4)
- {
- mons_lower(loc->monitor, loc->client);
- }
- else if (ev->button == Button5)
- {
- mons_raise(loc->monitor, loc->client);
- }
}
-static void monocled_click(XButtonEvent* ev, Location* loc)
+static void toggle_float(Location* loc)
{
- if (ev->button == Button1)
- {
- stacked_set(loc->monitor, loc->column, loc->client);
- }
- else if (ev->button == Button2)
- {
- if (FLAGS_SET(ev->state, (MODKEY|ShiftMask)))
- {
- mons_togglefloat(loc);
- }
- else if (FLAGS_SET(ev->state, MODKEY))
- {
- client_close(loc->client);
- }
- else
- {
- /* nothing to do */
- }
- }
- else if (ev->button == Button3)
- {
- 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_set(loc->monitor, loc->column, loc->column->clients);
- }
- }
- mons_layer(loc->monitor);
+ mons_togglefloat(loc);
}
-static void stacked_click(XButtonEvent* ev, Location* loc)
+static void close_client(Location* loc)
{
- if (ev->button == Button1)
+ client_close(loc->client);
+}
+
+static void shade_client(Location* loc)
+{
+ client_shade(loc->client);
+}
+
+static void lower_client(Location* loc)
+{
+ mons_lower(loc->monitor, loc->client);
+}
+
+static void raise_client(Location* loc)
+{
+ mons_raise(loc->monitor, loc->client);
+}
+
+static void stack_clients(Location* loc)
+{
+ stacked_set(loc);
+}
+
+static void rotate_client(Location* loc)
+{
+ Client *tail, *client = loc->column->clients;
+ if (client->next)
{
- X.mode = (X.edge == E_TOP ? M_TILE_RESIZE : M_COL_RESIZE);
+ loc->column->clients = client->next;
+ tail = list_last(loc->column->clients);
+ client->next = NULL;
+ tail->next = client;
+ monocled_set(loc);
}
- else if (ev->button == Button2)
- {
- if (FLAGS_SET(ev->state, (MODKEY|ShiftMask)))
- {
- mons_togglefloat(loc);
- }
- else if (FLAGS_SET(ev->state, MODKEY))
- {
- client_close(loc->client);
- }
- else
+}
+
+static void reposition_tile(Location* loc)
+{
+ (void)loc;
+ X.mode = (X.edge == E_TOP ? M_TILE_RESIZE : M_COL_RESIZE);
+}
+
+static void expand_tile(Location* loc)
+{
+ (void)loc;
+ puts("expand in place");
+}
+
+static void monocle_client(Location* loc)
+{
+ monocled_set(loc);
+}
+
+MouseAct Floating[] = {
+ { 0, Button1, ButtonPress, resize_frame },
+ { MODKEY|ShiftMask, Button2, ButtonPress, toggle_float },
+ { MODKEY, Button2, ButtonPress, close_client },
+ { 0, Button3, ButtonPress, shade_client },
+ { 0, Button4, ButtonPress, lower_client },
+ { 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, expand_tile },
+ { 0, Button3, ButtonPress, monocle_client },
+};
+
+static void process(XButtonEvent* ev, Location* loc, MouseAct* actions, int nactions)
+{
+ for (int i = 0; i < nactions; i++)
+ {
+ MouseAct* act = &actions[i];
+ int match = (
+ (ev->type == act->type) &&
+ ((int)ev->button == act->btn) &&
+ FLAGS_SET(ev->state, act->mods)
+ );
+ if (match)
{
- puts("expand in place");
+ Current = (XEvent*)ev;
+ act->func(loc);
+ break;
}
}
- else if (ev->button == Button3)
- {
- monocled_set(loc->monitor, loc->column, loc->client);
- }
}
void mouse_down(XButtonEvent* ev, Location* loc)
{
if (!loc->column)
{
- float_click(ev, loc);
+ process(ev, loc, Floating, sizeof(Floating)/sizeof(Floating[0]));
}
else if (loc->column->focused)
{
- monocled_click(ev, loc);
+ process(ev, loc, Monocled, sizeof(Monocled)/sizeof(Monocled[0]));
}
else
{
- stacked_click(ev, loc);
+ process(ev, loc, Stacked, sizeof(Stacked)/sizeof(Stacked[0]));
}
}
}
}
-void monocled_add(Monitor* mon, Column* col, Client* c)
+void monocled_add(Location* loc)
{
- coldims(mon, col, &(c->x), &(c->y), &(c->w), &(c->h));
+ Client* c = loc->client;
+ coldims(loc->monitor, loc->column, &(c->x), &(c->y), &(c->w), &(c->h));
client_adjust(c);
- c->next = col->clients;
- col->clients = c;
- col->focused = c;
+ c->next = loc->column->clients;
+ loc->column->clients = c;
+ loc->column->focused = c;
}
-void monocled_del(Monitor* mon, Column* col, Client* c)
+void monocled_del(Location* loc)
{
- col->clients = list_del(col->clients, c);
- col->focused = col->clients;
- c = col->clients;
+ 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)
{
- coldims(mon, col, &(c->x), &(c->y), &(c->w), &(c->h));
- client_adjust(c);
+ coldims(loc->monitor, loc->column,
+ &(loc->client->x), &(loc->client->y), &(loc->client->w), &(loc->client->h));
+ client_adjust(loc->client);
}
}
-void monocled_raise(Monitor* mon, Column* col, Client* c)
+void monocled_raise(Location* loc)
{
- col->clients = list_del(col->clients, c);
- c->next = col->clients;
- col->clients = c;
- col->focused = c;
- coldims(mon, col, &(c->x), &(c->y), &(c->w), &(c->h));
- client_adjust(c);
+ 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_adjust(loc->client);
}
-void monocled_set(Monitor* mon, Column* col, Client* c)
+void monocled_set(Location* loc)
{
- col->clients = list_del(col->clients, c);
- c->next = col->clients;
- col->clients = c;
- col->focused = c;
- coldims(mon, col, &(c->x), &(c->y), &(c->w), &(c->h));
- client_setshade(c, 0);
- client_adjust(c);
- mons_layer(mon);
+ 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(Monitor* mon, Column* col, Client* c)
+void stacked_add(Location* loc)
{
- coldims(mon, col, &(c->x), &(c->y), &(c->w), &(c->h));
- if (col->clients)
+ Client* c = loc->client;
+ coldims(loc->monitor, loc->column, &(c->x), &(c->y), &(c->w), &(c->h));
+ if (loc->column->clients)
{
- Client *cl, *max = col->clients;
+ Client *cl, *max = loc->column->clients;
LIST_FOR_EACH(cl, max)
{
if (cl->h > max->h)
}
if (max->h < 3*MIN_HEIGHT)
{
- if (col->next)
+ if (loc->column->next)
{
- stacked_add(mon, col->next, c);
+ stacked_add(loc);
}
else
{
- c->next = mon->cspace->floating;
- mon->cspace->floating = c;
- c->x = mon->midx - c->w/2;
- c->y = mon->midy - c->h/2;
+ 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
{
- c->next = col->clients;
- col->clients = c;
+ c->next = loc->column->clients;
+ loc->column->clients = c;
client_adjust(c);
}
}
-void stacked_del(Monitor* mon, Column* col, Client* c)
+void stacked_del(Location* loc)
{
- if (col->clients == c)
+ Client* c = loc->client;
+ if (loc->column->clients == c)
{
- col->clients = c->next;
- if (col->clients)
+ loc->column->clients = c->next;
+ if (loc->column->clients)
{
- col->clients->h += col->clients->y - mon->y;
- col->clients->y = mon->y;
- client_setshade(col->clients, 0);
- client_adjust(col->clients);
+ loc->column->clients->h += loc->column->clients->y - loc->monitor->y;
+ loc->column->clients->y = loc->monitor->y;
+ client_setshade(loc->column->clients, 0);
+ client_adjust(loc->column->clients);
}
}
else
{
- Client* prev = list_prev(col->clients, c);
+ Client* prev = list_prev(loc->column->clients, c);
prev->next = c->next;
prev->h += c->h;
client_setshade(prev, 0);
}
}
-void stacked_set(Monitor* mon, Column* col, Client* c)
+void stacked_set(Location* loc)
{
- (void)c;
- col->focused = NULL;
- int nclients = list_length(col->clients->next);
- int starty = (mon->y + mon->h) - (nclients * MIN_HEIGHT);
- col->clients->h = starty - mon->y - 1;
- client_adjust(col->clients);
- LIST_FOR_EACH(c, col->clients->next)
+ Client* c = loc->client;
+ loc->column->focused = NULL;
+ int nclients = list_length(loc->column->clients->next);
+ int starty = (loc->monitor->y + loc->monitor->h) - (nclients * MIN_HEIGHT);
+ loc->column->clients->h = starty - loc->monitor->y - 1;
+ client_adjust(loc->column->clients);
+ LIST_FOR_EACH(c, loc->column->clients->next)
{
c->y = starty;
c->h = MIN_HEIGHT;
}
}
-void stacked_addheight(Monitor* mon, Column* col, Client* c, int amount)
+void stacked_addheight(Location* loc, int amount)
{
- Client* prev = list_prev(col->clients, c);
+ Client* c = loc->client;
+ Client* prev = list_prev(loc->column->clients, c);
if (prev)
{
amount = (abs(amount) < BORDER_WIDTH ? min((int)(-c->h * 0.25), -2*MIN_HEIGHT) : amount);
int miny = (prev->y + MIN_HEIGHT);
- int maxy = min((mon->y + mon->h) , (c->y + c->h)) - MIN_HEIGHT;
+ int maxy = min((loc->monitor->y + loc->monitor->h) , (c->y + c->h)) - MIN_HEIGHT;
c->y = max(miny, min(maxy, c->y + amount));
prev->h = c->y - prev->y;
- c->h = (c->next ? c->next->y : mon->y + mon->h) - c->y;
+ c->h = (c->next ? c->next->y : loc->monitor->y + loc->monitor->h) - c->y;
printf("ADD_HEIGHT(w: %lx x: %d y: %d w: %d h: %d)\n", c->frame, c->x, c->y, c->w, c->h);
client_setshade(prev, (prev->h <= MIN_HEIGHT));
client_setshade(c, (c->h <= MIN_HEIGHT));