CTWM
Loading...
Searching...
No Matches
/usr/src/RPM/BUILD/ctwm-4.1.0/win_resize.c
Go to the documentation of this file.
1/*
2 * Copyright 1988 by Evans & Sutherland Computer Corporation,
3 * Salt Lake City, Utah
4 * Portions Copyright 1989 by the Massachusetts Institute of Technology
5 * Cambridge, Massachusetts
6 *
7 * Copyright 1992 Claude Lecommandeur.
8 */
9
10/***********************************************************************
11 *
12 * $XConsortium: resize.c,v 1.80 91/05/11 17:35:42 dave Exp $
13 *
14 * window resizing borrowed from the "wm" window manager
15 *
16 * 11-Dec-87 Thomas E. LaStrange File created
17 *
18 * Do the necessary modification to be integrated in ctwm.
19 * Can no longer be used for the standard twm.
20 *
21 * 22-April-92 Claude Lecommandeur.
22 *
23 *
24 ***********************************************************************/
25
26#include "ctwm.h"
27
28#include <stdio.h>
29#include <stdlib.h>
30
31#include "events.h"
32#include "util.h"
33#include "otp.h"
34#include "functions_defs.h"
35#include "add_window.h"
36#include "colormaps.h"
37#include "screen.h"
38#include "drawing.h"
39#include "r_area.h"
40#include "r_area_list.h"
41#include "r_layout.h"
42#include "win_decorations.h"
43#include "win_ops.h"
44#include "win_resize.h"
45#include "win_utils.h"
46#include "workspace_manager.h"
47#include "iconmgr.h"
48
49#define MINHEIGHT 0 /* had been 32 */
50#define MINWIDTH 0 /* had been 60 */
51
52static int dragx; /* all these variables are used */
53static int dragy; /* in resize operations */
54static unsigned int dragWidth;
55static unsigned int dragHeight;
56
57static int origx;
58static int origy;
59static int origWidth;
60static int origHeight;
61
62static int clampTop;
63static int clampBottom;
64static int clampLeft;
65static int clampRight;
66static int clampDX;
67static int clampDY;
68
69static int last_width;
70static int last_height;
71
72static unsigned int resizeGrabMask;
73
74static void DisplaySize(TwmWindow *tmp_win, int width, int height);
75
77{
79 int x, y, h, v, junkbw;
80 unsigned int junkMask;
81
82 switch(evp->type) {
83 case ButtonPress:
84 x = evp->xbutton.x_root;
85 y = evp->xbutton.y_root;
86 break;
87 case KeyPress:
88 x = evp->xkey.x_root;
89 y = evp->xkey.y_root;
90 break;
91 default:
92 if(!XQueryPointer(dpy, Scr->Root, &junkRoot, &junkRoot,
93 &x, &y, &junkbw, &junkbw, &junkMask)) {
94 return;
95 }
96 }
97
98 /*
99 * Determine in which of the 9 "quadrants" of the window we are.
100 * Cast the values to signed int: if the numerator is negative
101 * we don't want them converted to unsigned due to the default
102 * promotion rules: that would produce a very large quotient.
103 */
104 h = (int)(x - dragx) / (int)(dragWidth < 3 ? 1 : (dragWidth / 3));
105 v = (int)(y - dragy - tmp_win->title_height) /
106 (int)(dragHeight < 3 ? 1 : (dragHeight / 3));
107
108 if(h <= 0) {
109 clampLeft = 1;
110 clampDX = (x - dragx);
111 }
112 else if(h >= 2) {
113 clampRight = 1;
114 clampDX = (x - dragx - dragWidth);
115 }
116
117 if(v <= 0) {
118 clampTop = 1;
119 clampDY = (y - dragy);
120 }
121 else if(v >= 2) {
122 clampBottom = 1;
123 clampDY = (y - dragy - dragHeight);
124 }
125}
126
127/***********************************************************************
128 *
129 * Procedure:
130 * OpaqueResizeSize - determine if window should be resized opaquely.
131 *
132 * Inputs:
133 * tmp_win - the TwmWindow pointer
134 *
135 ***********************************************************************
136 */
137
139{
140 if(tmp_win->OpaqueResize) {
141 /*
142 * OpaqueResize defaults to a thousand. Assume that any number
143 * >= 1000 is "infinity" and don't bother calculating.
144 */
145 if(Scr->OpaqueResizeThreshold >= 1000) {
146 Scr->OpaqueResize = true;
147 }
148 else {
149 /*
150 * scrsz will hold the number of pixels in your resolution,
151 * which can get big. [signed] int may not cut it.
152 */
153 const unsigned long winsz = tmp_win->frame_width
154 * tmp_win->frame_height;
155 const unsigned long scrsz = Scr->rootw * Scr->rooth;
156 if(winsz > (scrsz * (Scr->OpaqueResizeThreshold / 100.0))) {
157 Scr->OpaqueResize = false;
158 }
159 else {
160 Scr->OpaqueResize = true;
161 }
162 }
163 }
164 else {
165 Scr->OpaqueResize = false;
166 }
167}
168
169
170/***********************************************************************
171 *
172 * Procedure:
173 * StartResize - begin a window resize operation
174 *
175 * Inputs:
176 * ev - the event structure (button press)
177 * tmp_win - the TwmWindow pointer
178 * fromtitlebar - action invoked from titlebar button
179 *
180 ***********************************************************************
181 */
182
184 bool fromtitlebar, bool from3dborder)
185{
187 unsigned int junkbw, junkDepth;
188 Cursor cursor;
189
190 cursor = (Scr->BorderCursors
191 && tmp_win->curcurs) ? tmp_win->curcurs : Scr->ResizeCursor;
192 ResizeWindow = tmp_win->frame;
193 if(! Scr->OpaqueResize || resizeWhenAdd) {
195 }
198
199 grabwin = Scr->Root;
200#ifdef WINBOX
201 if(tmp_win->winbox) {
202 grabwin = tmp_win->winbox->window;
203 }
204#endif
207
210 &junkDepth);
211 dragx += tmp_win->frame_bw;
212 dragy += tmp_win->frame_bw;
213 origx = dragx;
214 origy = dragy;
218
219 if(Scr->AutoRelativeResize && (from3dborder || !fromtitlebar)) {
221 }
222
223 Scr->SizeStringOffset = SIZE_HINDENT;
224 MoveResizeSizeWindow(evp->xbutton.x_root, evp->xbutton.y_root,
225 Scr->SizeStringWidth + SIZE_HINDENT * 2,
226 Scr->SizeFont.height + SIZE_VINDENT * 2);
227 XMapRaised(dpy, Scr->SizeWindow);
229 last_width = 0;
230 last_height = 0;
232
233 if(! Scr->OpaqueResize || resizeWhenAdd)
234 MoveOutline(Scr->Root, dragx - tmp_win->frame_bw,
235 dragy - tmp_win->frame_bw, dragWidth + 2 * tmp_win->frame_bw,
236 dragHeight + 2 * tmp_win->frame_bw,
237 tmp_win->frame_bw, tmp_win->title_height + tmp_win->frame_bw3D);
238}
239
240
241void MenuStartResize(TwmWindow *tmp_win, int x, int y, int w, int h)
242{
243 if(! Scr->OpaqueResize) {
245 }
249 Scr->Root, Scr->ResizeCursor, CurrentTime);
250 dragx = x + tmp_win->frame_bw;
251 dragy = y + tmp_win->frame_bw;
252 origx = dragx;
253 origy = dragy;
254 dragWidth = origWidth = w;
257 last_width = 0;
258 last_height = 0;
259 Scr->SizeStringOffset = SIZE_HINDENT;
261 Scr->SizeStringWidth + SIZE_HINDENT * 2,
262 Scr->SizeFont.height + SIZE_VINDENT * 2);
263 XMapRaised(dpy, Scr->SizeWindow);
265 if(! Scr->OpaqueResize)
266 MoveOutline(Scr->Root, dragx - tmp_win->frame_bw,
267 dragy - tmp_win->frame_bw,
268 dragWidth + 2 * tmp_win->frame_bw,
269 dragHeight + 2 * tmp_win->frame_bw,
270 tmp_win->frame_bw, tmp_win->title_height + tmp_win->frame_bw3D);
271}
272
273/***********************************************************************
274 *
275 * Procedure:
276 * AddStartResize - begin a windorew resize operation from AddWindow
277 *
278 * Inputs:
279 * tmp_win - the TwmWindow pointer
280 *
281 ***********************************************************************
282 */
283
284void AddStartResize(TwmWindow *tmp_win, int x, int y, int w, int h)
285{
290 Scr->Root, Scr->ResizeCursor, CurrentTime);
291
292 dragx = x + tmp_win->frame_bw;
293 dragy = y + tmp_win->frame_bw;
294 origx = dragx;
295 origy = dragy;
296 dragWidth = origWidth = w - 2 * tmp_win->frame_bw;
297 dragHeight = origHeight = h - 2 * tmp_win->frame_bw;
299 last_width = 0;
300 last_height = 0;
302}
303
304
306{
307 int action;
308 Cursor cursor = 0;
309
310 action = 0;
311
312 x_root -= clampDX;
313 y_root -= clampDY;
314
315 if(clampTop) {
316 int delta = y_root - dragy;
317 if((int)(dragHeight - delta) < MINHEIGHT) {
319 clampTop = 0;
320 }
321 dragy += delta;
322 dragHeight -= delta;
323 action = 1;
324 cursor = TopCursor;
325 }
326 else if(y_root <= dragy) {
327 dragy = y_root;
329 y_root;
330 clampBottom = 0;
331 clampTop = 1;
332 clampDY = 0;
333 action = 1;
334 cursor = TopCursor;
335 }
336 if(clampLeft) {
337 int delta = x_root - dragx;
338 if((int)(dragWidth - delta) < MINWIDTH) {
340 clampLeft = 0;
341 }
342 dragx += delta;
343 dragWidth -= delta;
344 action = 1;
345 cursor = clampTop ? TopLeftCursor : LeftCursor;
346 }
347 else if(x_root <= dragx) {
348 dragx = x_root;
350 x_root;
351 clampRight = 0;
352 clampLeft = 1;
353 clampDX = 0;
354 action = 1;
355 cursor = clampTop ? TopLeftCursor : LeftCursor;
356 }
357 if(clampBottom) {
358 int delta = y_root - dragy - dragHeight;
359 if((int)(dragHeight + delta) < MINHEIGHT) {
361 clampBottom = 0;
362 }
363 dragHeight += delta;
364 action = 1;
366 }
367 else if(y_root >= dragy + dragHeight) {
368 dragy = origy;
369 dragHeight = 1 + y_root - dragy;
370 clampTop = 0;
371 clampBottom = 1;
372 clampDY = 0;
373 action = 1;
375 }
376 if(clampRight) {
377 int delta = x_root - dragx - dragWidth;
378 if((int)(dragWidth + delta) < MINWIDTH) {
380 clampRight = 0;
381 }
382 dragWidth += delta;
383 action = 1;
385 cursor = clampTop ? TopRightCursor : cursor;
386 }
387 else if(x_root >= dragx + dragWidth) {
388 dragx = origx;
389 dragWidth = 1 + x_root - origx;
390 clampLeft = 0;
391 clampRight = 1;
392 clampDX = 0;
393 action = 1;
395 cursor = clampTop ? TopRightCursor : cursor;
396 }
397
398 if(action) {
400 if(clampLeft) {
402 }
403 if(clampTop) {
405 }
406 if(Scr->OpaqueResize)
407 SetupWindow(tmp_win, dragx - tmp_win->frame_bw, dragy - tmp_win->frame_bw,
408 dragWidth, dragHeight, -1);
409 else
410 MoveOutline(Scr->Root,
411 dragx - tmp_win->frame_bw,
412 dragy - tmp_win->frame_bw,
413 dragWidth + 2 * tmp_win->frame_bw,
414 dragHeight + 2 * tmp_win->frame_bw,
415 tmp_win->frame_bw, tmp_win->title_height + tmp_win->frame_bw3D);
416 if(Scr->BorderCursors && (cursor != tmp_win->curcurs)) {
417 tmp_win->curcurs = cursor;
419 }
420 }
421
423}
424
425/***********************************************************************
426 *
427 * Procedure:
428 * DoResize - move the rubberband around. This is called for
429 * each motion event when we are resizing
430 *
431 * Inputs:
432 * x_root - the X corrdinate in the root window
433 * y_root - the Y corrdinate in the root window
434 * tmp_win - the current twm window
435 *
436 ***********************************************************************
437 */
438
440{
441 int action;
442 Cursor cursor = 0;
443
444 action = 0;
445
446 x_root -= clampDX;
447 y_root -= clampDY;
448
449 if(clampTop) {
450 int delta = y_root - dragy;
451 if((int)(dragHeight - delta) < MINHEIGHT) {
453 clampTop = 0;
454 }
455 dragy += delta;
456 dragHeight -= delta;
457 action = 1;
458 cursor = TopCursor;
459 }
460 else if(y_root <= dragy) {
461 dragy = y_root;
463 y_root;
464 clampBottom = 0;
465 clampTop = 1;
466 clampDY = 0;
467 action = 1;
468 cursor = TopCursor;
469 }
470 if(clampLeft) {
471 int delta = x_root - dragx;
472 if((int)(dragWidth - delta) < MINWIDTH) {
474 clampLeft = 0;
475 }
476 dragx += delta;
477 dragWidth -= delta;
478 action = 1;
479 cursor = clampTop ? TopLeftCursor : LeftCursor;
480 }
481 else if(x_root <= dragx) {
482 dragx = x_root;
484 x_root;
485 clampRight = 0;
486 clampLeft = 1;
487 clampDX = 0;
488 action = 1;
489 cursor = clampTop ? TopLeftCursor : LeftCursor;
490 }
491 if(clampBottom) {
492 int delta = y_root - dragy - dragHeight;
493 if((int)(dragHeight + delta) < MINHEIGHT) {
495 clampBottom = 0;
496 }
497 dragHeight += delta;
498 action = 1;
500 }
501 else if(y_root >= dragy + dragHeight - 1) {
502 dragy = origy;
503 dragHeight = 1 + y_root - dragy;
504 clampTop = 0;
505 clampBottom = 1;
506 clampDY = 0;
507 action = 1;
509 }
510 if(clampRight) {
511 int delta = x_root - dragx - dragWidth;
512 if((int)(dragWidth + delta) < MINWIDTH) {
514 clampRight = 0;
515 }
516 dragWidth += delta;
517 action = 1;
519 cursor = clampTop ? TopRightCursor : cursor;
520 }
521 else if(x_root >= dragx + dragWidth - 1) {
522 dragx = origx;
523 dragWidth = 1 + x_root - origx;
524 clampLeft = 0;
525 clampRight = 1;
526 clampDX = 0;
527 action = 1;
529 cursor = clampTop ? TopRightCursor : cursor;
530 }
531
532 if(action) {
534 if(clampLeft) {
536 }
537 if(clampTop) {
539 }
540 if(Scr->OpaqueResize && ! resizeWhenAdd) {
541 SetupWindow(tmp_win, dragx - tmp_win->frame_bw, dragy - tmp_win->frame_bw,
542 dragWidth, dragHeight, -1);
543 }
544 else {
545 MoveOutline(Scr->Root,
546 dragx - tmp_win->frame_bw,
547 dragy - tmp_win->frame_bw,
548 dragWidth + 2 * tmp_win->frame_bw,
549 dragHeight + 2 * tmp_win->frame_bw,
550 tmp_win->frame_bw, tmp_win->title_height + tmp_win->frame_bw3D);
551 }
552 if(Scr->BorderCursors && (cursor != tmp_win->curcurs)) {
553 tmp_win->curcurs = cursor;
555 }
556 }
557
559}
560
561/***********************************************************************
562 *
563 * Procedure:
564 * DisplaySize - display the size in the dimensions window
565 *
566 * Inputs:
567 * tmp_win - the current twm window
568 * width - the width of the rubber band
569 * height - the height of the rubber band
570 *
571 ***********************************************************************
572 */
573
574static void DisplaySize(TwmWindow *tmp_win, int width, int height)
575{
576 char str[100];
577 int dwidth;
578 int dheight;
579
580 if(last_width == width && last_height == height) {
581 return;
582 }
583
584 last_width = width;
585 last_height = height;
586
587 dheight = height - tmp_win->title_height - 2 * tmp_win->frame_bw3D;
588 dwidth = width - 2 * tmp_win->frame_bw3D;
589
590 /*
591 * ICCCM says that PMinSize is the default is no PBaseSize is given,
592 * and vice-versa.
593 */
594 if(tmp_win->hints.flags & (PMinSize | PBaseSize)
595 && tmp_win->hints.flags & PResizeInc) {
596 if(tmp_win->hints.flags & PBaseSize) {
597 dwidth -= tmp_win->hints.base_width;
598 dheight -= tmp_win->hints.base_height;
599 }
600 else {
601 dwidth -= tmp_win->hints.min_width;
602 dheight -= tmp_win->hints.min_height;
603 }
604 }
605
606 if(tmp_win->hints.flags & PResizeInc) {
607 dwidth /= tmp_win->hints.width_inc;
608 dheight /= tmp_win->hints.height_inc;
609 }
610
611 sprintf(str, " %4d x %-4d ", dwidth, dheight);
612 XRaiseWindow(dpy, Scr->SizeWindow);
613
614 Draw3DBorder(Scr->SizeWindow, 0, 0,
615 Scr->SizeStringOffset + Scr->SizeStringWidth + SIZE_HINDENT,
616 Scr->SizeFont.height + SIZE_VINDENT * 2,
617 2, Scr->DefaultC, off, false, false);
618
619 FB(Scr->DefaultC.fore, Scr->DefaultC.back);
620 XmbDrawImageString(dpy, Scr->SizeWindow, Scr->SizeFont.font_set,
621 Scr->NormalGC, Scr->SizeStringOffset,
622 Scr->SizeFont.ascent + SIZE_VINDENT, str, 13);
623}
624
625/***********************************************************************
626 *
627 * Procedure:
628 * EndResize - finish the resize operation
629 *
630 ***********************************************************************
631 */
632
633void EndResize(void)
634{
636
637#ifdef DEBUG
638 fprintf(stderr, "EndResize\n");
639#endif
640
641 MoveOutline(Scr->Root, 0, 0, 0, 0, 0, 0);
642 XUnmapWindow(dpy, Scr->SizeWindow);
643
645 if(!tmp_win) {
646 return;
647 }
648
650
651 if(dragWidth != tmp_win->frame_width ||
652 dragHeight != tmp_win->frame_height) {
654 }
655
656 SetupWindow(tmp_win, dragx - tmp_win->frame_bw, dragy - tmp_win->frame_bw,
657 dragWidth, dragHeight, -1);
658
659 if(tmp_win->isiconmgr) {
660 int ncols = tmp_win->iconmgrp->cur_columns;
661 if(ncols == 0) {
662 ncols = 1;
663 }
664
665 tmp_win->iconmgrp->width = (int)(((dragWidth - 2 * tmp_win->frame_bw3D) *
666 (long) tmp_win->iconmgrp->columns)
667 / ncols);
668 PackIconManager(tmp_win->iconmgrp);
669 }
670
671 if(!Scr->NoRaiseResize) {
674 }
675
677
679}
680
682{
683 MoveOutline(Scr->Root, 0, 0, 0, 0, 0, 0);
684 XUnmapWindow(dpy, Scr->SizeWindow);
686 AddingX = dragx - tmp_win->frame_bw;
687 AddingY = dragy - tmp_win->frame_bw;
691}
692
693
694/***********************************************************************
695 *
696 * Procedure:
697 * AddEndResize - finish the resize operation for AddWindo<w
698 *
699 ***********************************************************************
700 */
701
703{
704
705#ifdef DEBUG
706 fprintf(stderr, "AddEndResize\n");
707#endif
708
710 AddingX = dragx;
711 AddingY = dragy;
712 AddingW = dragWidth + (2 * tmp_win->frame_bw);
713 AddingH = dragHeight + (2 * tmp_win->frame_bw);
714}
715
716/***********************************************************************
717 *
718 * Procedure:
719 * ConstrainSize - adjust the given width and height to account for the
720 * constraints imposed by size hints
721 *
722 * The general algorithm, especially the aspect ratio stuff, is
723 * borrowed from uwm's CheckConsistency routine.
724 *
725 ***********************************************************************/
726
728 unsigned int *widthp, unsigned int *heightp)
729{
730#define makemult(a,b) ((b==1) ? (a) : (((int)((a)/(b))) * (b)) )
731
734 int dwidth = *widthp, dheight = *heightp;
735
736
737 dwidth -= 2 * tmp_win->frame_bw3D;
738 dheight -= (tmp_win->title_height + 2 * tmp_win->frame_bw3D);
739
740 if(tmp_win->hints.flags & PMinSize) {
741 minWidth = tmp_win->hints.min_width;
742 minHeight = tmp_win->hints.min_height;
743 }
744 else if(tmp_win->hints.flags & PBaseSize) {
745 minWidth = tmp_win->hints.base_width;
746 minHeight = tmp_win->hints.base_height;
747 }
748 else {
749 minWidth = minHeight = 1;
750 }
751
752 if(tmp_win->hints.flags & PBaseSize) {
753 baseWidth = tmp_win->hints.base_width;
754 baseHeight = tmp_win->hints.base_height;
755 }
756 else if(tmp_win->hints.flags & PMinSize) {
757 baseWidth = tmp_win->hints.min_width;
758 baseHeight = tmp_win->hints.min_height;
759 }
760 else {
761 baseWidth = baseHeight = 0;
762 }
763
764
765 if(tmp_win->hints.flags & PMaxSize) {
766 maxWidth = min(Scr->MaxWindowWidth, tmp_win->hints.max_width);
767 maxHeight = min(Scr->MaxWindowHeight, tmp_win->hints.max_height);
768 }
769 else {
770 maxWidth = Scr->MaxWindowWidth;
771 maxHeight = Scr->MaxWindowHeight;
772 }
773
774 if(tmp_win->hints.flags & PResizeInc) {
775 xinc = tmp_win->hints.width_inc;
776 yinc = tmp_win->hints.height_inc;
777 if(xinc == 0) {
778 xinc = 1;
779 }
780 if(yinc == 0) {
781 yinc = 1;
782 }
783 }
784 else {
785 xinc = yinc = 1;
786 }
787
788 /*
789 * First, clamp to min and max values
790 */
791 if(dwidth < minWidth) {
793 }
794 if(dheight < minHeight) {
796 }
797
798 if(dwidth > maxWidth) {
800 }
801 if(dheight > maxHeight) {
803 }
804
805
806 /*
807 * Second, fit to base + N * inc
808 */
811
812
813 /*
814 * Third, adjust for aspect ratio
815 */
816 /*
817 * The math looks like this:
818 *
819 * minAspectX dwidth maxAspectX
820 * ---------- <= ------- <= ----------
821 * minAspectY dheight maxAspectY
822 *
823 * If that is multiplied out, then the width and height are
824 * invalid in the following situations:
825 *
826 * minAspectX * dheight > minAspectY * dwidth
827 * maxAspectX * dheight < maxAspectY * dwidth
828 *
829 */
830
831 if(tmp_win->hints.flags & PAspect) {
832 int minAspectX = tmp_win->hints.min_aspect.x;
833 int minAspectY = tmp_win->hints.min_aspect.y;
834 int maxAspectX = tmp_win->hints.max_aspect.x;
835 int maxAspectY = tmp_win->hints.max_aspect.y;
836
840 xinc);
841 if(dwidth + delta <= maxWidth) {
842 dwidth += delta;
843 }
844 else {
846 yinc);
847 if(dheight - delta >= minHeight) {
848 dheight -= delta;
849 }
850 }
851 }
852
855 yinc);
856 if(dheight + delta <= maxHeight) {
857 dheight += delta;
858 }
859 else {
861 xinc);
862 if(dwidth - delta >= minWidth) {
863 dwidth -= delta;
864 }
865 }
866 }
867 }
868 }
869
870
871 /*
872 * Fourth, account for border width and title height
873 */
874 *widthp = dwidth + 2 * tmp_win->frame_bw3D;
875 *heightp = dheight + tmp_win->title_height + 2 * tmp_win->frame_bw3D;
876}
877
878
879
880
881/**********************************************************************
882 * Rutgers mod #1 - rocky.
883 * Procedure:
884 * fullzoom - zooms window to full height of screen or
885 * to full height and width of screen. (Toggles
886 * so that it can undo the zoom - even when switching
887 * between fullzoom and vertical zoom.)
888 *
889 * Inputs:
890 * tmp_win - the TwmWindow pointer
891 *
892 *
893 **********************************************************************
894 */
895
896void fullzoom(TwmWindow *tmp_win, int func)
897{
899 unsigned int junkbw, junkDepth;
900 int tmpX, tmpY, tmpW, tmpH;
901
902 /*
903 * All our callers [need to] do this, so moving it here saves a few
904 * lines in some places around the calling, and when redundant it
905 * just wastes a comparison, so it's cheap.
906 */
907 if(tmp_win->squeezed) {
908 XBell(dpy, 0);
909 return;
910 }
911
912
914 &dragx, &dragy, (unsigned int *)&dragWidth, (unsigned int *)&dragHeight,
915 &junkbw,
916 &junkDepth);
917
918 /*
919 * Guard; if it was already not zoomed, and we're asking to unzoom
920 * it, just finish right away. This saves us work, but also avoids
921 * really bad side effects in some cases. e.g., if we try to
922 * ZOOM_NONE a window that's never been ZOOM'd, tmp_win->save_* will
923 * all be 0, so we'd wind up resizing it to a point. It's possible
924 * for that to happen via e.g. an EWMH message removing a _FULLSCREEN
925 * or similar attribute; that can then call into us telling us not to
926 * zoom, on a window that's never been zoomed.
927 *
928 * This wouldn't protect us if somehow it was zoomed but hadn't set
929 * that data, but I don't see how that can happen. Worry about that
930 * when it does.
931 */
932 if(func == ZOOM_NONE && tmp_win->zoomed == ZOOM_NONE) {
933 return;
934 }
935
936 if(tmp_win->zoomed == func) {
937 /* It was already zoomed this way, unzoom it */
938 dragHeight = tmp_win->save_frame_height;
939 dragWidth = tmp_win->save_frame_width;
940 dragx = tmp_win->save_frame_x;
941 dragy = tmp_win->save_frame_y;
942
944
945 /* XXX _should_ it be falling through here? */
946 }
947 else {
949 RArea area, finalArea = RAreaInvalid();
951
952#ifdef WINBOX
953 if(tmp_win->winbox) {
955 if(XGetWindowAttributes(dpy, tmp_win->winbox->window, &winattrs)) {
957 RAreaListNew(1,
959 winattrs.y,
960 winattrs.width,
961 winattrs.height),
962 NULL));
963 }
964 }
965#endif
966 if(borderedLayout == NULL) {
967 borderedLayout = Scr->BorderedLayout;
968 }
969
970 if(tmp_win->zoomed == ZOOM_NONE) {
971 tmp_win->save_frame_x = dragx;
972 tmp_win->save_frame_y = dragy;
973 tmp_win->save_frame_width = dragWidth;
974 tmp_win->save_frame_height = dragHeight;
975 }
976 tmp_win->zoomed = func;
977
978 frame_bw_times_2 = 2 * tmp_win->frame_bw;
979
981
982 switch(func) {
983 case ZOOM_NONE:
984 break;
985 case F_XZOOM:
987 /* fall through */
988 case F_ZOOM:
989 if(!RAreaIsValid(&finalArea)) {
991 }
992 dragy = finalArea.y;
994 break;
995 case F_XHORIZOOM:
997 /* fall through */
998 case F_HORIZOOM:
999 if(!RAreaIsValid(&finalArea)) {
1001 }
1002 dragx = finalArea.x;
1004 break;
1005 case F_XFULLZOOM:
1007 /* fall through */
1008 case F_FULLZOOM:
1009 if(!RAreaIsValid(&finalArea)) {
1011 }
1012 dragx = finalArea.x;
1013 dragy = finalArea.y;
1016 break;
1017 case F_XLEFTZOOM:
1019 dragWidth += area.x - dragx;
1020 // TODO make it visible if hidden
1021 break;
1022 case F_LEFTZOOM:
1024 dragWidth += area.x - dragx;
1025 // TODO make it visible if hidden
1026 break;
1027 case F_XRIGHTZOOM: {
1029 dragWidth = limit - area.x + 1 - frame_bw_times_2;
1030 // TODO make it visible if hidden
1031 }
1032 break;
1033 case F_RIGHTZOOM: {
1035 dragWidth = limit - area.x + 1 - frame_bw_times_2;
1036 // TODO make it visible if hidden
1037 }
1038 break;
1039 case F_XTOPZOOM:
1041 dragHeight += area.y - dragy;
1042 // TODO make it visible if hidden
1043 break;
1044 case F_TOPZOOM:
1046 dragHeight += area.y - dragy;
1047 // TODO make it visible if hidden
1048 break;
1049 case F_XBOTTOMZOOM: {
1051 dragHeight = limit - area.y + 1 - frame_bw_times_2;
1052 // TODO make it visible if hidden
1053 }
1054 break;
1055 case F_BOTTOMZOOM: {
1057 dragHeight = limit - area.y + 1 - frame_bw_times_2;
1058 // TODO make it visible if hidden
1059 }
1060 break;
1061 case F_FULLSCREENZOOM:
1062 case F_XFULLSCREENZOOM: {
1063 int bw3D = tmp_win->frame_bw3D;
1064 int bw3D_times_2 = 2 * bw3D;
1065 int bw = tmp_win->frame_bw + bw3D;
1066
1068 ? RLayoutFull(borderedLayout, &area)
1069 : RLayoutFull1(borderedLayout, &area);
1070 dragx = finalArea.x - bw;
1071 dragy = finalArea.y - tmp_win->title_height - bw;
1073 dragHeight = finalArea.height + tmp_win->title_height + bw3D_times_2;
1074
1075 /* and should ignore aspect ratio and size increments... */
1076#ifdef EWMH
1077 /* x-ref HandleFocusIn() comments for why we need this */
1080 /* the OtpRaise below is effectively already done here... */
1081#endif
1082 }
1083 }
1084
1085 /* Temporary built layout? */
1086 if(borderedLayout != Scr->BorderedLayout) {
1088 }
1089 }
1090
1091 if(!Scr->NoRaiseResize && func != F_FULLSCREENZOOM) {
1093 }
1094
1095 if(func != F_FULLSCREENZOOM) {
1097 }
1098#ifdef BETTERZOOM
1099 if(func == F_ZOOM) {
1100 if(dragy + dragHeight < tmp_win->save_frame_y + tmp_win->save_frame_height) {
1101 dragy = tmp_win->save_frame_y + tmp_win->save_frame_height - dragHeight;
1102 }
1103 }
1104#endif
1106 /* I don't understand the reason of this. Claude.
1107 XUngrabPointer (dpy, CurrentTime);
1108 */
1110
1112 tmp_win->w,
1113 &junkRoot, &junkRoot,
1114 &tmpX, &tmpY, &tmpW, &tmpH, &junkDepth);
1115 if(tmp_win->frame_x > tmpX ||
1116 tmp_win->frame_x + tmp_win->frame_width < tmpX ||
1117 tmp_win->frame_y > tmpY ||
1118 tmp_win->frame_y + tmp_win->frame_height < tmpY) {
1119 XWarpPointer(dpy, Scr->Root, tmp_win->w, 0, 0, 0, 0, 0, 0);
1120 }
1121
1122#ifdef EWMH
1123 /*
1124 * Reset _NET_WM_STATE prop on the window. It sets whichever state
1125 * applies, not always the _MAXIMIZED_VERT we specify here.
1126 */
1128#endif
1129}
1130
1131/*
1132 * Forget about a window being zoomed.
1133 * This also needs to undo the special effects of F_FULLSCREENZOOM.
1134 */
1136{
1137 if(tmp_win->zoomed != ZOOM_NONE) {
1138#ifdef EWMH
1139 if(tmp_win->zoomed == F_FULLSCREENZOOM) {
1142 }
1143#endif
1144
1145 tmp_win->zoomed = ZOOM_NONE;
1146 }
1147}
1148
1150{
1151 if(!tmp_win) {
1152 return;
1153 }
1154 tmp_win->savegeometry.x = tmp_win->frame_x;
1155 tmp_win->savegeometry.y = tmp_win->frame_y;
1156 tmp_win->savegeometry.width = tmp_win->frame_width;
1157 tmp_win->savegeometry.height = tmp_win->frame_height;
1158}
1159
1161{
1162 int x, y;
1163 unsigned int w, h;
1164
1165 if(!tmp_win) {
1166 return;
1167 }
1168 if(tmp_win->savegeometry.width == (unsigned int) - 1) {
1169 return;
1170 }
1171 x = tmp_win->savegeometry.x;
1172 y = tmp_win->savegeometry.y;
1173 w = tmp_win->savegeometry.width;
1174 h = tmp_win->savegeometry.height;
1175 SetupWindow(tmp_win, x, y, w, h, -1);
1176}
1177
1178
1180{
1181 int change = 0, size = 0;
1182 char *endptr;
1183 int rx, ry, wx, wy, mr;
1184 Window rr, cr;
1185
1186 if(Isdigit(in_string[0])) {
1187 /* Handle the case f.changesize "640x480" */
1188 wx = strtol(in_string, &endptr, 10);
1189 if(*endptr++ != 'x') {
1191 "%s: Bad argument to f.changesize: \"%s\" (pattern \"640x480\")\n",
1193 return;
1194 }
1195 wy = strtol(endptr, &endptr, 10);
1196
1197 if(wy < tmp_win->title_height + 1) {
1198 wy = tmp_win->title_height + 1;
1199 }
1200
1201 SetupWindow(tmp_win, tmp_win->frame_x, tmp_win->frame_y,
1202 wx, wy + tmp_win->title_height, -1);
1203 }
1204 else {
1205 /* Handle the cases like f.changesize "right +10" */
1206 int cmdlen = 0;
1207
1208 while(in_string[cmdlen] != ' ' && in_string[cmdlen] != '\0') {
1209 cmdlen++;
1210 }
1211
1212 if(in_string[cmdlen] != ' ') {
1214 "%s: Bad argument to f.changesize: \"%s\" (sizechange missing)\n",
1216 return;
1217 }
1218
1219 change = strtol(in_string + cmdlen + 1, &endptr, 10);
1220 if(*endptr != 0) {
1222 "%s: Bad argument to f.changesize: \"%s\" (sizechange not a number)\n",
1224 return;
1225 }
1226
1227 if(strncmp("bottom", in_string, cmdlen) == 0) {
1228 size = tmp_win->frame_height + change;
1229
1230 if(size < (tmp_win->title_height + 1)) {
1231 size = tmp_win->title_height + 1;
1232 }
1233
1234 SetupWindow(tmp_win, tmp_win->frame_x, tmp_win->frame_y,
1235 tmp_win->frame_width, size,
1236 -1);
1237
1238 XQueryPointer(dpy, tmp_win->w, &rr, &cr, &rx, &ry, &wx, &wy,
1239 (unsigned int *)&mr);
1240
1241 if((wy + tmp_win->title_height) > size) {
1242 XWarpPointer(dpy, None, tmp_win->w, 0, 0, 0, 0, 0, 0);
1243 }
1244 }
1245 else if(strncmp("top", in_string, cmdlen) == 0) {
1246 size = tmp_win->frame_height + change;
1247
1248 if(size < (tmp_win->title_height + 1)) {
1249 size = tmp_win->title_height + 1;
1250 }
1251
1252 SetupWindow(tmp_win, tmp_win->frame_x, (tmp_win->frame_y - change),
1253 tmp_win->frame_width, size,
1254 -1);
1255
1256 XQueryPointer(dpy, tmp_win->w, &rr, &cr, &rx, &ry, &wx, &wy,
1257 (unsigned int *)&mr);
1258
1259 if((wy + tmp_win->title_height) > size) {
1260 XWarpPointer(dpy, None, tmp_win->w, 0, 0, 0, 0, 0, 0);
1261 }
1262
1263
1264 }
1265 else if(strncmp("left", in_string, cmdlen) == 0) {
1266 size = tmp_win->frame_width + change;
1267
1268 if(size < 1) {
1269 size = 1;
1270 }
1271
1272 SetupWindow(tmp_win, (tmp_win->frame_x - change), tmp_win->frame_y,
1273 size, tmp_win->frame_height,
1274 -1);
1275
1276 XQueryPointer(dpy, tmp_win->w, &rr, &cr, &rx, &ry, &wx, &wy,
1277 (unsigned int *)&mr);
1278
1279 if(wx > size) {
1280 XWarpPointer(dpy, None, tmp_win->w, 0, 0, 0, 0, 0, 0);
1281 }
1282
1283
1284 }
1285 else if(strncmp("right", in_string, cmdlen) == 0) {
1286 size = tmp_win->frame_width + change;
1287
1288 if(size < 1) {
1289 size = 1;
1290 }
1291
1292 SetupWindow(tmp_win, tmp_win->frame_x, tmp_win->frame_y,
1293 size, tmp_win->frame_height,
1294 -1);
1295
1296 XQueryPointer(dpy, tmp_win->w, &rr, &cr, &rx, &ry, &wx, &wy,
1297 (unsigned int *)&mr);
1298
1299 if(wx > size) {
1300 XWarpPointer(dpy, None, tmp_win->w, 0, 0, 0, 0, 0, 0);
1301 }
1302
1303 }
1304 else {
1305 /* error */
1306 fprintf(stderr, "%s: Bad argument to f.changesize: \"%s\"\n (unknown border)",
1308 return;
1309 }
1310 }
1311}
1312
1313
1314/***********************************************************************
1315 *
1316 * Procedure:
1317 * resizeFromCenter -
1318 *
1319 ***********************************************************************
1320 */
1321void
1323{
1324 int lastx, lasty, bw2;
1325
1326 bw2 = tmp_win->frame_bw * 2;
1327 AddingW = tmp_win->attr.width + bw2 + 2 * tmp_win->frame_bw3D;
1328 AddingH = tmp_win->attr.height + tmp_win->title_height + bw2 + 2 *
1329 tmp_win->frame_bw3D;
1330
1333 &JunkBW, &JunkDepth);
1334
1335 XWarpPointer(dpy, None, w,
1336 0, 0, 0, 0, DragWidth / 2, DragHeight / 2);
1337 XQueryPointer(dpy, Scr->Root, &JunkRoot,
1338 &JunkChild, &JunkX, &JunkY,
1339 &AddingX, &AddingY, &JunkMask);
1340
1341 lastx = -10000;
1342 lasty = -10000;
1343
1345 while(1) {
1348
1349 if(Event.type == MotionNotify) {
1350 /* discard any extra motion events before a release */
1351 while(XCheckMaskEvent(dpy,
1353 if(Event.type == ButtonPress) {
1354 break;
1355 }
1356 }
1357
1358 if(Event.type == ButtonPress) {
1360 // Next line should be unneeded, done by MenuEndResize() ?
1362 break;
1363 }
1364
1365 if(Event.type != MotionNotify) {
1367 if(Cancel) {
1368 // ...
1370 return;
1371 }
1372 continue;
1373 }
1374
1375 /*
1376 * XXX - if we are going to do a loop, we ought to consider
1377 * using multiple GXxor lines so that we don't need to
1378 * grab the server.
1379 */
1382
1383 if(lastx != AddingX || lasty != AddingY) {
1385
1386 lastx = AddingX;
1387 lasty = AddingY;
1388 }
1389
1390 }
1391}
bool resizeWhenAdd
Definition add_window.c:90
static int PlaceX
Definition add_window.c:82
unsigned int AddingH
Definition add_window.c:80
int AddingY
Definition add_window.c:78
unsigned int AddingW
Definition add_window.c:79
int AddingX
Definition add_window.c:77
void UninstallRootColormap(void)
Definition colormaps.c:213
void InstallRootColormap(void)
Definition colormaps.c:173
int JunkY
Definition ctwm.h:358
char * ProgramName
Definition ctwm_main.c:146
Cursor RightCursor
Definition ctwm.h:354
unsigned int JunkBW
Definition ctwm.h:359
Window JunkRoot
Definition ctwm_main.c:142
int JunkX
Definition ctwm_main.c:143
Cursor BottomCursor
Definition ctwm.h:354
Display * dpy
Definition ctwm_main.c:84
Cursor LeftCursor
Definition ctwm.h:353
unsigned int JunkMask
Definition ctwm.h:359
Cursor BottomRightCursor
Definition ctwm.h:354
Cursor TopRightCursor
Definition ctwm.h:354
#define FB(fix_fore, fix_back)
Definition ctwm.h:119
Cursor TopCursor
Definition ctwm_main.c:112
Cursor BottomLeftCursor
Definition ctwm.h:353
Window JunkChild
Definition ctwm.h:357
Window ResizeWindow
Definition ctwm_main.c:85
#define ZOOM_NONE
Definition ctwm.h:111
Cursor TopLeftCursor
Definition ctwm.h:353
unsigned int JunkDepth
Definition ctwm.h:359
#define Scr
void Draw3DBorder(Window w, int x, int y, int width, int height, int bw, ColorPair cp, ButtonState state, bool fill, bool forcebw)
Definition drawing.c:34
@ off
Definition drawing.h:8
bool Cancel
Definition event_core.c:94
int origDragX
Definition event_core.c:69
unsigned int DragWidth
Definition event_core.c:73
unsigned int DragHeight
Definition event_core.c:74
int origDragY
Definition event_core.c:70
bool DispatchEvent2(void)
Definition event_core.c:343
XEvent Event
Definition event_core.c:66
void EwmhSet_NET_WM_STATE(TwmWindow *twm_win, int changes)
Definition ewmh.c:2137
#define EWMH_STATE_MAXIMIZED_VERT
Definition ewmh.h:37
void PackIconManager(IconMgr *ip)
Definition iconmgr.c:1143
int y
Definition menus.c:70
int x
Definition menus.c:69
void OtpSetAflag(TwmWindow *twm_win, unsigned flag)
Definition otp.c:1541
void OtpRestackWindow(TwmWindow *twm_win)
Definition otp.c:1648
void OtpClearAflag(TwmWindow *twm_win, unsigned flag)
Definition otp.c:1559
void OtpRaise(TwmWindow *twm_win, WinType wintype)
Definition otp.c:763
@ WinWin
Definition otp.h:14
RArea RAreaInvalid(void)
Return a facially-invalid RArea.
Definition r_area.c:49
RArea RAreaNew(int x, int y, int width, int height)
Construct an RArea from given components.
Definition r_area.c:19
bool RAreaIsValid(const RArea *self)
Is an RArea facially valid?
Definition r_area.c:63
RAreaList * RAreaListNew(int cap,...)
Create an RAreaList from a set of RArea's.
Definition r_area_list.c:40
void RLayoutFree(RLayout *self)
Clean up and free an RLayout.
Definition r_layout.c:112
RArea RLayoutFullVert1(const RLayout *self, const RArea *area)
Figure the best way to stretch an area vertically without crossing monitors.
Definition r_layout.c:942
int RLayoutFindBottomEdge(const RLayout *self, const RArea *area)
Find the bottom of the top stripe of self that area fits into.
Definition r_layout.c:424
int RLayoutFindRightEdge(const RLayout *self, const RArea *area)
Find the right edge of the left-most stripe of self that area fits into.
Definition r_layout.c:503
RArea RLayoutFullHoriz1(const RLayout *self, const RArea *area)
Figure the best way to stretch an area horizontally without crossing monitors.
Definition r_layout.c:909
int RLayoutFindMonitorTopEdge(const RLayout *self, const RArea *area)
Find the top edge of the bottom-most monitor that contains the most of a given RArea.
Definition r_layout.c:684
int RLayoutFindMonitorRightEdge(const RLayout *self, const RArea *area)
Find the right edge of the left-most monitor that contains the most of a given RArea.
Definition r_layout.c:764
int RLayoutFindLeftEdge(const RLayout *self, const RArea *area)
Find the left edge of the right-most stripe of self that area fits into.
Definition r_layout.c:489
int RLayoutFindMonitorBottomEdge(const RLayout *self, const RArea *area)
Find the bottom edge of the top-most monitor that contains the most of a given RArea.
Definition r_layout.c:645
RLayout * RLayoutNew(RAreaList *monitors)
Create an RLayout for a given set of monitors.
Definition r_layout.c:55
RArea RLayoutFull1(const RLayout *self, const RArea *area)
Figure the best way to resize an area to fill one monitor.
Definition r_layout.c:973
int RLayoutFindTopEdge(const RLayout *self, const RArea *area)
Find the top of the bottom stripe of self that area fits into.
Definition r_layout.c:438
RArea RLayoutFull(const RLayout *self, const RArea *area)
Figure the best way to stretch an area across the largest horizontal and vertical space it can from i...
Definition r_layout.c:883
RArea RLayoutFullHoriz(const RLayout *self, const RArea *area)
Figure the best way to stretch an area across the full horizontal width of an RLayout.
Definition r_layout.c:789
RArea RLayoutFullVert(const RLayout *self, const RArea *area)
Figure the best way to stretch an area across the full vertical height of an RLayout.
Definition r_layout.c:860
int RLayoutFindMonitorLeftEdge(const RLayout *self, const RArea *area)
Find the left edge of the right-most monitor that contains the most of a given RArea.
Definition r_layout.c:724
#define SIZE_VINDENT
Internal padding in the size window.
Definition screen.h:59
#define SIZE_HINDENT
Internal padding in the size window.
Definition screen.h:58
A particular extent of space.
Definition r_structs.h:16
int y
Y position.
Definition r_structs.h:18
int x
X position.
Definition r_structs.h:17
The layout of our display.
Definition r_structs.h:45
Info and control for every X Window we take over.
#define Isdigit(c)
Definition util.h:52
static int min(int a, int b)
Definition util.h:30
void SetupWindow(TwmWindow *tmp_win, int x, int y, int w, int h, int bw)
void MoveOutline(Window root, int x, int y, int width, int height, int bw, int th)
Definition win_ops.c:317
static int last_width
Definition win_resize.c:69
static void DisplaySize(TwmWindow *tmp_win, int width, int height)
Definition win_resize.c:574
void ChangeSize(char *in_string, TwmWindow *tmp_win)
void StartResize(XEvent *evp, TwmWindow *tmp_win, bool fromtitlebar, bool from3dborder)
Definition win_resize.c:183
static int origx
Definition win_resize.c:57
void MenuStartResize(TwmWindow *tmp_win, int x, int y, int w, int h)
Definition win_resize.c:241
static int origy
Definition win_resize.c:58
void ConstrainSize(TwmWindow *tmp_win, unsigned int *widthp, unsigned int *heightp)
Definition win_resize.c:727
static int clampLeft
Definition win_resize.c:64
void unzoom(TwmWindow *tmp_win)
void restoregeometry(TwmWindow *tmp_win)
static int last_height
Definition win_resize.c:70
static void do_auto_clamp(TwmWindow *tmp_win, XEvent *evp)
Definition win_resize.c:76
static int clampDX
Definition win_resize.c:66
static int dragy
Definition win_resize.c:53
static int clampRight
Definition win_resize.c:65
static unsigned int dragWidth
Definition win_resize.c:54
static int dragx
Definition win_resize.c:52
#define MINWIDTH
Definition win_resize.c:50
void resizeFromCenter(Window w, TwmWindow *tmp_win)
void OpaqueResizeSize(TwmWindow *tmp_win)
Definition win_resize.c:138
void MenuEndResize(TwmWindow *tmp_win)
Definition win_resize.c:681
static unsigned int dragHeight
Definition win_resize.c:55
static int clampBottom
Definition win_resize.c:63
void AddEndResize(TwmWindow *tmp_win)
Definition win_resize.c:702
#define MINHEIGHT
Definition win_resize.c:49
void EndResize(void)
Definition win_resize.c:633
static int clampDY
Definition win_resize.c:67
static int origHeight
Definition win_resize.c:60
void AddStartResize(TwmWindow *tmp_win, int x, int y, int w, int h)
Definition win_resize.c:284
static int origWidth
Definition win_resize.c:59
#define makemult(a, b)
void DoResize(int x_root, int y_root, TwmWindow *tmp_win)
Definition win_resize.c:439
static unsigned int resizeGrabMask
Definition win_resize.c:72
void MenuDoResize(int x_root, int y_root, TwmWindow *tmp_win)
Definition win_resize.c:305
static int clampTop
Definition win_resize.c:62
void fullzoom(TwmWindow *tmp_win, int func)
Definition win_resize.c:896
void savegeometry(TwmWindow *tmp_win)
void MoveResizeSizeWindow(int x, int y, unsigned int width, unsigned int height)
Definition win_utils.c:495
TwmWindow * GetTwmWindow(Window w)
Definition win_utils.c:190
void WMapRaise(TwmWindow *win)