I’m having the same issue with a german keyboard on Mac. “Cmd + ,” should open an unordered list. In some instances it opens the Anki preferences instead. I realised that this doesn’t happen as long as i avoid clicking on the Anki main-window when adding cards and instead only use the Anki Add-window. However if i click on the main-window once, “Cmd + ,” will open Anki preferences until i close the Add-window and open another Add-window by clicking on “Add” in the main-window. Sorry if this is confusing but i don’t know the correct terminology for the two windows.
@nick5 & @Ankiuser7: Those are exactly the problems I mentioned above
@Anon_0000 Cheers! If you need any more information (e.g., effects of a shortcut pressed), or if you write a fix and it has to be tested on a Mac, I will happily do that. Just hit me up.
I got my problem sorted out and want to give a little bit more info here into what I did so far.
Details
- First, we know that not all keyboard shortcuts are working in the add cards dialog.
- E.g. on my machine (german nonstandard qwertz keyboard) the intendation shortcut doesn’t work.
- So I looked at the editor code
ts/editor/editor-toolbar/BlockButtons.svelte
, which defines the shortcut like so:
const outdentKeyCombination = "Control+Shift+,";
function outdentListItem() {
if (getListItem(document.activeElement!.shadowRoot!)) {
execCommand("outdent");
} else {
alert("Indent/unindent currently only works with lists.");
}
}
const indentKeyCombination = "Control+Shift+.";
function indentListItem() {
if (getListItem(document.activeElement!.shadowRoot!)) {
execCommand("indent");
} else {
alert("Indent/unindent currently only works with lists.");
}
}
onMount(() => {
registerShortcut((event: KeyboardEvent) => {
preventDefault(event);
indentListItem();
}, indentKeyCombination);
registerShortcut((event: KeyboardEvent) => {
preventDefault(event);
outdentListItem();
}, outdentKeyCombination);
});
- We can see it calls
registerShortcut()
which is defined ints/lib/ts/tslib/shortcuts.ts
. - This then calls
check(event)
which in turn callscheckKey()
. - This function initially looks like this:
function checkKey(event: KeyboardEvent, key: number): boolean {
// avoid deprecation warning
const which = event["which" + ""];
return which === key;
}
- but I modified it to show me more info (if anki is run from the terminal and the add cards dialog is opened, pressing any key will log info):
function checkKey(event: KeyboardEvent, key: number): boolean {
// avoid deprecation warning
const which = event["which" + ""];
console.log("############## which === key", which === key);
console.log("############## which", which);
console.log("############## key", key);
console.log("############## event.key", event.key);
console.log("############## event.ctrlKey", event.ctrlKey);
console.log("############## event.shiftKey", event.shiftKey);
console.log("##############");
return which === key;
}
- Here’s example output of it (I pressed the Control key.):
JS info /_anki/js/editor.js:97041 ############## which === key false
JS info /_anki/js/editor.js:97042 ############## which 17
JS info /_anki/js/editor.js:97043 ############## key 84
JS info /_anki/js/editor.js:97044 ############## event.key Control
JS info /_anki/js/editor.js:97045 ############## event.ctrlKey true
JS info /_anki/js/editor.js:97046 ############## event.shiftKey false
JS info /_anki/js/editor.js:97047 ##############
- Altough event.which is deprecated it still correctly shows
17
, which corresponds to the Control key. It doesn’t seem to work with Shift+. though (which on my keyboard produces a :):
JS info /_anki/js/editor.js:97041 ############## which === key false
JS info /_anki/js/editor.js:97042 ############## which 16
JS info /_anki/js/editor.js:97043 ############## key 84
JS info /_anki/js/editor.js:97044 ############## event.key Shift
JS info /_anki/js/editor.js:97045 ############## event.ctrlKey false
JS info /_anki/js/editor.js:97046 ############## event.shiftKey true
JS info /_anki/js/editor.js:97047 ##############
JS info /_anki/js/editor.js:97041 ############## which === key false
JS info /_anki/js/editor.js:97042 ############## which 186
JS info /_anki/js/editor.js:97043 ############## key 66
JS info /_anki/js/editor.js:97044 ############## event.key :
JS info /_anki/js/editor.js:97045 ############## event.ctrlKey false
JS info /_anki/js/editor.js:97046 ############## event.shiftKey true
186
corresponds to ; not :. But, those keys are on the same key on an us qwerty keyboard (also see this thorough keyboard info).
Conclusion
After searching a bit on the internet I found that that’s a common problem with web apps and that there’s a few workarounds:
- Don’t use special characters in shortcuts (like /).
- Provide alternative shortcuts if 1. cannot easily be changed (without upsetting users).
- Allow users to customize shortcuts.
- Maybe use a library like Mousetrap (in conjunction with the points above).
But apparently it’s not really possible to just make the current shortcuts work on all layouts.
Maybe we can convince dae to accept alternative shortcuts or to integrate the addon for every shortcut anki has.
sounds great
Thanks @Anon_0000 for all the work you did put into this!
Correct my if I’m wrong, but your debug tool proved that upon pressing Shift + .
, which on our German QWERTZ keyboard should produce :
, the Anki checkKey
function recognizes the character code 186
, which corresponds to ;
instead of the :
we want to have Anki recognize.
As you correctly pointed out, and we already stated earlier in this thread, the which
property of KeyboardEvent is deprecated. We shouldn’t use this anyways.
Now, to have the keyboard shortcuts work like they are labelled, we could change the logic of the checkKey
function to use the key
property, which need recognizes the Shift + .
as :
, and change the KeyCombination variables accordingly.
I tried it with this dummy and switched keyboard layouts. Upon pressing Shift + .
on my German QWERTZ keyboard, event.key
recognizes :
, but it returns >
when I switch to an US keyboard.
This way the labels would all be correct and all keyboard shortcuts would work (but those that have system shortcuts assigned, see above), be it that a keyboard combination has a weird placement on a special layout.
In a next step, if desired, we could have the user set their keyboard layout in settings (maybe prompt upon setting up Anki initially), and adjust keyboard shortcuts and labels accordingly, to have meaningful keyboard shortcuts (i.e., have intend and outdent or superscript and subscript on two neighboring keys for every layout, which is not the case at the moment).
True. On an american leyout this is the same key, so it makes sense why it would work on us keyboards.
I think the issue that I faced is that “special” characters have different postitions based on different keyboard layouts (both, for other languages as well as when the layout itself is non standard for that language). So even if event.key
recognizes the key, there will be shortcuts that just cannot be typed in depending on the keyboard layout. As far as my research and testing goes, the only way to solve that is to change the shortcuts to use mostly keys that every layout has or to allow shortcut customization.
Reading this now makes me think I should have changed the shortcut during testing. E.g. instead of Control+Shift+. I should have tryed Control+:. I know that this is essentially the same on my german layout. But it should be different on other layouts and might allow us to use event.key
for every layout. I didn’t think about testing this but will do so once I’ve got a bit of free time.
I think being able to change keyboard shortcuts is still the better way, since then the user can be certain that every relevant shortcut works for their language and layout.
Besides: changing keyboard layouts should be the job of the OS. From a user perspective, they expect that the key they see on their physical keyboard is the one they actually type. If you were to change the layout e.g. from german to us english, then this wouldn’t be the case anymore (no matter if done from the OS level or theoretically within anki).
I see your point. We should at least change them in a way that most keyboards have those keys.
This could be it! As far as I can tell, event.key
won’t tell you Shift+.
was pressed, but only that :
was pressed. So if you were so kind to test this, as soon as time allows, and we’d be sure that event.key
in a first step allows us to recognize the key that was actually pressed, we could use that for every layout to begin with.
Well, after reading this I thought “True”, yet again, I just tested and this doesn’t seem to be the case for macOS. Most prominent example: My system language is set to German, and my “main” keyboard layout is set to German QWERTZ. Now, pressing ⌘ Y
in Safari brings up my search history, while ⌘ Z
is the undo action. When I switch to US QWERTY keyboard, Safari still labels “Search History” as ⌘ Y
in the menu bar. And the search history opens when I use ⌘ Z
(i.e., the button in between T
and U
), as this acts like a Y
when using the QWERTY layout.
This behavior is mostly* what Anki is doing right now, but macOS’ labels are labelled to a German keyboard layout (for me right now), and Anki’s labels are labelled to an US International keyboard layout.
(*But, as you can see in my Jan 17 post, this is not true for all shortcuts.)
That is, the app (in this case Safari) doesn’t seem to care what keyboard layout you have turned on right now, but rather what’s your standard layout. And this seems to be would be good starting point for Anki as well. In an ideal world, everything would work for people switching around keyboard layouts all the time (especially since Anki is widely used for language-learning). But for starters, we should allow people to use their standard layout without hassle.
While we are at it: I just noticed that Anki provides a second shortcut for entering/exiting fullscreen mode. We should, for macOS, remove the custom one (first one in screenshot), as the latter (fn F
) is a system standard for full screen on Mac.
I propose adding ⌘ +
and ⌘ -
for Zoom In and Zoom Out, respectively. I am using the mouse to scroll quite often, and would love to have those self-suggesting short cuts assigned as well.
I am happy to do write a commit myself as soon as I find the time for this after my tests in February. If you have any seconds thoughts regarding Full Screen and Zoom, let me know!
Another one: When editing a note, F7
is supposed to be Apply Text Color
, whereas the corresponding button displays the last used text color, e.g., orange, c.f.:
I have a set of multiple custom colors. Pressing F7
for me always applies the first entry of a custom color, rather than the one last used, e.g. it will apply green even though the button displays orange. This does not seem to be the desired behavior.