diff options
-rw-r--r-- | demos/input_method/main.cpp | 2 | ||||
-rw-r--r-- | include/cru/platform/native/input_method.hpp | 2 | ||||
-rw-r--r-- | include/cru/platform/native/window.hpp | 1 | ||||
-rw-r--r-- | include/cru/win/native/input_method.hpp | 3 | ||||
-rw-r--r-- | include/cru/win/native/window.hpp | 8 | ||||
-rw-r--r-- | include/cru/win/string.hpp | 2 | ||||
-rw-r--r-- | src/win/native/input_method.cpp | 27 | ||||
-rw-r--r-- | src/win/native/window.cpp | 21 |
8 files changed, 31 insertions, 35 deletions
diff --git a/demos/input_method/main.cpp b/demos/input_method/main.cpp index 01a1a695..ce96a8c1 100644 --- a/demos/input_method/main.cpp +++ b/demos/input_method/main.cpp @@ -111,7 +111,7 @@ int main() { } }); - window->CharEvent()->AddHandler( + input_method_context->TextEvent()->AddHandler( [window, &committed_text](const std::string_view& c) { committed_text += c; window->RequestRepaint(); diff --git a/include/cru/platform/native/input_method.hpp b/include/cru/platform/native/input_method.hpp index 4034be4e..c6413a7e 100644 --- a/include/cru/platform/native/input_method.hpp +++ b/include/cru/platform/native/input_method.hpp @@ -66,6 +66,8 @@ struct IInputMethodContext : virtual INativeResource { // Triggered every time composition text changes. virtual IEvent<std::nullptr_t>* CompositionEvent() = 0; + + virtual IEvent<std::string_view>* TextEvent() = 0; }; struct IInputMethodManager : virtual INativeResource { diff --git a/include/cru/platform/native/window.hpp b/include/cru/platform/native/window.hpp index 49b00023..57363a3b 100644 --- a/include/cru/platform/native/window.hpp +++ b/include/cru/platform/native/window.hpp @@ -57,7 +57,6 @@ struct INativeWindow : virtual INativeResource { virtual IEvent<NativeMouseButtonEventArgs>* MouseUpEvent() = 0; virtual IEvent<NativeKeyEventArgs>* KeyDownEvent() = 0; virtual IEvent<NativeKeyEventArgs>* KeyUpEvent() = 0; - virtual IEvent<std::string_view>* CharEvent() = 0; }; // See INativeWindow for more info. diff --git a/include/cru/win/native/input_method.hpp b/include/cru/win/native/input_method.hpp index 8e17abd5..ff867f3f 100644 --- a/include/cru/win/native/input_method.hpp +++ b/include/cru/win/native/input_method.hpp @@ -61,6 +61,8 @@ class WinInputMethodContext : public WinNativeResource, IEvent<std::nullptr_t>* CompositionEvent() override; + IEvent<std::string_view>* TextEvent() override; + private: void OnWindowNativeMessage(WindowNativeMessageEventArgs& args); @@ -76,6 +78,7 @@ class WinInputMethodContext : public WinNativeResource, Event<std::nullptr_t> composition_start_event_; Event<std::nullptr_t> composition_end_event_; Event<std::nullptr_t> composition_event_; + Event<std::string_view> text_event_; }; class WinInputMethodManager : public WinNativeResource, diff --git a/include/cru/win/native/window.hpp b/include/cru/win/native/window.hpp index 83497fa6..59b38ab5 100644 --- a/include/cru/win/native/window.hpp +++ b/include/cru/win/native/window.hpp @@ -72,7 +72,6 @@ class WinNativeWindow : public WinNativeResource, public virtual INativeWindow { IEvent<platform::native::NativeKeyEventArgs>* KeyUpEvent() override { return &key_up_event_; } - IEvent<std::string_view>* CharEvent() override { return &char_event_; }; IEvent<WindowNativeMessageEventArgs&>* NativeMessageEvent() { return &native_message_event_; @@ -109,7 +108,6 @@ class WinNativeWindow : public WinNativeResource, public virtual INativeWindow { void OnMouseWheelInternal(short delta, POINT point); void OnKeyDownInternal(int virtual_code); void OnKeyUpInternal(int virtual_code); - void OnCharInternal(wchar_t c); void OnActivatedInternal(); void OnDeactivatedInternal(); @@ -146,14 +144,8 @@ class WinNativeWindow : public WinNativeResource, public virtual INativeWindow { Event<platform::native::NativeMouseButtonEventArgs> mouse_up_event_; Event<platform::native::NativeKeyEventArgs> key_down_event_; Event<platform::native::NativeKeyEventArgs> key_up_event_; - Event<std::string_view> char_event_; Event<WindowNativeMessageEventArgs&> native_message_event_; - - // WM_CHAR may be sent twice successively with two utf-16 code units of - // surrogate pair when character is from supplementary planes. This field is - // used to save the previous one. - wchar_t last_wm_char_event_wparam_; }; class WinNativeWindowResolver : public WinNativeResource, diff --git a/include/cru/win/string.hpp b/include/cru/win/string.hpp index b2bfd245..aec0e3d9 100644 --- a/include/cru/win/string.hpp +++ b/include/cru/win/string.hpp @@ -27,6 +27,8 @@ namespace cru::platform::win { std::string ToUtf8String(const std::wstring_view& string); std::wstring ToUtf16String(const std::string_view& string); +inline bool IsSurrogatePair(wchar_t c) { return c >= 0xD800 && c <= 0xDFFF; } + inline bool IsSurrogatePairLeading(wchar_t c) { return c >= 0xD800 && c <= 0xDBFF; } diff --git a/src/win/native/input_method.cpp b/src/win/native/input_method.cpp index 091abedd..dba2b1eb 100644 --- a/src/win/native/input_method.cpp +++ b/src/win/native/input_method.cpp @@ -247,10 +247,31 @@ IEvent<std::nullptr_t>* WinInputMethodContext::CompositionEvent() { return &composition_event_; } +IEvent<std::string_view>* WinInputMethodContext::TextEvent() { + return &text_event_; +} + void WinInputMethodContext::OnWindowNativeMessage( WindowNativeMessageEventArgs& args) { - const auto message = args.GetWindowMessage(); + const auto& message = args.GetWindowMessage(); switch (message.msg) { + case WM_CHAR: { + const auto c = static_cast<wchar_t>(message.w_param); + if (platform::win::IsSurrogatePair(c)) { + // I don't think this will happen because normal key strike without ime + // should only trigger ascci character. If it is a charater from + // supplementary planes, it should be handled with ime messages. + log::Warn( + "WinInputMethodContext: A WM_CHAR message for character from " + "supplementary planes is ignored."); + } else { + wchar_t s[1] = {c}; + auto str = platform::win::ToUtf8String({s, 1}); + text_event_.Raise(str); + } + args.HandleWithResult(0); + break; + } case WM_IME_COMPOSITION: { composition_event_.Raise(nullptr); auto composition_text = GetCompositionText(); @@ -259,9 +280,7 @@ void WinInputMethodContext::OnWindowNativeMessage( composition_text); if (message.l_param & GCS_RESULTSTR) { auto result_string = GetResultString(); - log::Debug( - "WinInputMethodContext: WM_IME_COMPOSITION result string: {}", - result_string); + text_event_.Raise(result_string); } break; } diff --git a/src/win/native/window.cpp b/src/win/native/window.cpp index 30c77659..bda8e764 100644 --- a/src/win/native/window.cpp +++ b/src/win/native/window.cpp @@ -304,10 +304,6 @@ bool WinNativeWindow::HandleNativeWindowMessage(HWND hwnd, UINT msg, return true; } return false; - case WM_CHAR: - OnCharInternal(static_cast<wchar_t>(w_param)); - *result = 0; - return true; case WM_SIZE: OnResizeInternal(LOWORD(l_param), HIWORD(l_param)); *result = 0; @@ -428,23 +424,6 @@ void WinNativeWindow::OnKeyUpInternal(int virtual_code) { {VirtualKeyToKeyCode(virtual_code), RetrieveKeyMofifier()}); } -void WinNativeWindow::OnCharInternal(wchar_t c) { - if (platform::win::IsSurrogatePairLeading(c)) { - last_wm_char_event_wparam_ = c; - return; - } else if (platform::win::IsSurrogatePairTrailing(c)) { - wchar_t s[2] = {last_wm_char_event_wparam_, c}; - auto str = platform::win::ToUtf8String({s, 2}); - char_event_.Raise(str); - log::Debug("WinNativeWindow: char event, charactor is {}", str); - } else { - wchar_t s[1] = {c}; - auto str = platform::win::ToUtf8String({s, 1}); - char_event_.Raise(str); - log::Debug("WinNativeWindow: char event, charactor is {}", str); - } -} - void WinNativeWindow::OnActivatedInternal() {} void WinNativeWindow::OnDeactivatedInternal() {} |