Bug 1273091 - Mouse cursor does not disappear in html5 fullscreen video on Windows. r=masayuki
authorDavid Parks <dparks@mozilla.com>
Mon, 28 Nov 2016 10:46:15 -0800
changeset 324512 efad76d74c06a7c0c29b43dc3d87ac5e9b8443a2
parent 324511 8300b41fe20b187bdf37f6b351c3342474a4a2db
child 324513 011a51e21bbbb73b83918c798756376cd62601e7
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewersmasayuki
bugs1273091
milestone53.0a1
Bug 1273091 - Mouse cursor does not disappear in html5 fullscreen video on Windows. r=masayuki When we jump to fullscreen, the OS sends a WM_MOUSELEAVE, which we turn into a eMouseExitFromWidget. The eMouseEnterIntoWidget was previously only sent when the mouse moved into the widget, which required the mouse to move. When entering fullscreen, we want the eMouseEnterIntoWidget to happen right away.
widget/windows/nsWindow.cpp
widget/windows/nsWindow.h
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -265,16 +265,19 @@ LONG            nsWindow::sLastMouseDown
 LONG            nsWindow::sLastClickCount         = 0L;
 BYTE            nsWindow::sLastMouseButton        = 0;
 
 // Trim heap on minimize. (initialized, but still true.)
 int             nsWindow::sTrimOnMinimize         = 2;
 
 TriStateBool nsWindow::sHasBogusPopupsDropShadowOnMultiMonitor = TRI_UNKNOWN;
 
+WPARAM nsWindow::sMouseExitwParam = 0;
+LPARAM nsWindow::sMouseExitlParamScreen = 0;
+
 static SystemTimeConverter<DWORD>&
 TimeConverter() {
   static SystemTimeConverter<DWORD> timeConverterSingleton;
   return timeConverterSingleton;
 }
 
 namespace mozilla {
 
@@ -3268,16 +3271,27 @@ nsWindow::MakeFullScreen(bool aFullScree
     taskbarInfo->PrepareFullScreenHWND(mWnd, FALSE);
   }
 
   if (mWidgetListener) {
     mWidgetListener->SizeModeChanged(mSizeMode);
     mWidgetListener->FullscreenChanged(aFullScreen);
   }
 
+  // Send a eMouseEnterIntoWidget event since Windows has already sent
+  // a WM_MOUSELEAVE that caused us to send a eMouseExitFromWidget event.
+  if (aFullScreen && !sCurrentWindow) {
+    sCurrentWindow = this;
+    LPARAM pos = sCurrentWindow->lParamToClient(sMouseExitlParamScreen);
+    sCurrentWindow->DispatchMouseEvent(eMouseEnterIntoWidget,
+                                       sMouseExitwParam, pos, false,
+                                       WidgetMouseEvent::eLeftButton,
+                                       MOUSE_INPUT_SOURCE(), MOUSE_POINTERID());
+  }
+
   return NS_OK;
 }
 
 /**************************************************************
  *
  * SECTION: Native data storage
  *
  * nsIWidget::GetNativeData
@@ -4246,16 +4260,18 @@ nsWindow::DispatchMouseEvent(EventMessag
             sCurrentWindow->DispatchMouseEvent(eMouseEnterIntoWidget,
                                                wParam, pos, false,
                                                WidgetMouseEvent::eLeftButton,
                                                aInputSource, aPointerId);
           }
         }
       }
     } else if (aEventMessage == eMouseExitFromWidget) {
+      sMouseExitwParam = wParam;
+      sMouseExitlParamScreen = lParamToScreen(lParam);
       if (sCurrentWindow == this) {
         sCurrentWindow = nullptr;
       }
     }
 
     result = ConvertStatus(DispatchInputEvent(&event));
 
     // Release the widget with NS_IF_RELEASE() just in case
--- a/widget/windows/nsWindow.h
+++ b/widget/windows/nsWindow.h
@@ -641,16 +641,23 @@ protected:
   int32_t mCachedHitTestResult;
 
   RefPtr<mozilla::widget::WinCompositorWidget> mBasicLayersSurface;
 
   static bool sNeedsToInitMouseWheelSettings;
   static void InitMouseWheelScrollData();
 
   double mSizeConstraintsScale; // scale in effect when setting constraints
+
+  // Used to remember the wParam (i.e. currently pressed modifier keys)
+  // and lParam (i.e. last mouse position) in screen coordinates from
+  // the previous mouse-exit.  Static since it is not
+  // associated with a particular widget (since we exited the widget).
+  static WPARAM sMouseExitwParam;
+  static LPARAM sMouseExitlParamScreen;
 };
 
 /**
  * A child window is a window with different style.
  */
 class ChildWindow : public nsWindow {
 
 public: