1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 1998
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Mats Palmgren <mats.palmgren@bredband.net>
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either of the GNU General Public License Version 2 or later (the "GPL"),
27 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : #ifndef nsEventStateManager_h__
40 : #define nsEventStateManager_h__
41 :
42 : #include "nsEvent.h"
43 : #include "nsGUIEvent.h"
44 : #include "nsIContent.h"
45 : #include "nsIObserver.h"
46 : #include "nsWeakReference.h"
47 : #include "nsHashtable.h"
48 : #include "nsITimer.h"
49 : #include "nsCOMPtr.h"
50 : #include "nsIDocument.h"
51 : #include "nsCOMArray.h"
52 : #include "nsIFrameLoader.h"
53 : #include "nsIFrame.h"
54 : #include "nsCycleCollectionParticipant.h"
55 : #include "nsIMarkupDocumentViewer.h"
56 : #include "nsIScrollableFrame.h"
57 : #include "nsFocusManager.h"
58 : #include "nsIDocument.h"
59 : #include "nsEventStates.h"
60 : #include "mozilla/TimeStamp.h"
61 : #include "nsContentUtils.h"
62 :
63 : class nsIPresShell;
64 : class nsIDocShell;
65 : class nsIDocShellTreeNode;
66 : class nsIDocShellTreeItem;
67 : class imgIContainer;
68 : class nsDOMDataTransfer;
69 : class MouseEnterLeaveDispatcher;
70 :
71 : namespace mozilla {
72 : namespace dom {
73 : class TabParent;
74 : }
75 : }
76 :
77 : /*
78 : * Event listener manager
79 : */
80 :
81 : class nsEventStateManager : public nsSupportsWeakReference,
82 : public nsIObserver
83 : {
84 : friend class nsMouseWheelTransaction;
85 : public:
86 :
87 : typedef mozilla::TimeStamp TimeStamp;
88 : typedef mozilla::TimeDuration TimeDuration;
89 :
90 : nsEventStateManager();
91 : virtual ~nsEventStateManager();
92 :
93 : NS_DECL_CYCLE_COLLECTING_ISUPPORTS
94 : NS_DECL_NSIOBSERVER
95 :
96 : nsresult Init();
97 : nsresult Shutdown();
98 :
99 : /* The PreHandleEvent method is called before event dispatch to either
100 : * the DOM or frames. Any processing which must not be prevented or
101 : * cancelled should occur here. Any processing which is intended to
102 : * be conditional based on either DOM or frame processing should occur in
103 : * PostHandleEvent. Any centralized event processing which must occur before
104 : * DOM or frame event handling should occur here as well.
105 : */
106 : nsresult PreHandleEvent(nsPresContext* aPresContext,
107 : nsEvent *aEvent,
108 : nsIFrame* aTargetFrame,
109 : nsEventStatus* aStatus);
110 :
111 : /* The PostHandleEvent method should contain all system processing which
112 : * should occur conditionally based on DOM or frame processing. It should
113 : * also contain any centralized event processing which must occur after
114 : * DOM and frame processing.
115 : */
116 : nsresult PostHandleEvent(nsPresContext* aPresContext,
117 : nsEvent *aEvent,
118 : nsIFrame* aTargetFrame,
119 : nsEventStatus* aStatus);
120 :
121 : void NotifyDestroyPresContext(nsPresContext* aPresContext);
122 : void SetPresContext(nsPresContext* aPresContext);
123 : void ClearFrameRefs(nsIFrame* aFrame);
124 :
125 : nsIFrame* GetEventTarget();
126 : already_AddRefed<nsIContent> GetEventTargetContent(nsEvent* aEvent);
127 :
128 : /**
129 : * Notify that the given NS_EVENT_STATE_* bit has changed for this content.
130 : * @param aContent Content which has changed states
131 : * @param aState Corresponding state flags such as NS_EVENT_STATE_FOCUS
132 : * @return Whether the content was able to change all states. Returns false
133 : * if a resulting DOM event causes the content node passed in
134 : * to not change states. Note, the frame for the content may
135 : * change as a result of the content state change, because of
136 : * frame reconstructions that may occur, but this does not
137 : * affect the return value.
138 : */
139 : bool SetContentState(nsIContent *aContent, nsEventStates aState);
140 : void ContentRemoved(nsIDocument* aDocument, nsIContent* aContent);
141 : bool EventStatusOK(nsGUIEvent* aEvent);
142 :
143 : /**
144 : * Register accesskey on the given element. When accesskey is activated then
145 : * the element will be notified via nsIContent::PerformAccesskey() method.
146 : *
147 : * @param aContent the given element
148 : * @param aKey accesskey
149 : */
150 : void RegisterAccessKey(nsIContent* aContent, PRUint32 aKey);
151 :
152 : /**
153 : * Unregister accesskey for the given element.
154 : *
155 : * @param aContent the given element
156 : * @param aKey accesskey
157 : */
158 : void UnregisterAccessKey(nsIContent* aContent, PRUint32 aKey);
159 :
160 : /**
161 : * Get accesskey registered on the given element or 0 if there is none.
162 : *
163 : * @param aContent the given element
164 : * @return registered accesskey
165 : */
166 : PRUint32 GetRegisteredAccessKey(nsIContent* aContent);
167 :
168 : bool GetAccessKeyLabelPrefix(nsAString& aPrefix);
169 :
170 : nsresult SetCursor(PRInt32 aCursor, imgIContainer* aContainer,
171 : bool aHaveHotspot, float aHotspotX, float aHotspotY,
172 : nsIWidget* aWidget, bool aLockCursor);
173 :
174 0 : static void StartHandlingUserInput()
175 : {
176 0 : ++sUserInputEventDepth;
177 0 : if (sUserInputEventDepth == 1) {
178 0 : sHandlingInputStart = TimeStamp::Now();
179 : }
180 0 : }
181 :
182 0 : static void StopHandlingUserInput()
183 : {
184 0 : --sUserInputEventDepth;
185 0 : if (sUserInputEventDepth == 0) {
186 0 : sHandlingInputStart = TimeStamp();
187 : }
188 0 : }
189 :
190 0 : static bool IsHandlingUserInput()
191 : {
192 0 : if (sUserInputEventDepth <= 0) {
193 0 : return false;
194 : }
195 0 : TimeDuration timeout = nsContentUtils::HandlingUserInputTimeout();
196 0 : return timeout <= TimeDuration(0) ||
197 0 : (TimeStamp::Now() - sHandlingInputStart) <= timeout;
198 : }
199 :
200 : /**
201 : * Returns true if the current code is being executed as a result of user input.
202 : * This includes timers or anything else that is initiated from user input.
203 : * However, mouse hover events are not counted as user input, nor are
204 : * page load events. If this method is called from asynchronously executed code,
205 : * such as during layout reflows, it will return false. If more time has elapsed
206 : * since the user input than is specified by the
207 : * dom.event.handling-user-input-time-limit pref (default 1 second), this
208 : * function also returns false.
209 : */
210 : NS_IMETHOD_(bool) IsHandlingUserInputExternal() { return IsHandlingUserInput(); }
211 :
212 : nsPresContext* GetPresContext() { return mPresContext; }
213 :
214 : NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsEventStateManager,
215 : nsIObserver)
216 :
217 : static nsIDocument* sMouseOverDocument;
218 :
219 : static nsEventStateManager* GetActiveEventStateManager() { return sActiveESM; }
220 :
221 : // Sets aNewESM to be the active event state manager, and
222 : // if aContent is non-null, marks the object as active.
223 : static void SetActiveManager(nsEventStateManager* aNewESM,
224 : nsIContent* aContent);
225 :
226 : // Sets the full-screen event state on aElement to aIsFullScreen.
227 : static void SetFullScreenState(mozilla::dom::Element* aElement, bool aIsFullScreen);
228 :
229 : static bool IsRemoteTarget(nsIContent* aTarget);
230 :
231 : protected:
232 : friend class MouseEnterLeaveDispatcher;
233 :
234 : void UpdateCursor(nsPresContext* aPresContext, nsEvent* aEvent, nsIFrame* aTargetFrame, nsEventStatus* aStatus);
235 : /**
236 : * Turn a GUI mouse event into a mouse event targeted at the specified
237 : * content. This returns the primary frame for the content (or null
238 : * if it goes away during the event).
239 : */
240 : nsIFrame* DispatchMouseEvent(nsGUIEvent* aEvent, PRUint32 aMessage,
241 : nsIContent* aTargetContent,
242 : nsIContent* aRelatedContent);
243 : /**
244 : * Synthesize DOM and frame mouseover and mouseout events from this
245 : * MOUSE_MOVE or MOUSE_EXIT event.
246 : */
247 : void GenerateMouseEnterExit(nsGUIEvent* aEvent);
248 : /**
249 : * Tell this ESM and ESMs in parent documents that the mouse is
250 : * over some content in this document.
251 : */
252 : void NotifyMouseOver(nsGUIEvent* aEvent, nsIContent* aContent);
253 : /**
254 : * Tell this ESM and ESMs in affected child documents that the mouse
255 : * has exited this document's currently hovered content.
256 : * @param aEvent the event that triggered the mouseout
257 : * @param aMovingInto the content node we've moved into. This is used to set
258 : * the relatedTarget for mouseout events. Also, if it's non-null
259 : * NotifyMouseOut will NOT change the current hover content to null;
260 : * in that case the caller is responsible for updating hover state.
261 : */
262 : void NotifyMouseOut(nsGUIEvent* aEvent, nsIContent* aMovingInto);
263 : void GenerateDragDropEnterExit(nsPresContext* aPresContext, nsGUIEvent* aEvent);
264 : /**
265 : * Fire the dragenter and dragexit/dragleave events when the mouse moves to a
266 : * new target.
267 : *
268 : * @param aRelatedTarget relatedTarget to set for the event
269 : * @param aTargetContent target to set for the event
270 : * @param aTargetFrame target frame for the event
271 : */
272 : void FireDragEnterOrExit(nsPresContext* aPresContext,
273 : nsGUIEvent* aEvent,
274 : PRUint32 aMsg,
275 : nsIContent* aRelatedTarget,
276 : nsIContent* aTargetContent,
277 : nsWeakFrame& aTargetFrame);
278 : /**
279 : * Update the initial drag session data transfer with any changes that occur
280 : * on cloned data transfer objects used for events.
281 : */
282 : void UpdateDragDataTransfer(nsDragEvent* dragEvent);
283 :
284 : nsresult SetClickCount(nsPresContext* aPresContext, nsMouseEvent *aEvent, nsEventStatus* aStatus);
285 : nsresult CheckForAndDispatchClick(nsPresContext* aPresContext, nsMouseEvent *aEvent, nsEventStatus* aStatus);
286 : void EnsureDocument(nsPresContext* aPresContext);
287 : void FlushPendingEvents(nsPresContext* aPresContext);
288 :
289 : /**
290 : * The phases of HandleAccessKey processing. See below.
291 : */
292 : typedef enum {
293 : eAccessKeyProcessingNormal = 0,
294 : eAccessKeyProcessingUp,
295 : eAccessKeyProcessingDown
296 : } ProcessingAccessKeyState;
297 :
298 : /**
299 : * Access key handling. If there is registered content for the accesskey
300 : * given by the key event and modifier mask then call
301 : * content.PerformAccesskey(), otherwise call HandleAccessKey() recursively,
302 : * on descendant docshells first, then on the ancestor (with |aBubbledFrom|
303 : * set to the docshell associated with |this|), until something matches.
304 : *
305 : * @param aPresContext the presentation context
306 : * @param aEvent the key event
307 : * @param aStatus the event status
308 : * @param aBubbledFrom is used by an ancestor to avoid calling HandleAccessKey()
309 : * on the child the call originally came from, i.e. this is the child
310 : * that recursively called us in its Up phase. The initial caller
311 : * passes |nsnull| here. This is to avoid an infinite loop.
312 : * @param aAccessKeyState Normal, Down or Up processing phase (see enums
313 : * above). The initial event receiver uses 'normal', then 'down' when
314 : * processing children and Up when recursively calling its ancestor.
315 : * @param aModifierMask modifier mask for the key event
316 : */
317 : void HandleAccessKey(nsPresContext* aPresContext,
318 : nsKeyEvent* aEvent,
319 : nsEventStatus* aStatus,
320 : nsIDocShellTreeItem* aBubbledFrom,
321 : ProcessingAccessKeyState aAccessKeyState,
322 : PRInt32 aModifierMask);
323 :
324 : bool ExecuteAccessKey(nsTArray<PRUint32>& aAccessCharCodes,
325 : bool aIsTrustedEvent);
326 :
327 : //---------------------------------------------
328 : // DocShell Focus Traversal Methods
329 : //---------------------------------------------
330 :
331 : nsIContent* GetFocusedContent();
332 : bool IsShellVisible(nsIDocShell* aShell);
333 :
334 : // These functions are for mousewheel and pixel scrolling
335 : void SendLineScrollEvent(nsIFrame* aTargetFrame,
336 : nsMouseScrollEvent* aEvent,
337 : nsPresContext* aPresContext,
338 : nsEventStatus* aStatus,
339 : PRInt32 aNumLines);
340 : void SendPixelScrollEvent(nsIFrame* aTargetFrame,
341 : nsMouseScrollEvent* aEvent,
342 : nsPresContext* aPresContext,
343 : nsEventStatus* aStatus);
344 : /**
345 : * @param aQueryEvent If you set vailid pointer for this, DoScrollText()
346 : * computes the line-height and page size of current
347 : * mouse wheel scroll target and sets it to the event.
348 : * And then, this method does NOT scroll any scrollable
349 : * elements. I.e., you can just query the scroll target
350 : * information.
351 : */
352 : nsresult DoScrollText(nsIFrame* aTargetFrame,
353 : nsMouseScrollEvent* aMouseEvent,
354 : nsIScrollableFrame::ScrollUnit aScrollQuantity,
355 : bool aAllowScrollSpeedOverride,
356 : nsQueryContentEvent* aQueryEvent = nsnull,
357 : nsIAtom *aOrigin = nsnull);
358 : void DoScrollHistory(PRInt32 direction);
359 : void DoScrollZoom(nsIFrame *aTargetFrame, PRInt32 adjustment);
360 : nsresult GetMarkupDocumentViewer(nsIMarkupDocumentViewer** aMv);
361 : nsresult ChangeTextSize(PRInt32 change);
362 : nsresult ChangeFullZoom(PRInt32 change);
363 : /**
364 : * Computes actual delta value used for scrolling. If user customized the
365 : * scrolling speed and/or direction, this would return the customized value.
366 : * Otherwise, it would return the original delta value of aMouseEvent.
367 : */
368 : PRInt32 ComputeWheelDeltaFor(nsMouseScrollEvent* aMouseEvent);
369 : /**
370 : * Computes the action for the aMouseEvent with prefs. The result is
371 : * MOUSE_SCROLL_N_LINES, MOUSE_SCROLL_PAGE, MOUSE_SCROLL_HISTORY,
372 : * MOUSE_SCROLL_ZOOM, MOUSE_SCROLL_PIXELS or -1.
373 : * When the result is -1, nothing happens for the event.
374 : *
375 : * @param aUseSystemSettings Set the result of UseSystemScrollSettingFor().
376 : */
377 : PRInt32 ComputeWheelActionFor(nsMouseScrollEvent* aMouseEvent,
378 : bool aUseSystemSettings);
379 : /**
380 : * Gets the wheel action for the aMouseEvent ONLY with the pref.
381 : * When you actually do something for the event, probably you should use
382 : * ComputeWheelActionFor().
383 : */
384 : PRInt32 GetWheelActionFor(nsMouseScrollEvent* aMouseEvent);
385 : /**
386 : * Gets the pref value for line scroll amount for the aMouseEvent.
387 : * Note that this method doesn't check whether the aMouseEvent is line scroll
388 : * event and doesn't use system settings.
389 : */
390 : PRInt32 GetScrollLinesFor(nsMouseScrollEvent* aMouseEvent);
391 : /**
392 : * Whether use system scroll settings or settings in our prefs for the event.
393 : * TRUE, if use system scroll settings. Otherwise, FALSE.
394 : */
395 : bool UseSystemScrollSettingFor(nsMouseScrollEvent* aMouseEvent);
396 : // end mousewheel functions
397 :
398 : /*
399 : * When a touch gesture is about to start, this function determines what
400 : * kind of gesture interaction we will want to use, based on what is
401 : * underneath the initial touch point.
402 : * Currently it decides between panning (finger scrolling) or dragging
403 : * the target element, as well as the orientation to trigger panning and
404 : * display visual boundary feedback. The decision is stored back in aEvent.
405 : */
406 : void DecideGestureEvent(nsGestureNotifyEvent* aEvent, nsIFrame* targetFrame);
407 :
408 : // routines for the d&d gesture tracking state machine
409 : void BeginTrackingDragGesture ( nsPresContext* aPresContext, nsMouseEvent* inDownEvent,
410 : nsIFrame* inDownFrame ) ;
411 : void StopTrackingDragGesture ( ) ;
412 : void GenerateDragGesture ( nsPresContext* aPresContext, nsMouseEvent *aEvent ) ;
413 :
414 : /**
415 : * Determine which node the drag should be targeted at.
416 : * This is either the node clicked when there is a selection, or, for HTML,
417 : * the element with a draggable property set to true.
418 : *
419 : * aSelectionTarget - target to check for selection
420 : * aDataTransfer - data transfer object that will contain the data to drag
421 : * aSelection - [out] set to the selection to be dragged
422 : * aTargetNode - [out] the draggable node, or null if there isn't one
423 : */
424 : void DetermineDragTarget(nsPresContext* aPresContext,
425 : nsIContent* aSelectionTarget,
426 : nsDOMDataTransfer* aDataTransfer,
427 : nsISelection** aSelection,
428 : nsIContent** aTargetNode);
429 :
430 : /*
431 : * Perform the default handling for the dragstart/draggesture event and set up a
432 : * drag for aDataTransfer if it contains any data. Returns true if a drag has
433 : * started.
434 : *
435 : * aDragEvent - the dragstart/draggesture event
436 : * aDataTransfer - the data transfer that holds the data to be dragged
437 : * aDragTarget - the target of the drag
438 : * aSelection - the selection to be dragged
439 : */
440 : bool DoDefaultDragStart(nsPresContext* aPresContext,
441 : nsDragEvent* aDragEvent,
442 : nsDOMDataTransfer* aDataTransfer,
443 : nsIContent* aDragTarget,
444 : nsISelection* aSelection);
445 :
446 : bool IsTrackingDragGesture ( ) const { return mGestureDownContent != nsnull; }
447 : /**
448 : * Set the fields of aEvent to reflect the mouse position and modifier keys
449 : * that were set when the user first pressed the mouse button (stored by
450 : * BeginTrackingDragGesture). aEvent->widget must be
451 : * mCurrentTarget->GetNearestWidget().
452 : */
453 : void FillInEventFromGestureDown(nsMouseEvent* aEvent);
454 :
455 : nsresult DoContentCommandEvent(nsContentCommandEvent* aEvent);
456 : nsresult DoContentCommandScrollEvent(nsContentCommandEvent* aEvent);
457 :
458 : void DoQueryScrollTargetInfo(nsQueryContentEvent* aEvent,
459 : nsIFrame* aTargetFrame);
460 : void DoQuerySelectedText(nsQueryContentEvent* aEvent);
461 :
462 : bool RemoteQueryContentEvent(nsEvent *aEvent);
463 : mozilla::dom::TabParent *GetCrossProcessTarget();
464 : bool IsTargetCrossProcess(nsGUIEvent *aEvent);
465 :
466 : void DispatchCrossProcessEvent(nsEvent* aEvent, nsIFrameLoader* remote);
467 : bool HandleCrossProcessEvent(nsEvent *aEvent,
468 : nsIFrame* aTargetFrame,
469 : nsEventStatus *aStatus);
470 :
471 : private:
472 : static inline void DoStateChange(mozilla::dom::Element* aElement,
473 : nsEventStates aState, bool aAddState);
474 : static inline void DoStateChange(nsIContent* aContent, nsEventStates aState,
475 : bool aAddState);
476 : static void UpdateAncestorState(nsIContent* aStartNode,
477 : nsIContent* aStopBefore,
478 : nsEventStates aState,
479 : bool aAddState);
480 :
481 : PRInt32 mLockCursor;
482 :
483 : nsWeakFrame mCurrentTarget;
484 : nsCOMPtr<nsIContent> mCurrentTargetContent;
485 : nsWeakFrame mLastMouseOverFrame;
486 : nsCOMPtr<nsIContent> mLastMouseOverElement;
487 : static nsWeakFrame sLastDragOverFrame;
488 :
489 : // member variables for the d&d gesture state machine
490 : nsIntPoint mGestureDownPoint; // screen coordinates
491 : // The content to use as target if we start a d&d (what we drag).
492 : nsCOMPtr<nsIContent> mGestureDownContent;
493 : // The content of the frame where the mouse-down event occurred. It's the same
494 : // as the target in most cases but not always - for example when dragging
495 : // an <area> of an image map this is the image. (bug 289667)
496 : nsCOMPtr<nsIContent> mGestureDownFrameOwner;
497 : // State of keys when the original gesture-down happened
498 : bool mGestureDownShift;
499 : bool mGestureDownControl;
500 : bool mGestureDownAlt;
501 : bool mGestureDownMeta;
502 :
503 : nsCOMPtr<nsIContent> mLastLeftMouseDownContent;
504 : nsCOMPtr<nsIContent> mLastLeftMouseDownContentParent;
505 : nsCOMPtr<nsIContent> mLastMiddleMouseDownContent;
506 : nsCOMPtr<nsIContent> mLastMiddleMouseDownContentParent;
507 : nsCOMPtr<nsIContent> mLastRightMouseDownContent;
508 : nsCOMPtr<nsIContent> mLastRightMouseDownContentParent;
509 :
510 : nsCOMPtr<nsIContent> mActiveContent;
511 : nsCOMPtr<nsIContent> mHoverContent;
512 : static nsCOMPtr<nsIContent> sDragOverContent;
513 : nsCOMPtr<nsIContent> mURLTargetContent;
514 :
515 : // The last element on which we fired a mouseover event, or null if
516 : // the last mouseover event we fired has finished processing.
517 : nsCOMPtr<nsIContent> mFirstMouseOverEventElement;
518 :
519 : // The last element on which we fired a mouseout event, or null if
520 : // the last mouseout event we fired has finished processing.
521 : nsCOMPtr<nsIContent> mFirstMouseOutEventElement;
522 :
523 : nsPresContext* mPresContext; // Not refcnted
524 : nsCOMPtr<nsIDocument> mDocument; // Doesn't necessarily need to be owner
525 :
526 : PRUint32 mLClickCount;
527 : PRUint32 mMClickCount;
528 : PRUint32 mRClickCount;
529 :
530 : bool m_haveShutdown;
531 :
532 : // Time at which we began handling user input.
533 : static TimeStamp sHandlingInputStart;
534 :
535 : public:
536 : static nsresult UpdateUserActivityTimer(void);
537 : // Array for accesskey support
538 : nsCOMArray<nsIContent> mAccessKeys;
539 :
540 : // Unlocks pixel scrolling
541 : bool mLastLineScrollConsumedX;
542 : bool mLastLineScrollConsumedY;
543 :
544 : static PRInt32 sUserInputEventDepth;
545 :
546 : static bool sNormalLMouseEventInProcess;
547 :
548 : static nsEventStateManager* sActiveESM;
549 :
550 : static void ClearGlobalActiveContent(nsEventStateManager* aClearer);
551 :
552 : // Functions used for click hold context menus
553 : bool mClickHoldContextMenu;
554 : nsCOMPtr<nsITimer> mClickHoldTimer;
555 : void CreateClickHoldTimer ( nsPresContext* aPresContext, nsIFrame* inDownFrame,
556 : nsGUIEvent* inMouseDownEvent ) ;
557 : void KillClickHoldTimer ( ) ;
558 : void FireContextClick ( ) ;
559 : static void sClickHoldCallback ( nsITimer* aTimer, void* aESM ) ;
560 : };
561 :
562 : /**
563 : * This class is used while processing real user input. During this time, popups
564 : * are allowed. For mousedown events, mouse capturing is also permitted.
565 : */
566 : class nsAutoHandlingUserInputStatePusher
567 : {
568 : public:
569 0 : nsAutoHandlingUserInputStatePusher(bool aIsHandlingUserInput,
570 : nsEvent* aEvent,
571 : nsIDocument* aDocument)
572 : : mIsHandlingUserInput(aIsHandlingUserInput),
573 : mIsMouseDown(aEvent && aEvent->message == NS_MOUSE_BUTTON_DOWN),
574 0 : mResetFMMouseDownState(false)
575 : {
576 0 : if (aIsHandlingUserInput) {
577 0 : nsEventStateManager::StartHandlingUserInput();
578 0 : if (mIsMouseDown) {
579 0 : nsIPresShell::SetCapturingContent(nsnull, 0);
580 0 : nsIPresShell::AllowMouseCapture(true);
581 0 : if (aDocument && NS_IS_TRUSTED_EVENT(aEvent)) {
582 0 : nsFocusManager* fm = nsFocusManager::GetFocusManager();
583 0 : if (fm) {
584 0 : fm->SetMouseButtonDownHandlingDocument(aDocument);
585 0 : mResetFMMouseDownState = true;
586 : }
587 : }
588 : }
589 : }
590 0 : }
591 :
592 0 : ~nsAutoHandlingUserInputStatePusher()
593 : {
594 0 : if (mIsHandlingUserInput) {
595 0 : nsEventStateManager::StopHandlingUserInput();
596 0 : if (mIsMouseDown) {
597 0 : nsIPresShell::AllowMouseCapture(false);
598 0 : if (mResetFMMouseDownState) {
599 0 : nsFocusManager* fm = nsFocusManager::GetFocusManager();
600 0 : if (fm) {
601 0 : fm->SetMouseButtonDownHandlingDocument(nsnull);
602 : }
603 : }
604 : }
605 : }
606 0 : }
607 :
608 : protected:
609 : bool mIsHandlingUserInput;
610 : bool mIsMouseDown;
611 : bool mResetFMMouseDownState;
612 :
613 : private:
614 : // Hide so that this class can only be stack-allocated
615 : static void* operator new(size_t /*size*/) CPP_THROW_NEW { return nsnull; }
616 : static void operator delete(void* /*memory*/) {}
617 : };
618 :
619 : #define NS_EVENT_NEEDS_FRAME(event) (!NS_IS_ACTIVATION_EVENT(event))
620 :
621 : #endif // nsEventStateManager_h__
|