From 753219a03d39ee1fbded057925b1acb6f163b1ff Mon Sep 17 00:00:00 2001 From: "pinkerton%netscape.com" Date: Fri, 30 Mar 2001 04:45:40 +0000 Subject: [PATCH] switching mac to use NS_CONTEXTMENU event, click-hold context menus, switching embedding to use NS_CONTEXTMENU event. r=saari/sr=hyatt. bug# 36665, 18726 --- content/events/src/nsEventStateManager.cpp | 267 ++++++++- content/events/src/nsEventStateManager.h | 30 +- .../xul/content/src/nsXULPopupListener.cpp | 20 +- .../webBrowser/nsDocShellTreeOwner.cpp | 540 ++++++++++-------- .../browser/webBrowser/nsDocShellTreeOwner.h | 110 ++-- widget/src/mac/nsMacEventHandler.cpp | 36 +- 6 files changed, 702 insertions(+), 301 deletions(-) diff --git a/content/events/src/nsEventStateManager.cpp b/content/events/src/nsEventStateManager.cpp index 837d44127df..f390eefd76d 100644 --- a/content/events/src/nsEventStateManager.cpp +++ b/content/events/src/nsEventStateManager.cpp @@ -83,8 +83,13 @@ #include "nsIFrameTraversal.h" #include "nsLayoutCID.h" +#include "nsHTMLAtoms.h" +#include "nsXULAtoms.h" +#include "nsIDOMHTMLFormElement.h" + static NS_DEFINE_CID(kFrameTraversalCID, NS_FRAMETRAVERSAL_CID); + //we will use key binding by default now. this wil lbreak viewer for now #define NON_KEYBINDING 0 @@ -141,6 +146,10 @@ nsEventStateManager::nsEventStateManager() mBrowseWithCaret = PR_FALSE; hHover = PR_FALSE; NS_INIT_REFCNT(); + +#ifdef CLICK_HOLD_CONTEXT_MENUS + mEventDownWidget = nsnull; +#endif ++mInstanceCount; } @@ -288,7 +297,7 @@ nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext, switch (aEvent->message) { case NS_MOUSE_LEFT_BUTTON_DOWN: - BeginTrackingDragGesture ( (nsGUIEvent*)aEvent, aTargetFrame ); + BeginTrackingDragGesture ( aPresContext, (nsGUIEvent*)aEvent, aTargetFrame ); mLClickCount = ((nsMouseEvent*)aEvent)->clickCount; SetClickCount(aPresContext, (nsMouseEvent*)aEvent, aStatus); break; @@ -301,6 +310,9 @@ nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext, SetClickCount(aPresContext, (nsMouseEvent*)aEvent, aStatus); break; case NS_MOUSE_LEFT_BUTTON_UP: +#ifdef CLICK_HOLD_CONTEXT_MENUS + KillClickHoldTimer(); +#endif StopTrackingDragGesture(); case NS_MOUSE_MIDDLE_BUTTON_UP: case NS_MOUSE_RIGHT_BUTTON_UP: @@ -642,18 +654,188 @@ nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext, } +#ifdef CLICK_HOLD_CONTEXT_MENUS + + +// +// CreateClickHoldTimer +// +// Fire off a timer for determining if the user wants click-hold. This timer +// is a one-shot that will be cancelled when the user moves enough to fire +// a drag. +// +void +nsEventStateManager :: CreateClickHoldTimer ( nsIPresContext* inPresContext, nsGUIEvent* inMouseDownEvent ) +{ + // just to be anal (er, safe) + if ( mClickHoldTimer ) { + mClickHoldTimer->Cancel(); + mClickHoldTimer = nsnull; + } + + mClickHoldTimer = do_CreateInstance("@mozilla.org/timer;1"); + if ( mClickHoldTimer ) + mClickHoldTimer->Init(sClickHoldCallback, this, kClickHoldDelay, NS_PRIORITY_HIGH); + + mEventPoint = inMouseDownEvent->point; + mEventRefPoint = inMouseDownEvent->refPoint; + mEventDownWidget = inMouseDownEvent->widget; + + mEventPresContext = inPresContext; + +} // CreateClickHoldTimer + + +// +// KillClickHoldTimer +// +// Stop the timer that would show the context menu dead in its tracks +// +void +nsEventStateManager :: KillClickHoldTimer ( ) +{ + if ( mClickHoldTimer ) { + mClickHoldTimer->Cancel(); + mClickHoldTimer = nsnull; + } + + mEventDownWidget = nsnull; + mEventPresContext = nsnull; + +} // KillTooltipTimer + + +// +// sClickHoldCallback +// +// This fires after the mouse has been down for a certain length of time. +// +void +nsEventStateManager :: sClickHoldCallback ( nsITimer *aTimer, void* aESM ) +{ + nsEventStateManager* self = NS_STATIC_CAST(nsEventStateManager*, aESM); + if ( self ) + self->FireContextClick(); + + // NOTE: |aTimer| and |self->mAutoHideTimer| are invalid after calling ClosePopup(); + +} // sAutoHideCallback + + +// +// FireContextClick +// +// If we're this far, our timer has fired, which means the mouse has been down +// for a certain period of time and has not moved enough to generate a dragGesture. +// We can be certain the user wants a context-click at this stage, so generate +// a dom event and fire it in. +// +// After the event fires, check if PreventDefault() has been set on the event which +// means that someone either ate the event or put up a context menu. This is our cue +// to stop tracking the drag gesture. If we always did this, draggable items w/out +// a context menu wouldn't be draggable after a certain length of time, which is +// _not_ what we want. +// +void +nsEventStateManager :: FireContextClick ( ) +{ + if ( !mEventDownWidget || !mEventPresContext ) + return; + + nsEventStatus status = nsEventStatus_eIgnore; + nsMouseEvent event; + event.eventStructType = NS_MOUSE_EVENT; + event.message = NS_CONTEXTMENU; + event.widget = mEventDownWidget; + event.clickCount = 1; + event.point = mEventPoint; + event.refPoint = mEventRefPoint; + event.isShift = PR_FALSE; + event.isControl = PR_FALSE; + event.isAlt = PR_FALSE; + event.isMeta = PR_FALSE; + + // Dispatch to the DOM. We have to fake out the ESM and tell it that the + // current target frame is actually where the mouseDown occurred, otherwise it + // will use the frame the mouse is currently over which may or may not be + // the same. (Note: saari and I have decided that we don't have to reset |mCurrentTarget| + // when we're through because no one else is doing anything more with this + // event and it will get reset on the very next event to the correct frame). + mCurrentTarget = mGestureDownFrame; + nsCOMPtr lastContent; + if ( mGestureDownFrame ) { + mGestureDownFrame->GetContent(getter_AddRefs(lastContent)); + + if ( lastContent ) { + // before dispatching, check that we're not on something that doesn't get a context menu + PRBool allowedToDispatch = PR_TRUE; + + nsCOMPtr tag; + lastContent->GetTag ( *getter_AddRefs(tag) ); + nsCOMPtr formElm ( do_QueryInterface(lastContent) ); + if ( formElm ) { + // of all form elements, onlyt and