Bug 151249 - Middle-click on link doesn't work on Mac. r=pinkerton, sr=sfraser.

This commit is contained in:
pedemont%us.ibm.com 2004-12-15 16:32:02 +00:00
parent f44157ebb5
commit 16e3e0ddd3
4 changed files with 83 additions and 9 deletions

View File

@ -1572,14 +1572,22 @@ PRBool nsMacEventHandler::HandleMouseDownEvent(EventRecord& aOSEvent)
case inContent:
{
// don't allow clicks that rolled up a popup through to the content area.
if ( ignoreClickInContent )
break;
// don't allow clicks that rolled up a popup through to the content area.
if ( ignoreClickInContent )
break;
nsMouseEvent mouseEvent;
PRUint32 mouseButton = NS_MOUSE_LEFT_BUTTON_DOWN;
if ( aOSEvent.modifiers & controlKey )
mouseButton = NS_MOUSE_RIGHT_BUTTON_DOWN;
// We've hacked our events to include the button.
// Normally message is undefined in mouse click/drag events.
if ( aOSEvent.message == kEventMouseButtonSecondary )
mouseButton = NS_MOUSE_RIGHT_BUTTON_DOWN;
if ( aOSEvent.message == kEventMouseButtonTertiary )
mouseButton = NS_MOUSE_MIDDLE_BUTTON_DOWN;
ConvertOSEventToMouseEvent(aOSEvent, mouseEvent, mouseButton);
#if !TARGET_CARBON
@ -1669,7 +1677,16 @@ PRBool nsMacEventHandler::HandleMouseUpEvent(
PRBool retVal = PR_FALSE;
nsMouseEvent mouseEvent;
ConvertOSEventToMouseEvent(aOSEvent, mouseEvent, NS_MOUSE_LEFT_BUTTON_UP);
PRUint32 mouseButton = NS_MOUSE_LEFT_BUTTON_UP;
// We've hacked our events to include the button.
// Normally message is undefined in mouse click/drag events.
if ( aOSEvent.message == kEventMouseButtonSecondary )
mouseButton = NS_MOUSE_RIGHT_BUTTON_UP;
if ( aOSEvent.message == kEventMouseButtonTertiary )
mouseButton = NS_MOUSE_MIDDLE_BUTTON_UP;
ConvertOSEventToMouseEvent(aOSEvent, mouseEvent, mouseButton);
nsWindow* widgetReleased = (nsWindow*)mouseEvent.widget;
nsWindow* widgetHit = gEventDispatchHandler.GetWidgetHit();
@ -1774,13 +1791,17 @@ void nsMacEventHandler::ConvertOSEventToMouseEvent(
static SInt16 sLastClickCount = 0;
// we're going to time double-clicks from mouse *up* to next mouse *down*
if (aMessage == NS_MOUSE_LEFT_BUTTON_UP)
if (aMessage == NS_MOUSE_LEFT_BUTTON_UP ||
aMessage == NS_MOUSE_RIGHT_BUTTON_UP ||
aMessage == NS_MOUSE_MIDDLE_BUTTON_UP)
{
// remember when this happened for the next mouse down
sLastMouseUp = aOSEvent.when;
sLastWhere = aOSEvent.where;
}
else if (aMessage == NS_MOUSE_LEFT_BUTTON_DOWN)
else if (aMessage == NS_MOUSE_LEFT_BUTTON_DOWN ||
aMessage == NS_MOUSE_RIGHT_BUTTON_DOWN ||
aMessage == NS_MOUSE_MIDDLE_BUTTON_DOWN)
{
// now look to see if we want to convert this to a double- or triple-click
const short kDoubleClickMoveThreshold = 5;

View File

@ -203,6 +203,17 @@ nsMacMessagePump::nsMacMessagePump(nsToolkit *aToolkit)
// added to support Menu Sharing API. Initializes the Menu Sharing API.
InitSharedMenus (ErrorDialog, EventFilter);
#endif
// To handle middle-button clicks we must use Carbon Events
const EventTypeSpec eventTypes[] = {
{ kEventClassMouse, kEventMouseDown },
{ kEventClassMouse, kEventMouseUp }
};
EventHandlerUPP handlerUPP =
::NewEventHandlerUPP(nsMacMessagePump::CarbonMouseHandler);
::InstallApplicationEventHandler(handlerUPP, GetEventTypeCount(eventTypes),
eventTypes, (void*)this, NULL);
}
//=================================================================
@ -1017,3 +1028,43 @@ PRBool nsMacMessagePump::DispatchMenuCommandToRaptor(
}
#endif
pascal OSStatus nsMacMessagePump::CarbonMouseHandler(
EventHandlerCallRef nextHandler,
EventRef theEvent, void *userData)
{
EventMouseButton button;
OSErr err = ::GetEventParameter(theEvent, kEventParamMouseButton,
typeMouseButton, NULL,
sizeof(EventMouseButton), NULL, &button);
if (err != noErr)
return eventNotHandledErr;
EventRecord theRecord;
if (!::ConvertEventRefToEventRecord(theEvent, &theRecord)) {
if (button == kEventMouseButtonTertiary) {
// This will return FALSE on a middle click event; that's to let us know
// it's giving us a nullEvent, which is expected since Classic events
// don't support the middle button normally.
//
// We know better, so let's restore the actual event kind.
UInt32 kind = ::GetEventKind(theEvent);
theRecord.what = (kind == kEventMouseDown) ? mouseDown : mouseUp;
} else {
// Or maybe it's the tenth swirlygig button wheel being twist-clicked.
// Just pretend we never saw it...
return eventNotHandledErr;
}
}
// Classic mouse events don't record the button specifier. The message
// parameter is unused in mouse click events, so let's stuff it there.
// We'll pick it up in nsMacEventHandler::HandleMouseDownEvent().
theRecord.message = (UInt32)button;
// Process the modified event internally
nsMacMessagePump *pump = (nsMacMessagePump*)userData;
pump->DispatchEvent(PR_TRUE, &theRecord);
return noErr;
}

View File

@ -109,9 +109,11 @@ private:
#endif
PRBool BrowserIsBusy();
WindowPtr GetFrontApplicationWindow();
static pascal OSStatus CarbonMouseHandler(EventHandlerCallRef nextHandler,
EventRef theEvent, void *userData);
};

View File

@ -1,5 +1,5 @@
<!ENTITY urlbar.label "Cmd+Return in the Location bar">
<!ENTITY middleClick.label "Cmd+click or Cmd+Return on links in a Web page">
<!ENTITY urlbar.label "&#8984;+Return in the Location bar">
<!ENTITY middleClick.label "Middle-click, &#8984;+click or &#8984;+Return on links in a Web page">
<!-- LOCALIZATION NOTE : this is part of an inline-style attribute on the
preference dialog's <window> node, which specifies the width and height