Bug 583296 - Fix StartDrawingPlugin to correctly detect nested OS X OOPP paint events. r=josh SEAMONKEY_2_1a3_BUILD1 SEAMONKEY_2_1a3_BUILD2 SEAMONKEY_2_1a3_RELEASE
authorBenoit Girard <b56girard@gmail.com>
Sun, 15 Aug 2010 13:42:09 -0400
changeset 50639 5e9c05dbe8d6a2165e0112cba51068abbc1a3b96
parent 50638 49c7db18003b0972af4c9331bcb3659925c7267f
child 50640 0074c4f2d5613fce33517662d8c1a95b1595e966
child 50642 a1a1dba5b084d74d53494bfb21488dd28181e587
push id1
push usershaver@mozilla.com
push dateTue, 04 Jan 2011 17:58:04 +0000
reviewersjosh
bugs583296
milestone2.0b4pre
Bug 583296 - Fix StartDrawingPlugin to correctly detect nested OS X OOPP paint events. r=josh
dom/plugins/PluginUtilsOSX.mm
widget/src/cocoa/nsChildView.h
widget/src/cocoa/nsChildView.mm
--- a/dom/plugins/PluginUtilsOSX.mm
+++ b/dom/plugins/PluginUtilsOSX.mm
@@ -67,31 +67,28 @@ using namespace mozilla::plugins::Plugin
 @end
 
 #define EVENT_PROCESS_DELAY 0.05 // 50 ms
 
 NPError mozilla::plugins::PluginUtilsOSX::ShowCocoaContextMenu(void* aMenu, int aX, int aY, void* pluginModule, RemoteProcessEvents remoteEvent) 
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
 
-  // Leave out this code until we can fix painting. See bug 568513.
-  /*
   // Create a timer to process browser events while waiting
   // on the menu. This prevents the browser from hanging
   // during the lifetime of the menu.
   EventProcessor* eventProcessor = [[EventProcessor alloc] init];
   [eventProcessor setRemoteEvents:remoteEvent pluginModule:pluginModule];
   NSTimer *eventTimer = [NSTimer timerWithTimeInterval:EVENT_PROCESS_DELAY
                              target:eventProcessor selector:@selector(onTick) 
                              userInfo:nil repeats:TRUE];
   // Use NSEventTrackingRunLoopMode otherwise the timer will
   // not fire during the right click menu.
   [[NSRunLoop currentRunLoop] addTimer:eventTimer 
                               forMode:NSEventTrackingRunLoopMode];
-  */
 
   NSMenu* nsmenu = reinterpret_cast<NSMenu*>(aMenu);
   NSPoint screen_point = ::NSMakePoint(aX, aY);
 
   [nsmenu popUpMenuPositioningItem:nil atLocation:screen_point inView:nil];
 
   //[eventTimer invalidate];
   //[eventProcessor release];
--- a/widget/src/cocoa/nsChildView.h
+++ b/widget/src/cocoa/nsChildView.h
@@ -426,16 +426,17 @@ protected:
 #endif
 
   nsRefPtr<gfxASurface> mTempThebesSurface;
 
   PRPackedBool          mVisible;
   PRPackedBool          mDrawing;
   PRPackedBool          mPluginDrawing;
   PRPackedBool          mPluginIsCG; // true if this is a CoreGraphics plugin
+  PRPackedBool          mIsDispatchPaint; // Is a paint event being dispatched
 
   NP_CGContext          mPluginCGContext;
 #ifndef NP_NO_QUICKDRAW
   NP_Port               mPluginQDPort;
 #endif
   nsIPluginInstanceOwner* mPluginInstanceOwner; // [WEAK]
 
   static PRUint32 sLastInputEventCount;
--- a/widget/src/cocoa/nsChildView.mm
+++ b/widget/src/cocoa/nsChildView.mm
@@ -465,16 +465,17 @@ static void DebugPrintAllKeyboardLayouts
 nsChildView::nsChildView() : nsBaseWidget()
 , mView(nsnull)
 , mParentView(nsnull)
 , mParentWidget(nsnull)
 , mVisible(PR_FALSE)
 , mDrawing(PR_FALSE)
 , mPluginDrawing(PR_FALSE)
 , mPluginIsCG(PR_FALSE)
+, mIsDispatchPaint(PR_FALSE)
 , mPluginInstanceOwner(nsnull)
 {
 #ifdef PR_LOGGING
   if (!sCocoaLog) {
     sCocoaLog = PR_NewLogModule("nsCocoaWidgets");
 #ifdef DEBUG
     DebugPrintAllKeyboardLayouts();
 #endif // DEBUG
@@ -1245,17 +1246,17 @@ NS_IMETHODIMP nsChildView::StartDrawPlug
   // In QuickDraw drawing mode, prevent reentrant handling of any plugin event
   // (this emulates behavior on the 1.8 branch, where only QuickDraw mode is
   // supported).  But in CoreGraphics drawing mode only do this if the current
   // plugin event isn't an update/paint event.  This allows popupcontextmenu()
   // to work properly from a plugin that supports the Cocoa event model,
   // without regressing bug 409615.  See bug 435041.  (StartDrawPlugin() and
   // EndDrawPlugin() wrap every call to nsIPluginInstance::HandleEvent() --
   // not just calls that "draw" or paint.)
-  if (!mPluginIsCG || (mView != [NSView focusView])) {
+  if (!mPluginIsCG || mIsDispatchPaint) {
     if (mPluginDrawing)
       return NS_ERROR_FAILURE;
   }
 
   // It appears that the WindowRef from which we get the plugin port undergoes the
   // traditional BeginUpdate/EndUpdate cycle, which, if you recall, sets the visible
   // region to the intersection of the visible region and the update region. Since
   // we don't know here if we're being drawn inside a BeginUpdate/EndUpdate pair
@@ -1690,19 +1691,24 @@ NS_IMETHODIMP nsChildView::DispatchEvent
       void* clientData = nsnull;
       if (event->widget)
         event->widget->GetClientData(clientData);
       if (!clientData)
         event->widget = mParentWidget;
     }
   }
 
+  PRBool restoreIsDispatchPaint = mIsDispatchPaint;
+  mIsDispatchPaint = mIsDispatchPaint || event->eventStructType == NS_PAINT_EVENT;
+
   if (mEventCallback)
     aStatus = (*mEventCallback)(event);
 
+  mIsDispatchPaint = restoreIsDispatchPaint;
+
   return NS_OK;
 }
 
 PRBool nsChildView::DispatchWindowEvent(nsGUIEvent &event)
 {
   nsEventStatus status;
   DispatchEvent(&event, status);
   return ConvertStatus(status);