-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Emoji fix #1890
Emoji fix #1890
Conversation
Unfortunately I don't have a good way to test on Windows at the moment. Trying to get access to a remote desktop machine.
Looking into it, it seems to work sometimes 🤔 |
@@ -26,6 +26,11 @@ | |||
resolved "https://registry.yarnpkg.com/@types/chai/-/chai-3.5.2.tgz#c11cd2817d3a401b7ba0f5a420f35c56139b1c1e" | |||
integrity sha1-wRzSgX06QBt7oPWkIPNcVhObHB4= | |||
|
|||
"@types/dom-inputevent@^1.0.3": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be undone since we're not using anymore
*/ | ||
export interface IInputEvent { | ||
readonly data?: string; | ||
readonly inputType?: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's missing from the type probably because support is bad (no Firefox), do you know why it appears to work on Firefox despite this? https://developer.mozilla.org/en-US/docs/Web/API/InputEvent/inputType#Browser_compatibility
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Tyriar The data
attribute is not supported on Firefox. As per my previous comment, inputting emojis somewhat works with Firefox even without the code on this branch: #469 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting. I'll run it with the debugger to understand what's happening on Firefox
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did a bit of investigation on Firefox:
- An alternative to
data
is to useevent.target.value
but only if we're clearing thetextarea
on every change - Firefox positioning of the Emoji popup is buggy in that, if you move the
textarea
around, the emoji popup's position (later, when it shows) will use the previous position of the textarea. A work-around I found is to manually settextarea.value
to something (doesn't matter what), which seems to force firefox to recalculate the position used for emoji popup. Seems like a cache invalidation bug. - Firefox treats emoji input as composition while chrome doesn't 🤷♂️
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Oh, and finally, and this might be a deal breaker, there's no
inputType
on Firefox, which we're using to detect when text is inserted vs. when text is pasted. There might be a way to work around this, by treating it as a composition but I haven't looked deeper into it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we can't easily do it reliably on Firefox, I think at least doing it on Chrome would definitely be an improvement.
// https://stackoverflow.com/questions/30757193/ | ||
// For a complete list of all assigned codepoints, go to: | ||
// https://unicode.org/Public/emoji/11.0/emoji-data.txt | ||
export function isEmoji(str: string): boolean { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's move this into CharWidth.ts, this will later be renamed to Unicode*.ts so i think it makes sense to live there.
if (!this._isComposing) { | ||
return; | ||
} | ||
|
||
if (this._terminal.buffer.isCursorInViewport) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did you need to remove this? I don't think it's meant to move when composing (after it becomes visible)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure I follow. If that were the case, shouldn't the if
be if (this._isComposing)
. My understanding is that this if
avoids unnecessarily moving the textarea
when is not needed (not composing anything), but I might be wrong 😝
The idea here is that we need a textarea
to follow the cursor at all times so that the emoji popup shows at the right position (right under the text area).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thinking about this a bit more, it might be better to move the positioning of the textarea
to Terminal.ts
since it's not a composition thing anymore, and we wouldn't be moving the composition view unnecessarily (which I think is what you meant initially)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function is only meant to do anything after compositionstart
and before compositionend
, I think you're right that maybe this should be moved out.
// For a complete list of all assigned codepoints, go to: | ||
// https://unicode.org/Public/emoji/11.0/emoji-data.txt | ||
export function isEmoji(str: string): boolean { | ||
if (str.codePointAt === undefined) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add:
// TODO: Remove when IE11 support is dropped
* There's a @types/dom-inputevent but at the moment it's outdated and missing | ||
* some properties (e.g. inputType). So in the meantime we're using this instead | ||
*/ | ||
export interface IInputEvent { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's call this IDomInputEvent
to be clear as IKeyboardEvent
above is an xterm.js thing
@jerch do you know why if you press space twice after inserting an emoji a This even happens on master when you paste an emoji |
Ping @juancampa, you'll have difficulty keeping this page up to date in Hyper if it doesn't get merged in |
@@ -206,11 +202,13 @@ export class CompositionHelper { | |||
// Sync the textarea to the exact position of the composition view so the IME knows where the | |||
// text is. | |||
const compositionViewBounds = this._compositionView.getBoundingClientRect(); | |||
const width = Math.max(compositionViewBounds.width, this._terminal.charMeasure.width); | |||
const height = Math.max(compositionViewBounds.height, this._terminal.charMeasure.height); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm sure these two lines are wrong.
It will cause bug totally unrelated with emoji.
I have tested it in my environment.
Hope you can reconsider it.
Maybe we need Math.min
or something?
Closing off since this needed a bunch of changes and has diverged a lot. A new attempt at fixing should probably start on a fresh branch. |
Problems
There were multiple problems with emoji
Solutions
input
event, only for emoji handling. Also, the textarea needs to have alineheight > 0
for this event to fire, at least in Chromium.Testing
IE (support dropped)