Bug 868498: Enable switching between overlay and regular scrollbars without browser restart on Mac OSX. r=roc
authorStephen Pohl <spohl.mozilla.bugs@gmail.com>
Tue, 16 Jul 2013 08:58:44 -0400
changeset 138664 a0ba09885dab0505e7d0b754426257d8bef8c81e
parent 138663 3d33faf4d81fd4b1a8739d66d7a48d398ea4c9ea
child 138665 e8bf739addfa78fa844499706b7dc29777cfd497
push id24964
push userryanvm@gmail.com
push dateTue, 16 Jul 2013 20:04:09 +0000
treeherderautoland@fd10ead17ace [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs868498
milestone25.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 868498: Enable switching between overlay and regular scrollbars without browser restart on Mac OSX. r=roc
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsGfxScrollFrame.h
widget/cocoa/nsChildView.mm
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -721,26 +721,27 @@ GetBrowserRoot(nsIContent* aContent)
           frameContent->NodeInfo()->Equals(nsGkAtoms::browser, kNameSpaceID_XUL))
         return frameContent;
     }
   }
 
   return nullptr;
 }
 
-
 NS_IMETHODIMP
 nsHTMLScrollFrame::Reflow(nsPresContext*           aPresContext,
                           nsHTMLReflowMetrics&     aDesiredSize,
                           const nsHTMLReflowState& aReflowState,
                           nsReflowStatus&          aStatus)
 {
   DO_GLOBAL_REFLOW_COUNT("nsHTMLScrollFrame");
   DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
 
+  mInner.HandleScrollbarStyleSwitching();
+
   ScrollReflowState state(this, aReflowState);
   // sanity check: ensure that if we have no scrollbar, we treat it
   // as hidden.
   if (!mInner.mVScrollbarBox || mInner.mNeverHasVerticalScrollbar)
     state.mStyles.mVertical = NS_STYLE_OVERFLOW_HIDDEN;
   if (!mInner.mHScrollbarBox || mInner.mNeverHasHorizontalScrollbar)
     state.mStyles.mHorizontal = NS_STYLE_OVERFLOW_HIDDEN;
 
@@ -769,20 +770,16 @@ nsHTMLScrollFrame::Reflow(nsPresContext*
       reflowScrollCorner = showResizer == mInner.mCollapsedResizer;
       mInner.mCollapsedResizer = !showResizer;
     }
   }
 
   nsRect oldScrollAreaBounds = mInner.mScrollPort;
   nsRect oldScrolledAreaBounds =
     mInner.mScrolledFrame->GetScrollableOverflowRectRelativeToParent();
-  // Adjust to a multiple of device pixels to restore the invariant that
-  // oldScrollPosition is a multiple of device pixels. This could have been
-  // thrown out by a zoom change.
-  nsIntPoint ptDevPx;
   nsPoint oldScrollPosition = mInner.GetScrollPosition();
 
   state.mComputedBorder = aReflowState.mComputedBorderPadding -
     aReflowState.mComputedPadding;
 
   nsresult rv = ReflowContents(&state, aDesiredSize);
   if (NS_FAILED(rv))
     return rv;
@@ -966,16 +963,33 @@ nsGfxScrollFrameInner::GetNondisappearin
         }
       }
     }
   }
 
   return GetDesiredScrollbarSizes(aState).LeftRight();
 }
 
+void
+nsGfxScrollFrameInner::HandleScrollbarStyleSwitching()
+{
+  // Check if we switched between scrollbar styles.
+  if (mScrollbarActivity &&
+      LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars) == 0) {
+    mScrollbarActivity->Destroy();
+    mScrollbarActivity = nullptr;
+    mOuter->PresContext()->ThemeChanged();
+  }
+  else if (!mScrollbarActivity &&
+           LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars) != 0) {
+    mScrollbarActivity = new ScrollbarActivity(do_QueryFrame(mOuter));
+    mOuter->PresContext()->ThemeChanged();
+  }
+}
+
 nsresult
 nsXULScrollFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
 {
   return mInner.CreateAnonymousContent(aElements);
 }
 
 void
 nsXULScrollFrame::AppendAnonymousContentTo(nsBaseContentList& aElements,
--- a/layout/generic/nsGfxScrollFrame.h
+++ b/layout/generic/nsGfxScrollFrame.h
@@ -264,16 +264,18 @@ public:
   bool IsAlwaysActive() const;
   void MarkActive();
   void MarkInactive();
   nsExpirationState* GetExpirationState() { return &mActivityExpirationState; }
 
   void ScheduleSyntheticMouseMove();
   static void ScrollActivityCallback(nsITimer *aTimer, void* anInstance);
 
+  void HandleScrollbarStyleSwitching();
+
   // owning references to the nsIAnonymousContentCreator-built content
   nsCOMPtr<nsIContent> mHScrollbarContent;
   nsCOMPtr<nsIContent> mVScrollbarContent;
   nsCOMPtr<nsIContent> mScrollCornerContent;
   nsCOMPtr<nsIContent> mResizerContent;
 
   nsRevocableEventPtr<ScrollEvent> mScrollEvent;
   nsRevocableEventPtr<AsyncScrollPortEvent> mAsyncScrollPortEvent;
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -2803,17 +2803,17 @@ NSEvent* gLastDragMouseDownEvent = nil;
                                                name:NSControlTintDidChangeNotification
                                              object:nil];
   [[NSNotificationCenter defaultCenter] addObserver:self
                                            selector:@selector(systemMetricsChanged)
                                                name:NSSystemColorsDidChangeNotification
                                              object:nil];
   // TODO: replace the string with the constant once we build with the 10.7 SDK
   [[NSNotificationCenter defaultCenter] addObserver:self
-                                           selector:@selector(systemMetricsChanged)
+                                           selector:@selector(scrollbarSystemMetricChanged)
                                                name:@"NSPreferredScrollerStyleDidChangeNotification"
                                              object:nil];
   [[NSDistributedNotificationCenter defaultCenter] addObserver:self
                                                       selector:@selector(systemMetricsChanged)
                                                           name:@"AppleAquaScrollBarVariantChanged"
                                                         object:nil
                                             suspensionBehavior:NSNotificationSuspensionBehaviorDeliverImmediately]; 
   [[NSNotificationCenter defaultCenter] addObserver:self
@@ -2956,16 +2956,28 @@ NSEvent* gLastDragMouseDownEvent = nil;
 }
 
 - (void)systemMetricsChanged
 {
   if (mGeckoChild)
     mGeckoChild->NotifyThemeChanged();
 }
 
+- (void)scrollbarSystemMetricChanged
+{
+  [self systemMetricsChanged];
+
+  if (mGeckoChild) {
+    nsIWidgetListener* listener = mGeckoChild->GetWidgetListener();
+    if (listener) {
+      listener->GetPresShell()->ReconstructFrames();
+    }
+  }
+}
+
 - (void)setNeedsPendingDisplay
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
 
   mPendingFullDisplay = YES;
   if (!mPendingDisplay) {
     [self performSelector:@selector(processPendingRedraws) withObject:nil afterDelay:0];
     mPendingDisplay = YES;