aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--demos/input_method/main.cpp2
-rw-r--r--include/cru/platform/native/input_method.hpp2
-rw-r--r--include/cru/platform/native/window.hpp1
-rw-r--r--include/cru/win/native/input_method.hpp3
-rw-r--r--include/cru/win/native/window.hpp8
-rw-r--r--include/cru/win/string.hpp2
-rw-r--r--src/win/native/input_method.cpp27
-rw-r--r--src/win/native/window.cpp21
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() {}