Merge pull request #9366 from GodotExplorer/pr-ime-position-flow-cursor

IME window follow the input cursor.
This commit is contained in:
Rémi Verschelde 2017-07-11 17:07:14 +02:00 committed by GitHub
commit a5bb77d523
7 changed files with 39 additions and 14 deletions

View file

@ -300,6 +300,11 @@ bool _OS::get_borderless_window() const {
return OS::get_singleton()->get_borderless_window(); 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) { void _OS::set_use_file_access_save_and_swap(bool p_enable) {
FileAccess::set_backup_save(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("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("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("set_screen_orientation", "orientation"), &_OS::set_screen_orientation);
ClassDB::bind_method(D_METHOD("get_screen_orientation"), &_OS::get_screen_orientation); ClassDB::bind_method(D_METHOD("get_screen_orientation"), &_OS::get_screen_orientation);

View file

@ -158,6 +158,8 @@ public:
virtual void set_borderless_window(bool p_borderless); virtual void set_borderless_window(bool p_borderless);
virtual bool get_borderless_window() const; 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); Error native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track);
bool native_video_is_playing(); bool native_video_is_playing();
void native_video_pause(); void native_video_pause();

View file

@ -179,6 +179,8 @@ public:
virtual void set_borderless_window(int p_borderless) {} virtual void set_borderless_window(int p_borderless) {}
virtual bool get_borderless_window() { return 0; } 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 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 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; }; virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle) { return ERR_UNAVAILABLE; };

View file

@ -508,22 +508,17 @@ void OS_X11::xim_destroy_callback(::XIM im, ::XPointer client_data,
os->xic = NULL; 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; return;
}
::XPoint spot; ::XPoint spot;
spot.x = x; spot.x = short(p_pos.x);
spot.y = y; spot.y = short(p_pos.y);
XVaNestedList preedit_attr = XVaCreateNestedList(0, XVaNestedList preedit_attr = XVaCreateNestedList(0, XNSpotLocation, &spot, NULL);
XNSpotLocation, &spot, XSetICValues(xic, XNPreeditAttributes, preedit_attr, NULL);
NULL);
XSetICValues(xic,
XNPreeditAttributes, preedit_attr,
NULL);
XFree(preedit_attr); XFree(preedit_attr);
return;
} }
void OS_X11::finalize() { void OS_X11::finalize() {
@ -1489,7 +1484,7 @@ void OS_X11::process_xevents() {
case ConfigureNotify: case ConfigureNotify:
if (xic) { if (xic) {
// Not portable. // Not portable.
set_ime_position(0, 1); set_ime_position(Point2(0, 1));
} }
/* call resizeGLScene only if our window-size changed */ /* call resizeGLScene only if our window-size changed */

View file

@ -115,7 +115,6 @@ class OS_X11 : public OS_Unix {
::XIMStyle xim_style; ::XIMStyle xim_style;
static void xim_destroy_callback(::XIM im, ::XPointer client_data, static void xim_destroy_callback(::XIM im, ::XPointer client_data,
::XPointer call_data); ::XPointer call_data);
void set_ime_position(short x, short y);
Point2i last_mouse_pos; Point2i last_mouse_pos;
bool last_mouse_pos_valid; bool last_mouse_pos_valid;
@ -253,6 +252,7 @@ public:
virtual void set_borderless_window(int p_borderless); virtual void set_borderless_window(int p_borderless);
virtual bool get_borderless_window(); virtual bool get_borderless_window();
virtual void set_ime_position(const Point2 &p_pos);
virtual void move_window_to_foreground(); virtual void move_window_to_foreground();
virtual void alert(const String &p_alert, const String &p_title = "ALERT!"); virtual void alert(const String &p_alert, const String &p_title = "ALERT!");

View file

@ -660,6 +660,11 @@ void LineEdit::_notification(int p_what) {
Point2(x_ofs, y_ofs), Size2(1, caret_height)), Point2(x_ofs, y_ofs), Size2(1, caret_height)),
cursor_color); cursor_color);
} }
if (has_focus()) {
OS::get_singleton()->set_ime_position(get_global_position() + Point2(x_ofs, y_ofs + caret_height));
}
} break; } break;
case NOTIFICATION_FOCUS_ENTER: { case NOTIFICATION_FOCUS_ENTER: {
@ -667,12 +672,17 @@ void LineEdit::_notification(int p_what) {
draw_caret = true; 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()) if (OS::get_singleton()->has_virtual_keyboard())
OS::get_singleton()->show_virtual_keyboard(text, get_global_rect()); OS::get_singleton()->show_virtual_keyboard(text, get_global_rect());
} break; } break;
case NOTIFICATION_FOCUS_EXIT: { case NOTIFICATION_FOCUS_EXIT: {
OS::get_singleton()->set_ime_position(Point2());
if (OS::get_singleton()->has_virtual_keyboard()) if (OS::get_singleton()->has_virtual_keyboard())
OS::get_singleton()->hide_virtual_keyboard(); OS::get_singleton()->hide_virtual_keyboard();

View file

@ -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; } break;
case NOTIFICATION_FOCUS_ENTER: { case NOTIFICATION_FOCUS_ENTER: {
if (!caret_blink_enabled) { if (!caret_blink_enabled) {
draw_caret = true; 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()) if (OS::get_singleton()->has_virtual_keyboard())
OS::get_singleton()->show_virtual_keyboard(get_text(), get_global_rect()); OS::get_singleton()->show_virtual_keyboard(get_text(), get_global_rect());
if (raised_from_completion) { if (raised_from_completion) {
@ -1206,6 +1213,8 @@ void TextEdit::_notification(int p_what) {
} break; } break;
case NOTIFICATION_FOCUS_EXIT: { case NOTIFICATION_FOCUS_EXIT: {
OS::get_singleton()->set_ime_position(Point2());
if (OS::get_singleton()->has_virtual_keyboard()) if (OS::get_singleton()->has_virtual_keyboard())
OS::get_singleton()->hide_virtual_keyboard(); OS::get_singleton()->hide_virtual_keyboard();
if (raised_from_completion) { if (raised_from_completion) {