Bug 725475 - Use more hidden scrollbars to tempt Synaptics drivers into giving us scrolling messages. r=jmathies
authorCameron McCormack <cam@mcc.id.au>
Thu, 08 Mar 2012 13:16:47 +1100
changeset 88480 d0dba3f1cc92eed4cf2a89fddbb92b8dbd21076a
parent 88479 45d1588c2c715874bbfdfdf5ac7725db349b8a33
child 88481 52ffdbb7c6990cf7b8eec8f78166a70fc9af67c6
push id6861
push usercmccormack@mozilla.com
push dateThu, 08 Mar 2012 02:32:03 +0000
treeherdermozilla-inbound@d0dba3f1cc92 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjmathies
bugs725475
milestone13.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 725475 - Use more hidden scrollbars to tempt Synaptics drivers into giving us scrolling messages. r=jmathies
ipc/glue/WindowsMessageLoop.cpp
widget/windows/nsWindow.cpp
--- a/ipc/glue/WindowsMessageLoop.cpp
+++ b/ipc/glue/WindowsMessageLoop.cpp
@@ -201,27 +201,30 @@ ProcessOrDeferMessage(HWND hwnd,
     // Messages that can be deferred as-is. These must not contain pointers in
     // their wParam or lParam arguments!
     case WM_ACTIVATE:
     case WM_ACTIVATEAPP:
     case WM_CANCELMODE:
     case WM_CAPTURECHANGED:
     case WM_CHILDACTIVATE:
     case WM_DESTROY:
+    case WM_DISPLAYCHANGE:
     case WM_ENABLE:
     case WM_IME_NOTIFY:
     case WM_IME_SETCONTEXT:
+    case WM_KEYDOWN:
+    case WM_KEYUP:
     case WM_KILLFOCUS:
     case WM_MOUSEWHEEL:
     case WM_NCDESTROY:
     case WM_PARENTNOTIFY:
     case WM_SETFOCUS:
     case WM_SYSCOMMAND:
-    case WM_DISPLAYCHANGE:
-    case WM_SHOWWINDOW: // Intentional fall-through.
+    case WM_SHOWWINDOW:
+    case WM_VSCROLL: // Intentional fall-through.
     case WM_XP_THEMECHANGED: {
       deferred = new DeferredSendMessage(hwnd, uMsg, wParam, lParam);
       break;
     }
 
     case WM_DEVICECHANGE:
     case WM_POWERBROADCAST:
     case WM_NCACTIVATE: // Intentional fall-through.
@@ -319,17 +322,21 @@ ProcessOrDeferMessage(HWND hwnd,
 
         wchar_t className[256] = { 0 };
         if (GetClassNameW(hwnd, className, sizeof(className) - 1) > 0) {
           log.AppendLiteral(" (\"");
           log.Append(NS_ConvertUTF16toUTF8((PRUnichar*)className));
           log.AppendLiteral("\")");
         }
 
-        log.AppendLiteral(", sending it to DefWindowProc instead of the normal "
+        log.AppendLiteral(", wParam = ");
+        log.AppendInt(wParam);
+        log.AppendLiteral(", lParam = ");
+        log.AppendInt(lParam);
+        log.AppendLiteral("; sending it to DefWindowProc instead of the normal "
                           "window procedure.");
         NS_ERROR(log.get());
 #endif
         return DefWindowProc(hwnd, uMsg, wParam, lParam);
       }
     }
   }
 
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -576,47 +576,63 @@ nsWindow::Create(nsIWidget *aParent,
     return NS_ERROR_FAILURE;
   }
 
   if (mIsRTL && nsUXThemeData::dwmSetWindowAttributePtr) {
     DWORD dwAttribute = TRUE;    
     nsUXThemeData::dwmSetWindowAttributePtr(mWnd, DWMWA_NONCLIENT_RTL_LAYOUT, &dwAttribute, sizeof dwAttribute);
   }
 
-  if (mWindowType != eWindowType_plugin &&
-      mWindowType != eWindowType_invisible &&
+  if ((mWindowType == eWindowType_toplevel ||
+       mWindowType == eWindowType_dialog ||
+       mWindowType == eWindowType_popup) &&
       MouseScrollHandler::Device::IsFakeScrollableWindowNeeded()) {
-    // Ugly Thinkpad Driver Hack (Bugs 507222 and 594977)
+    // Ugly Thinkpad Driver Hack (Bugs 507222, 594977 and 725475)
     //
-    // We create two zero-sized windows as descendants of the top-level window,
-    // like so:
+    // We create three zero-sized windows as descendants of the top-level
+    // window, like so:
     //
     //   Top-level window (MozillaWindowClass)
     //     FAKETRACKPOINTSCROLLCONTAINER (MozillaWindowClass)
     //       FAKETRACKPOINTSCROLLABLE (MozillaWindowClass)
+    //     FAKETRACKPOINTSCROLLBAR (ScrollBar)
     //
-    // We need to have the middle window, otherwise the Trackpoint driver
+    // We need to have the container window, otherwise the Trackpoint driver
     // will fail to deliver scroll messages.  WM_MOUSEWHEEL messages are
     // sent to the FAKETRACKPOINTSCROLLABLE, which then propagate up the
     // window hierarchy until they are handled by nsWindow::WindowProc.
     // WM_HSCROLL messages are also sent to the FAKETRACKPOINTSCROLLABLE,
     // but these do not propagate automatically, so we have the window
     // procedure pretend that they were dispatched to the top-level window
     // instead.
     //
     // The FAKETRACKPOINTSCROLLABLE needs to have the specific window styles it
     // is given below so that it catches the Trackpoint driver's heuristics.
+    //
+    // The FAKETRACKPOINTSCROLLBAR is needed for certain configurations of
+    // Synaptics drivers when a plugin window is visible and would otherwise
+    // attract all scrolling messages.  A corresponding horizontal scrollbar
+    // does not seem to be needed to attract WM_HSCROLL messages.
     HWND scrollContainerWnd = ::CreateWindowW
       (className.get(), L"FAKETRACKPOINTSCROLLCONTAINER",
        WS_CHILD | WS_VISIBLE,
        0, 0, 0, 0, mWnd, NULL, nsToolkit::mDllInstance, NULL);
     HWND scrollableWnd = ::CreateWindowW
       (className.get(), L"FAKETRACKPOINTSCROLLABLE",
        WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP | 0x30,
        0, 0, 0, 0, scrollContainerWnd, NULL, nsToolkit::mDllInstance, NULL);
+    HWND scrollBarWnd = ::CreateWindowW
+      (L"SCROLLBAR", L"FAKETRACKPOINTSCROLLBAR",
+       WS_CHILD | WS_VISIBLE | SBS_VERT,
+       0, 0, 0, 0, mWnd, NULL, nsToolkit::mDllInstance, NULL);
+
+    // We set the hidden scroll bar control to have a range of values and
+    // be positioned in the middle, so that scrolling up and down works.
+    SCROLLINFO scrollInfo = { sizeof SCROLLINFO, SIF_ALL, 0, 100, 1, 50, 50 };
+    ::SetScrollInfo(scrollBarWnd, SB_CTL, &scrollInfo, FALSE);
 
     // Give the FAKETRACKPOINTSCROLLABLE window a specific ID so that
     // WindowProcInternal can distinguish it from the top-level window
     // easily.
     ::SetWindowLongPtrW(scrollableWnd, GWLP_ID, eFakeTrackPointScrollableID);
 
     // Make FAKETRACKPOINTSCROLLABLE use nsWindow::WindowProc, and store the
     // old window procedure in its "user data".
@@ -6848,21 +6864,19 @@ nsWindow::SetWindowClipRegion(const nsTA
   }
 
   // If a plugin is not visible, especially if it is in a background tab,
   // it should not be able to steal keyboard focus.  This code checks whether
   // the region that the plugin is being clipped to is NULLREGION.  If it is,
   // the plugin window gets disabled.
   if(mWindowType == eWindowType_plugin) {
     if(NULLREGION == ::CombineRgn(dest, dest, dest, RGN_OR)) {
-      ::ShowWindow(mWnd, SW_HIDE);
       ::EnableWindow(mWnd, FALSE);
     } else {
       ::EnableWindow(mWnd, TRUE);
-      ::ShowWindow(mWnd, SW_SHOW);
     }
   }
   if (!::SetWindowRgn(mWnd, dest, TRUE)) {
     ::DeleteObject(dest);
     return NS_ERROR_FAILURE;
   }
   return NS_OK;
 }