widget/windows/winrt/MetroInput.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #pragma once
     8 // Moz headers (alphabetical)
     9 #include "keyboardlayout.h"   // mModifierKeyState
    10 #include "nsBaseHashtable.h"  // mTouches
    11 #include "nsHashKeys.h"       // type of key for mTouches
    12 #include "mozwrlbase.h"
    13 #include "nsDeque.h"
    14 #include "mozilla/EventForwards.h"
    15 #include "mozilla/layers/APZCTreeManager.h"
    17 // System headers (alphabetical)
    18 #include <EventToken.h>     // EventRegistrationToken
    19 #include <stdint.h>         // uint32_t
    20 #include <wrl\client.h>     // Microsoft::WRL::ComPtr class
    21 #include <wrl\implements.h> // Microsoft::WRL::InspectableClass macro
    23 // Moz forward declarations
    24 class MetroWidget;
    25 struct nsIntPoint;
    27 namespace mozilla {
    28 namespace dom {
    29 class Touch;
    30 }
    31 }
    33 // Windows forward declarations
    34 namespace ABI {
    35   namespace Windows {
    36     namespace Devices {
    37       namespace Input {
    38         enum PointerDeviceType;
    39       }
    40     };
    41     namespace Foundation {
    42       struct Point;
    43     };
    44     namespace UI {
    45       namespace Core {
    46         struct ICoreWindow;
    47         struct IAcceleratorKeyEventArgs;
    48         struct IKeyEventArgs;
    49         struct IPointerEventArgs;
    50       };
    51       namespace Input {
    52         struct IEdgeGesture;
    53         struct IEdgeGestureEventArgs;
    54         struct IGestureRecognizer;
    55         struct IManipulationCompletedEventArgs;
    56         struct IManipulationStartedEventArgs;
    57         struct IManipulationUpdatedEventArgs;
    58         struct IPointerPoint;
    59         struct IRightTappedEventArgs;
    60         struct ITappedEventArgs;
    61         struct ManipulationDelta;
    62       };
    63     };
    64   };
    65 };
    67 namespace mozilla {
    68 namespace widget {
    69 namespace winrt {
    71 class MetroInput : public Microsoft::WRL::RuntimeClass<IInspectable>
    72 {
    73   InspectableClass(L"MetroInput", BaseTrust);
    75 private:
    76   typedef mozilla::layers::AllowedTouchBehavior AllowedTouchBehavior;
    77   typedef uint32_t TouchBehaviorFlags;
    79   // Devices
    80   typedef ABI::Windows::Devices::Input::PointerDeviceType PointerDeviceType;
    82   // Foundation
    83   typedef ABI::Windows::Foundation::Point Point;
    85   // UI::Core
    86   typedef ABI::Windows::UI::Core::ICoreWindow ICoreWindow;
    87   typedef ABI::Windows::UI::Core::IAcceleratorKeyEventArgs \
    88                                   IAcceleratorKeyEventArgs;
    89   typedef ABI::Windows::UI::Core::IKeyEventArgs IKeyEventArgs;
    90   typedef ABI::Windows::UI::Core::IPointerEventArgs IPointerEventArgs;
    92   // UI::Input
    93   typedef ABI::Windows::UI::Input::IEdgeGesture IEdgeGesture;
    94   typedef ABI::Windows::UI::Input::IEdgeGestureEventArgs IEdgeGestureEventArgs;
    95   typedef ABI::Windows::UI::Input::IGestureRecognizer IGestureRecognizer;
    96   typedef ABI::Windows::UI::Input::IManipulationCompletedEventArgs \
    97                                    IManipulationCompletedEventArgs;
    98   typedef ABI::Windows::UI::Input::IManipulationStartedEventArgs \
    99                                    IManipulationStartedEventArgs;
   100   typedef ABI::Windows::UI::Input::IManipulationUpdatedEventArgs \
   101                                    IManipulationUpdatedEventArgs;
   102   typedef ABI::Windows::UI::Input::IPointerPoint IPointerPoint;
   103   typedef ABI::Windows::UI::Input::IRightTappedEventArgs IRightTappedEventArgs;
   104   typedef ABI::Windows::UI::Input::ITappedEventArgs ITappedEventArgs;
   105   typedef ABI::Windows::UI::Input::ManipulationDelta ManipulationDelta;
   107   typedef mozilla::layers::ScrollableLayerGuid ScrollableLayerGuid;
   109 public:
   110   MetroInput(MetroWidget* aWidget,
   111              ICoreWindow* aWindow);
   112   virtual ~MetroInput();
   114   // These input events are received from our window. These are basic
   115   // pointer and keyboard press events. MetroInput responds to them
   116   // by sending gecko events and forwarding these input events to its
   117   // GestureRecognizer to be processed into more complex input events
   118   // (tap, rightTap, rotate, etc)
   119   HRESULT OnPointerPressed(ICoreWindow* aSender,
   120                            IPointerEventArgs* aArgs);
   121   HRESULT OnPointerReleased(ICoreWindow* aSender,
   122                             IPointerEventArgs* aArgs);
   123   HRESULT OnPointerMoved(ICoreWindow* aSender,
   124                          IPointerEventArgs* aArgs);
   125   HRESULT OnPointerEntered(ICoreWindow* aSender,
   126                            IPointerEventArgs* aArgs);
   127   HRESULT OnPointerExited(ICoreWindow* aSender,
   128                           IPointerEventArgs* aArgs);
   130   // The Edge gesture event is special.  It does not come from our window
   131   // or from our GestureRecognizer.
   132   HRESULT OnEdgeGestureStarted(IEdgeGesture* aSender,
   133                                IEdgeGestureEventArgs* aArgs);
   134   HRESULT OnEdgeGestureCanceled(IEdgeGesture* aSender,
   135                                 IEdgeGestureEventArgs* aArgs);
   136   HRESULT OnEdgeGestureCompleted(IEdgeGesture* aSender,
   137                                  IEdgeGestureEventArgs* aArgs);
   139   // Swipe gesture callback from the GestureRecognizer.
   140   HRESULT OnManipulationCompleted(IGestureRecognizer* aSender,
   141                                   IManipulationCompletedEventArgs* aArgs);
   143   // Tap gesture callback from the GestureRecognizer.
   144   HRESULT OnTapped(IGestureRecognizer* aSender, ITappedEventArgs* aArgs);
   145   HRESULT OnRightTapped(IGestureRecognizer* aSender,
   146                         IRightTappedEventArgs* aArgs);
   148   void HandleTap(const Point& aPoint, unsigned int aTapCount);
   149   void HandleLongTap(const Point& aPoint);
   151   static bool IsInputModeImprecise();
   153 private:
   154   Microsoft::WRL::ComPtr<ICoreWindow> mWindow;
   155   Microsoft::WRL::ComPtr<MetroWidget> mWidget;
   156   Microsoft::WRL::ComPtr<IGestureRecognizer> mGestureRecognizer;
   158   ModifierKeyState mModifierKeyState;
   160   // Tracking input level
   161   enum InputPrecisionLevel {
   162     LEVEL_PRECISE,
   163     LEVEL_IMPRECISE
   164   };
   165   static InputPrecisionLevel sCurrentInputLevel;
   166   void UpdateInputLevel(InputPrecisionLevel aInputLevel);
   168   // Initialization/Uninitialization helpers
   169   void RegisterInputEvents();
   170   void UnregisterInputEvents();
   172   // Hit testing for apz content
   173   bool mNonApzTargetForTouch;
   174   bool HitTestChrome(const LayoutDeviceIntPoint& pt);
   176   // Event processing helpers.  See function definitions for more info.
   177   bool TransformRefPoint(const Point& aPosition,
   178                          LayoutDeviceIntPoint& aRefPointOut);
   179   void TransformTouchEvent(WidgetTouchEvent* aEvent);
   180   void OnPointerNonTouch(IPointerPoint* aPoint);
   181   void AddPointerMoveDataToRecognizer(IPointerEventArgs* aArgs);
   182   void InitGeckoMouseEventFromPointerPoint(WidgetMouseEvent* aEvent,
   183                                            IPointerPoint* aPoint);
   184   void ProcessManipulationDelta(ManipulationDelta const& aDelta,
   185                                 Point const& aPosition,
   186                                 uint32_t aMagEventType,
   187                                 uint32_t aRotEventType);
   188   uint16_t ProcessInputTypeForGesture(IEdgeGestureEventArgs* aArgs);
   189   bool ShouldDeliverInputToRecognizer();
   191   // Returns array of allowed touch behaviors  for touch points of given TouchEvent.
   192   // Note: event argument should be transformed via apzc before supplying to this method.
   193   void GetAllowedTouchBehavior(WidgetTouchEvent* aTransformedEvent, nsTArray<TouchBehaviorFlags>& aOutBehaviors);
   195   // Checks whether any touch behavior is allowed.
   196   bool IsTouchBehaviorForbidden(const nsTArray<TouchBehaviorFlags>& aTouchBehaviors);
   198   // The W3C spec states that "whether preventDefault has been called" should
   199   // be tracked on a per-touchpoint basis, but it also states that touchstart
   200   // and touchmove events can contain multiple changed points.  At the time of
   201   // this writing, W3C touch events are in the process of being abandoned in
   202   // favor of W3C pointer events, so it is unlikely that this ambiguity will
   203   // be resolved.  Additionally, nsPresShell tracks "whether preventDefault
   204   // has been called" on a per-touch-session basis.  We will follow a similar
   205   // approach here.
   206   //
   207   // Specifically:
   208   //   If preventDefault is called on the FIRST touchstart event of a touch
   209   //   session, then no default actions associated with any touchstart,
   210   //   touchmove, or touchend events will be taken.  This means that no
   211   //   mousedowns, mousemoves, mouseups, clicks, swipes, rotations,
   212   //   magnifications, etc will be dispatched during this touch session;
   213   //   only touchstart, touchmove, and touchend.
   214   //
   215   //   If preventDefault is called on the FIRST touchmove event of a touch
   216   //   session, then no default actions associated with the _touchmove_ events
   217   //   will be dispatched.  However, it is still possible that additional
   218   //   events will be generated based on the touchstart and touchend events.
   219   //   For example, a set of mousemove, mousedown, and mouseup events might
   220   //   be sent if a tap is detected.
   221   bool mContentConsumingTouch;
   222   bool mApzConsumingTouch;
   223   bool mCancelable;
   224   bool mRecognizerWantsEvents;
   226   nsTArray<uint32_t> mCanceledIds;
   228   // In the old Win32 way of doing things, we would receive a WM_TOUCH event
   229   // that told us the state of every touchpoint on the touch surface.  If
   230   // multiple touchpoints had moved since the last update we would learn
   231   // about all their movement simultaneously.
   232   //
   233   // In the new WinRT way of doing things, we receive a separate
   234   // PointerPressed/PointerMoved/PointerReleased event for each touchpoint
   235   // that has changed.
   236   //
   237   // When we learn of touch input, we dispatch gecko events in response.
   238   // With the new WinRT way of doing things, we would end up sending many
   239   // more gecko events than we would using the Win32 mechanism.  E.g.,
   240   // for 5 active touchpoints, we would be sending 5 times as many gecko
   241   // events.  This caused performance to visibly degrade on modestly-powered
   242   // machines.  In response, we no longer send touch events immediately
   243   // upon receiving PointerPressed or PointerMoved.  Instead, we store
   244   // the updated touchpoint info and record the fact that the touchpoint
   245   // has changed.  If ever we try to update a touchpoint has already
   246   // changed, we dispatch a touch event containing all the changed touches.
   247   void InitTouchEventTouchList(WidgetTouchEvent* aEvent);
   248   nsBaseHashtable<nsUint32HashKey,
   249                   nsRefPtr<mozilla::dom::Touch>,
   250                   nsRefPtr<mozilla::dom::Touch> > mTouches;
   252   // These registration tokens are set when we register ourselves to receive
   253   // events from our window.  We must hold on to them for the entire duration
   254   // that we want to receive these events.  When we are done, we must
   255   // unregister ourself with the window using these tokens.
   256   EventRegistrationToken mTokenPointerPressed;
   257   EventRegistrationToken mTokenPointerReleased;
   258   EventRegistrationToken mTokenPointerMoved;
   259   EventRegistrationToken mTokenPointerEntered;
   260   EventRegistrationToken mTokenPointerExited;
   262   // When we register ourselves to handle edge gestures, we receive a
   263   // token. To we unregister ourselves, we must use the token we received.
   264   EventRegistrationToken mTokenEdgeStarted;
   265   EventRegistrationToken mTokenEdgeCanceled;
   266   EventRegistrationToken mTokenEdgeCompleted;
   268   // These registration tokens are set when we register ourselves to receive
   269   // events from our GestureRecognizer.  It's probably not a huge deal if we
   270   // don't unregister ourselves with our GestureRecognizer before destroying
   271   // the GestureRecognizer, but it can't hurt.
   272   EventRegistrationToken mTokenManipulationCompleted;
   273   EventRegistrationToken mTokenTapped;
   274   EventRegistrationToken mTokenRightTapped;
   276   // Due to a limitation added in 8.1 the ui thread can't re-enter the main
   277   // native event dispatcher in MetroAppShell. So all events delivered to us
   278   // on the ui thread via a native event dispatch call get bounced through
   279   // the gecko thread event queue using runnables. Most events can be sent
   280   // async without the need to see the status result. Those that do have
   281   // specialty callbacks. Note any event that arrives to us on the ui thread
   282   // that originates from another thread is safe to send sync.
   284   // Async event dispatching
   285   void DispatchAsyncEventIgnoreStatus(WidgetInputEvent* aEvent);
   286   void DispatchAsyncTouchEvent(WidgetTouchEvent* aEvent);
   288   // Async event callbacks
   289   void DeliverNextQueuedEventIgnoreStatus();
   290   void DeliverNextQueuedTouchEvent();
   292   void HandleFirstTouchStartEvent(WidgetTouchEvent* aEvent);
   293   void HandleFirstTouchMoveEvent(WidgetTouchEvent* aEvent);
   295   // Sync event dispatching
   296   void DispatchEventIgnoreStatus(WidgetGUIEvent* aEvent);
   297   void DispatchTouchCancel(WidgetTouchEvent* aEvent);
   299   nsDeque mInputEventQueue;
   300   mozilla::layers::ScrollableLayerGuid mTargetAPZCGuid;
   301   static nsEventStatus sThrowawayStatus;
   302 };
   304 } } }

mercurial