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:
pinkerton%netscape.com 2001-05-17 18:37:50 +00:00
Родитель f269df764c
Коммит 0b03ce7cda
7 изменённых файлов: 71 добавлений и 20 удалений

Просмотреть файл

@ -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;
}