1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_dom_UserActivation_h
8 #define mozilla_dom_UserActivation_h
10 #include "mozilla/Assertions.h"
11 #include "mozilla/EventForwards.h"
12 #include "mozilla/TimeStamp.h"
13 #include "nsCycleCollectionParticipant.h"
14 #include "nsWrapperCache.h"
15 #include "nsPIDOMWindow.h"
22 namespace mozilla::dom
{
24 class UserActivation final
: public nsISupports
, public nsWrapperCache
{
26 // WebIDL UserActivation
28 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
29 NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(UserActivation
)
31 explicit UserActivation(nsPIDOMWindowInner
* aWindow
);
33 nsPIDOMWindowInner
* GetParentObject() const { return mWindow
; }
34 JSObject
* WrapObject(JSContext
* aCx
, JS::Handle
<JSObject
*> aGivenProto
) final
;
36 bool HasBeenActive() const;
37 bool IsActive() const;
39 // End of WebIDL UserActivation
41 enum class State
: uint8_t {
44 // It is considered as has-been-activated, but not transient-activated given
45 // that it is being consumed.
47 // It is considered as has-been-activated, and also transient-activated if
53 class StateAndModifiers
;
55 // Modifier keys held while the user activation.
58 static constexpr uint8_t Shift
= 0x10;
59 static constexpr uint8_t Meta
= 0x20;
60 static constexpr uint8_t Control
= 0x40;
61 static constexpr uint8_t Alt
= 0x80;
63 static constexpr uint8_t Mask
= 0xF0;
65 constexpr Modifiers() = default;
66 explicit constexpr Modifiers(uint8_t aModifiers
) : mModifiers(aModifiers
) {}
68 static constexpr Modifiers
None() { return Modifiers(0); }
70 void SetShift() { mModifiers
|= Shift
; }
71 void SetMeta() { mModifiers
|= Meta
; }
72 void SetControl() { mModifiers
|= Control
; }
73 void SetAlt() { mModifiers
|= Alt
; }
75 bool IsShift() const { return mModifiers
& Shift
; }
76 bool IsMeta() const { return mModifiers
& Meta
; }
77 bool IsControl() const { return mModifiers
& Control
; }
78 bool IsAlt() const { return mModifiers
& Alt
; }
81 uint8_t mModifiers
= 0;
83 friend class StateAndModifiers
;
85 friend struct IPC::ParamTraits
;
88 // State and Modifiers encoded into single data, for WindowContext field.
89 class StateAndModifiers
{
91 using DataT
= uint8_t;
93 constexpr StateAndModifiers() = default;
94 explicit constexpr StateAndModifiers(DataT aStateAndModifiers
)
95 : mStateAndModifiers(aStateAndModifiers
) {}
97 DataT
GetRawData() const { return mStateAndModifiers
; }
99 State
GetState() const { return State(RawState()); }
100 void SetState(State aState
) {
101 MOZ_ASSERT((uint8_t(aState
) & Modifiers::Mask
) == 0);
102 mStateAndModifiers
= uint8_t(aState
) | RawModifiers();
105 Modifiers
GetModifiers() const { return Modifiers(RawModifiers()); }
106 void SetModifiers(Modifiers aModifiers
) {
107 mStateAndModifiers
= RawState() | aModifiers
.mModifiers
;
111 uint8_t RawState() const { return mStateAndModifiers
& ~Modifiers::Mask
; }
113 uint8_t RawModifiers() const {
114 return mStateAndModifiers
& Modifiers::Mask
;
117 uint8_t mStateAndModifiers
= 0;
121 * Returns true if the current code is being executed as a result of
122 * user input or keyboard input. The former includes anything that is
123 * initiated by user, with the exception of page load events or mouse
124 * over events. And the latter returns true when one of the user inputs
125 * is an input from keyboard. If these methods are called from asynchronously
126 * executed code, such as during layout reflows, it will return false.
128 static bool IsHandlingUserInput();
129 static bool IsHandlingKeyboardInput();
132 * Returns true if the event is considered as user interaction event. I.e.,
133 * enough obvious input to allow to open popup, etc. Otherwise, returns false.
135 static bool IsUserInteractionEvent(const WidgetEvent
* aEvent
);
138 * StartHandlingUserInput() is called when we start to handle a user input.
139 * StopHandlingUserInput() is called when we finish handling a user input.
140 * If the caller knows which input event caused that, it should set
141 * aMessage to the event message. Otherwise, set eVoidEvent.
142 * Note that StopHandlingUserInput() caller should call it with exactly same
143 * event message as its corresponding StartHandlingUserInput() call because
144 * these methods may count the number of specific event message.
146 static void StartHandlingUserInput(EventMessage aMessage
);
147 static void StopHandlingUserInput(EventMessage aMessage
);
149 static TimeStamp
GetHandlingInputStart();
152 * Get the timestamp at which the latest user input was handled.
154 * Guaranteed to be monotonic. Until the first user input, return
157 static TimeStamp
LatestUserInputStart();
160 ~UserActivation() = default;
162 nsCOMPtr
<nsPIDOMWindowInner
> mWindow
;
166 * This class is used while processing real user input. During this time, popups
167 * are allowed. For mousedown events, mouse capturing is also permitted.
169 class MOZ_RAII AutoHandlingUserInputStatePusher final
{
171 explicit AutoHandlingUserInputStatePusher(bool aIsHandlingUserInput
,
172 WidgetEvent
* aEvent
= nullptr);
173 ~AutoHandlingUserInputStatePusher();
176 EventMessage mMessage
;
177 bool mIsHandlingUserInput
;
180 } // namespace mozilla::dom
182 #endif // mozilla_dom_UserActivation_h