macOS: do not pass input events while having marked text
fix chinese input method backspacing issue macOS: Set pre-edit text for IME macOS: implement glfwPlatformUpdateIMEState set firstRectForCharacterRange correctly macOS: update IME position on each input macOS: use float instead of int for updateIMEState minor fix macOS: ignore marked text on deadkey fixes german keyboard input macOS: convert markedRect to screen coord
This commit is contained in:
parent
eaba3cff0b
commit
e36e44ab3a
@ -529,6 +529,7 @@ static GLFWapplicationshouldhandlereopenfun handle_reopen_callback = NULL;
|
||||
_GLFWwindow* window;
|
||||
NSTrackingArea* trackingArea;
|
||||
NSMutableAttributedString* markedText;
|
||||
NSRect markedRect;
|
||||
}
|
||||
|
||||
- (instancetype)initWithGlfwWindow:(_GLFWwindow *)initWindow;
|
||||
@ -545,6 +546,7 @@ static GLFWapplicationshouldhandlereopenfun handle_reopen_callback = NULL;
|
||||
window = initWindow;
|
||||
trackingArea = nil;
|
||||
markedText = [[NSMutableAttributedString alloc] init];
|
||||
markedRect = NSMakeRect(0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
[self updateTrackingAreas];
|
||||
[self registerForDraggedTypes:@[NSPasteboardTypeFileURL]];
|
||||
@ -815,6 +817,8 @@ is_ascii_control_char(char x) {
|
||||
const int mods = translateFlags(flags);
|
||||
const int key = translateKey(scancode, GLFW_TRUE);
|
||||
const GLFWbool process_text = !window->ns.textInputFilterCallback || window->ns.textInputFilterCallback(key, mods, scancode, flags) != 1;
|
||||
const bool previous_has_marked_text = [self hasMarkedText];
|
||||
[self unmarkText];
|
||||
_glfw.ns.text[0] = 0;
|
||||
if (!_glfw.ns.unicodeData) {
|
||||
// Using the cocoa API for key handling is disabled, as there is no
|
||||
@ -859,6 +863,20 @@ is_ascii_control_char(char x) {
|
||||
if (is_ascii_control_char(_glfw.ns.text[0])) _glfw.ns.text[0] = 0; // don't send text for ascii control codes
|
||||
debug_key(@"text: %s glfw_key: %s\n",
|
||||
format_text(_glfw.ns.text), _glfwGetKeyName(key));
|
||||
debug_key(@"marked text: %@", markedText);
|
||||
if (!window->ns.deadKeyState) {
|
||||
if ([self hasMarkedText]) {
|
||||
_glfwInputKeyboard(window, key, scancode, GLFW_PRESS, mods,
|
||||
[[markedText string] UTF8String], 1); // update pre-edit text
|
||||
} else if (previous_has_marked_text) {
|
||||
_glfwInputKeyboard(window, key, scancode, GLFW_PRESS, mods,
|
||||
NULL, 1); // clear pre-edit text
|
||||
}
|
||||
if (([self hasMarkedText] || previous_has_marked_text) && !_glfw.ns.text[0]) {
|
||||
// do not pass keys like BACKSPACE while there's pre-edit text, let IME handle it
|
||||
return;
|
||||
}
|
||||
}
|
||||
_glfwInputKeyboard(window, key, scancode, GLFW_PRESS, mods, _glfw.ns.text, 0);
|
||||
}
|
||||
|
||||
@ -997,6 +1015,28 @@ is_ascii_control_char(char x) {
|
||||
[[markedText mutableString] setString:@""];
|
||||
}
|
||||
|
||||
void _glfwPlatformUpdateIMEState(_GLFWwindow *w, int which, int a, int b, int c, int d) {
|
||||
[w->ns.view updateIMEStateFor: which left:(CGFloat)a top:(CGFloat)b cellWidth:(CGFloat)c cellHeight:(CGFloat)d];
|
||||
}
|
||||
|
||||
- (void)updateIMEStateFor:(int)which
|
||||
left:(CGFloat)left
|
||||
top:(CGFloat)top
|
||||
cellWidth:(CGFloat)cellWidth
|
||||
cellHeight:(CGFloat)cellHeight
|
||||
{
|
||||
left /= window->ns.xscale;
|
||||
top /= window->ns.yscale;
|
||||
cellWidth /= window->ns.xscale;
|
||||
cellHeight /= window->ns.yscale;
|
||||
debug_key(@"updateIMEState: %f, %f, %f, %f\n", left, top, cellWidth, cellHeight);
|
||||
const NSRect frame = [window->ns.view frame];
|
||||
const NSRect rectInView = NSMakeRect(left,
|
||||
frame.size.height - top - cellHeight,
|
||||
cellWidth, cellHeight);
|
||||
markedRect = [window->ns.object convertRectToScreen: rectInView];
|
||||
}
|
||||
|
||||
- (NSArray*)validAttributesForMarkedText
|
||||
{
|
||||
return [NSArray array];
|
||||
@ -1016,8 +1056,7 @@ is_ascii_control_char(char x) {
|
||||
- (NSRect)firstRectForCharacterRange:(NSRange)range
|
||||
actualRange:(NSRangePointer)actualRange
|
||||
{
|
||||
const NSRect frame = [window->ns.view frame];
|
||||
return NSMakeRect(frame.origin.x, frame.origin.y, 0.0, 0.0);
|
||||
return markedRect;
|
||||
}
|
||||
|
||||
- (void)insertText:(id)string replacementRange:(NSRange)replacementRange
|
||||
|
||||
2
glfw/input.c
vendored
2
glfw/input.c
vendored
@ -919,7 +919,7 @@ GLFWAPI void glfwUpdateIMEState(GLFWwindow* handle, int which, int a, int b, int
|
||||
assert(window != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
#if defined(_GLFW_X11) || defined(_GLFW_WAYLAND)
|
||||
#if defined(_GLFW_X11) || defined(_GLFW_WAYLAND) || defined(_GLFW_COCOA)
|
||||
_glfwPlatformUpdateIMEState(window, which, a, b, c, d);
|
||||
#else
|
||||
(void)window; (void)which; (void)a; (void)b; (void)c; (void)d;
|
||||
|
||||
@ -143,6 +143,11 @@ on_key_input(int key, int scancode, int action, int mods, const char* text, int
|
||||
} else debug("committed pre-edit text: (null)\n");
|
||||
return;
|
||||
case 0:
|
||||
// for macOS, update ime position on every key input
|
||||
// because the position is required before next input
|
||||
#if defined(__APPLE__)
|
||||
update_ime_position(global_state.callback_os_window, w, screen);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
debug("invalid state, ignoring\n");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user