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 extern void SetRealScreenInternal();
30 extern void SetRealScreen();
31 extern void SnapRealScreen();
32 extern void SetMapStateProp();
33 extern void twmrc_error_prefix();
35 void SetVirtualPixmap();
36 void SetRealScreenPixmap();
39 static int starting_x, starting_y;
42 static int original_x, original_y;
44 static void GetDesktopWindowCoordinates(tmp_win, x, y, w, h)
49 int border = tmp_win->frame_bw + tmp_win->frame_bw3D;
51 /* Stig Ostholm <ostholm%ce.chalmers.se@uunet> */
54 *x = tmp_win->frame_x / Scr->VirtualDesktopDScale;
56 /* *y = tmp_win->virtual_frame_y / Scr->VirtualDesktopDScale; */
57 *y = tmp_win->frame_y / Scr->VirtualDesktopDScale; /* DSE */
58 /* RFB 4/92 no SCALE_D */
59 /* *x = SCALE_D(tmp_win->virtual_frame_x); */
60 /* *y = SCALE_D(tmp_win->virtual_frame_y); */
63 *x = tmp_win->virtual_frame_x / Scr->VirtualDesktopDScale;
65 *y = tmp_win->virtual_frame_y / Scr->VirtualDesktopDScale;
66 /* RFB 4/92 no SCALE_D */
67 /* *x = SCALE_D(tmp_win->virtual_frame_x); */
68 /* *y = SCALE_D(tmp_win->virtual_frame_y); */
73 tmp_win->frame_width + Scr->VirtualDesktopDScale / 2
76 + tmp_win->frame_bw + tmp_win->frame_bw )
81 if ( *w <= 0 ) *w = 1; /* 4/92 RFB */
86 tmp_win->frame_height + Scr->VirtualDesktopDScale / 2
88 /* + tmp_win->title_height */
92 + tmp_win->frame_bw + tmp_win->frame_bw ) - 2;
96 /* 4/92 RFB -- subtract borderwidth from windowwidth... */
97 if ( *h <= 0 ) *h = 1; /* 4/92 RFB */
99 } /* Stig Ostholm <ostholm%ce.chalmers.se@uunet> */
103 * create the virtual desktop display and store the window in the screen structure
105 void CreateDesktopDisplay()
110 /* djhjr - 5/17/98 */
111 #ifndef ORIGINAL_PIXMAPS
115 XSetWindowAttributes attributes; /* attributes for create windows */
116 unsigned long valuemask;
117 unsigned int pm_numcolors;
123 width = Scr->VirtualDesktopWidth / Scr->VirtualDesktopDScale;
124 height = Scr->VirtualDesktopHeight / Scr->VirtualDesktopDScale;
126 /* done in SetVirtualDesktop() - djhjr - 9/26/01
127 * we have some checking for negative (x,y) to do *
128 if (Scr->VirtualDesktopDX < 0) {
129 Scr->VirtualDesktopDX = Scr->MyDisplayWidth - width -
130 (2 * Scr->BorderWidth) + Scr->VirtualDesktopDX;
132 if (Scr->VirtualDesktopDY < 0) {
133 Scr->VirtualDesktopDY = Scr->MyDisplayHeight - height -
134 (2 * Scr->BorderWidth) + Scr->VirtualDesktopDY;
138 Scr->VirtualDesktopDisplayOuter =
139 XCreateSimpleWindow(dpy, Scr->Root,
140 Scr->VirtualDesktopDX, Scr->VirtualDesktopDY,
145 width + (Scr->VirtualDesktopBevelWidth * 2),
146 height + (Scr->VirtualDesktopBevelWidth * 2),
148 /* was 'Scr->BorderWidth' - submitted by Rolf Neugebauer */
151 Scr->Black, Scr->VirtualDesktopDisplayC.back);
155 XSetWindowAttributes attr;
157 attr.backing_store = True;
158 XChangeWindowAttributes(dpy, Scr->VirtualDesktopDisplayOuter,
159 CWBackingStore, &attr);
162 if ( width != Scr->VirtualDesktopMaxWidth )
163 Scr->VirtualDesktopMaxWidth = width;
164 if ( height != Scr->VirtualDesktopMaxHeight )
165 Scr->VirtualDesktopMaxHeight = height;
166 /* vtwm 5.2: RFB growable but not unreasonable interior window! */
169 * re-written to use an Image structure for XPM support
173 #ifdef ORIGINAL_PIXMAPS
174 Scr->VirtualDesktopDisplay =
175 XCreateSimpleWindow(dpy, Scr->VirtualDesktopDisplayOuter,
180 Scr->VirtualDesktopBevelWidth,
181 Scr->VirtualDesktopBevelWidth,
183 Scr->VirtualDesktopMaxWidth,
184 Scr->VirtualDesktopMaxHeight,
186 Scr->VirtualDesktopDisplayBorder,
187 Scr->VirtualC.back);/*RFB VCOLOR*/
189 XDefineCursor( dpy, Scr->VirtualDesktopDisplay,
190 Scr->VirtualCursor ); /*RFBCURSOR*/
192 if ( Scr->virtualPm ) /*RFB PIXMAP*/
193 { /* Background pixmap, copied from tvtwm */
198 pm = XCreatePixmap( dpy, Scr->VirtualDesktopDisplay,
199 Scr->virtual_pm_width, Scr->virtual_pm_height,
201 gcv.foreground = Scr->VirtualC.fore;
202 gcv.background = Scr->VirtualC.back;
203 gcv.graphics_exposures = False;
204 gc = XCreateGC (dpy, Scr->Root,
205 (GCForeground|GCBackground|GCGraphicsExposures),
209 XCopyPlane (dpy, Scr->virtualPm, pm, gc, 0, 0,
210 Scr->virtual_pm_width, Scr->virtual_pm_height,
213 XSetWindowBackgroundPixmap( dpy, Scr->VirtualDesktopDisplay,
215 XClearWindow( dpy, Scr->VirtualDesktopDisplay );
217 XFreePixmap (dpy, pm);
219 #else /* ORIGINAL_PIXMAPS */
222 /* djhjr - 5/23/98 9/2/98 */
223 #ifndef NO_XPM_SUPPORT
225 pm_numcolors = SetPixmapsBackground(Scr->virtualPm, Scr->Root,
229 if (pm_numcolors > 2) /* not a bitmap */
231 valuemask = CWBackPixmap;
232 attributes.background_pixmap = Scr->virtualPm->pixmap;
234 Scr->VirtualDesktopDisplay = XCreateWindow(dpy,
235 Scr->VirtualDesktopDisplayOuter,
240 Scr->VirtualDesktopBevelWidth,
241 Scr->VirtualDesktopBevelWidth,
243 Scr->VirtualDesktopMaxWidth,
244 Scr->VirtualDesktopMaxHeight,
246 Scr->d_depth, (unsigned int) CopyFromParent,
247 Scr->d_visual, valuemask, &attributes);
251 Scr->VirtualDesktopDisplay = XCreateSimpleWindow(dpy,
252 Scr->VirtualDesktopDisplayOuter,
257 Scr->VirtualDesktopBevelWidth,
258 Scr->VirtualDesktopBevelWidth,
260 Scr->VirtualDesktopMaxWidth,
261 Scr->VirtualDesktopMaxHeight,
263 Scr->VirtualDesktopDisplayBorder,
264 Scr->VirtualC.back); /*RFB VCOLOR*/
268 pm = XCreatePixmap( dpy, Scr->VirtualDesktopDisplay,
269 Scr->virtualPm->width, Scr->virtualPm->height,
272 gcv.foreground = Scr->VirtualC.fore;
273 gcv.background = Scr->VirtualC.back;
274 gcv.graphics_exposures = False;
276 gc = XCreateGC(dpy, Scr->Root,
277 (GCForeground | GCBackground | GCGraphicsExposures),
282 XCopyPlane(dpy, Scr->virtualPm->pixmap, pm, gc, 0, 0,
283 Scr->virtualPm->width, Scr->virtualPm->height,
288 XSetWindowBackgroundPixmap(dpy, Scr->VirtualDesktopDisplay, pm);
290 XClearWindow(dpy, Scr->VirtualDesktopDisplay);
293 XFreePixmap(dpy, pm);
297 XDefineCursor(dpy, Scr->VirtualDesktopDisplay, Scr->VirtualCursor); /*RFB CURSOR */
298 #endif /* ORIGINAL_PIXMAPS */
300 XSetStandardProperties(dpy, Scr->VirtualDesktopDisplayOuter,
303 "Virtual Desktop", "Virtual Desktop",
306 "VTWM Desktop", "VTWM Desktop",
308 VTWM_DESKTOP_CLASS, VTWM_DESKTOP_CLASS,
310 None, NULL, 0, NULL);
312 /* Stig Ostholm moved a few lines away from here */
316 if ( Scr->UseRealScreenBorder )
319 border = Scr->RealScreenBorderWidth; * DSE *
322 border = Scr->RealScreenBorderWidth;
325 * re-written to use an Image structure for XPM support
329 #ifdef ORIGINAL_PIXMAPS
330 /* create the real screen display */
331 Scr->VirtualDesktopDScreen =
332 XCreateSimpleWindow(dpy, Scr->VirtualDesktopDisplay,
336 SCALE_D(Scr->MyDisplayWidth - 2 * border),
337 SCALE_D(Scr->MyDisplayHeight - 2 * border),
339 SCALE_D(Scr->MyDisplayWidth) - 2 * border,
340 SCALE_D(Scr->MyDisplayHeight) - 2 * border,
342 border, /* make it distinctive */
343 /* RFB 4/92: make borderwidth 0 instead of 2 */
344 /* RFB 5.2: some people need the border... */
345 Scr->VirtualDesktopDisplayBorder,
346 Scr->RealScreenC.back ); /* RFB 4/92 */
348 if ( Scr->RealScreenPm ) /*RFB PIXMAP*/
349 { /* Background pixmap */
354 pm = XCreatePixmap( dpy, Scr->VirtualDesktopDScreen,
355 Scr->RealScreen_pm_width, Scr->RealScreen_pm_height,
357 gcv.foreground = Scr->RealScreenC.fore;
358 gcv.background = Scr->RealScreenC.back;
359 gcv.graphics_exposures = False;
360 gc = XCreateGC (dpy, Scr->Root,
361 (GCForeground|GCBackground|GCGraphicsExposures),
365 XCopyPlane (dpy, Scr->RealScreenPm, pm, gc, 0, 0,
366 Scr->RealScreen_pm_width, Scr->RealScreen_pm_height,
369 XSetWindowBackgroundPixmap( dpy, Scr->VirtualDesktopDScreen,
371 XClearWindow( dpy, Scr->VirtualDesktopDScreen );
373 XFreePixmap (dpy, pm);
375 #else /* ORIGINAL_PIXMAPS */
378 /* djhjr - 5/23/98 9/2/98 */
379 #ifndef NO_XPM_SUPPORT
380 if (Scr->realscreenPm)
381 pm_numcolors = SetPixmapsBackground(Scr->realscreenPm,
382 Scr->Root, Scr->RealScreenC.back);
385 if (pm_numcolors > 2) /* not a bitmap */
387 valuemask = CWBackPixmap | CWBorderPixel;
388 attributes.background_pixmap = Scr->realscreenPm->pixmap;
389 attributes.border_pixel = Scr->VirtualDesktopDisplayBorder;
391 Scr->VirtualDesktopDScreen = XCreateWindow(dpy,
392 Scr->VirtualDesktopDisplay,
396 SCALE_D(Scr->MyDisplayWidth - 2 * border),
397 SCALE_D(Scr->MyDisplayHeight - 2 * border),
399 SCALE_D(Scr->MyDisplayWidth) - 2 * border,
400 SCALE_D(Scr->MyDisplayHeight) - 2 * border,
403 Scr->d_depth, (unsigned int) CopyFromParent,
404 Scr->d_visual, valuemask, &attributes);
408 Scr->VirtualDesktopDScreen = XCreateSimpleWindow(dpy,
409 Scr->VirtualDesktopDisplay,
413 SCALE_D(Scr->MyDisplayWidth - 2 * border),
414 SCALE_D(Scr->MyDisplayHeight - 2 * border),
416 SCALE_D(Scr->MyDisplayWidth) - 2 * border,
417 SCALE_D(Scr->MyDisplayHeight) - 2 * border,
419 border, /* make it distinctive */
420 /* RFB 4/92: make borderwidth 0 instead of 2 */
421 /* RFB 5.2: some people need the border... */
422 Scr->VirtualDesktopDisplayBorder,
423 Scr->RealScreenC.back ); /* RFB 4/92 */
425 if (Scr->realscreenPm)
427 pm = XCreatePixmap(dpy, Scr->VirtualDesktopDScreen,
428 Scr->realscreenPm->width, Scr->realscreenPm->height,
431 gcv.foreground = Scr->RealScreenC.fore;
432 gcv.background = Scr->RealScreenC.back;
433 gcv.graphics_exposures = False;
435 gc = XCreateGC(dpy, Scr->Root,
436 (GCForeground | GCBackground | GCGraphicsExposures),
441 XCopyPlane(dpy, Scr->realscreenPm->pixmap, pm, gc, 0, 0,
442 Scr->realscreenPm->width, Scr->realscreenPm->height,
447 XSetWindowBackgroundPixmap(dpy, Scr->VirtualDesktopDScreen, pm);
449 XClearWindow(dpy, Scr->VirtualDesktopDScreen);
452 XFreePixmap(dpy, pm);
455 #endif /* ORIGINAL_PIXMAPS */
457 /* declare our interest */
458 XSelectInput(dpy, Scr->VirtualDesktopDisplay, ButtonPressMask | ButtonReleaseMask |
459 KeyPressMask | KeyReleaseMask | ExposureMask);
461 /* Stig Ostholm moved some lines to here: */
462 Scr->VirtualDesktopDisplayTwin =
463 AddWindow(Scr->VirtualDesktopDisplayOuter, FALSE, NULL);
465 /* djhjr - 5/19/98 */
466 Scr->VirtualDesktopDisplayTwin->class.res_name = strdup(VTWM_DESKTOP_CLASS);
467 Scr->VirtualDesktopDisplayTwin->class.res_class = strdup(VTWM_DESKTOP_CLASS);
468 XSetClassHint(dpy, Scr->VirtualDesktopDisplayOuter, &Scr->VirtualDesktopDisplayTwin->class);
470 /* limit the minimum size of the virtual desktop - djhjr - 2/23/99 */
471 Scr->VirtualDesktopDisplayTwin->hints.flags |= PMinSize;
472 Scr->VirtualDesktopDisplayTwin->hints.min_width =
473 SCALE_D(Scr->MyDisplayWidth) + (Scr->VirtualDesktopBevelWidth * 2);
474 Scr->VirtualDesktopDisplayTwin->hints.min_height =
475 SCALE_D(Scr->MyDisplayHeight) + (Scr->VirtualDesktopBevelWidth * 2);
478 /* this is a gross hack, but people wanted it */
479 Scr->VirtualDesktopDisplayTwin->nailed = TRUE;
480 #endif /* GROSS_HACK */
482 SetMapStateProp(Scr->VirtualDesktopDisplayTwin, NormalState);
483 /* :ereh ot senil emos devom mlohtsO gitS */
485 /* position the representation */
486 DisplayScreenOnDesktop();
489 XMapWindow(dpy, Scr->VirtualDesktopDScreen);
490 XMapWindow(dpy, Scr->VirtualDesktopDisplay);
491 XMapWindow(dpy, Scr->VirtualDesktopDisplayOuter);
493 /* create the autopan windows if we are doing this */
494 if (Scr->AutoPanX > 0) {
498 Scr->VirtualDesktopAutoPan[0] = XCreateWindow(dpy, Scr->Root,
502 Scr->MyDisplayHeight,
509 Scr->VirtualDesktopAutoPan[1] = XCreateWindow(dpy, Scr->Root,
510 Scr->MyDisplayWidth - AP_SIZE,
513 Scr->MyDisplayHeight,
520 Scr->VirtualDesktopAutoPan[2] = XCreateWindow(dpy, Scr->Root,
531 Scr->VirtualDesktopAutoPan[3] = XCreateWindow(dpy, Scr->Root,
533 Scr->MyDisplayHeight - AP_SIZE,
542 /* set the event masks on the windows */
543 for(l = 0; l <= 3; l++) {
544 XSetStandardProperties(dpy, Scr->VirtualDesktopAutoPan[l],
545 "Automatic Pan", "Automatic Pan",
546 None, NULL, 0, NULL);
549 * Added the leave event for pan resistance -
550 * see events.c:HandleEnterNotify().
554 XSelectInput(dpy, Scr->VirtualDesktopAutoPan[l],
555 EnterWindowMask | LeaveWindowMask);
557 XMapWindow(dpy, Scr->VirtualDesktopAutoPan[l]);
560 } /* end if Scr->AutoPan */
564 * re-written to use an Image structure for XPM support
568 #ifdef ORIGINAL_PIXMAPS
569 void SetVirtualPixmap (filename)
572 Pixmap pm = GetBitmap (filename);
575 if (Scr->virtualPm) {
576 XFreePixmap (dpy, Scr->virtualPm);
579 Scr->virtual_pm_width = JunkWidth;
580 Scr->virtual_pm_height = JunkHeight;
583 #else /* ORIGINAL_PIXMAPS */
584 void SetVirtualPixmap (filename)
587 if (!Scr->virtualPm) Scr->virtualPm = SetPixmapsPixmap(filename);
589 #endif /* ORIGINAL_PIXMAPS */
592 * re-written to use an Image structure for XPM support
596 #ifdef ORIGINAL_PIXMAPS
597 void SetRealScreenPixmap (filename)
600 Pixmap pm = GetBitmap (filename);
603 if (Scr->RealScreenPm) {
604 XFreePixmap (dpy, Scr->RealScreenPm);
606 Scr->RealScreenPm = pm;
607 Scr->RealScreen_pm_width = JunkWidth;
608 Scr->RealScreen_pm_height = JunkHeight;
611 #else /* ORIGINAL_PIXMAPS */
612 void SetRealScreenPixmap (filename)
615 if (!Scr->realscreenPm) Scr->realscreenPm = SetPixmapsPixmap(filename);
617 #endif /* ORIGINAL_PIXMAPS */
620 * add this window to the virtual desktop - aka nail it
622 void UpdateDesktop(tmp_win)
625 int x, y, width, height;
631 if (!tmp_win->showindesktopdisplay)
635 XUnmapWindow(dpy, tmp_win->VirtualDesktopDisplayWindow);
639 GetDesktopWindowCoordinates(tmp_win, &x, &y, &width, &height);
640 /* Stig Ostholm <ostholm%ce.chalmers.se@uunet> these 3 lines */
641 dwindow = (tmp_win->nailed)
642 ? Scr->VirtualDesktopDScreen : Scr->VirtualDesktopDisplay;
644 /* if it already has a vd display window, just move it to the right place
645 and map it, else actually create the window */
646 if (!tmp_win->VirtualDesktopDisplayWindow) {
647 Pixel background, border;
650 if (!GetColorFromList(Scr->VirtualDesktopColorBL, tmp_win->full_name,
651 &tmp_win->class, &background) &&
652 !GetColorFromList(Scr->TitleBackgroundL, tmp_win->full_name,
653 &tmp_win->class, &background))
654 background = Scr->VirtualDesktopDisplayC.back;
656 background = tmp_win->virtual.back;
658 /* 7/10/90 - uses border list not foreground */
659 if(!GetColorFromList(Scr->VirtualDesktopColorBoL, tmp_win->full_name,
660 &tmp_win->class, &border) &&
661 !GetColorFromList(Scr->TitleForegroundL, tmp_win->full_name,
662 &tmp_win->class, &border))
663 border = Scr->VirtualDesktopDisplayBorder;
665 /* the position and size don't matter */
666 tmp_win->VirtualDesktopDisplayWindow =
667 XCreateSimpleWindow(dpy,
668 dwindow, x, y, width, height, /* Stig */
669 1, border, background);
671 /*RFBCURSOR*/XDefineCursor( dpy, tmp_win->VirtualDesktopDisplayWindow,
672 /*RFBCURSOR*/Scr->DesktopCursor );
674 /* listen for expose events to redraw the name */
675 if (Scr->NamesInVirtualDesktop)
676 XSelectInput(dpy, tmp_win->VirtualDesktopDisplayWindow,
679 /* save the twm window on the window */
680 XSaveContext(dpy, tmp_win->VirtualDesktopDisplayWindow,
681 VirtualContext, (caddr_t) tmp_win);
682 XSaveContext(dpy, tmp_win->VirtualDesktopDisplayWindow,
683 TwmContext, (caddr_t) tmp_win);
687 0 /* Stig Ostholm <ostholm%ce.chalmers.se@uunet> */
688 0 /* comment out this section */
690 0 /* unmap whilst we reconfigure it */
691 0 XUnmapWindow(dpy, tmp_win->VirtualDesktopDisplayWindow);
693 0 if (tmp_win->nailed) {
694 0 x = tmp_win->frame_x / Scr->VirtualDesktopDScale;
695 0 y = tmp_win->frame_y / Scr->VirtualDesktopDScale;
696 0/* RFB 4/92 no SCALE_D */
697 0 /* x = SCALE_D(tmp_win->frame_x); */
698 0 /* y = SCALE_D(tmp_win->frame_y); */
700 0 /* reparent this window into the little screen representation */
701 0 XReparentWindow(dpy, tmp_win->VirtualDesktopDisplayWindow,
702 0 Scr->VirtualDesktopDScreen, x, y);
704 0 x = tmp_win->virtual_frame_x / Scr->VirtualDesktopDScale;
705 0 y = tmp_win->virtual_frame_y / Scr->VirtualDesktopDScale;
706 0/* RFB 4/92 no SCALE_D */
707 0 /* x = SCALE_D(tmp_win->virtual_frame_x); */
708 0 /* y = SCALE_D(tmp_win->virtual_frame_y); */
710 0 XReparentWindow(dpy, tmp_win->VirtualDesktopDisplayWindow,
711 0 Scr->VirtualDesktopDisplay, x, y);
714 0 /* calculate the sizes and position */
716 0 tmp_win->frame_width + Scr->VirtualDesktopDScale / 2
717 0 + tmp_win->frame_bw + tmp_win->frame_bw )
720 0 tmp_win->frame_height + Scr->VirtualDesktopDScale / 2
722 0 /* + tmp_win->title_height */
724 0 + tmp_win->frame_bw + tmp_win->frame_bw ) - 2;
725 0/* 4/92 RFB -- subtract borderwidth from windowwidth... */
726 0 if ( width <= 0 ) width = 1; /* 4/92 RFB */
727 0 if ( height <= 0 ) height = 1; /* 4/92 RFB */
730 0 fprintf(stderr, "%d*%d+%d+%d\n", x, y, width, height);
733 0 /* move and size it */
734 0 XMoveWindow(dpy, tmp_win->VirtualDesktopDisplayWindow,
736 0 XResizeWindow(dpy, tmp_win->VirtualDesktopDisplayWindow,
739 } else { /* Unmapping is fixed by XReparentWindow */
740 XReparentWindow(dpy, tmp_win->VirtualDesktopDisplayWindow,
742 XResizeWindow(dpy, tmp_win->VirtualDesktopDisplayWindow,
746 XMapWindow(dpy, tmp_win->VirtualDesktopDisplayWindow);
750 0/* Stig Ostholm <ostholm%ce.chalmers.se@uunet> */
752 0 * remove a window from the desktop display - aka unnail it
754 0void RemoveFromDesktop(tmp_win)
763 0 if (tmp_win->VirtualDesktopDisplayWindow)
764 0 XUnmapWindow(dpy, tmp_win->VirtualDesktopDisplayWindow);
766 0 /* reparent its representation out of the real screen window */
767 0 x = tmp_win->virtual_frame_x /Scr->VirtualDesktopDScale;
768 0 y = tmp_win->virtual_frame_y / Scr->VirtualDesktopDScale;
769 0/* RFB 4/92 no SCALE_D */
770 0 /* x = SCALE_D(tmp_win->virtual_frame_x); */
771 0 /* y = SCALE_D(tmp_win->virtual_frame_y); */
773 0 XReparentWindow(dpy, tmp_win->VirtualDesktopDisplayWindow,
774 0 Scr->VirtualDesktopDisplay, x, y);
778 /* Stig Ostholm <ostholm%ce.chalmers.se@uunet>
779 * Nail/unnail a window on the desktop display.
781 void NailDesktop(tmp_win)
786 if (!tmp_win->VirtualDesktopDisplayWindow
791 GetDesktopWindowCoordinates(tmp_win, &x, &y, (int *) 0, (int *) 0);
792 XReparentWindow(dpy, tmp_win->VirtualDesktopDisplayWindow,
794 ? Scr->VirtualDesktopDScreen
795 : Scr->VirtualDesktopDisplay,
797 XMapWindow(dpy, tmp_win->VirtualDesktopDisplayWindow);
801 * state during the move
803 static unsigned int moving_x, moving_y, moving_w, moving_h, moving_bw;
804 static unsigned int moving_off_x, moving_off_y;
805 Window moving_window;
806 TwmWindow *moving_twindow;
808 /**********************************************************/
810 /* RFB 7/16/93 -- moved these static variables up to */
811 /* this part of the file so that I could use moving_bw */
812 /* in DisplayScreenOnDesktop(). */
814 /* Note that moving_bw is set to 0 if you clicked *in* */
815 /* the window; therefore it can only have a non-zero */
816 /* value if you clicked at a random location in the */
817 /* panner, making the RealScreen jump to the pointer, */
818 /* AND you also had RealScreenBorderWidth set. */
820 /* This is almost the final step in getting the panner */
821 /* to behave pefectly! It still jitters a bit at the */
824 /**********************************************************/
827 * correctly position the real screen representation on the virtual desktop display
829 void DisplayScreenOnDesktop()
837 border = ( Scr->UseRealScreenBorder ) ? moving_bw : 0;
840 border = moving_bw = 0;
842 /* the -3 is to account for the 2 pixel border and the 1 pixel
843 * offset added by SCALE_D.... */
844 XMoveWindow(dpy, Scr->VirtualDesktopDScreen,
845 Scr->VirtualDesktopX / Scr->VirtualDesktopDScale - border,
846 Scr->VirtualDesktopY / Scr->VirtualDesktopDScale - border
847 /* SCALE_D(Scr->VirtualDesktopX), */ /* - RFB changed 3 to 1 */
848 /* SCALE_D(Scr->VirtualDesktopY) */ /* - RFB changed 3 to 1 */
850 /* 4/92 RFB -- simply use SCALE_D; well, no...
851 ** the problem is that SCALE_D adds 1 if the result is 0, but
852 ** just gives the right result otherwise.
855 /* Way back, somebody wrote: */
856 /* I've convinced myself that this is not necessary */
857 /* XLowerWindow(dpy, Scr->VirtualDesktopDScreen); */
860 void ResizeDesktopDisplay(w, h)
869 /* added compensation for the titlebar - djhjr - 2/23/99 */
870 h -= Scr->VirtualDesktopDisplayTwin->title_height;
872 /* added compensation for frame and bevel widths - djhjr - 2/7/99 */
873 bw = Scr->VirtualDesktopBevelWidth * 2;
874 if (Scr->BorderBevelWidth) bw += Scr->BorderWidth * 2;
877 if ( w - bw != Scr->VirtualDesktopMaxWidth )
878 { Scr->VirtualDesktopMaxWidth = w - bw;
881 if ( h - bw != Scr->VirtualDesktopMaxHeight )
882 { Scr->VirtualDesktopMaxHeight = h - bw;
886 { XResizeWindow( dpy, Scr->VirtualDesktopDisplay,
887 Scr->VirtualDesktopMaxWidth,
888 Scr->VirtualDesktopMaxHeight );
891 /* calculate the new vd size */
892 Scr->VirtualDesktopWidth = SCALE_U(w - bw);
893 Scr->VirtualDesktopHeight = SCALE_U(h - bw);
895 x = SCALE_D(Scr->VirtualDesktopX);
896 y = SCALE_D(Scr->VirtualDesktopY);
898 /* redraw it so that the real screen representation ends up on the display */
899 np = SCALE_D(Scr->VirtualDesktopWidth) - SCALE_D(Scr->MyDisplayWidth);
903 np = SCALE_D(Scr->VirtualDesktopHeight) - SCALE_D(Scr->MyDisplayHeight);
908 /* this is a bit of a fudge factor to account for the borderwidth */
913 SetRealScreen(SCALE_U(x), SCALE_U(y));
915 /* done in setrealscreen now */
917 /* move the display window */
918 XMoveWindow(dpy, Scr->VirtualDesktopDScreen, x - 1, y - 1);
924 * F_MOVESCREEN function
925 * move a window in the desktop display - possible including the `real' screen
927 void StartMoveWindowInDesktop(ev)
938 moving_window = ev.subwindow;
941 moving_window = Scr->VirtualDesktopDScreen;
943 XGrabPointer(dpy, Scr->VirtualDesktopDisplayOuter, True,
944 ButtonPressMask | ButtonReleaseMask | ButtonMotionMask,
945 GrabModeAsync, GrabModeAsync,
946 Scr->VirtualDesktopDisplay, Scr->NoCursor, CurrentTime);
951 /* djhjr - 4/27/98 */
955 /* find the window by looking at the context on the little window */
956 if ((moving_window != Scr->VirtualDesktopDScreen) &&
957 (XFindContext(dpy, moving_window, VirtualContext,
958 (caddr_t *) &moving_twindow) == XCNOENT)) {
959 /* i don't think that this should _ever_ happen */
960 moving_window = None;
961 moving_twindow = NULL;
965 /* use Junk globals - djhjr - 4/28/98 */
966 XGetGeometry(dpy, moving_window, &JunkChild, &xoff, &yoff,
967 &moving_w, &moving_h, &moving_bw, &JunkMask);
969 moving_off_x = moving_off_y = 0;
970 if ( xoff <= moving_x && moving_x <= ( xoff + moving_w )
971 && yoff <= moving_y && moving_y <= ( yoff + moving_h ))
972 { /* The pointer is IN the window.
973 ** don't start by moving the window so its upper-left is at
976 moving_off_x = xoff - moving_x;
977 moving_off_y = yoff - moving_y;
981 /* djhjr - 4/28/98 */
982 XMapRaised(dpy, Scr->SizeWindow);
983 InstallRootColormap();
984 if (moving_window == Scr->VirtualDesktopDScreen)
988 XGetGeometry(dpy, moving_twindow->frame, &JunkChild, &JunkX, &JunkY,
989 &JunkWidth, &JunkHeight, &JunkBW, &JunkMask);
991 /* djhjr - 9/28/99 */
993 int hilite = moving_twindow->highlight;
995 moving_twindow->highlight = True;
996 SetBorder(moving_twindow, (hilite) ? True : False);
997 moving_twindow->highlight = hilite;
999 Scr->Focus = moving_twindow; /* evil */
1001 EventHandler[EnterNotify] = HandleUnknown;
1002 EventHandler[LeaveNotify] = HandleUnknown;
1005 /* djhjr - 10/2/02 */
1006 if (Scr->VirtualSendsMotionEvents &&
1007 (moving_window != Scr->VirtualDesktopDScreen && !moving_twindow->opaque_move))
1008 MoveOutline(Scr->Root,
1010 moving_twindow->frame_width,
1011 moving_twindow->frame_height,
1012 moving_twindow->frame_bw,
1013 moving_twindow->title_height + moving_twindow->frame_bw3D);
1017 /* added 'original_? = ' - djhjr - 11/3/03 */
1018 original_x = JunkX + Scr->VirtualDesktopX;
1019 original_y = JunkY + Scr->VirtualDesktopY;
1020 DisplayPosition(original_x, original_y);
1022 /* get things going */
1023 DoMoveWindowOnDesktop(ev.x, ev.y);
1026 void DoMoveWindowOnDesktop(x, y)
1033 * cancel the effects of scaling errors by skipping the code
1034 * if nothing is actually moved - djhjr - 4/27/98
1036 if (x == starting_x && y == starting_y)
1039 /* djhjr - 2/7/99 */
1040 x -= Scr->VirtualDesktopBevelWidth;
1041 y -= Scr->VirtualDesktopBevelWidth;
1045 /* check that we are legit */
1050 /* added real screen's border!? - djhjr - 2/15/99 */
1051 int np = ( Scr->VirtualDesktopWidth /
1052 Scr->VirtualDesktopDScale ) - moving_w -
1053 Scr->RealScreenBorderWidth * 2;
1055 /* RFB 4/92 no SCALE_D */
1063 /* added real screen's border!? - djhjr - 2/15/99 */
1064 int np = ( Scr->VirtualDesktopHeight /
1065 Scr->VirtualDesktopDScale ) - moving_h -
1066 Scr->RealScreenBorderWidth * 2;
1068 /* RFB 4/92 no SCALE_D */
1076 /* move the display window */
1077 /* removed '- moving_bw' - djhjr - 2/15/99 */
1078 XMoveWindow(dpy, moving_window, x/* - moving_bw*/, y/* - moving_bw*/);
1080 /* djhjr - 4/28/98 */
1081 DisplayPosition(SCALE_U(x), SCALE_U(y));
1083 /* nah... it's pretty easy! - djhjr - 4/17/98
1084 * move the real window *
1085 * this is very difficult on anything not very powerful *
1086 * XMoveWindow(dpy, moving_twindow->frame, SCALE_U(x), SCALE_U(y)); *
1088 if (Scr->VirtualSendsMotionEvents)
1089 if (moving_window != Scr->VirtualDesktopDScreen)
1091 if (moving_twindow->opaque_move)
1092 XMoveWindow(dpy, moving_twindow->frame,
1093 SCALE_U(x) - Scr->VirtualDesktopX,
1094 SCALE_U(y) - Scr->VirtualDesktopY);
1096 MoveOutline(Scr->Root,
1097 SCALE_U(x) - Scr->VirtualDesktopX,
1098 SCALE_U(y) - Scr->VirtualDesktopY,
1099 moving_twindow->frame_width,
1100 moving_twindow->frame_height,
1101 moving_twindow->frame_bw,
1102 moving_twindow->title_height + moving_twindow->frame_bw3D);
1104 /* djhjr - 9/28/99 */
1105 Scr->Focus = moving_twindow; /* evil */
1109 void EndMoveWindowOnDesktop()
1114 /* djhjr - 4/28/98 */
1115 XUnmapWindow(dpy, Scr->SizeWindow);
1116 UninstallRootColormap();
1118 if (moving_window == Scr->VirtualDesktopDScreen) {
1119 /* added '(Cancel) ? ... :' - djhjr - 11/3/03 */
1120 SetRealScreen((Cancel) ? original_x : SCALE_U(moving_x),/* - moving_bw,*/
1121 (Cancel) ? original_y : SCALE_U(moving_y) /*- moving_bw*/ );
1123 /* djhjr - 4/17/98 10/2/02 */
1124 if (Scr->VirtualSendsMotionEvents &&
1125 (moving_window != Scr->VirtualDesktopDScreen && !moving_twindow->opaque_move))
1126 /* erase the move outline */
1127 MoveOutline(Scr->Root, 0, 0, 0, 0, 0, 0);
1129 /* same little check as at the top of DoMoveWindowOnDesktop() - djhjr - 4/27/98 */
1130 if (moving_x != starting_x || moving_y != starting_y)
1132 /* move the window in virtual space */
1133 /* added '(Cancel) ? ... :' - djhjr - 11/3/03 */
1134 moving_twindow->virtual_frame_x =
1135 (Cancel) ? original_x : SCALE_U(moving_x);
1136 moving_twindow->virtual_frame_y =
1137 (Cancel) ? original_y : SCALE_U(moving_y);
1139 /* move it in real space */
1140 moving_twindow->frame_x = V_TO_R_X(moving_twindow->virtual_frame_x);
1141 moving_twindow->frame_y = V_TO_R_Y(moving_twindow->virtual_frame_y);
1143 /* djhjr - 11/3/03 */
1145 XMoveWindow(dpy, moving_window,
1146 SCALE_D(original_x), SCALE_D(original_y));
1148 XMoveWindow(dpy, moving_twindow->frame,
1149 moving_twindow->frame_x, moving_twindow->frame_y);
1151 /* notify the window */
1152 SendConfigureNotify(moving_twindow,
1153 moving_twindow->frame_x, moving_twindow->frame_y);
1156 /* djhjr - 9/28/99 */
1158 int hilite = moving_twindow->highlight;
1160 moving_twindow->highlight = True;
1161 SetBorder(moving_twindow, False);
1162 moving_twindow->highlight = hilite;
1164 Scr->Focus = NULL; /* evil */
1166 EventHandler[EnterNotify] = HandleEnterNotify;
1167 EventHandler[LeaveNotify] = HandleLeaveNotify;
1170 /* added '!Cancel &&' - djhjr - 11/3/03 */
1171 if (!Cancel && !Scr->NoRaiseMove) {
1172 XRaiseWindow(dpy, moving_twindow->frame);
1173 XRaiseWindow(dpy, moving_twindow->VirtualDesktopDisplayWindow);
1175 RaiseStickyAbove(); /* DSE */
1179 /* djhjr - 6/4/98 */
1180 if (Scr->VirtualSendsMotionEvents && !moving_twindow->opaque_move)
1182 XUnmapWindow(dpy, Scr->VirtualDesktopDisplay);
1183 XMapWindow(dpy, Scr->VirtualDesktopDisplay);
1186 moving_window = None;
1190 moving_window = None;
1191 moving_twindow = NULL;
1194 /* Stig Ostholm <ostholm%ce.chalmers.se@uunet>
1195 * move and resize a window on the desktop.
1197 void MoveResizeDesktop(tmp_win, noraise)
1203 if (!tmp_win->VirtualDesktopDisplayWindow
1208 GetDesktopWindowCoordinates(tmp_win, &x, &y, &w, &h);
1209 /* Resize the desktop representation window */
1210 XMoveResizeWindow(dpy, tmp_win->VirtualDesktopDisplayWindow,
1213 XRaiseWindow(dpy, tmp_win->VirtualDesktopDisplayWindow);
1216 void SetVirtualDesktop(geom, scale)
1222 twmrc_error_prefix();
1223 fprintf(stderr, "VirtualDesktop already defined -- ignored.\n");
1228 twmrc_error_prefix();
1230 "VirtualDesktop scale must be positive, not %d\n", scale);
1233 Scr->VirtualDesktopDScale = scale;
1235 JunkMask = XParseGeometry (geom, &JunkX, &JunkY, &JunkWidth, &JunkHeight);
1237 if ((JunkMask & (WidthValue | HeightValue)) !=
1238 (WidthValue | HeightValue)) {
1239 twmrc_error_prefix();
1240 fprintf (stderr, "bad VirtualDesktop \"%s\"\n", geom);
1243 if (JunkWidth <= 0 || JunkHeight <= 0) {
1244 twmrc_error_prefix();
1245 fprintf (stderr, "VirtualDesktop \"%s\" must be positive\n", geom);
1250 * More flexible way of selecting size of virtual desktop (ala tvtwm)
1251 * M.J.E. Mol marcel@duteca.et.tudelft.nl
1253 if (JunkWidth > Scr->MyDisplayWidth)
1254 /* specified as total pixels */
1255 JunkWidth /= Scr->VirtualDesktopDScale;
1256 else if (JunkWidth*Scr->VirtualDesktopDScale < Scr->MyDisplayWidth) {
1257 /* specified as number of physical screens */
1258 JunkWidth *= Scr->MyDisplayWidth;
1259 JunkWidth /= Scr->VirtualDesktopDScale;
1261 /* else specified as size of panner window */
1263 if (JunkHeight > Scr->MyDisplayHeight)
1264 /* specified as total pixels */
1265 JunkHeight /= Scr->VirtualDesktopDScale;
1266 else if (JunkHeight*Scr->VirtualDesktopDScale < Scr->MyDisplayHeight) {
1267 /* specified as number of physical screens */
1268 JunkHeight *= Scr->MyDisplayHeight;
1269 JunkHeight /= Scr->VirtualDesktopDScale;
1271 /* else specified as size of panner window */
1273 /* tar@math.ksu.edu: fix handling of -0 X and Y geometry */
1274 /* account for VirtualDesktopBevelWidth - djhjr - 9/26/01 */
1275 if (JunkMask & XValue) {
1276 if (JunkMask & XNegative) {
1277 Scr->VirtualDesktopDX = Scr->MyDisplayWidth
1278 - JunkWidth - (2 * Scr->BorderWidth)
1279 - (2 * Scr->VirtualDesktopBevelWidth) + JunkX;
1281 else Scr->VirtualDesktopDX = JunkX;
1283 if (JunkMask & YValue) {
1284 if (JunkMask & YNegative) {
1285 Scr->VirtualDesktopDY = Scr->MyDisplayHeight
1286 - JunkHeight - (2 * Scr->BorderWidth)
1287 - (2 * Scr->VirtualDesktopBevelWidth) + JunkY;
1289 else Scr->VirtualDesktopDY = JunkY;
1292 JunkWidth *= Scr->VirtualDesktopDScale;
1293 JunkHeight *= Scr->VirtualDesktopDScale;
1295 /* check that the vd is at least as big as the screen */
1296 /* handled above, M.J.E. Mol
1297 ** if ((JunkWidth < Scr->MyDisplayWidth)
1298 ** || (JunkHeight < Scr->MyDisplayHeight))
1300 ** twmrc_error_prefix();
1302 ** "VirtualDesktop must be larger than screen (%dx%d)\n",
1303 ** Scr->MyDisplayWidth, Scr->MyDisplayHeight);
1307 Scr->VirtualDesktopWidth = JunkWidth;
1308 Scr->VirtualDesktopHeight = JunkHeight;
1310 /* all of the values looked reasonable */
1311 Scr->Virtual = TRUE;
1314 void VirtualMoveWindow(t, x, y)
1321 /* move window in virtual space */
1322 t->virtual_frame_x = x;
1323 t->virtual_frame_y = y;
1325 /* move it in real space */
1326 t->frame_x = V_TO_R_X(x);
1327 t->frame_y = V_TO_R_Y(y);
1329 XMoveWindow(dpy, t->frame,
1330 t->frame_x, t->frame_y);
1332 /* update the display */
1333 /* UpdateDesktop(t); Stig */
1334 MoveResizeDesktop(t, FALSE); /* Stig */
1336 if (!Scr->NoRaiseMove) {
1337 XRaiseWindow(dpy, t->frame);
1338 /* XRaiseWindow(dpy, t->VirtualDesktopDisplayWindow); Stig */
1340 RaiseStickyAbove(); /* DSE */
1347 * for Kevin Twidle <kpt@doc.ic.ac.uk>
1348 * this snaps the real screen to a grid defined by the pandistance values.
1350 void SnapRealScreen()
1355 mod = Scr->VirtualDesktopX % Scr->VirtualDesktopPanDistanceX;
1356 div = Scr->VirtualDesktopX / Scr->VirtualDesktopPanDistanceX;
1358 if (mod > (Scr->VirtualDesktopPanDistanceX / 2))
1359 newx = Scr->VirtualDesktopPanDistanceX * (div + 1);
1361 newx = Scr->VirtualDesktopPanDistanceX * div;
1363 mod = Scr->VirtualDesktopY % Scr->VirtualDesktopPanDistanceY;
1364 div = Scr->VirtualDesktopY / Scr->VirtualDesktopPanDistanceY;
1366 if (mod > (Scr->VirtualDesktopPanDistanceY / 2))
1367 newy = Scr->VirtualDesktopPanDistanceY * (div + 1);
1369 newy = Scr->VirtualDesktopPanDistanceY * div;
1371 SetRealScreenInternal(newx, newy, FALSE, NULL, NULL); /* DSE */
1375 void SetRealScreen(x, y)
1378 if (Scr->snapRealScreen)
1379 SetRealScreenInternal(x, y, TRUE, NULL, NULL); /* DSE */
1381 SetRealScreenInternal(x, y, FALSE, NULL, NULL); /* DSE */
1385 * handles the possibility of snapping
1387 void SetRealScreenInternal(x, y, dosnap, dx, dy)
1389 int *dx, *dy; /* a pointer to an integer that contains the value
1390 (AutoPanBorderWidth + AutoPanExtraWarp) is passed in to
1391 both dx and dy when autopanning, or NULL is passed. On
1392 return, the value is modified to store how much the pointer
1393 should actually be warped, in case
1394 AutoPanWarpWithRespectToRealScreen is nonzero. -- DSE */
1403 if (x > (Scr->VirtualDesktopWidth - Scr->MyDisplayWidth))
1404 x = Scr->VirtualDesktopWidth - Scr->MyDisplayWidth;
1405 if (y > (Scr->VirtualDesktopHeight - Scr->MyDisplayHeight))
1406 y = Scr->VirtualDesktopHeight - Scr->MyDisplayHeight;
1408 /* if ( Scr->RealScreenBorderWidth ) */
1413 /* how big a move is this ? */
1414 xdiff = Scr->VirtualDesktopX - x;
1415 ydiff = Scr->VirtualDesktopY - y;
1418 /* calculate how much we might warp the pointer */
1419 int x_warp = ((xdiff<0) ? -1 : 1) *
1420 ((50 + abs(xdiff) * Scr->AutoPanWarpWithRespectToRealScreen) / 100);
1421 int y_warp = ((ydiff<0) ? -1 : 1) *
1422 ((50 + abs(ydiff) * Scr->AutoPanWarpWithRespectToRealScreen) / 100);
1424 /* make sure the pointer warps enought with respect to the real screen
1425 so that it can get out of the autopan windows. */
1427 if ( abs (*dx) < abs(x_warp) ) *dx = x_warp;
1429 if ( abs (*dx) < abs(y_warp) ) *dy = y_warp;
1432 /* make sure it isn't warped too much in case ``AutoPan 100'' and
1433 ``AutoPanWarpWithRespectToRealScreen 100'' (also known as
1434 ``NaturalAutopanBehavior'') are set. -- DSE */
1436 int max_x_warp = ((xdiff<0) ? -1 : 1) *
1437 (Scr->MyDisplayWidth - 2 * Scr->AutoPanBorderWidth);
1438 int max_y_warp = ((ydiff<0) ? -1 : 1) *
1439 (Scr->MyDisplayHeight - 2 * Scr->AutoPanBorderWidth);
1441 if ( abs(*dx) > abs(max_x_warp) ) *dx = max_x_warp;
1443 if ( abs(*dy) > abs(max_y_warp) ) *dy = max_y_warp;
1446 /* move all of the windows by walking the twm list */
1447 for (Tmp_win = Scr->TwmRoot.next; Tmp_win != NULL; Tmp_win = Tmp_win->next)
1449 if (Scr->StaticIconPositions && Tmp_win->icon && Tmp_win->icon_w)
1452 * Make icons "stay put" on the virtual desktop when
1453 * not otherwise nailed - djhjr - 12/14/98
1455 XGetGeometry(dpy, Tmp_win->icon_w, &JunkRoot, &JunkX, &JunkY,
1456 &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth);
1458 XMoveWindow(dpy, Tmp_win->icon_w,
1459 JunkX + xdiff, JunkY + ydiff);
1462 if (Tmp_win->nailed || (Scr->DeIconifyToScreen && Tmp_win->icon))
1465 * The window is nailed or...
1466 * The window is currently an icon, we are trying to
1467 * keep things on the screen, so move it around the
1468 * virtual desktop so that it stays on the real screen
1470 Tmp_win->virtual_frame_x -= xdiff;
1471 Tmp_win->virtual_frame_y -= ydiff;
1478 Tmp_win->frame_x += xdiff;
1479 Tmp_win->frame_y += ydiff;
1483 XMoveWindow(dpy, Tmp_win->frame,
1484 Tmp_win->frame_x, Tmp_win->frame_y);
1485 SendConfigureNotify(Tmp_win,
1486 Tmp_win->frame_x, Tmp_win->frame_y);
1491 Scr->VirtualDesktopX = x;
1492 Scr->VirtualDesktopY = y;
1497 DisplayScreenOnDesktop();
1501 * pan the real screen on the virtual desktop by (xoff, yoff)
1503 void PanRealScreen(xoff, yoff, dx, dy)
1505 int *dx, *dy; /* DSE */
1507 /* panning the screen can never mean that you need to snap */
1508 SetRealScreenInternal(Scr->VirtualDesktopX + xoff, Scr->VirtualDesktopY + yoff,
1509 /* why not? - djhjr - 1/24/98
1512 Scr->snapRealScreen, dx, dy);
1517 * raise the auto-pan windows if needed
1523 if (Scr->AutoPanX > 0)
1524 for (i = 0; i <= 3; i++)
1525 XRaiseWindow(dpy, Scr->VirtualDesktopAutoPan[i]);
1529 * Raise sticky windows if StickyAbove is set. -- DSE
1532 void RaiseStickyAbove () {
1533 if (Scr->StickyAbove) {
1535 for (Tmp_win = Scr->TwmRoot.next; Tmp_win != NULL;
1536 Tmp_win = Tmp_win->next)
1537 if (Tmp_win->nailed) {
1538 XRaiseWindow(dpy,Tmp_win->w);
1539 XRaiseWindow(dpy,Tmp_win->VirtualDesktopDisplayWindow);
1540 XRaiseWindow(dpy,Tmp_win->frame);
1546 * Lower sticky windows. -- DSE
1549 void LowerSticky () {
1551 for (Tmp_win = Scr->TwmRoot.next; Tmp_win != NULL;
1552 Tmp_win = Tmp_win->next)
1553 if (Tmp_win->nailed) {
1554 XLowerWindow(dpy,Tmp_win->w);
1555 XLowerWindow(dpy,Tmp_win->VirtualDesktopDisplayWindow);
1556 XLowerWindow(dpy,Tmp_win->frame);