mirror of
https://github.com/gnustep/libs-back.git
synced 2025-06-03 02:30:50 +00:00
fixups for implementation of window levels support
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@26218 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
44bad647b4
commit
2ed723345f
3 changed files with 192 additions and 106 deletions
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
||||||
|
2008-03-06 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
|
* Source\win32\WIN32Server.m: Improve window level code ... when moving
|
||||||
|
a window to the top of a level, jump it right to the top of the window
|
||||||
|
z-order so that it is above any non-gnustep windows.
|
||||||
|
* Source\win32\w32_movesize.m: If a window is jumped to the top of the
|
||||||
|
z-order and hence breaks the level rules, use a bubble sort to get
|
||||||
|
the windows back in level order by raising any windows which are
|
||||||
|
lower than they should be.
|
||||||
|
|
||||||
2008-03-05 Richard Frith-Macdonald <rfm@gnu.org>
|
2008-03-05 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
* Headers\win32\WIN32Server.h: Add fields to track window level/ordering
|
* Headers\win32\WIN32Server.h: Add fields to track window level/ordering
|
||||||
|
|
|
@ -1036,6 +1036,11 @@ NSLog(@"Callback");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flag = SW_SHOW;
|
||||||
|
if (IsIconic((HWND)winNum))
|
||||||
|
flag = SW_RESTORE;
|
||||||
|
ShowWindow((HWND)winNum, flag);
|
||||||
|
|
||||||
win = (WIN_INTERN *)GetWindowLong((HWND)winNum, GWL_USERDATA);
|
win = (WIN_INTERN *)GetWindowLong((HWND)winNum, GWL_USERDATA);
|
||||||
|
|
||||||
if (op == NSWindowOut)
|
if (op == NSWindowOut)
|
||||||
|
@ -1080,11 +1085,6 @@ NSLog(@"Callback");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
flag = SW_SHOW;
|
|
||||||
if (IsIconic((HWND)winNum))
|
|
||||||
flag = SW_RESTORE;
|
|
||||||
ShowWindow((HWND)winNum, flag);
|
|
||||||
|
|
||||||
if (win->level <= NSDesktopWindowLevel)
|
if (win->level <= NSDesktopWindowLevel)
|
||||||
{
|
{
|
||||||
// For desktop level, put this at the bottom of the z-order
|
// For desktop level, put this at the bottom of the z-order
|
||||||
|
@ -1135,9 +1135,27 @@ NSLog(@"Callback");
|
||||||
otherWin, other->level);
|
otherWin, other->level);
|
||||||
if (other->level >= win->level)
|
if (other->level >= win->level)
|
||||||
{
|
{
|
||||||
if (other->level > win->level
|
if (other->level > win->level)
|
||||||
|| op == NSWindowBelow
|
{
|
||||||
|| foreground == otherWin)
|
/* On windows, there is no notion of levels, so
|
||||||
|
* native apps will automatically move to the
|
||||||
|
* very top of the stack (above our alert panels etc)
|
||||||
|
*
|
||||||
|
* So to cope with this, when we move to the top
|
||||||
|
* of a level, we assume there may be native apps
|
||||||
|
* above us and we set otherWin=0 to move to the
|
||||||
|
* very top of the stack past them.
|
||||||
|
*
|
||||||
|
* We rely on the fact that we have code in the
|
||||||
|
* window positioning notification to rearrange
|
||||||
|
* (sort) all the windows into level order if
|
||||||
|
* moving this window to the top messes up the
|
||||||
|
* level ordering.
|
||||||
|
*/
|
||||||
|
otherWin = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (op == NSWindowBelow || foreground == otherWin)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1167,8 +1185,10 @@ NSLog(@"Callback");
|
||||||
SetWindowPos((HWND)winNum, (HWND)otherWin, 0, 0, 0, 0,
|
SetWindowPos((HWND)winNum, (HWND)otherWin, 0, 0, 0, 0,
|
||||||
SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
|
SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
|
||||||
|
|
||||||
#if 1
|
/* For debug log window stack.
|
||||||
{
|
*/
|
||||||
|
if (GSDebugSet(@"WTrace") == YES)
|
||||||
|
{
|
||||||
NSString *s = @"Window list:\n";
|
NSString *s = @"Window list:\n";
|
||||||
|
|
||||||
otherWin = (int)GetDesktopWindow();
|
otherWin = (int)GetDesktopWindow();
|
||||||
|
@ -1183,7 +1203,7 @@ NSLog(@"Callback");
|
||||||
|
|
||||||
otherWin = (int)GetNextWindow((HWND)otherWin, GW_HWNDPREV);
|
otherWin = (int)GetNextWindow((HWND)otherWin, GW_HWNDPREV);
|
||||||
|
|
||||||
if (otherWin > 0 && otherWin != winNum
|
if (otherWin > 0
|
||||||
&& GetClassName((HWND)otherWin, buf, 32) == 18
|
&& GetClassName((HWND)otherWin, buf, 32) == 18
|
||||||
&& strncmp(buf, "GNUstepWindowClass", 18) == 0)
|
&& strncmp(buf, "GNUstepWindowClass", 18) == 0)
|
||||||
{
|
{
|
||||||
|
@ -1196,8 +1216,7 @@ NSLog(@"Callback");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NSDebugLLog(@"WTrace", @"orderwindow: %@", s);
|
NSDebugLLog(@"WTrace", @"orderwindow: %@", s);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) movewindow: (NSPoint)loc : (int)winNum
|
- (void) movewindow: (NSPoint)loc : (int)winNum
|
||||||
|
|
|
@ -252,84 +252,141 @@
|
||||||
|
|
||||||
- (void) decodeWM_WINDOWPOSCHANGEDParams: (WPARAM)wParam : (LPARAM)lParam : (HWND)hwnd
|
- (void) decodeWM_WINDOWPOSCHANGEDParams: (WPARAM)wParam : (LPARAM)lParam : (HWND)hwnd
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
/* FIXME we really want to ensure that windows stay in the correct
|
|
||||||
* level order. When we change ordering programmatically using
|
|
||||||
* orderwindow::: that's OK, but if someone else reorders our
|
|
||||||
* windows, how do we cope?
|
|
||||||
* Perhaps we should veto/adjust ordering before it happens, or
|
|
||||||
* perhaps we should re-order here?
|
|
||||||
*/
|
|
||||||
if ((inf->flags & SWP_NOZORDER) == 0)
|
|
||||||
{
|
|
||||||
/* If this window has been moved to the front, we need to move
|
|
||||||
* any other higher level windows to follow it.
|
|
||||||
*/
|
|
||||||
win = (WIN_INTERN *)GetWindowLong(hwnd, GWL_USERDATA);
|
|
||||||
if (win->level > NSDesktopWindowLevel)
|
|
||||||
{
|
|
||||||
int otherWin;
|
|
||||||
int levelToMove = NSDesktopWindowlevel;
|
|
||||||
|
|
||||||
/* Start searching from bottom of window list...
|
|
||||||
* The last child of the desktop.
|
|
||||||
*/
|
|
||||||
otherWin = (int)GetDesktopWindow();
|
|
||||||
otherWin = (int)GetWindow((HWND)otherWin, GW_CHILD);
|
|
||||||
if (otherWin > 0)
|
|
||||||
{
|
|
||||||
otherWin = (int)GetWindow((HWND)otherWin, GW_HWNDLAST);
|
|
||||||
}
|
|
||||||
while (otherWin > 0)
|
|
||||||
{
|
|
||||||
TCHAR buf[32];
|
|
||||||
|
|
||||||
otherWin = (int)GetNextWindow((HWND)otherWin, GW_HWNDPREV);
|
|
||||||
if (otherWin == 0 || otherWin == (int)hwnd)
|
|
||||||
{
|
|
||||||
break; // No higher level windows below this
|
|
||||||
}
|
|
||||||
if (GetClassName((HWND)otherWin, buf, 32) == 18
|
|
||||||
&& strncmp(buf, "GNUstepWindowClass", 18) == 0)
|
|
||||||
{
|
|
||||||
other = (WIN_INTERN *)GetWindowLong((HWND)otherWin,
|
|
||||||
GWL_USERDATA);
|
|
||||||
if (other->orderedIn == YES)
|
|
||||||
{
|
|
||||||
BOOL moveThisWindow = NO;
|
|
||||||
|
|
||||||
if (levelToMove > NSDesktopWindowLevel)
|
|
||||||
{
|
|
||||||
if (other->level == levelToMove)
|
|
||||||
{
|
|
||||||
moveThisWindow = YES;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (other->level > win->level)
|
|
||||||
{
|
|
||||||
levelToMove = other->level;
|
|
||||||
moveThisWindow = YES;
|
|
||||||
}
|
|
||||||
if (moveThisWidnow == YES)
|
|
||||||
{
|
|
||||||
SetWindowPos((HWND)otherWin, HWND_TOP, 0, 0, 0, 0,
|
|
||||||
SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) decodeWM_WINDOWPOSCHANGINGParams: (WPARAM)wParam : (LPARAM)lParam : (HWND)hwnd
|
|
||||||
{
|
|
||||||
WIN_INTERN *win;
|
|
||||||
WINDOWPOS *inf = (WINDOWPOS*)lParam;
|
WINDOWPOS *inf = (WINDOWPOS*)lParam;
|
||||||
|
|
||||||
if ((inf->flags & SWP_NOZORDER) == 0)
|
if ((inf->flags & SWP_NOZORDER) == 0)
|
||||||
{
|
{
|
||||||
|
HWND hi;
|
||||||
|
HWND lo;
|
||||||
|
WIN_INTERN *hInf;
|
||||||
|
WIN_INTERN *lInf;
|
||||||
|
|
||||||
|
/* For debugging, log current window stack.
|
||||||
|
*/
|
||||||
|
if (GSDebugSet(@"WTrace") == YES)
|
||||||
|
{
|
||||||
|
NSString *s = @"Window list:\n";
|
||||||
|
|
||||||
|
hi = GetDesktopWindow();
|
||||||
|
hi = GetWindow(hi, GW_CHILD);
|
||||||
|
if (hi > 0)
|
||||||
|
{
|
||||||
|
hi = GetWindow(hi, GW_HWNDLAST);
|
||||||
|
}
|
||||||
|
while (hi > 0)
|
||||||
|
{
|
||||||
|
TCHAR buf[32];
|
||||||
|
|
||||||
|
hi = GetNextWindow(hi, GW_HWNDPREV);
|
||||||
|
|
||||||
|
if (hi > 0
|
||||||
|
&& GetClassName(hi, buf, 32) == 18
|
||||||
|
&& strncmp(buf, "GNUstepWindowClass", 18) == 0)
|
||||||
|
{
|
||||||
|
hInf = (WIN_INTERN *)GetWindowLong(hi, GWL_USERDATA);
|
||||||
|
if (hInf->orderedIn == YES)
|
||||||
|
{
|
||||||
|
s = [s stringByAppendingFormat:
|
||||||
|
@"%d (%d)\n", hi, hInf->level];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NSLog(@"window pos changed: %@", s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This window has changed its z-order, so we take the opportunity
|
||||||
|
* to check that all the GNUstep windows are in the correct order
|
||||||
|
* of their levels.
|
||||||
|
* We do this as a simple bubble sort ...swapping over a pait of
|
||||||
|
* windows if we find any pair in the list which are in the wrong
|
||||||
|
* order. This sort has the virtue of being simple and of
|
||||||
|
* maintaining window order within a level. ... but may be too slow.
|
||||||
|
*/
|
||||||
|
hi = GetDesktopWindow();
|
||||||
|
hi = GetWindow(hi, GW_CHILD);
|
||||||
|
while (hi > 0)
|
||||||
|
{
|
||||||
|
TCHAR buf[32];
|
||||||
|
|
||||||
|
/* Find a GNUstep window which is ordered in and above desktop
|
||||||
|
*/
|
||||||
|
while (hi > 0)
|
||||||
|
{
|
||||||
|
if (GetClassName(hi, buf, 32) == 18
|
||||||
|
&& strncmp(buf, "GNUstepWindowClass", 18) == 0
|
||||||
|
&& (hInf = (WIN_INTERN *)GetWindowLong(hi, GWL_USERDATA))
|
||||||
|
&& hInf->level > NSDesktopWindowLevel
|
||||||
|
&& hInf->orderedIn == YES)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
hi = GetNextWindow(hi, GW_HWNDNEXT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hi > 0)
|
||||||
|
{
|
||||||
|
NSDebugLLog(@"WTrace", @"sort hi %d (%d)", hi, hInf->level);
|
||||||
|
/* Find the next (lower in z-order) GNUstep window which
|
||||||
|
* is ordered in and above desktop
|
||||||
|
*/
|
||||||
|
lo = GetNextWindow(hi, GW_HWNDNEXT);
|
||||||
|
while (lo > 0)
|
||||||
|
{
|
||||||
|
if (GetClassName(lo, buf, 32) == 18
|
||||||
|
&& strncmp(buf, "GNUstepWindowClass", 18) == 0
|
||||||
|
&& (lInf = (WIN_INTERN *)GetWindowLong(lo, GWL_USERDATA))
|
||||||
|
&& lInf->level > NSDesktopWindowLevel
|
||||||
|
&& lInf->orderedIn == YES)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lo = GetNextWindow(lo, GW_HWNDNEXT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lo > 0)
|
||||||
|
{
|
||||||
|
NSDebugLLog(@"WTrace", @"sort lo %d (%d)", lo, lInf->level);
|
||||||
|
/* Check to see if the higher of the two windows should
|
||||||
|
* actually be lower.
|
||||||
|
*/
|
||||||
|
if (hInf->level < lInf->level)
|
||||||
|
{
|
||||||
|
HWND higher;
|
||||||
|
|
||||||
|
/* Insert the low window before the high one.
|
||||||
|
* ie after the window preceding the high one.
|
||||||
|
*/
|
||||||
|
higher = GetNextWindow(hi, GW_HWNDPREV);
|
||||||
|
if (higher == 0)
|
||||||
|
{
|
||||||
|
higher = HWND_TOP;
|
||||||
|
}
|
||||||
|
NSDebugLLog(@"WTrace", @"swap %d (%d) with %d (%d)",
|
||||||
|
hi, hInf->level, lo, lInf->level);
|
||||||
|
SetWindowPos(lo, higher, 0, 0, 0, 0,
|
||||||
|
SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
|
||||||
|
|
||||||
|
/* Done this iteration of the sort ... the next
|
||||||
|
* iteration takes place when we get notified
|
||||||
|
* that the swap we have just donew is complete.
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hi = lo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) decodeWM_WINDOWPOSCHANGINGParams: (WPARAM)wParam : (LPARAM)lParam : (HWND)hwnd
|
||||||
|
{
|
||||||
|
WINDOWPOS *inf = (WINDOWPOS*)lParam;
|
||||||
|
|
||||||
|
if ((inf->flags & SWP_NOZORDER) == 0)
|
||||||
|
{
|
||||||
|
WIN_INTERN *win;
|
||||||
|
|
||||||
/* desktop level windows should stay at the bottom of the
|
/* desktop level windows should stay at the bottom of the
|
||||||
* window list, so we can simply override any re-ordering
|
* window list, so we can simply override any re-ordering
|
||||||
* to ensure that they are at the bottom unless another
|
* to ensure that they are at the bottom unless another
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue