-
Notifications
You must be signed in to change notification settings - Fork 28
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 rework #170
Cursor rework #170
Conversation
Looks like you're now appending the newline cluster to the previous line rather than waiting to append it to the next line. We'll need to test, but I suspect that means that the bug fixed in #163 won't be present. The key thing not being which line the newline cluster ends up in, but that the cluster is "committed" eagerly rather than deferred to the next iteration of the loop (the fix in #163 was handling that deferred cluster commit handling the case that the next iteration of the loop was an inline box (and thus went down a different code path)). If you wanted to keep the "newline is at the start of the following line" behaviour then think you could probably just reverse the |
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've left some review comments on the layout code that I'm familiar with. I haven't reviewed the selection code which I don't fully understand yet.
let whitespace = cluster.info().whitespace(); | ||
let is_newline = whitespace == Whitespace::Newline; | ||
let is_space = whitespace.is_space_or_nbsp(); | ||
let boundary = cluster.info().boundary(); |
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.
Can you explain why you have switched from Boundary::Mandatory
to Whitespace::Newline
here? What (if anything) is the difference?
I'm assuming the reason you (can safely) check Boundary::Line
before checking is_newline
is because a newline will never be a Boundary::Line
(it will always be a Boundary::Mandatory
)? If this is not the case then I think you need to invert the order in which you check those conditions.
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.
The full explanation is at #132 (comment)
tldr; Unicode LBA specifies a break after the newline and a trailing newline doesn’t have a following cluster so we lose that information.
Re check order: good question. I’m going to assume that a newline sequence is not marked as a break opportunity because the code appears to work as is :)
This was initially done to force a line to be created at the end of the layout when the last character was a newline. This didn’t really work anyway and I agree that it’s more intuitive (and correct!) to keep the newline attached to the line it ends. |
|
Ah, I see. We won’t have a downstream cluster at the end of the text. I’ll push a fix for this in a bit. |
- correct condition for empty text in shaping - compute actual layout height based on line max coordinates - try to handle end of text conditions in AccessKit methods
Just tried the latest push with a screen reader. If I go to the end of the default text in vello_editor with Ctrl+End, then the accessible selection is where it should be. But if I then press Enter to start a new blank line at the end, then the accessible selection is on the previous line, after the hard line break, rather than on the new, blank line. |
- use from_byte_index in from_accesskit instead of setting index directly to capture correct affinity for trailing newline
This is probably a question of affinity. I pushed an update that might address it. |
No change to the accessibility behavior when inserting a new blank line at the end. |
I can confirm that works. The behaviour seems a tiny bit janky, as it allows both the selections. |
FWIW, Chrome allows both on my machine. |
On my Windows 11 machine both Firefox and Chrome allow both selections. |
Word selection and movement is entirely inconsistent across platforms/editors so I chose a set of behaviors that seemed to make sense. Including space-like “words” in mouse selection was intentional because you cannot otherwise extend the selection into a space without using the keyboard, and as noted, there is precedent for this in Chrome. |
@mwcampbell I pushed a change to add a "phantom" text run to the last empty line. The logic is a bit janky but I believe (hope?) the mapping to AccessKit is correct. |
Replaces PlainEditor::active_text with PlainEditor::selected_text for cut/copy
The phantom run for a blank line at the end seems to work correctly. I can find just one more accessibility problem: if the text is entirely empty, there's a phantom run, but |
Thanks Matt. I added a special case for that. Assuming this is okay for accessibility, I don't plan on making any further changes unless new issues are raised by others. |
The AccessKit integration now looks good to me. |
Great! I appreciate your patience and your help with testing. |
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've done some testing of the vello_editor
example, and this seems to resolve all of the robustness issues around newlines I was seeing before. I've also updated Blitz to use this branch, which seems to work well.
Thanks Nico. I’m going to go ahead and merge this. If there are further issues they can be addressed in a follow up. |
I've had to add a hack to workaround a (new)? Parley bug where an empty initial text causes a crash Note that later setting the text to be empty does not reproduce the crash
The upstream PR has now been merged: linebender/parley#170 I've had to add a hack to workaround linebender/parley#186. This occurs because of the first pass of layout with zero available area.
This is a draft because some functionality (mostly around word/line selection) is still missing. I also commented out the fix from #163 because the
skip_mandatory_break
flag is now gone and I haven't dug into the logic from that PR.Submitting this now so that people can take a look and see if it fixes some of the known bugs, particularly around newline handling.
note: #166 should probably land first