IME context detection.

This commit is contained in:
Saracen 2018-06-07 21:16:57 +01:00
parent 76875ba145
commit c5bdb5b1d8
11 changed files with 79 additions and 4 deletions

View file

@ -348,6 +348,11 @@ bool _OS::get_borderless_window() const {
return OS::get_singleton()->get_borderless_window();
}
void _OS::set_ime_active(const bool p_active) {
return OS::get_singleton()->set_ime_active(p_active);
}
void _OS::set_ime_position(const Point2 &p_pos) {
return OS::get_singleton()->set_ime_position(p_pos);

View file

@ -183,6 +183,7 @@ public:
virtual bool get_window_per_pixel_transparency_enabled() const;
virtual void set_window_per_pixel_transparency_enabled(bool p_enabled);
virtual void set_ime_active(const bool p_active);
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);

View file

@ -232,6 +232,7 @@ public:
virtual Size2 get_layered_buffer_size() { return Size2(0, 0); }
virtual void swap_layered_buffer() {}
virtual void set_ime_active(const bool p_active) {}
virtual void set_ime_position(const Point2 &p_pos) {}
virtual void set_ime_intermediate_text_callback(ImeCallback p_callback, void *p_inp) {}

View file

@ -117,6 +117,7 @@ public:
String open_with_filename;
Point2 im_position;
bool im_active;
ImeCallback im_callback;
void *im_target;
@ -233,6 +234,7 @@ public:
virtual bool get_window_per_pixel_transparency_enabled() const;
virtual void set_window_per_pixel_transparency_enabled(bool p_enabled);
virtual void set_ime_active(const bool p_active);
virtual void set_ime_position(const Point2 &p_pos);
virtual void set_ime_intermediate_text_callback(ImeCallback p_callback, void *p_inp);

View file

@ -959,7 +959,7 @@ static int remapKey(unsigned int key) {
push_to_key_event_buffer(ke);
}
if ((OS_OSX::singleton->im_position.x != 0) && (OS_OSX::singleton->im_position.y != 0))
if (OS_OSX::singleton->im_active == true)
[self interpretKeyEvents:[NSArray arrayWithObject:event]];
}
@ -1129,6 +1129,10 @@ String OS_OSX::get_unique_id() const {
return serial_number;
}
void OS_OSX::set_ime_active(const bool p_active) {
im_active = p_active;
}
void OS_OSX::set_ime_position(const Point2 &p_pos) {
im_position = p_pos;
}
@ -2542,6 +2546,7 @@ OS_OSX::OS_OSX() {
mouse_mode = OS::MOUSE_MODE_VISIBLE;
main_loop = NULL;
singleton = this;
im_active = false;
im_position = Point2();
im_callback = NULL;
im_target = NULL;

View file

@ -1181,6 +1181,15 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
if (p_desired.layered_splash) {
set_window_per_pixel_transparency_enabled(true);
}
// IME
im_himc = ImmGetContext(hWnd);
ImmReleaseContext(hWnd, im_himc);
im_position = Vector2();
set_ime_active(false);
return OK;
}
@ -2659,13 +2668,29 @@ String OS_Windows::get_unique_id() const {
return String(HwProfInfo.szHwProfileGuid);
}
void OS_Windows::set_ime_active(const bool p_active) {
if (p_active) {
ImmAssociateContext(hWnd, im_himc);
set_ime_position(im_position);
} else {
ImmAssociateContext(hWnd, (HIMC)0);
}
}
void OS_Windows::set_ime_position(const Point2 &p_pos) {
im_position = p_pos;
HIMC himc = ImmGetContext(hWnd);
if (himc == (HIMC)0)
return;
COMPOSITIONFORM cps;
cps.dwStyle = CFS_FORCE_POSITION;
cps.ptCurrentPos.x = p_pos.x;
cps.ptCurrentPos.y = p_pos.y;
cps.ptCurrentPos.x = im_position.x;
cps.ptCurrentPos.y = im_position.y;
ImmSetCompositionWindow(himc, &cps);
ImmReleaseContext(hWnd, himc);
}

View file

@ -111,6 +111,10 @@ class OS_Windows : public OS {
WNDPROC user_proc;
// IME
HIMC im_himc;
Vector2 im_position;
MouseMode mouse_mode;
bool alt_mem;
bool gr_mem;
@ -282,6 +286,7 @@ public:
virtual String get_unique_id() const;
virtual void set_ime_active(const bool p_active);
virtual void set_ime_position(const Point2 &p_pos);
virtual void release_rendering_thread();

View file

@ -391,6 +391,9 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
wm_delete = XInternAtom(x11_display, "WM_DELETE_WINDOW", true);
XSetWMProtocols(x11_display, x11_window, &wm_delete, 1);
im_active = false;
im_position = Vector2();
if (xim && xim_style) {
xic = XCreateIC(xim, XNInputStyle, xim_style, XNClientWindow, x11_window, XNFocusWindow, x11_window, (char *)NULL);
@ -400,7 +403,7 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
xic = NULL;
}
if (xic) {
XSetICFocus(xic);
XUnsetICFocus(xic);
} else {
WARN_PRINT("XCreateIC couldn't create xic");
}
@ -541,8 +544,25 @@ void OS_X11::xim_destroy_callback(::XIM im, ::XPointer client_data,
os->xic = NULL;
}
void OS_X11::set_ime_active(const bool p_active) {
im_active = p_active;
if (!xic)
return;
if (p_active) {
XSetICFocus(xic);
set_ime_position(im_position);
} else {
XUnsetICFocus(xic);
}
}
void OS_X11::set_ime_position(const Point2 &p_pos) {
im_position = p_pos;
if (!xic)
return;

View file

@ -116,6 +116,10 @@ class OS_X11 : public OS_Unix {
static void xim_destroy_callback(::XIM im, ::XPointer client_data,
::XPointer call_data);
// IME
bool im_active;
Vector2 im_position;
Point2i last_mouse_pos;
bool last_mouse_pos_valid;
Point2i last_click_pos;
@ -269,6 +273,7 @@ public:
virtual bool get_window_per_pixel_transparency_enabled() const;
virtual void set_window_per_pixel_transparency_enabled(bool p_enabled);
virtual void set_ime_active(const bool p_active);
virtual void set_ime_position(const Point2 &p_pos);
virtual String get_unique_id() const;

View file

@ -756,6 +756,7 @@ void LineEdit::_notification(int p_what) {
if (has_focus()) {
OS::get_singleton()->set_ime_active(true);
OS::get_singleton()->set_ime_position(get_global_position() + Point2(x_ofs, y_ofs + caret_height));
OS::get_singleton()->set_ime_intermediate_text_callback(_ime_text_callback, this);
}
@ -766,6 +767,7 @@ void LineEdit::_notification(int p_what) {
draw_caret = true;
}
OS::get_singleton()->set_ime_active(true);
Point2 cursor_pos = Point2(get_cursor_position(), 1) * get_minimum_size().height;
OS::get_singleton()->set_ime_position(get_global_position() + cursor_pos);
OS::get_singleton()->set_ime_intermediate_text_callback(_ime_text_callback, this);
@ -778,6 +780,7 @@ void LineEdit::_notification(int p_what) {
OS::get_singleton()->set_ime_position(Point2());
OS::get_singleton()->set_ime_intermediate_text_callback(NULL, NULL);
OS::get_singleton()->set_ime_active(false);
ime_text = "";
ime_selection = Point2();

View file

@ -1388,6 +1388,7 @@ void TextEdit::_notification(int p_what) {
}
if (has_focus()) {
OS::get_singleton()->set_ime_active(true);
OS::get_singleton()->set_ime_position(get_global_position() + cursor_pos + Point2(0, get_row_height()));
OS::get_singleton()->set_ime_intermediate_text_callback(_ime_text_callback, this);
}
@ -1399,6 +1400,7 @@ void TextEdit::_notification(int p_what) {
draw_caret = true;
}
OS::get_singleton()->set_ime_active(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);
OS::get_singleton()->set_ime_intermediate_text_callback(_ime_text_callback, this);
@ -1413,6 +1415,7 @@ void TextEdit::_notification(int p_what) {
OS::get_singleton()->set_ime_position(Point2());
OS::get_singleton()->set_ime_intermediate_text_callback(NULL, NULL);
OS::get_singleton()->set_ime_active(false);
ime_text = "";
ime_selection = Point2();