From 10792c0bc6adbee9b91d65690be32294d652edb2 Mon Sep 17 00:00:00 2001 From: Alexandre Wilhelm Date: Mon, 6 Apr 2015 17:37:08 -0700 Subject: [PATCH] New: Added listener onblur and onfocus on the CPPlatformWindow for updating keyWindow and firstResponder Previously, when switching from a platformWindow to another platformWindow or to another application, Cappuccino did not behave as Cocoa, Cappuccino still considered that the window was key and main. Now it works as in cocoa, the platform window lost its focus and is not the keyWindow and mainWindow of the cappuccino application. Test app in Tests/Manual/CPPlatformWindow/ --- AppKit/CPWindow/CPWindow.j | 1 + AppKit/Platform/DOM/CPPlatformWindow+DOM.j | 53 +++++++++++++++++++++- 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/AppKit/CPWindow/CPWindow.j b/AppKit/CPWindow/CPWindow.j index 7fb67763e..9b6dde66b 100644 --- a/AppKit/CPWindow/CPWindow.j +++ b/AppKit/CPWindow/CPWindow.j @@ -984,6 +984,7 @@ CPTexturedBackgroundWindowMask [[CPNotificationCenter defaultCenter] removeObserver:self name:_CPPlatformWindowWillCloseNotification object:nil]; [[self contentView] _removeObservers]; + _hasBecomeKeyWindow = NO; } diff --git a/AppKit/Platform/DOM/CPPlatformWindow+DOM.j b/AppKit/Platform/DOM/CPPlatformWindow+DOM.j index 3cab0b5b9..1ab6ae7ab 100644 --- a/AppKit/Platform/DOM/CPPlatformWindow+DOM.j +++ b/AppKit/Platform/DOM/CPPlatformWindow+DOM.j @@ -396,7 +396,15 @@ _CPPlatformWindowWillCloseNotification = @"_CPPlatformWindowWillCloseNotificatio touchEventSelector = @selector(touchEvent:), touchEventImplementation = class_getMethodImplementation(theClass, touchEventSelector), - touchEventCallback = function (anEvent) { touchEventImplementation(self, nil, anEvent); }; + touchEventCallback = function (anEvent) { touchEventImplementation(self, nil, anEvent); }, + + onFocusEventSelector = @selector(focusEvent:), + onFocusEventImplementation = class_getMethodImplementation(theClass, onFocusEventSelector), + onFocusEventCallback = function (anEvent) { onFocusEventImplementation(self, nil, anEvent); }, + + onBlurEventSelector = @selector(blurEvent:), + onBlurEventImplementation = class_getMethodImplementation(theClass, onBlurEventSelector), + onBlurEventCallback = function (anEvent) { onBlurEventImplementation(self, nil, anEvent); }; if (theDocument.addEventListener) { @@ -430,6 +438,9 @@ _CPPlatformWindowWillCloseNotification = @"_CPPlatformWindowWillCloseNotificatio _DOMWindow.addEventListener("resize", resizeEventCallback, NO); + _DOMWindow.addEventListener("blur", onBlurEventCallback, NO); + _DOMWindow.addEventListener("focus", onFocusEventCallback, NO); + _DOMWindow.addEventListener("unload", function() { _DOMWindow.removeEventListener("unload", arguments.callee, NO); @@ -453,6 +464,9 @@ _CPPlatformWindowWillCloseNotification = @"_CPPlatformWindowWillCloseNotificatio _DOMWindow.removeEventListener("resize", resizeEventCallback, NO); + _DOMWindow.removeEventListener("blur", onBlurEventCallback, NO); + _DOMWindow.removeEventListener("focus", onFocusEventCallback, NO); + //FIXME: does firefox really need a different value? _DOMWindow.removeEventListener("DOMMouseScroll", scrollEventCallback, NO); _DOMWindow.removeEventListener("wheel", scrollEventCallback, NO); @@ -479,6 +493,9 @@ _CPPlatformWindowWillCloseNotification = @"_CPPlatformWindowWillCloseNotificatio _DOMWindow.attachEvent("onresize", resizeEventCallback); + _DOMWindow.attachEvent("onblur", onBlurEventCallback); + _DOMWindow.attachEvent("onfocus", onFocusEventCallback); + _DOMWindow.onmousewheel = scrollEventCallback; theDocument.onmousewheel = scrollEventCallback; @@ -505,7 +522,11 @@ _CPPlatformWindowWillCloseNotification = @"_CPPlatformWindowWillCloseNotificatio _DOMWindow.detachEvent("onresize", resizeEventCallback); + _DOMWindow.detachEvent("onblur", onBlurEventCallback); + _DOMWindow.detachEvent("onfocus", onFocusEventCallback); + _DOMWindow.onmousewheel = NULL; + theDocument.onmousewheel = NULL; _DOMBodyElement.ondrag = NULL; @@ -1031,6 +1052,28 @@ _CPPlatformWindowWillCloseNotification = @"_CPPlatformWindowWillCloseNotificatio _shouldUpdateContentRect = YES; } +/*! + @ignore +*/ +- (void)blurEvent:(DOMEvent)aDOMEvent +{ + var location = _lastMouseEventLocation || CGPointMakeZero(), + theWindow = [self _hitTest:location withTest:@selector(_isValidMousePoint:) returnsDefaultWindowIfNull:YES]; + + [theWindow resignKeyWindow]; +} + +/*! + @ignore +*/ +- (void)focusEvent:(DOMEvent)aDOMEvent +{ + var location = _lastMouseEventLocation || CGPointMakeZero(), + theWindow = [self _hitTest:location withTest:@selector(_isValidMousePoint:) returnsDefaultWindowIfNull:YES]; + + [theWindow makeKeyAndOrderFront:self]; +} + - (void)touchEvent:(DOMEvent)aDOMEvent { if (aDOMEvent.touches && (aDOMEvent.touches.length == 1 || (aDOMEvent.touches.length == 0 && aDOMEvent.changedTouches.length == 1))) @@ -1517,6 +1560,11 @@ _CPPlatformWindowWillCloseNotification = @"_CPPlatformWindowWillCloseNotificatio } - (CPWindow)_hitTest:(CGPoint)location withTest:(SEL)aTest +{ + return [self _hitTest:location withTest:aTest returnsDefaultWindowIfNull:NO]; +} + +- (CPWindow)_hitTest:(CGPoint)location withTest:(SEL)aTest returnsDefaultWindowIfNull:(BOOL)returnsDefaultWindowIfNull { if (self._only) return self._only; @@ -1540,6 +1588,9 @@ _CPPlatformWindowWillCloseNotification = @"_CPPlatformWindowWillCloseNotificatio } } + if (!theWindow && returnsDefaultWindowIfNull) + theWindow = [[[layers objectForKey:[levels firstObject]] orderedWindows] firstObject]; + return theWindow; }