1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCHPAD_PINCH_EVENT_QUEUE_H_
6 #define CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCHPAD_PINCH_EVENT_QUEUE_H_
7 
8 #include <memory>
9 
10 #include "base/containers/circular_deque.h"
11 #include "base/optional.h"
12 #include "content/common/content_export.h"
13 #include "content/common/input/event_with_latency_info.h"
14 #include "content/public/common/input_event_ack_source.h"
15 #include "content/public/common/input_event_ack_state.h"
16 #include "third_party/blink/public/common/input/web_input_event.h"
17 
18 namespace content {
19 
20 class QueuedTouchpadPinchEvent;
21 
22 // Interface with which TouchpadPinchEventQueue can forward synthetic mouse
23 // wheel events and notify of pinch events.
24 class CONTENT_EXPORT TouchpadPinchEventQueueClient {
25  public:
26   virtual ~TouchpadPinchEventQueueClient() = default;
27 
28   using MouseWheelEventHandledCallback =
29       base::OnceCallback<void(const MouseWheelEventWithLatencyInfo& event,
30                               InputEventAckSource ack_source,
31                               InputEventAckState ack_result)>;
32 
33   virtual void SendMouseWheelEventForPinchImmediately(
34       const MouseWheelEventWithLatencyInfo& event,
35       MouseWheelEventHandledCallback callback) = 0;
36   virtual void OnGestureEventForPinchAck(
37       const GestureEventWithLatencyInfo& event,
38       InputEventAckSource ack_source,
39       InputEventAckState ack_result) = 0;
40 };
41 
42 // A queue for sending synthetic mouse wheel events for touchpad pinches.
43 // In order for a page to prevent touchpad pinch zooming, we send synthetic
44 // wheel events which may be cancelled. Once we've determined whether a page
45 // has prevented the pinch, the TouchpadPinchEventQueueClient may proceed with
46 // handling the pinch.
47 // See README.md for further details.
48 class CONTENT_EXPORT TouchpadPinchEventQueue {
49  public:
50   // The |client| must outlive the TouchpadPinchEventQueue.
51   TouchpadPinchEventQueue(TouchpadPinchEventQueueClient* client);
52   ~TouchpadPinchEventQueue();
53 
54   // Adds the given touchpad pinch |event| to the queue. The event may be
55   // coalesced with previously queued events.
56   void QueueEvent(const GestureEventWithLatencyInfo& event);
57 
58   bool has_pending() const WARN_UNUSED_RESULT;
59 
60  private:
61   // Notifies the queue that a synthetic mouse wheel event has been processed
62   // by the renderer.
63   void ProcessMouseWheelAck(const MouseWheelEventWithLatencyInfo& ack_event,
64                             InputEventAckSource ack_source,
65                             InputEventAckState ack_result);
66 
67   void TryForwardNextEventToRenderer();
68 
69   const bool touchpad_async_pinch_events_;
70   TouchpadPinchEventQueueClient* client_;
71 
72   base::circular_deque<std::unique_ptr<QueuedTouchpadPinchEvent>> pinch_queue_;
73   std::unique_ptr<QueuedTouchpadPinchEvent> pinch_event_awaiting_ack_;
74   base::Optional<bool> first_event_prevented_;
75 
76   DISALLOW_COPY_AND_ASSIGN(TouchpadPinchEventQueue);
77 };
78 
79 }  // namespace content
80 
81 #endif  // CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCHPAD_PINCH_EVENT_QUEUE_H_
82