static void xbtnpress(XEvent* e)
{
XButtonEvent* ev = &(e->xbutton);
- X.start_x = ev->x_root;
- X.start_y = 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;
Client* c = client_get(e->xbutton.window, &loc);
if (c && (ev->window == c->frame))
{
- mouse_click(ev, &loc);
+ mouse_down(ev, &loc);
}
}
static void xbtnrelease(XEvent* e)
{
- (void)e;
+ XButtonEvent* ev = &(e->xbutton);
+ Location loc;
+ Client* c = client_get(e->xbutton.window, &loc);
+ if (c && (ev->window == c->frame))
+ {
+ mouse_up(ev, &loc);
+ }
X.mode = M_IDLE;
}
{
mouse_drag(ev, &loc);
}
- X.start_x = ev->x_root;
- X.start_y = ev->y_root;
+ X.last_x = ev->x_root, X.last_y = ev->y_root;
}
static void xconfigrequest(XEvent* e)
typedef struct {
Display* disp;
- int screen, mode, start_x, start_y;
+ int screen, mode, start_x, start_y, last_x, last_y;
Window root;
unsigned long black, white, gray;
Cursor csr_root, csr_point;
void client_show(Client* c, int show);
void client_readprops(Client* c);
void client_shade(Client* c);
+void client_setshade(Client* c, int shade);
/* mouse.c */
-void mouse_click(XButtonEvent* ev, Location* loc);
+void mouse_down(XButtonEvent* ev, Location* loc);
+void mouse_up(XButtonEvent* ev, Location* loc);
void mouse_drag(XMotionEvent* ev, Location* loc);
/* tile.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);
/* error.c */
extern int (*error_default)(Display* disp, XErrorEvent* ev);
#!/bin/sh
cc -g -Wall -Wextra -Werror -I/usr/X11R6/include -L/usr/X11R6/lib -o anvil *.c -lX11 -lXinerama -lm
+error="$?"
ctags *
grep -n 'TODO' *.c | sed -e 's/: \+/: /' -e 's/\/\* *//g' -e 's/ *\*\/$//' -e 's/TODO: *//'
+exit "$error"
wa.do_not_propagate_mask = ButtonPressMask | ButtonReleaseMask;
XChangeWindowAttributes(X.disp, c->win, CWEventMask | CWDontPropagate, &wa);
XReparentWindow(X.disp, c->win, c->frame,
- BORDER_WIDTH, BORDER_WIDTH + TITLE_HEIGHT
- );
+ BORDER_WIDTH, BORDER_WIDTH + TITLE_HEIGHT);
/* Map the window and draw the frame */
XAddToSaveSet(X.disp, c->win);
{
c->w += xdiff;
c->h += ydiff;
- if (c->w < 50) c->w = 50;
- if (c->h < 50) c->h = 50;
+ if (c->w < TITLE_HEIGHT+BORDER_WIDTH) c->w = TITLE_HEIGHT+BORDER_WIDTH;
+ if (c->h < TITLE_HEIGHT+BORDER_WIDTH) c->h = TITLE_HEIGHT+BORDER_WIDTH;
if (c->flags & F_SHADED)
{
XResizeWindow(X.disp, c->frame, c->w, TITLE_HEIGHT+BORDER_WIDTH);
void client_shade(Client* c)
{
if (c->flags & F_SHADED)
+ {
+ client_setshade(c, 0);
+ }
+ else
+ {
+ client_setshade(c, 1);
+ }
+ client_adjust(c);
+}
+
+void client_setshade(Client* c, int shade)
+{
+ if (!shade && (c->flags & F_SHADED))
{
c->flags &= ~F_SHADED;
XMapWindow(X.disp, c->win);
}
- else
+ else if (shade && !(c->flags & F_SHADED))
{
c->flags |= F_SHADED;
XUnmapWindow(X.disp, c->win);
}
- client_adjust(c);
}
static void stacked_click(XButtonEvent* ev, Location* loc)
{
- /* TODO: handle button 1 drag to resize, reposition, and move windows */
if (ev->button == Button2)
{
client_close(loc->client);
}
}
-void mouse_click(XButtonEvent* ev, Location* loc)
+void mouse_down(XButtonEvent* ev, Location* loc)
{
if (!loc->column)
{
{
if (X.mode != M_RESIZE)
{
- client_move(loc->client, ev->x_root - X.start_x, ev->y_root - X.start_y);
+ client_move(loc->client, ev->x_root - X.last_x, ev->y_root - X.last_y);
}
else
{
- client_resize(loc->client, ev->x_root - X.start_x, ev->y_root - X.start_y);
+ client_resize(loc->client, ev->x_root - X.last_x, ev->y_root - X.last_y);
}
XSync(X.disp, False);
}
}
+void mouse_up(XButtonEvent* ev, Location* loc)
+{
+ (void)ev, (void)loc;
+ /* TODO: handle button 1 drag to resize, reposition, and move windows */
+ /* TODO: check if we clicked in frame originally or if we clicked in titlebar */
+ if (!loc->column->focused)
+ {
+ stacked_addheight(loc->monitor, loc->column, loc->client, ev->y_root - X.start_y);
+ }
+}
+
static void monocled_drag(XMotionEvent* ev, Location* loc)
{
(void)ev, (void)loc;
/* TODO: implement switch back to stacked mode */
}
-
-
+void stacked_addheight(Monitor* mon, Column* col, Client* c, int amount)
+{
+ Client* prev = col->clients;
+ for (; prev && prev->next != c; prev = prev->next);
+ if (prev)
+ {
+ amount = (amount == 0 ? (int)(-c->h * 0.25) : amount);
+ int miny = (prev->y + TITLE_HEIGHT+BORDER_WIDTH);
+ int maxy = min((mon->y + mon->h) , (c->y + c->h)) - TITLE_HEIGHT+BORDER_WIDTH;
+ if (amount < 0)
+ {
+ c->y = max(miny, c->y + amount);
+ prev->h = c->y - prev->y;
+ }
+ else if (amount > 0)
+ {
+ c->y = min(maxy, c->y + amount);
+ prev->h = c->y - prev->y;
+ }
+ c->h = (c->next ? c->next->y : mon->y + mon->h) - c->y;
+ client_setshade(prev, (prev->h <= TITLE_HEIGHT+BORDER_WIDTH));
+ client_setshade(c, (c->h <= TITLE_HEIGHT+BORDER_WIDTH));
+ client_adjust(prev);
+ client_adjust(c);
+ }
+}
int new_w = c->w - BORDER_WIDTH/2;
int new_h = c->h - BORDER_WIDTH/2;
XWarpPointer(X.disp, None, c->frame, 0, 0, 0, 0, new_w, new_h);
- X.start_x = c->x + new_w;
- X.start_y = c->y + new_h;
+ X.last_x = c->x + new_w;
+ X.last_y = c->y + new_h;
}
Client* delclient(Client* list, Client* dead)