Bug 1130935 part.1 Add a method to check if current IME supports vertical writing mode r=emk
authorMasayuki Nakano <masayuki@d-toybox.com>
Fri, 15 May 2015 10:18:07 +0900
changeset 243951 9744edd77df434dedad42712181ba52aeeeb3b59
parent 243950 ae57a9f6ac60d310fab99b3338c7f75441b543a3
child 243952 eb660def02c0f6a1568e98ea6f5b48f46a2a0929
push id59807
push usermasayuki@d-toybox.com
push dateFri, 15 May 2015 01:18:23 +0000
treeherdermozilla-inbound@c6c67158efef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemk
bugs1130935
milestone41.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 1130935 part.1 Add a method to check if current IME supports vertical writing mode r=emk
modules/libpref/init/all.js
widget/windows/nsIMM32Handler.cpp
widget/windows/nsIMM32Handler.h
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -3064,16 +3064,21 @@ pref("intl.tsf.hack.easy_changjei.do_not
 // of selected clause of composition string.
 pref("intl.tsf.hack.google_ja_input.do_not_return_no_layout_error_at_first_char", true);
 // Whether use previous character rect for the result of
 // ITfContextView::GetTextExt() if the specified range is the caret of
 // composition string.
 pref("intl.tsf.hack.google_ja_input.do_not_return_no_layout_error_at_caret", true);
 #endif
 
+// Even if IME claims that they support vertical writing mode but it may not
+// support vertical writing mode for its candidate window.  This pref allows
+// to ignore the claim.
+pref("intl.imm.vertical_writing.always_assume_not_supported", false);
+
 // See bug 448927, on topmost panel, some IMEs are not usable on Windows.
 pref("ui.panel.default_level_parent", false);
 
 pref("mousewheel.system_scroll_override_on_root_content.enabled", true);
 
 // High resolution scrolling with supported mouse drivers on Vista or later.
 pref("mousewheel.enable_pixel_scrolling", true);
 
--- a/widget/windows/nsIMM32Handler.cpp
+++ b/widget/windows/nsIMM32Handler.cpp
@@ -11,23 +11,95 @@
 #include "nsWindowDefs.h"
 #include "WinUtils.h"
 #include "KeyboardLayout.h"
 #include <algorithm>
 
 #include "mozilla/MiscEvents.h"
 #include "mozilla/TextEvents.h"
 
+#ifndef IME_PROP_ACCEPT_WIDE_VKEY
+#define IME_PROP_ACCEPT_WIDE_VKEY 0x20
+#endif
+
 using namespace mozilla;
 using namespace mozilla::widget;
 
 static nsIMM32Handler* gIMM32Handler = nullptr;
 
 PRLogModuleInfo* gIMM32Log = nullptr;
 
+static void
+HandleSeparator(nsACString& aDesc)
+{
+  if (!aDesc.IsEmpty()) {
+    aDesc.AppendLiteral(" | ");
+  }
+}
+
+class GetIMEGeneralPropertyName : public nsAutoCString
+{
+public:
+  GetIMEGeneralPropertyName(DWORD aFlags)
+  {
+    if (!aFlags) {
+      AppendLiteral("no flags");
+      return;
+    }
+    if (aFlags & IME_PROP_AT_CARET) {
+      AppendLiteral("IME_PROP_AT_CARET");
+    }
+    if (aFlags & IME_PROP_SPECIAL_UI) {
+      HandleSeparator(*this);
+      AppendLiteral("IME_PROP_SPECIAL_UI");
+    }
+    if (aFlags & IME_PROP_CANDLIST_START_FROM_1) {
+      HandleSeparator(*this);
+      AppendLiteral("IME_PROP_CANDLIST_START_FROM_1");
+    }
+    if (aFlags & IME_PROP_UNICODE) {
+      HandleSeparator(*this);
+      AppendLiteral("IME_PROP_UNICODE");
+    }
+    if (aFlags & IME_PROP_COMPLETE_ON_UNSELECT) {
+      HandleSeparator(*this);
+      AppendLiteral("IME_PROP_COMPLETE_ON_UNSELECT");
+    }
+    if (aFlags & IME_PROP_ACCEPT_WIDE_VKEY) {
+      HandleSeparator(*this);
+      AppendLiteral("IME_PROP_ACCEPT_WIDE_VKEY");
+    }
+  }
+  virtual ~GetIMEGeneralPropertyName() {}
+};
+
+class GetIMEUIPropertyName : public nsAutoCString
+{
+public:
+  GetIMEUIPropertyName(DWORD aFlags)
+  {
+    if (!aFlags) {
+      AppendLiteral("no flags");
+      return;
+    }
+    if (aFlags & UI_CAP_2700) {
+      AppendLiteral("UI_CAP_2700");
+    }
+    if (aFlags & UI_CAP_ROT90) {
+      HandleSeparator(*this);
+      AppendLiteral("UI_CAP_ROT90");
+    }
+    if (aFlags & UI_CAP_ROTANY) {
+      HandleSeparator(*this);
+      AppendLiteral("UI_CAP_ROTANY");
+    }
+  }
+  virtual ~GetIMEUIPropertyName() {}
+};
+
 static UINT sWM_MSIME_MOUSE = 0; // mouse message for MSIME 98/2000
 
 //-------------------------------------------------------------------------
 //
 // from http://download.microsoft.com/download/6/0/9/60908e9e-d2c1-47db-98f6-216af76a235f/msime.h
 // The document for this has been removed from MSDN...
 //
 //-------------------------------------------------------------------------
@@ -38,16 +110,18 @@ static UINT sWM_MSIME_MOUSE = 0; // mous
 #define IMEMOUSE_LDOWN      0x01
 #define IMEMOUSE_RDOWN      0x02
 #define IMEMOUSE_MDOWN      0x04
 #define IMEMOUSE_WUP        0x10    // wheel up
 #define IMEMOUSE_WDOWN      0x20    // wheel down
 
 UINT nsIMM32Handler::sCodePage = 0;
 DWORD nsIMM32Handler::sIMEProperty = 0;
+DWORD nsIMM32Handler::sIMEUIProperty = 0;
+bool nsIMM32Handler::sAssumeVerticalWritingModeNotSupported = false;
 
 /* static */ void
 nsIMM32Handler::EnsureHandlerInstance()
 {
   if (!gIMM32Handler) {
     gIMM32Handler = new nsIMM32Handler();
   }
 }
@@ -56,16 +130,19 @@ nsIMM32Handler::EnsureHandlerInstance()
 nsIMM32Handler::Initialize()
 {
   if (!gIMM32Log)
     gIMM32Log = PR_NewLogModule("nsIMM32HandlerWidgets");
 
   if (!sWM_MSIME_MOUSE) {
     sWM_MSIME_MOUSE = ::RegisterWindowMessage(RWM_MOUSE);
   }
+  sAssumeVerticalWritingModeNotSupported =
+    Preferences::GetBool(
+      "intl.imm.vertical_writing.always_assume_not_supported", false);
   InitKeyboardLayout(::GetKeyboardLayout(0));
 }
 
 /* static */ void
 nsIMM32Handler::Terminate()
 {
   if (!gIMM32Handler)
     return;
@@ -106,28 +183,58 @@ nsIMM32Handler::ShouldDrawCompositionStr
 {
   // If current IME has special UI or its composition window should not
   // positioned to caret position, we should now draw composition string
   // ourselves.
   return !(sIMEProperty & IME_PROP_SPECIAL_UI) &&
           (sIMEProperty & IME_PROP_AT_CARET);
 }
 
+/* static */ bool
+nsIMM32Handler::IsVerticalWritingSupported()
+{
+  // Even if IME claims that they support vertical writing mode but it may not
+  // support vertical writing mode for its candidate window.
+  if (sAssumeVerticalWritingModeNotSupported) {
+    return false;
+  }
+  return !!(sIMEUIProperty & (UI_CAP_2700 | UI_CAP_ROT90 | UI_CAP_ROTANY));
+}
+
 /* static */ void
 nsIMM32Handler::InitKeyboardLayout(HKL aKeyboardLayout)
 {
+#ifdef PR_LOGGING
+  nsAutoString IMEName;
+  if (PR_LOG_TEST(gIMM32Log, PR_LOG_ALWAYS)) {
+    UINT IMENameLength = ::ImmGetDescriptionW(aKeyboardLayout, nullptr, 0);
+    if (IMENameLength) {
+      // Add room for the terminating null character
+      IMEName.SetLength(++IMENameLength);
+      IMENameLength =
+        ::ImmGetDescriptionW(aKeyboardLayout, IMEName.BeginWriting(),
+                             IMENameLength);
+      // Adjust the length to ignore the terminating null character
+      IMEName.SetLength(IMENameLength);
+    }
+  }
+#endif // #ifdef PR_LOGGING
+
   WORD langID = LOWORD(aKeyboardLayout);
   ::GetLocaleInfoW(MAKELCID(langID, SORT_DEFAULT),
                    LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER,
                    (PWSTR)&sCodePage, sizeof(sCodePage) / sizeof(WCHAR));
   sIMEProperty = ::ImmGetProperty(aKeyboardLayout, IGP_PROPERTY);
+  sIMEUIProperty = ::ImmGetProperty(aKeyboardLayout, IGP_UI);
   PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
-    ("IMM32: InitKeyboardLayout, aKeyboardLayout=%08x, sCodePage=%lu, "
-     "sIMEProperty=%08x",
-     aKeyboardLayout, sCodePage, sIMEProperty));
+    ("IMM32: InitKeyboardLayout, aKeyboardLayout=%08x (\"%s\"), sCodePage=%lu, "
+     "sIMEProperty=%s, sIMEUIProperty=%s",
+     aKeyboardLayout, NS_ConvertUTF16toUTF8(IMEName).get(),
+     sCodePage, GetIMEGeneralPropertyName(sIMEProperty).get(),
+     GetIMEUIPropertyName(sIMEUIProperty).get()));
 }
 
 /* static */ UINT
 nsIMM32Handler::GetKeyboardCodePage()
 {
   return sCodePage;
 }
 
--- a/widget/windows/nsIMM32Handler.h
+++ b/widget/windows/nsIMM32Handler.h
@@ -154,16 +154,17 @@ public:
 protected:
   static void EnsureHandlerInstance();
 
   static bool IsComposingOnOurEditor();
   static bool IsComposingOnPlugin();
   static bool IsComposingWindow(nsWindow* aWindow);
 
   static bool ShouldDrawCompositionStringOurselves();
+  static bool IsVerticalWritingSupported();
   static void InitKeyboardLayout(HKL aKeyboardLayout);
   static UINT GetKeyboardCodePage();
 
   /**
    * Checks whether the window is top level window of the composing window.
    * In this method, the top level window means in all windows, not only in all
    * OUR windows.  I.e., if the aWindow is embedded, this always returns FALSE.
    */
@@ -356,11 +357,13 @@ protected:
   uint32_t mCompositionStart;
 
   bool mIsComposing;
   bool mIsComposingOnPlugin;
   bool mNativeCaretIsCreated;
 
   static UINT sCodePage;
   static DWORD sIMEProperty;
+  static DWORD sIMEUIProperty;
+  static bool sAssumeVerticalWritingModeNotSupported;
 };
 
 #endif // nsIMM32Handler_h__