Bug 952324 - Don't block native events for more than 50ms [r=jimm a=lsblakk]
authorMatt Brubeck <mbrubeck@mozilla.com>
Fri, 20 Dec 2013 07:51:13 -0800
changeset 175450 ea0884724339210927a68f860fb510b5e70cee27
parent 175449 440cc338dc726edfe4ff798e64e5725f281b23cd
child 175451 8c00175975d82d27948484b46a532c12854399fa
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimm, lsblakk
bugs952324
milestone28.0a2
Bug 952324 - Don't block native events for more than 50ms [r=jimm a=lsblakk]
widget/windows/winrt/MetroAppShell.cpp
--- a/widget/windows/winrt/MetroAppShell.cpp
+++ b/widget/windows/winrt/MetroAppShell.cpp
@@ -7,16 +7,17 @@
 #include "nsXULAppAPI.h"
 #include "mozilla/widget/AudioSession.h"
 #include "MetroUtils.h"
 #include "MetroApp.h"
 #include "FrameworkView.h"
 #include "nsIObserverService.h"
 #include "nsServiceManagerUtils.h"
 #include "mozilla/AutoRestore.h"
+#include "mozilla/TimeStamp.h"
 #include "WinUtils.h"
 #include "nsIAppStartup.h"
 #include "nsToolkitCompsCID.h"
 #include <shellapi.h>
 
 using namespace mozilla;
 using namespace mozilla::widget;
 using namespace mozilla::widget::winrt;
@@ -44,16 +45,17 @@ namespace widget {
 // pulled from win32 app shell
 extern UINT sAppShellGeckoMsgId;
 } }
 
 static ComPtr<ICoreWindowStatic> sCoreStatic;
 static bool sIsDispatching = false;
 static bool sShouldPurgeThreadQueue = false;
 static bool sBlockNativeEvents = false;
+static TimeStamp sPurgeThreadQueueStart;
 
 MetroAppShell::~MetroAppShell()
 {
   if (mEventWnd) {
     SendMessage(mEventWnd, WM_CLOSE, 0, 0);
   }
 }
 
@@ -278,16 +280,17 @@ MetroAppShell::DispatchAllGeckoEvents()
   // Only do this if requested
   if (!sShouldPurgeThreadQueue) {
     return;
   }
 
   NS_ASSERTION(NS_IsMainThread(), "DispatchAllGeckoEvents should be called on the main thread");
 
   sShouldPurgeThreadQueue = false;
+  sPurgeThreadQueueStart = TimeStamp::Now();
 
   sBlockNativeEvents = true;
   nsIThread *thread = NS_GetCurrentThread();
   NS_ProcessPendingEvents(thread, PURGE_MAX_TIMEOUT);
   sBlockNativeEvents = false;
 }
 
 static void
@@ -330,23 +333,27 @@ MetroAppShell::ProcessOneNativeEventIfPr
   DispatchAllGeckoEvents();
 
   return !!HIWORD(::GetQueueStatus(MOZ_QS_ALLEVENT));
 }
 
 bool
 MetroAppShell::ProcessNextNativeEvent(bool mayWait)
 {
-  // NS_ProcessPendingEvents will process thread events *and* call
-  // nsBaseAppShell::OnProcessNextEvent to process native events. However
-  // we do not want native events getting dispatched while we are trying
+  // NS_ProcessPendingEvents will process thread events *and* call
+  // nsBaseAppShell::OnProcessNextEvent to process native events. However
+  // we do not want native events getting dispatched while we are trying
   // to dispatch pending input in DispatchAllGeckoEvents since a native
   // event may be a UIA Automation call coming in to check focus.
   if (sBlockNativeEvents) {
-    return false;
+    if ((TimeStamp::Now() - sPurgeThreadQueueStart).ToMilliseconds()
+        < PURGE_MAX_TIMEOUT) {
+      return false;
+    }
+    sBlockNativeEvents = false;
   }
 
   if (ProcessOneNativeEventIfPresent()) {
     return true;
   }
   if (mayWait) {
     DWORD result = ::MsgWaitForMultipleObjectsEx(0, nullptr, MSG_WAIT_TIMEOUT,
                                                  MOZ_QS_ALLEVENT,