-
Notifications
You must be signed in to change notification settings - Fork 13
fix: Allow some things to handle the enter key on read only workspaces #597
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
fix: Allow some things to handle the enter key on read only workspaces #597
Conversation
ae074db to
bd45dd7
Compare
390afaa to
0695cfc
Compare
src/actions/clipboard.ts
Outdated
| this.oldCutShortcut.callback(workspace, e, shortcut, scope); | ||
| if (didCut) { | ||
| this.copyWorkspace = workspace; | ||
| this.copyWorkspace = workspace.isFlyout |
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.
just checking, is this change supposed to be here? it doesn't seem related to the PR title
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.
Whoops, not sure how this slipped in.
src/actions/enter.ts
Outdated
| case Constants.STATE.WORKSPACE: | ||
| // The main workspace may or may not handle it depending on what's | ||
| // selected, so always pass it through to the callback. | ||
| return true; |
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 precondition should really try to give an accurate answer. The keyboard shortcut help display could be depending on the precondition being accurate. Rachel envisions a contextual help where only keyboard shortcuts that would currently do anything are shown.
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.
For some cases there's no API to ask if it would be allowed and some of them we don't even know if it did anything. For example, the Icon.onClick() method doesn't have a return and there's no isClickable() method, but it only opens the mutator if the workspace is editable.
Because of that, it didn't seem like it was worth making the precondition overly complex if we're going to have to handle it anyway, but I'll factor out the logic to check all the known cases.
src/actions/enter.ts
Outdated
| flyoutCursor = this.navigation.getFlyoutCursor( | ||
| workspace.targetWorkspace, | ||
| ); | ||
| if (targetWorkspace.isReadOnly()) return false; |
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.
Do you need to check this again since you're already checking it in the precondition?
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.
Removed. Thanks for catching!
src/actions/enter.ts
Outdated
| } else if (curNode instanceof icons.Icon) { | ||
| curNode.onClick(); | ||
| } | ||
| return true; |
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.
Despite the comment in the precondition, it seems like now we're saying the keyboard shortcut for enter will always be handled regardless of whether the workspace is in read-only mode or not. This doesn't seem correct to me, e.g. the field editors shouldn't open if the workspace is in read-only mode.
Based on #585 and playing with the current mouse behavior for read-only mode, I think only icons should be special cased, and the rest of these should continue not doing anything.
It would be helpful if you can add in the PR descriptions which cases you intended to make interactable in read-only, as then I know if we're on the same page about the intentions which may be different than being on the same page about the actual result of the code (which I may be misreading, for example).
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 problem is we don't know if it was handled or not for all cases, specifically icons which have an on click() method that doesn't return anything. I've added additional return false statements where we do know.
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.
OK, that's fine for icons.
For connections and workspace, I don't think the enter key should do anything in read-only mode, but I think this does actually cause them to do something. I can't tell if you intended them to change behavior and we should discuss that intention, or if that is unintentional, or if I'm wrong and the behavior hasn't changed.
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.
Ah, I'd misunderstood that path. Added a check to shouldHandle for this case.
src/actions/enter.ts
Outdated
| for (const input of block.inputList) { | ||
| for (const field of input.fieldRow) { | ||
| if (field.isClickable() && field.isFullBlockField()) { | ||
| if (field.isFullBlockField()) { |
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 remove this check? if the field isn't clickable, it shouldn't be "enter"able either, I think.
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'd removed it because field.showEditor() calls this.isClickable() before showing the editor so it had seemed redundant. That said, I'm adding it back so that this method returns whether or not it handled the return correctly.
src/actions/enter.ts
Outdated
| if (!curNode) return false; | ||
| if (curNode instanceof Field && !curNode.isClickable()) return false; | ||
| // Returning true is sometimes incorrect for icons, but there's no API to check. | ||
| return true; |
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 is still going to be a behavior change for pressing enter on other cases, if I'm reading this correctly. If the workspace is read-only then pressing enter shouldn't open the toolbox. It doesn't before this change but I think this change will cause it to open because of this precondition + you're not checking it in the callback.
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.
Yes, that was intentional to make it consistent with mouse which still opens the toolbox on click.
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.
err, ignore my previous comment. It's intentional that pressing 't' opens the toolbox on a read only workspace. I've updated it so pressing enter on the ws or a connection won't since that's an insert action.
src/actions/enter.ts
Outdated
| } else if (curNode instanceof icons.Icon) { | ||
| curNode.onClick(); | ||
| } | ||
| return true; |
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.
OK, that's fine for icons.
For connections and workspace, I don't think the enter key should do anything in read-only mode, but I think this does actually cause them to do something. I can't tell if you intended them to change behavior and we should discuss that intention, or if that is unintentional, or if I'm wrong and the behavior hasn't changed.
src/actions/enter.ts
Outdated
| } else if (curNode instanceof icons.Icon) { | ||
| curNode.onClick(); | ||
| } | ||
| return true; |
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.
Also, you shouldn't return true as the default, because if the current node isn't an instance of any of these things (e.g. custom focusable object, or workspace comment), you shouldn't say we've handled the shortcut because we haven't. Those custom objects could register their own shortcut handler for enter and if you return true that could cause theirs to not be executed.
I realize this is the old behavior, but I think that's a bug.
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.
Updated to return false by default and true for each case we handle.
maribethb
left a 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.
lgtm, but it would be helpful if you can make the pr description more informative for future reference when reading the changelog, e.g.:
- Enables creating a workspace cursor ('w' key) while in readonly mode
- Enables enter key to "click" on icons while in readonly mode
- Returns false from the keyboard shortcut callback more often when the shortcut isn't actually handled
Fixes #585
This updates the enter handler to do more selective checks when deciding whether or not to handle an enter key. Also simplifies getState() slightly to remove an unnecessary parameter.
In general, this is aiming to reach parity between mouse and keyboard behavior when on a read-only workspace. Specific changes to behavior:
TODO for RaspberryPiFoundation/blockly#8915
Add additional tests for enter and click with a read-only workspace and ensure both modalities are consistent.