summaryrefslogtreecommitdiffstats
path: root/layout/generic/ScrollPositionUpdate.h
blob: ca22da8af0776e361579f63b6697568f64ad2e58 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef mozilla_ScrollPositionUpdate_h_
#define mozilla_ScrollPositionUpdate_h_

#include <cstdint>
#include <iosfwd>

#include "nsPoint.h"
#include "mozilla/ScrollGeneration.h"
#include "mozilla/ScrollOrigin.h"
#include "mozilla/ScrollSnapTargetId.h"
#include "mozilla/ScrollTypes.h"
#include "Units.h"

namespace IPC {
template <typename T>
struct ParamTraits;
}  // namespace IPC

namespace mozilla {

enum class ScrollUpdateType {
  // A scroll update to a specific destination, regardless of the current
  // scroll position.
  Absolute,
  // A scroll update by a specific amount, based off a given starting scroll
  // position. XXX Fold this into PureRelative, it should be relatively
  // straightforward after bug 1655733.
  Relative,
  // A scroll update by a specific amount, where only the delta is provided.
  // The delta should be applied to whatever the current scroll position is
  // on the receiver side.
  PureRelative,
};

enum class ScrollTriggeredByScript : bool { No, Yes };

/**
 * This class represents an update to the scroll position that is initiated by
 * something on the main thread. A list of these classes is accumulated by
 * scrollframes on the main thread, and the list is sent over as part of a
 * paint transaction to the compositor. The compositor can then iterate through
 * the scroll updates and apply/merge them with scrolling that has already
 * occurred independently on the compositor side.
 */
class ScrollPositionUpdate {
  friend struct IPC::ParamTraits<mozilla::ScrollPositionUpdate>;

 public:
  // Constructor for IPC use only.
  explicit ScrollPositionUpdate();

  // Create a ScrollPositionUpdate for a newly created (or reconstructed)
  // scrollframe.
  static ScrollPositionUpdate NewScrollframe(nsPoint aInitialPosition);
  // Create a ScrollPositionUpdate for a new absolute/instant scroll, to
  // the given destination.
  static ScrollPositionUpdate NewScroll(ScrollOrigin aOrigin,
                                        nsPoint aDestination);
  // Create a ScrollPositionUpdate for a new relative/instant scroll, with
  // the given source/destination.
  static ScrollPositionUpdate NewRelativeScroll(nsPoint aSource,
                                                nsPoint aDestination);
  // Create a ScrollPositionUpdate for a new absolute/smooth scroll, which
  // animates smoothly to the given destination from whatever the current
  // scroll position is in the receiver.
  // If the smooth operation involves snapping to |aDestination|,
  // |aSnapTargetIds| has snap-target-ids for snapping. Once after this smooth
  // scroll finished on the target APZC, the ids will be reported back to the
  // main-thread as the last snap target ids which will be used for re-snapping
  // to the same snapped element(s).
  static ScrollPositionUpdate NewSmoothScroll(
      ScrollMode aMode, ScrollOrigin aOrigin, nsPoint aDestination,
      ScrollTriggeredByScript aTriggeredByScript,
      UniquePtr<ScrollSnapTargetIds> aSnapTargetIds);
  // Create a ScrollPositionUpdate for a new pure-relative scroll. The
  // aMode parameter controls whether or not this is a smooth animation or
  // instantaneous scroll.
  static ScrollPositionUpdate NewPureRelativeScroll(ScrollOrigin aOrigin,
                                                    ScrollMode aMode,
                                                    const nsPoint& aDelta);

  bool operator==(const ScrollPositionUpdate& aOther) const;

  MainThreadScrollGeneration GetGeneration() const;
  ScrollUpdateType GetType() const;
  ScrollMode GetMode() const;
  ScrollOrigin GetOrigin() const;
  // GetDestination is only valid for Absolute and Relative types; it asserts
  // otherwise.
  CSSPoint GetDestination() const;
  // GetSource is only valid for the Relative type; it asserts otherwise.
  CSSPoint GetSource() const;
  // GetDelta is only valid for the PureRelative type; it asserts otherwise.
  CSSPoint GetDelta() const;

  ScrollTriggeredByScript GetScrollTriggeredByScript() const {
    return mTriggeredByScript;
  }
  bool WasTriggeredByScript() const {
    return mTriggeredByScript == ScrollTriggeredByScript::Yes;
  }
  const ScrollSnapTargetIds& GetSnapTargetIds() const { return mSnapTargetIds; }

  friend std::ostream& operator<<(std::ostream& aStream,
                                  const ScrollPositionUpdate& aUpdate);

 private:
  MainThreadScrollGeneration mScrollGeneration;
  // Refer to the ScrollUpdateType documentation for what the types mean.
  // All fields are populated for all types, except as noted below.
  ScrollUpdateType mType;
  ScrollMode mScrollMode;
  ScrollOrigin mScrollOrigin;
  // mDestination is not populated when mType == PureRelative.
  CSSPoint mDestination;
  // mSource is not populated when mType == Absolute || mType == PureRelative.
  CSSPoint mSource;
  // mDelta is not populated when mType == Absolute || mType == Relative.
  CSSPoint mDelta;
  ScrollTriggeredByScript mTriggeredByScript;
  ScrollSnapTargetIds mSnapTargetIds;
};

}  // namespace mozilla

#endif  // mozilla_ScrollPositionUpdate_h_