rbreaves / kinto

Mac-style shortcut keys for Linux & Windows.

Home Page:http://kinto.sh

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Kinto (xkb/x11) Shortcut Creation

rbreaves opened this issue · comments

No longer supported - xkb version of Kinto is deprecated.

How to Add Setxkbmap Option inside Kinto

To summarize you'll need to pull the partial out of the symbols file the option resides in and then add that to the mac_gui file and lastly reference it in the keymap file(s) you want it in.

symbols directory

/usr/share/X11/xkb/symbols/ 

symbols file

~/.xkb/symbols/mac_gui

keymap files

~/.xkb/keymap/kbd.mac.gui
~/.xkb/keymap/kbd.mac.term

A more detailed explaination is here.
#50 (comment)

How to Add or Change keymaps for Applications

Note: All of the following is already done in Kinto (but may also change as improvements are made). The following is purely for documentation and example sake as they are real examples of how to leverage the json config to support additional keymaps.

First it is important to understand how Kinto operates.

  1. It listens for any focus/active window changes
  2. It applies the proper keymap based on the programs name.
  3. It may monitor your caret/cursor input status, if the app is known to cause shortcut conflicts with wordwise
  4. It runs anywhere from 1 to 3 commands to fully remap your computer.

Ok great, we've covered the basics, now what are your options on modifying functionality?
It depends.

Do you want to remap keys using xkb or xbindkeys with xdotool, or something else entirely?
The choice is yours, but I'd recommend xbindkeys with xdotool for anyone that doesn't want to spend the time or learn xkb. I prefer xkb but it completely remaps your keyboard and it could break things if done poorly.

How to Remap using XBindKeys with Xdotool - Firefox

  1. By default Firefox is mapped with the standard gui based xkb config, and only if no input has focus does it then run xbindkeys to map the Cmd+Left/Right arrow key location to the Back and Forwards functionality you'd expect.

  2. The xbindkeys script takes into account the xkb mapping being the base because it is actually remapping Home and End to Back and Forwards as there is no real reason to reload an entire xkb layout.

~/.config/kinto/user_config.json

...
{
    "name": "firefox",
    "run": "setxkbmap -option;xkbcomp -w0 -I$HOME/.xkb ~/.xkb/keymap/kbd.mac.gui $DISPLAY",
    "run_onInput": "killall xbindkeys > /dev/null 2>&1",
    "run_offInput": "killall xbindkeys > /dev/null 2>&1;xbindkeys -f $HOME/.config/kinto/.firefox-nw",
    "symbols": "",
    "types": "",
    "de": [
	2
    ],
    "appnames": [
	"Firefox"
    ]
},
...

~/.config/kinto/.firefox-nw

"xdotool key --delay 0 --clearmodifiers Control_L+bracketleft"
  // Alt/Cmd + Left
  Home + Release

"xdotool key --delay 0 --clearmodifiers Control_L+bracketright"
  // Alt/Cmd + Right
  End + Release
  
# Note additional keymaps can easily be added to this file and I will accept any PR's with keymaps that align with macs

Once you have made your changes you can restart the Kinto service and the changes will take affect.

systemctl --user restart keyswap

Under normal circumstances this keymap would not have worked well had Firefox not included 2 keymap options for going forwards or back. In the next example, Chrome, you will see how to solve this very same problem but in xkb format and it is the only way to fix it for Chrome due to conflicting with wordwise shortcuts.

Also the choice of xdotool over something like xte (xautomation) was explicit, xdotool allows you to hold down a modifier and continue to repeat the action(s) and xte does not.

How to Remap Using XKB - Chrome

This gets to be a little more complicated, but this is what you have to do to accomplish the same on the xkb level.

Summary

  1. Copy ~/.xkb/keymap/kbd.mac.gui and append the name of the app. (e.g. chrome)
  2. Edit ~/.xkb/keymap/kbd.mac.gui.chrome
  3. Add new keybindings to ~/.xkb/symbols/mac_gui
  4. Only edit types if you absolutely need to add another modifier level (~/.xkb/types/mac_gui)

Understand that as you add or modify the ~/.xkb/symbols/ files that these two groups symbols[Group1] and actions[Group1] will be following the order of the modifier levels that are configured in the related ~/.xkb/types/mac_gui or mac_term file.

Also you will have to discover the proper xkb names for keys and that they will often follow two different labels/names. eg RGHT vs Right ... replace key <RGHT> vs symbols[Group1]= [ Right, ....

A good place to get the proper names/labels are these two files.

/usr/share/X11/xkb/symbols/us
/usr/share/X11/xkb/symbols/inet

Ok, so here are the detailed instructions.

  1. cp ~/.xkb/keymap/kbd.mac.gui ~/.xkb/keymap/kbd.mac.gui.chrome

  2. nano ~/.xkb/keymap/kbd.mac.gui.chrome

# Change mac_gui(mac_levelssym)
...
xkb_symbols   { include "pc+us+us:2+inet(evdev)+ctrl(swap_lwin_lctl)+ctrl(swap_rwin_rctl)+mac_gui(mac_levelssym)"	};
...
# To +mac_gui(mac_chrome)
xkb_symbols   { include "pc+us+us:2+inet(evdev)+ctrl(swap_lwin_lctl)+ctrl(swap_rwin_rctl)+mac_gui(mac_chrome)"	};
...
};
  1. Add your new "partial xkb_symbols" via nano ~/.xkb/symbols/mac_gui
partial xkb_symbols "mac_chrome" {
    // Back Button
    replace key <LEFT> {
        type[Group1]= "ONE_LEVEL_CTRL",
        symbols[Group1]= [
            Left,
            Left,
            Left
        ],
        actions[Group1]= [
            NoAction(),
            RedirectKey(key=<UP>),
            RedirectKey(key=<LEFT>,modifiers=Mod1,clearmods=Control)
        ]
    };
    // Forwards Button
    replace key <RGHT> {
        type[Group1]= "ONE_LEVEL_CTRL",
        symbols[Group1]= [
            Right,
            Right,
            Right
        ],
        actions[Group1]= [
            NoAction(),
            RedirectKey(key=<DOWN>),
            RedirectKey(key=<RGHT>,modifiers=Mod1,clearmods=Control)
        ]
    };

~/.config/kinto/user_config.json

{
    "name": "chrome",
    "run": "setxkbmap -option;xkbcomp -w0 -I$HOME/.xkb ~/.xkb/keymap/kbd.mac.gui.chrome $DISPLAY",
    "run_onInput": "xkbcomp -w0 -I$HOME/.xkb ~/.xkb/keymap/kbd.mac.gui $DISPLAY",
    "run_offInput": "xkbcomp -w0 -I$HOME/.xkb ~/.xkb/keymap/kbd.mac.gui.chrome $DISPLAY",
    "symbols": "",
    "types": "",
    "de": [
	2
    ],
    "appnames": [
	"Chromium",
	"Chromium-browser",
	"Google-chrome"
    ]
}
  1. Not making changes to types but it looks like this. It contains 5 levels of modifiers, Base, Alt, Control, Shift+Control, and Shift+Alt. Additional Levels can and may be added later, but please do not change the order of the Levels or existing symbols files will break!! You can add new levels however without issue.
default partial xkb_types "addmac_levels" {
    type "ONE_LEVEL_CTRL" {
        modifiers= Mod1+Control+Shift;
        map[Mod1]= Level2;
        map[Control]= Level3;
        map[Mod1+Control]= Level3;
        map[Shift+Control]= Level4;
        map[Shift+Mod1] = Level5;
        level_name[Level1]= "Base";
        level_name[Level2]= "Alt";
        level_name[Level3]= "Control";
        level_name[Level4]= "Shift with Control";
        level_name[Level5] = "Shift Alt";
    };
};

Once you have made your changes you can restart the Kinto service and the changes will take affect.

systemctl --user restart keyswap

JSON config files

Features

  • Unlimited keyboard configurations per App/category (user_config.json - config -> create app object)
  • Dynamic Desktop Environment shortcut capabilities (user_config.json - de -> create DE tweak/remap)

Located at ~/.config/kinto/ you will find user_config.json which will look like the following after an install. You can modify the defaults.json file in the root directory of kinto to create additional keyboard layout types/support without needing to modify any of the underlying Kinto code.

You can also add additional Desktop Environment related tweaks to user_config.json in the install directory as well and the installer will prompt you to install them. You may also fork and submit any json or additional .xkb configurations to me for approval if you believe it makes Linux more like typing on a Mac.

{"config":[
	//
	// Each config category contains the category name, and references to the de tweaks
	// And contains the default run commands plus what behavior they should exhibit for
	// input fields on/off focus, if any.
	// Symbols and types are not currently used - may later replace the need for static
	// files with xkbcomp.
	//
	// If you use xbindkeys outside of Kinto then you may want to remove xbindkeys from
	// this config after setup or rewrite the command to exclude your own xbindkeys.
	//
	{
		"name":"gui",
		"run":"setxkbmap -option;xkbcomp -w0 -I$HOME/.xkb ~/.xkb/keymap/kbd.mac.gui $DISPLAY",
		"de":[2],
		"appnames":[ "" ],
		"run_onInput":"",
		"run_offInput": "killall xbindkeys > /dev/null 2>&1",
		"symbols":"",
		"types":"",
		"de":[],
		"appnames":[ "" ]
	},
	{
		"name":"term",
		"run":"setxkbmap -option;xkbcomp -w0 -I$HOME/.xkb ~/.xkb/keymap/kbd.mac.term $DISPLAY",
		"de":[2],
		"appnames":[ "Gnome-terminal","konsole","io.elementary.terminal","terminator","sakura","guake","tilda","xterm","eterm","kitty" ],
		"run_onInput":"",
		"run_offInput": "killall xbindkeys > /dev/null 2>&1",
		"symbols":"",
		"types":"",
		"de":[],
		"appnames":[ "" ]
	}],
	// Init - Array that references de objects by their ID and runs the "run" command
	// when the app initially runs.
	"init": [1],
	// detypes - DE's with support or planned support
	"detypes":["gnome2","gnome3","kde4","kde5","xfce","i3wm"],
	// de - tweak objects and initial command to be ran on start.
	//
	//    Intent - init or gui_term, to signify what type of tweak it is.
	//      run, run_term, run_gui - run is only relevant for init, and the
	//      other two relate to gui_term and running under those modes.
	"de":[{
		"id": 1,
		"type": ["gnome3"],
		"active": false,
		"intent":"init",
		"name":"gnome-init",
		"description":"Gnome - Remove Superkey Overlay keybinding to Activities Overview",
		"run":"gsettings set org.gnome.mutter overlay-key ''",
		"run_term":"",
		"run_gui":""
	},
	{
		"id": 2,
		"type": ["gnome3"],
		"active": false,
		"intent":"gui_term",
		"name":"Gnome Activities Overview",
		"description":"Cmd+Space activates Activities Overview",
		"run":"",
		"run_term":"gsettings set org.gnome.desktop.wm.keybindings panel-main-menu \"['<Control><Shift>Space']\"",
		"run_gui":"gsettings set org.gnome.desktop.wm.keybindings panel-main-menu \"['<Ctrl>Space']\""
	},
	{
		"id": 3,
		"type": ["kde5"],
		"active": false,
		"intent":"init",
		"name":"kde-init",
		"description":"KDE Plasma 5 - Removes Superkey Overlay from the Launcher Menu",
		"run":"kwriteconfig5 --file ~/.config/kwinrc --group ModifierOnlyShortcuts --key Meta \"\";qdbus org.kde.KWin /KWin reconfigure",
		"run_term":"",
		"run_gui":""
	}]
}