Bug 934811 - Ensure that no scrollbars are displayed for touch input. r=jimm,tn
authorStephen Pohl <spohl.mozilla.bugs@gmail.com>
Tue, 03 Dec 2013 13:21:09 -0500
changeset 167760 80ae75938371e3ca39f011c612710fda52b5da2c
parent 167759 fa43b2934acee32ed70d828aa73e5d000b7e36b7
child 167761 361907c4a2ce95f67a6f618ecf7cf10a57cbc653
push id4703
push userakeybl@mozilla.com
push dateMon, 09 Dec 2013 20:24:19 +0000
treeherdermozilla-aurora@20af7fbd96c1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimm, tn
bugs934811
milestone28.0a1
Bug 934811 - Ensure that no scrollbars are displayed for touch input. r=jimm,tn
gfx/src/nsITheme.h
layout/generic/nsGfxScrollFrame.cpp
widget/windows/WinUtils.cpp
widget/windows/WinUtils.h
widget/windows/nsNativeThemeWin.cpp
widget/windows/nsNativeThemeWin.h
widget/windows/winrt/MetroInput.cpp
widget/windows/winrt/MetroInput.h
--- a/gfx/src/nsITheme.h
+++ b/gfx/src/nsITheme.h
@@ -152,16 +152,22 @@ public:
    * Does the nsITheme implementation draw its own focus ring for this widget?
    */
   virtual bool ThemeDrawsFocusForWidget(uint8_t aWidgetType)=0;
   
   /**
     * Should we insert a dropmarker inside of combobox button?
    */
   virtual bool ThemeNeedsComboboxDropmarker()=0;
+
+  /**
+   * Should we hide scrollbars?
+   */
+  virtual bool ShouldHideScrollbars()
+  { return false; }
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsITheme, NS_ITHEME_IID)
 
 // Creator function
 extern nsresult NS_NewNativeTheme(nsISupports *aOuter, REFNSIID aIID, void **aResult);
 
 #endif
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -2090,16 +2090,22 @@ struct HoveredStateComparator
 
 void
 ScrollFrameHelper::AppendScrollPartsTo(nsDisplayListBuilder*   aBuilder,
                                            const nsRect&           aDirtyRect,
                                            const nsDisplayListSet& aLists,
                                            bool&                   aCreateLayer,
                                            bool                    aPositioned)
 {
+  nsITheme* theme = mOuter->PresContext()->GetTheme();
+  if (theme &&
+      theme->ShouldHideScrollbars()) {
+    return;
+  }
+
   bool overlayScrollbars =
     LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars) != 0;
 
   nsAutoTArray<nsIFrame*, 3> scrollParts;
   for (nsIFrame* kid = mOuter->GetFirstPrincipalChild(); kid; kid = kid->GetNextSibling()) {
     if (kid == mScrolledFrame ||
         (kid->IsPositioned() || overlayScrollbars) != aPositioned)
       continue;
--- a/widget/windows/WinUtils.cpp
+++ b/widget/windows/WinUtils.cpp
@@ -30,16 +30,19 @@
 #include "nsIDownloader.h"
 #include "nsINetUtil.h"
 #include "nsIChannel.h"
 #include "nsIObserver.h"
 #include "imgIEncoder.h"
 #include "nsIThread.h"
 #include "MainThreadUtils.h"
 #include "gfxColor.h"
+#ifdef MOZ_METRO
+#include "winrt/MetroInput.h"
+#endif // MOZ_METRO
 
 #ifdef NS_ENABLE_TSF
 #include <textstor.h>
 #include "nsTextStore.h"
 #endif // #ifdef NS_ENABLE_TSF
 
 #ifdef PR_LOGGING
 PRLogModuleInfo* gWindowsLog = nullptr;
@@ -1172,11 +1175,22 @@ WinUtils::SetupKeyModifiersSequence(nsTA
   for (uint32_t i = 0; i < ArrayLength(sModifierKeyMap); ++i) {
     const uint32_t* map = sModifierKeyMap[i];
     if (aModifiers & map[0]) {
       aArray->AppendElement(KeyPair(map[1], map[2]));
     }
   }
 }
 
+/* static */
+bool
+WinUtils::ShouldHideScrollbars()
+{
+#ifdef MOZ_METRO
+  if (XRE_GetWindowsEnvironment() == WindowsEnvironmentType_Metro) {
+    return widget::winrt::MetroInput::IsInputModeImprecise();
+  }
+#endif // MOZ_METRO
+  return false;
+}
 
 } // namespace widget
 } // namespace mozilla
--- a/widget/windows/WinUtils.h
+++ b/widget/windows/WinUtils.h
@@ -314,16 +314,18 @@ public:
   static DwmGetWindowAttributeProc dwmGetWindowAttributePtr;
   static DwmSetWindowAttributeProc dwmSetWindowAttributePtr;
   static DwmInvalidateIconicBitmapsProc dwmInvalidateIconicBitmapsPtr;
   static DwmDefWindowProcProc dwmDwmDefWindowProcPtr;
   static DwmGetCompositionTimingInfoProc dwmGetCompositionTimingInfoPtr;
 
   static void Initialize();
 
+  static bool ShouldHideScrollbars();
+
 private:
   typedef HRESULT (WINAPI * SHCreateItemFromParsingNamePtr)(PCWSTR pszPath,
                                                             IBindCtx *pbc,
                                                             REFIID riid,
                                                             void **ppv);
   static SHCreateItemFromParsingNamePtr sCreateItemFromParsingName;
   typedef HRESULT (WINAPI * SHGetKnownFolderPathPtr)(REFKNOWNFOLDERID rfid,
                                                      DWORD dwFlags,
--- a/widget/windows/nsNativeThemeWin.cpp
+++ b/widget/windows/nsNativeThemeWin.cpp
@@ -19,29 +19,31 @@
 #include "nsIDOMHTMLInputElement.h"
 #include "nsLookAndFeel.h"
 #include "nsMenuFrame.h"
 #include "nsGkAtoms.h"
 #include <malloc.h>
 #include "nsWindow.h"
 #include "nsIComboboxControlFrame.h"
 #include "prinrval.h"
+#include "WinUtils.h"
 
 #include "gfxPlatform.h"
 #include "gfxContext.h"
 #include "gfxMatrix.h"
 #include "gfxWindowsPlatform.h"
 #include "gfxWindowsSurface.h"
 #include "gfxWindowsNativeDrawing.h"
 
 #include "nsUXThemeData.h"
 #include "nsUXThemeConstants.h"
 #include <algorithm>
 
 using mozilla::IsVistaOrLater;
+using namespace mozilla::widget;
 
 #ifdef PR_LOGGING
 extern PRLogModuleInfo* gWindowsLog;
 #endif
 
 NS_IMPL_ISUPPORTS_INHERITED1(nsNativeThemeWin, nsNativeTheme, nsITheme)
 
 nsNativeThemeWin::nsNativeThemeWin() :
@@ -2598,16 +2600,22 @@ nsNativeThemeWin::WidgetAppearanceDepend
     case NS_THEME_WINDOW_BUTTON_MAXIMIZE:
     case NS_THEME_WINDOW_BUTTON_RESTORE:
       return true;
     default:
       return false;
   }
 }
 
+bool
+nsNativeThemeWin::ShouldHideScrollbars()
+{
+  return WinUtils::ShouldHideScrollbars();
+}
+
 nsITheme::Transparency
 nsNativeThemeWin::GetWidgetTransparency(nsIFrame* aFrame, uint8_t aWidgetType)
 {
   switch (aWidgetType) {
   case NS_THEME_SCROLLBAR_SMALL:
   case NS_THEME_SCROLLBAR:
   case NS_THEME_STATUSBAR:
     // Knowing that scrollbars and statusbars are opaque improves
--- a/widget/windows/nsNativeThemeWin.h
+++ b/widget/windows/nsNativeThemeWin.h
@@ -64,16 +64,18 @@ public:
   bool WidgetIsContainer(uint8_t aWidgetType);
 
   bool ThemeDrawsFocusForWidget(uint8_t aWidgetType) MOZ_OVERRIDE;
 
   bool ThemeNeedsComboboxDropmarker();
 
   virtual bool WidgetAppearanceDependsOnWindowFocus(uint8_t aWidgetType) MOZ_OVERRIDE;
 
+  virtual bool ShouldHideScrollbars() MOZ_OVERRIDE;
+
   nsNativeThemeWin();
   virtual ~nsNativeThemeWin();
 
 protected:
   HANDLE GetTheme(uint8_t aWidgetType);
   nsresult GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType,
                                 int32_t& aPart, int32_t& aState);
   nsresult ClassicGetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType,
--- a/widget/windows/winrt/MetroInput.cpp
+++ b/widget/windows/winrt/MetroInput.cpp
@@ -202,21 +202,23 @@ namespace {
     WidgetGUIEvent* mPtr;
   };
 }
 
 namespace mozilla {
 namespace widget {
 namespace winrt {
 
+MetroInput::InputPrecisionLevel MetroInput::sCurrentInputLevel =
+  MetroInput::InputPrecisionLevel::LEVEL_IMPRECISE;
+
 MetroInput::MetroInput(MetroWidget* aWidget,
                        UI::Core::ICoreWindow* aWindow)
               : mWidget(aWidget),
                 mChromeHitTestCacheForTouch(false),
-                mCurrentInputLevel(LEVEL_IMPRECISE),
                 mWindow(aWindow)
 {
   LogFunction();
   NS_ASSERTION(aWidget, "Attempted to create MetroInput for null widget!");
   NS_ASSERTION(aWindow, "Attempted to create MetroInput for null window!");
 
   mTokenPointerPressed.value = 0;
   mTokenPointerReleased.value = 0;
@@ -239,31 +241,36 @@ MetroInput::MetroInput(MetroWidget* aWid
 }
 
 MetroInput::~MetroInput()
 {
   LogFunction();
   UnregisterInputEvents();
 }
 
+/* static */
+bool MetroInput::IsInputModeImprecise()
+{
+  return sCurrentInputLevel == LEVEL_IMPRECISE;
+}
 
 /**
  * Tracks the current input level (precise/imprecise) and fires an observer
  * when the mode changes.
  */
 void
 MetroInput::UpdateInputLevel(InputPrecisionLevel aInputLevel)
 {
   // ignore mouse input if we have active touch input.
   if (aInputLevel == LEVEL_PRECISE && mTouches.Count() > 0) {
     return;
   }
-  if (mCurrentInputLevel != aInputLevel) {
-    mCurrentInputLevel = aInputLevel;
-    MetroUtils::FireObserver(mCurrentInputLevel == LEVEL_PRECISE ?
+  if (sCurrentInputLevel != aInputLevel) {
+    sCurrentInputLevel = aInputLevel;
+    MetroUtils::FireObserver(sCurrentInputLevel == LEVEL_PRECISE ?
                                "metro_precise_input" : "metro_imprecise_input");
   }
 }
 
 /**
  * Processes an IEdgeGestureEventArgs and returns the input source type
  * for the event. Also updates input level via UpdateInputLevel.
  */
--- a/widget/windows/winrt/MetroInput.h
+++ b/widget/windows/winrt/MetroInput.h
@@ -140,29 +140,31 @@ public:
   // Tap gesture callback from the GestureRecognizer.
   HRESULT OnTapped(IGestureRecognizer* aSender, ITappedEventArgs* aArgs);
   HRESULT OnRightTapped(IGestureRecognizer* aSender,
                         IRightTappedEventArgs* aArgs);
 
   void HandleTap(const Point& aPoint, unsigned int aTapCount);
   void HandleLongTap(const Point& aPoint);
 
+  static bool IsInputModeImprecise();
+
 private:
   Microsoft::WRL::ComPtr<ICoreWindow> mWindow;
   Microsoft::WRL::ComPtr<MetroWidget> mWidget;
   Microsoft::WRL::ComPtr<IGestureRecognizer> mGestureRecognizer;
 
   ModifierKeyState mModifierKeyState;
 
   // Tracking input level
   enum InputPrecisionLevel {
     LEVEL_PRECISE,
     LEVEL_IMPRECISE
   };
-  InputPrecisionLevel mCurrentInputLevel;
+  static InputPrecisionLevel sCurrentInputLevel;
   void UpdateInputLevel(InputPrecisionLevel aInputLevel);
 
   // Initialization/Uninitialization helpers
   void RegisterInputEvents();
   void UnregisterInputEvents();
 
   // Hit testing for chrome content
   bool mChromeHitTestCacheForTouch;