diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index 095f058ed9c..e863078a481 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -300,6 +300,11 @@ bool _OS::get_borderless_window() const { return OS::get_singleton()->get_borderless_window(); } +void _OS::set_ime_position(const Point2 &p_pos) { + + return OS::get_singleton()->set_ime_position(p_pos); +} + void _OS::set_use_file_access_save_and_swap(bool p_enable) { FileAccess::set_backup_save(p_enable); @@ -993,6 +998,8 @@ void _OS::_bind_methods() { ClassDB::bind_method(D_METHOD("set_borderless_window", "borderless"), &_OS::set_borderless_window); ClassDB::bind_method(D_METHOD("get_borderless_window"), &_OS::get_borderless_window); + ClassDB::bind_method(D_METHOD("set_ime_position"), &_OS::set_ime_position); + ClassDB::bind_method(D_METHOD("set_screen_orientation", "orientation"), &_OS::set_screen_orientation); ClassDB::bind_method(D_METHOD("get_screen_orientation"), &_OS::get_screen_orientation); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index 87d84c0732b..f72f665d9e4 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -158,6 +158,8 @@ public: virtual void set_borderless_window(bool p_borderless); virtual bool get_borderless_window() const; + virtual void set_ime_position(const Point2 &p_pos); + Error native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track); bool native_video_is_playing(); void native_video_pause(); diff --git a/core/os/os.h b/core/os/os.h index 11fe8b44e36..cafd1f4e148 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -179,6 +179,8 @@ public: virtual void set_borderless_window(int p_borderless) {} virtual bool get_borderless_window() { return 0; } + virtual void set_ime_position(const Point2 &p_pos) {} + virtual Error open_dynamic_library(const String p_path, void *&p_library_handle) { return ERR_UNAVAILABLE; }; virtual Error close_dynamic_library(void *p_library_handle) { return ERR_UNAVAILABLE; }; virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle) { return ERR_UNAVAILABLE; }; diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 790182794eb..4aca1468b1a 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -508,22 +508,17 @@ void OS_X11::xim_destroy_callback(::XIM im, ::XPointer client_data, os->xic = NULL; } -void OS_X11::set_ime_position(short x, short y) { +void OS_X11::set_ime_position(const Point2 &p_pos) { - if (!xic) { + if (!xic) return; - } + ::XPoint spot; - spot.x = x; - spot.y = y; - XVaNestedList preedit_attr = XVaCreateNestedList(0, - XNSpotLocation, &spot, - NULL); - XSetICValues(xic, - XNPreeditAttributes, preedit_attr, - NULL); + spot.x = short(p_pos.x); + spot.y = short(p_pos.y); + XVaNestedList preedit_attr = XVaCreateNestedList(0, XNSpotLocation, &spot, NULL); + XSetICValues(xic, XNPreeditAttributes, preedit_attr, NULL); XFree(preedit_attr); - return; } void OS_X11::finalize() { @@ -1489,7 +1484,7 @@ void OS_X11::process_xevents() { case ConfigureNotify: if (xic) { // Not portable. - set_ime_position(0, 1); + set_ime_position(Point2(0, 1)); } /* call resizeGLScene only if our window-size changed */ diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index 39c512b6bde..12e4bbb086c 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -115,7 +115,6 @@ class OS_X11 : public OS_Unix { ::XIMStyle xim_style; static void xim_destroy_callback(::XIM im, ::XPointer client_data, ::XPointer call_data); - void set_ime_position(short x, short y); Point2i last_mouse_pos; bool last_mouse_pos_valid; @@ -253,6 +252,7 @@ public: virtual void set_borderless_window(int p_borderless); virtual bool get_borderless_window(); + virtual void set_ime_position(const Point2 &p_pos); virtual void move_window_to_foreground(); virtual void alert(const String &p_alert, const String &p_title = "ALERT!"); diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index bc579020bd2..8d3271ca8c5 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -660,6 +660,11 @@ void LineEdit::_notification(int p_what) { Point2(x_ofs, y_ofs), Size2(1, caret_height)), cursor_color); } + + if (has_focus()) { + + OS::get_singleton()->set_ime_position(get_global_position() + Point2(x_ofs, y_ofs + caret_height)); + } } break; case NOTIFICATION_FOCUS_ENTER: { @@ -667,12 +672,17 @@ void LineEdit::_notification(int p_what) { draw_caret = true; } + Point2 cursor_pos = Point2(get_cursor_pos(), 1) * get_minimum_size().height; + OS::get_singleton()->set_ime_position(get_global_position() + cursor_pos); + if (OS::get_singleton()->has_virtual_keyboard()) OS::get_singleton()->show_virtual_keyboard(text, get_global_rect()); } break; case NOTIFICATION_FOCUS_EXIT: { + OS::get_singleton()->set_ime_position(Point2()); + if (OS::get_singleton()->has_virtual_keyboard()) OS::get_singleton()->hide_virtual_keyboard(); diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 936a9b77f8d..ffa23ce7714 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -1191,12 +1191,19 @@ void TextEdit::_notification(int p_what) { } } + if (has_focus()) { + OS::get_singleton()->set_ime_position(get_global_position() + cursor_pos + Point2(0, get_row_height())); + } } break; case NOTIFICATION_FOCUS_ENTER: { if (!caret_blink_enabled) { draw_caret = true; } + + Point2 cursor_pos = Point2(cursor_get_column(), cursor_get_line()) * get_row_height(); + OS::get_singleton()->set_ime_position(get_global_position() + cursor_pos); + if (OS::get_singleton()->has_virtual_keyboard()) OS::get_singleton()->show_virtual_keyboard(get_text(), get_global_rect()); if (raised_from_completion) { @@ -1206,6 +1213,8 @@ void TextEdit::_notification(int p_what) { } break; case NOTIFICATION_FOCUS_EXIT: { + OS::get_singleton()->set_ime_position(Point2()); + if (OS::get_singleton()->has_virtual_keyboard()) OS::get_singleton()->hide_virtual_keyboard(); if (raised_from_completion) {