Make WebViews in NSPopovers render as they would in active windows.
authortimothy@apple.com <timothy@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 20 Sep 2011 13:37:35 +0000 (13:37 +0000)
committertimothy@apple.com <timothy@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 20 Sep 2011 13:37:35 +0000 (13:37 +0000)
The NSWindowDid{Become,Resign}KeyNotifications are not fired when NSPopovers
are shown or hidden since they share key with the parent window. So WebView
and WebHTMLView need to also observe the will order on/off screen notifications.

https://webkit.org/b/68402
rdar://problem/9754099

Reviewed by John Sullivan.

* WebView/WebHTMLView.mm:
(-[WebHTMLView _removeWindowObservers]): Remove order on/off screen notification obversers.
(-[WebHTMLView addWindowObservers]): Add order on/off screen notification obversers.
(-[WebHTMLView windowWillOrderOnScreen:]): Check if the window is already a key window,
which can be the case for NSPopovers.
(-[WebHTMLView windowWillOrderOffScreen:]): Remove the mouse moved observer.
* WebView/WebView.mm:
(-[WebView addWindowObserversForWindow:]): Add order off screen notification obverser.
(-[WebView removeWindowObservers]): Remove order off screen notification obverser.
(-[WebView _windowWillOrderOnScreen:]): Call _updateActiveState.
(-[WebView _windowWillOrderOffScreen:]): Ditto.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@95534 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit/mac/ChangeLog
Source/WebKit/mac/WebView/WebHTMLView.mm
Source/WebKit/mac/WebView/WebView.mm

index 72f0178..9710d5d 100644 (file)
@@ -1,3 +1,28 @@
+2011-09-19  Timothy Hatcher  <timothy@apple.com>
+
+        Make WebViews in NSPopovers render as they would in active windows.
+
+        The NSWindowDid{Become,Resign}KeyNotifications are not fired when NSPopovers
+        are shown or hidden since they share key with the parent window. So WebView
+        and WebHTMLView need to also observe the will order on/off screen notifications.
+
+        https://webkit.org/b/68402
+        rdar://problem/9754099
+
+        Reviewed by John Sullivan.
+
+        * WebView/WebHTMLView.mm:
+        (-[WebHTMLView _removeWindowObservers]): Remove order on/off screen notification obversers.
+        (-[WebHTMLView addWindowObservers]): Add order on/off screen notification obversers.
+        (-[WebHTMLView windowWillOrderOnScreen:]): Check if the window is already a key window,
+        which can be the case for NSPopovers.
+        (-[WebHTMLView windowWillOrderOffScreen:]): Remove the mouse moved observer.
+        * WebView/WebView.mm:
+        (-[WebView addWindowObserversForWindow:]): Add order off screen notification obverser.
+        (-[WebView removeWindowObservers]): Remove order off screen notification obverser.
+        (-[WebView _windowWillOrderOnScreen:]): Call _updateActiveState.
+        (-[WebView _windowWillOrderOffScreen:]): Ditto.
+
 2011-09-19  Mark Rowe  <mrowe@apple.com>
 
         <http://webkit.org/b/68421> Stop calling UpdateSystemActivity in places where we hold power assertions that achieve the same effect
index 5773924..090f000 100644 (file)
@@ -932,6 +932,8 @@ static NSURL* uniqueURLWithRelativePart(NSString *relativePart)
     NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
     [notificationCenter removeObserver:self name:NSWindowDidBecomeKeyNotification object:nil];
     [notificationCenter removeObserver:self name:NSWindowDidResignKeyNotification object:nil];
+    [notificationCenter removeObserver:self name:WKWindowWillOrderOnScreenNotification() object:window];
+    [notificationCenter removeObserver:self name:WKWindowWillOrderOffScreenNotification() object:window];
     [notificationCenter removeObserver:self name:NSWindowWillCloseNotification object:window];
     
     _private->observingWindowNotifications = false;
@@ -2859,6 +2861,8 @@ WEBCORE_COMMAND(yankAndSelect)
     NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
     [notificationCenter addObserver:self selector:@selector(windowDidBecomeKey:) name:NSWindowDidBecomeKeyNotification object:nil];
     [notificationCenter addObserver:self selector:@selector(windowDidResignKey:) name:NSWindowDidResignKeyNotification object:nil];
+    [notificationCenter addObserver:self selector:@selector(windowWillOrderOnScreen:) name:WKWindowWillOrderOnScreenNotification() object:window];
+    [notificationCenter addObserver:self selector:@selector(windowWillOrderOffScreen:) name:WKWindowWillOrderOffScreenNotification() object:window];
     [notificationCenter addObserver:self selector:@selector(windowWillClose:) name:NSWindowWillCloseNotification object:window];
     
     _private->observingWindowNotifications = true;
@@ -3378,6 +3382,30 @@ static void setMenuTargets(NSMenu* menu)
     }
 }
 
+- (void)windowWillOrderOnScreen:(NSNotification *)notification
+{
+    if (!pthread_main_np()) {
+        [self performSelectorOnMainThread:_cmd withObject:notification waitUntilDone:NO];
+        return;
+    }
+
+    // Check if the window is already a key window, which can be the case for NSPopovers.
+    if ([[self window] isKeyWindow])
+        [self addMouseMovedObserver];
+}
+
+- (void)windowWillOrderOffScreen:(NSNotification *)notification
+{
+    if (!pthread_main_np()) {
+        [self performSelectorOnMainThread:_cmd withObject:notification waitUntilDone:NO];
+        return;
+    }
+
+    // When the WebView is in a NSPopover the NSWindowDidResignKeyNotification isn't sent
+    // unless the parent window loses key. So we need to remove the mouse moved observer.
+    [self removeMouseMovedObserver];
+}
+
 - (void)windowWillClose:(NSNotification *)notification
 {
     if (!pthread_main_np()) {
index 58f7fc7..b740335 100644 (file)
@@ -3194,6 +3194,8 @@ static NSString * const windowDidChangeResolutionNotification = @"NSWindowDidCha
             name:NSWindowDidResignKeyNotification object:nil];
         [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowWillOrderOnScreen:)
             name:WKWindowWillOrderOnScreenNotification() object:window];
+        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowWillOrderOffScreen:)
+            name:WKWindowWillOrderOffScreenNotification() object:window];
         [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowDidChangeResolution:)
             name:windowDidChangeResolutionNotification object:window];
     }
@@ -3210,6 +3212,8 @@ static NSString * const windowDidChangeResolutionNotification = @"NSWindowDidCha
         [[NSNotificationCenter defaultCenter] removeObserver:self
             name:WKWindowWillOrderOnScreenNotification() object:window];
         [[NSNotificationCenter defaultCenter] removeObserver:self
+            name:WKWindowWillOrderOffScreenNotification() object:window];
+        [[NSNotificationCenter defaultCenter] removeObserver:self
             name:windowDidChangeResolutionNotification object:window];
     }
 }
@@ -3279,10 +3283,23 @@ static NSString * const windowDidChangeResolutionNotification = @"NSWindowDidCha
 
 - (void)_windowWillOrderOnScreen:(NSNotification *)notification
 {
+    // Update the active state here so WebViews in NSPopovers get the active state.
+    // This is needed because the normal NSWindowDidBecomeKeyNotification is not fired
+    // for NSPopover windows since they share key with their parent window.
+    [self _updateActiveState];
+
     if (![self shouldUpdateWhileOffscreen])
         [self setNeedsDisplay:YES];
 }
 
+- (void)_windowWillOrderOffScreen:(NSNotification *)notification
+{
+    // Update the active state here so WebViews in NSPopovers get the inactive state.
+    // This is needed because the normal NSWindowDidResignKeyNotification is not fired
+    // for NSPopover windows since they share key with their parent window.
+    [self _updateActiveState];
+}
+
 - (void)_windowWillClose:(NSNotification *)notification
 {
     if ([self shouldCloseWithWindow] && ([self window] == [self hostWindow] || ([self window] && ![self hostWindow]) || (![self window] && [self hostWindow])))