diff -r -c fvwm-2.0.46/fvwm/add_window.c fvwm-2.0.46-patched/fvwm/add_window.c *** fvwm-2.0.46/fvwm/add_window.c Fri May 15 22:59:30 1998 --- fvwm-2.0.46-patched/fvwm/add_window.c Sat May 16 00:01:14 1998 *************** *** 345,351 **** Scr.FvwmRoot.next->prev = tmp_win; tmp_win->prev = &Scr.FvwmRoot; Scr.FvwmRoot.next = tmp_win; ! /* create windows */ tmp_win->frame_x = tmp_win->attr.x + tmp_win->old_bw - tmp_win->bw; tmp_win->frame_y = tmp_win->attr.y + tmp_win->old_bw - tmp_win->bw; --- 345,362 ---- Scr.FvwmRoot.next->prev = tmp_win; tmp_win->prev = &Scr.FvwmRoot; Scr.FvwmRoot.next = tmp_win; ! ! /* ! RBW - 05/15/1998 - add it into the stacking order chain also. ! This chain is anchored at both ends on Scr.FvwmRoot, there are ! no null pointers. ! */ ! tmp_win->stack_next = Scr.FvwmRoot.stack_next; ! Scr.FvwmRoot.stack_next->stack_prev = tmp_win; ! tmp_win->stack_prev = &Scr.FvwmRoot; ! Scr.FvwmRoot.stack_next = tmp_win; ! ! /* create windows */ tmp_win->frame_x = tmp_win->attr.x + tmp_win->old_bw - tmp_win->bw; tmp_win->frame_y = tmp_win->attr.y + tmp_win->old_bw - tmp_win->bw; diff -r -c fvwm-2.0.46/fvwm/fvwm.c fvwm-2.0.46-patched/fvwm/fvwm.c *** fvwm-2.0.46/fvwm/fvwm.c Fri May 15 22:59:32 1998 --- fvwm-2.0.46-patched/fvwm/fvwm.c Sat May 16 00:01:16 1998 *************** *** 1170,1175 **** --- 1170,1180 ---- Scr.d_depth = DefaultDepth(dpy, Scr.screen); Scr.FvwmRoot.w = Scr.Root; Scr.FvwmRoot.next = 0; + + /* RBW - 05/15/1998 - 2 new fields to init - stacking order chain. */ + Scr.FvwmRoot.stack_next = &Scr.FvwmRoot; + Scr.FvwmRoot.stack_prev = &Scr.FvwmRoot; + XGetWindowAttributes(dpy,Scr.Root,&(Scr.FvwmRoot.attr)); Scr.root_pushes = 0; Scr.pushed_window = &Scr.FvwmRoot; *************** *** 1263,1269 **** MyXGrabServer (dpy); InstallWindowColormaps (&Scr.FvwmRoot); /* force reinstall */ ! for (tmp = Scr.FvwmRoot.next; tmp != NULL; tmp = tmp->next) { RestoreWithdrawnLocation (tmp,True); XUnmapWindow(dpy,tmp->frame); --- 1268,1278 ---- MyXGrabServer (dpy); InstallWindowColormaps (&Scr.FvwmRoot); /* force reinstall */ ! /* ! RBW - 05/15/1998 ! Grab the last window and work backwards: preserve stacking order on restart. ! */ ! for (tmp = Scr.FvwmRoot.stack_prev; tmp != &Scr.FvwmRoot; tmp = tmp->stack_prev) { RestoreWithdrawnLocation (tmp,True); XUnmapWindow(dpy,tmp->frame); diff -r -c fvwm-2.0.46/fvwm/fvwm.h fvwm-2.0.46-patched/fvwm/fvwm.h *** fvwm-2.0.46/fvwm/fvwm.h Fri May 15 22:59:32 1998 --- fvwm-2.0.46-patched/fvwm/fvwm.h Sat May 16 00:01:16 1998 *************** *** 133,138 **** --- 133,140 ---- { struct FvwmWindow *next; /* next fvwm window */ struct FvwmWindow *prev; /* prev fvwm window */ + struct FvwmWindow *stack_next; /* next (lower) fvwm window in stacking order */ + struct FvwmWindow *stack_prev; /* prev (higher) fvwm window in stacking order */ Window w; /* the child window */ int old_bw; /* border width before reparenting */ Window frame; /* the frame window */ *************** *** 214,219 **** --- 216,226 ---- unsigned long buttons; int IconBox[4]; int BoxFillMethod; + /* + RBW - 05/15/1998 - new flags to supplement the flags word, implemented + as named bit fields. + */ + unsigned ViewportMoved : 1; /* To prevent double move in MoveViewport. */ } FvwmWindow; /*************************************************************************** diff -r -c fvwm-2.0.46/fvwm/misc.c fvwm-2.0.46-patched/fvwm/misc.c *** fvwm-2.0.46/fvwm/misc.c Fri May 15 22:59:33 1998 --- fvwm-2.0.46-patched/fvwm/misc.c Sat May 16 00:01:16 1998 *************** *** 186,191 **** --- 186,199 ---- XDeleteContext(dpy, Tmp_win->corners[i], FvwmContext); } + /* + RBW - 05/15/1998 - new: have to unhook the stacking order chain also. + There's always a prev and next, since this is a ring anchored on + Scr.FvwmRoot + */ + Tmp_win->stack_prev->stack_next = Tmp_win->stack_next; + Tmp_win->stack_next->stack_prev = Tmp_win->stack_prev; + Tmp_win->prev->next = Tmp_win->next; if (Tmp_win->next != NULL) Tmp_win->next->prev = Tmp_win->prev; *************** *** 667,673 **** Scr.LastWindowRaised = t; if(i > 0) ! XRaiseWindow(dpy,wins[0]); XRestackWindows(dpy,wins,i); free(wins); --- 675,692 ---- Scr.LastWindowRaised = t; if(i > 0) ! { ! XRaiseWindow(dpy,wins[0]); ! /* ! RBW - 05/15/1998 - new: maintain the stacking order chain. ! */ ! t->stack_prev->stack_next = t->stack_next; /* Pluck from chain. */ ! t->stack_next->stack_prev = t->stack_prev; ! t->stack_next = Scr.FvwmRoot.stack_next; /* Set new pointers. */ ! t->stack_prev = Scr.FvwmRoot.stack_next->stack_prev; ! Scr.FvwmRoot.stack_next->stack_prev = t; /* Insert at top of chain. */ ! Scr.FvwmRoot.stack_next = t; ! } XRestackWindows(dpy,wins,i); free(wins); *************** *** 687,692 **** --- 706,720 ---- XLowerWindow(dpy, t->icon_pixmap_w); } Scr.LastWindowRaised = (FvwmWindow *)0; + /* + RBW - 05/15/1998 - new: maintain the stacking order chain. + */ + t->stack_prev->stack_next = t->stack_next; /* Pluck from chain. */ + t->stack_next->stack_prev = t->stack_prev; + t->stack_next = Scr.FvwmRoot.stack_prev->stack_next; /* Set new pointers. */ + t->stack_prev = Scr.FvwmRoot.stack_prev; + Scr.FvwmRoot.stack_prev->stack_next = t; /* Insert at end of chain. */ + Scr.FvwmRoot.stack_prev = t; } diff -r -c fvwm-2.0.46/fvwm/virtual.c fvwm-2.0.46-patched/fvwm/virtual.c *** fvwm-2.0.46/fvwm/virtual.c Fri May 15 22:59:34 1998 --- fvwm-2.0.46-patched/fvwm/virtual.c Sat May 16 00:01:17 1998 *************** *** 343,355 **** /*************************************************************************** * ! * Moves the viewport within thwe virtual desktop * ***************************************************************************/ void MoveViewport(int newx, int newy, Bool grab) { ! FvwmWindow *t; int deltax,deltay; if(grab) MyXGrabServer(dpy); --- 343,358 ---- /*************************************************************************** * ! * Moves the viewport within the virtual desktop * ***************************************************************************/ void MoveViewport(int newx, int newy, Bool grab) { ! FvwmWindow *t, *t1; int deltax,deltay; + int PageTop, PageLeft; + int PageBottom, PageRight; + int txl, txr, tyt, tyb; if(grab) MyXGrabServer(dpy); *************** *** 366,371 **** --- 369,382 ---- deltay = Scr.Vy - newy; deltax = Scr.Vx - newx; + /* + Identify the bounding rectangle that will be moved into + the viewport. + */ + PageBottom = Scr.MyDisplayHeight - deltay; + PageRight = Scr.MyDisplayWidth - deltax; + PageTop = 0 - deltay; + PageLeft = 0 - deltax; Scr.Vx = newx; Scr.Vy = newy; *************** *** 373,409 **** if((deltax!=0)||(deltay!=0)) { ! for (t = Scr.FvwmRoot.next; t != NULL; t = t->next) ! { ! /* If the window is iconified, and sticky Icons is set, ! * then the window should essentially be sticky */ ! if(!((t->flags & ICONIFIED)&&(t->flags & StickyIcon)) && ! (!(t->flags & STICKY))) ! { ! if(!(t->flags & StickyIcon)) ! { ! t->icon_x_loc += deltax; ! t->icon_xl_loc += deltax; ! t->icon_y_loc += deltay; ! if(t->icon_pixmap_w != None) ! XMoveWindow(dpy,t->icon_pixmap_w,t->icon_x_loc, ! t->icon_y_loc); ! if(t->icon_w != None) ! XMoveWindow(dpy,t->icon_w,t->icon_x_loc, t->icon_y_loc+t->icon_p_height); ! if(!(t->flags &ICON_UNMAPPED)) ! Broadcast(M_ICON_LOCATION,7,t->w,t->frame, ! (unsigned long)t, ! t->icon_x_loc,t->icon_y_loc, ! t->icon_w_width, ! t->icon_w_height+t->icon_p_height); ! } ! SetupFrame (t, t->frame_x+ deltax, t->frame_y + deltay, ! t->frame_width, t->frame_height,FALSE); ! } ! } for (t = Scr.FvwmRoot.next; t != NULL; t = t->next) { /* If its an icon, and its sticking, autoplace it so * that it doesn't wind up on top a a stationary * icon */ --- 384,497 ---- if((deltax!=0)||(deltay!=0)) { ! ! /* ! RBW - 05/15/1998 - new: chase the chain bidirectionally, all at once! ! The idea is to move the windows that are moving out of the viewport from ! the bottom of the stacking order up, to minimize the expose-redraw overhead. ! Windows that will be moving into view will be moved top down, for the same ! reason. ! Newer: use the new stacking-order chain, rather than the old ! last-focused chain. ! */ ! ! t = Scr.FvwmRoot.stack_next; ! t1 = Scr.FvwmRoot.stack_prev; ! while (t != &Scr.FvwmRoot || t1 != &Scr.FvwmRoot) ! { ! if (t != &Scr.FvwmRoot) ! { ! /* ! If the window is moving into the viewport... ! */ ! txl = t->frame_x; ! tyt = t->frame_y; ! txr = t->frame_x + t->frame_width; ! tyb = t->frame_y + t->frame_height; ! if ((txr >= PageLeft && txl <= PageRight ! && tyb >= PageTop && tyt <= PageBottom) ! && ! t->ViewportMoved) ! { ! t->ViewportMoved = True; /* Block double move. */ ! /* If the window is iconified, and sticky Icons is set, ! * then the window should essentially be sticky */ ! if(!((t->flags & ICONIFIED)&&(t->flags & StickyIcon)) && ! (!(t->flags & STICKY))) ! { ! if(!(t->flags & StickyIcon)) ! { ! t->icon_x_loc += deltax; ! t->icon_xl_loc += deltax; ! t->icon_y_loc += deltay; ! if(t->icon_pixmap_w != None) ! XMoveWindow(dpy,t->icon_pixmap_w,t->icon_x_loc, ! t->icon_y_loc); ! if(t->icon_w != None) ! XMoveWindow(dpy,t->icon_w,t->icon_x_loc, t->icon_y_loc+t->icon_p_height); ! if(!(t->flags &ICON_UNMAPPED)) ! Broadcast(M_ICON_LOCATION,7,t->w,t->frame, ! (unsigned long)t, ! t->icon_x_loc,t->icon_y_loc, ! t->icon_w_width, ! t->icon_w_height+t->icon_p_height); ! } ! SetupFrame (t, t->frame_x+ deltax, t->frame_y + deltay, ! t->frame_width, t->frame_height,FALSE); ! } ! } ! /* Bump to next win... */ ! t = t->stack_next; ! } ! if (t1 != &Scr.FvwmRoot) ! { ! /* ! If the window is not moving into the viewport... ! */ ! txl = t1->frame_x; ! tyt = t1->frame_y; ! txr = t1->frame_x + t1->frame_width; ! tyb = t1->frame_y + t1->frame_height; ! if (! (txr >= PageLeft && txl <= PageRight ! && tyb >= PageTop && tyt <= PageBottom) ! && ! t1->ViewportMoved) ! { ! t1->ViewportMoved = True; /* Block double move. */ ! /* If the window is iconified, and sticky Icons is set, ! * then the window should essentially be sticky */ ! if(!((t1->flags & ICONIFIED)&&(t1->flags & StickyIcon)) && ! (!(t1->flags & STICKY))) ! { ! if(!(t1->flags & StickyIcon)) ! { ! t1->icon_x_loc += deltax; ! t1->icon_xl_loc += deltax; ! t1->icon_y_loc += deltay; ! if(t1->icon_pixmap_w != None) ! XMoveWindow(dpy,t1->icon_pixmap_w,t1->icon_x_loc, ! t1->icon_y_loc); ! if(t1->icon_w != None) ! XMoveWindow(dpy,t1->icon_w,t1->icon_x_loc, ! t1->icon_y_loc+t1->icon_p_height); ! if(!(t1->flags &ICON_UNMAPPED)) ! Broadcast(M_ICON_LOCATION,7,t1->w,t1->frame, ! (unsigned long)t1, ! t1->icon_x_loc,t1->icon_y_loc, ! t1->icon_w_width, ! t1->icon_w_height+t1->icon_p_height); ! } ! SetupFrame (t1, t1->frame_x+ deltax, t1->frame_y + deltay, ! t1->frame_width, t1->frame_height,FALSE); ! } ! } ! /* Bump to next win... */ ! t1 = t1->stack_prev; ! } ! } ! for (t = Scr.FvwmRoot.next; t != NULL; t = t->next) { + t->ViewportMoved = False; /* Clear double move blocker. */ /* If its an icon, and its sticking, autoplace it so * that it doesn't wind up on top a a stationary * icon */ *************** *** 441,447 **** void changeDesks(int val1, int val2) { int oldDesk; ! FvwmWindow *FocusWin = 0, *t; static FvwmWindow *StickyWin = 0; oldDesk = Scr.CurrentDesk; --- 529,535 ---- void changeDesks(int val1, int val2) { int oldDesk; ! FvwmWindow *FocusWin = 0, *t, *t1; static FvwmWindow *StickyWin = 0; oldDesk = Scr.CurrentDesk; *************** *** 461,500 **** /* Scan the window list, mapping windows on the new Desk, * unmapping windows on the old Desk */ MyXGrabServer(dpy); ! for (t = Scr.FvwmRoot.next; t != NULL; t = t->next) { ! /* Only change mapping for non-sticky windows */ ! if(!((t->flags & ICONIFIED)&&(t->flags & StickyIcon)) && ! (!(t->flags & STICKY))&&(!(t->flags & ICON_UNMAPPED))) ! { ! if(t->Desk == oldDesk) ! { ! if (Scr.Focus == t) ! t->FocusDesk = oldDesk; ! else ! t->FocusDesk = -1; ! UnmapIt(t); ! } ! else if(t->Desk == Scr.CurrentDesk) ! { ! MapIt(t); ! if (t->FocusDesk == Scr.CurrentDesk) ! { ! FocusWin = t; ! } ! } ! } ! else ! { ! /* Window is sticky */ ! t->Desk = Scr.CurrentDesk; ! if (Scr.Focus == t) ! { ! t->FocusDesk =oldDesk; ! StickyWin = t; ! } ! } } MyXUngrabServer(dpy); for (t = Scr.FvwmRoot.next; t != NULL; t = t->next) { --- 549,614 ---- /* Scan the window list, mapping windows on the new Desk, * unmapping windows on the old Desk */ MyXGrabServer(dpy); ! ! /* ! RBW - 05/08/1998 - new: chase the chain bidirectionally, unmapping ! windows bottom-up and mapping them top-down, to minimize expose-redraw ! overhead. ! Newer: use the new stacking-order chain, rather than the old ! last-focused chain. ! */ ! t = Scr.FvwmRoot.stack_next; ! t1 = Scr.FvwmRoot.stack_prev; ! while (t != &Scr.FvwmRoot || t1 != &Scr.FvwmRoot) { ! if (t != &Scr.FvwmRoot) ! { ! if(!((t->flags & ICONIFIED)&&(t->flags & StickyIcon)) && ! (!(t->flags & STICKY))&&(!(t->flags & ICON_UNMAPPED))) ! { ! if(t->Desk == Scr.CurrentDesk) ! { ! MapIt(t); ! if (t->FocusDesk == Scr.CurrentDesk) ! { ! FocusWin = t; ! } ! } ! } ! else ! /* ! Only need to do these in one of the passes... ! */ ! { ! /* Window is sticky */ ! t->Desk = Scr.CurrentDesk; ! if (Scr.Focus == t) ! { ! t->FocusDesk =oldDesk; ! StickyWin = t; ! } ! } ! t = t->stack_next; ! } ! if (t1 != &Scr.FvwmRoot) ! { ! /* Only change mapping for non-sticky windows */ ! if(!((t1->flags & ICONIFIED)&&(t1->flags & StickyIcon)) && ! (!(t1->flags & STICKY))&&(!(t1->flags & ICON_UNMAPPED))) ! { ! if(t1->Desk == oldDesk) ! { ! if (Scr.Focus == t1) ! t1->FocusDesk = oldDesk; ! else ! t1->FocusDesk = -1; ! UnmapIt(t1); ! } ! } ! t1 = t1->stack_prev; ! } } + MyXUngrabServer(dpy); for (t = Scr.FvwmRoot.next; t != NULL; t = t->next) { *************** *** 525,531 **** /************************************************************************** * ! * Move to a new desktop * *************************************************************************/ void changeWindowsDesk(XEvent *eventp,Window w,FvwmWindow *t, --- 639,645 ---- /************************************************************************** * ! * Move a window to a new desktop * *************************************************************************/ void changeWindowsDesk(XEvent *eventp,Window w,FvwmWindow *t, *************** *** 556,563 **** if(val1 == t->Desk) return; ! /* Scan the window list, mapping windows on the new Desk, ! * unmapping windows on the old Desk */ /* Only change mapping for non-sticky windows */ if(!((t->flags & ICONIFIED)&&(t->flags & StickyIcon)) && (!(t->flags & STICKY))&&(!(t->flags & ICON_UNMAPPED))) --- 670,678 ---- if(val1 == t->Desk) return; ! /* ! Set the window's desktop, and map or unmap it as needed. ! */ /* Only change mapping for non-sticky windows */ if(!((t->flags & ICONIFIED)&&(t->flags & StickyIcon)) && (!(t->flags & STICKY))&&(!(t->flags & ICON_UNMAPPED)))