commit 156f1828f6feabff76ce82e79ddd72f26c5b950d
parent 8a2782bba3ac5a64a55c7d7760955e7dac21cd05
Author: Kris Maglione <jg@suckless.org>
Date: Sat, 5 Apr 2008 17:04:00 -0400
Add grow and nudge commands to /tag/*/ctl.
Diffstat:
3 files changed, 179 insertions(+), 4 deletions(-)
diff --git a/cmd/wmii/float.c b/cmd/wmii/float.c
@@ -50,6 +50,15 @@ float_detach(Frame *f) {
area_focus(sel);
}
+void
+float_resizeframe(Frame *f, Rectangle r) {
+
+ if(f->area->view == screen->sel)
+ client_resize(f->client, r);
+ else
+ frame_resize(f, r);
+}
+
static void
rect_push(Vector_rect *vec, Rectangle r) {
Rectangle *rp;
diff --git a/cmd/wmii/fns.h b/cmd/wmii/fns.h
@@ -115,6 +115,7 @@ void ewmh_updateviews(void);
/* float.c */
void float_attach(Area*, Frame*);
void float_detach(Frame*);
+void float_resizeframe(Frame*, Rectangle);
/* frame.c */
Frame* frame_create(Client*, View*);
diff --git a/cmd/wmii/message.c b/cmd/wmii/message.c
@@ -6,6 +6,8 @@
#include "fns.h"
static char* msg_debug(IxpMsg*);
+static char* msg_grow(View*, IxpMsg*);
+static char* msg_nudge(View*, IxpMsg*);
static char* msg_selectframe(Frame*, IxpMsg*, int);
static char* msg_sendframe(Frame*, int, bool);
@@ -27,9 +29,11 @@ enum {
LFOCUSCOLORS,
LFONT,
LGRABMOD,
+ LGROW,
LKILL,
LLEFT,
LNORMCOLORS,
+ LNUDGE,
LOFF,
LON,
LQUIT,
@@ -56,9 +60,11 @@ char *symtab[] = {
"focuscolors",
"font",
"grabmod",
+ "grow",
"kill",
"left",
"normcolors",
+ "nudge",
"off",
"on",
"quit",
@@ -132,6 +138,21 @@ gettoggle(IxpMsg *m) {
}
}
+static int
+getdirection(IxpMsg *m) {
+ int i;
+
+ switch(i = getsym(msg_getword(m))) {
+ case LLEFT:
+ case LRIGHT:
+ case LUP:
+ case LDOWN:
+ return i;
+ default:
+ return -1;
+ }
+}
+
static void
eatrunes(IxpMsg *m, int (*p)(Rune), int val) {
Rune r;
@@ -243,6 +264,14 @@ getulong(const char *s, ulong *ret) {
return (end == rend);
}
+static char*
+strend(const char *s, int n) {
+ int len;
+
+ len = strlen(s);
+ return (char*)(uintptr_t)s + max(0, len - n);
+}
+
static Client*
strclient(View *v, char *s) {
ulong id;
@@ -252,6 +281,8 @@ strclient(View *v, char *s) {
* 0x<window xid>
*/
+ if(s == nil)
+ return nil;
if(!strcmp(s, "sel"))
return view_selclient(v);
if(getulong(s, &id))
@@ -293,6 +324,40 @@ strarea(View *v, const char *s) {
return a;
}
+static Frame*
+getframe(View *v, IxpMsg *m) {
+ Client *c;
+ Frame *f;
+ Area *a;
+ char *s;
+ ulong l;
+
+ s = msg_getword(m);
+ if(!strcmp(s, "client")) {
+ c = strclient(v, msg_getword(m));
+ if(c == nil)
+ return nil;
+ return client_viewframe(c, v);
+ }
+
+ a = strarea(v, s);
+ if(a == nil) {
+ print("a == nil\n");
+ return nil;
+ }
+
+ s = msg_getword(m);
+ if(!s)
+ return nil;
+ if(!strcmp(s, "sel"))
+ return a->sel;
+ if(!getulong(s, &l))
+ return nil;
+ for(f=a->frame; f; f=f->anext)
+ if(--l == 0) break;
+ return f;
+}
+
char*
message_client(Client *c, IxpMsg *m) {
char *s;
@@ -418,13 +483,14 @@ message_view(View *v, IxpMsg *m) {
* area ::= ~
* | <column number>
* | sel
+ * direction ::= left
+ * | right
+ * | up
+ * | down
* # This *should* be identical to <frame>
* place ::= <column number>
* #| ~ # This should be, but isn't.
- * | left
- * | right
- * | up
- * | down
+ * | <direction>
* | toggle
* colmode ::= default
* | stack
@@ -441,11 +507,16 @@ message_view(View *v, IxpMsg *m) {
* | ~
* | <column> <frame number>
* | <column>
+ * amount ::=
+ * | <number>
+ * | <number>px
*
* colmode <area> <colmode>
* select <area>
* send <frame> <place>
* swap <frame> <place>
+ * grow <thing> <direction> <amount>
+ * nudge <thing> <direction> <amount>
* select <ordframe>
*/
@@ -469,6 +540,10 @@ message_view(View *v, IxpMsg *m) {
view_focus(screen, v);
frame_draw_all();
return nil;
+ case LGROW:
+ return msg_grow(v, m);
+ case LNUDGE:
+ return msg_nudge(v, m);
case LSELECT:
return msg_selectarea(v->sel, m);
case LSEND:
@@ -507,6 +582,96 @@ msg_debug(IxpMsg *m) {
return nil;
}
+static bool
+getamt(IxpMsg *m, int *amt) {
+ char *s, *p;
+ long l;
+
+ s = msg_getword(m);
+ if(s) {
+ p = strend(s, 2);
+ if(!strcmp(p, "px")) {
+ *p = '\0';
+ *amt = 1;
+ }
+
+ if(!getlong(s, &l))
+ return false;
+ *amt *= l;
+ }
+ return true;
+}
+
+static char*
+msg_grow(View *v, IxpMsg *m) {
+ Frame *f;
+ Rectangle r;
+ int dir, amount;
+
+ f = getframe(v, m);
+ if(f == nil)
+ return "bad frame";
+
+ dir = getdirection(m);
+ if(dir == -1)
+ return "bad direction";
+
+ amount = Dy(f->titlebar);
+ if(!getamt(m, &amount))
+ return Ebadvalue;
+
+ r = f->r;
+ switch(dir) {
+ case LLEFT: r.min.x -= amount; break;
+ case LRIGHT: r.max.x += amount; break;
+ case LUP: r.min.y -= amount; break;
+ case LDOWN: r.max.y += amount; break;
+ default: abort();
+ }
+
+ if(f->area->floating)
+ float_resizeframe(f, r);
+ else
+ column_resizeframe(f, r);
+
+ return nil;
+}
+
+static char*
+msg_nudge(View *v, IxpMsg *m) {
+ Frame *f;
+ Rectangle r;
+ int dir, amount;
+
+ f = getframe(v, m);
+ if(f == nil)
+ return "bad frame";
+
+ dir = getdirection(m);
+ if(dir == -1)
+ return "bad direction";
+
+ amount = Dy(f->titlebar);
+ if(!getamt(m, &amount))
+ return Ebadvalue;
+
+ r = f->r;
+ switch(dir) {
+ case LLEFT: r = rectaddpt(r, Pt(-amount, 0)); break;
+ case LRIGHT: r = rectaddpt(r, Pt( amount, 0)); break;
+ case LUP: r = rectaddpt(r, Pt(0, -amount)); break;
+ case LDOWN: r = rectaddpt(r, Pt(0, amount)); break;
+ default: abort();
+ }
+
+ if(f->area->floating)
+ float_resizeframe(f, r);
+ else
+ column_resizeframe(f, r);
+
+ return nil;
+}
+
char*
msg_parsecolors(IxpMsg *m, CTuple *col) {
static char Ebad[] = "bad color string";