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

Feature Request: Prevent Swapping Command & Option Keys When Using A Mac Keyboard on Linux #59

Closed
BloodyMess opened this issue Oct 3, 2020 · 27 comments

Comments

@BloodyMess
Copy link

BloodyMess commented Oct 3, 2020

I'm having a problem related to #28, but I'm not sure if it should be under that issue or a new one. So I'm doing both. Feel free to delete whichever one you feel is best.

My system config is this:
SOFTWARE:

  • elementary OS 5.1.7 Hera (with all current updates) based on Ubuntu 18.04LTS
  • Linux Kernel 5.4.0-48-generic
  • GTK 3.22.30
  • SheepShaver built from a current snapshot of master branch from this repository.

HARDWARE:

  • Ryzen 3900X
  • Radeon RX590
  • 128GB RAM
  • Matias Tactile Pro Keyboard for Mac

As you can see above, I'm using a keyboard made for Macs on my Linux system. I'm trying to get my SheepShaver Mac to use the correct command and option keys on my Mac keyboard.

Other builds I've been running previously (from vasi, as posted on the e-maculation forums) have swapped the command and option keys and also would only respond to the left command and option keys, ignoring the right-hand command and option keys.

I ran across issue #28 while searching for a solution, and downloaded a snapshot to see if your SheepShaver was any better. I looked at the code in video_sdl2.cpp and found the places where the keycodes were being swapped unless the __APPLE__ macro is defined.

Since swapping those keys isn't appropriate for the Mac keyboard I'm using, I commented out the #ifdef __APPLE__ lines and their related #else blocks, so that just the lines of code that set the keycodes correctly and correctly sets the opt_down and cmd_down variables remained. I also unswapped the command and option keycodes in the "sdl x11" section of the "keycodes" file.

This mostly worked!

But there is an odd bug that I cant' figure out so far: when I press a command-key combination it seems to be sending the regular keypress first and then immediately follows it with the correct command-key combo that I pressed. For Example:

  1. At the Finder Desktop, Press command-N to create a new folder. This creates a folder presenting the "untitled" text for you to edit.
  2. WITHOUT pressing any other keys or clicking the mouse anywhere, press command-I to open the Get Info window.
  3. You'll see that the name of the folder has been changed to an "i" and THEN the Get Info window was opened for the folder.
  4. Pressing command-w to close the Get Info window will again change the folder name, this time to "w", before acting on the command-w press to close the window.

The order that these key events happens in can be verified like this:

  1. In the Finder (at Desktop or with a folder window active, it doesn't matter) with nothing selected, press command-i.
  2. The Finder will process the plain "i" keypress by selecting the icon with the closest matching name , and then opening the Get Info window.

Like i said earlier, I don't know if this should be under issue #28 or in its own issue.

Also, I'm not sure whether it should be a bug or a feature request to not swap the command and option keys when a Mac keyboard is being used regardless of whether the system itself is a Mac.

@BloodyMess BloodyMess changed the title Feature Request: Prevent Swapping Command & Option Key When Using A Mac Keyboard on Linux Feature Request: Prevent Swapping Command & Option Keys When Using A Mac Keyboard on Linux Oct 3, 2020
@rakslice
Copy link

rakslice commented Oct 3, 2020

One question is: if you leave the __APPLE__ special cases in video_sdl2.cpp as they are and just use the keycodes file to remap the modifiers the other way, does that also have a problem? Then it's the same symptom as #28 .

If you are modifying the __APPLE__ special cases for the keyboard in video_sdl2.cpp, did you get all three: the ones for SDL_KEYUP and SDL_KEYDOWN in handle_events() for the modifier flags as well as the one in kc_decode() for the keysyms? Oh yeah, I see that you mention you did.

The fact that the keyboard handling has special cases for __APPLE__ has always made it occur to me that the reverse case -- plugging a generic USB keyboard into a Mac -- might be awkward, but not quite enough to actually plug a USB keyboard into my Mac to see what SS does with it. I should do that. :D

@rakslice
Copy link

rakslice commented Oct 3, 2020

Also, I'm not sure whether it should be a bug or a feature request to not swap the command and option keys when a Mac keyboard is being used regardless of whether the system itself is a Mac.

Since SDL2 doesn't tell us anything about the keyboard that generated the keypress, and there's no way to infer it if I understand correctly, I think it may be academic.

Maybe the best we could do would be to add a specific settings toggle for it to make it easier to swap than writing an entire keysyms file?

But there is an odd bug that I cant' figure out so far: when I press a command-key combination it seems to be sending the regular keypress first and then immediately follows it with the correct command-key combo that I pressed. For Example:

At the Finder Desktop, Press command-N to create a new folder. This creates a folder presenting the "untitled" text for you to edit.

WITHOUT pressing any other keys or clicking the mouse anywhere, press command-I to open the Get Info window.
You'll see that the name of the folder has been changed to an "i" and THEN the Get Info window was opened for the folder.
Pressing command-w to close the Get Info window will again change the folder name, this time to "w", before acting on the command-w press to close the window.
The order that these key events happens in can be verified like this:

In the Finder (at Desktop or with a folder window active, it doesn't matter) with nothing selected, press command-i.
The Finder will process the plain "i" keypress by selecting the icon with the closest matching name , and then opening the Get Info window.

Is that behaviour consistent with not having codes for SDL_KEYUP that are consistent with the ones for SDL_KEYDOWN?

@rakslice
Copy link

rakslice commented Oct 3, 2020

As a practical matter, do you have your desktop environment configured somehow such that it doesn't intercept whatever key generates SDLK_LGUI, the left Windows key on a standard USB keyboard? If so, how easy was that to do? I always assumed that getting around this was the reason we map Alt to Command on most platforms.

@kanjitalk755
Copy link
Owner

How about this implementation:
https://github.com/kanjitalk755/macemu/tree/test_opt_cmd

@cat7
Copy link

cat7 commented Oct 6, 2020

In Qemu, the windows key is intercepted when the mouse is grabbed.
That is achieved somewhere in this patch set: https://lists.nongnu.org/archive/html/qemu-devel/2020-05/msg05619.html

@BloodyMess
Copy link
Author

BloodyMess commented Oct 6, 2020

How about this implementation:
https://github.com/kanjitalk755/macemu/tree/test_opt_cmd

Well, there's some improvement: This implementation fixes ignoring the righthand option and command keys. Unfortunately it doesn't fix the swapping. The option and command keys remain swapped. I tried both the original keycodes file as well as one with the option and command codes swapped and also with the keycodes preference entry set to false.

I ran the showkey command in the terminal and pressed the bottom row modifier keys, in order from left to right. These were the codes it displayed for them:

Left Control:	29
Left Option:	56
Left Command:	125

Right Command:	126
Right Option:	100
Right Control:	97

CORRECTION:
I had forgotten that running SheepShaver using sudo caused it to use a preferences file located in /root/.sheepshaver.

The new prefs option actually does fix the option/command swapping problem. And it still fixes recognizing the righthand option and command keys.

It also halfway fixes the funky behaviour of sending the regular character before the command key combo: It works perfectly fine when I use the righthand modifier keys, but it still has the problem when using the lefthand modifier keys.

@kanjitalk755
Copy link
Owner

@cat7

In Qemu, the windows key is intercepted when the mouse is grabbed.

I don't know the relevance to this issue.

@BloodyMess

I tested SS under Arch Linux.

I ran the showkey command in the terminal and pressed the bottom row modifier keys, in order from left to right. These were the codes it displayed for them:

All had the same result.

It also halfway fixes the funky behaviour of sending the regular character before the command key combo: It works perfectly fine when I use the righthand modifier keys, but it still has the problem when using the lefthand modifier keys.

I couldn't reproduce this phenomena.
In video_sdl2.cpp, both side of modifier keys are treated equivalent.

case SDLK_LALT: case SDLK_RALT: return swap_opt_cmd() ? 0x37 : 0x3a;
case SDLK_LGUI: case SDLK_RGUI: return swap_opt_cmd() ? 0x3a : 0x37;

So there's nothing more we can do with SS code.

@rakslice
Copy link

rakslice commented Oct 7, 2020

I guess there is some kind of interception of Cmd / Win, a.k.a. what ev calls KEY_LEFTMETA, USB HID key code 125 going on.

I wonder if there is a way to convince whatever is doing that in elementaryOS to not do that, or at least get SDL to give some less dumb input when it happens?

For the benefit of those trying to reproduce the problem, this is one of those bug reports where perhaps a tedious level precision helps.

Testing in elementaryOS Hera x86_64, with option and command swapped:

  1. Launch SheepShaver and focus the Finder Desktop
  2. Press and hold command.
  3. Press and release N to create a new folder. This creates a folder presenting the "untitled folder" text for you to edit.
  4. Release command
  5. Press and hold command
  6. Press and release I
    Expected:
    Name of folder stays as the default "untitled folder" and Get Info window is open
    Actual:
    Name of the folder has been changed to an "i" and Get Info window is open

I would never have thought to release command and press it again except that I was eventually trying with Key Caps open in the emulated Mac, and that gave away the underlying issue: the command key doesn't register when you press it, it only registers when you finish a two key combination.

This seems to be because SheepShaver doesn't get a key event when you press left meta until a shortcut with left meta is complete that elementaryOS doesn't want.

When SheepShaver does get a key event it gets 3 at once, and 5 altogether:

When the meta key is pressed:

  • No events.

When the letter key is pressed:

  • Letter key down
  • Left meta key down
  • Letter key down

When the letter key is released:

  • Letter key up

When left meta key is released:

  • Left meta key up

So in other words if you had kept left meta held down after the first key combination, it continues to register as down and any subsequent key combinations work normally.

Right meta doesn't have this problem; it registers right away and pressing a two key combination with it only generates 4 events, one for each key event as expected.

Pressing command-w to close the Get Info window will again change the folder name, this time to "w", before acting on the command-w press to close the window.

That part I have no clue how you did; I've set command key behaviour to Disabled in System Settings -> Keyboard -> Layout, and scoured all the shortcuts in Shortcuts and in Gnome Tweaks for Cmd W, and didn't find anything, but left meta + W and right meta + W are still captured by ElementaryOS no matter what and make it give an overview of the open windows.

@rakslice
Copy link

rakslice commented Oct 7, 2020

XDG_SESSION_TYPE=x11

Testing with xev -event keyboard, it only sees three events, there is no KeyPress for Super_L and the others are as expected.

@rakslice
Copy link

rakslice commented Oct 7, 2020

But using xev to monitor SheepShaver instead of using its own window, it sees four events:

Left meta pressed:

  • Nothing

Letter key pressed:

  • KeyRelease for letter
  • KeyPress for letter

Letter key released:

  • KeyRelease for letter

Left meta released:

  • KeyRelease for Super_L

@rakslice
Copy link

rakslice commented Oct 7, 2020

One thing I'm noticing during this testing is that the host key repeat applying in SheepShaver makes shortcuts repeat in a way that doesn't happen on a real Mac, and unnecessarily duplicates key repeat already being done in software by the emulated Mac on things that should repeat.

Actually, of the SDL key events seen for the Left Meta shortcut in this issue:

  • Letter key down
  • Left meta key down
  • Letter key down <-- this one has event.key.repeat set
  • Letter key up
  • Left meta key up

@rakslice
Copy link

rakslice commented Oct 7, 2020

Okay, I see that the elementaryos shortcuts that aren't working properly in the settings GUI yet are modifiable through org.pantheon.desktop.gala in dconf-editor etc.

@kanjitalk755
Copy link
Owner

In addition to org.pantheon.desktop.gala, change the superkey with org.gnome.mutter.overlay-key.

For example:
Use default value: OFF
Custom value: Control_R

@rakslice
Copy link

rakslice commented Oct 7, 2020

Ah, removing Super_L from org.gnome.mutter.overlay-key is sufficient to let SheepShaver see the initial Super_L press by itself, which causes it to be delivered first before the other key in a key combination.

I have a code change in a branch to make it so that when consecutive keydown events arrive simultaneously modifiers are delivered first, and also to ignore key repeat events: https://github.com/rakslice/macemu/tree/sdl2_keys

@kanjitalk755
Copy link
Owner

Do we need to change the handling of key repeats even if the superkey is set properly?
If so, please exemplify a concrete case.

@BloodyMess
Copy link
Author

That part I have no clue how you did; I've set command key behaviour to Disabled in System Settings -> Keyboard -> Layout, and scoured all the shortcuts in Shortcuts and in Gnome Tweaks for Cmd W, and didn't find anything, but left meta + W and right meta + W are still captured by ElementaryOS no matter what and make it give an overview of the open windows.

If you go into the Shortcuts tab of the Keyboard settings panel, select the item with command-w assigned to it, then click on the item's right column to allow reassignment of the shortcut for that item. While it's waiting for you to select a new keyboard shortcut: Simply press the Delete/Backspace key, which will clear the shortcut key assignment and disable the item.

@BloodyMess
Copy link
Author

One thing I'm noticing during this testing is that the host key repeat applying in SheepShaver makes shortcuts repeat in a way that doesn't happen on a real Mac, and unnecessarily duplicates key repeat already being done in software by the emulated Mac on things that should repeat.

Actually, of the SDL key events seen for the Left Meta shortcut in this issue:

* Letter key down

* Left meta key down

* Letter key down <-- this one has `event.key.repeat` set

* Letter key up

* Left meta key up

This might be a clue to something I thought was an entirely different issue with handling keypresses:

If you hold down a modifier key for more than a couple of seconds, SheepShaver "forgets" that the modifier key is still pressed. This has tripped me up more times than I care to admit, even when I'm consciously trying to work around it.

@BloodyMess
Copy link
Author

Ah, removing Super_L from org.gnome.mutter.overlay-key is sufficient to let SheepShaver see the initial Super_L press by itself, which causes it to be delivered first before the other key in a key combination.

I have a code change in a branch to make it so that when consecutive keydown events arrive simultaneously modifiers are delivered first, and also to ignore key repeat events: https://github.com/rakslice/macemu/tree/sdl2_keys

I've used dconf-editor to clear the overlay key string and disable the default, and built your sdl2_keys branch.

It seems to be working fine. So far, I've only quickly tested it with the actions listed in this thread, but it looks good so far!

@rakslice
Copy link

rakslice commented Oct 7, 2020

@kanjitalk755 Sure, when using X11, run SheepShaver, go to the desktop, and press cmd + n and hold them down for 10 seconds.
Expected: One new folder is created
Actual: Lots of new folders are created :D

@BloodyMess But like I said there was nothing in the Shortcuts using Cmd + W. I eventually found it in a setting in org.pantheon.desktop.gala in dconf

@rakslice
Copy link

rakslice commented Oct 7, 2020

I assume that elementary's Keyboard settings panel is a work in progress, because for instance if I click on a Disabled item and it says "New accelerator" and I type a new shortcut, it just goes back to Disabled, it doesn't seem to be able to take an actual setting no matter what combinations I try.

@BloodyMess
Copy link
Author

@BloodyMess But like I said there was nothing in the Shortcuts using Cmd + W. I eventually found it in a setting in org.pantheon.desktop.gala in dconf

Yes, I think if you have the command key disabled in the Layout panel, then it just marks things as disabled in the other panels, but apparently doesn't actually change them. I seem to remember having to leave the command key enabled in the Layout panel to let me make changes in the other panels.

@kanjitalk755
Copy link
Owner

@rakslice

I have confirmed that key repeats should be ignored.

One more question.

If we set the superkey properly, the event occurrence order of the command key and other keys will be the order in which the user pressed it, so I think that look ahead for keydown events is unnecessary, but how about it?

@rakslice
Copy link

rakslice commented Oct 8, 2020

Yeah, I don't know any other case where multiple key presses happen at the same time that would need the reordering, and without that it is unnecessary.

@kanjitalk755
Copy link
Owner

I added a step to ignore key repeat and merged to the master.

@BloodyMess
Copy link
Author

I added a step to ignore key repeat and merged to the master.

I just built the latest snapshot and it seems to be working well. Even the problem of "forgetting" that a modifier key is being held down for an extended period isn't happening now.

@BloodyMess
Copy link
Author

I went through d-conf looking for any key bindings that might need to be changed on elementaryOS (or any other gnome based system) to let SheepShaver function normally. It might be a good idea to mention in a read-me that users of systems like these might need to do this sort of thing to let SheepShaver react to keypresses correctly.

Here are the changes I made on my system:

------------------------------------------------------------------------------------------------------
org.gnome.desktop.wm.keybindings:

	CHANGE ALL SETTINGS TO:
		UseDefaultValue:	OFF
		Custom Value:		[]

------------------------------------------------------------------------------------------------------
org.gnome.mutter:

org.gnome.mutter.overlay-key
	DEFAULT:			'Super_L'

	CHANGE TO:
	UseDefaultValue:		OFF
	Custom Value:			


------------------------------------------------------------------------------------------------------
org.gnome.mutter.keybindings:

org.gnome.mutter.keybindings.switch-monitor
	DEFAULT:			['<Super>p', 'XF86Display']

	CHANGE TO:
		UseDefaultValue:	OFF
		Custom Value:		['XF86Display']


org.gnome.mutter.keybindings.toggle-tiled-left
	DEFAULT:			['<Control><Super>Left']

	CHANGE TO:
		UseDefaultValue:	OFF
		Custom Value:		[]


org.gnome.mutter.keybindings.toggle-tiled-right
	DEFAULT:			['<Control><Super>Right']

	CHANGE TO:
		UseDefaultValue:	OFF
		Custom Value:		[]


------------------------------------------------------------------------------------------------------
org.gnome.mutter.wayland.keybindings:

org.gnome.mutter.wayland.keybindings.restore-shortcuts
	DEFAULT:			['<Super>Escape']

	CHANGE TO:
		UseDefaultValue:	OFF
		Custom Value:		[]



------------------------------------------------------------------------------------------------------
org.pantheon.desktop.gala.keybindings:

org.pantheon.desktop.gala.keybindings.cycle-workspaces-next
	DEFAULT:			['<Super>Tab']
	
	CHANGE TO:
		UseDefaultValue:	OFF
		Custom Value:		['<Super><Alt><Control>Tab']


org.pantheon.desktop.gala.keybindings.cycle-workspaces-previous
	DEFAULT:			['<Super><Shift>Tab']
	
	CHANGE TO:
		UseDefaultValue:	OFF
		Custom Value:		['<Super><Shift><Alt><Control>Tab']


org.pantheon.desktop.gala.keybindings.expose-all-windows
	DEFAULT:			['<Super>a']
	
	CHANGE TO:
		UseDefaultValue:	OFF
		Custom Value:		[]


org.pantheon.desktop.gala.keybindings.expose-windows
	DEFAULT:			['<Super>w']
	
	CHANGE TO:
		UseDefaultValue:	OFF
		Custom Value:		[]


org.pantheon.desktop.gala.keybindings.move-to-workspace-first
	DEFAULT:			['<Super><Shift>Home']
	
	CHANGE TO:
		UseDefaultValue:	OFF
		Custom Value:		[]


org.pantheon.desktop.gala.keybindings.move-to-workspace-last
	DEFAULT:			['<Super><Shift>End', '<Super>0']
	
	CHANGE TO:
		UseDefaultValue:	OFF
		Custom Value:		[]


org.pantheon.desktop.gala.keybindings.pip
	DEFAULT:			['<Super>f']
	
	CHANGE TO:
		UseDefaultValue:	OFF
		Custom Value:		[]


org.pantheon.desktop.gala.keybindings.switch-input-source
	DEFAULT:			['']
	
	CHANGE TO:
		UseDefaultValue:	OFF
		Custom Value:		[]


org.pantheon.desktop.gala.keybindings.switch-input-source-backward
	DEFAULT:			['<Alt>Space']
	
	CHANGE TO:
		UseDefaultValue:	OFF
		Custom Value:		[]


org.pantheon.desktop.gala.keybindings.switch-to-workspace-first
	DEFAULT:			['<Super>Home']
	
	CHANGE TO:
		UseDefaultValue:	OFF
		Custom Value:		[]


org.pantheon.desktop.gala.keybindings.switch-to-workspace-last
	DEFAULT:			['<Super>End', '<Super>0']
	
	CHANGE TO:
		UseDefaultValue:	OFF
		Custom Value:		[]


org.pantheon.desktop.gala.keybindings.zoom-in
	DEFAULT:			['<Super>plus', '<Super>KP_Add']
	
	CHANGE TO:
		UseDefaultValue:	OFF
		Custom Value:		[]


org.pantheon.desktop.gala.keybindings.zoom-out
	DEFAULT:			['<Super>minus', '<Super>KP_Subtract']
	
	CHANGE TO:
		UseDefaultValue:	OFF
		Custom Value:		[]

@kanjitalk755
Copy link
Owner

The above settings can be referenced from the top-level readme.md.

This issue was closed.
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

No branches or pull requests

4 participants