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<nsPIEventSinkStandalone> 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 @@
-<!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
      in em units of the dialog. Localizers ONLY can increase these widths 
      if they are having difficulty getting panel content to fit. 1em = the 
      width of the letter 'm' in the selected font.
      XUL/FE DEVELOPERS: DO NOT MODIFY THIS VALUE. It represents the correct
      size of this window for en-US. -->
