2 * $Id: desktop.c,v 3.0 90/11/20 16:13:09 dme Exp Locker: dme $
4 * Copyright (c) 1990 Dave Edmondson.
5 * Copyright (c) 1990 Imperial College of Science, Technoology & Medicine
8 * Permission to use, copy, modify, and distribute this software and its
9 * documentation for any purpose and without fee is hereby granted, provided
10 * that the above copyright notice appear in all copies and that both that
11 * copyright notice and this permission notice appear in supporting
12 * documentation, and that the names of Dave Edmondson or Imperial College
13 * not be used in advertising or publicity pertaining to distribution of the
14 * software without specific, written prior permission. Dave Edmondson and
15 * Imperial College make no representations about the suitability of this
16 * software for any purpose. It is provided "as is" without express or
23 #include "add_window.h"
29 #define strdup Strdup /* avoid conflict with system header files */
30 extern char *strdup(char *);
32 extern void SetRealScreenInternal();
33 extern void SetRealScreen();
34 extern void SnapRealScreen();
35 extern void SetMapStateProp();
36 extern void twmrc_error_prefix();
38 void SetVirtualPixmap();
39 void SetRealScreenPixmap();
42 static int starting_x, starting_y;
45 static int original_x, original_y;
47 static void GetDesktopWindowCoordinates(tmp_win, x, y, w, h)
52 int border = tmp_win->frame_bw + tmp_win->frame_bw3D;
54 /* Stig Ostholm <ostholm%ce.chalmers.se@uunet> */
57 *x = tmp_win->frame_x / Scr->VirtualDesktopDScale;
59 /* *y = tmp_win->virtual_frame_y / Scr->VirtualDesktopDScale; */
60 *y = tmp_win->frame_y / Scr->VirtualDesktopDScale; /* DSE */
61 /* RFB 4/92 no SCALE_D */
62 /* *x = SCALE_D(tmp_win->virtual_frame_x); */
63 /* *y = SCALE_D(tmp_win->virtual_frame_y); */
66 *x = tmp_win->virtual_frame_x / Scr->VirtualDesktopDScale;
68 *y = tmp_win->virtual_frame_y / Scr->VirtualDesktopDScale;
69 /* RFB 4/92 no SCALE_D */
70 /* *x = SCALE_D(tmp_win->virtual_frame_x); */
71 /* *y = SCALE_D(tmp_win->virtual_frame_y); */
76 tmp_win->frame_width + Scr->VirtualDesktopDScale / 2
79 + tmp_win->frame_bw + tmp_win->frame_bw )
84 if ( *w <= 0 ) *w = 1; /* 4/92 RFB */
89 tmp_win->frame_height + Scr->VirtualDesktopDScale / 2
91 /* + tmp_win->title_height */
95 + tmp_win->frame_bw + tmp_win->frame_bw ) - 2;
99 /* 4/92 RFB -- subtract borderwidth from windowwidth... */
100 if ( *h <= 0 ) *h = 1; /* 4/92 RFB */
102 } /* Stig Ostholm <ostholm%ce.chalmers.se@uunet> */
106 * create the virtual desktop display and store the window in the screen structure
108 void CreateDesktopDisplay()
113 /* djhjr - 5/17/98 */
114 #ifndef ORIGINAL_PIXMAPS
118 XSetWindowAttributes attributes; /* attributes for create windows */
119 unsigned long valuemask;
120 unsigned int pm_numcolors;
126 width = Scr->VirtualDesktopWidth / Scr->VirtualDesktopDScale;
127 height = Scr->VirtualDesktopHeight / Scr->VirtualDesktopDScale;
129 /* done in SetVirtualDesktop() - djhjr - 9/26/01
130 * we have some checking for negative (x,y) to do *
131 if (Scr->VirtualDesktopDX < 0) {
132 Scr->VirtualDesktopDX = Scr->MyDisplayWidth - width -
133 (2 * Scr->BorderWidth) + Scr->VirtualDesktopDX;
135 if (Scr->VirtualDesktopDY < 0) {
136 Scr->VirtualDesktopDY = Scr->MyDisplayHeight - height -
137 (2 * Scr->BorderWidth) + Scr->VirtualDesktopDY;
141 Scr->VirtualDesktopDisplayOuter =
142 XCreateSimpleWindow(dpy, Scr->Root,
143 Scr->VirtualDesktopDX, Scr->VirtualDesktopDY,
148 width + (Scr->VirtualDesktopBevelWidth * 2),
149 height + (Scr->VirtualDesktopBevelWidth * 2),
151 /* was 'Scr->BorderWidth' - submitted by Rolf Neugebauer */
154 Scr->Black, Scr->VirtualDesktopDisplayC.back);
158 XSetWindowAttributes attr;
160 attr.backing_store = True;
161 XChangeWindowAttributes(dpy, Scr->VirtualDesktopDisplayOuter,
162 CWBackingStore, &attr);
165 if ( width != Scr->VirtualDesktopMaxWidth )
166 Scr->VirtualDesktopMaxWidth = width;
167 if ( height != Scr->VirtualDesktopMaxHeight )
168 Scr->VirtualDesktopMaxHeight = height;
169 /* vtwm 5.2: RFB growable but not unreasonable interior window! */
172 * re-written to use an Image structure for XPM support
176 #ifdef ORIGINAL_PIXMAPS
177 Scr->VirtualDesktopDisplay =
178 XCreateSimpleWindow(dpy, Scr->VirtualDesktopDisplayOuter,
183 Scr->VirtualDesktopBevelWidth,
184 Scr->VirtualDesktopBevelWidth,
186 Scr->VirtualDesktopMaxWidth,
187 Scr->VirtualDesktopMaxHeight,
189 Scr->VirtualDesktopDisplayBorder,
190 Scr->VirtualC.back);/*RFB VCOLOR*/
192 XDefineCursor( dpy, Scr->VirtualDesktopDisplay,
193 Scr->VirtualCursor ); /*RFBCURSOR*/
195 if ( Scr->virtualPm ) /*RFB PIXMAP*/
196 { /* Background pixmap, copied from tvtwm */
201 pm = XCreatePixmap( dpy, Scr->VirtualDesktopDisplay,
202 Scr->virtual_pm_width, Scr->virtual_pm_height,
204 gcv.foreground = Scr->VirtualC.fore;
205 gcv.background = Scr->VirtualC.back;
206 gcv.graphics_exposures = False;
207 gc = XCreateGC (dpy, Scr->Root,
208 (GCForeground|GCBackground|GCGraphicsExposures),
212 XCopyPlane (dpy, Scr->virtualPm, pm, gc, 0, 0,
213 Scr->virtual_pm_width, Scr->virtual_pm_height,
216 XSetWindowBackgroundPixmap( dpy, Scr->VirtualDesktopDisplay,
218 XClearWindow( dpy, Scr->VirtualDesktopDisplay );
220 XFreePixmap (dpy, pm);
222 #else /* ORIGINAL_PIXMAPS */
225 /* djhjr - 5/23/98 9/2/98 */
226 #ifndef NO_XPM_SUPPORT
228 pm_numcolors = SetPixmapsBackground(Scr->virtualPm, Scr->Root,
232 if (pm_numcolors > 2) /* not a bitmap */
234 valuemask = CWBackPixmap;
235 attributes.background_pixmap = Scr->virtualPm->pixmap;
237 Scr->VirtualDesktopDisplay = XCreateWindow(dpy,
238 Scr->VirtualDesktopDisplayOuter,
243 Scr->VirtualDesktopBevelWidth,
244 Scr->VirtualDesktopBevelWidth,
246 Scr->VirtualDesktopMaxWidth,
247 Scr->VirtualDesktopMaxHeight,
249 Scr->d_depth, (unsigned int) CopyFromParent,
250 Scr->d_visual, valuemask, &attributes);
254 Scr->VirtualDesktopDisplay = XCreateSimpleWindow(dpy,
255 Scr->VirtualDesktopDisplayOuter,
260 Scr->VirtualDesktopBevelWidth,
261 Scr->VirtualDesktopBevelWidth,
263 Scr->VirtualDesktopMaxWidth,
264 Scr->VirtualDesktopMaxHeight,
266 Scr->VirtualDesktopDisplayBorder,
267 Scr->VirtualC.back); /*RFB VCOLOR*/
271 pm = XCreatePixmap( dpy, Scr->VirtualDesktopDisplay,
272 Scr->virtualPm->width, Scr->virtualPm->height,
275 gcv.foreground = Scr->VirtualC.fore;
276 gcv.background = Scr->VirtualC.back;
277 gcv.graphics_exposures = False;
279 gc = XCreateGC(dpy, Scr->Root,
280 (GCForeground | GCBackground | GCGraphicsExposures),
285 XCopyPlane(dpy, Scr->virtualPm->pixmap, pm, gc, 0, 0,
286 Scr->virtualPm->width, Scr->virtualPm->height,
291 XSetWindowBackgroundPixmap(dpy, Scr->VirtualDesktopDisplay, pm);
293 XClearWindow(dpy, Scr->VirtualDesktopDisplay);
296 XFreePixmap(dpy, pm);
300 XDefineCursor(dpy, Scr->VirtualDesktopDisplay, Scr->VirtualCursor); /*RFB CURSOR */
301 #endif /* ORIGINAL_PIXMAPS */
303 XSetStandardProperties(dpy, Scr->VirtualDesktopDisplayOuter,
306 "Virtual Desktop", "Virtual Desktop",
309 "VTWM Desktop", "VTWM Desktop",
311 VTWM_DESKTOP_CLASS, VTWM_DESKTOP_CLASS,
313 None, NULL, 0, NULL);
315 /* Stig Ostholm moved a few lines away from here */
319 if ( Scr->UseRealScreenBorder )
322 border = Scr->RealScreenBorderWidth; * DSE *
325 border = Scr->RealScreenBorderWidth;
328 * re-written to use an Image structure for XPM support
332 #ifdef ORIGINAL_PIXMAPS
333 /* create the real screen display */
334 Scr->VirtualDesktopDScreen =
335 XCreateSimpleWindow(dpy, Scr->VirtualDesktopDisplay,
339 SCALE_D(Scr->MyDisplayWidth - 2 * border),
340 SCALE_D(Scr->MyDisplayHeight - 2 * border),
342 SCALE_D(Scr->MyDisplayWidth) - 2 * border,
343 SCALE_D(Scr->MyDisplayHeight) - 2 * border,
345 border, /* make it distinctive */
346 /* RFB 4/92: make borderwidth 0 instead of 2 */
347 /* RFB 5.2: some people need the border... */
348 Scr->VirtualDesktopDisplayBorder,
349 Scr->RealScreenC.back ); /* RFB 4/92 */
351 if ( Scr->RealScreenPm ) /*RFB PIXMAP*/
352 { /* Background pixmap */
357 pm = XCreatePixmap( dpy, Scr->VirtualDesktopDScreen,
358 Scr->RealScreen_pm_width, Scr->RealScreen_pm_height,
360 gcv.foreground = Scr->RealScreenC.fore;
361 gcv.background = Scr->RealScreenC.back;
362 gcv.graphics_exposures = False;
363 gc = XCreateGC (dpy, Scr->Root,
364 (GCForeground|GCBackground|GCGraphicsExposures),
368 XCopyPlane (dpy, Scr->RealScreenPm, pm, gc, 0, 0,
369 Scr->RealScreen_pm_width, Scr->RealScreen_pm_height,
372 XSetWindowBackgroundPixmap( dpy, Scr->VirtualDesktopDScreen,
374 XClearWindow( dpy, Scr->VirtualDesktopDScreen );
376 XFreePixmap (dpy, pm);
378 #else /* ORIGINAL_PIXMAPS */
381 /* djhjr - 5/23/98 9/2/98 */
382 #ifndef NO_XPM_SUPPORT
383 if (Scr->realscreenPm)
384 pm_numcolors = SetPixmapsBackground(Scr->realscreenPm,
385 Scr->Root, Scr->RealScreenC.back);
388 if (pm_numcolors > 2) /* not a bitmap */
390 valuemask = CWBackPixmap | CWBorderPixel;
391 attributes.background_pixmap = Scr->realscreenPm->pixmap;
392 attributes.border_pixel = Scr->VirtualDesktopDisplayBorder;
394 Scr->VirtualDesktopDScreen = XCreateWindow(dpy,
395 Scr->VirtualDesktopDisplay,
399 SCALE_D(Scr->MyDisplayWidth - 2 * border),
400 SCALE_D(Scr->MyDisplayHeight - 2 * border),
402 SCALE_D(Scr->MyDisplayWidth) - 2 * border,
403 SCALE_D(Scr->MyDisplayHeight) - 2 * border,
406 Scr->d_depth, (unsigned int) CopyFromParent,
407 Scr->d_visual, valuemask, &attributes);
411 Scr->VirtualDesktopDScreen = XCreateSimpleWindow(dpy,
412 Scr->VirtualDesktopDisplay,
416 SCALE_D(Scr->MyDisplayWidth - 2 * border),
417 SCALE_D(Scr->MyDisplayHeight - 2 * border),
419 SCALE_D(Scr->MyDisplayWidth) - 2 * border,
420 SCALE_D(Scr->MyDisplayHeight) - 2 * border,
422 border, /* make it distinctive */
423 /* RFB 4/92: make borderwidth 0 instead of 2 */
424 /* RFB 5.2: some people need the border... */
425 Scr->VirtualDesktopDisplayBorder,
426 Scr->RealScreenC.back ); /* RFB 4/92 */
428 if (Scr->realscreenPm)
430 pm = XCreatePixmap(dpy, Scr->VirtualDesktopDScreen,
431 Scr->realscreenPm->width, Scr->realscreenPm->height,
434 gcv.foreground = Scr->RealScreenC.fore;
435 gcv.background = Scr->RealScreenC.back;
436 gcv.graphics_exposures = False;
438 gc = XCreateGC(dpy, Scr->Root,
439 (GCForeground | GCBackground | GCGraphicsExposures),
444 XCopyPlane(dpy, Scr->realscreenPm->pixmap, pm, gc, 0, 0,
445 Scr->realscreenPm->width, Scr->realscreenPm->height,
450 XSetWindowBackgroundPixmap(dpy, Scr->VirtualDesktopDScreen, pm);
452 XClearWindow(dpy, Scr->VirtualDesktopDScreen);
455 XFreePixmap(dpy, pm);
458 #endif /* ORIGINAL_PIXMAPS */
460 /* declare our interest */
461 XSelectInput(dpy, Scr->VirtualDesktopDisplay, ButtonPressMask | ButtonReleaseMask |
462 KeyPressMask | KeyReleaseMask | ExposureMask);
464 /* Stig Ostholm moved some lines to here: */
465 Scr->VirtualDesktopDisplayTwin =
466 AddWindow(Scr->VirtualDesktopDisplayOuter, FALSE, NULL);
468 /* djhjr - 5/19/98 */
469 Scr->VirtualDesktopDisplayTwin->class.res_name = strdup(VTWM_DESKTOP_CLASS);
470 Scr->VirtualDesktopDisplayTwin->class.res_class = strdup(VTWM_DESKTOP_CLASS);
471 XSetClassHint(dpy, Scr->VirtualDesktopDisplayOuter, &Scr->VirtualDesktopDisplayTwin->class);
473 /* limit the minimum size of the virtual desktop - djhjr - 2/23/99 */
474 Scr->VirtualDesktopDisplayTwin->hints.flags |= PMinSize;
475 Scr->VirtualDesktopDisplayTwin->hints.min_width =
476 SCALE_D(Scr->MyDisplayWidth) + (Scr->VirtualDesktopBevelWidth * 2);
477 Scr->VirtualDesktopDisplayTwin->hints.min_height =
478 SCALE_D(Scr->MyDisplayHeight) + (Scr->VirtualDesktopBevelWidth * 2);
481 /* this is a gross hack, but people wanted it */
482 Scr->VirtualDesktopDisplayTwin->nailed = TRUE;
483 #endif /* GROSS_HACK */
485 SetMapStateProp(Scr->VirtualDesktopDisplayTwin, NormalState);
486 /* :ereh ot senil emos devom mlohtsO gitS */
488 /* position the representation */
489 DisplayScreenOnDesktop();
492 XMapWindow(dpy, Scr->VirtualDesktopDScreen);
493 XMapWindow(dpy, Scr->VirtualDesktopDisplay);
494 XMapWindow(dpy, Scr->VirtualDesktopDisplayOuter);
496 /* create the autopan windows if we are doing this */
497 if (Scr->AutoPanX > 0) {
501 Scr->VirtualDesktopAutoPan[0] = XCreateWindow(dpy, Scr->Root,
505 Scr->MyDisplayHeight,
512 Scr->VirtualDesktopAutoPan[1] = XCreateWindow(dpy, Scr->Root,
513 Scr->MyDisplayWidth - AP_SIZE,
516 Scr->MyDisplayHeight,
523 Scr->VirtualDesktopAutoPan[2] = XCreateWindow(dpy, Scr->Root,
534 Scr->VirtualDesktopAutoPan[3] = XCreateWindow(dpy, Scr->Root,
536 Scr->MyDisplayHeight - AP_SIZE,
545 /* set the event masks on the windows */
546 for(l = 0; l <= 3; l++) {
547 XSetStandardProperties(dpy, Scr->VirtualDesktopAutoPan[l],
548 "Automatic Pan", "Automatic Pan",
549 None, NULL, 0, NULL);
552 * Added the leave event for pan resistance -
553 * see events.c:HandleEnterNotify().
557 XSelectInput(dpy, Scr->VirtualDesktopAutoPan[l],
558 EnterWindowMask | LeaveWindowMask);
560 XMapWindow(dpy, Scr->VirtualDesktopAutoPan[l]);
563 } /* end if Scr->AutoPan */
567 * re-written to use an Image structure for XPM support
571 #ifdef ORIGINAL_PIXMAPS
572 void SetVirtualPixmap (filename)
575 Pixmap pm = GetBitmap (filename);
578 if (Scr->virtualPm) {
579 XFreePixmap (dpy, Scr->virtualPm);
582 Scr->virtual_pm_width = JunkWidth;
583 Scr->virtual_pm_height = JunkHeight;
586 #else /* ORIGINAL_PIXMAPS */
587 void SetVirtualPixmap (filename)
590 if (!Scr->virtualPm) Scr->virtualPm = SetPixmapsPixmap(filename);
592 #endif /* ORIGINAL_PIXMAPS */
595 * re-written to use an Image structure for XPM support
599 #ifdef ORIGINAL_PIXMAPS
600 void SetRealScreenPixmap (filename)
603 Pixmap pm = GetBitmap (filename);
606 if (Scr->RealScreenPm) {
607 XFreePixmap (dpy, Scr->RealScreenPm);
609 Scr->RealScreenPm = pm;
610 Scr->RealScreen_pm_width = JunkWidth;
611 Scr->RealScreen_pm_height = JunkHeight;
614 #else /* ORIGINAL_PIXMAPS */
615 void SetRealScreenPixmap (filename)
618 if (!Scr->realscreenPm) Scr->realscreenPm = SetPixmapsPixmap(filename);
620 #endif /* ORIGINAL_PIXMAPS */
623 * add this window to the virtual desktop - aka nail it
625 void UpdateDesktop(tmp_win)
628 int x, y, width, height;
634 if (!tmp_win->showindesktopdisplay)
638 XUnmapWindow(dpy, tmp_win->VirtualDesktopDisplayWindow);
642 GetDesktopWindowCoordinates(tmp_win, &x, &y, &width, &height);
643 /* Stig Ostholm <ostholm%ce.chalmers.se@uunet> these 3 lines */
644 dwindow = (tmp_win->nailed)
645 ? Scr->VirtualDesktopDScreen : Scr->VirtualDesktopDisplay;
647 /* if it already has a vd display window, just move it to the right place
648 and map it, else actually create the window */
649 if (!tmp_win->VirtualDesktopDisplayWindow) {
650 Pixel background, border;
653 if (!GetColorFromList(Scr->VirtualDesktopColorBL, tmp_win->full_name,
654 &tmp_win->class, &background) &&
655 !GetColorFromList(Scr->TitleBackgroundL, tmp_win->full_name,
656 &tmp_win->class, &background))
657 background = Scr->VirtualDesktopDisplayC.back;
659 background = tmp_win->virtual.back;
661 /* 7/10/90 - uses border list not foreground */
662 if(!GetColorFromList(Scr->VirtualDesktopColorBoL, tmp_win->full_name,
663 &tmp_win->class, &border) &&
664 !GetColorFromList(Scr->TitleForegroundL, tmp_win->full_name,
665 &tmp_win->class, &border))
666 border = Scr->VirtualDesktopDisplayBorder;
668 /* the position and size don't matter */
669 tmp_win->VirtualDesktopDisplayWindow =
670 XCreateSimpleWindow(dpy,
671 dwindow, x, y, width, height, /* Stig */
672 1, border, background);
674 /*RFBCURSOR*/XDefineCursor( dpy, tmp_win->VirtualDesktopDisplayWindow,
675 /*RFBCURSOR*/Scr->DesktopCursor );
677 /* listen for expose events to redraw the name */
678 if (Scr->NamesInVirtualDesktop)
679 XSelectInput(dpy, tmp_win->VirtualDesktopDisplayWindow,
682 /* save the twm window on the window */
683 XSaveContext(dpy, tmp_win->VirtualDesktopDisplayWindow,
684 VirtualContext, (caddr_t) tmp_win);
685 XSaveContext(dpy, tmp_win->VirtualDesktopDisplayWindow,
686 TwmContext, (caddr_t) tmp_win);
690 0 /* Stig Ostholm <ostholm%ce.chalmers.se@uunet> */
691 0 /* comment out this section */
693 0 /* unmap whilst we reconfigure it */
694 0 XUnmapWindow(dpy, tmp_win->VirtualDesktopDisplayWindow);
696 0 if (tmp_win->nailed) {
697 0 x = tmp_win->frame_x / Scr->VirtualDesktopDScale;
698 0 y = tmp_win->frame_y / Scr->VirtualDesktopDScale;
699 0/* RFB 4/92 no SCALE_D */
700 0 /* x = SCALE_D(tmp_win->frame_x); */
701 0 /* y = SCALE_D(tmp_win->frame_y); */
703 0 /* reparent this window into the little screen representation */
704 0 XReparentWindow(dpy, tmp_win->VirtualDesktopDisplayWindow,
705 0 Scr->VirtualDesktopDScreen, x, y);
707 0 x = tmp_win->virtual_frame_x / Scr->VirtualDesktopDScale;
708 0 y = tmp_win->virtual_frame_y / Scr->VirtualDesktopDScale;
709 0/* RFB 4/92 no SCALE_D */
710 0 /* x = SCALE_D(tmp_win->virtual_frame_x); */
711 0 /* y = SCALE_D(tmp_win->virtual_frame_y); */
713 0 XReparentWindow(dpy, tmp_win->VirtualDesktopDisplayWindow,
714 0 Scr->VirtualDesktopDisplay, x, y);
717 0 /* calculate the sizes and position */
719 0 tmp_win->frame_width + Scr->VirtualDesktopDScale / 2
720 0 + tmp_win->frame_bw + tmp_win->frame_bw )
723 0 tmp_win->frame_height + Scr->VirtualDesktopDScale / 2
725 0 /* + tmp_win->title_height */
727 0 + tmp_win->frame_bw + tmp_win->frame_bw ) - 2;
728 0/* 4/92 RFB -- subtract borderwidth from windowwidth... */
729 0 if ( width <= 0 ) width = 1; /* 4/92 RFB */
730 0 if ( height <= 0 ) height = 1; /* 4/92 RFB */
733 0 fprintf(stderr, "%d*%d+%d+%d\n", x, y, width, height);
736 0 /* move and size it */
737 0 XMoveWindow(dpy, tmp_win->VirtualDesktopDisplayWindow,
739 0 XResizeWindow(dpy, tmp_win->VirtualDesktopDisplayWindow,
742 } else { /* Unmapping is fixed by XReparentWindow */
743 XReparentWindow(dpy, tmp_win->VirtualDesktopDisplayWindow,
745 XResizeWindow(dpy, tmp_win->VirtualDesktopDisplayWindow,
749 XMapWindow(dpy, tmp_win->VirtualDesktopDisplayWindow);
753 0/* Stig Ostholm <ostholm%ce.chalmers.se@uunet> */
755 0 * remove a window from the desktop display - aka unnail it
757 0void RemoveFromDesktop(tmp_win)
766 0 if (tmp_win->VirtualDesktopDisplayWindow)
767 0 XUnmapWindow(dpy, tmp_win->VirtualDesktopDisplayWindow);
769 0 /* reparent its representation out of the real screen window */
770 0 x = tmp_win->virtual_frame_x /Scr->VirtualDesktopDScale;
771 0 y = tmp_win->virtual_frame_y / Scr->VirtualDesktopDScale;
772 0/* RFB 4/92 no SCALE_D */
773 0 /* x = SCALE_D(tmp_win->virtual_frame_x); */
774 0 /* y = SCALE_D(tmp_win->virtual_frame_y); */
776 0 XReparentWindow(dpy, tmp_win->VirtualDesktopDisplayWindow,
777 0 Scr->VirtualDesktopDisplay, x, y);
781 /* Stig Ostholm <ostholm%ce.chalmers.se@uunet>
782 * Nail/unnail a window on the desktop display.
784 void NailDesktop(tmp_win)
789 if (!tmp_win->VirtualDesktopDisplayWindow
794 GetDesktopWindowCoordinates(tmp_win, &x, &y, (int *) 0, (int *) 0);
795 XReparentWindow(dpy, tmp_win->VirtualDesktopDisplayWindow,
797 ? Scr->VirtualDesktopDScreen
798 : Scr->VirtualDesktopDisplay,
800 XMapWindow(dpy, tmp_win->VirtualDesktopDisplayWindow);
804 * state during the move
806 static unsigned int moving_x, moving_y, moving_w, moving_h, moving_bw;
807 static unsigned int moving_off_x, moving_off_y;
808 Window moving_window;
809 TwmWindow *moving_twindow;
811 /**********************************************************/
813 /* RFB 7/16/93 -- moved these static variables up to */
814 /* this part of the file so that I could use moving_bw */
815 /* in DisplayScreenOnDesktop(). */
817 /* Note that moving_bw is set to 0 if you clicked *in* */
818 /* the window; therefore it can only have a non-zero */
819 /* value if you clicked at a random location in the */
820 /* panner, making the RealScreen jump to the pointer, */
821 /* AND you also had RealScreenBorderWidth set. */
823 /* This is almost the final step in getting the panner */
824 /* to behave pefectly! It still jitters a bit at the */
827 /**********************************************************/
830 * correctly position the real screen representation on the virtual desktop display
832 void DisplayScreenOnDesktop()
840 border = ( Scr->UseRealScreenBorder ) ? moving_bw : 0;
843 border = moving_bw = 0;
845 /* the -3 is to account for the 2 pixel border and the 1 pixel
846 * offset added by SCALE_D.... */
847 XMoveWindow(dpy, Scr->VirtualDesktopDScreen,
848 Scr->VirtualDesktopX / Scr->VirtualDesktopDScale - border,
849 Scr->VirtualDesktopY / Scr->VirtualDesktopDScale - border
850 /* SCALE_D(Scr->VirtualDesktopX), */ /* - RFB changed 3 to 1 */
851 /* SCALE_D(Scr->VirtualDesktopY) */ /* - RFB changed 3 to 1 */
853 /* 4/92 RFB -- simply use SCALE_D; well, no...
854 ** the problem is that SCALE_D adds 1 if the result is 0, but
855 ** just gives the right result otherwise.
858 /* Way back, somebody wrote: */
859 /* I've convinced myself that this is not necessary */
860 /* XLowerWindow(dpy, Scr->VirtualDesktopDScreen); */
863 void ResizeDesktopDisplay(w, h)
872 /* added compensation for the titlebar - djhjr - 2/23/99 */
873 h -= Scr->VirtualDesktopDisplayTwin->title_height;
875 /* added compensation for frame and bevel widths - djhjr - 2/7/99 */
876 bw = Scr->VirtualDesktopBevelWidth * 2;
877 if (Scr->BorderBevelWidth) bw += Scr->BorderWidth * 2;
880 if ( w - bw != Scr->VirtualDesktopMaxWidth )
881 { Scr->VirtualDesktopMaxWidth = w - bw;
884 if ( h - bw != Scr->VirtualDesktopMaxHeight )
885 { Scr->VirtualDesktopMaxHeight = h - bw;
889 { XResizeWindow( dpy, Scr->VirtualDesktopDisplay,
890 Scr->VirtualDesktopMaxWidth,
891 Scr->VirtualDesktopMaxHeight );
894 /* calculate the new vd size */
895 Scr->VirtualDesktopWidth = SCALE_U(w - bw);
896 Scr->VirtualDesktopHeight = SCALE_U(h - bw);
898 x = SCALE_D(Scr->VirtualDesktopX);
899 y = SCALE_D(Scr->VirtualDesktopY);
901 /* redraw it so that the real screen representation ends up on the display */
902 np = SCALE_D(Scr->VirtualDesktopWidth) - SCALE_D(Scr->MyDisplayWidth);
906 np = SCALE_D(Scr->VirtualDesktopHeight) - SCALE_D(Scr->MyDisplayHeight);
911 /* this is a bit of a fudge factor to account for the borderwidth */
916 SetRealScreen(SCALE_U(x), SCALE_U(y));
918 /* done in setrealscreen now */
920 /* move the display window */
921 XMoveWindow(dpy, Scr->VirtualDesktopDScreen, x - 1, y - 1);
927 * F_MOVESCREEN function
928 * move a window in the desktop display - possible including the `real' screen
930 void StartMoveWindowInDesktop(ev)
941 moving_window = ev.subwindow;
944 moving_window = Scr->VirtualDesktopDScreen;
946 XGrabPointer(dpy, Scr->VirtualDesktopDisplayOuter, True,
947 ButtonPressMask | ButtonReleaseMask | ButtonMotionMask,
948 GrabModeAsync, GrabModeAsync,
949 Scr->VirtualDesktopDisplay, Scr->NoCursor, CurrentTime);
954 /* djhjr - 4/27/98 */
958 /* find the window by looking at the context on the little window */
959 if ((moving_window != Scr->VirtualDesktopDScreen) &&
960 (XFindContext(dpy, moving_window, VirtualContext,
961 (caddr_t *) &moving_twindow) == XCNOENT)) {
962 /* i don't think that this should _ever_ happen */
963 moving_window = None;
964 moving_twindow = NULL;
968 /* use Junk globals - djhjr - 4/28/98 */
969 XGetGeometry(dpy, moving_window, &JunkChild, &xoff, &yoff,
970 &moving_w, &moving_h, &moving_bw, &JunkMask);
972 moving_off_x = moving_off_y = 0;
973 if ( xoff <= moving_x && moving_x <= ( xoff + moving_w )
974 && yoff <= moving_y && moving_y <= ( yoff + moving_h ))
975 { /* The pointer is IN the window.
976 ** don't start by moving the window so its upper-left is at
979 moving_off_x = xoff - moving_x;
980 moving_off_y = yoff - moving_y;
984 /* djhjr - 4/28/98 */
985 XMapRaised(dpy, Scr->SizeWindow);
986 InstallRootColormap();
987 if (moving_window == Scr->VirtualDesktopDScreen)
991 XGetGeometry(dpy, moving_twindow->frame, &JunkChild, &JunkX, &JunkY,
992 &JunkWidth, &JunkHeight, &JunkBW, &JunkMask);
994 /* djhjr - 9/28/99 */
996 int hilite = moving_twindow->highlight;
998 moving_twindow->highlight = True;
999 SetBorder(moving_twindow, (hilite) ? True : False);
1000 moving_twindow->highlight = hilite;
1002 Scr->Focus = moving_twindow; /* evil */
1004 EventHandler[EnterNotify] = HandleUnknown;
1005 EventHandler[LeaveNotify] = HandleUnknown;
1008 /* djhjr - 10/2/02 */
1009 if (Scr->VirtualSendsMotionEvents &&
1010 (moving_window != Scr->VirtualDesktopDScreen && !moving_twindow->opaque_move))
1011 MoveOutline(Scr->Root,
1013 moving_twindow->frame_width,
1014 moving_twindow->frame_height,
1015 moving_twindow->frame_bw,
1016 moving_twindow->title_height + moving_twindow->frame_bw3D);
1020 /* added 'original_? = ' - djhjr - 11/3/03 */
1021 original_x = JunkX + Scr->VirtualDesktopX;
1022 original_y = JunkY + Scr->VirtualDesktopY;
1023 DisplayPosition(original_x, original_y);
1025 /* get things going */
1026 DoMoveWindowOnDesktop(ev.x, ev.y);
1029 void DoMoveWindowOnDesktop(x, y)
1036 * cancel the effects of scaling errors by skipping the code
1037 * if nothing is actually moved - djhjr - 4/27/98
1039 if (x == starting_x && y == starting_y)
1042 /* djhjr - 2/7/99 */
1043 x -= Scr->VirtualDesktopBevelWidth;
1044 y -= Scr->VirtualDesktopBevelWidth;
1048 /* check that we are legit */
1053 /* added real screen's border!? - djhjr - 2/15/99 */
1054 int np = ( Scr->VirtualDesktopWidth /
1055 Scr->VirtualDesktopDScale ) - moving_w -
1056 Scr->RealScreenBorderWidth * 2;
1058 /* RFB 4/92 no SCALE_D */
1066 /* added real screen's border!? - djhjr - 2/15/99 */
1067 int np = ( Scr->VirtualDesktopHeight /
1068 Scr->VirtualDesktopDScale ) - moving_h -
1069 Scr->RealScreenBorderWidth * 2;
1071 /* RFB 4/92 no SCALE_D */
1079 /* move the display window */
1080 /* removed '- moving_bw' - djhjr - 2/15/99 */
1081 XMoveWindow(dpy, moving_window, x/* - moving_bw*/, y/* - moving_bw*/);
1083 /* djhjr - 4/28/98 */
1084 DisplayPosition(SCALE_U(x), SCALE_U(y));
1086 /* nah... it's pretty easy! - djhjr - 4/17/98
1087 * move the real window *
1088 * this is very difficult on anything not very powerful *
1089 * XMoveWindow(dpy, moving_twindow->frame, SCALE_U(x), SCALE_U(y)); *
1091 if (Scr->VirtualSendsMotionEvents)
1092 if (moving_window != Scr->VirtualDesktopDScreen)
1094 if (moving_twindow->opaque_move)
1095 XMoveWindow(dpy, moving_twindow->frame,
1096 SCALE_U(x) - Scr->VirtualDesktopX,
1097 SCALE_U(y) - Scr->VirtualDesktopY);
1099 MoveOutline(Scr->Root,
1100 SCALE_U(x) - Scr->VirtualDesktopX,
1101 SCALE_U(y) - Scr->VirtualDesktopY,
1102 moving_twindow->frame_width,
1103 moving_twindow->frame_height,
1104 moving_twindow->frame_bw,
1105 moving_twindow->title_height + moving_twindow->frame_bw3D);
1107 /* djhjr - 9/28/99 */
1108 Scr->Focus = moving_twindow; /* evil */
1112 void EndMoveWindowOnDesktop()
1117 /* djhjr - 4/28/98 */
1118 XUnmapWindow(dpy, Scr->SizeWindow);
1119 UninstallRootColormap();
1121 if (moving_window == Scr->VirtualDesktopDScreen) {
1122 /* added '(Cancel) ? ... :' - djhjr - 11/3/03 */
1123 SetRealScreen((Cancel) ? original_x : SCALE_U(moving_x),/* - moving_bw,*/
1124 (Cancel) ? original_y : SCALE_U(moving_y) /*- moving_bw*/ );
1126 /* djhjr - 4/17/98 10/2/02 */
1127 if (Scr->VirtualSendsMotionEvents &&
1128 (moving_window != Scr->VirtualDesktopDScreen && !moving_twindow->opaque_move))
1129 /* erase the move outline */
1130 MoveOutline(Scr->Root, 0, 0, 0, 0, 0, 0);
1132 /* same little check as at the top of DoMoveWindowOnDesktop() - djhjr - 4/27/98 */
1133 if (moving_x != starting_x || moving_y != starting_y)
1135 /* move the window in virtual space */
1136 /* added '(Cancel) ? ... :' - djhjr - 11/3/03 */
1137 moving_twindow->virtual_frame_x =
1138 (Cancel) ? original_x : SCALE_U(moving_x);
1139 moving_twindow->virtual_frame_y =
1140 (Cancel) ? original_y : SCALE_U(moving_y);
1142 /* move it in real space */
1143 moving_twindow->frame_x = V_TO_R_X(moving_twindow->virtual_frame_x);
1144 moving_twindow->frame_y = V_TO_R_Y(moving_twindow->virtual_frame_y);
1146 /* djhjr - 11/3/03 */
1148 XMoveWindow(dpy, moving_window,
1149 SCALE_D(original_x), SCALE_D(original_y));
1151 XMoveWindow(dpy, moving_twindow->frame,
1152 moving_twindow->frame_x, moving_twindow->frame_y);
1154 /* notify the window */
1155 SendConfigureNotify(moving_twindow,
1156 moving_twindow->frame_x, moving_twindow->frame_y);
1159 /* djhjr - 9/28/99 */
1161 int hilite = moving_twindow->highlight;
1163 moving_twindow->highlight = True;
1164 SetBorder(moving_twindow, False);
1165 moving_twindow->highlight = hilite;
1167 Scr->Focus = NULL; /* evil */
1169 EventHandler[EnterNotify] = HandleEnterNotify;
1170 EventHandler[LeaveNotify] = HandleLeaveNotify;
1173 /* added '!Cancel &&' - djhjr - 11/3/03 */
1174 if (!Cancel && !Scr->NoRaiseMove) {
1175 XRaiseWindow(dpy, moving_twindow->frame);
1176 XRaiseWindow(dpy, moving_twindow->VirtualDesktopDisplayWindow);
1178 RaiseStickyAbove(); /* DSE */
1182 /* djhjr - 6/4/98 */
1183 if (Scr->VirtualSendsMotionEvents && !moving_twindow->opaque_move)
1185 XUnmapWindow(dpy, Scr->VirtualDesktopDisplay);
1186 XMapWindow(dpy, Scr->VirtualDesktopDisplay);
1189 moving_window = None;
1193 moving_window = None;
1194 moving_twindow = NULL;
1197 /* Stig Ostholm <ostholm%ce.chalmers.se@uunet>
1198 * move and resize a window on the desktop.
1200 void MoveResizeDesktop(tmp_win, noraise)
1206 if (!tmp_win->VirtualDesktopDisplayWindow
1211 GetDesktopWindowCoordinates(tmp_win, &x, &y, &w, &h);
1212 /* Resize the desktop representation window */
1213 XMoveResizeWindow(dpy, tmp_win->VirtualDesktopDisplayWindow,
1216 XRaiseWindow(dpy, tmp_win->VirtualDesktopDisplayWindow);
1219 void SetVirtualDesktop(geom, scale)
1225 twmrc_error_prefix();
1226 fprintf(stderr, "VirtualDesktop already defined -- ignored.\n");
1231 twmrc_error_prefix();
1233 "VirtualDesktop scale must be positive, not %d\n", scale);
1236 Scr->VirtualDesktopDScale = scale;
1238 JunkMask = XParseGeometry (geom, &JunkX, &JunkY, &JunkWidth, &JunkHeight);
1240 if ((JunkMask & (WidthValue | HeightValue)) !=
1241 (WidthValue | HeightValue)) {
1242 twmrc_error_prefix();
1243 fprintf (stderr, "bad VirtualDesktop \"%s\"\n", geom);
1246 if (JunkWidth <= 0 || JunkHeight <= 0) {
1247 twmrc_error_prefix();
1248 fprintf (stderr, "VirtualDesktop \"%s\" must be positive\n", geom);
1253 * More flexible way of selecting size of virtual desktop (ala tvtwm)
1254 * M.J.E. Mol marcel@duteca.et.tudelft.nl
1256 if (JunkWidth > Scr->MyDisplayWidth)
1257 /* specified as total pixels */
1258 JunkWidth /= Scr->VirtualDesktopDScale;
1259 else if (JunkWidth*Scr->VirtualDesktopDScale < Scr->MyDisplayWidth) {
1260 /* specified as number of physical screens */
1261 JunkWidth *= Scr->MyDisplayWidth;
1262 JunkWidth /= Scr->VirtualDesktopDScale;
1264 /* else specified as size of panner window */
1266 if (JunkHeight > Scr->MyDisplayHeight)
1267 /* specified as total pixels */
1268 JunkHeight /= Scr->VirtualDesktopDScale;
1269 else if (JunkHeight*Scr->VirtualDesktopDScale < Scr->MyDisplayHeight) {
1270 /* specified as number of physical screens */
1271 JunkHeight *= Scr->MyDisplayHeight;
1272 JunkHeight /= Scr->VirtualDesktopDScale;
1274 /* else specified as size of panner window */
1276 /* tar@math.ksu.edu: fix handling of -0 X and Y geometry */
1277 /* account for VirtualDesktopBevelWidth - djhjr - 9/26/01 */
1278 if (JunkMask & XValue) {
1279 if (JunkMask & XNegative) {
1280 Scr->VirtualDesktopDX = Scr->MyDisplayWidth
1281 - JunkWidth - (2 * Scr->BorderWidth)
1282 - (2 * Scr->VirtualDesktopBevelWidth) + JunkX;
1284 else Scr->VirtualDesktopDX = JunkX;
1286 if (JunkMask & YValue) {
1287 if (JunkMask & YNegative) {
1288 Scr->VirtualDesktopDY = Scr->MyDisplayHeight
1289 - JunkHeight - (2 * Scr->BorderWidth)
1290 - (2 * Scr->VirtualDesktopBevelWidth) + JunkY;
1292 else Scr->VirtualDesktopDY = JunkY;
1295 JunkWidth *= Scr->VirtualDesktopDScale;
1296 JunkHeight *= Scr->VirtualDesktopDScale;
1298 /* check that the vd is at least as big as the screen */
1299 /* handled above, M.J.E. Mol
1300 ** if ((JunkWidth < Scr->MyDisplayWidth)
1301 ** || (JunkHeight < Scr->MyDisplayHeight))
1303 ** twmrc_error_prefix();
1305 ** "VirtualDesktop must be larger than screen (%dx%d)\n",
1306 ** Scr->MyDisplayWidth, Scr->MyDisplayHeight);
1310 Scr->VirtualDesktopWidth = JunkWidth;
1311 Scr->VirtualDesktopHeight = JunkHeight;
1313 /* all of the values looked reasonable */
1314 Scr->Virtual = TRUE;
1317 void VirtualMoveWindow(t, x, y)
1324 /* move window in virtual space */
1325 t->virtual_frame_x = x;
1326 t->virtual_frame_y = y;
1328 /* move it in real space */
1329 t->frame_x = V_TO_R_X(x);
1330 t->frame_y = V_TO_R_Y(y);
1332 XMoveWindow(dpy, t->frame,
1333 t->frame_x, t->frame_y);
1335 /* update the display */
1336 /* UpdateDesktop(t); Stig */
1337 MoveResizeDesktop(t, FALSE); /* Stig */
1339 if (!Scr->NoRaiseMove) {
1340 XRaiseWindow(dpy, t->frame);
1341 /* XRaiseWindow(dpy, t->VirtualDesktopDisplayWindow); Stig */
1343 RaiseStickyAbove(); /* DSE */
1350 * for Kevin Twidle <kpt@doc.ic.ac.uk>
1351 * this snaps the real screen to a grid defined by the pandistance values.
1353 void SnapRealScreen()
1358 mod = Scr->VirtualDesktopX % Scr->VirtualDesktopPanDistanceX;
1359 div = Scr->VirtualDesktopX / Scr->VirtualDesktopPanDistanceX;
1361 if (mod > (Scr->VirtualDesktopPanDistanceX / 2))
1362 newx = Scr->VirtualDesktopPanDistanceX * (div + 1);
1364 newx = Scr->VirtualDesktopPanDistanceX * div;
1366 mod = Scr->VirtualDesktopY % Scr->VirtualDesktopPanDistanceY;
1367 div = Scr->VirtualDesktopY / Scr->VirtualDesktopPanDistanceY;
1369 if (mod > (Scr->VirtualDesktopPanDistanceY / 2))
1370 newy = Scr->VirtualDesktopPanDistanceY * (div + 1);
1372 newy = Scr->VirtualDesktopPanDistanceY * div;
1374 SetRealScreenInternal(newx, newy, FALSE, NULL, NULL); /* DSE */
1378 void SetRealScreen(x, y)
1381 if (Scr->snapRealScreen)
1382 SetRealScreenInternal(x, y, TRUE, NULL, NULL); /* DSE */
1384 SetRealScreenInternal(x, y, FALSE, NULL, NULL); /* DSE */
1388 * handles the possibility of snapping
1390 void SetRealScreenInternal(x, y, dosnap, dx, dy)
1392 int *dx, *dy; /* a pointer to an integer that contains the value
1393 (AutoPanBorderWidth + AutoPanExtraWarp) is passed in to
1394 both dx and dy when autopanning, or NULL is passed. On
1395 return, the value is modified to store how much the pointer
1396 should actually be warped, in case
1397 AutoPanWarpWithRespectToRealScreen is nonzero. -- DSE */
1406 if (x > (Scr->VirtualDesktopWidth - Scr->MyDisplayWidth))
1407 x = Scr->VirtualDesktopWidth - Scr->MyDisplayWidth;
1408 if (y > (Scr->VirtualDesktopHeight - Scr->MyDisplayHeight))
1409 y = Scr->VirtualDesktopHeight - Scr->MyDisplayHeight;
1411 /* if ( Scr->RealScreenBorderWidth ) */
1416 /* how big a move is this ? */
1417 xdiff = Scr->VirtualDesktopX - x;
1418 ydiff = Scr->VirtualDesktopY - y;
1421 /* calculate how much we might warp the pointer */
1422 int x_warp = ((xdiff<0) ? -1 : 1) *
1423 ((50 + abs(xdiff) * Scr->AutoPanWarpWithRespectToRealScreen) / 100);
1424 int y_warp = ((ydiff<0) ? -1 : 1) *
1425 ((50 + abs(ydiff) * Scr->AutoPanWarpWithRespectToRealScreen) / 100);
1427 /* make sure the pointer warps enought with respect to the real screen
1428 so that it can get out of the autopan windows. */
1430 if ( abs (*dx) < abs(x_warp) ) *dx = x_warp;
1432 if ( abs (*dx) < abs(y_warp) ) *dy = y_warp;
1435 /* make sure it isn't warped too much in case ``AutoPan 100'' and
1436 ``AutoPanWarpWithRespectToRealScreen 100'' (also known as
1437 ``NaturalAutopanBehavior'') are set. -- DSE */
1439 int max_x_warp = ((xdiff<0) ? -1 : 1) *
1440 (Scr->MyDisplayWidth - 2 * Scr->AutoPanBorderWidth);
1441 int max_y_warp = ((ydiff<0) ? -1 : 1) *
1442 (Scr->MyDisplayHeight - 2 * Scr->AutoPanBorderWidth);
1444 if ( abs(*dx) > abs(max_x_warp) ) *dx = max_x_warp;
1446 if ( abs(*dy) > abs(max_y_warp) ) *dy = max_y_warp;
1449 /* move all of the windows by walking the twm list */
1450 for (Tmp_win = Scr->TwmRoot.next; Tmp_win != NULL; Tmp_win = Tmp_win->next)
1452 if (Scr->StaticIconPositions && Tmp_win->icon && Tmp_win->icon_w)
1455 * Make icons "stay put" on the virtual desktop when
1456 * not otherwise nailed - djhjr - 12/14/98
1458 XGetGeometry(dpy, Tmp_win->icon_w, &JunkRoot, &JunkX, &JunkY,
1459 &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth);
1461 XMoveWindow(dpy, Tmp_win->icon_w,
1462 JunkX + xdiff, JunkY + ydiff);
1465 if (Tmp_win->nailed || (Scr->DeIconifyToScreen && Tmp_win->icon))
1468 * The window is nailed or...
1469 * The window is currently an icon, we are trying to
1470 * keep things on the screen, so move it around the
1471 * virtual desktop so that it stays on the real screen
1473 Tmp_win->virtual_frame_x -= xdiff;
1474 Tmp_win->virtual_frame_y -= ydiff;
1481 Tmp_win->frame_x += xdiff;
1482 Tmp_win->frame_y += ydiff;
1486 XMoveWindow(dpy, Tmp_win->frame,
1487 Tmp_win->frame_x, Tmp_win->frame_y);
1488 SendConfigureNotify(Tmp_win,
1489 Tmp_win->frame_x, Tmp_win->frame_y);
1494 Scr->VirtualDesktopX = x;
1495 Scr->VirtualDesktopY = y;
1500 DisplayScreenOnDesktop();
1504 * pan the real screen on the virtual desktop by (xoff, yoff)
1506 void PanRealScreen(xoff, yoff, dx, dy)
1508 int *dx, *dy; /* DSE */
1510 /* panning the screen can never mean that you need to snap */
1511 SetRealScreenInternal(Scr->VirtualDesktopX + xoff, Scr->VirtualDesktopY + yoff,
1512 /* why not? - djhjr - 1/24/98
1515 Scr->snapRealScreen, dx, dy);
1520 * raise the auto-pan windows if needed
1526 if (Scr->AutoPanX > 0)
1527 for (i = 0; i <= 3; i++)
1528 XRaiseWindow(dpy, Scr->VirtualDesktopAutoPan[i]);
1532 * Raise sticky windows if StickyAbove is set. -- DSE
1535 void RaiseStickyAbove () {
1536 if (Scr->StickyAbove) {
1538 for (Tmp_win = Scr->TwmRoot.next; Tmp_win != NULL;
1539 Tmp_win = Tmp_win->next)
1540 if (Tmp_win->nailed) {
1541 XRaiseWindow(dpy,Tmp_win->w);
1542 XRaiseWindow(dpy,Tmp_win->VirtualDesktopDisplayWindow);
1543 XRaiseWindow(dpy,Tmp_win->frame);
1549 * Lower sticky windows. -- DSE
1552 void LowerSticky () {
1554 for (Tmp_win = Scr->TwmRoot.next; Tmp_win != NULL;
1555 Tmp_win = Tmp_win->next)
1556 if (Tmp_win->nailed) {
1557 XLowerWindow(dpy,Tmp_win->w);
1558 XLowerWindow(dpy,Tmp_win->VirtualDesktopDisplayWindow);
1559 XLowerWindow(dpy,Tmp_win->frame);