void ShowContextMenu(HWND hWnd, PRBool status) { abpJSContextHolder holder; JSObject* overlay = UnwrapJSObject(fakeBrowserWindow); JSContext* cx = holder.get(); if (cx != nsnull && overlay != nsnull) { jsval arg = (status ? JSVAL_TRUE : JSVAL_FALSE); jsval retval; if (JS_CallFunctionName(cx, overlay, "buildContextMenu", 1, &arg, &retval)) { HMENU hMenu = NS_REINTERPRET_CAST(HMENU, JSVAL_TO_INT(retval)); POINT pt; GetCursorPos(&pt); TrackPopupMenu(hMenu, TPM_LEFTALIGN, pt.x, pt.y, 0, hWnd, NULL); } } }
//------------------------------------------------------------------------- // // DoMouseDown // //------------------------------------------------------------------------- PRBool nsMacMessagePump::DoMouseDown(EventRecord &anEvent) { WindowPtr whichWindow; WindowPartCode partCode; PRBool handled = PR_FALSE; partCode = ::FindWindow(anEvent.where, &whichWindow); switch (partCode) { case inNoWindow: break; case inCollapseBox: // we never seem to get this. case inSysWindow: if ( gRollupListener && gRollupWidget ) gRollupListener->Rollup(); break; case inMenuBar: { // If a xul popup is displayed, roll it up and don't allow the click // through to the menu code. This is how MacOS context menus work, so // I think this is a valid solution. if ( gRollupListener && gRollupWidget ) { gRollupListener->Rollup(); } else { ::MenuSelect(anEvent.where); handled = PR_TRUE; } break; } case inContent: { nsGraphicsUtils::SafeSetPortWindowPort(whichWindow); if ( IsWindowHilited(whichWindow) || (gRollupListener && gRollupWidget) ) handled = DispatchOSEventToRaptor(anEvent, whichWindow); else { nsCOMPtr<nsIWidget> topWidget; nsToolkit::GetTopWidget ( whichWindow, getter_AddRefs(topWidget) ); nsCOMPtr<nsPIWidgetMac> macWindow ( do_QueryInterface(topWidget) ); if ( macWindow ) { // a click occurred in a background window. Use WaitMouseMove() to determine if // it was a click or a drag. If it was a drag, send a drag gesture to the // background window. We don't need to rely on the ESM to track the gesture, // the OS has just told us. If it was a click, bring it to the front like normal. Boolean initiateDragFromBGWindow = ::WaitMouseMoved(anEvent.where); if ( initiateDragFromBGWindow ) { nsCOMPtr<nsIEventSink> sink ( do_QueryInterface(topWidget) ); if ( sink ) { // dispach a mousedown, an update event to paint any changes, // then the drag gesture event PRBool handled = PR_FALSE; sink->DispatchEvent ( &anEvent, &handled ); EventRecord updateEvent = anEvent; updateEvent.what = updateEvt; updateEvent.message = NS_REINTERPRET_CAST(UInt32, whichWindow); sink->DispatchEvent ( &updateEvent, &handled ); sink->DragEvent ( NS_DRAGDROP_GESTURE, anEvent.where.h, anEvent.where.v, 0L, &handled ); } } else { PRBool enabled; if (NS_SUCCEEDED(topWidget->IsEnabled(&enabled)) && !enabled) ::SysBeep(1); else macWindow->ComeToFront(); } handled = PR_TRUE; } } break; } case inDrag: { nsGraphicsUtils::SafeSetPortWindowPort(whichWindow); Point oldTopLeft = {0, 0}; ::LocalToGlobal(&oldTopLeft); // roll up popups BEFORE we start the drag if ( gRollupListener && gRollupWidget ) gRollupListener->Rollup(); Rect screenRect; ::GetRegionBounds(::GetGrayRgn(), &screenRect); ::DragWindow(whichWindow, anEvent.where, &screenRect); Point newTopLeft = {0, 0}; ::LocalToGlobal(&newTopLeft); // only activate if the command key is not down if (!(anEvent.modifiers & cmdKey)) { nsCOMPtr<nsIWidget> topWidget; nsToolkit::GetTopWidget(whichWindow, getter_AddRefs(topWidget)); nsCOMPtr<nsPIWidgetMac> macWindow ( do_QueryInterface(topWidget) ); if ( macWindow ) macWindow->ComeToFront(); } // Dispatch the event because some windows may want to know that they have been moved. anEvent.where.h += newTopLeft.h - oldTopLeft.h; anEvent.where.v += newTopLeft.v - oldTopLeft.v; handled = DispatchOSEventToRaptor(anEvent, whichWindow); break; } case inGrow: { nsGraphicsUtils::SafeSetPortWindowPort(whichWindow); Rect sizeLimit; sizeLimit.top = kMinWindowHeight; sizeLimit.left = kMinWindowWidth; sizeLimit.bottom = 0x7FFF; sizeLimit.right = 0x7FFF; Rect newSize; ::ResizeWindow(whichWindow, anEvent.where, &sizeLimit, &newSize); Point newPt = botRight(newSize); ::LocalToGlobal(&newPt); newPt.h -= 8, newPt.v -= 8; anEvent.where = newPt; // important! handled = DispatchOSEventToRaptor(anEvent, whichWindow); break; } case inGoAway: { nsGraphicsUtils::SafeSetPortWindowPort(whichWindow); if (::TrackGoAway(whichWindow, anEvent.where)) { handled = DispatchOSEventToRaptor(anEvent, whichWindow); } break; } case inZoomIn: case inZoomOut: if (::TrackBox(whichWindow, anEvent.where, partCode)) { if (partCode == inZoomOut) { nsCOMPtr<nsIWidget> topWidget; nsToolkit::GetTopWidget ( whichWindow, getter_AddRefs(topWidget) ); nsCOMPtr<nsPIWidgetMac> macWindow ( do_QueryInterface(topWidget) ); if ( macWindow ) macWindow->CalculateAndSetZoomedSize(); } // !!! Do not call ZoomWindow before calling DispatchOSEventToRaptor // otherwise nsMacEventHandler::HandleMouseDownEvent won't get // the right partcode for the click location handled = DispatchOSEventToRaptor(anEvent, whichWindow); } break; case inToolbarButton: // Mac OS X only nsGraphicsUtils::SafeSetPortWindowPort(whichWindow); handled = DispatchOSEventToRaptor(anEvent, whichWindow); break; } return handled; }