From c514fd7a08ca472cfceb338fd466029da366a314 Mon Sep 17 00:00:00 2001 From: Ross Boucher Date: Sat, 6 Mar 2010 00:57:59 -0800 Subject: [PATCH] Fix an issue where window levels weren't kept in sync with dom window layers. Closes #507. --- AppKit/CPMenu/_CPMenuBarWindow.j | 3 +-- AppKit/CPWindow/CPWindow.j | 5 +++++ AppKit/Platform/CPPlatformWindow.j | 14 ++++++++++++ AppKit/Platform/DOM/CPPlatformWindow+DOM.j | 25 ++++++++++++++-------- 4 files changed, 36 insertions(+), 11 deletions(-) diff --git a/AppKit/CPMenu/_CPMenuBarWindow.j b/AppKit/CPMenu/_CPMenuBarWindow.j index da829d047..29e582016 100644 --- a/AppKit/CPMenu/_CPMenuBarWindow.j +++ b/AppKit/CPMenu/_CPMenuBarWindow.j @@ -61,8 +61,7 @@ var _CPMenuBarWindowBackgroundColor = nil, if (self) { - // FIXME: http://280north.lighthouseapp.com/projects/13294-cappuccino/tickets/39-dont-allow-windows-to-go-above-menubar - [self setLevel:-1];//CPTornOffMenuWindowLevel]; + [self setLevel:CPMainMenuWindowLevel]; [self setAutoresizingMask:CPWindowWidthSizable]; var contentView = [self contentView]; diff --git a/AppKit/CPWindow/CPWindow.j b/AppKit/CPWindow/CPWindow.j index e68c33174..11d029994 100644 --- a/AppKit/CPWindow/CPWindow.j +++ b/AppKit/CPWindow/CPWindow.j @@ -783,6 +783,11 @@ CPTexturedBackgroundWindowMask */ - (void)setLevel:(int)aLevel { + if (aLevel === _level) + return; + + [_platformWindow moveWindow:self fromLevel:_level toLevel:aLevel]; + _level = aLevel; if ([self _sharesChromeWithPlatformWindow]) diff --git a/AppKit/Platform/CPPlatformWindow.j b/AppKit/Platform/CPPlatformWindow.j index d9716d77f..3f253aeac 100644 --- a/AppKit/Platform/CPPlatformWindow.j +++ b/AppKit/Platform/CPPlatformWindow.j @@ -196,6 +196,20 @@ var PrimaryPlatformWindow = NULL; #endif } +- (void)moveWindow:(CPWindow)aWindow fromLevel:(int)fromLevel toLevel:(int)toLevel +{ +#if PLATFORM(DOM) + if (!aWindow._isVisible) + return; + + var fromLayer = [self layerAtLevel:fromLevel create:NO], + toLayer = [self layerAtLevel:toLevel create:YES]; + + [fromLayer removeWindow:aWindow]; + [toLayer insertWindow:aWindow atIndex:CPNotFound]; +#endif +} + - (void)setLevel:(CPInteger)aLevel { _level = aLevel; diff --git a/AppKit/Platform/DOM/CPPlatformWindow+DOM.j b/AppKit/Platform/DOM/CPPlatformWindow+DOM.j index 1e7f8d835..c90ad06c0 100644 --- a/AppKit/Platform/DOM/CPPlatformWindow+DOM.j +++ b/AppKit/Platform/DOM/CPPlatformWindow+DOM.j @@ -305,7 +305,6 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; touchEventImplementation = class_getMethodImplementation(theClass, touchEventSelector), touchEventCallback = function (anEvent) { touchEventImplementation(self, nil, anEvent); }; - if (theDocument.addEventListener) { if ([CPPlatform supportsDragAndDrop]) @@ -1109,7 +1108,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; (CPArray)orderedWindowsAtLevel:(int)aLevel { var layer = [self layerAtLevel:aLevel create:NO]; - + if (!layer) return []; @@ -1119,7 +1118,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; - (CPDOMWindowLayer)layerAtLevel:(int)aLevel create:(BOOL)aFlag { var layer = [_windowLayers objectForKey:aLevel]; - + // If the layer doesn't currently exist, and the create flag is true, // create the layer. if (!layer && aFlag) @@ -1127,7 +1126,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; layer = [[CPDOMWindowLayer alloc] initWithLevel:aLevel]; [_windowLayers setObject:layer forKey:aLevel]; - + // Find the nearest layer. This is similar to a binary search, // only we know we won't find the value. var low = 0, @@ -1144,7 +1143,11 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; low = middle + 1; } - [_windowLevels insertObject:aLevel atIndex:_windowLevels[middle] > aLevel ? middle : middle + 1]; + var insertionIndex = 0; + if (middle !== undefined) + insertionIndex = _windowLevels[middle] > aLevel ? middle : middle + 1 + + [_windowLevels insertObject:aLevel atIndex:insertionIndex]; layer._DOMElement.style.zIndex = aLevel; _DOMBodyElement.appendChild(layer._DOMElement); } @@ -1158,15 +1161,19 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; // Grab the appropriate level for the layer, and create it if // necessary (if we are not simply removing the window). - var layer = [self layerAtLevel:[aWindow level] create:aPlace != CPWindowOut]; - + var layer = [self layerAtLevel:[aWindow level] create:aPlace !== CPWindowOut]; + // Ignore otherWindow, simply remove this window from it's level. // If layer is nil, this will be a no-op. - if (aPlace == CPWindowOut) + if (aPlace === CPWindowOut) return [layer removeWindow:aWindow]; + var insertionIndex = CPNotFound; + if (otherWindow) + insertionIndex = aPlace === CPWindowAbove ? otherWindow._index + 1 : otherWindow._index; + // Place the window at the appropriate index. - [layer insertWindow:aWindow atIndex:(otherWindow ? (aPlace == CPWindowAbove ? otherWindow._index + 1 : otherWindow._index) : CPNotFound)]; + [layer insertWindow:aWindow atIndex:insertionIndex]; } - (void)_removeLayers