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 174265 80ae75938371e3ca39f011c612710fda52b5da2c
parent 174264 fa43b2934acee32ed70d828aa73e5d000b7e36b7
child 174266 361907c4a2ce95f67a6f618ecf7cf10a57cbc653
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimm, tn
bugs934811
milestone28.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 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;