bug 853252 - check for changed backing scale when we receive a windowDidChangeScreen message. r=smichaud
authorJonathan Kew <jkew@mozilla.com>
Fri, 12 Apr 2013 08:45:50 +0100
changeset 128564 c81138a2c6adff60f2c3975d4b358de2e3f7b0ab
parent 128561 5bc732a49eaecd3e64b2a3afdd3a975ed837b835
child 128565 46c36b3006172b13250882dd255246d5db1cc2b2
push id24532
push userryanvm@gmail.com
push dateFri, 12 Apr 2013 19:06:49 +0000
treeherdermozilla-central@2aff2d574a1e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmichaud
bugs853252
milestone23.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
bug 853252 - check for changed backing scale when we receive a windowDidChangeScreen message. r=smichaud
widget/cocoa/nsCocoaWindow.mm
--- a/widget/cocoa/nsCocoaWindow.mm
+++ b/widget/cocoa/nsCocoaWindow.mm
@@ -1471,16 +1471,19 @@ GetBackingScaleFactor(NSWindow* aWindow)
   // This causes us to handle popup window sizing incorrectly when the
   // popup is resized to zero height (bug 820327) - nsXULPopupManager
   // becomes (incorrectly) convinced the popup has been explicitly forced
   // to a non-default size and needs to have size attributes attached.
 
   // Workaround: instead of asking the window, we'll find the screen it is on
   // and ask that for *its* backing scale factor.
 
+  // (See bug 853252 and additional comments in windowDidChangeScreen: below
+  // for further complications this causes.)
+
   // First, expand the rect so that it actually has a measurable area,
   // for FindTargetScreenForRect to use.
   if (frame.size.width == 0) {
     frame.size.width = 1;
   }
   if (frame.size.height == 0) {
     frame.size.height = 1;
   }
@@ -2178,16 +2181,40 @@ bool nsCocoaWindow::ShouldFocusPlugin()
   mGeckoWindow->ReportSizeEvent();
 }
 
 - (void)windowDidChangeScreen:(NSNotification *)aNotification
 {
   if (!mGeckoWindow)
     return;
 
+  // Because of Cocoa's peculiar treatment of zero-size windows (see comments
+  // at GetBackingScaleFactor() above), we sometimes have a situation where
+  // our concept of backing scale (based on the screen where the zero-sized
+  // window is positioned) differs from Cocoa's idea (always based on the
+  // Retina screen, AFAICT, even when an external non-Retina screen is the
+  // primary display).
+  //
+  // As a result, if the window was created with zero size on an external
+  // display, but then made visible on the (secondary) Retina screen, we
+  // will *not* get a windowDidChangeBackingProperties notification for it.
+  // This leads to an incorrect GetDefaultScale(), and widget coordinate
+  // confusion, as per bug 853252.
+  //
+  // To work around this, we check for a backing scale mismatch when we
+  // receive a windowDidChangeScreen notification, as we will receive this
+  // even if Cocoa was already treating the zero-size window as having
+  // Retina backing scale.
+  NSWindow *window = (NSWindow *)[aNotification object];
+  if ([window respondsToSelector:@selector(backingScaleFactor)]) {
+    if (GetBackingScaleFactor(window) != mGeckoWindow->BackingScaleFactor()) {
+      mGeckoWindow->BackingScaleFactorChanged();
+    }
+  }
+
   mGeckoWindow->ReportMoveEvent();
 }
 
 // Lion's full screen mode will bypass our internal fullscreen tracking, so
 // we need to catch it when we transition and call our own methods, which in
 // turn will fire "fullscreen" events.
 - (void)windowDidEnterFullScreen:(NSNotification *)notification
 {