25

I'd like to add set a functionality to the pair fn+right/left to be like in Mac - 'home' and 'end'. I don't mean to replace the 'home' and 'end' buttons - just adding another 'home'/'end' keys. The advantage is in writing/modifying text. I use the arrows a lot, and I also use the home and end buttons, but why jump to a whole new button? My left hand is already near the fn (function) key - ready to press control or shift.

How do I set this?

Thanks.

2 Answers2

10

I definitely understand why you want to do this! Here's my bet what I have done:

Launch a terminal and run 'xev'. Place your mouse cursor over the Event Tester window and press fn+right/left. You should get a read-out like:

    KeyRelease event, serial 36, synthetic NO, window 0x5200001,
root 0xb2, subw 0x0, time 89989888, (98,124), root:(1007,175),
state 0x0, keycode 171 (keysym 0x1008ff17, XF86AudioNext), same_screen YES,
XLookupString gives 0 bytes: 
XFilterEvent returns: False

This is for my keyboard and fn+right. Find the keycode -- here it's 171.

Now go edit your .bashrc file in your home directory. It's hidden, so pres Ctrl+H in Nautilus to show. Then add lines

    xmodmap -e "keycode 171 = Home"
    xmodmap -e "keycode xxx = End"

where you replace the 171 and xxx with the obtained keycodes. Then save and close the file. Close all your terminals, open one, and you should be ready to go!

Now, there is one draw-back: you have to activate this on every boot. You do that by opening a terminal, and that's it. You can close it again immediately. Or you can try fixing it to do it automatically, as described here. I just run the terminal using a shortcut and then kill it...

Rasmus
  • 8,655
0

If you have Ubuntu+Gnome and xev does not show anything when you type Fn+Left or Fn+Right - than you might have an interceptor in Gnome session like I did. Also my hardware laptop keyboard shows "backward" and "forward" player/music icons for left and right buttons - it means my hardware keyboard sends keycode 173 for Fn+Left and keycode 171 for Fn+Right.

Disable gnome session listeners

You can disable listeners with UI dconf-editor.

Install and run dconf-editor.

Go to the following paths and disable Use default value and put empty array [] in Custom value.

For Fn+Left:

/org/gnome/settings-daemon/plugins/media-keys/previous-static.

For Fn+Right:

/org/gnome/settings-daemon/plugins/media-keys/next-static

Apply changes for both paths and close dconf-editor.

Apply software buttons mapping with xmodmap

Now apply custom handler for Fn+Left:

xmodmap -e "keycode 171 = End"

Before this setting it was for me xmodmap -pk | grep -i '171':

171     0x1008ff17 (XF86AudioNext)  0x0000 (NoSymbol)   0x1008ff17 (XF86AudioNext)  0x0000 (NoSymbol)   0x1008ff17 (XF86AudioNext)

After this setting:

171     0xff57 (End)    0x0000 (NoSymbol)   0xff57 (End)    0x0000 (NoSymbol)   0xff57 (End)

Apply custom handler for Fn+Right:

xmodmap -e "keycode 173 = Home"

Before xmodmap -pk | grep -i '173':

173     0x1008ff16 (XF86AudioPrev)  0x0000 (NoSymbol)   0x1008ff16 (XF86AudioPrev)  0x0000 (NoSymbol)   0x1008ff16 (XF86AudioPrev)

After:

173     0xff50 (Home)   0x0000 (NoSymbol)   0xff50 (Home)   0x0000 (NoSymbol)   0xff50 (Home)

Now it works for me. However the result is not permanent, after reboot you have to do this again. Some startups scripts to do this do not work nice, because xmodmap must be initialized only after some time (when it is ready).

Apply software buttons mapping with xkb

Turns out that xmodmap is outdated and not used anymore in Gnome.

Permanent solution is to use xkb.

Create symbol file fn_mod at /usr/share/X11/xkb/symbols/ (sudo requires) with following content:

// /usr/share/X11/xkb/symbols/inet
// key <I171>   {      [ XF86AudioNext         ]       };
// key <I173>   {      [ XF86AudioPrev         ]       };
//
// /usr/share/X11/xkb/symbols/pc
// key <HOME> { [  Home         ]   };
// key  <END> { [  End          ]   };
//
// make Fn+Left (keycode 171) act as Home
partial modifier_keys
xkb_symbols "left_as_home" {
    key <I171> { [ End ] };
};

// make Fn+Right (keycode 173) act as End partial modifier_keys xkb_symbols "right_as_end" { key <I173> { [ Home ] }; };

Make backup for following files in case you will brake them:

/usr/share/X11/xkb/rules/evdev.xml
/usr/share/X11/xkb/rules/evdev
/usr/share/X11/xkb/rules/evdev.lst

Add following content into evdev.xml (<xkbConfigRegistry> -> <optionList> ->):

    <group allowMultipleSelection="true">
      <configItem>
        <name>fn_mod</name>
        <description>Fn key behavior</description>
      </configItem>
      <option>
        <configItem>
          <name>fn_mod:left_as_home</name>
          <description>Fn+Left (aka XF86AudioPrev) act as Home</description>
        </configItem>
      </option>
      <option>
        <configItem>
          <name>fn_mod:right_as_end</name>
          <description>Fn+Right (aka XF86AudioNext) act as End</description>
        </configItem>
      </option>
    </group>

Add following content into evdev (Find line ! option = symbols and append on the next line):

  fn_mod:left_as_home  = +fn_mod(left_as_home)
  fn_mod:right_as_end  = +fn_mod(right_as_end)

Add following content into evdev.lst (Find line ! option and append on the next line):

  fn_mod               Fn key behavior
  fn_mod:left_as_home  Fn+Left (aka XF86AudioPrev) act as Home
  fn_mod:right_as_end  Fn+Right (aka XF86AudioNext) act as End

evdev.xml changes will create UI tweak in gnome-tweaks. To check/enable this open gnome-tweaks go to the Keyboard & Mouse -> Additional Layout Options -> Fn key behavior.

Finally reboot the session and check in terminal.

$ setxkbmap -query
rules:      evdev
model:      pc105
layout:     us,ru,us
variant:    ,,
options:    fn_mod:left_as_home,fn_mod:right_as_end
$ setxkbmap -print
xkb_keymap {
    xkb_keycodes  { include "evdev+aliases(qwerty)" };
    xkb_types     { include "complete"  };
    xkb_compat    { include "complete"  };
    xkb_symbols   { include "pc+us+ru:2+us:3+inet(evdev)+fn_mod(left_as_home)+fn_mod(right_as_end)" };
    xkb_geometry  { include "pc(pc105)" };
};