Skip to content
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

Add basic keyboard shortcuts #567

Merged
merged 1 commit into from
Oct 1, 2024

Conversation

tomasmatus
Copy link
Member

@tomasmatus tomasmatus commented Jun 18, 2024

fixes: #451

For now this adds following keybindings:

  • alt + arrow up: go up one directory
  • alt + arrow down: activate selected item, enter directory
  • Enter: activate selected item, enter directory
  • ctrl + shift + L: focus files breadcrumbs to manually edit it
  • F2: rename selected file
  • shift + N: create new directory
  • ctrl + c: copy file/directory
  • ctrl + v: paste file/directory
  • ctrl + a: select all files

Alt + arrow left/right is already supported by cockpit files browser
history.


Files: basic keyboard shortcuts

Screen Shot 2024-10-01 at 09 33 45

b.wait_text(".breadcrumb-button:nth-of-type(5)", "anotherdir")

# Go back in history twice
# b.key("ArrowLeft", repeat=2, modifiers=1)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jelly do you have any idea what might be happening here? the b.key(...) doesn't seem to work when running this test in chromium but everything works fine in firefox

Copy link
Member

@jelly jelly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The biggest thing which is missing (and should be added after discussion) is a way to view the keybindings. We should have a dropdownitem in the main kebab + modal for that.

  • Moving up / out of a directory key bindings seems a little bit obscure to me.
  • F2 for rename, this feels so random? Which applications have this as default?

@tomasmatus
Copy link
Member Author

a way to view the keybindings

yes, I will add this when we are more settled with shortcuts

F2 for rename, this feels so random? Which applications have this as default?

both dolphin and nautilus

case "N":
if (!e.ctrlKey && !e.altKey) {
Dialogs.show(
<CreateDirectoryModal currentPath={currentPath} />
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ooops, looks like this slipped my mind!

@tomasmatus
Copy link
Member Author

Turns out ctrl + a to select all files breaks using the same shortcut in the filtering text input

@garrett
Copy link
Member

garrett commented Jun 20, 2024

The biggest thing which is missing (and should be added after discussion) is a way to view the keybindings. We should have a dropdownitem in the main kebab + modal for that.

We have mockups for that in the menu and an issue for that already @ #451

What is probably good for a discussion is if we want to override default browser behavior for ctrl + l which focuses the Address Bar to "focus files breadcrumbs to manually edit it" or use the keybind that I set (L aka shift + l).

We have an issue for this already, where I suggested control-shift-L, which aligns with how browsers and file managers use control-L, but adds in the shift as to not stomp on browser behavior: #450

@garrett
Copy link
Member

garrett commented Jun 20, 2024

BTW: Mockup and explanation for keyboard shortcuts reference modal is now @ #451 (comment)

@tomasmatus
Copy link
Member Author

Added a first round of help dialog, I'll play with the css to make keys look fancy later.
image

@garrett
Copy link
Member

garrett commented Jun 25, 2024

I've pushed up my changes to restyle the keyboard shortcuts.

Now, it:

  • looks more like the mockup visually
  • flows when the content is too narrow
  • uses headings
  • reports the accessibility tree properly (previously, the list wasn't being expressed properly and the headings were just text, all due to the list element having content that was not permitted)
  • is reformatted in the JSX so it's easier to understand what's going on, using multiple lines and indentation

@garrett
Copy link
Member

garrett commented Jun 25, 2024

F2 for rename, this feels so random? Which applications have this as default?

both dolphin and nautilus

It's also the way you rename in Explorer, in Windows.

Meanwhile, for renaming, macOS uses... enter. (Yes, I'm not kidding.) Everywhere else, including browsers on a focused area or widget, enter activates. But in Finder, it's to rename.

F2 makes more sense than enter, and it's a keyboard shortcut most people are already familiar with if they use keyboard shortcuts in file managers.

@tomasmatus tomasmatus force-pushed the basic_keybinds branch 2 times, most recently from c3d4aa3 to 1745428 Compare June 27, 2024 09:39
Copy link
Member

@jelly jelly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is one big issue, when I browse to a directory where I get a permission denied or a non-existant directory then the keybindings no longer work as the eventhandlers are only added on "valid folders".

src/files-card-body.tsx Show resolved Hide resolved
test/check-application Outdated Show resolved Hide resolved
src/files-breadcrumbs.tsx Outdated Show resolved Hide resolved
@tomasmatus tomasmatus force-pushed the basic_keybinds branch 2 times, most recently from 2c25a52 to adceb56 Compare August 5, 2024 10:17
src/header.tsx Outdated
const onSelect = (_ev?: React.MouseEvent, itemId?: string | number) => {
if (itemId === "hidden-toggle") {
setShowHidden(prevShowHidden => {
localStorage.setItem("files:showHiddenFiles", !showHidden ? "true" : "false");
return !prevShowHidden;
});
} else if (itemId === "shortcuts-help") {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dw it is tested :)

@tomasmatus tomasmatus force-pushed the basic_keybinds branch 2 times, most recently from eca07b3 to 802c7dd Compare August 13, 2024 07:22
@tomasmatus tomasmatus requested a review from jelly August 19, 2024 07:29
@tomasmatus tomasmatus force-pushed the basic_keybinds branch 2 times, most recently from 0b2424a to 92b7601 Compare September 2, 2024 13:00
@jelly
Copy link
Member

jelly commented Sep 3, 2024

I don't believe that the location of the keyboard shortcuts help is logical here:

image

test/check-application Show resolved Hide resolved
src/header.tsx Outdated
const onSelect = (_ev?: React.MouseEvent, itemId?: string | number) => {
if (itemId === "hidden-toggle") {
setShowHidden(prevShowHidden => {
localStorage.setItem("files:showHiddenFiles", !showHidden ? "true" : "false");
return !prevShowHidden;
});
} else if (itemId === "shortcuts-help") {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Weird hmmm

src/app.tsx Show resolved Hide resolved
@garrett
Copy link
Member

garrett commented Sep 3, 2024

Agreed; the keyboard shortcuts modal is supposed to go in the main menu, not the view menu.

@tomasmatus
Copy link
Member Author

Agreed; the keyboard shortcuts modal is supposed to go in the main menu, not the view menu.

Wasn't that removed? Where should it go then?

image

@tomasmatus
Copy link
Member Author

tomasmatus commented Sep 4, 2024

CI red, fixing in #727

@jelly
Copy link
Member

jelly commented Sep 5, 2024

Agreed; the keyboard shortcuts modal is supposed to go in the main menu, not the view menu.

Wasn't that removed? Where should it go then?

image

@garrett what was the idea/ design here?

@garrett
Copy link
Member

garrett commented Sep 9, 2024

It should go into the menu, which is supposed to be in the place where the menu should be — and that was never in the sidebar. The sidebar never had a menu in any of the mockups at any point in time. The fact that the sidebar has a menu in main is a huge UX bug. (I've pointed this out several times during development, but we haven't moved it as I had an in progress mockup for some time now and haven't had the opportunity to address it properly yet.)

The menu was always supposed to be either global and/or in the toolbar. The current mockups — which I haven't had time to finish yet — have the menu in the toolbar.

The current state of the sidebarless redesign with merged menus looks like this:

image

But it's unfinished, so it's subject to change. And it will change. But the menu position is probably the most solid of this mockup at this point, and the menu items are probably pretty close too.

I basically made a compromise after looking at other file management apps and seeing they have a menu like this too, on Windows, macOS, and KDE. GNOME's is different, as they don't act upon the selection (and rely on a context menu only), but everything else does. Other designs for it have it come after the selected items, which is more proper in the idea of a flow, but non-GNOME file managers, word processors, and all kinds of other apps actually do sometimes change their menus and toolbars (including toolbar icons) based on selection of what comes after it in the UI, so it's OK enough for us to do this too. And it's probably what everyone other than people using GNOME would expect.

I think we'd want to also adjust the context menu to be similar too.

For now, I think the correct solution is to have the opposite of a "follow-up" and make a separate PR that moves the menu from the sidebar to the toolbar (to the right of the upload button) as a first step.


Summary: Move the menu from the sidebar to the toolbar first, then make sure the keyboard shortcuts are in the menu at the bottom.

tomasmatus added a commit to tomasmatus/cockpit-files that referenced this pull request Sep 16, 2024
tomasmatus added a commit to tomasmatus/cockpit-files that referenced this pull request Sep 17, 2024
tomasmatus added a commit to tomasmatus/cockpit-files that referenced this pull request Sep 17, 2024
tomasmatus added a commit to tomasmatus/cockpit-files that referenced this pull request Sep 17, 2024
test/check-application Outdated Show resolved Hide resolved
tomasmatus added a commit to tomasmatus/cockpit-files that referenced this pull request Sep 18, 2024
tomasmatus added a commit to tomasmatus/cockpit-files that referenced this pull request Sep 23, 2024
tomasmatus added a commit to tomasmatus/cockpit-files that referenced this pull request Sep 24, 2024
jelly pushed a commit that referenced this pull request Sep 24, 2024
Copy link
Member

@jelly jelly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good, some minor fixes / suggestions and then I think it's good to land

src/app.tsx Outdated Show resolved Hide resolved
src/files-card-body.tsx Outdated Show resolved Hide resolved
src/files-card-body.tsx Outdated Show resolved Hide resolved
src/header.tsx Outdated Show resolved Hide resolved
test/check-application Outdated Show resolved Hide resolved
test/check-application Show resolved Hide resolved
test/check-application Show resolved Hide resolved
src/menu.tsx Outdated Show resolved Hide resolved
@tomasmatus tomasmatus requested a review from jelly September 25, 2024 13:09
fixes: cockpit-project#451

For now this adds following keybindings:

- `alt + arrow up`: go up one directory
- `alt + arrow down`: activate selected item, enter directory
- `Enter`: activate selected item, enter directory
- `ctrl + shift + L`: focus files breadcrumbs to manually edit it
- `F2`: rename selected file
- `shift + N`: create new directory
- `ctrl + c`: copy file/directory
- `ctrl + v`: paste file/directory
- `ctrl + a`: select all files

Alt + arrow left/right is already supported by cockpit files browser
history.
Comment on lines +158 to +159
return () => {
document.removeEventListener("keydown", onKeyboardNav);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These 2 added lines are not executed by any test.

title={_("Keyboard shortcuts")}
variant={ModalVariant.large}
className="shortcuts-dialog"
onClose={() => dialogResult.resolve()}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This added line is not executed by any test.

const selectedIdx = sortedFiles?.findIndex(file => file.name === firstSelectedName);
const newIdx = selectedIdx < sortedFiles.length - 1
? selectedIdx + 1
: 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This added line is not executed by any test.

const selectedIdx = sortedFiles?.findIndex(file => file.name === firstSelectedName);
const newIdx = selectedIdx > 0
? selectedIdx - 1
: sortedFiles.length - 1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This added line is not executed by any test.

"-R",
...clipboard,
path
]).catch(err => addAlert(err.message, AlertVariant.danger, `${new Date().getTime()}`));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This added line is not executed by any test.

Copy link
Member

@jelly jelly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some small comments and one follow up but let's not let this block this for much longer.

return () => {
document.removeEventListener("keydown", onKeyboardNav);
};
}, []);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dependency array can go

@@ -1174,6 +1177,20 @@ class TestFiles(testlib.MachineCase):
b.wait_not_present(".pf-v5-c-modal-box")
b.wait_visible("[data-item='renamed-foo.txt']")

# Rename file using keyboard shortcut
b.click("[data-item='newfile']")
b.key("\uE032") # F2
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm any reason "F2" doesn't work?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems worth it, let's do it :) But don't block merging on it.

@@ -814,6 +814,9 @@ class TestFiles(testlib.MachineCase):
b.mouse("[data-item='delete2']", "click", ctrlKey=True)
b.wait_visible("[data-item='delete1'].row-selected")
b.wait_visible("[data-item='delete2'].row-selected")
b.focus("#files-card-parent")
# For strange reasons ctrlKey remains pressed after the b.mouse() above (spotted in firefox)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we keep seeing this in the keyboard event, sounds like something we should investigate in Bidi

@jelly jelly merged commit 49de6d0 into cockpit-project:main Oct 1, 2024
25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Keyboard shortcuts (general)
5 participants