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;
|
_GLFWwindow* window;
|
||||||
NSTrackingArea* trackingArea;
|
NSTrackingArea* trackingArea;
|
||||||
NSMutableAttributedString* markedText;
|
NSMutableAttributedString* markedText;
|
||||||
|
NSRect markedRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)initWithGlfwWindow:(_GLFWwindow *)initWindow;
|
- (instancetype)initWithGlfwWindow:(_GLFWwindow *)initWindow;
|
||||||
@ -545,6 +546,7 @@ static GLFWapplicationshouldhandlereopenfun handle_reopen_callback = NULL;
|
|||||||
window = initWindow;
|
window = initWindow;
|
||||||
trackingArea = nil;
|
trackingArea = nil;
|
||||||
markedText = [[NSMutableAttributedString alloc] init];
|
markedText = [[NSMutableAttributedString alloc] init];
|
||||||
|
markedRect = NSMakeRect(0.0, 0.0, 0.0, 0.0);
|
||||||
|
|
||||||
[self updateTrackingAreas];
|
[self updateTrackingAreas];
|
||||||
[self registerForDraggedTypes:@[NSPasteboardTypeFileURL]];
|
[self registerForDraggedTypes:@[NSPasteboardTypeFileURL]];
|
||||||
@ -815,6 +817,8 @@ is_ascii_control_char(char x) {
|
|||||||
const int mods = translateFlags(flags);
|
const int mods = translateFlags(flags);
|
||||||
const int key = translateKey(scancode, GLFW_TRUE);
|
const int key = translateKey(scancode, GLFW_TRUE);
|
||||||
const GLFWbool process_text = !window->ns.textInputFilterCallback || window->ns.textInputFilterCallback(key, mods, scancode, flags) != 1;
|
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;
|
_glfw.ns.text[0] = 0;
|
||||||
if (!_glfw.ns.unicodeData) {
|
if (!_glfw.ns.unicodeData) {
|
||||||
// Using the cocoa API for key handling is disabled, as there is no
|
// 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
|
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",
|
debug_key(@"text: %s glfw_key: %s\n",
|
||||||
format_text(_glfw.ns.text), _glfwGetKeyName(key));
|
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);
|
_glfwInputKeyboard(window, key, scancode, GLFW_PRESS, mods, _glfw.ns.text, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -997,6 +1015,28 @@ is_ascii_control_char(char x) {
|
|||||||
[[markedText mutableString] setString:@""];
|
[[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
|
- (NSArray*)validAttributesForMarkedText
|
||||||
{
|
{
|
||||||
return [NSArray array];
|
return [NSArray array];
|
||||||
@ -1016,8 +1056,7 @@ is_ascii_control_char(char x) {
|
|||||||
- (NSRect)firstRectForCharacterRange:(NSRange)range
|
- (NSRect)firstRectForCharacterRange:(NSRange)range
|
||||||
actualRange:(NSRangePointer)actualRange
|
actualRange:(NSRangePointer)actualRange
|
||||||
{
|
{
|
||||||
const NSRect frame = [window->ns.view frame];
|
return markedRect;
|
||||||
return NSMakeRect(frame.origin.x, frame.origin.y, 0.0, 0.0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)insertText:(id)string replacementRange:(NSRange)replacementRange
|
- (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);
|
assert(window != NULL);
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT();
|
_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);
|
_glfwPlatformUpdateIMEState(window, which, a, b, c, d);
|
||||||
#else
|
#else
|
||||||
(void)window; (void)which; (void)a; (void)b; (void)c; (void)d;
|
(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");
|
} else debug("committed pre-edit text: (null)\n");
|
||||||
return;
|
return;
|
||||||
case 0:
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
debug("invalid state, ignoring\n");
|
debug("invalid state, ignoring\n");
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user