sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

dwm-exresize-r1606.diff (12751B)


      1 diff --git a/config.def.h b/config.def.h
      2 index 7fb4d82..959a119 100644
      3 --- a/config.def.h
      4 +++ b/config.def.h
      5 @@ -88,6 +88,33 @@ static Key keys[] = {
      6  	TAGKEYS(                        XK_8,                      7)
      7  	TAGKEYS(                        XK_9,                      8)
      8  	{ MODKEY|ShiftMask,             XK_q,      quit,           {0} },
      9 +
     10 +	{ MODKEY,                       XK_KP_7,   explace,                {.ui = EX_NW }},
     11 +	{ MODKEY,                       XK_KP_8,   explace,                {.ui = EX_N  }},
     12 +	{ MODKEY,                       XK_KP_9,   explace,                {.ui = EX_NE }},
     13 +	{ MODKEY,                       XK_KP_4,   explace,                {.ui = EX_W  }},
     14 +	{ MODKEY,                       XK_KP_5,   explace,                {.ui = EX_C  }},
     15 +	{ MODKEY,                       XK_KP_6,   explace,                {.ui = EX_E  }},
     16 +	{ MODKEY,                       XK_KP_1,   explace,                {.ui = EX_SW }},
     17 +	{ MODKEY,                       XK_KP_2,   explace,                {.ui = EX_S  }},
     18 +	{ MODKEY,                       XK_KP_3,   explace,                {.ui = EX_SE }},
     19 +
     20 +	{ MODKEY|ShiftMask,             XK_KP_8,   exresize,               {.v = (int []){   0,  25 }}},
     21 +	{ MODKEY|ShiftMask,             XK_KP_2,   exresize,               {.v = (int []){   0, -25 }}},
     22 +	{ MODKEY|ShiftMask,             XK_KP_6,   exresize,               {.v = (int []){  25,   0 }}},
     23 +	{ MODKEY|ShiftMask,             XK_KP_4,   exresize,               {.v = (int []){ -25,   0 }}},
     24 +	{ MODKEY|ShiftMask,             XK_KP_5,   exresize,               {.v = (int []){  25,  25 }}},
     25 +	{ MODKEY|ShiftMask|ControlMask, XK_KP_5,   exresize,               {.v = (int []){ -25, -25 }}},
     26 +
     27 +	{ MODKEY|ControlMask,           XK_KP_6,   togglehorizontalexpand, {.i = +1} },
     28 +	{ MODKEY|ControlMask,           XK_KP_3,   togglehorizontalexpand, {.i =  0} },
     29 +	{ MODKEY|ControlMask,           XK_KP_4,   togglehorizontalexpand, {.i = -1} },
     30 +	{ MODKEY|ControlMask,           XK_KP_8,   toggleverticalexpand,   {.i = +1} },
     31 +	{ MODKEY|ControlMask,           XK_KP_1,   toggleverticalexpand,   {.i =  0} },
     32 +	{ MODKEY|ControlMask,           XK_KP_2,   toggleverticalexpand,   {.i = -1} },
     33 +	{ MODKEY|ControlMask,           XK_KP_9,   togglemaximize,         {.i = -1} },
     34 +	{ MODKEY|ControlMask,           XK_KP_7,   togglemaximize,         {.i = +1} },
     35 +	{ MODKEY|ControlMask,           XK_KP_5,   togglemaximize,         {.i =  0} },
     36  };
     37  
     38  /* button definitions */
     39 diff --git a/dwm.c b/dwm.c
     40 index 4986b07..8fc0c57 100644
     41 --- a/dwm.c
     42 +++ b/dwm.c
     43 @@ -89,11 +89,14 @@ struct Client {
     44  	char name[256];
     45  	float mina, maxa;
     46  	int x, y, w, h;
     47 +	int sfx, sfy, sfw, sfh; /* stored float geometry, used on mode revert */
     48  	int oldx, oldy, oldw, oldh;
     49  	int basew, baseh, incw, inch, maxw, maxh, minw, minh;
     50  	int bw, oldbw;
     51  	unsigned int tags;
     52 -	Bool isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
     53 +	unsigned char expandmask;
     54 +	int expandx1, expandy1, expandx2, expandy2;
     55 +	Bool wasfloating, isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
     56  	Client *next;
     57  	Client *snext;
     58  	Monitor *mon;
     59 @@ -1132,8 +1135,14 @@ manage(Window w, XWindowAttributes *wa) {
     60  	updatewindowtype(c);
     61  	updatesizehints(c);
     62  	updatewmhints(c);
     63 +	c->sfx = c->x;
     64 +	c->sfy = c->y;
     65 +	c->sfw = c->w;
     66 +	c->sfh = c->h;
     67  	XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
     68  	grabbuttons(c, False);
     69 +	c->wasfloating = False;
     70 +	c->expandmask = 0;
     71  	if(!c->isfloating)
     72  		c->isfloating = c->oldstate = trans != None || c->isfixed;
     73  	if(c->isfloating)
     74 @@ -1234,8 +1243,9 @@ movemouse(const Arg *arg) {
     75  		case MotionNotify:
     76  			nx = ocx + (ev.xmotion.x - x);
     77  			ny = ocy + (ev.xmotion.y - y);
     78 -			if(nx >= selmon->wx && nx <= selmon->wx + selmon->ww
     79 -			&& ny >= selmon->wy && ny <= selmon->wy + selmon->wh) {
     80 +			if ((m = recttomon(nx, ny, c->w, c->h))) {
     81 +				if (m != selmon) 
     82 +					sendmon(c, m);
     83  				if(abs(selmon->wx - nx) < snap)
     84  					nx = selmon->wx;
     85  				else if(abs((selmon->wx + selmon->ww) - (nx + WIDTH(c))) < snap)
     86 @@ -1343,6 +1353,7 @@ resizeclient(Client *c, int x, int y, int w, int h) {
     87  	c->oldy = c->y; c->y = wc.y = y;
     88  	c->oldw = c->w; c->w = wc.width = w;
     89  	c->oldh = c->h; c->h = wc.height = h;
     90 +	c->expandmask = 0;
     91  	wc.border_width = c->bw;
     92  	XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
     93  	configure(c);
     94 @@ -1379,9 +1390,9 @@ resizemouse(const Arg *arg) {
     95  		case MotionNotify:
     96  			nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1);
     97  			nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1);
     98 -			if(c->mon->wx + nw >= selmon->wx && c->mon->wx + nw <= selmon->wx + selmon->ww
     99 -			&& c->mon->wy + nh >= selmon->wy && c->mon->wy + nh <= selmon->wy + selmon->wh)
    100 -			{
    101 +			if ((m = recttomon(c->x, c->y, nw, nh))) {
    102 +				if (m != selmon) 
    103 +					sendmon(c, m);
    104  				if(!c->isfloating && selmon->lt[selmon->sellt]->arrange
    105  				&& (abs(nw - c->w) > snap || abs(nh - c->h) > snap))
    106  					togglefloating(NULL);
    107 @@ -1463,6 +1474,7 @@ scan(void) {
    108  
    109  void
    110  sendmon(Client *c, Monitor *m) {
    111 +	Monitor *oldm = selmon;
    112  	if(c->mon == m)
    113  		return;
    114  	unfocus(c, True);
    115 @@ -1472,8 +1484,11 @@ sendmon(Client *c, Monitor *m) {
    116  	c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */
    117  	attach(c);
    118  	attachstack(c);
    119 -	focus(NULL);
    120 -	arrange(NULL);
    121 +	if (oldm != m)
    122 +		arrange(oldm);
    123 +	arrange(m);
    124 +	focus(c);
    125 +	restack(m);
    126  }
    127  
    128  void
    129 @@ -1549,8 +1564,18 @@ setfullscreen(Client *c, Bool fullscreen) {
    130  
    131  void
    132  setlayout(const Arg *arg) {
    133 -	if(!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
    134 +	if(!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) {
    135  		selmon->sellt ^= 1;
    136 +		if (!selmon->lt[selmon->sellt]->arrange) {
    137 +			for (Client *c = selmon->clients ; c ; c = c->next) {
    138 +				if(!c->isfloating) {
    139 +					/*restore last known float dimensions*/
    140 +					resize(c, selmon->mx + c->sfx, selmon->my + c->sfy,
    141 +					       c->sfw, c->sfh, False);
    142 +				}
    143 +			}
    144 +		}
    145 +	}
    146  	if(arg && arg->v)
    147  		selmon->lt[selmon->sellt] = (Layout *)arg->v;
    148  	strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol);
    149 @@ -1732,9 +1757,19 @@ togglefloating(const Arg *arg) {
    150  	if(selmon->sel->isfullscreen) /* no support for fullscreen windows */
    151  		return;
    152  	selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed;
    153 -	if(selmon->sel->isfloating)
    154 -		resize(selmon->sel, selmon->sel->x, selmon->sel->y,
    155 -		       selmon->sel->w, selmon->sel->h, False);
    156 +	if(selmon->sel->isfloating) {
    157 +		/*restore last known float dimensions*/
    158 +		resize(selmon->sel, selmon->mx + selmon->sel->sfx, selmon->my + selmon->sel->sfy,
    159 +		       selmon->sel->sfw, selmon->sel->sfh, False);
    160 +	} else {
    161 +		if (selmon->sel->isfullscreen)
    162 +			setfullscreen(selmon->sel, False);
    163 +		/*save last known float dimensions*/
    164 +		selmon->sel->sfx = selmon->sel->x - selmon->mx;
    165 +		selmon->sel->sfy = selmon->sel->y - selmon->my;
    166 +		selmon->sel->sfw = selmon->sel->w;
    167 +		selmon->sel->sfh = selmon->sel->h;
    168 +	}
    169  	arrange(selmon);
    170  }
    171  
    172 diff --git a/exresize.c b/exresize.c
    173 new file mode 100644
    174 index 0000000..2343ffe
    175 --- /dev/null
    176 +++ b/exresize.c
    177 @@ -0,0 +1,195 @@
    178 +#define EXPAND_LEFT  (1 << 0)
    179 +#define EXPAND_RIGHT (1 << 2)
    180 +#define EXPAND_UP    (1 << 4)
    181 +#define EXPAND_DOWN  (1 << 6)
    182 +
    183 +#define IS_SET(q, w) ((q & w) != 0)
    184 +#define IS_FORCED(q, w) IS_SET((q << 1), w)
    185 +
    186 +#define EXPANDALL       (EXPAND_LEFT | EXPAND_RIGHT | EXPAND_UP | EXPAND_DOWN)
    187 +#define UNEXPAND       (EXPANDALL << 1) // Force all directions to 0
    188 +#define FORCE_EXPANDALL ~0 // Force expand in all directions
    189 +
    190 +enum { EX_NW, EX_N, EX_NE, EX_W, EX_C, EX_E, EX_SW, EX_S, EX_SE };
    191 +
    192 +void expand(unsigned char mask);
    193 +
    194 +void togglemaximize(const Arg *arg);
    195 +void toggleverticalexpand(const Arg *arg);
    196 +void togglehorizontalexpand(const Arg *arg);
    197 +void exresize(const Arg *arg);
    198 +void explace(const Arg *arg);
    199 +
    200 +void
    201 +exresize(const Arg *arg) {
    202 +	Client *c;
    203 +	int x, y, nx, ny, nw, nh;
    204 +	c = selmon->sel;
    205 +
    206 +	if (!c || !arg) return;
    207 +	if (selmon->lt[selmon->sellt]->arrange && !c->isfloating)
    208 +		togglefloating(NULL);
    209 +	if (c->expandmask != 0)
    210 +		expand(UNEXPAND);
    211 +
    212 +	x = ((int *)arg->v)[0];
    213 +	y = ((int *)arg->v)[1];
    214 +
    215 +	nw = MIN(selmon->ww - c->bw*2, c->w + x);
    216 +	nh = MIN(selmon->wh - c->bw*2, c->h + y);
    217 +	nx = c->x - x/2;
    218 +	ny = c->y - y/2;
    219 +
    220 +	if (!((abs(c->x + c->w/2 - (selmon->wx + selmon->ww/2)) < snap))) {
    221 +		if ((nw == selmon->ww) || 
    222 +				(nx < selmon->wx) ||
    223 +				(abs(selmon->wx - c->x) < snap))
    224 +			nx = selmon->wx;
    225 +		else if ((nx+nw > (selmon->wx + selmon->ww)) || 
    226 +				(abs((selmon->wx + selmon->ww) - (c->x + c->w)) < snap))
    227 +			nx = (selmon->wx + selmon->ww) - nw - c->bw*2;
    228 +    } else 
    229 +		nx = selmon->wx + selmon->ww/2 - nw/2;
    230 +
    231 +    if (!((abs(c->y + c->h/2 - (selmon->wy + selmon->wh/2)) < snap))) {
    232 +
    233 +		if ((nh == selmon->wh) || 
    234 +				(ny < selmon->wy) ||
    235 +				(abs(selmon->wy - c->y) < snap))
    236 +			ny = selmon->wy;
    237 +		else if ((ny+nh > (selmon->wy + selmon->wh)) ||
    238 +				(abs((selmon->wy + selmon->wh) - (c->y + c->h)) < snap))
    239 +			ny = (selmon->wy + selmon->wh) - nh - c->bw*2;
    240 +	} else 
    241 +        ny = selmon->wy + selmon->wh/2 - nh/2;
    242 +
    243 +
    244 +	resizeclient(c, nx, ny, MAX(nw, 32), MAX(nh, 32));
    245 +	XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w/2, c->h/2);
    246 +}
    247 +
    248 +void
    249 +explace(const Arg *arg) {
    250 +	Client *c;
    251 +	int nx, ny;
    252 +
    253 +	c = selmon->sel;
    254 +	if (!c || (arg->ui >= 9)) return;
    255 +	if (selmon->lt[selmon->sellt]->arrange && !c->isfloating)
    256 +		togglefloating(NULL);
    257 +
    258 +	nx = (arg->ui % 3) - 1;
    259 +	ny = (arg->ui / 3) - 1;
    260 +
    261 +	if (nx < 0) nx = selmon->wx;
    262 +	else if (nx > 0) nx = selmon->wx + selmon->ww - c->w - c->bw*2;
    263 +	else nx = selmon->wx + selmon->ww/2 - c->w/2;
    264 +
    265 +	if (ny < 0) ny = selmon->wy;
    266 +	else if (ny > 0) ny = selmon->wy + selmon->wh - c->h - c->bw*2;
    267 +	else ny = selmon->wy + selmon->wh/2 - c->h/2;
    268 +
    269 +	resize(c, nx, ny, c->w, c->h, True);
    270 +	XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w/2, c->h/2);
    271 +}
    272 +
    273 +int
    274 +calculate_expand(unsigned char mask, unsigned char curmask,
    275 +		unsigned char *newmask, unsigned char key,
    276 +		int *reset_value, int new_reset_value,
    277 +		int max_value, int old_value) {
    278 +	if (IS_SET(key, mask) ||
    279 +			(IS_SET(key, curmask) && (!IS_SET(key, mask) && IS_FORCED(key, mask))) ||
    280 +			(!IS_SET(key, curmask) && (IS_SET(key, mask) && IS_FORCED(key, mask)))) {
    281 +
    282 +		if (IS_SET(key, mask) && (!IS_SET(key,curmask) || IS_FORCED(key,mask)))
    283 +		{
    284 +			if (!IS_SET(key, curmask))
    285 +				*reset_value = new_reset_value;
    286 +			*newmask |= key;
    287 +			return max_value;
    288 +		} else if ((IS_SET(key,curmask) && IS_SET(key, mask)) ||
    289 +				(!IS_SET(key, mask) && IS_FORCED(key, mask))) {
    290 +			*newmask &= ~key;
    291 +			return *reset_value;
    292 +		} else {
    293 +			*newmask &= ~key;
    294 +			return old_value;
    295 +		}
    296 +	} else
    297 +		return new_reset_value;
    298 +}
    299 +
    300 +void
    301 +expand(unsigned char mask) {
    302 +	XEvent ev;
    303 +	int nx1, ny1, nx2, ny2;
    304 +	unsigned char curmask;
    305 +	unsigned char newmask;
    306 +
    307 +	if(!selmon->sel || selmon->sel->isfixed)
    308 +		return;
    309 +	XRaiseWindow(dpy, selmon->sel->win);
    310 +	newmask = curmask = selmon->sel->expandmask;
    311 +
    312 +	if (curmask == 0) {
    313 +		if(!selmon->lt[selmon->sellt]->arrange || selmon->sel->isfloating)
    314 +			selmon->sel->wasfloating = True;
    315 +		else {
    316 +			togglefloating(NULL);
    317 +			selmon->sel->wasfloating = False;
    318 +		}
    319 +	}
    320 +
    321 +	nx1 = calculate_expand(mask, curmask, &newmask,
    322 +			EXPAND_LEFT, &selmon->sel->expandx1,
    323 +			selmon->sel->x,
    324 +			selmon->wx,
    325 +			selmon->sel->oldx);
    326 +	nx2 = calculate_expand(mask, curmask, &newmask,
    327 +			EXPAND_RIGHT, &selmon->sel->expandx2,
    328 +			selmon->sel->x + selmon->sel->w,
    329 +			selmon->wx + selmon->ww - 2*borderpx,
    330 +			selmon->sel->oldw + selmon->sel->x);
    331 +	ny1 = calculate_expand(mask, curmask, &newmask,
    332 +			EXPAND_UP, &selmon->sel->expandy1,
    333 +			selmon->sel->y,
    334 +			selmon->wy,
    335 +			selmon->sel->oldy);
    336 +	ny2 = calculate_expand(mask, curmask, &newmask,
    337 +			EXPAND_DOWN, &selmon->sel->expandy2,
    338 +			selmon->sel->y + selmon->sel->h,
    339 +			selmon->wy + selmon->wh - 2*borderpx,
    340 +			selmon->sel->oldh + selmon->sel->y);
    341 +
    342 +
    343 +	resizeclient(selmon->sel, nx1, ny1, MAX(nx2-nx1, 32), MAX(ny2-ny1, 32));
    344 +
    345 +	if ((newmask == 0) && (!selmon->sel->wasfloating))
    346 +		togglefloating(NULL);
    347 +	selmon->sel->expandmask = newmask;
    348 +	drawbar(selmon);
    349 +	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
    350 +}
    351 +
    352 +void
    353 +togglemaximize(const Arg *arg) {
    354 +	if (arg->i > 0) expand(FORCE_EXPANDALL);
    355 +	else if (arg->i < 0) expand(UNEXPAND);
    356 +	else expand(EXPANDALL);
    357 +}
    358 +
    359 +void
    360 +toggleverticalexpand(const Arg *arg) {
    361 +	if (arg->i < 0) expand(EXPAND_DOWN);
    362 +	else if (arg->i > 0) expand(EXPAND_UP);
    363 +	else expand(EXPAND_DOWN | EXPAND_UP);
    364 +}
    365 +
    366 +void
    367 +togglehorizontalexpand(const Arg *arg) {
    368 +	if (arg->i < 0) expand(EXPAND_LEFT);
    369 +	else if (arg->i > 0) expand(EXPAND_RIGHT);
    370 +	else expand(EXPAND_LEFT | EXPAND_RIGHT);
    371 +}
    372 +