Bug 1077515 - part 11 - Remap arrow keys for vertical writing mode in the Gtk widget code. r=roc
authorJonathan Kew <jkew@mozilla.com>
Sat, 22 Nov 2014 14:39:04 +0000
changeset 217001 4c90e4b108ec5abd714867d511e0791ddb0254bd
parent 217000 23fcc95993718d7c99042c80683c844b735dee48
child 217002 203d3b5da245f9d2b89373114b61e86e35e62b99
push id52195
push userjkew@mozilla.com
push dateSat, 22 Nov 2014 14:54:52 +0000
treeherdermozilla-inbound@203d3b5da245 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs1077515
milestone36.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 1077515 - part 11 - Remap arrow keys for vertical writing mode in the Gtk widget code. r=roc
widget/gtk/nsWindow.cpp
widget/gtk/nsWindow.h
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -6000,22 +6000,89 @@ nsWindow::GetIMEUpdatePreference()
         nsIMEUpdatePreference::NOTIFY_SELECTION_CHANGE);
     // We shouldn't notify IME of selection change caused by changes of
     // composition string.  Therefore, we don't need to be notified selection
     // changes which are caused by compositionchange events handled.
     updatePreference.DontNotifyChangesCausedByComposition();
     return updatePreference;
 }
 
+bool
+nsWindow::ExecuteNativeKeyBindingRemapped(NativeKeyBindingsType aType,
+                                          const WidgetKeyboardEvent& aEvent,
+                                          DoCommandCallback aCallback,
+                                          void* aCallbackData,
+                                          uint32_t aGeckoKeyCode,
+                                          uint32_t aNativeKeyCode)
+{
+    WidgetKeyboardEvent modifiedEvent(aEvent);
+    modifiedEvent.keyCode = aGeckoKeyCode;
+    static_cast<GdkEventKey*>(modifiedEvent.mNativeKeyEvent)->keyval =
+        aNativeKeyCode;
+
+    NativeKeyBindings* keyBindings = NativeKeyBindings::GetInstance(aType);
+    return keyBindings->Execute(modifiedEvent, aCallback, aCallbackData);
+}
+
 NS_IMETHODIMP_(bool)
 nsWindow::ExecuteNativeKeyBinding(NativeKeyBindingsType aType,
                                   const WidgetKeyboardEvent& aEvent,
                                   DoCommandCallback aCallback,
                                   void* aCallbackData)
 {
+    if (aEvent.keyCode >= nsIDOMKeyEvent::DOM_VK_LEFT &&
+        aEvent.keyCode <= nsIDOMKeyEvent::DOM_VK_DOWN) {
+
+        // Check if we're targeting content with vertical writing mode,
+        // and if so remap the arrow keys.
+        WidgetQueryContentEvent query(true, NS_QUERY_SELECTED_TEXT, this);
+        nsEventStatus status;
+        DispatchEvent(&query, status);
+
+        if (query.mSucceeded && query.mReply.mWritingMode.IsVertical()) {
+            uint32_t geckoCode = 0;
+            uint32_t gdkCode = 0;
+            switch (aEvent.keyCode) {
+            case nsIDOMKeyEvent::DOM_VK_LEFT:
+                if (query.mReply.mWritingMode.IsVerticalLR()) {
+                    geckoCode = nsIDOMKeyEvent::DOM_VK_UP;
+                    gdkCode = GDK_Up;
+                } else {
+                    geckoCode = nsIDOMKeyEvent::DOM_VK_DOWN;
+                    gdkCode = GDK_Down;
+                }
+                break;
+
+            case nsIDOMKeyEvent::DOM_VK_RIGHT:
+                if (query.mReply.mWritingMode.IsVerticalLR()) {
+                    geckoCode = nsIDOMKeyEvent::DOM_VK_DOWN;
+                    gdkCode = GDK_Down;
+                } else {
+                    geckoCode = nsIDOMKeyEvent::DOM_VK_UP;
+                    gdkCode = GDK_Up;
+                }
+                break;
+
+            case nsIDOMKeyEvent::DOM_VK_UP:
+                geckoCode = nsIDOMKeyEvent::DOM_VK_LEFT;
+                gdkCode = GDK_Left;
+                break;
+
+            case nsIDOMKeyEvent::DOM_VK_DOWN:
+                geckoCode = nsIDOMKeyEvent::DOM_VK_RIGHT;
+                gdkCode = GDK_Right;
+                break;
+            }
+
+            return ExecuteNativeKeyBindingRemapped(aType, aEvent, aCallback,
+                                                   aCallbackData,
+                                                   geckoCode, gdkCode);
+        }
+    }
+
     NativeKeyBindings* keyBindings = NativeKeyBindings::GetInstance(aType);
     return keyBindings->Execute(aEvent, aCallback, aCallbackData);
 }
 
 NS_IMETHODIMP
 nsWindow::GetToggledKeyState(uint32_t aKeyCode, bool* aLEDState)
 {
     NS_ENSURE_ARG_POINTER(aLEDState);
--- a/widget/gtk/nsWindow.h
+++ b/widget/gtk/nsWindow.h
@@ -258,16 +258,23 @@ public:
     bool               DispatchKeyDownEvent(GdkEventKey *aEvent,
                                             bool *aIsCancelled);
 
     NS_IMETHOD NotifyIME(const IMENotification& aIMENotification) MOZ_OVERRIDE;
     NS_IMETHOD_(void) SetInputContext(const InputContext& aContext,
                                       const InputContextAction& aAction);
     NS_IMETHOD_(InputContext) GetInputContext();
     virtual nsIMEUpdatePreference GetIMEUpdatePreference();
+    bool ExecuteNativeKeyBindingRemapped(
+                        NativeKeyBindingsType aType,
+                        const mozilla::WidgetKeyboardEvent& aEvent,
+                        DoCommandCallback aCallback,
+                        void* aCallbackData,
+                        uint32_t aGeckoKeyCode,
+                        uint32_t aNativeKeyCode);
     NS_IMETHOD_(bool) ExecuteNativeKeyBinding(
                         NativeKeyBindingsType aType,
                         const mozilla::WidgetKeyboardEvent& aEvent,
                         DoCommandCallback aCallback,
                         void* aCallbackData) MOZ_OVERRIDE;
     NS_IMETHOD GetToggledKeyState(uint32_t aKeyCode, bool* aLEDState);
 
     // These methods are for toplevel windows only.