Bug 625454 - Ignore native events on Mac when the run loop is in event tracking mode. r=smichaud a=LegNeato
--- a/widget/src/cocoa/nsAppShell.mm
+++ b/widget/src/cocoa/nsAppShell.mm
@@ -389,19 +389,25 @@ nsAppShell::ProcessGeckoEvents(void* aIn
windowNumber:0
context:NULL
subtype:0
data1:0
data2:0]
atStart:NO];
}
+ // During "event tracking" mode, we're in a nested event loop (and we're
+ // usually in a performance-critical section such as a window resize), so we
+ // block native events.
+ NSString *runLoopMode = [[NSRunLoop currentRunLoop] currentMode];
+ PRBool blockNativeEvents = runLoopMode == NSEventTrackingRunLoopMode;
+
if (self->mSuspendNativeCount <= 0) {
++self->mNativeEventCallbackDepth;
- self->NativeEventCallback();
+ self->NativeEventCallback(blockNativeEvents);
--self->mNativeEventCallbackDepth;
} else {
self->mSkippedNativeCallback = PR_TRUE;
}
// Still needed to fix bug 343033 ("5-10 second delay or hang or crash
// when quitting Cocoa Firefox").
[NSApp postEvent:[NSEvent otherEventWithType:NSApplicationDefined
--- a/widget/src/xpwidgets/nsBaseAppShell.cpp
+++ b/widget/src/xpwidgets/nsBaseAppShell.cpp
@@ -88,19 +88,20 @@ nsBaseAppShell::Init()
nsCOMPtr<nsIObserverService> obsSvc =
mozilla::services::GetObserverService();
if (obsSvc)
obsSvc->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_FALSE);
return NS_OK;
}
-// Called by nsAppShell's native event callback
+// Called by nsAppShell's native event callback. Set aAlwaysBlockNative to true
+// to always block native events.
void
-nsBaseAppShell::NativeEventCallback()
+nsBaseAppShell::NativeEventCallback(PRBool aAlwaysBlockNative)
{
PRInt32 hasPending = PR_AtomicSet(&mNativeEventPending, 0);
if (hasPending == 0)
return;
// If DoProcessNextNativeEvent is on the stack, then we assume that we can
// just unwind and let nsThread::ProcessNextEvent process the next event.
// However, if we are called from a nested native event loop (maybe via some
@@ -112,17 +113,19 @@ nsBaseAppShell::NativeEventCallback()
return;
}
// nsBaseAppShell::Run is not being used to pump events, so this may be
// our only opportunity to process pending gecko events.
nsIThread *thread = NS_GetCurrentThread();
PRBool prevBlockNativeEvent = mBlockNativeEvent;
- if (mEventloopNestingState == eEventloopOther) {
+ if (aAlwaysBlockNative) {
+ mBlockNativeEvent = PR_TRUE;
+ } else if (mEventloopNestingState == eEventloopOther) {
if (!NS_HasPendingEvents(thread))
return;
// We're in a nested native event loop and have some gecko events to
// process. While doing that we block processing native events from the
// appshell - instead, we want to get back to the nested native event
// loop ASAP (bug 420148).
mBlockNativeEvent = PR_TRUE;
}
--- a/widget/src/xpwidgets/nsBaseAppShell.h
+++ b/widget/src/xpwidgets/nsBaseAppShell.h
@@ -68,17 +68,17 @@ protected:
* This method is called by subclasses when the app shell singleton is
* instantiated.
*/
nsresult Init();
/**
* Called by subclasses from a native event. See ScheduleNativeEventCallback.
*/
- void NativeEventCallback();
+ void NativeEventCallback(PRBool aAlwaysBlockNative = PR_FALSE);
/**
* Make a decision as to whether or not NativeEventCallback will
* trigger gecko event processing when there are pending gecko
* events.
*/
virtual void DoProcessMoreGeckoEvents();