Browse Source

Enable IME for Linux platform. Only tested using ibus.

Yao Wei Tjong 姚伟忠 9 years ago
parent
commit
1efb0d9085

+ 2 - 2
Docs/GettingStarted.dox

@@ -30,8 +30,8 @@ Although all required third-party libraries are included as source code, there a
     - libpulse-dev (Debian-based) or pulseaudio-libs-devel (RedHat-based) for PulseAudio.
     - libroar-dev (Debian-based only) for RoarAudio (SNDIO).
   + %Input method editor (optional). One or both of these can be installed at the same time to enable the IME support in the game engine. When both frameworks are installed on user's host system, the application uses XMODIFIFIERS environment variable to determine which one is active.
-    - libibus-1.0-dev (Debian-based) or ibus-devel (RedHat-based) for Intelligent Input Bus (ibus).
-    - fcitx-libs-dev (Debian-based) or fcitx-devel (RedHat-based) for Flexible Input Method Framework (fcitx).
+    - libibus-1.0-dev (Debian-based) or ibus-devel (RedHat-based) for Intelligent %Input Bus (ibus).
+    - fcitx-libs-dev (Debian-based) or fcitx-devel (RedHat-based) for Flexible %Input Method Framework (fcitx).
   + Miscellaneous (optional).
     - libdbus-1-dev (Debian-based) or dbus-devel (Redhat-based) for system-wide messaging (e.g. inhibiting screen-saver).
     - libreadline6-dev (Debian-based) or readline-devel (Redhat-based) for easy editing of command lines in interactive standalone host tools, e.g. isql and lua interpreter.

+ 2 - 0
Source/ThirdParty/SDL/CMakeLists.txt

@@ -1011,6 +1011,7 @@ elseif(UNIX)    # Urho3D - at this point both UNIX and UNIX_SYS should be equiva
       set(HAVE_IBUS_IBUS_H TRUE)
       include_directories(${IBUS_H_INCLUDE_DIRS} ${GLIB_H_INCLUDE_DIRS} ${GLIB_CONFIG_H_INCLUDE_DIRS})
       list(APPEND EXTRA_LIBS ibus-1.0)
+      add_definitions (-DSDL_USE_IME)
     endif ()
 
     # Urho3D - bug fix - use find_path() to detect fcitx's header file so it works for both native and cross-compiling builds
@@ -1018,6 +1019,7 @@ elseif(UNIX)    # Urho3D - at this point both UNIX and UNIX_SYS should be equiva
     if (FCITX_H_INCLUDE_DIRS)
       set (HAVE_FCITX_FRONTEND_H TRUE)
       include_directories (${FCITX_H_INCLUDE_DIRS})
+      add_definitions (-DSDL_USE_IME)
     endif ()
 
     # Urho3D - bug fix - moved below logic from generic Unix block to Linux-specific block

+ 25 - 30
Source/Urho3D/Input/Input.cpp

@@ -1137,10 +1137,7 @@ void Input::SetScreenJoystickVisible(SDL_JoystickID id, bool enable)
 
 void Input::SetScreenKeyboardVisible(bool enable)
 {
-    if (!graphics_)
-        return;
-
-    if (enable != IsScreenKeyboardVisible())
+    if (enable != SDL_IsTextInputActive())
     {
         if (enable)
             SDL_StartTextInput();
@@ -1444,18 +1441,12 @@ bool Input::IsScreenJoystickVisible(SDL_JoystickID id) const
 
 bool Input::GetScreenKeyboardSupport() const
 {
-    return graphics_ ? SDL_HasScreenKeyboardSupport() != 0 : false;
+    return SDL_HasScreenKeyboardSupport();
 }
 
 bool Input::IsScreenKeyboardVisible() const
 {
-    if (graphics_)
-    {
-        SDL_Window* window = graphics_->GetWindow();
-        return SDL_IsScreenKeyboardShown(window) != SDL_FALSE;
-    }
-    else
-        return false;
+    return SDL_IsTextInputActive();
 }
 
 bool Input::IsMouseLocked() const
@@ -1856,29 +1847,33 @@ void Input::HandleSDLEvent(void* sdlEvent)
 
     switch (evt.type)
     {
-        case SDL_KEYDOWN:
-            SetKey(ConvertSDLKeyCode(evt.key.keysym.sym, evt.key.keysym.scancode), evt.key.keysym.scancode, true);
-            break;
+    case SDL_KEYDOWN:
+        SetKey(ConvertSDLKeyCode(evt.key.keysym.sym, evt.key.keysym.scancode), evt.key.keysym.scancode, true);
+        break;
 
-        case SDL_KEYUP:
-            SetKey(ConvertSDLKeyCode(evt.key.keysym.sym, evt.key.keysym.scancode), evt.key.keysym.scancode, false);
-            break;
+    case SDL_KEYUP:
+        SetKey(ConvertSDLKeyCode(evt.key.keysym.sym, evt.key.keysym.scancode), evt.key.keysym.scancode, false);
+        break;
 
-        case SDL_TEXTINPUT:
+    case SDL_TEXTINPUT:
         {
-            textInput_ = &evt.text.text[0];
-            unsigned unicode = textInput_.AtUTF8(0);
-            if (unicode)
-            {
-                using namespace TextInput;
+            using namespace TextInput;
+
+            VariantMap textInputEventData;
+            textInputEventData[P_TEXT] = textInput_ = &evt.text.text[0];
+            SendEvent(E_TEXTINPUT, textInputEventData);
+        }
+        break;
 
-                VariantMap textInputEventData;
+    case SDL_TEXTEDITING:
+        {
+            using namespace TextEditing;
 
-                textInputEventData[P_TEXT] = textInput_;
-                textInputEventData[P_BUTTONS] = mouseButtonDown_;
-                textInputEventData[P_QUALIFIERS] = GetQualifiers();
-                SendEvent(E_TEXTINPUT, textInputEventData);
-            }
+            VariantMap textEditingEventData;
+            textEditingEventData[P_COMPOSITION] = &evt.edit.text[0];
+            textEditingEventData[P_CURSOR] = evt.edit.start;
+            textEditingEventData[P_SELECTION_LENGTH] = evt.edit.length;
+            SendEvent(E_TEXTEDITING, textEditingEventData);
         }
         break;
 

+ 8 - 2
Source/Urho3D/Input/InputEvents.h

@@ -90,8 +90,14 @@ URHO3D_EVENT(E_KEYUP, KeyUp)
 URHO3D_EVENT(E_TEXTINPUT, TextInput)
 {
     URHO3D_PARAM(P_TEXT, Text);                    // String
-    URHO3D_PARAM(P_BUTTONS, Buttons);              // int
-    URHO3D_PARAM(P_QUALIFIERS, Qualifiers);        // int
+}
+
+/// Text editing event.
+URHO3D_EVENT(E_TEXTEDITING, TextEditing)
+{
+    URHO3D_PARAM(P_COMPOSITION, Composition);      // String
+    URHO3D_PARAM(P_CURSOR, Cursor);                // int
+    URHO3D_PARAM(P_SELECTION_LENGTH, SelectionLength);  // int
 }
 
 /// Joystick connected.

+ 12 - 12
Source/Urho3D/UI/LineEdit.cpp

@@ -31,6 +31,8 @@
 
 #include "../DebugNew.h"
 
+#include <SDL/SDL.h>
+
 namespace Urho3D
 {
 
@@ -429,25 +431,19 @@ void LineEdit::OnKey(int key, int buttons, int qualifiers)
         UpdateCursor();
 }
 
-void LineEdit::OnTextInput(const String& text, int buttons, int qualifiers)
+void LineEdit::OnTextInput(const String& text)
 {
     if (!editable_)
         return;
 
     bool changed = false;
 
-    // If only CTRL is held down, do not edit
-    if ((qualifiers & (QUAL_CTRL | QUAL_ALT)) == QUAL_CTRL)
-        return;
-
-    // Send char as an event to allow changing it
-    using namespace CharEntry;
+    // Send text entry as an event to allow changing it
+    using namespace TextEntry;
 
     VariantMap& eventData = GetEventDataMap();
     eventData[P_ELEMENT] = this;
     eventData[P_TEXT] = text;
-    eventData[P_BUTTONS] = buttons;
-    eventData[P_QUALIFIERS] = qualifiers;
     SendEvent(E_TEXTENTRY, eventData);
 
     const String newText = eventData[P_TEXT].GetString().SubstringUTF8(0);
@@ -603,6 +599,10 @@ void LineEdit::UpdateCursor()
     cursor_->SetPosition(text_->GetPosition() + IntVector2(x, 0));
     cursor_->SetSize(cursor_->GetWidth(), text_->GetRowHeight());
 
+    IntVector2 screenPosition = ElementToScreen(cursor_->GetPosition());
+    SDL_Rect rect = {screenPosition.x_, screenPosition.y_, cursor_->GetSize().x_, cursor_->GetSize().y_};
+    SDL_SetTextInputRect(&rect);
+
     // Scroll if necessary
     int sx = -GetChildOffset().x_;
     int left = clipBorder_.left_;
@@ -636,7 +636,7 @@ unsigned LineEdit::GetCharIndex(const IntVector2& position)
     return M_MAX_UNSIGNED;
 }
 
-void LineEdit::HandleFocused(StringHash eventType, VariantMap& eventData)
+void LineEdit::HandleFocused(StringHash /*eventType*/, VariantMap& eventData)
 {
     if (eventData[Focused::P_BYKEY].GetBool())
     {
@@ -649,7 +649,7 @@ void LineEdit::HandleFocused(StringHash eventType, VariantMap& eventData)
         GetSubsystem<Input>()->SetScreenKeyboardVisible(true);
 }
 
-void LineEdit::HandleDefocused(StringHash eventType, VariantMap& eventData)
+void LineEdit::HandleDefocused(StringHash /*eventType*/, VariantMap& /*eventData*/)
 {
     text_->ClearSelection();
 
@@ -657,7 +657,7 @@ void LineEdit::HandleDefocused(StringHash eventType, VariantMap& eventData)
         GetSubsystem<Input>()->SetScreenKeyboardVisible(false);
 }
 
-void LineEdit::HandleLayoutUpdated(StringHash eventType, VariantMap& eventData)
+void LineEdit::HandleLayoutUpdated(StringHash /*eventType*/, VariantMap& /*eventData*/)
 {
     UpdateCursor();
 }

+ 1 - 1
Source/Urho3D/UI/LineEdit.h

@@ -67,7 +67,7 @@ public:
     /// React to a key press.
     virtual void OnKey(int key, int buttons, int qualifiers);
     /// React to text input event.
-    virtual void OnTextInput(const String& text, int buttons, int qualifiers);
+    virtual void OnTextInput(const String& text);
 
     /// Set text.
     void SetText(const String& text);

+ 1 - 4
Source/Urho3D/UI/UI.cpp

@@ -1720,12 +1720,9 @@ void UI::HandleTextInput(StringHash eventType, VariantMap& eventData)
 {
     using namespace TextInput;
 
-    mouseButtons_ = eventData[P_BUTTONS].GetInt();
-    qualifiers_ = eventData[P_QUALIFIERS].GetInt();
-
     UIElement* element = focusElement_;
     if (element)
-        element->OnTextInput(eventData[P_TEXT].GetString(), mouseButtons_, qualifiers_);
+        element->OnTextInput(eventData[P_TEXT].GetString());
 }
 
 void UI::HandleBeginFrame(StringHash eventType, VariantMap& eventData)

+ 1 - 1
Source/Urho3D/UI/UIElement.h

@@ -178,7 +178,7 @@ public:
     /// React to a key press.
     virtual void OnKey(int key, int buttons, int qualifiers) { }
     /// React to text input event.
-    virtual void OnTextInput(const String& text, int buttons, int qualifiers) { }
+    virtual void OnTextInput(const String& text) { }
 
     /// React to resize.
     virtual void OnResize(const IntVector2& newSize, const IntVector2& delta) { }

+ 3 - 5
Source/Urho3D/UI/UIEvents.h

@@ -231,13 +231,11 @@ URHO3D_EVENT(E_MODALCHANGED, ModalChanged)
     URHO3D_PARAM(P_MODAL, Modal);                  // bool
 }
 
-/// Text entry into a LineEdit. The char can be modified in the event data.
-URHO3D_EVENT(E_TEXTENTRY, CharEntry)
+/// Text entry into a LineEdit. The text can be modified in the event data.
+URHO3D_EVENT(E_TEXTENTRY, TextEntry)
 {
     URHO3D_PARAM(P_ELEMENT, Element);              // UIElement pointer
-    URHO3D_PARAM(P_TEXT, Text);                    // String
-    URHO3D_PARAM(P_BUTTONS, Buttons);              // int
-    URHO3D_PARAM(P_QUALIFIERS, Qualifiers);        // int
+    URHO3D_PARAM(P_TEXT, Text);                    // String [in/out]
 }
 
 /// Editable text changed