Bug 1009243 - Part 2: Make <input type="color"> fire "input" events on Windows. r=jimm
authorBirunthan Mohanathas <birunthan@mohanathas.com>
Mon, 25 Aug 2014 12:17:45 -0700
changeset 223100 47ecfa3c421f626d2cb8cb8e2b41a34c15f7cb0c
parent 223099 4725899adffa702ca40dc10ae4e78e535b1f0ad3
child 223101 34724a298c39ff366e08bd11d4e0047cbb4f892d
push id3979
push userraliiev@mozilla.com
push dateMon, 13 Oct 2014 16:35:44 +0000
treeherdermozilla-beta@30f2cc610691 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimm
bugs1009243
milestone34.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 1009243 - Part 2: Make <input type="color"> fire "input" events on Windows. r=jimm
widget/windows/nsColorPicker.cpp
widget/windows/nsColorPicker.h
--- a/widget/windows/nsColorPicker.cpp
+++ b/widget/windows/nsColorPicker.cpp
@@ -86,67 +86,101 @@ BGRIntToRGBString(DWORD color, nsAString
 
   aResult.Assign('#');
   aResult.Append(ToHexString(r));
   aResult.Append(ToHexString(g));
   aResult.Append(ToHexString(b));
 }
 } // anonymous namespace
 
+static AsyncColorChooser* gColorChooser;
+
 AsyncColorChooser::AsyncColorChooser(COLORREF aInitialColor,
                                      nsIWidget* aParentWidget,
                                      nsIColorPickerShownCallback* aCallback)
   : mInitialColor(aInitialColor)
+  , mColor(aInitialColor)
   , mParentWidget(aParentWidget)
   , mCallback(aCallback)
 {
 }
 
 NS_IMETHODIMP
 AsyncColorChooser::Run()
 {
   static COLORREF sCustomColors[16] = {0} ;
 
   MOZ_ASSERT(NS_IsMainThread(),
       "Color pickers can only be opened from main thread currently");
 
-  static bool sColorPickerOpen = false;
   // Allow only one color picker to be opened at a time, to workaround bug 944737
-  if (!sColorPickerOpen) {
-    mozilla::AutoRestore<bool> autoRestoreColorPickerOpen(sColorPickerOpen);
-    sColorPickerOpen = true;
+  if (!gColorChooser) {
+    mozilla::AutoRestore<AsyncColorChooser*> restoreColorChooser(gColorChooser);
+    gColorChooser = this;
 
     AutoDestroyTmpWindow adtw((HWND) (mParentWidget.get() ?
       mParentWidget->GetNativeData(NS_NATIVE_TMP_WINDOW) : nullptr));
 
     CHOOSECOLOR options;
     options.lStructSize   = sizeof(options);
     options.hwndOwner     = adtw.get();
-    options.Flags         = CC_RGBINIT | CC_FULLOPEN;
+    options.Flags         = CC_RGBINIT | CC_FULLOPEN | CC_ENABLEHOOK;
     options.rgbResult     = mInitialColor;
     options.lpCustColors  = sCustomColors;
+    options.lpfnHook      = HookProc;
 
-    if (ChooseColor(&options)) {
-      mColor = options.rgbResult;
-    }
+    mColor = ChooseColor(&options) ? options.rgbResult : mInitialColor;
   } else {
     NS_WARNING("Currently, it's not possible to open more than one color "
                "picker at a time");
     mColor = mInitialColor;
   }
 
   if (mCallback) {
     nsAutoString colorStr;
     BGRIntToRGBString(mColor, colorStr);
     mCallback->Done(colorStr);
   }
 
   return NS_OK;
 }
 
+void
+AsyncColorChooser::Update(COLORREF aColor)
+{
+  if (mColor != aColor) {
+    mColor = aColor;
+
+    nsAutoString colorStr;
+    BGRIntToRGBString(mColor, colorStr);
+    mCallback->Update(colorStr);
+  }
+}
+
+/* static */ UINT_PTR CALLBACK
+AsyncColorChooser::HookProc(HWND aDialog, UINT aMsg,
+                            WPARAM aWParam, LPARAM aLParam)
+{
+  if (!gColorChooser) {
+    return 0;
+  }
+
+  if (aMsg == WM_CTLCOLORSTATIC) {
+    // The color picker does not expose a proper way to retrieve the current
+    // color, so we need to obtain it from the static control displaying the
+    // current color instead.
+    const int kCurrentColorBoxID = 709;
+    if ((HWND)aLParam == GetDlgItem(aDialog, kCurrentColorBoxID)) {
+      gColorChooser->Update(GetPixel((HDC)aWParam, 0, 0));
+    }
+  }
+
+  return 0;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 // nsIColorPicker
 
 nsColorPicker::nsColorPicker()
 {
 }
 
 nsColorPicker::~nsColorPicker()
--- a/widget/windows/nsColorPicker.h
+++ b/widget/windows/nsColorPicker.h
@@ -21,16 +21,21 @@ class AsyncColorChooser :
 {
 public:
   AsyncColorChooser(COLORREF aInitialColor,
                     nsIWidget* aParentWidget,
                     nsIColorPickerShownCallback* aCallback);
   NS_IMETHOD Run() MOZ_OVERRIDE;
 
 private:
+  void Update(COLORREF aColor);
+
+  static UINT_PTR CALLBACK HookProc(HWND aDialog, UINT aMsg,
+                                    WPARAM aWParam, LPARAM aLParam);
+
   COLORREF mInitialColor;
   COLORREF mColor;
   nsCOMPtr<nsIWidget> mParentWidget;
   nsCOMPtr<nsIColorPickerShownCallback> mCallback;
 };
 
 class nsColorPicker :
   public nsIColorPicker