How to set and make permanent keyboard layout for MacBook Pros both in TW and Leap 15.2

As YaST keyboard utility doesn’t correctly set layout and for those who still struggle by setting keyboard layout on both console, display manager and X on Apple’s MacBook Pro (may works on regulars MacBook too but not tested) and make it permanent, make the following steps (this is for TW and Leap 15.2 with LightDM as the display manager):

sudo -s
localectl set-x11-keymap --no-convert fr apple mac
localectl set-keymap fr-mac
dracut -f

This sets for the console and LightDM:

localectl status
   System Locale: LANG=fr_FR.UTF-8
       VC Keymap: fr-mac
      X11 Layout: fr
       X11 Model: apple
     X11 Variant: mac
cat /etc/vconsole.conf 
KEYMAP=fr-mac
FONT=eurlatgr.psfu
FONT_MAP=
FONT_UNIMAP=

And for X sessions:

cat /etc/X11/xorg.conf.d/00-keyboard.conf
# Written by systemd-localed(8), read by systemd-localed and Xorg. It's
# probably wise not to edit this file manually. Use localectl(1) to
# instruct systemd-localed to update it.
Section "InputClass"
        Identifier "system-keyboard"
        MatchIsKeyboard "on"
        Option "XkbLayout" "fr"
        Option "XkbModel" "apple"
        Option "XkbVariant" "mac"
EndSection

Call to dracut(8) is important as this make those settings permanent across reboots by regenerating the initramfs with new keyboard layout.
If your keyboard has a different mapping than french, you can choose something else with the help of localectl(1).

For the console and the display manager:

localectl list-keymaps

*list of keymaps*]

sudo localectl set-keymap <keymap>

For X:

localectl list-x11-keymap-layouts

*list of layouts*]

sudo localectl set-x11-keymap --no-convert <layout> apple mac

Thanks, this is great. I’m running openSUSE on an older (2009) MacBook Pro, and was just recently trying to set up some keybindings in my IceWM setup. So I certainly appreciate this post.

Just wanted to get back and say I followed through on your suggestions. It’s worked very well. I have finally been able to set F12 as the raise volume key (“XF86AudioRaiseVolume”), F11 as the lower volume key (“XF86AudioLowerVolume”), and F10 as the mute volume key (“XF86AudioMute”). Thanks again.

Well, seems I spoke too soon. Yesterday I did get the F10, F11, and F12 keys to mute, decrease volume, and increase volume respectively. But today it is not working. In doing the checks which you outlined, I do get the following:


mark@localhost:~> localectl status
   System Locale: LANG=en_GB.UTF-8
       VC Keymap: mac-us
      X11 Layout: us
       X11 Model: apple
     X11 Variant: mac
mark@localhost:~> cat /etc/vconsole.conf
KEYMAP=mac-us
FONT=eurlatgr.psfu
FONT_MAP=
FONT_UNIMAP=
mark@localhost:~> cat /etc/X11/xorg.conf.d/00-keyboard.conf
# Written by systemd-localed(8), read by systemd-localed and Xorg. It's
# probably wise not to edit this file manually. Use localectl(1) to
# instruct systemd-localed to update it.
Section "InputClass"
        Identifier "system-keyboard"
        MatchIsKeyboard "on"
        Option "XkbLayout" "us"
        Option "XkbModel" "apple"
        Option "XkbVariant" "mac"
EndSection
mark@localhost:~> 

So, it looks fine. Yet, the volume keys that I set up yesterday do not work. I get the following when I run xev (I’ll first show an example for F1):


KeyPress event, serial 41, synthetic NO, window 0x3200001,
    root 0x54d, subw 0x0, time 2817721, (-111,-12), root:(562,14),
    state 0x0, keycode 232 (keysym 0x1008ff03, XF86MonBrightnessDown), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

The function keys from F2 to F9 are similar. But, F10, F11, and F12 give the following result:


                        FocusOut event, serial 41, synthetic NO, window 0x3200001,
     mode NotifyGrab, detail NotifyAncestor
 
 
 FocusIn event, serial 41, synthetic NO, window 0x3200001,
     mode NotifyUngrab, detail NotifyAncestor
 
 
 KeymapNotify event, serial 41, synthetic NO, window 0x0,
     keys:  2   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0    
            0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0    
 
 
  

That was happening for a time yesterday too, but then suddenly it started giving results similar to F1 and the other function keys. I’m not sure why, but at that point it was working, and pressing these keys actually did change the volume. No longer. And I don’t know why.

Now, when I press fn+F10, I get the following:


KeyPress event, serial 41, synthetic NO, window 0x3200001,
    root 0x54d, subw 0x0, time 3445825, (-250,157), root:(423,183),
    state 0x0, keycode 76 (keysym 0xffc7, F10), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

That suggests that in my key binding code, I could use “F10” (or “0xffc7”) and then get the mute result via pressing fn+F10, yet this does not work.

I’m not sure what to try next. It’s odd that it briefly worked yesterday.

I’m afraid I’m of no help there as I don’t use iceWM but a DE (xfce 4.14) on which all of the multimedia keys are working right out of the box.
How did you set iceWM keys configuration? Briefly looked at iceWM’s documentation, there’s /etc/icewm/keys which configure globally some keybindings for that WM:

cat /etc/icewm/keys 
# This is an example for IceWM's hotkey definition file.
#
# Place your variants in @CFGDIR@ or in $HOME/.icewm
# since modifications to this file will be discarded when you
# (re)install icewm.
#
# A list of all valid keyboard symbols can be found in
# /usr/include/X11/keysym.h, keysymdefs.h, XF86keysym.h, ...
# You'll have to omit XK_ prefixs and to replace XF86XK_ prefixes by
# XF86. Valid modifiers are Alt, Ctrl, Shift, Meta, Super and Hyper.
#
key "Alt+Ctrl+t"            xterm
key "Alt+Ctrl+b"            xdg-open about:blank
key "Alt+Ctrl+s"            xdg-open http://www.google.com

key "Super+KP_Subtract"            amixer sset PCM 5%-
key "Super+KP_Add"            amixer sset PCM 5%+

# "Multimedia key" bindings for XFree86. Gather the keycodes of your
# advanced function keys by watching the output of the xev command whilest
# pressing those keys and map those symbols by using xmodmap.

key "XF86Standby"            /bin/sh -c "{ test -e /run/systemd/system && systemctl suspend; } ||:"
key "XF86Sleep"                /bin/sh -c "{ test -e /run/systemd/system && systemctl suspend; } ||:"
key "XF86AudioLowerVolume"        amixer sset PCM 5%-
key "XF86AudioRaiseVolume"        amixer sset PCM 5%+
key "XF86AudioMute"            amixer sset PCM 0%
key "XF86HomePage"            xdg-open about:blank
key "XF86Search"            xdg-open http://www.google.com
key "XF86Eject"                eject
key "XF86Calculator"  /bin/sh -c "gnome-calculator || xcalc || ( type bc >/dev/null 2>&1 && xterm -e bc -l)"

Custom keybindings can be set per user on $HOME/.icewm/keys
Have you done what is suggested in etc/icewm/keys?

# "Multimedia key" bindings for XFree86. Gather the keycodes of your
# advanced function keys by watching the output of the xev command whilest
# pressing those keys and map those symbols by using xmodmap.

Mapping keycodes using xmodmap should be IMHO the next steps to do.

Mapping keycodes using xmodmap should be IMHO the next steps to do.

I’m not completely sure how to do that. I’ll give it a try, but if you have some basic pointers for me, I’d appreciate it.

I’m afraid I’m of no help there as I don’t use iceWM but a DE (xfce 4.14) on which all of the multimedia keys are working right out of the box.

I’d be curious to see the code behind how xfce handles the keys which are used to increase and decrease volume. I’m curious which commands are utilized, given that Linux largely relies on pulseaudio for sound rather than alsa (much of the suggested code behind IceWM keymapping assumed alsa).

xmodmap(1)'s manpage has detailed examples on how to use an $HOME/.xmodmap file. Also check how your DE (icewm in your case) makes use of this file.

XFCE handles multimedia keys with xfce4-pulseaudio-plugin :wink:

More infos at panel-plugins:xfce4-pulseaudio-plugin:start [Xfce Docs]

Thanks, that’s great. If I set up XFCE4 I’ll be sure to include the xfce4-panel-plugin-pulseaudio package.

I did finally figure out how to get audio control bound to the keys (specifically to F10, F11, and F12). It seems I just needed to install a couple of alsa packages to be able to use the amixer program in the script (initially I was worried that this might mess up the pulseaudio setup, but everything seems well – I just installed alsa-utils). I also did set up a keymapping file to clear up some confusion the machine had over the Fn key (sometimes keymapping got messed up between, say, solely pressing “F10” and pressing “Fn+F10”). I found the instructions here. Here’s the file I set up (/home/mark/.Xmodmap)


keycode  76 = F10 F10 F10 F10 F10 F10 XF86Switch_VT_10
keycode  95 = F11 F11 F11 F11 F11 F11 XF86Switch_VT_11
keycode  96 = F12 F12 F12 F12 F12 F12 XF86Switch_VT_12

keycode 121 = XF86AudioMute NoSymbol XF86AudioMute
keycode 122 = XF86AudioLowerVolume NoSymbol XF86AudioLowerVolume
keycode 123 = XF86AudioRaiseVolume NoSymbol XF86AudioRaiseVolume

Here’s the keys entry (/home/mark/.icewm/keys)


key "XF86AudioLowerVolume" amixer sset Master 5%-
key "XF86AudioRaiseVolume" amixer sset Master 5%+
key "XF86AudioMute" amixer sset Master toggle

I set that up on the basis of what I discovered using xev and xmodmap, as you had suggested.

Anyway, thanks for your help. I set this up yesterday, and it’s still working. So, I’m confident now that I’ve solved it.

Great news! :wink: