зеркало из https://github.com/mozilla/gecko-dev.git
add support for context menu key. use focussed element as the target, not the mouse coordinates. r=roc,dean_tessman@hotmail.com/sr=hyatt. bug#74410, 36665.
This commit is contained in:
Родитель
f269df764c
Коммит
0b03ce7cda
|
@ -1409,6 +1409,7 @@ const char* nsDOMEvent::GetEventName(PRUint32 aEventType)
|
|||
case NS_MUTATION_CHARACTERDATAMODIFIED:
|
||||
return mEventNames[eDOMEvents_characterdatamodified];
|
||||
case NS_CONTEXTMENU:
|
||||
case NS_CONTEXTMENU_KEY:
|
||||
return mEventNames[eDOMEvents_contextmenu];
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -63,6 +63,12 @@
|
|||
#include "nsDOMCID.h"
|
||||
#include "nsIScriptObjectOwner.h" // for nsIScriptEventHandlerOwner
|
||||
#include "nsIClassInfo.h"
|
||||
#include "nsIFocusController.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIBoxObject.h"
|
||||
#include "nsIDOMNSDocument.h"
|
||||
#include "nsIWidget.h"
|
||||
|
||||
|
||||
static NS_DEFINE_CID(kDOMScriptObjectFactoryCID,
|
||||
NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
|
||||
|
@ -1366,12 +1372,55 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext,
|
|||
break;
|
||||
|
||||
case NS_CONTEXTMENU:
|
||||
case NS_CONTEXTMENU_KEY:
|
||||
listeners = GetListenersByType(eEventArrayType_ContextMenu, nsnull, PR_FALSE);
|
||||
if (listeners) {
|
||||
if (nsnull == *aDOMEvent) {
|
||||
|
||||
// If we're here because of the key-equiv for showing context menus, we
|
||||
// have to reset the event target to the currently focused element. Get it
|
||||
// from the focus controller.
|
||||
nsCOMPtr<nsIDOMEventTarget> currentTarget ( aCurrentTarget );
|
||||
nsCOMPtr<nsIDOMElement> currentFocus;
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
if ( aEvent->message == NS_CONTEXTMENU_KEY ) {
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
aPresContext->GetShell(getter_AddRefs(shell));
|
||||
shell->GetDocument(getter_AddRefs(doc));
|
||||
if ( doc ) {
|
||||
nsCOMPtr<nsIScriptGlobalObject> scriptObj;
|
||||
doc->GetScriptGlobalObject(getter_AddRefs(scriptObj));
|
||||
if ( scriptObj ) {
|
||||
nsCOMPtr<nsPIDOMWindow> privWindow = do_QueryInterface(scriptObj);
|
||||
if ( privWindow ) {
|
||||
nsCOMPtr<nsIFocusController> focusController;
|
||||
privWindow->GetRootFocusController(getter_AddRefs(focusController));
|
||||
if ( focusController )
|
||||
focusController->GetFocusedElement(getter_AddRefs(currentFocus));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nsnull == *aDOMEvent) {
|
||||
// If we're here because of the key-equiv for showing context menus, we
|
||||
// have to twiddle with the NS event to make sure the context menu comes
|
||||
// up in the upper left of the relevant content area before we create
|
||||
// the DOM event. Since we never call InitMouseEvent() on the event,
|
||||
// the client X/Y will be 0,0. We can make use of that if the widget is null.
|
||||
if ( aEvent->message == NS_CONTEXTMENU_KEY )
|
||||
NS_IF_RELEASE(((nsGUIEvent*)aEvent)->widget); // nulls out widget
|
||||
|
||||
ret = NS_NewDOMUIEvent(aDOMEvent, aPresContext, empty, aEvent);
|
||||
}
|
||||
|
||||
if (NS_OK == ret) {
|
||||
// update the target
|
||||
if ( currentFocus ) {
|
||||
currentTarget = do_QueryInterface(currentFocus);
|
||||
nsCOMPtr<nsIPrivateDOMEvent> pEvent ( do_QueryInterface(*aDOMEvent) );
|
||||
pEvent->SetTarget ( currentTarget );
|
||||
}
|
||||
|
||||
for (int i=0; !mListenersRemoved && listeners && i<listeners->Count(); i++) {
|
||||
nsListenerStruct *ls = (nsListenerStruct*)listeners->ElementAt(i);
|
||||
|
||||
|
@ -1380,6 +1429,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext,
|
|||
if (contextMenuListener) {
|
||||
switch(aEvent->message) {
|
||||
case NS_CONTEXTMENU:
|
||||
case NS_CONTEXTMENU_KEY:
|
||||
ret = contextMenuListener->ContextMenu(*aDOMEvent);
|
||||
break;
|
||||
default:
|
||||
|
@ -1391,6 +1441,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext,
|
|||
PRUint32 subType = 0;
|
||||
switch(aEvent->message) {
|
||||
case NS_CONTEXTMENU:
|
||||
case NS_CONTEXTMENU_KEY:
|
||||
subType = NS_EVENT_BITS_CONTEXT_MENU;
|
||||
if (ls->mSubType & NS_EVENT_BITS_CONTEXT_MENU) {
|
||||
correctSubType = PR_TRUE;
|
||||
|
@ -1400,7 +1451,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext,
|
|||
break;
|
||||
}
|
||||
if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) {
|
||||
ret = HandleEventSubType(ls, *aDOMEvent, aCurrentTarget, subType, aFlags);
|
||||
ret = HandleEventSubType(ls, *aDOMEvent, currentTarget, subType, aFlags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5355,7 +5355,7 @@ PresShell::HandleEvent(nsIView *aView,
|
|||
nsIEventStateManager *manager;
|
||||
if (NS_OK == mPresContext->GetEventStateManager(&manager)) {
|
||||
//change 6-01-00 mjudge,ftang adding ime as an event that needs focused element
|
||||
if (NS_IS_KEY_EVENT(aEvent) || NS_IS_IME_EVENT(aEvent)) {
|
||||
if (NS_IS_KEY_EVENT(aEvent) || NS_IS_IME_EVENT(aEvent) || aEvent->message == NS_CONTEXTMENU_KEY) {
|
||||
//Key events go to the focused frame, not point based.
|
||||
manager->GetFocusedContent(&mCurrentEventContent);
|
||||
if (mCurrentEventContent)
|
||||
|
|
|
@ -5355,7 +5355,7 @@ PresShell::HandleEvent(nsIView *aView,
|
|||
nsIEventStateManager *manager;
|
||||
if (NS_OK == mPresContext->GetEventStateManager(&manager)) {
|
||||
//change 6-01-00 mjudge,ftang adding ime as an event that needs focused element
|
||||
if (NS_IS_KEY_EVENT(aEvent) || NS_IS_IME_EVENT(aEvent)) {
|
||||
if (NS_IS_KEY_EVENT(aEvent) || NS_IS_IME_EVENT(aEvent) || aEvent->message == NS_CONTEXTMENU_KEY) {
|
||||
//Key events go to the focused frame, not point based.
|
||||
manager->GetFocusedContent(&mCurrentEventContent);
|
||||
if (mCurrentEventContent)
|
||||
|
|
|
@ -306,20 +306,20 @@ NS_IMETHODIMP nsView :: HandleEvent(nsGUIEvent *event, PRUint32 aEventFlags,
|
|||
// Hold a refcount to the observer. The continued existence of the observer will
|
||||
// delay deletion of this view hierarchy should the event want to cause its
|
||||
// destruction in, say, some JavaScript event handler.
|
||||
nsIViewObserver *obs;
|
||||
if (NS_FAILED(mViewManager->GetViewObserver(obs)))
|
||||
obs = nsnull;
|
||||
nsCOMPtr<nsIViewObserver> obs;
|
||||
mViewManager->GetViewObserver(*getter_AddRefs(obs));
|
||||
|
||||
// if accessible event pass directly to the view observer
|
||||
if (event->eventStructType == NS_ACCESSIBLE_EVENT) {
|
||||
if (event->eventStructType == NS_ACCESSIBLE_EVENT || event->message == NS_CONTEXTMENU_KEY) {
|
||||
if (obs)
|
||||
obs->HandleEvent((nsIView *)this, event, aStatus, aForceHandle, aHandled);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
*aStatus = nsEventStatus_eIgnore;
|
||||
|
||||
//see if any of this view's children can process the event
|
||||
if (*aStatus == nsEventStatus_eIgnore && !(mVFlags & NS_VIEW_PUBLIC_FLAG_DONT_CHECK_CHILDREN)) {
|
||||
if ( !(mVFlags & NS_VIEW_PUBLIC_FLAG_DONT_CHECK_CHILDREN) ) {
|
||||
PRInt32 numkids;
|
||||
nsRect trect;
|
||||
nscoord x, y;
|
||||
|
@ -374,8 +374,6 @@ NS_IMETHODIMP nsView :: HandleEvent(nsGUIEvent *event, PRUint32 aEventFlags,
|
|||
}
|
||||
*/
|
||||
|
||||
NS_IF_RELEASE(obs);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -271,13 +271,7 @@ struct nsReconversionEvent : public nsInputEvent {
|
|||
nsReconversionEventReply theReply;
|
||||
};
|
||||
|
||||
/**
|
||||
* Tooltip event
|
||||
*/
|
||||
struct nsTooltipEvent : public nsGUIEvent {
|
||||
/// Index of tooltip area which generated the event. @see SetTooltips in nsIWidget
|
||||
PRUint32 tipIndex;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* MenuItem event
|
||||
|
@ -315,6 +309,7 @@ enum nsDragDropEventStatus {
|
|||
nsDragDropEventStatus_eDrop
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Event Struct Types
|
||||
*/
|
||||
|
@ -426,6 +421,7 @@ enum nsDragDropEventStatus {
|
|||
|
||||
#define NS_CONTEXTMENU_MESSAGE_START 500
|
||||
#define NS_CONTEXTMENU (NS_CONTEXTMENU_MESSAGE_START)
|
||||
#define NS_CONTEXTMENU_KEY (NS_CONTEXTMENU_MESSAGE_START + 1)
|
||||
|
||||
#define NS_SCROLLBAR_MESSAGE_START 1000
|
||||
#define NS_SCROLLBAR_POS (NS_SCROLLBAR_MESSAGE_START)
|
||||
|
|
|
@ -3021,7 +3021,12 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
|
|||
break;
|
||||
|
||||
case WM_CONTEXTMENU:
|
||||
result = DispatchMouseEvent(NS_CONTEXTMENU);
|
||||
{
|
||||
// if the context menu is brought up from the keyboard, |lParam|
|
||||
// will be maxlong. Send a different event msg instead.
|
||||
PRUint32 msg = (lParam == 0xFFFFFFFF) ? NS_CONTEXTMENU_KEY : NS_CONTEXTMENU;
|
||||
result = DispatchMouseEvent(msg);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_LBUTTONDBLCLK:
|
||||
|
@ -4112,7 +4117,7 @@ PRBool nsWindow::DispatchMouseEvent(PRUint32 aEventType, nsPoint* aPoint)
|
|||
gCurrentWindow = nsnull;
|
||||
}
|
||||
}
|
||||
NS_RELEASE(event.widget);
|
||||
NS_IF_RELEASE(event.widget);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче