Browse Source

Keyboard handling improvements

JoshEngebretson 10 years ago
parent
commit
10322f3d25

+ 9 - 23
Source/AtomicWebView/UIWebView.cpp

@@ -143,8 +143,8 @@ UIWebView::UIWebView(Context* context, const String &initialURL) : UIWidget(cont
 
     initialURL_ = initialURL;
 
-    //SubscribeToEvent(E_KEYDOWN, HANDLER(UIWebView, HandleKeyDown));
-    //SubscribeToEvent(E_KEYUP, HANDLER(UIWebView, HandleKeyUp));
+    SubscribeToEvent(E_KEYDOWN, HANDLER(UIWebView, HandleKeyDown));
+    SubscribeToEvent(E_KEYUP, HANDLER(UIWebView, HandleKeyUp));
     SubscribeToEvent(E_TEXTINPUT, HANDLER(UIWebView, HandleTextInput));
 }
 
@@ -158,16 +158,7 @@ void UIWebView::HandleKeyDown(StringHash eventType, VariantMap& eventData)
     if (!widget_ || !widget_->GetIsFocused())
         return;
 
-    //if (eventData[KeyDown::P_REPEAT].GetBool())
-    //    return;
-
-    int key = eventData[KeyDown::P_KEY].GetInt();
-    int scanCode = eventData[KeyDown::P_SCANCODE].GetInt();
-    unsigned raw = eventData[KeyDown::P_RAW].GetUInt();
-    int buttons = eventData[KeyDown::P_BUTTONS].GetInt();
-    int qual = eventData[KeyDown::P_QUALIFIERS].GetInt();
-
-    webClient_->SendKeyEvent(scanCode, qual, false);
+    webClient_->SendKeyEvent(eventType, eventData);
 
 }
 
@@ -176,13 +167,7 @@ void UIWebView::HandleKeyUp(StringHash eventType, VariantMap& eventData)
     if (!widget_ || !widget_->GetIsFocused())
         return;
 
-    int key = eventData[KeyUp::P_KEY].GetInt();
-    int scanCode = eventData[KeyUp::P_SCANCODE].GetInt();
-    unsigned raw = eventData[KeyUp::P_RAW].GetUInt();
-    int buttons = eventData[KeyUp::P_BUTTONS].GetInt();
-    int qual = eventData[KeyUp::P_QUALIFIERS].GetInt();
-
-    webClient_->SendKeyEvent(scanCode, qual, true);
+    webClient_->SendKeyEvent(eventType, eventData);
 
 }
 
@@ -191,16 +176,17 @@ void UIWebView::HandleTextInput(StringHash eventType, VariantMap& eventData)
     if (!widget_ || !widget_->GetIsFocused())
         return;
 
-    String text = eventData[TextInput::P_TEXT].GetString();
-
-    webClient_->SendTextEvent(text, 0);
+    webClient_->SendTextInputEvent(eventType, eventData);
 
 }
 
 bool UIWebView::HandleKeyEvent(const TBWidgetEvent &ev, bool keyDown)
 {
+
+#ifdef ATOMIC_PLATFORM_OSX
     if (!keyDown)
         return true;
+#endif
 
     if (ev.special_key == TB_KEY_UNDEFINED)
         return true;
@@ -244,7 +230,7 @@ bool UIWebView::HandleKeyEvent(const TBWidgetEvent &ev, bool keyDown)
     if (scanCode == SDL_SCANCODE_UNKNOWN)
         return true;
 
-    webClient_->SendKeyEvent(scanCode, qual, !keyDown);
+    //webClient_->SendKeyEvent(scanCode, qual, !keyDown);
 
     return true;
 

+ 8 - 53
Source/AtomicWebView/WebClient.cpp

@@ -18,8 +18,7 @@
 
 #include "WebBrowserHost.h"
 #include "WebClient.h"
-
-#include "WebKeyboardSDL.h"
+#include "WebKeyboard.h"
 
 namespace Atomic
 {
@@ -254,63 +253,18 @@ void WebClient::SendMouseWheelEvent(int x, int y, unsigned modifier,int deltaX,
 } cef_event_flags_t;
 
 */
-void WebClient::SendKeyEvent(int scanCode, int qual, bool keyUp)
+void WebClient::SendKeyEvent(const StringHash eventType, VariantMap& eventData)
 {
     if (!d_->browser_.get())
         return;
 
     CefRefPtr<CefBrowserHost> host = d_->browser_->GetHost();
-    CefKeyEvent keyEvent;
-
-    if (keyUp)
-        return;
-
-    // handle return special
-    if (scanCode == SDL_SCANCODE_RETURN)
-    {
-        keyEvent.type = KEYEVENT_CHAR;
-        keyEvent.character = 13;
-        host->SendKeyEvent(keyEvent);
-        return;
-    }
-
-    unsigned modifiers = EVENTFLAG_NONE;
 
-    if (qual & QUAL_SHIFT)
-        modifiers |= EVENTFLAG_SHIFT_DOWN;
-    if (qual & QUAL_ALT)
-        modifiers |= EVENTFLAG_ALT_DOWN;
-    if (qual & QUAL_CTRL)
-        modifiers |= EVENTFLAG_CONTROL_DOWN;
-
-#ifdef ATOMIC_PLATFORM_OSX
-    Input* input = GetSubsystem<Input>();
-    if (input->GetKeyDown(KEY_LGUI) || input->GetKeyDown(KEY_RGUI))
-    {
-        modifiers |= EVENTFLAG_COMMAND_DOWN;
-    }
-#endif
-
-    keyEvent.modifiers = modifiers;
-
-    int nativeKeyCode = GetNativeKeyFromSDLScanCode(scanCode);
+    CefKeyEvent keyEvent;
 
-    if (nativeKeyCode == -1)
+    if (!ConvertKeyEvent(eventType, eventData, keyEvent))
         return;
 
-    /*
-    target->type = src->type;
-    target->modifiers = src->modifiers;
-    target->windows_key_code = src->windows_key_code;
-    target->native_key_code = src->native_key_code;
-    target->is_system_key = src->is_system_key;
-    target->character = src->character;
-    target->unmodified_character = src->unmodified_character;
-    */
-
-    keyEvent.type = keyUp ? KEYEVENT_KEYUP : KEYEVENT_KEYDOWN;
-    keyEvent.native_key_code = nativeKeyCode;
-
     host->SendKeyEvent(keyEvent);
 
 #ifdef ATOMIC_PLATFORM_OSX
@@ -329,7 +283,7 @@ void WebClient::SendKeyEvent(int scanCode, int qual, bool keyUp)
 
 }
 
-void WebClient::SendTextEvent(const String& text, unsigned modifiers)
+void WebClient::SendTextInputEvent(const StringHash eventType, VariantMap& eventData)
 {
     if (!d_->browser_.get())
         return;
@@ -337,8 +291,9 @@ void WebClient::SendTextEvent(const String& text, unsigned modifiers)
     CefRefPtr<CefBrowserHost> host = d_->browser_->GetHost();
 
     CefKeyEvent keyEvent;
-    keyEvent.type = KEYEVENT_CHAR;
-    keyEvent.character = text[0];
+
+    if (!ConvertTextInputEvent(eventType, eventData, keyEvent))
+        return;
 
     host->SendKeyEvent(keyEvent);
 }

+ 2 - 3
Source/AtomicWebView/WebClient.h

@@ -38,9 +38,8 @@ public:
     void SendMouseMoveEvent(int x, int y, unsigned modifier, bool mouseLeave = false) const;
     void SendMouseWheelEvent(int x, int y, unsigned modifier, int deltaX, int deltaY) const;
 
-    void SendTextEvent(const String& text, unsigned modifiers);
-
-    void SendKeyEvent(int scanCode, int qual, bool keyUp);
+    void SendTextInputEvent(const StringHash eventType, VariantMap& eventData);
+    void SendKeyEvent(const StringHash eventType, VariantMap& eventData);
 
     void ShortcutCut();
     void ShortcutCopy();

+ 47 - 0
Source/AtomicWebView/WebKeyboard.h

@@ -0,0 +1,47 @@
+
+#pragma once
+
+#include <Atomic/Core/Variant.h>
+
+namespace Atomic
+{
+
+bool ConvertKeyEvent(const StringHash eventType, VariantMap& eventData, CefKeyEvent& keyEvent);
+bool ConvertTextInputEvent(const StringHash eventType, VariantMap& eventData, CefKeyEvent& keyEvent);
+
+struct WebKeyEvent
+{
+    bool repeat;
+    int key;
+    int scanCode;
+    unsigned raw;
+    int buttons;
+    int qual;
+    bool keyDown;
+
+    WebKeyEvent(const StringHash eventType, VariantMap& eventData)
+    {
+        if (eventType == "KeyDown")
+        {
+            keyDown = true;
+            repeat = eventData[KeyDown::P_REPEAT].GetBool();
+            key = eventData[KeyDown::P_KEY].GetInt();
+            scanCode = eventData[KeyDown::P_SCANCODE].GetInt();
+            raw = eventData[KeyDown::P_RAW].GetUInt();
+            buttons = eventData[KeyDown::P_BUTTONS].GetInt();
+            qual = eventData[KeyDown::P_QUALIFIERS].GetInt();
+        }
+        else if (eventType == "KeyUp")
+        {
+            keyDown = false;
+            key = eventData[KeyUp::P_KEY].GetInt();
+            scanCode = eventData[KeyUp::P_SCANCODE].GetInt();
+            raw = eventData[KeyUp::P_RAW].GetUInt();
+            buttons = eventData[KeyUp::P_BUTTONS].GetInt();
+            qual = eventData[KeyUp::P_QUALIFIERS].GetInt();
+        }
+
+    }
+};
+
+}

+ 149 - 0
Source/AtomicWebView/WebKeyboardWindows.cpp

@@ -0,0 +1,149 @@
+
+#ifdef ATOMIC_PLATFORM_WINDOWS
+
+#include <include/cef_client.h>
+
+#include <ThirdParty/SDL/include/SDL.h>
+#include <ThirdParty/SDL/include/SDL_syswm.h>
+
+#include <ThirdParty/SDL/src/events/scancodes_windows.h>
+
+#include <Atomic/Core/Variant.h>
+#include <Atomic/Input/InputEvents.h>
+#include <Atomic/Input/Input.h>
+#include <Atomic/IO/Log.h>
+
+#include "WebKeyboard.h"
+
+namespace Atomic
+{
+
+static bool SDLScanCodeToWindowsScanCode(SDL_Scancode code, LPARAM& lParam, WPARAM& wParam )
+{
+
+    wParam = 0;
+    lParam = 0;
+
+    if (code >= SDL_SCANCODE_A && code <= SDL_SCANCODE_0)
+        return false;
+
+    /*
+    int numCodes = sizeof(windows_scancode_table)/sizeof(SDL_Scancode);
+
+    int windowsScanCode = -1;
+    for (int i  = 0; i < numCodes; i++)
+    {
+        if (windows_scancode_table[i] == code)
+        {
+            windowsScanCode = i;
+            break;
+        }
+    }
+
+    if (windowsScanCode != -1)
+    {
+        lParam = windowsScanCode << 16;
+    }
+    */
+
+    switch (code)
+    {
+    case SDL_SCANCODE_RIGHT:
+        wParam = VK_RIGHT;
+        break;
+    case SDL_SCANCODE_LEFT:
+        wParam = VK_LEFT;
+        break;
+    case SDL_SCANCODE_UP:
+        wParam = VK_UP;
+        break;
+    case SDL_SCANCODE_DOWN:
+        wParam = VK_DOWN;
+        break;
+    case SDL_SCANCODE_DELETE:
+        wParam = VK_DELETE;
+        break;
+    case SDL_SCANCODE_BACKSPACE:
+        wParam = VK_BACK;
+        break;
+
+    }
+
+    return wParam != 0;
+
+}
+
+bool ConvertKeyEvent(const StringHash eventType, VariantMap& eventData, CefKeyEvent& keyEvent)
+{
+    if (eventType != "KeyDown" && eventType != "KeyUp")
+    {
+        LOGERROR("ConvertKeyEvent - Unknown event type");
+        return false;
+    }
+
+    WebKeyEvent wk(eventType, eventData);
+
+    if (wk.scanCode == SDL_SCANCODE_RETURN)
+    {
+        if (!wk.keyDown)
+            return false;
+
+        keyEvent.windows_key_code = VK_RETURN;
+        keyEvent.native_key_code = (int) 0;
+        keyEvent.type = KEYEVENT_CHAR;
+        return true;
+    }
+
+    LPARAM lParam;
+    WPARAM wParam;
+
+    keyEvent.modifiers = EVENTFLAG_NONE;
+
+    if (wk.qual & QUAL_SHIFT)
+        keyEvent.modifiers |= EVENTFLAG_SHIFT_DOWN;
+    if (wk.qual & QUAL_ALT)
+        keyEvent.modifiers |= EVENTFLAG_ALT_DOWN;
+    if (wk.qual & QUAL_CTRL)
+        keyEvent.modifiers |= EVENTFLAG_CONTROL_DOWN;
+
+
+    if (SDLScanCodeToWindowsScanCode((SDL_Scancode) wk.scanCode, lParam, wParam))
+    {
+        keyEvent.windows_key_code = (int) wParam;
+        keyEvent.native_key_code = (int) lParam;
+        keyEvent.type = wk.keyDown ? KEYEVENT_RAWKEYDOWN : KEYEVENT_KEYUP;
+    }
+
+    return true;
+}
+
+bool ConvertTextInputEvent(StringHash eventType, VariantMap& eventData, CefKeyEvent& keyEvent)
+{
+    if (eventType != "TextInput")
+    {
+        LOGERROR("ConvertTextInputEvent - Unknown event type");
+        return false;
+    }
+
+    String text = eventData[TextInput::P_TEXT].GetString();
+
+    SDL_Keycode keyCode = SDL_GetKeyFromName(text.CString());
+
+    if (SDL_strlen(text.CString()) == 1)
+    {
+        if (text[0] >= 'A' && text[0] <= 'Z')
+        {
+            keyCode -= 32;
+        }
+    }
+
+    keyEvent.windows_key_code = (int) keyCode;
+    keyEvent.native_key_code = 0;// (int) lParam;
+    keyEvent.type = KEYEVENT_CHAR;
+
+    return true;
+}
+
+}
+
+#endif