Merge pull request #140 from rbreaves/dev

- Xkeysnail added to Production branch
This commit is contained in:
Ben Reaves
2020-05-02 22:02:14 -05:00
committed by GitHub
12 changed files with 684 additions and 363 deletions

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
.env/
.DS_Store
__pycache__/
xkeysnail/

404
README.md
View File

@@ -8,7 +8,7 @@
\- Type in Linux & Windows like it's a Mac. \-
Seamless copy and paste with all apps and terminals. Also the only linux remapper that is aware of your cursor/caret status - meaning it avoids shortcut conflicts within an app versus wordwise shortcuts when a text field is in use.
Seamless copy and paste with all apps and terminals. Also the only linux remapper that is aware of your cursor/caret status - meaning it avoids shortcut conflicts within an app versus wordwise shortcuts when a text field is in use. (xkeysnail implementation of Kinto has caret checking disabled in master for now.)
## What does this do exactly?
@@ -26,9 +26,9 @@ Kinto works for standard Windows, Apple and Chromebook keyboards. The following
- systemd
- x11
- IBus*
- Fedora/RHEL/Manjaro/Arch/Debian/Ubuntu based distro 16.04+
Binary is included and will be installed, but you can also compile kintox11.c on your system. You will need to compile and install json-c first as its libraries will be required to compile and run the program.
- Manjaro/Arch/Debian/Ubuntu based distro 16.04+
- Fedora/RHEL (may not work w/ xkeysnail, but original xkb version does)
- xkeysnail (Recommended, but optional)
*IBus is needed to support wordwise during browser app usage as the keymap will need to change slightly depending if the cursor/caret is on screen waiting for input. Setup.py will set it but you can manually set it as well or check your current Input Method.
@@ -70,9 +70,50 @@ sudo apt install python3
To Uninstall Kinto
```
./uninstall.sh
./setup.py
```
## Shortcut Creation (Xkeysnail)
**GUI Keys**
| Value| Description|Mac/Kinto Equivalent|
| ----- |:--------:|:--------:|
|C,Ctrl|Control|Cmd|
|M,Alt| Alt/Option|Alt/Option|
|Super | Win/Super|Ctrl|
**Terminal Keys**
| Value| Description|Mac/Kinto Equivalent|
| ----- |:--------:|:--------:|
|RC,RCtrl|Right Control on Left & Right Alt/Cmd key|Cmd|
|M,Alt| Alt/Option|Alt/Option|
|Ctrl | Ctrl|Ctrl|
You can define new keymaps for your specific app via this method. You also do not have to cancel out the original keybinding if you do not need or want to, but you can do so with "pass_through_key".
### Defining Keymaps Per App
```
# Keybindings for Sublime Text
define_keymap(re.compile("Sublime_text"),{
K("C-h"): pass_through_key, # cancel replace
K("Ctrl-Alt-f"): K("Ctrl-h"), # replace
K("C-M-v"): [K("C-k"), K("C-v")], # paste_from_history
}
```
In the above example I am also showing that you can define a single shortcut to enact multiple shortcut keys if needed by defining an array of shortcuts to trigger.
You can also make changes to the file in your /tmp/kinto/xkeysnail/kinto.py location and see them take affect in real time, but for your changes to be permanent you will need to make your changes in the ~/.config/kinto/kinto.py location & restart the xkeysnail service.
```
sudo systemctl restart xkeysnail
```
More information can be seen on the readme page of [xkeysnail](https://github.com/mooz/xkeysnail).
## Shortcut Creation (XKB)
The older xkb shortcut method info can be read about in ticket [#125](https://github.com/rbreaves/kinto/issues/125).
## Other Notes Related to Install
**Manjaro with Gnome there are issues.**
@@ -108,326 +149,46 @@ git pull origin master
Under systemd this is how you control Kinto.
Kinto (xkb/x11) = keyswap
Kinto (udev/xkeysnail/x11) = xkeysnail
Status
```
systemctl --user status keyswap
sudo systemctl status xkeysnail
```
Stop (your keymap will return to normal)
```
systemctl --user stop keyswap
sudo systemctl stop xkeysnail
```
Start
```
systemctl --user start keyswap
sudo systemctl start xkeysnail
```
Restart
```
systemctl --user restart keyswap
sudo systemctl restart xkeysnail
```
Enable
```
systemctl --user enable keyswap
sudo systemctl enable xkeysnail
```
Disable
```
systemctl --user disable keyswap
sudo systemctl disable xkeysnail
```
## 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.
https://github.com/rbreaves/kinto/issues/50#issuecomment-595953373
## 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)" };
...
};
```
3. 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"
]
}
```
4. 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":""
}]
}
```
## Learning macOS style hotkeys on Linux
@@ -442,13 +203,25 @@ systemctl --user stop keyswap && setxkbmap -option;setxkbmap -option altwin:swap
### Does not start when you log in or after you reboot?
Kinto (xkb/x11) = keyswap
Kinto (udev/xkeysnail/x11) = xkeysnail
1. Check the status
```
systemctl --user status keyswap
sudo systemctl status xkeysnail
```
2. Check the service journal
```
journalctl --user-unit=keyswap.service -b
sudo journalctl --unit=xkeysnail.service -b
```
Note: You can also watch your log live
```
journalctl -l --user-unit=keyswap.service -b
sudo journalctl -l --unit=xkeysnail.service -b
```
You may need to manually set your DISPLAY in the systemd service file. Normally it pulls in the proper DISPLAY value but if it doesn't you can try this.
@@ -460,6 +233,8 @@ echo $DISPLAY
```
nano ~/.config/systemd/user/keyswap.service
sudo nano /etc/systemd/system/xkeysnail.service
```
...
[Service]
@@ -473,18 +248,26 @@ If you continue to have issues then open a ticket and send me the info.
### Keyswap is not occurring, but it was working.
Now that Kinto is using a custom written C program I am not aware of any specific bugs or issues, but you can start here if you having difficulties and please report it if it is reproducible.
Kinto (xkb/x11) = keyswap
Kinto (udev/xkeysnail/x11) = xkeysnail
Now that Kinto (xkb/x11) is using a custom written C program I am not aware of any specific bugs or issues, but you can start here if you having difficulties and please report it if it is reproducible.
1. Get status
```
systemctl --user status keyswap
sudo systemctl status xkeysnail
```
2. Restart Kinto
```
systemctl --user restart keyswap
sudo systemctl restart xkeysnail
```
3. Check the Status again and open a ticket if you need to.
```
systemctl --user status keyswap
sudo systemctl status xkeysnail
```
You can also do the following to see if it is an actual issue with kintox11 not running or your service file.
@@ -497,12 +280,39 @@ cd ~/.config/kinto
If all else fails you can now run Kinto in debug mode as of 1.0.6-2. The output will become more verbose and I'd recommend running this directly after stopping the service.
Kinto (xkb/x11)
```
systemctl --user stop keyswap
cd ~/.config/kinto
./kintox11 --debug
```
Kinto (udev/xkeysnail)
Stop
```
sudo systemctl stop xkeysnail
```
nano ~/.config/kinto/xkeystart.sh
Remove the 2 instances of --quiet and resave
```
#!/bin/bash
/usr/local/bin/xkeysnail --quiet --watch "$1" &
inotifywait -m -e close_write,moved_to,create -q "$1" |
while read -r path; do
/usr/bin/killall xkeysnail
/usr/local/bin/xkeysnail --quiet --watch "$1" &
done
```
Start
```
sudo systemctl start xkeysnail
sudo systemctl status xkeysnail
```
## Language Support
I'd appreciate any help from people with non-US based keyboards, to help ensure that these keymaps and keyswap methods work in all or most languages.
@@ -547,5 +357,7 @@ Lastly these four people were also very helpful to me as well. @probonopd for be
If I left anyone out then I apologize, that was not intentional. I am happy to say that this project is at a state of completion. Bug fixes will primarily be the only activity happening going forward and possibly a rewrite for Wayland at some point. Contributions as mentioned above are welcomed, and will be merged into master if they help with the goal of making typing on linux more like a mac.
*https://askubuntu.com/questions/1010276/can-i-act-on-the-event-that-a-window-opens-without-polling
**https://gist.github.com/kui/2622504
***https://medium.com/@probonopd/make-it-simple-linux-desktop-usability-part-1-5fa0fb369b42

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python3
import json, time, os, sys
import json, time, os, sys, subprocess, shlex
from shutil import copyfile
from subprocess import PIPE, Popen
from prekinto import *
@@ -62,8 +62,12 @@ def setShortcuts():
if dename == "gnome":
cmdline('dconf dump /org/gnome/desktop/wm/keybindings/ > keybindings_`date +"%Y.%m.%d-%s"`.conf')
cmdline('dconf dump /org/gnome/mutter/keybindings/ > mutter_`date +"%Y.%m.%d-%s"`.conf')
cmdline("gsettings set org.gnome.desktop.wm.keybindings switch-applications \"['<Primary>F13','<Primary><Shift>F13','<Alt>Tab']\"")
cmdline("gsettings set org.gnome.desktop.wm.keybindings switch-applications-backward \"['<Primary>F14','<Primary><Shift>F14','<Alt><Shift>Tab']\"")
if(kintotype == 1):
cmdline("gsettings set org.gnome.desktop.wm.keybindings switch-applications \"['<Primary>Tools','<Alt>Tab']\"")
cmdline("gsettings set org.gnome.desktop.wm.keybindings switch-applications-backward \"['<Primary><Shift>Tools','<Alt><Shift>Tab']\"")
else:
cmdline("gsettings set org.gnome.desktop.wm.keybindings switch-applications \"['<Primary>F13','<Primary><Shift>F13','<Alt>Tab']\"")
cmdline("gsettings set org.gnome.desktop.wm.keybindings switch-applications-backward \"['<Primary>F14','<Primary><Shift>F14','<Alt><Shift>Tab']\"")
cmdline("gsettings set org.gnome.desktop.wm.keybindings minimize \"['<Super>h','<Alt>F9']\"")
cmdline("gsettings set org.gnome.desktop.wm.keybindings panel-main-menu \"['<Primary><Shift>Space','<Primary>Space']\"")
if distro == "ubuntu" and dename == "gnome":
@@ -83,8 +87,12 @@ def setShortcuts():
cmdline("gsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-left ['']")
cmdline("gsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-right ['']")
elif distro == "elementary" and dename == "gnome":
cmdline("gsettings set org.gnome.desktop.wm.keybindings switch-applications \"['<Primary>F13','<Primary><Shift>F13','<Alt>Tab']\"")
cmdline("gsettings set org.gnome.desktop.wm.keybindings switch-applications-backward \"['<Primary>F14','<Primary><Shift>F14','<Alt><Shift>Tab']\"")
if(kintotype == 1):
cmdline("gsettings set org.gnome.desktop.wm.keybindings switch-applications \"['<Primary>Tools','<Alt>Tab']\"")
cmdline("gsettings set org.gnome.desktop.wm.keybindings switch-applications-backward \"['<Primary><Shift>Tools','<Alt><Shift>Tab']\"")
else:
cmdline("gsettings set org.gnome.desktop.wm.keybindings switch-applications \"['<Primary>F13','<Primary><Shift>F13','<Alt>Tab']\"")
cmdline("gsettings set org.gnome.desktop.wm.keybindings switch-applications-backward \"['<Primary>F14','<Primary><Shift>F14','<Alt><Shift>Tab']\"")
cmdline("gsettings set org.gnome.desktop.wm.keybindings show-desktop \"['<Super>d','<Super>Down']\"")
cmdline("gsettings set org.gnome.desktop.wm.keybindings toggle-maximized \"['<Alt>F10','<Super>Up']\"")
cmdline("gsettings set org.gnome.desktop.wm.keybindings panel-main-menu \"['<Control><Shift>Space','<Super>Space']\"")
@@ -143,9 +151,13 @@ def setShortcuts():
cmdline('cp ~/.config/kglobalshortcutsrc ./kde_kglobalshortcutsrc_`date +"%Y.%m.%d-%s"`')
cmdline('kwriteconfig5 --file "$HOME/.config/kglobalshortcutsrc" --group "kwin" --key "Switch to Previous Desktop" "Meta+Left,Meta+Left,Switch to Previous Desktop"')
cmdline('kwriteconfig5 --file "$HOME/.config/kglobalshortcutsrc" --group "kwin" --key "Window Operations Menu" "none,Alt+F3,Window Operations Menu"')
cmdline('kwriteconfig5 --file "$HOME/.config/kglobalshortcutsrc" --group "kwin" --key "Walk Through Windows" "Ctrl+F13,Alt+Tab,Walk Through Windows"')
if(kintotype == 1):
cmdline('kwriteconfig5 --file "$HOME/.config/kglobalshortcutsrc" --group "kwin" --key "Walk Through Windows" "Ctrl+Tools,Alt+Tab,Walk Through Windows"')
cmdline('kwriteconfig5 --file "$HOME/.config/kglobalshortcutsrc" --group "kwin" --key "Walk Through Windows (Reverse)" "Ctrl+Shift+Tools,Alt+Shift+Backtab,Walk Through Windows (Reverse)"')
else:
cmdline('kwriteconfig5 --file "$HOME/.config/kglobalshortcutsrc" --group "kwin" --key "Walk Through Windows" "Ctrl+F13,Alt+Tab,Walk Through Windows"')
cmdline('kwriteconfig5 --file "$HOME/.config/kglobalshortcutsrc" --group "kwin" --key "Walk Through Windows (Reverse)" "Ctrl+Shift+F14,Alt+Shift+Backtab,Walk Through Windows (Reverse)"')
cmdline('kwriteconfig5 --file "$HOME/.config/kglobalshortcutsrc" --group "kwin" --key "Walk Through Windows Alternative" "none,none,Walk Through Windows"')
cmdline('kwriteconfig5 --file "$HOME/.config/kglobalshortcutsrc" --group "kwin" --key "Walk Through Windows (Reverse)" "Ctrl+Shift+F14,Alt+Shift+Backtab,Walk Through Windows (Reverse)"')
cmdline('kwriteconfig5 --file "$HOME/.config/kglobalshortcutsrc" --group "kwin" --key "Maximize Window" "none,Meta+PgUp,Maximize Window"')
cmdline('kwriteconfig5 --file "$HOME/.config/kglobalshortcutsrc" --group "kwin" --key "Window Maximize" "Meta+Ctrl+F,Alt+F10,Maximize Window"')
cmdline('kwriteconfig5 --file "$HOME/.config/kglobalshortcutsrc" --group "kwin" --key "Minimize Window" "Meta+h,Meta+PgDown,Minimize Window"')
@@ -338,10 +350,18 @@ if os.path.isdir(homedir + "/.config/kinto") == False:
with open('defaults.json') as json_file:
data = json.load(json_file)
color_arr = [bcolors.CBEIGE,bcolors.CRED2,bcolors.CGREEN,bcolors.CYELLOW ]
print("\nKinto - Type in Linux like it's a Mac.\n")
kintotype = int(input(color_arr[2] + "1) Kinto - xkeysnail (udev/x11) - Recommended\n" + color_arr[0] + "2) Kinto - Original xkb/x11 implementation\n\n" + bcolors.ENDC))
print("")
if(kintotype == 1):
setShortcuts()
subprocess.check_call(shlex.split("./xkeysnail_service.sh"))
exit()
for index, item in enumerate(data['defaulttypes']):
ossym = ""
if item == "windows":

View File

@@ -0,0 +1,78 @@
#!/bin/bash
for pid in $(pidof -x caret_status_xkey.sh); do
if [ $pid != $$ ]; then
echo "[$(date)] : caret_status_xkey.sh : Process is already running with PID $pid"
exit 1
fi
done
mkdir -p /tmp/kinto/xkeysnail
echo "0" > /tmp/kinto/caret
millitime=`date +%s%3N`
echo "$millitime" > /tmp/kinto/millitime
IBUSADD=$(cat ~/.config/ibus/bus/`ls ~/.config/ibus/bus -1rt | tail -n1` | awk -F'IBUS_ADDRESS=' '{print $2}' | xargs)
dbus-monitor --address $IBUSADD "path='/org/freedesktop/IBus/Panel',interface='org.freedesktop.IBus.Panel',member='FocusOut'" 2> /dev/null | grep --line-buffered -o -P '(?<=object path \"/org/freedesktop/IBus/InputContext_).*(?=[\"])' |
while read ln
do
newtime=`date +%s%3N`
difftime=$(( newtime - millitime ))
millitime="$newtime"
echo "$millitime" > /tmp/kinto/millitime
appname=$(xprop -id `xprop -root | grep "_NET_ACTIVE_WINDOW(WINDOW)" | awk '{print $5}'` | grep "WM_CLASS(STRING)" | awk '{print substr($4,2,length($4)-2)}')
if [ "${ln}" == "1" ]; then
appname=$(xprop -id `xprop -root | grep "_NET_ACTIVE_WINDOW(WINDOW)" | awk '{print $5}'` | grep "WM_CLASS(STRING)" | awk '{print substr($4,2,length($4)-2)}')
if [ "${appname}" == "Firefox" ]; then
# echo "ff ww"
printf 'ff ww %s\n' "1" > /tmp/kinto/caret
elif [ "${appname}" == "Chromium" ] || [ "${appname}" == "Chromium-browser" ] || [ "${appname}" == "Google-chrome" ] || [ "${appname}" == "Epiphany" ]; then
# echo "chrome ww"
printf 'chrome ww %s\n' "1" > /tmp/kinto/caret
else
echo "reset" > /tmp/kinto/caret
fi
else
if [ "${appname}" == "Firefox" ]; then
# echo "ff nw"
printf 'ff nw\n' > /tmp/kinto/caret
elif [ "${appname}" == "Chromium" ] || [ "${appname}" == "Chromium-browser" ] || [ "${appname}" == "Google-chrome" ] || [ "${appname}" == "Epiphany" ]; then
# echo "chrome nw"
printf 'chrome nw\n' > /tmp/kinto/caret
else
echo "reset" > /tmp/kinto/caret
fi
fi
done&
while (true);do
sleep 0.2
appname2=$(xprop -id `xprop -root | grep "_NET_ACTIVE_WINDOW(WINDOW)" | awk '{print $5}'` | grep "WM_CLASS(STRING)" | awk '{print substr($4,2,length($4)-2)}')
check=$(cat /tmp/kinto/caret)
millitime=$(cat /tmp/kinto/millitime)
newtime=`date +%s%3N`
difftime=$(( newtime - millitime ))
if (( $difftime > 200 )); then
if [ "${check}" == "ff nw" ] && [ "${lastcheck}" != 1 ]; then
echo "firefox no wordwise"
# Sets new config
perl -pi -e "s/[^\n]\s{3}(K.*)(# Chrome-nw)/ # \$1\$2/g;s/[^\n]\s{3}#\s(K.*)(# Firefox-nw)/ \$1\$2/g;s/[^\n]\s{3}(K.*)(# Beginning of Line)/ # \$1\$2/g;s/[^\n]\s{3}(K.*)(# End of Line)/ # \$1\$2/g" /tmp/kinto/xkeysnail/kinto.py 2>/dev/null
lastcheck=1
ww=0
elif [ "${check}" == "chrome nw" ] && [ "${lastcheck}" != 2 ]; then
echo "chrome no wordwise"
# Sets new config
perl -pi -e "s/[^\n]\s{3}(K.*)(# Firefox-nw)/ # \$1\$2/g;s/[^\n]\s{3}(K.*)(# Beginning of Line)/ # \$1\$2/g;s/[^\n]\s{3}(K.*)(# End of Line)/ # \$1\$2/g;s/[^\n]\s{3}#\s(K.*)(# Chrome-nw)/ \$1\$2/g" /tmp/kinto/xkeysnail/kinto.py 2>/dev/null
lastcheck=2
ww=0
elif ([ "${check}" != "chrome nw" ] && [ "${check}" != "ff nw" ] && [ "${lastcheck}" != 3 ]) || ([ "${appname2}" != "Firefox" ] && [ "${appname2}" != "Chromium" ] && [ "${appname2}" != "Chromium-browser" ] && [ "${appname2}" != "Google-chrome" ] && [ "${appname2}" != "Epiphany" ] && [ "${check}" == "reset" ] && [ "${lastcheck}" != 3 ]); then
echo "wordwise"
# Sets original config
perl -pi -e "s/[^\n]\s{3}(K.*)(# Firefox-nw)/ # \$1\$2/g;s/[^\n]\s{3}#\s(K.*)(# Beginning of Line)/ \$1\$2/g;s/[^\n]\s{3}#\s(K.*)(# End of Line)/ \$1\$2/g;s/[^\n]\s{3}(K.*)(# Chrome-nw)/ # \$1\$2/g" /tmp/kinto/xkeysnail/kinto.py 2>/dev/null
# cp /home/ryan/.config/kinto/kinto.py /tmp/kinto/xkeysnail/kinto.py
lastcheck=3
fi
fi
done

21
system-config/unipkg.sh Executable file
View File

@@ -0,0 +1,21 @@
#!/bin/bash
if pkgmgr="$( which apt-get )" 2> /dev/null; then
echo "Debian"
$pkgmgr update
$pkgmgr --yes --force-yes install "$1"
elif pkgmgr="$( which dnf )" 2> /dev/null; then
echo "dnf"
$pkgmgr check-update; $pkgmgr install -y "$1"
elif pkgmgr="$( which pacman )" 2> /dev/null; then
echo "Arch-based"
$pkgmgr -Syy;yes | $pkgmgr -S "$1"
else
echo "Package manager not found, please install $1" >&2
exit 1
fi
if [[ 1 -ne $# ]]; then
echo "Syntax: $0 PACKAGE"
exit 1
fi
exit $?

View File

@@ -11,13 +11,13 @@ define_conditional_modmap(lambda wm_class: wm_class not in ("Gnome-terminal","ko
# Key.RIGHT_ALT: Key.RIGHT_CTRL, # Chromebook
# Key.RIGHT_CTRL: Key.RIGHT_ALT, # Chromebook
# Default Mac/Win
Key.LEFT_ALT: Key.RIGHT_CTRL, # WinMac
Key.LEFT_META: Key.LEFT_ALT, # WinMac
Key.LEFT_CTRL: Key.LEFT_META, # WinMac
Key.RIGHT_ALT: Key.RIGHT_CTRL, # WinMac
Key.RIGHT_META: Key.RIGHT_ALT, # WinMac
Key.RIGHT_CTRL: Key.RIGHT_META, # WinMac
# # Default Mac/Win
# Key.LEFT_ALT: Key.RIGHT_CTRL, # WinMac
# Key.LEFT_META: Key.LEFT_ALT, # WinMac
# Key.LEFT_CTRL: Key.LEFT_META, # WinMac
# Key.RIGHT_ALT: Key.RIGHT_CTRL, # WinMac
# Key.RIGHT_META: Key.RIGHT_ALT, # WinMac
# Key.RIGHT_CTRL: Key.RIGHT_META, # WinMac
# # Mac Only
# Key.LEFT_META: Key.RIGHT_CTRL, # Mac
@@ -27,22 +27,22 @@ define_conditional_modmap(lambda wm_class: wm_class not in ("Gnome-terminal","ko
})
# [Conditional modmap] Change modifier keys in certain applications
define_conditional_modmap(re.compile("Gnome-terminal|konsole|io.elementary.terminal|terminator|sakura|guake|tilda|xterm|eterm|kitty"), {
define_conditional_modmap(re.compile("Gnome-terminal|konsole|Io.elementary.terminal|terminator|sakura|guake|tilda|xterm|eterm|kitty"), {
# # Chromebook
# Key.LEFT_ALT: Key.RIGHT_CTRL,
# Key.LEFT_ALT: Key.RIGHT_CTRL, # Chromebook
# # Left Ctrl Stays Left Ctrl
# Key.LEFT_META: Key.LEFT_ALT,
# Key.RIGHT_ALT: Key.RIGHT_CTRL,
# Key.RIGHT_CTRL: Key.RIGHT_ALT,
# Key.LEFT_META: Key.LEFT_ALT, # Chromebook
# Key.RIGHT_ALT: Key.RIGHT_CTRL, # Chromebook
# Key.RIGHT_CTRL: Key.RIGHT_ALT, # Chromebook
# # Right Meta does not exist on chromebooks
# Default Mac/Win
Key.LEFT_ALT: Key.RIGHT_CTRL, # WinMac
Key.LEFT_META: Key.LEFT_ALT, # WinMac
Key.LEFT_CTRL: Key.LEFT_CTRL, # WinMac
Key.RIGHT_ALT: Key.RIGHT_CTRL, # WinMac
Key.RIGHT_META: Key.RIGHT_ALT, # WinMac
Key.RIGHT_CTRL: Key.LEFT_CTRL, # WinMac
# # Default Mac/Win
# Key.LEFT_ALT: Key.RIGHT_CTRL, # WinMac
# Key.LEFT_META: Key.LEFT_ALT, # WinMac
# Key.LEFT_CTRL: Key.LEFT_CTRL, # WinMac
# Key.RIGHT_ALT: Key.RIGHT_CTRL, # WinMac
# Key.RIGHT_META: Key.RIGHT_ALT, # WinMac
# Key.RIGHT_CTRL: Key.LEFT_CTRL, # WinMac
# # Mac Only
# Key.LEFT_META: Key.RIGHT_CTRL, # Mac
@@ -51,6 +51,98 @@ define_conditional_modmap(re.compile("Gnome-terminal|konsole|io.elementary.termi
# Key.RIGHT_CTRL: Key.LEFT_CTRL, # Mac
})
# Keybindings for Nautilus
define_keymap(re.compile("Org.gnome.Nautilus"),{
K("RC-Up"): K("M-Up"), # Go Up dir
K("RC-Down"): K("M-Down"), # Go Down dir
K("RC-Left"): K("M-Left"), # Go Back
K("RC-Right"): K("M-Right"), # Go Forward
})
define_keymap(None,{
# Cmd Tab - App Switching Default
K("RC-Tab"): K("RC-F13"), # Default
K("RC-Shift-Tab"): K("RC-Shift-F13"), # Default
K("RC-Grave"): K("RC-Shift-F13"), # Default
# K("RC-Tab"): K("RC-backslash"), # Chromebook
# K("RC-Shift-Tab"): K("RC-Shift-backslash"), # Chromebook
# K("RC-Grave"): K("RC-Shift-backslash"), # Chromebook
# In-App Tab switching
# K("M-Tab"): K("C-Tab"), # Chromebook - In-App Tab switching
# K("M-Shift-Tab"): K("C-Shift-Tab"), # Chromebook - In-App Tab switching
# K("M-Grave") : K("C-Shift-Tab"), # Chromebook - In-App Tab switching
K("Super-Tab"): K("LC-Tab"), # Default
K("Super-Shift-Tab"): K("LC-Shift-Tab"), # Default
K("LC-Grave") : K("LC-Shift-Tab"), # Default
# Wordwise
K("RC-Left"): K("Home"), # Beginning of Line
K("RC-Shift-Left"): K("Shift-Home"), # Select all to Beginning of Line
K("RC-Right"): K("End"), # End of Line
K("RC-Shift-Right"): K("Shift-End"), # Select all to End of Line
# K("RC-Left"): K("C-LEFT_BRACE"), # Firefox-nw - Back
# K("RC-Right"): K("C-RIGHT_BRACE"), # Firefox-nw - Forward
# K("RC-Left"): K("M-LEFT"), # Chrome-nw - Back
# K("RC-Right"): K("M-RIGHT"), # Chrome-nw - Forward
K("RC-Up"): K("C-Home"), # Beginning of File
K("RC-Shift-Up"): K("C-Shift-Home"), # Select all to Beginning of File
K("RC-Down"): K("C-End"), # End of File
K("RC-Shift-Down"): K("C-Shift-End"), # Select all to End of File
K("M-Backspace"): K("Delete"), # Delete
# K(""): pass_through_key, # cancel
# K(""): K(""), #
})
define_keymap(lambda wm_class: wm_class not in ("Code"),{
# Wordwise remaining - for Everything but VS Code
K("M-Left"): K("C-Left"), # Left of Word
K("M-Shift-Left"): K("C-Shift-Left"), # Select Left of Word
K("M-Right"): K("C-Right"), # Right of Word
K("M-Shift-Right"): K("C-Shift-Right"), # Select Right of Word
# ** VS Code fix **
# Electron issue precludes normal keybinding fix.
# Alt menu auto-focus/toggle gets in the way.
#
# refer to ./xkeysnail-config/vscode_keybindings.json
# **
#
# ** Firefox fix **
# User will need to set "ui.key.menuAccessKeyFocuses"
# under about:config to false.
#
# https://superuser.com/questions/770301/pentadactyl-how-to-disable-menu-bar-toggle-by-alt
# **
#
})
# Keybindings for VS Code
define_keymap(re.compile("Code"),{
# Wordwise remaining - for VS Code
# Alt-F19 hack fixes Alt menu activation
K("M-Left"): [K("M-F19"),K("C-Left")], # Left of Word
K("M-Right"): [K("M-F19"),K("C-Right")], # Right of Word
K("M-Shift-Left"): [K("M-F19"),K("C-Shift-Left")], # Select Left of Word
K("M-Shift-Right"): [K("M-F19"),K("C-Shift-Right")], # Select Right of Word
# VS Code Shortcuts
K("C-g"): pass_through_key, # cancel Go to Line...
K("Super-g"): K("C-g"), # Go to Line...
K("F3"): pass_through_key, # cancel Find next
K("C-h"): pass_through_key, # cancel replace
K("C-M-f"): K("C-h"), # replace
K("C-Shift-h"): pass_through_key, # cancel replace_next
K("C-M-e"): K("C-Shift-h"), # replace_next
K("f3"): pass_through_key, # cancel find_next
K("C-g"): K("f3"), # find_next
K("Shift-f3"): pass_through_key, # cancel find_prev
K("C-Shift-g"): K("Shift-f3"), # find_prev
K("Super-C-g"): K("C-f2"), # Sublime - find_all_under
K("Super-Shift-up"): K("M-Shift-up"), # multi-cursor up
K("Super-Shift-down"): K("M-Shift-down"), # multi-cursor down
# K(""): pass_through_key, # cancel
# K(""): K(""), #
}, "Code")
# Keybindings for Sublime Text
define_keymap(re.compile("Sublime_text"),{
K("C-Super-up"): K("M-o"), # Switch file
@@ -60,6 +152,8 @@ define_keymap(re.compile("Sublime_text"),{
K("Super-M-up"): K("C-up"), # scroll_lines up
K("C-down"): pass_through_key, # cancel scroll_lines down
K("Super-M-down"): K("C-down"), # scroll_lines down
K("Super-Shift-up"): K("M-Shift-up"), # multi-cursor up
K("Super-Shift-down"): K("M-Shift-down"), # multi-cursor down
K("C-PAGE_DOWN"): pass_through_key, # cancel next_view
K("C-PAGE_UP"): pass_through_key, # cancel prev_view
K("C-Shift-left_brace"): K("C-PAGE_DOWN"), # next_view
@@ -114,36 +208,6 @@ define_keymap(re.compile("Sublime_text"),{
# K(""): K(""), #
}, "Sublime Text")
define_keymap(None,{
# Cmd Tab - App Switching Default
K("RC-Tab"): K("RC-F13"),
K("RC-Shift-Tab"): K("RC-Shift-F13"),
K("RC-Grave"): K("RC-Shift-F13"),
# In-App Tab switching
# K("M-Tab"): K("C-Tab"), # Chromebook
# K("M-Shift-Tab"): K("C-Shift-Tab"), # Chromebook
K("Super-Tab"): K("LC-Tab"), # Default
K("Super-Shift-Tab"): K("LC-Shift-Tab"), # Default
K("LC-Grave") : K("LC-Shift-Tab"), # Default
# Wordwise
K("RC-Left"): K("Home"), # Beginning of Line
K("RC-Right"): K("End"), # End of Line
K("M-Left"): K("C-Left"), # Left of Word
K("M-Right"): K("C-Right"), # Right of Word
K("RC-Up"): K("C-Home"), # Beginning of File
K("RC-Down"): K("C-End"), # End of File
K("M-Backspace"): K("Delete"), # Delete
# K(""): pass_through_key, # cancel
# K(""): K(""), #
})
# define_keymap(re.compile("Gnome-terminal|io.elementary.terminal|terminator|sakura|guake|tilda|xterm|eterm|kitty"),{
# # Ctrl Tab - In App Tab Switching
# # LC is already set
# K("LC-Grave") : K("LC-Shift-Tab"),
# }, "Terminals tab switching")
define_keymap(re.compile("konsole"),{
# Ctrl Tab - In App Tab Switching
K("LC-Tab") : K("Shift-Right"),
@@ -152,13 +216,19 @@ define_keymap(re.compile("konsole"),{
}, "Konsole tab switching")
define_keymap(re.compile("Gnome-terminal|konsole|io.elementary.terminal|terminator|sakura|guake|tilda|xterm|eterm|kitty"),{
define_keymap(re.compile("Io.elementary.terminal"),{
# Ctrl Tab - In App Tab Switching
K("LC-Tab") : K("LC-PAGE_DOWN"),
K("LC-Shift-Tab") : K("LC-PAGE_UP"),
K("LC-Grave") : K("LC-PAGE_UP"),
K("LC-Tab") : K("LC-Shift-Right"),
K("LC-Shift-Tab") : K("LC-Shift-Left"),
K("LC-Grave") : K("LC-Shift-Left"),
}, "Elementary Terminal tab switching")
define_keymap(re.compile("Gnome-terminal|konsole|Io.elementary.terminal|terminator|sakura|guake|tilda|xterm|eterm|kitty"),{
# Ctrl Tab - In App Tab Switching
# K("LC-Tab") : K("LC-PAGE_DOWN"),
# K("LC-Shift-Tab") : K("LC-PAGE_UP"),
# K("LC-Grave") : K("LC-PAGE_UP"),
# Converts Cmd to use Ctrl-Shift
K("RC-Tab"): K("RC-F13"),
K("RC-Shift-Tab"): K("RC-Shift-F13"),
@@ -203,8 +273,3 @@ define_keymap(re.compile("Gnome-terminal|konsole|io.elementary.terminal|terminat
K("RC-SLASH"): K("C-Shift-SLASH"),
K("RC-KPASTERISK"): K("C-Shift-KPASTERISK"),
}, "terminals")
# define_keymap(re.compile("Chromium-browser"),{
# # K("RC-Tab"): K("C-F13"),
# # K("RC-Shift-Tab"): K("C-f1"),
# }, "Chromium-browser")

View File

@@ -0,0 +1,5 @@
# /etc/sudoers.d/limitedadmins
%{username} ALL=NOPASSWD: {systemctl} restart xkeysnail
%{username} ALL=NOPASSWD: {systemctl} start xkeysnail
%{username} ALL=NOPASSWD: {systemctl} stop xkeysnail
%{username} ALL=NOPASSWD: {systemctl} status xkeysnail

14
xkeysnail-config/prexk.sh Executable file
View File

@@ -0,0 +1,14 @@
#!/bin/bash
if [ -f /home/{username}/.config/systemd/user/keyswap.timer ]; then
systemctl --user stop keyswap.timer >/dev/null 2>&1
systemctl --user disable keyswap.timer >/dev/null 2>&1
fi
if [ -f /home/{username}/.config/systemd/user/keyswap.service ]; then
systemctl --user stop keyswap >/dev/null 2>&1
systemctl --user disable keyswap >/dev/null 2>&1
fi
# export DISPLAY={displayid};/usr/bin/xhost +SI:localuser:root
mkdir -p /tmp/kinto/xkeysnail
cp /home/{username}/.config/kinto/kinto.py /tmp/kinto/xkeysnail/kinto.py

View File

@@ -0,0 +1,8 @@
[Desktop Entry]
Name=Kinto_xkey
GenericName=Kinto_xkey
Comment=Make Linux Type Like it's a Mac
Exec=/bin/bash -c "{xhost} +SI:localuser:root && sudo {systemctl} restart xkeysnail"
Terminal=false
Type=Application
X-GNOME-Autostart-enabled=true

View File

@@ -0,0 +1,15 @@
[Unit]
Description=xkeysnail
[Service]
Type=simple
KillMode=process
ExecStartPre=/bin/bash -c "{xhost} +SI:localuser:root && /sbin/runuser -l {username} -c /home/{username}/.config/kinto/prexk.sh"
ExecStart=/usr/bin/sudo /bin/bash -c '{experimental-caret}/home/{username}/.config/kinto/xkeystart.sh /tmp/kinto/xkeysnail/kinto.py'
ExecStop=/bin/bash -c 'me=$$;ps -ef | grep \'[t]mp/kinto\' | awk -v me=$me \'$2 != me {print $2}\' | xargs kill;/usr/bin/killall dbus-monitor;/usr/bin/killall xkeysnail;{kill-caret}'
Restart=on-failure
RestartSec=3
Environment=DISPLAY={displayid}
[Install]
WantedBy=graphical.target

19
xkeysnail-config/xkeystart.sh Executable file
View File

@@ -0,0 +1,19 @@
#!/bin/bash
# >/dev/null 2>&1
if [ -f /usr/local/bin/xkeysnail ];then
xkeyfullpath="/usr/local/bin/xkeysnail"
elif [ -f /usr/bin/xkeysnail ];then
xkeyfullpath="/usr/bin/xkeysnail"
else
xkeyfullpath=`which xkeysnail`
fi
"$xkeyfullpath" --quiet --watch "$1" &
inotifywait -m -e close_write,moved_to,create,modify /tmp/kinto/xkeysnail |
while read -r path; do
/usr/bin/killall xkeysnail
"$xkeyfullpath" --quiet --watch "$1" &
done

263
xkeysnail_service.sh Executable file
View File

@@ -0,0 +1,263 @@
#!/bin/bash
# set about:config?filter=ui.key.menuAccessKeyFocuses
# to false for wordwise to work in Firefox
typeset -l distro
distro=$(awk -F= '$1=="NAME" { print $2 ;}' /etc/os-release)
function uninstall {
typeset -l dename
dename=$(./system-config/dename.sh | cut -d " " -f1)
while true; do
read -rep $'\nPress R to restore your original shortcuts.\nPress F to reset to factory shortcuts. (f/r)\n' yn
case $yn in
[Ff]* ) yn="f"; break;;
[Rr]* ) yn="r";break;;
* ) echo "Please answer yes or no.";;
esac
done
if [ "$yn" == "f" ];then
echo "Reset to factory shortcuts"
if [ "$dename" == "gnome" ];then
echo "Resetting DE hotkeys..."
echo "gsettings reset-recursively org.gnome.desktop.wm.keybindings"
gsettings reset-recursively org.gnome.desktop.wm.keybindings
echo "gsettings reset-recursively org.gnome.mutter.keybindings"
gsettings reset-recursively org.gnome.mutter.keybindings
elif [ "$dename" == "kde" ];then
echo "Resetting DE hotkeys..."
mv ~/.config/kwinrc ~/.config/kwinrc.kinto
mv ~/.config/kglobalshortcutsrc ~/.config/kglobalshortcutsrc.kinto
elif [ "$dename" == "xfce" ];then
echo "Resetting DE hotkeys..."
cp /etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-keyboard-shortcuts.xml ~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-keyboard-shortcuts.xml
fi
elif [ "$yn" == "r" ]; then
echo "Restore original user shortcuts"
if [ "$dename" == "gnome" ]; then
echo "Restoring DE hotkeys..."
wmkeys=$(ls | grep -m1 "keybinding")
mutterkeys=$(ls | grep -m1 "mutter")
if [[ ${#wmkeys} > 0 ]]; then
echo "dconf load /org/gnome/desktop/wm/keybindings/ < $wmkeys"
dconf load /org/gnome/desktop/wm/keybindings/ < "$wmkeys"
else
echo "Gnome Desktop keybindings backup not found..."
fi
if [[ ${#mutterkeys} > 0 ]]; then
echo "dconf load /org/gnome/mutter/keybindings/ < $mutterkeys"
dconf load /org/gnome/mutter/keybindings/ <"$mutterkeys"
fi
if [[ ${#wmkeys} > 0 ]] || [[ ${#mutterkeys} > 0 ]]; then
echo "Gnome hotkeys have been successfully restored."
fi
elif [ "$dename" == "kde" ]; then
echo "Restoring DE hotkeys..."
kwinkeys = $(ls | grep -m1 "kwinrc")
kdekeys = $(ls | grep -m1 "kglobalshortcutsrc")
cp ./"$kdekeys" ~/.config/kglobalshortcutsrc
cp ./"$kwinkeys" ~/.config/kwinrc
elif [ "$dename" == "xfce" ]; then
echo "Restoring DE hotkeys..."
xfcekeys = $(ls | grep -m1 "xfce4-keyboard")
cp ./"$xfcekeys" ~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-keyboard-shortcuts.xml
fi
fi
}
if [ $# -eq 0 ]; then
echo "Install Kinto - xkeysnail (udev)"
echo " 1) Windows & Mac (HID driver)"
echo " 2) Mac Only & VMs on Macbooks"
echo " 3) Chromebook"
echo " 4) Uninstall"
read n
set "$n"
fi
if [[ $1 == "1" || $1 == "2" || $1 == "3" || $1 == "winmac" || $1 == "mac" || $1 == "chromebook" ]]; then
branch=$(git rev-parse --abbrev-ref HEAD)
if [ "$branch" == "dev" ] || [ "$branch" == "alpha" ];then
while true; do
read -rep $'\nExperimental Support for Firefox/Chrome Back/Forward hotkeys (Cmd+Left/Right)?\n(Keys could get stuck, switch windows or press ctrl &/or super to release) (y/n)\n' yn
case $yn in
[Yy]* ) exp='/sbin/runuser -l {username} -c "export DISPLAY={displayid};/home/{username}/.config/kinto/caret_status_xkey.sh\&";'; expsh='"/home/{username}/.config/kinto/caret_status_xkey.sh"'; break;;
[Nn]* ) exp=" "; expsh=" " break;;
# * ) echo "Please answer yes or no.";;
esac
done
else
echo -e "\nSupport for Firefox/Chrome Back/Forward hotkeys (Cmd+Left/Right) disabled on $branch w/ xkeysnail \n"
exp=" "
expsh=" "
fi
sudo systemctl enable xkeysnail >/dev/null 2>&1
if ! [ -x "$(command -v inotifywait)" ]; then
echo "Will need to install inotify-tools to restart key remapper live for config file changes..."
sudo ./system-config/unipkg.sh inotify-tools
fi
if ! [ -x "$(command -v pip3)" ]; then
echo "Will need to install python3-pip..."
sudo ./system-config/unipkg.sh python3-pip
fi
if ! [ -x "$(command -v python3-config)" ]; then
if [ "$distro" == "ubuntu" ] || [ "$distro" == "debian" ]; then
pydev="python3-dev"
elif [ "$distro" == "fedora" ]; then
pydev="python3-devel"
fi
if [ "$distro" == "gnome" ] || [ "$distro" == "fedora" ] || [ "$distro" == "debian" ]; then
echo "Will need to install $pydev..."
sudo ./system-config/unipkg.sh "$pydev"
fi
fi
if ! [ -x "$(command -v xhost)" ]; then
if [ "$distro" == "\"manjaro linux\"" ]; then
sudo ./system-config/unipkg.sh xorg-xhost
fi
fi
# echo "Transferring files..."
mkdir -p ~/.config/kinto
# KDE xhost fix
mkdir -p ~/.kde/Autostart
echo -e '#!/bin/sh\rxhost +SI:localuser:root' > ~/.kde/Autostart/kintohost.sh
chmod +x ~/.kde/Autostart/kintohost.sh
# KDE startup - xhost fix
yes | cp -rf ./xkeysnail-config/xkeysnail.desktop ~/.config/autostart/xkeysnail.desktop
yes | cp -rf ./xkeysnail-config/xkeystart.sh ~/.config/kinto/xkeystart.sh
yes | cp -rf ./xkeysnail-config/kinto.py ./xkeysnail-config/kinto.py.new
yes | cp -rf ./xkeysnail-config/limitedadmins ./xkeysnail-config/limitedadmins.new
yes | cp -rf ./xkeysnail-config/prexk.sh ~/.config/kinto/prexk.sh
yes | cp -rf ./system-config/caret_status_xkey.sh ~/.config/kinto/caret_status_xkey.sh
yes | cp -rf ./xkeysnail-config/xkeysnail.service ./xkeysnail-config/xkeysnail.service.new
# yes | cp -rf ./xkeysnail-config/xkeysnail.timer ~/.config/systemd/user/xkeysnail.timer
sed -i "s#{experimental-caret}#$exp#g" ./xkeysnail-config/xkeysnail.service.new
if [ "$expsh" != " " ];then
sed -i "s#{kill-caret}#/usr/bin/pkill -f $expsh#g" ./xkeysnail-config/xkeysnail.service.new
else
sed -i "s#{kill-caret}#$expsh#g" ./xkeysnail-config/xkeysnail.service.new
fi
sed -i "s/{username}/`whoami`/g" ./xkeysnail-config/xkeysnail.service.new
sed -i "s#{xhost}#`which xhost`#g" ./xkeysnail-config/xkeysnail.service.new
sed -i "s/{username}/`whoami`/g" ./xkeysnail-config/limitedadmins.new
sed -i "s#{systemctl}#`which systemctl`#g" ./xkeysnail-config/limitedadmins.new
sudo chown root:root ./xkeysnail-config/limitedadmins.new
sudo mv ./xkeysnail-config/limitedadmins.new /etc/sudoers.d/limitedadmins
sed -i "s#{systemctl}#`which systemctl`#g" ~/.config/autostart/xkeysnail.desktop
sed -i "s#{xhost}#`which xhost`#g" ~/.config/autostart/xkeysnail.desktop
sed -i "s/{username}/`whoami`/g" ~/.config/kinto/prexk.sh
sed -i "s/{displayid}/`echo "$DISPLAY"`/g" ./xkeysnail-config/xkeysnail.service.new
sed -i "s/{displayid}/`echo "$DISPLAY"`/g" ~/.config/kinto/prexk.sh
elif ! [[ $1 == "4" || $1 == "uninstall" ]]; then
echo "Expected argument was not provided"
fi
if [[ $1 == "1" || $1 == "winmac" ]]; then
echo '1' | sudo tee -a /sys/module/hid_apple/parameters/swap_opt_cmd;echo 'options hid_apple swap_opt_cmd=1' | sudo tee -a /etc/modprobe.d/hid_apple.conf;sudo update-initramfs -u -k all
perl -pi -e "s/(# )(.*)(# WinMac)/\$2\$3/g" ./xkeysnail-config/kinto.py.new
elif [[ $1 == "2" || $1 == "mac" ]]; then
perl -pi -e "s/(# )(.*)(# Mac)/\$2\$3/g" ./xkeysnail-config/kinto.py.new
elif [[ $1 == "3" || $1 == "chromebook" ]]; then
perl -pi -e "s/(# )(.*)(# Chromebook)/\$2\$3/g" ./xkeysnail-config/kinto.py.new
perl -pi -e "s/(\w.*)(# Default)/# \$1\$2/g" ./xkeysnail-config/kinto.py.new
fi
if [[ $1 == "1" || $1 == "2" || $1 == "3" || $1 == "winmac" || $1 == "mac" || $1 == "chromebook" ]]; then
mv ./xkeysnail-config/kinto.py.new ~/.config/kinto/kinto.py
# if [ "$distro" == "fedora" ];then
sudo rm /etc/systemd/system/xkeysnail.service
if [ -d /usr/lib/systemd/system ];then
xkeypath="/usr/lib/systemd/system/"
elif [ -d /lib/systemd/system ];then
xkeypath="/lib/systemd/system/"
fi
sudo mv ./xkeysnail-config/xkeysnail.service.new "$xkeypath"xkeysnail.service && echo "Service file added to "$xkeypath"xkeysnail.service"
sudo chown -R root:root "$xkeypath"xkeysnail.service && echo "Ownership set for root..." || echo "Failed to set ownership..."
sudo chmod 644 "$xkeypath"xkeysnail.service && echo "Permissions set to 644..." || echo "Failed to set permissions..."
sudo ln -s "$xkeypath"xkeysnail.service /etc/systemd/system/xkeysnail.service && echo "Created soft symlink..." || echo "Failed to create soft symlink..."
sudo ln -s "$xkeypath"xkeysnail.service /etc/systemd/system/graphical.target.wants/xkeysnail.service && echo "Created soft symlink for graphical target..." || echo "Failed to create soft symlink for graphical target..."
xhost +SI:localuser:root
git clone --depth 1 https://github.com/rbreaves/xkeysnail.git
cd xkeysnail
giturl=$(git ls-remote --get-url)
if [ "$geturl" != "https://github.com/rbreaves/xkeysnail.git" ];then
cd ..
rm -rf ./xkeysnail
git clone --depth 1 https://github.com/rbreaves/xkeysnail.git
cd xkeysnail
fi
git pull origin master
sudo pip3 install --upgrade .
sudo systemctl daemon-reload
sudo systemctl --state=not-found --all | grep xkeysnail
if [ "$distro" == "fedora" ];then
systemctl enable xkeysnail.service
else
sudo systemctl enable xkeysnail.service
fi
sudo systemctl restart xkeysnail
echo -e "Adding xhost fix...\n"
LINE='xhost +SI:localuser:root'
if [ ! -e "~/.xprofile" ]; then
# Ubuntu xhost fix
echo "$LINE" > ~/.xprofile
# echo "$LINE" > ~/.xinitrc
fi
# Ubuntu xhost fix
grep -qF -- "$LINE" ~/.xprofile || echo "$LINE" >> ~/.xprofile
# KDE xhost fix
# grep -qF -- "$LINE" ~/.bashrc || echo "$LINE" >> ~/.bashrc
# grep -qF -- "$LINE" ~/.xinitrc || echo "$LINE" >> ~/.xinitrc
# remove kintox11 login startup
if test -f "~/.config/autostart/kinto.desktop"; then
rm ~/.config/autostart/kinto.desktop
fi
echo -e "Kinto install is \e[1m\e[32mcomplete\e[0m.\n"
if `sudo systemctl is-active --quiet xkeysnail`;then
echo -e "Kinto \e[1m\e[32mxkeysnail service is running\e[0m.\n"
echo "Commands for controlling Kinto's xkeysnail service"
echo "sudo systemctl restart xkeysnail"
echo "sudo systemctl stop xkeysnail"
echo "sudo systemctl start xkeysnail"
echo "sudo systemctl status xkeysnail"
else
echo -e "Kinto \e[1m\e[91mxkeysnail service has failed.\e[0m"
echo "You can run 'sudo systemctl status xkeysnail' for more info"
echo "You can also run 'sudo journalctl -u xkeysnail'"
fi
elif ! [[ $1 == "4" || $1 == "uninstall" ]]; then
echo "Expected argument was not provided"
else
echo "Uninstalling Kinto - xkeysnail (udev)"
uninstall
# Undo Apple keyboard cmd & alt swap
if test -f "/sys/module/hid_apple/parameters/swap_opt_cmd" && [ `cat /sys/module/hid_apple/parameters/swap_opt_cmd` == "1" ]; then
echo '0' | sudo tee -a /sys/module/hid_apple/parameters/swap_opt_cmd
echo 'options hid_apple swap_opt_cmd=0' | sudo tee -a /etc/modprobe.d/hid_apple.conf
sudo update-initramfs -u -k all
fi
sudo systemctl stop xkeysnail
sudo systemctl disable xkeysnail
sudo rm /etc/sudoers.d/limitedadmins
rm ~/.config/autostart/xkeysnail.desktop
rm -rf ~/.config/kinto
sudo rm /etc/systemd/system/xkeysnail.service
sudo rm /etc/systemd/system/graphical.target.wants/xkeysnail.service
sudo rm /usr/lib/systemd/system/xkeysnail.service
sudo systemctl daemon-reload
sudo systemctl --state=not-found --all | grep xkeysnail
exit 0
fi