dwm-exresize-r1606.diff - sites - public wiki contents of suckless.org
(HTM) git clone git://git.suckless.org/sites
(DIR) Log
(DIR) Files
(DIR) 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 +