ソースを参照

Enable IME for Linux platform. Only tested using ibus.

Yao Wei Tjong 姚伟忠 9 年 前
コミット
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.
     - libpulse-dev (Debian-based) or pulseaudio-libs-devel (RedHat-based) for PulseAudio.
     - libroar-dev (Debian-based only) for RoarAudio (SNDIO).
     - 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.
   + %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).
   + Miscellaneous (optional).
     - libdbus-1-dev (Debian-based) or dbus-devel (Redhat-based) for system-wide messaging (e.g. inhibiting screen-saver).
     - 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.
     - 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)
       set(HAVE_IBUS_IBUS_H TRUE)
       include_directories(${IBUS_H_INCLUDE_DIRS} ${GLIB_H_INCLUDE_DIRS} ${GLIB_CONFIG_H_INCLUDE_DIRS})
       include_directories(${IBUS_H_INCLUDE_DIRS} ${GLIB_H_INCLUDE_DIRS} ${GLIB_CONFIG_H_INCLUDE_DIRS})
       list(APPEND EXTRA_LIBS ibus-1.0)
       list(APPEND EXTRA_LIBS ibus-1.0)
+      add_definitions (-DSDL_USE_IME)
     endif ()
     endif ()
 
 
     # Urho3D - bug fix - use find_path() to detect fcitx's header file so it works for both native and cross-compiling builds
     # 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)
     if (FCITX_H_INCLUDE_DIRS)
       set (HAVE_FCITX_FRONTEND_H TRUE)
       set (HAVE_FCITX_FRONTEND_H TRUE)
       include_directories (${FCITX_H_INCLUDE_DIRS})
       include_directories (${FCITX_H_INCLUDE_DIRS})
+      add_definitions (-DSDL_USE_IME)
     endif ()
     endif ()
 
 
     # Urho3D - bug fix - moved below logic from generic Unix block to Linux-specific block
     # 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)
 void Input::SetScreenKeyboardVisible(bool enable)
 {
 {
-    if (!graphics_)
-        return;
-
-    if (enable != IsScreenKeyboardVisible())
+    if (enable != SDL_IsTextInputActive())
     {
     {
         if (enable)
         if (enable)
             SDL_StartTextInput();
             SDL_StartTextInput();
@@ -1444,18 +1441,12 @@ bool Input::IsScreenJoystickVisible(SDL_JoystickID id) const
 
 
 bool Input::GetScreenKeyboardSupport() const
 bool Input::GetScreenKeyboardSupport() const
 {
 {
-    return graphics_ ? SDL_HasScreenKeyboardSupport() != 0 : false;
+    return SDL_HasScreenKeyboardSupport();
 }
 }
 
 
 bool Input::IsScreenKeyboardVisible() const
 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
 bool Input::IsMouseLocked() const
@@ -1856,29 +1847,33 @@ void Input::HandleSDLEvent(void* sdlEvent)
 
 
     switch (evt.type)
     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;
         break;
 
 

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

@@ -90,8 +90,14 @@ URHO3D_EVENT(E_KEYUP, KeyUp)
 URHO3D_EVENT(E_TEXTINPUT, TextInput)
 URHO3D_EVENT(E_TEXTINPUT, TextInput)
 {
 {
     URHO3D_PARAM(P_TEXT, Text);                    // String
     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.
 /// Joystick connected.

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

@@ -31,6 +31,8 @@
 
 
 #include "../DebugNew.h"
 #include "../DebugNew.h"
 
 
+#include <SDL/SDL.h>
+
 namespace Urho3D
 namespace Urho3D
 {
 {
 
 
@@ -429,25 +431,19 @@ void LineEdit::OnKey(int key, int buttons, int qualifiers)
         UpdateCursor();
         UpdateCursor();
 }
 }
 
 
-void LineEdit::OnTextInput(const String& text, int buttons, int qualifiers)
+void LineEdit::OnTextInput(const String& text)
 {
 {
     if (!editable_)
     if (!editable_)
         return;
         return;
 
 
     bool changed = false;
     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();
     VariantMap& eventData = GetEventDataMap();
     eventData[P_ELEMENT] = this;
     eventData[P_ELEMENT] = this;
     eventData[P_TEXT] = text;
     eventData[P_TEXT] = text;
-    eventData[P_BUTTONS] = buttons;
-    eventData[P_QUALIFIERS] = qualifiers;
     SendEvent(E_TEXTENTRY, eventData);
     SendEvent(E_TEXTENTRY, eventData);
 
 
     const String newText = eventData[P_TEXT].GetString().SubstringUTF8(0);
     const String newText = eventData[P_TEXT].GetString().SubstringUTF8(0);
@@ -603,6 +599,10 @@ void LineEdit::UpdateCursor()
     cursor_->SetPosition(text_->GetPosition() + IntVector2(x, 0));
     cursor_->SetPosition(text_->GetPosition() + IntVector2(x, 0));
     cursor_->SetSize(cursor_->GetWidth(), text_->GetRowHeight());
     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
     // Scroll if necessary
     int sx = -GetChildOffset().x_;
     int sx = -GetChildOffset().x_;
     int left = clipBorder_.left_;
     int left = clipBorder_.left_;
@@ -636,7 +636,7 @@ unsigned LineEdit::GetCharIndex(const IntVector2& position)
     return M_MAX_UNSIGNED;
     return M_MAX_UNSIGNED;
 }
 }
 
 
-void LineEdit::HandleFocused(StringHash eventType, VariantMap& eventData)
+void LineEdit::HandleFocused(StringHash /*eventType*/, VariantMap& eventData)
 {
 {
     if (eventData[Focused::P_BYKEY].GetBool())
     if (eventData[Focused::P_BYKEY].GetBool())
     {
     {
@@ -649,7 +649,7 @@ void LineEdit::HandleFocused(StringHash eventType, VariantMap& eventData)
         GetSubsystem<Input>()->SetScreenKeyboardVisible(true);
         GetSubsystem<Input>()->SetScreenKeyboardVisible(true);
 }
 }
 
 
-void LineEdit::HandleDefocused(StringHash eventType, VariantMap& eventData)
+void LineEdit::HandleDefocused(StringHash /*eventType*/, VariantMap& /*eventData*/)
 {
 {
     text_->ClearSelection();
     text_->ClearSelection();
 
 
@@ -657,7 +657,7 @@ void LineEdit::HandleDefocused(StringHash eventType, VariantMap& eventData)
         GetSubsystem<Input>()->SetScreenKeyboardVisible(false);
         GetSubsystem<Input>()->SetScreenKeyboardVisible(false);
 }
 }
 
 
-void LineEdit::HandleLayoutUpdated(StringHash eventType, VariantMap& eventData)
+void LineEdit::HandleLayoutUpdated(StringHash /*eventType*/, VariantMap& /*eventData*/)
 {
 {
     UpdateCursor();
     UpdateCursor();
 }
 }

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

@@ -67,7 +67,7 @@ public:
     /// React to a key press.
     /// React to a key press.
     virtual void OnKey(int key, int buttons, int qualifiers);
     virtual void OnKey(int key, int buttons, int qualifiers);
     /// React to text input event.
     /// React to text input event.
-    virtual void OnTextInput(const String& text, int buttons, int qualifiers);
+    virtual void OnTextInput(const String& text);
 
 
     /// Set text.
     /// Set text.
     void SetText(const String& 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;
     using namespace TextInput;
 
 
-    mouseButtons_ = eventData[P_BUTTONS].GetInt();
-    qualifiers_ = eventData[P_QUALIFIERS].GetInt();
-
     UIElement* element = focusElement_;
     UIElement* element = focusElement_;
     if (element)
     if (element)
-        element->OnTextInput(eventData[P_TEXT].GetString(), mouseButtons_, qualifiers_);
+        element->OnTextInput(eventData[P_TEXT].GetString());
 }
 }
 
 
 void UI::HandleBeginFrame(StringHash eventType, VariantMap& eventData)
 void UI::HandleBeginFrame(StringHash eventType, VariantMap& eventData)

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

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