CTWM
Loading...
Searching...
No Matches
/usr/src/RPM/BUILD/ctwm-4.1.0/functions_win.c
Go to the documentation of this file.
1/*
2 * Functions related to manipulating windows.
3 *
4 * This doesn't include stuff related to changing their occupation (in
5 * functions_workspaces.c), or moving/resizing (in
6 * functions_win_moveresize.c), or a few other cases of things
7 * peripherally involving windows.
8 */
9
10#include "ctwm.h"
11
12#include <stdlib.h>
13
14#include "colormaps.h"
15#include "ctwm_atoms.h"
16#include "events.h"
17#include "event_handlers.h"
18#include "functions.h"
19#include "functions_defs.h"
20#include "functions_internal.h"
21#include "icons.h"
22#include "occupation.h"
23#include "otp.h"
24#include "parse.h"
25#include "screen.h"
26#include "win_decorations.h"
27#include "win_iconify.h"
28#include "win_ops.h"
29#include "win_utils.h"
30#include "workspace_manager.h"
31
32
33
34/*
35 *************************************************************
36 *
37 * Moving windows on/off the AutoRaise/AutoLower lists
38 *
39 *************************************************************
40 */
42{
43 tmp_win->auto_raise = !tmp_win->auto_raise;
44 if(tmp_win->auto_raise) {
45 ++(Scr->NumAutoRaises);
46 }
47 else {
48 --(Scr->NumAutoRaises);
49 }
50}
51
53{
54 tmp_win->auto_lower = !tmp_win->auto_lower;
55 if(tmp_win->auto_lower) {
56 ++(Scr->NumAutoLowers);
57 }
58 else {
59 --(Scr->NumAutoLowers);
60 }
61}
62
63
64
65
66/*
67 *************************************************************
68 *
69 * Raising and lowering
70 *
71 *************************************************************
72 */
73
74/* Separate function because raise and raiseorsqueeze can both need it */
75static void
77{
78 /* check to make sure raise is not from the WindowFunction */
79 if(tmp_win->icon && (w == tmp_win->icon->w) && Context != C_ROOT) {
81 }
82 else {
85 }
86}
87
92
94{
95 /* FIXME using the same double-click ConstrainedMoveTime here */
96 if((eventp->xbutton.time - last_time) < ConstrainedMoveTime) {
98 return;
99 }
100 last_time = eventp->xbutton.time;
101
102 /* intentional fall-thru into F_RAISE */
104}
105
107{
108 if(tmp_win->icon && (w == tmp_win->icon->w)) {
110 }
111 else {
114 }
115}
116
118{
119 if(!WindowMoved) {
120 if(tmp_win->icon && w == tmp_win->icon->w) {
122 }
123 else {
126 }
127 }
128}
129
130
131/*
132 * Smaller raise/lower
133 */
135{
136 /* check to make sure raise is not from the WindowFunction */
137 if(tmp_win->icon && (w == tmp_win->icon->w) && Context != C_ROOT) {
139 }
140 else {
143 }
144}
145
147{
148 /* check to make sure raise is not from the WindowFunction */
149 if(tmp_win->icon && (w == tmp_win->icon->w) && Context != C_ROOT) {
151 }
152 else {
155 }
156}
157
158
159/*
160 * Raising/lowering a non-targetted window
161 */
166
171
172
173
174
175/*
176 *************************************************************
177 *
178 * Iconification and its inverse.
179 *
180 *************************************************************
181 */
182static void
184{
185 if(tmp_win->isicon) {
187 }
188 else if(func == F_ICONIFY) {
189 Iconify(tmp_win, eventp->xbutton.x_root - 5,
190 eventp->xbutton.y_root - 5);
191 }
192}
193
202
203
204/*
205 * This is a synthetic function; it only exists as an action in some
206 * magic menus like TwmWindows (x-ref f.winwarp as well). It acts as a
207 * sort of deiconify, so I've stuck it here.
208 */
210{
211 /*
212 * This is a synthetic function; it exists only to be called
213 * internally from the various magic menus like TwmWindows
214 * etc.
215 */
216 tmp_win = (TwmWindow *)action;
217 if(! tmp_win) {
218 return;
219 }
220 if(Scr->WindowFunction.func != 0) {
221 ExecuteFunction(Scr->WindowFunction.func,
222 Scr->WindowFunction.item->action,
223 w, tmp_win, eventp, C_FRAME, false);
224 }
225 else {
228 }
229}
230
231
232
233
234/*
235 *************************************************************
236 *
237 * Focus locking
238 *
239 *************************************************************
240 */
242{
243 if(!tmp_win->isicon) {
244 if(!Scr->FocusRoot && Scr->Focus == tmp_win) {
245 FocusOnRoot();
246 }
247 else {
249 SetFocus(tmp_win, eventp->xbutton.time);
250 Scr->FocusRoot = false;
251 }
252 }
253}
254
256{
257 FocusOnRoot();
258}
259
260
261
262
263/*
264 *************************************************************
265 *
266 * Window destruction
267 *
268 *************************************************************
269 */
270static void
275
277{
278 if(tmp_win->isiconmgr) { /* don't send ourself a message */
280 return;
281 }
282 if(tmp_win->iswspmgr
284 || tmp_win->iswinbox
285#endif
286 || (Scr->workSpaceMgr.occupyWindow
287 && tmp_win == Scr->workSpaceMgr.occupyWindow->twm_win)) {
288 XBell(dpy, 0);
289 return;
290 }
291 if(tmp_win->protocols & DoesWmDeleteWindow) {
293 if(ButtonPressed != -1) {
294 XEvent kev;
295
297 if(kev.xbutton.window == tmp_win->w) {
298 kev.xbutton.window = Scr->Root;
299 }
301 }
302 return;
303 }
304 XBell(dpy, 0);
305}
306
308{
309 if(tmp_win->isiconmgr || tmp_win->iswspmgr
311 || tmp_win->iswinbox
312#endif
313 || (Scr->workSpaceMgr.occupyWindow
314 && tmp_win == Scr->workSpaceMgr.occupyWindow->twm_win)) {
315 XBell(dpy, 0);
316 return;
317 }
319 if(ButtonPressed != -1) {
320 XEvent kev;
321
323 if(kev.xbutton.window == tmp_win->w) {
324 kev.xbutton.window = Scr->Root;
325 }
327 }
328}
329
331{
332 if(tmp_win->isiconmgr) {
334 return;
335 }
336 if(tmp_win->iswspmgr
338 || tmp_win->iswinbox
339#endif
340 || (Scr->workSpaceMgr.occupyWindow
341 && tmp_win == Scr->workSpaceMgr.occupyWindow->twm_win)) {
342 XBell(dpy, 0);
343 return;
344 }
345 if(tmp_win->protocols & DoesWmDeleteWindow) {
347 }
348 else {
350 }
351 if(ButtonPressed != -1) {
352 XEvent kev;
353
355 if(kev.xbutton.window == tmp_win->w) {
356 kev.xbutton.window = Scr->Root;
357 }
359 }
360}
361
362
363
364
365/*
366 *************************************************************
367 *
368 * Messing with OnTopPriority bits
369 *
370 *************************************************************
371 */
372static void
374{
376 int pri;
377 char *endp;
378
379 if(tmp_win->icon && w == tmp_win->icon->w) {
381 }
382 else {
383 wintype = WinWin;
384 }
385 switch(func) {
388 break;
389 case F_SETPRIORITY:
390 pri = (int)strtol(action, &endp, 10);
392 (*endp == '<' || *endp == 'b') ? Below : Above);
393 break;
394 case F_CHANGEPRIORITY:
396 break;
397 case F_SWITCHPRIORITY:
399 break;
400 }
401
402 /*
403 * Stash up our current flags if there aren't any set yet. This is
404 * necessary because otherwise the EWMH prop we [may] stash below
405 * would be taken as gospel on restart, when it shouldn't be.
406 */
408
409#ifdef EWMH
410 /*
411 * We changed the priority somehow, so we may have changed where it
412 * sits relative to the middle. So trigger rechecking/setting of the
413 * _STATE_{ABOVE,BELOW}. (_ABOVE in changes arg covers both)
414 */
416#endif /* EWMH */
417}
434
435
436
437
438/*
439 *************************************************************
440 *
441 * Some misc utilities
442 *
443 *************************************************************
444 */
446{
447 if(tmp_win->protocols & DoesWmSaveYourself) {
449 }
450 else {
451 XBell(dpy, 0);
452 }
453}
454
455DFHANDLER(colormap)
456{
457 /* XXX Window targetting; should this be on the Defer list? */
458 if(strcmp(action, COLORMAP_NEXT) == 0) {
460 }
461 else if(strcmp(action, COLORMAP_PREV) == 0) {
463 }
464 else {
466 }
467}
468
470{
472 unsigned long valuemask;
473
475 attributes.background_pixel = Scr->Black;
476 w = XCreateWindow(dpy, Scr->Root, 0, 0,
477 Scr->rootw,
478 Scr->rooth,
479 0,
482 &attributes);
483 XMapWindow(dpy, w);
485 XFlush(dpy);
486
487}
488
490{
491 if(context == C_ICON && tmp_win->icon && tmp_win->icon->w)
492 w = XCreateSimpleWindow(dpy, tmp_win->icon->w,
493 0, 0, 9999, 9999, 0, Scr->Black, Scr->Black);
494 else
495 w = XCreateSimpleWindow(dpy, tmp_win->frame,
496 0, 0, 9999, 9999, 0, Scr->Black, Scr->Black);
497
498 XMapWindow(dpy, w);
500 XFlush(dpy);
501}
502
503
504
505
506/*
507 *************************************************************
508 *
509 * Window squeezing related bits
510 *
511 *************************************************************
512 */
517
519{
520 if(tmp_win->squeezed) {
522 }
523}
524
525
527{
529 Window rootw;
530 int deltax = 0, newx = 0;
531 int origX;
532 int origNum;
534
535 PopDownMenu();
536 if(tmp_win->squeezed ||
537 !tmp_win->squeeze_info ||
538 !tmp_win->title_w ||
539 context == C_ICON) {
540 XBell(dpy, 0);
541 return;
542 }
543
544 /* If the SqueezeInfo isn't copied yet, do it now */
545 if(!tmp_win->squeeze_info_copied) {
546 SqueezeInfo *s = malloc(sizeof(SqueezeInfo));
547 if(!s) {
548 return;
549 }
550 *s = *tmp_win->squeeze_info;
551 tmp_win->squeeze_info = s;
552 tmp_win->squeeze_info_copied = true;
553 }
554 si = tmp_win->squeeze_info;
555
556 if(si->denom != 0) {
557 int target_denom = tmp_win->frame_width;
558 /*
559 * If not pixel based, scale the denominator to equal the
560 * window width, so the numerator equals pixels.
561 * That way we can just modify it by pixel units, just
562 * like the other case.
563 */
564
565 if(si->denom != target_denom) {
566 float scale = (float)target_denom / si->denom;
567 si->num *= scale;
568 si->denom = target_denom; /* s->denom *= scale; */
569 }
570 }
571
572 /* now move the mouse */
573#ifdef WINBOX
574 if(tmp_win->winbox) {
575 XTranslateCoordinates(dpy, Scr->Root, tmp_win->winbox->window,
576 eventp->xbutton.x_root, eventp->xbutton.y_root,
577 &eventp->xbutton.x_root, &eventp->xbutton.y_root, &JunkChild);
578 }
579#endif
580 /*
581 * the event is always a button event, since key events
582 * are "weeded out" - although incompletely only
583 * F_MOVE and F_RESIZE - in HandleKeyPress().
584 */
585
586 /*
587 * XXX This var may be actually unnecessary; it's used only
588 * once as an arg to a later X call, but during that time I
589 * don't believe anything can mutate eventp or anything near
590 * the root. However, due to the union nature of XEvent,
591 * it's hard to be sure without more investigation, so I
592 * leave the intermediate var for now.
593 *
594 * Note that we're looking inside the XButtonEvent member
595 * here, but other bits of this code later look at the
596 * XMotionEvent piece. This should be further investigated
597 * and resolved; they can't both be right (though the
598 * structure of the structs are such that almost all the
599 * similar elements are in the same place, at least in
600 * theory).
601 */
602 rootw = eventp->xbutton.root;
603
606
607 if(!Scr->NoGrabServer) {
609 }
610
611 grabwin = Scr->Root;
612#ifdef WINBOX
613 if(tmp_win->winbox) {
614 grabwin = tmp_win->winbox->window;
615 }
616#endif
619 ButtonMotionMask | PointerMotionMask, /* PointerMotionHintMask */
621
622#if 0 /* what's this for ? */
623 if(! tmp_win->icon || w != tmp_win->icon->w) {
625 eventp->xbutton.x,
626 eventp->xbutton.y,
627 &DragX, &DragY, &JunkChild);
628
629 w = tmp_win->frame;
630 }
631#endif
632
634
637 &JunkDepth);
638
639 origX = eventp->xbutton.x_root;
640 origNum = si->num;
641
643 /* warp the pointer to the middle of the window */
644 XWarpPointer(dpy, None, Scr->Root, 0, 0, 0, 0,
645 origDragX + DragWidth / 2,
646 origDragY + DragHeight / 2);
647 XFlush(dpy);
648 }
649
650 while(1) {
655
656 /* block until there is an interesting event */
661
662 /* throw away enter and leave events until release */
663 if(Event.xany.type == EnterNotify ||
664 Event.xany.type == LeaveNotify) {
665 continue;
666 }
667
668 if(Event.type == MotionNotify) {
669 /* discard any extra motion events before a logical release */
670 while(XCheckMaskEvent(dpy,
672 if(Event.type == releaseEvent) {
673 break;
674 }
675 }
676 }
677
678 if(!DispatchEvent2()) {
679 continue;
680 }
681
682 if(Event.type == releaseEvent) {
683 break;
684 }
685
686 /* something left to do only if the pointer moved */
687 if(Event.type != MotionNotify) {
688 continue;
689 }
690
691 /* get current pointer pos, useful when there is lag */
692 XQueryPointer(dpy, rootw, &eventp->xmotion.root, &JunkChild,
693 &eventp->xmotion.x_root, &eventp->xmotion.y_root,
694 &JunkX, &JunkY, &JunkMask);
695
697#ifdef WINBOX
698 if(tmp_win->winbox) {
699 XTranslateCoordinates(dpy, Scr->Root, tmp_win->winbox->window,
700 eventp->xmotion.x_root, eventp->xmotion.y_root,
701 &eventp->xmotion.x_root, &eventp->xmotion.y_root, &JunkChild);
702 }
703#endif
704
705 if(!Scr->NoRaiseMove && Scr->OpaqueMove && !WindowMoved) {
707 }
708
709 deltax = eventp->xmotion.x_root - origX;
710 newx = origNum + deltax;
711
712 /*
713 * Clamp to left and right.
714 * If we're in pixel size, keep within [ 0, frame_width >.
715 * If we're proportional, don't cross the 0.
716 * Also don't let the nominator get bigger than the denominator.
717 * Keep within [ -denom, -1] or [ 0, denom >.
718 */
719 {
720 int wtmp = tmp_win->frame_width; /* or si->denom; if it were != 0 */
721 if(origNum < 0) {
722 if(newx >= 0) {
723 newx = -1;
724 }
725 else if(newx < -wtmp) {
726 newx = -wtmp;
727 }
728 }
729 else if(origNum >= 0) {
730 if(newx < 0) {
731 newx = 0;
732 }
733 else if(newx >= wtmp) {
734 newx = wtmp - 1;
735 }
736 }
737 }
738
739 si->num = newx;
740 /* This, finally, actually moves the title bar */
741 /* XXX pressing a second button should cancel and undo this */
743 }
744
745 /*
746 * The ButtonRelease handler will have taken care of
747 * ungrabbing our pointer.
748 */
749 return;
750}
static int PlaceX
Definition add_window.c:82
bool InstallWindowColormaps(int type, TwmWindow *tmp)
Definition colormaps.c:39
void BumpWindowColormap(TwmWindow *tmp, int inc)
Definition colormaps.c:496
int JunkY
Definition ctwm.h:358
Window JunkRoot
Definition ctwm_main.c:142
#define DoesWmDeleteWindow
Definition ctwm.h:324
#define DoesWmSaveYourself
Definition ctwm.h:323
int JunkX
Definition ctwm_main.c:143
Display * dpy
Definition ctwm_main.c:84
#define C_ROOT
Definition ctwm.h:78
unsigned int JunkMask
Definition ctwm.h:359
#define C_FRAME
Definition ctwm.h:79
Window JunkChild
Definition ctwm.h:357
#define C_ICON
Definition ctwm.h:77
unsigned int JunkDepth
Definition ctwm.h:359
#define Scr
unsigned int DragBW
Definition event_core.c:75
Time EventTime
Definition event_core.c:79
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
int DragY
Definition event_core.c:72
bool DispatchEvent2(void)
Definition event_core.c:343
XEvent Event
Definition event_core.c:66
event_proc EventHandler[256]
Definition event_core.c:64
int ButtonPressed
Definition event_core.c:93
Window DragWindow
Definition event_core.c:68
int DragX
Definition event_core.c:71
int Context
Definition event_core.c:65
void HandleUnknown(void)
void FixRootEvent(XEvent *e)
void EwmhSet_NET_WM_STATE(TwmWindow *twm_win, int changes)
Definition ewmh.c:2137
#define EWMH_STATE_ABOVE
Definition ewmh.h:41
void ExecuteFunction(int func, void *action, Window w, TwmWindow *tmp_win, XEvent *eventp, int context, bool pulldown)
Definition functions.c:99
bool WindowMoved
Definition functions.c:52
Time last_time
Definition functions.c:71
void HideIconManager(void)
#define DFHANDLER(func)
#define EF_ARGS
#define EF_FULLPROTO
static void raise_handler(int func, void *action, Window w, TwmWindow *tmp_win, XEvent *eventp, int context, bool pulldown)
static void iconify_handler(int func, void *action, Window w, TwmWindow *tmp_win, XEvent *eventp, int context, bool pulldown)
static void otp_priority_handler(int func, void *action, Window w, TwmWindow *tmp_win, XEvent *eventp, int context, bool pulldown)
static void SendDeleteWindowMessage(TwmWindow *tmp, Time timestamp)
bool menuFromFrameOrWindowOrTitlebar
Definition menus.c:60
void PopDownMenu(void)
Definition menus.c:1442
#define COLORMAP_NEXT
Definition menus.h:135
#define COLORMAP_PREV
Definition menus.h:136
void OtpChangePriority(TwmWindow *twm_win, WinType wintype, int relpriority)
Definition otp.c:920
void OtpTinyLower(TwmWindow *twm_win, WinType wintype)
Definition otp.c:819
void OtpTinyRaise(TwmWindow *twm_win, WinType wintype)
Definition otp.c:805
void OtpStashAflagsFirstTime(TwmWindow *twm_win)
Definition otp.c:1585
void OtpLower(TwmWindow *twm_win, WinType wintype)
Definition otp.c:777
void OtpToggleSwitching(TwmWindow *twm_win, WinType wintype)
Definition otp.c:963
void OtpSetPriority(TwmWindow *twm_win, WinType wintype, int new_pri, int where)
Definition otp.c:894
void OtpCirculateSubwindows(VirtualScreen *vs, int direction)
Definition otp.c:849
void OtpSwitchPriority(TwmWindow *twm_win, WinType wintype)
Definition otp.c:941
void OtpRaise(TwmWindow *twm_win, WinType wintype)
Definition otp.c:763
void OtpRaiseLower(TwmWindow *twm_win, WinType wintype)
Definition otp.c:791
WinType
Definition otp.h:14
@ WinWin
Definition otp.h:14
@ IconWin
Definition otp.h:14
int ConstrainedMoveTime
Definition parse.c:92
Info and control for every X Window we take over.
void SetFrameShape(TwmWindow *tmp)
void Iconify(TwmWindow *tmp_win, int def_x, int def_y)
Definition win_iconify.c:45
void DeIconify(TwmWindow *tmp_win)
void Squeeze(TwmWindow *tmp_win)
Definition win_ops.c:223
void SetFocus(TwmWindow *tmp_win, Time tim)
Definition win_ops.c:128
void FocusOnRoot(void)
Definition win_ops.c:189
void send_clientmessage(Window w, Atom a, Time timestamp)
Definition win_utils.c:996
void WMapLower(TwmWindow *win)
void WMapRaiseLower(TwmWindow *win)
void WMapRaise(TwmWindow *win)