diff --git a/dom/plugins/PluginInstanceChild.cpp b/dom/plugins/PluginInstanceChild.cpp index b6e15eb9ebe3..5db10429ec33 100644 --- a/dom/plugins/PluginInstanceChild.cpp +++ b/dom/plugins/PluginInstanceChild.cpp @@ -124,6 +124,7 @@ PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface) , mWinlessPopupSurrogateHWND(0) , mWinlessThrottleOldWndProc(0) , mWinlessHiddenMsgHWND(0) + , mMouseHook(NULL) #endif // OS_WIN , mAsyncCallMutex("PluginInstanceChild::mAsyncCallMutex") #if defined(OS_MACOSX) @@ -1042,6 +1043,42 @@ PluginInstanceChild::RegisterWindowClass() return RegisterClassEx(&wcex) ? true : false; } +static inline void +HandleMouseCapture(HWND aWnd, UINT aMessage) +{ + // Make sure capture is released by the child on mouse events. Fixes a + // problem with flash full screen mode mouse input. Appears to be + // caused by a bug in flash, since we are not setting the capture + // on the window. (In non-oopp land, we would set and release via + // widget for other reasons.) + switch (aMessage) { + case WM_LBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_RBUTTONDOWN: + SetCapture(aWnd); + break; + case WM_LBUTTONUP: + case WM_MBUTTONUP: + case WM_RBUTTONUP: + ReleaseCapture(); + break; + } +} + +LRESULT CALLBACK MouseHookProc(int code, + WPARAM wParam, + LPARAM lParam) +{ + if (code == HC_ACTION) { + MOUSEHOOKSTRUCT* hookStruct = + reinterpret_cast(lParam); + if (hookStruct) + HandleMouseCapture(hookStruct->hwnd, wParam); + } + + return CallNextHookEx(NULL, code, wParam, lParam); +} + bool PluginInstanceChild::CreatePluginWindow() { @@ -1068,6 +1105,11 @@ PluginInstanceChild::CreatePluginWindow() SetWindowLongPtrA(mPluginWindowHWND, GWLP_WNDPROC, reinterpret_cast(DefWindowProcA)); + // Mouse capture hook for flash full screen capture bug + if (GetQuirks() & PluginModuleChild::QUIRK_FLASH_HOOK_MOUSE_CAPTURE) { + mMouseHook = SetWindowsHookEx(WH_MOUSE, MouseHookProc, NULL, + GetCurrentThreadId()); + } return true; } @@ -1089,6 +1131,11 @@ PluginInstanceChild::DestroyPluginWindow() DestroyWindow(mPluginWindowHWND); mPluginWindowHWND = 0; } + + if (mMouseHook) { + UnhookWindowsHookEx(mMouseHook); + mMouseHook = NULL; + } } void @@ -1200,25 +1247,11 @@ PluginInstanceChild::PluginWindowProc(HWND hWnd, return 0; } + HandleMouseCapture(hWnd, message); + LRESULT res = CallWindowProc(self->mPluginWndProc, hWnd, message, wParam, lParam); - // Make sure capture is released by the child on mouse events. Fixes a - // problem with flash full screen mode mouse input. Appears to be - // caused by a bug in flash, since we are not setting the capture - // on the window. (In non-oopp land, we would set and release via - // widget for other reasons.) - switch (message) { - case WM_LBUTTONDOWN: - case WM_MBUTTONDOWN: - case WM_RBUTTONDOWN: - case WM_LBUTTONUP: - case WM_MBUTTONUP: - case WM_RBUTTONUP: - ReleaseCapture(); - break; - } - if (message == WM_CLOSE) self->DestroyPluginWindow(); diff --git a/dom/plugins/PluginInstanceChild.h b/dom/plugins/PluginInstanceChild.h index a4dbbd730947..a7e70e81cda0 100644 --- a/dom/plugins/PluginInstanceChild.h +++ b/dom/plugins/PluginInstanceChild.h @@ -346,6 +346,7 @@ private: nsIntPoint mPluginSize; WNDPROC mWinlessThrottleOldWndProc; HWND mWinlessHiddenMsgHWND; + HHOOK mMouseHook; #endif friend class ChildAsyncCall; diff --git a/dom/plugins/PluginModuleChild.cpp b/dom/plugins/PluginModuleChild.cpp index da9c21cb3624..ad0b2c313f6f 100644 --- a/dom/plugins/PluginModuleChild.cpp +++ b/dom/plugins/PluginModuleChild.cpp @@ -1829,6 +1829,7 @@ PluginModuleChild::InitQuirksModes(const nsCString& aMimeType) mQuirks |= QUIRK_FLASH_HOOK_SETLONGPTR; mQuirks |= QUIRK_FLASH_HOOK_GETWINDOWINFO; mQuirks |= QUIRK_FLASH_MASK_CLEARTYPE_SETTINGS; + mQuirks |= QUIRK_FLASH_HOOK_MOUSE_CAPTURE; } #endif } diff --git a/dom/plugins/PluginModuleChild.h b/dom/plugins/PluginModuleChild.h index d9c5c20782bb..72daca43411d 100644 --- a/dom/plugins/PluginModuleChild.h +++ b/dom/plugins/PluginModuleChild.h @@ -238,6 +238,9 @@ public: // Win: Flash trashes the alpha channel in our buffers when cleartype // is enabled. Mask this setting so they don't know it's enabled. QUIRK_FLASH_MASK_CLEARTYPE_SETTINGS = 1 << 6, + // Win: Addresses a flash bug with mouse capture and full screen + // windows. + QUIRK_FLASH_HOOK_MOUSE_CAPTURE = 1 << 7, }; int GetQuirks() { return mQuirks; }