-
-
Notifications
You must be signed in to change notification settings - Fork 959
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cursor show error when use <shift> to switch english input from chinese input (pinyin) #4541
Comments
This one has been on my list for a while. I can reproduce this issue in other input methods. |
Thank you for reply. |
@page-down Shouldn't this be already handled in keyDown where it tests if the NSTextInputContext has been changed? |
NSTextInputContext? Not sure if I follow... No, the input source was not changed, this state transition occurred in the IME itself. It looks like the input method initiated the text cancellation. |
Ah then you just need to see which selector is called for that, and |
glfw/cocoa_window.m - (void)insertText: ...
{
// ...
if ([self hasMarkedText]) {
[self unmarkText];
marked_text_cleared_by_insert = true;
// <---- HERE
GLFWkeyevent dummy = {.action = GLFW_RELEASE, .ime_state = GLFW_IME_PREEDIT_CHANGED};
_glfwInputKeyboard(window, &dummy);
} However, it seems that there is no chance to reach the following location. The shift key does not reach keydown. - (void)keyDown:(NSEvent *)event
{
// ...
bool bracketed_ime = false;
if (!window->ns.deadKeyState) {
if ([self hasMarkedText]) {
if (!marked_text_cleared_by_insert) {
UPDATE_PRE_EDIT_TEXT;
} else bracketed_ime = true; // <----- any chances?
// ...
if (bracketed_ime) {
// insertText followed by setMarkedText
CLEAR_PRE_EDIT_TEXT; // <----- any chances?
}
|
Why is it not reaching that line? Where is it returning? line 1184? |
The modifier keys doesn't reach the keyDown, right? There will be no return because it is not entered. The insertText is executed directly. |
Ah right its a modifier key, so have a check for this inserted in flagsChanged. If marked text goes from existing to cleared send a clear preedit event. |
Or is inserttext called before or after flagschanged? Yeah it must be since we dont call interpretkeyevents in flagschanged. So I guess this is unfixable unless we can figure out how cocoa calls flagschanged and check markedtext before it is called. |
flagsChanged and then insertText. If the text cannot be inserted, at least the pre edit text can be cleaned up. |
On Wed, Jan 19, 2022 at 01:38:39AM -0800, page-down wrote:
flagsChanged and then insertText.
If the text cannot be inserted, at least the pre edit text can be cleaned up.
OK so maybe set a flag in the window object that indicates to
insertText that it is being called from keyDown. When it is not called
form keyDown (aka that flag is not set, and the text is removed, send a
clear pre-edit message to kitty).
|
I tried it and this clears the preedit text properly, need to deal with modifier keys like num_lock. But for now, it can only be cleared, and maybe after that we'll see if we can insert text. Since I know some input methods use modifier keys to select candidates. Also found two issues that I haven't had time to go through in detail. Enter the text, press Tab, and the input is cancelled, but the preedit text is still there.
Enter the text and press F1, the preedit text is cleared, however, it is still in the input method state.
|
these are both the same issue, look at line 1184. Basically in order to |
One possibility is to override activate/deactivate in GLFWTextInputContext and keep track of whether it is active or not with that. |
I'm not sure if this concept is present in macOS's input method framework, perhaps another way of thinking is needed.
I tested both of them and they are basically independent of the input method state (US/ABC is also an input source, so is it equivalent to being active all the time?) The activation state changes with the window focus. In fact, insertText is also triggered when the window loses focus, so the problem that needs to be solved at this point is no longer related to the key event. I tested the behavior of iTerm2, after entering |
I did the test again and found that different input methods behave differently. The way we currently handle it (for windows losing focus) is something that needs to be improved. There are input methods that will output the unconfirmed text in other programs (iTerm2) immediately after losing focus. For some input methods, the pre edit state is maintained after switching focus, and you can continue typing after switching back. However, in kitty, the current way of handling it is to just clean up the pre edit text, causing the overlay text to disappear when the focus comes back. From a personal point of view, I am more care about the accurate response to keyboard events, while the input method just needs to be usable under normal circumstances (e.g., back to the topic, being able to press shift and response). |
I really dont care about handling focus change. As for keys that dont produce text, if there is no way to query the state of the IME system then I dont see how we can handle them. I suppose one could track the selector the ime system calls and if it doesnt call any, then clear pre-edit. This will work if backspace/delete call a selector. |
I tried the latest changes and still have the problem.
if (!in_key_down && !_glfw.ns.text[0]) In this case, _glfw.ns.text has text content. EDIT:
Sorry, I tested it before with |
The logic of keyDown is to wait for insertText to be called after interpretKeyEvents is called, and then send the text via glfw keyevent. // keyDown:
glfw_keyevent.text = _glfw.ns.text;
glfw_keyevent.ime_state = GLFW_IME_NONE;
add_alternate_keys(&glfw_keyevent, event);
_glfwInputKeyboard(window, &glfw_keyevent); However, in this case, the last part of the keyDown code will not be executed after insertText, so can it be sent directly? |
Hmm... I tried the above commit.
|
What is the contents of utf8? |
From your previous post it looks like utf8 is the letter k? Pressing shift id supposed to insert the letter k? |
This is not making any sense to me. Can you give me a set of steps to reproduce the problem with some builtin IME available on macOS |
Yes, it's the According to my understanding, after the input method is canceled ( Also I was recently looking at whether there is a relevant implementation in QT and came across the following code and wondered if it would help.
I can give you the configuration example for RIME Squirrel. default.custom.yaml patch:
schema_list:
- schema: table-auto-select
ascii_composer/switch_key:
# commit_text - the selected candidate text
# commit_code - the code
# clear - cancel and clear all without commit
Shift_L: commit_code
key_binder/bindings: {}
switcher/hotkeys: {} The rest is the same as the previous one. After changing the configuration file, you need to click the input method icon in the menu bar and select Type k and press shift. |
The following is the relevant input method controller implementation, the rest are not important. https://github.com/rime/squirrel/blob/master/SquirrelInputController.m @implementation SquirrelInputController { ... }
- (BOOL)handleEvent:(NSEvent*)event client:(id)sender
{
// Return YES to indicate the the key input was received and dealt with.
// Key processing will not continue in that case. In other words the
// system will not deliver a key down event to the application.
// Returning NO means the original key down will be passed on to the client.
// ...
switch (event.type) {
case NSEventTypeFlagsChanged: {
if (_lastModifier == modifiers) {
handled = YES;
break;
// ...
return handled;
}
-(void)deactivateServer:(id)sender
{
//...
[self commitComposition:sender];
}
-(void)commitComposition:(id)sender
{
//...
// [self commitString: @(raw_input)];
// The code in commitString is:
[_currentClient insertText:string
replacementRange:NSMakeRange(NSNotFound, 0)];
_preeditString = @"";
} |
Hmm, well in that case the only way to fix this is to actually implement storage of the markedText and commit when the marking is removed. That will neccessitate a rewrite of a whole lot of keyDown and insertText and various other things. Something for a rainy day. |
I committed a fix with a slightly different approach. See if it works, |
No problem, I can help test it.
I think it's indeed as you said that the key event input needs to be sorted out. Since the input source is actually turned on the whole time and only works properly after letting the input method handle everything. The problem still exists with the following logs.
|
why is CLEAR_PRE_EDIT_TEXT not being called in flagsChanged for you? Is |
After |
But in your log insertText is being called. Can you use a debugger to figure out what is the call stack that is calling it? |
Is it related to the following logs? I'm still working on other things and need a little time.
|
Yes basically, I expect the call to handleEvent to in turn call inserttext which should set marked_text_cleared_by_insert. From your log it looks like insertText is called by something else, unless I am reading the log wrong. And no rush take your time, I am anyway going to be ending for the day soon. |
OK, so I'll send the stack trace first.
|
Ah, its being called by the event loop not by handleEvent, so this approach wont work. |
Try 655a5a2 |
Finally, the pre edit text can be cleared (sometimes only), even though the text is not inserted into the child.
The following is the log when it is not working.
|
And another: f21ddae |
After a very short time of testing, the preedit text can be cleaned up and no noticeable problems are found. Except the following doesn't seem to work.
|
I thought my commit took care of that. Check what's happening in |
if (size == SEND_TEXT_TO_CHILD) {
// ...
} else if (size > 0) {
// ...
} else {
debug("ignoring ...");
}
size: 0 ev->text: k It seems that EDIT3: encode_key: EDIT4: Try the following code, I can insert the text now. GLFWkeyevent glfw_keyevent = {.text=_glfw.ns.text, .ime_state=GLFW_IME_COMMIT_TEXT}; EDIT5: I see some REPEAT during normal input.
|
Since we're already dealing with IME issues, here's the last one I know of, for now.
|
size: 0 ev->text: k
It seems that `k` cannot be encoded?
|
Sorry, I edited the above reply. Is it possible to use: GLFWkeyevent glfw_keyevent = {.text=_glfw.ns.text, .ime_state=GLFW_IME_COMMIT_TEXT}; At this point, when using the modifier key, it clears the preedit text and inserts the text properly, and no other problems were found except for the REPEAT key event mentioned above. |
On Sat, Jan 22, 2022 at 06:42:22AM -0800, page-down wrote:
>> size: 0 ev->text: k It seems that `k` cannot be encoded?
>
> `ff836a8`
Sorry, I edited the above reply. Is it possible to use:
```objc
GLFWkeyevent glfw_keyevent = {.text=_glfw.ns.text, .ime_state=GLFW_IME_COMMIT_TEXT};
```
Yes that should be fine, feel free to send a PR.
|
Never mind I committed the change. |
I believe this is fixed now, closing. |
@kovidgoyal To Reproduce:
|
Describe the bug
I often use shift to cancel the pre edit with chinese intput method.
In kitty, the cursor block will show error, but in iTerm2, it will use the pre edit word.
ps: i use the sogou app
Screenshots
In kitty
2022-01-19.2.20.53.mov
In iTerm2
2022-01-19.2.24.51.mov
Environment details
Additional context
The same problem when i use
kitty --config NONE
The text was updated successfully, but these errors were encountered: