Index: widget/src/mac/nsMacEventHandler.cpp =================================================================== RCS file: /cvsroot/mozilla/widget/src/mac/nsMacEventHandler.cpp,v retrieving revision 1.163 diff -u -8 -p -r1.163 nsMacEventHandler.cpp --- widget/src/mac/nsMacEventHandler.cpp 30 Jul 2004 15:24:12 -0000 1.163 +++ widget/src/mac/nsMacEventHandler.cpp 28 Aug 2004 01:04:47 -0000 @@ -1566,24 +1566,32 @@ PRBool nsMacEventHandler::HandleMouseDow } gEventDispatchHandler.DispatchGuiEvent(mTopLevelWidget, NS_XUL_CLOSE); // mTopLevelWidget->Destroy(); (this, by contrast, would immediately close the window) break; } 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; +#if XP_MACOSX + // 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; +#endif ConvertOSEventToMouseEvent(aOSEvent, mouseEvent, mouseButton); #if !TARGET_CARBON // Check if the mousedown is in our window's phantom scrollbar. If so, track // the movement of the mouse. The scrolling code is in the action proc. Point local = aOSEvent.where; ::GlobalToLocal ( &local ); ControlHandle scrollbar; @@ -1663,17 +1671,26 @@ PRBool nsMacEventHandler::HandleMouseDow // //------------------------------------------------------------------------- PRBool nsMacEventHandler::HandleMouseUpEvent( EventRecord& aOSEvent) { PRBool retVal = PR_FALSE; nsMouseEvent mouseEvent; - ConvertOSEventToMouseEvent(aOSEvent, mouseEvent, NS_MOUSE_LEFT_BUTTON_UP); + PRUint32 mouseButton = NS_MOUSE_LEFT_BUTTON_UP; +#if XP_MACOSX + // 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; +#endif + ConvertOSEventToMouseEvent(aOSEvent, mouseEvent, mouseButton); nsWindow* widgetReleased = (nsWindow*)mouseEvent.widget; nsWindow* widgetHit = gEventDispatchHandler.GetWidgetHit(); if ( widgetReleased ) retVal |= widgetReleased->DispatchMouseEvent(mouseEvent); if ( widgetReleased != widgetHit ) { @@ -1768,23 +1785,23 @@ void nsMacEventHandler::ConvertOSEventTo nsMouseEvent& aMouseEvent, PRUint32 aMessage) { static UInt32 sLastMouseUp = 0; static Point sLastWhere = {0}; 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; if (((aOSEvent.when - sLastMouseUp) < ::GetDblTime()) && (((abs(aOSEvent.where.h - sLastWhere.h) < kDoubleClickMoveThreshold) && (abs(aOSEvent.where.v - sLastWhere.v) < kDoubleClickMoveThreshold)))) { Index: widget/src/mac/nsMacMessagePump.cpp =================================================================== RCS file: /cvsroot/mozilla/widget/src/mac/nsMacMessagePump.cpp,v retrieving revision 1.142 diff -u -8 -p -r1.142 nsMacMessagePump.cpp --- widget/src/mac/nsMacMessagePump.cpp 18 Apr 2004 22:00:27 -0000 1.142 +++ widget/src/mac/nsMacMessagePump.cpp 28 Aug 2004 01:04:49 -0000 @@ -232,16 +232,27 @@ nsMacMessagePump::nsMacMessagePump(nsToo // startup the watch cursor idle time vbl task nsWatchTask::GetTask().Start(); #if TARGET_CARBON && !XP_MACOSX // added to support Menu Sharing API. Initializes the Menu Sharing API. InitSharedMenus (ErrorDialog, EventFilter); #endif + +#ifdef XP_MACOSX + // 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); +#endif } //================================================================= /* Destructor * @update dc 08/31/98 * @param NONE * @return NONE */ @@ -1062,8 +1073,49 @@ PRBool nsMacMessagePump::DispatchMenuCom nsToolkit::GetWindowEventSink ( theFrontWindow, getter_AddRefs(sink) ); nsCOMPtr menuSink ( do_QueryInterface(sink) ); if ( menuSink ) menuSink->DispatchMenuEvent ( &anEvent, menuResult, &handled ); return handled; } #endif + +#if XP_MACOSX +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; +} +#endif Index: widget/src/mac/nsMacMessagePump.h =================================================================== RCS file: /cvsroot/mozilla/widget/src/mac/nsMacMessagePump.h,v retrieving revision 1.33 diff -u -8 -p -r1.33 nsMacMessagePump.h --- widget/src/mac/nsMacMessagePump.h 18 Apr 2004 22:00:27 -0000 1.33 +++ widget/src/mac/nsMacMessagePump.h 28 Aug 2004 01:04:49 -0000 @@ -107,14 +107,17 @@ private: #if USE_MENUSELECT PRBool DispatchMenuCommandToRaptor(EventRecord &anEvent, long menuResult); #endif PRBool BrowserIsBusy(); WindowPtr GetFrontApplicationWindow(); +#if XP_MACOSX + static pascal OSStatus CarbonMouseHandler(EventHandlerCallRef nextHandler, EventRef theEvent, void *userData); +#endif }; #endif // nsMacMessagePump_h__ Index: xpfe/components/prefwindow/resources/locale/en-US/mac/platformPrefOverlay.dtd =================================================================== RCS file: /cvsroot/mozilla/xpfe/components/prefwindow/resources/locale/en-US/mac/platformPrefOverlay.dtd,v retrieving revision 1.5 diff -u -8 -p -r1.5 platformPrefOverlay.dtd --- xpfe/components/prefwindow/resources/locale/en-US/mac/platformPrefOverlay.dtd 21 Nov 2003 09:13:36 -0000 1.5 +++ xpfe/components/prefwindow/resources/locale/en-US/mac/platformPrefOverlay.dtd 28 Aug 2004 01:04:49 -0000 @@ -1,10 +1,10 @@ - - + +