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_GlobalKeyListener_h_
8 #define mozilla_GlobalKeyListener_h_
10 #include "mozilla/EventForwards.h"
11 #include "mozilla/layers/KeyboardMap.h"
12 #include "nsIDOMEventListener.h"
13 #include "nsIWeakReferenceUtils.h"
18 class EventListenerManager
;
19 class WidgetKeyboardEvent
;
20 struct IgnoreModifierState
;
32 class KeyEventHandler
;
35 * A generic listener for key events.
37 * Maintains a list of shortcut handlers and is registered as a listener for DOM
38 * key events from a target. Responsible for executing the appropriate handler
39 * when a keyboard event is received.
41 class GlobalKeyListener
: public nsIDOMEventListener
{
43 explicit GlobalKeyListener(dom::EventTarget
* aTarget
);
45 void InstallKeyboardEventListenersTo(
46 EventListenerManager
* aEventListenerManager
);
47 void RemoveKeyboardEventListenersFrom(
48 EventListenerManager
* aEventListenerManager
);
51 NS_DECL_NSIDOMEVENTLISTENER
54 virtual ~GlobalKeyListener() = default;
57 void WalkHandlers(dom::KeyboardEvent
* aKeyEvent
);
63 struct MOZ_STACK_CLASS WalkHandlersResult
{
64 // Set to true if it found a command matches with given keyboard event and
66 bool mMeaningfulHandlerFound
= false;
67 // Set to true if the command which is found or executed is reserved for
69 bool mReservedHandlerForChromeFound
= false;
70 // Set to true if found handler is disabled.
71 bool mDisabledHandlerFound
= false;
74 // walk the handlers, looking for one to handle the event
76 WalkHandlersResult
WalkHandlersInternal(Purpose aPurpose
,
77 dom::KeyboardEvent
* aKeyEvent
);
79 // Walk the handlers for aEvent, aCharCode and aIgnoreModifierState.
81 WalkHandlersResult
WalkHandlersAndExecute(
82 Purpose aPurpose
, dom::KeyboardEvent
* aKeyEvent
, uint32_t aCharCode
,
83 const IgnoreModifierState
& aIgnoreModifierState
);
85 // HandleEvent function for the capturing phase in the default event group.
87 void HandleEventOnCaptureInDefaultEventGroup(dom::KeyboardEvent
* aEvent
);
88 // HandleEvent function for the capturing phase in the system event group.
90 void HandleEventOnCaptureInSystemEventGroup(dom::KeyboardEvent
* aEvent
);
92 // Check if any handler would handle the given event. Optionally returns
93 // whether the command handler for the event is marked with the "reserved"
96 WalkHandlersResult
HasHandlerForEvent(dom::KeyboardEvent
* aEvent
);
98 // Returns true if the key would be reserved for the given handler. A reserved
99 // key is not sent to a content process or single-process equivalent.
100 bool IsReservedKey(WidgetKeyboardEvent
* aKeyEvent
, KeyEventHandler
* aHandler
);
102 // lazily load the handlers. Overridden to handle being attached
103 // to a particular element rather than the document
104 virtual void EnsureHandlers() = 0;
106 virtual bool CanHandle(KeyEventHandler
* aHandler
, bool aWillExecute
) const {
110 virtual bool IsDisabled() const { return false; }
112 virtual already_AddRefed
<dom::EventTarget
> GetHandlerTarget(
113 KeyEventHandler
* aHandler
) {
114 return do_AddRef(mTarget
);
117 dom::EventTarget
* mTarget
; // weak ref;
119 KeyEventHandler
* mHandler
; // Linked list of event handlers.
123 * A listener for shortcut keys defined in XUL keyset elements.
125 * Listens for keyboard events from the document object and triggers the
126 * appropriate XUL key elements.
128 class XULKeySetGlobalKeyListener final
: public GlobalKeyListener
{
130 explicit XULKeySetGlobalKeyListener(dom::Element
* aElement
,
131 dom::EventTarget
* aTarget
);
133 static void AttachKeyHandler(dom::Element
* aElementTarget
);
134 static void DetachKeyHandler(dom::Element
* aElementTarget
);
137 virtual ~XULKeySetGlobalKeyListener();
139 // Returns the element which was passed as a parameter to the constructor,
140 // unless the element has been removed from the document. Optionally returns
141 // whether the disabled attribute is set on the element (assuming the element
143 dom::Element
* GetElement(bool* aIsDisabled
= nullptr) const;
145 virtual void EnsureHandlers() override
;
147 virtual bool CanHandle(KeyEventHandler
* aHandler
,
148 bool aWillExecute
) const override
;
149 virtual bool IsDisabled() const override
;
150 virtual already_AddRefed
<dom::EventTarget
> GetHandlerTarget(
151 KeyEventHandler
* aHandler
) override
;
154 * GetElementForHandler() retrieves an element for the handler. The element
155 * may be a command element or a key element.
157 * @param aHandler The handler.
158 * @param aElementForHandler Must not be nullptr. The element is returned to
160 * @return true if the handler is valid. Otherwise, false.
162 bool GetElementForHandler(KeyEventHandler
* aHandler
,
163 dom::Element
** aElementForHandler
) const;
166 * IsExecutableElement() returns true if aElement is executable.
167 * Otherwise, false. aElement should be a command element or a key element.
169 bool IsExecutableElement(dom::Element
* aElement
) const;
171 // Using weak pointer to the DOM Element.
172 nsWeakPtr mWeakPtrForElement
;
176 * Listens for built-in shortcut keys.
178 * Listens to DOM keyboard events from the window or text input and runs the
179 * built-in shortcuts (see dom/events/keyevents) as necessary.
181 class RootWindowGlobalKeyListener final
: public GlobalKeyListener
{
183 explicit RootWindowGlobalKeyListener(dom::EventTarget
* aTarget
);
185 static void AttachKeyHandler(dom::EventTarget
* aTarget
);
187 static layers::KeyboardMap
CollectKeyboardShortcuts();
190 // Is an HTML editable element focused
191 static bool IsHTMLEditorFocused();
193 virtual void EnsureHandlers() override
;
196 } // namespace mozilla