Bug 563377 - Flash fullscreen window refuses to close. r=bent.
authorJim Mathies <jmathies@mozilla.com>
Tue, 18 May 2010 11:43:45 -0500
changeset 42416 6861c31f2ec6
parent 42415 49ca6b8821f2
child 42417 652733ce0792
push id13329
push userjmathies@mozilla.com
push dateTue, 18 May 2010 16:44:30 +0000
treeherdermozilla-central@6861c31f2ec6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbent
bugs563377
milestone1.9.3a5pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
Bug 563377 - Flash fullscreen window refuses to close. r=bent.
dom/plugins/PluginInstanceParent.cpp
dom/plugins/PluginModuleChild.cpp
--- a/dom/plugins/PluginInstanceParent.cpp
+++ b/dom/plugins/PluginInstanceParent.cpp
@@ -49,16 +49,17 @@
 
 #if defined(OS_WIN)
 #include <windowsx.h>
 
 // Plugin focus event for widget.
 extern const PRUnichar* kOOPPPluginFocusEventId;
 UINT gOOPPPluginFocusEvent =
     RegisterWindowMessage(kOOPPPluginFocusEventId);
+extern const PRUnichar* kFlashFullscreenClass;
 UINT gOOPPSpinNativeLoopEvent =
     RegisterWindowMessage(L"SyncChannel Spin Inner Loop Message");
 UINT gOOPPStopNativeLoopEvent =
     RegisterWindowMessage(L"SyncChannel Stop Inner Loop Message");
 #elif defined(MOZ_WIDGET_GTK2)
 #include <gdk/gdk.h>
 #elif defined(XP_MACOSX)
 #include <ApplicationServices/ApplicationServices.h>
@@ -655,17 +656,17 @@ PluginInstanceParent::NPP_HandleEvent(vo
               // which fires WM_KILLFOCUS. Delayed delivery causes Flash to
               // misinterpret the event, dropping back out of fullscreen. Trap
               // this event and drop it.
               PRUnichar szClass[26];
               HWND hwnd = GetForegroundWindow();
               if (hwnd && hwnd != mPluginHWND &&
                   GetClassNameW(hwnd, szClass,
                                 sizeof(szClass)/sizeof(PRUnichar)) &&
-                  !wcscmp(szClass, L"ShockwaveFlashFullScreen")) {
+                  !wcscmp(szClass, kFlashFullscreenClass)) {
                   return 0;
               }
             }
             break;
 
             case WM_WINDOWPOSCHANGED:
             {
                 // We send this in nsObjectFrame just before painting
--- a/dom/plugins/PluginModuleChild.cpp
+++ b/dom/plugins/PluginModuleChild.cpp
@@ -64,22 +64,27 @@
 #include "nsNPAPIPlugin.h"
 
 using namespace mozilla::plugins;
 
 #if defined(XP_WIN)
 #ifndef WM_MOUSEHWHEEL
 #define WM_MOUSEHWHEEL     0x020E
 #endif
+const PRUnichar * kFlashFullscreenClass = L"ShockwaveFlashFullScreen";
 #endif
 
 namespace {
 PluginModuleChild* gInstance = nsnull;
 }
 
+#ifdef XP_WIN
+// Used with fix for flash fullscreen window loosing focus.
+static bool gDelayFlashFocusReplyUntilEval = false;
+#endif
 
 PluginModuleChild::PluginModuleChild() :
     mLibrary(0),
     mShutdownFunc(0),
     mInitializeFunc(0)
 #if defined(OS_WIN) || defined(OS_MACOSX)
   , mGetEntryPointsFunc(0)
 #elif defined(MOZ_WIDGET_GTK2)
@@ -1162,16 +1167,23 @@ bool NP_CALLBACK
 
     PluginScriptableObjectChild* actor =
       InstCast(aNPP)->GetActorForNPObject(aObject);
     if (!actor) {
         NS_ERROR("Failed to create actor?!");
         return false;
     }
 
+#ifdef XP_WIN
+    if (gDelayFlashFocusReplyUntilEval) {
+        ReplyMessage(0);
+        gDelayFlashFocusReplyUntilEval = false;
+    }
+#endif
+
     return actor->Evaluate(aScript, aResult);
 }
 
 bool NP_CALLBACK
 _getproperty(NPP aNPP,
              NPObject* aNPObj,
              NPIdentifier aPropertyName,
              NPVariant* aResult)
@@ -1879,34 +1891,52 @@ PluginModuleChild::ExitedCall()
         MessageLoop::current()->SetNestableTasksAllowed(f._savedNestableTasksAllowed);
 
     mIncallPumpingStack.TruncateLength(len - 1);
 }
 
 LRESULT CALLBACK
 PluginModuleChild::CallWindowProcHook(int nCode, WPARAM wParam, LPARAM lParam)
 {
+    gDelayFlashFocusReplyUntilEval = false;
+
     // Trap and reply to anything we recognize as the source of a
     // potential send message deadlock.
     if (nCode >= 0 &&
         (InSendMessageEx(NULL)&(ISMEX_REPLIED|ISMEX_SEND)) == ISMEX_SEND) {
         CWPSTRUCT* pCwp = reinterpret_cast<CWPSTRUCT*>(lParam);
         switch(pCwp->message) {
             // Sync messages we can reply to:
             case WM_SETFOCUS:
-            case WM_KILLFOCUS:
             case WM_MOUSEHWHEEL:
             case WM_MOUSEWHEEL:
             case WM_HSCROLL:
             case WM_VSCROLL:
             case WM_CONTEXTMENU:
             case WM_IME_SETCONTEXT:
             case WM_WINDOWPOSCHANGED:
                 ReplyMessage(0);
             break;
+            case WM_KILLFOCUS:
+            {
+                // Fix for flash fullscreen window loosing focus. On single
+                // core systems, sync killfocus events need to be handled
+                // after the flash fullscreen window procedure processes this
+                // message, otherwise fullscreen focus will not work correctly.
+                PRUnichar szClass[26];
+                if (GetClassNameW(pCwp->hwnd, szClass,
+                                  sizeof(szClass)/sizeof(PRUnichar)) &&
+                    !wcscmp(szClass, kFlashFullscreenClass)) {
+                    gDelayFlashFocusReplyUntilEval = true;
+                }
+                else {
+                    ReplyMessage(0);
+                }
+            }
+            break;
             // Sync message that can't be handled:
             case WM_WINDOWPOSCHANGING:
             case WM_DESTROY:
             case WM_PAINT:
             break;
             // Everything else:
             default: {
 #ifdef DEBUG