I like Alt + Left/Right to change the tab while in a browser but to do what they normally do in other programs. Most browsers don't let you have custom keybindings (they almost always use Ctrl + PgUp/PgDn, which on my keyboard is Ctrl + Fn + Up/Down) so I'm stuck with an OS level solution: bind Alt + Left/Right to do Ctrl + PgUp/PgDn if the current window is a browser and to be themselves otherwise. In X11 I accomplished this with AutoKey, but I want a solution that works in Wayland. Heres where I'm at, key-mapper doesn't allow bash commands, Hawck might work (I haven't tried it), KMonad isn't quite flexible enough with Bash scripts, wtype and ydotool didn't work for me but evemu-event did (I found it here), I can get the current window name using
gdbus call \
--session \
--dest org.gnome.Shell \
--object-path /org/gnome/Shell \
--method org.gnome.Shell.Eval "
global
.get_window_actors()
.map(a=>a.meta_window)
.find(w=>w.has_focus())
.get_wm_class()" \
| cut -d'"' -f 2
which I found from here. That means I can make this script
#!/bin/bash
# setsid --fork gnome-terminal
# Checks if the current window is Google Chrome (could be adapted for Firefox)
# and if it is then sends a Ctrl + PgUp key (moves the tab focus one tab to the left)
# Its intended to be called by a key management thing (KMonad for example) when Alt + Left is hit
# This is how I simulate key presses
# Taken from here: https://unix.stackexchange.com/questions/381831/keyboard-emulation-in-wayland
# Needs sudo apt install evemu-tools
function type_key() {
EVDEVICE=/dev/input/event4
# press the keys down in sequtial order
for key in $@; do
evemu-event $EVDEVICE --type EV_KEY --code KEY_$key --value 1 --sync
done
# lift the keys up in sequential order
for (( idx=${#@}; idx>0; idx-- )); do
evemu-event $EVDEVICE --type EV_KEY --code KEY_${!idx} --value 0 --sync
done
}
# Also look into https://github.com/sezanzeb/key-mapper, it can't do bash commands but otherwise
# looks pretty good for this stuff
# I know of no way to get the window name in Wayland generally, I can do it if we're in Gnome
# Taken from here: https://unix.stackexchange.com/questions/399753/how-to-get-a-list-of-active-windows-when-using-wayland
WINDOW_CLASS=$(gdbus call \
--session \
--dest org.gnome.Shell \
--object-path /org/gnome/Shell \
--method org.gnome.Shell.Eval "
global
.get_window_actors()
.map(a=>a.meta_window)
.find(w=>w.has_focus())
.get_wm_class()" \
| cut -d'"' -f 2)
# Use "Google-chrome" for Chrome and "firefox" for Firefox
if [[ "$WINDOW_CLASS" = "gnome-terminal-server" ]] || [[ "$WINDOW_CLASS" = "Google-chrome" ]] || [[ "$WINDOW_CLASS" = "firefox" ]]
then
type_key RIGHTCTRL PAGEUP
else
type_key RIGHTALT LEFT
fi
# Check out web app manager
# https://ubuntuhandbook.org/index.php/2021/01/install-linux-mints-web-app-manager-ubuntu-20-04/
and use Gnome Settings -> KeyBoard Shortcuts -> Custom Shortcuts -> + to bind Alt + Left to the above script (it requires giving the script a "sudo pass", as done here). However, although the script does switch tabs when executed from Gnome Terminal, it doesn't switch tabs in Google Chrome (perhaps this is a evemu-event problem, perhaps this alternative would work evescript?) nor does it switch tabs when called using the Gnome set global keybinding Alt + Left.
Any ideas on how I could get this working? I would like to not have to install yet another program like KMonad to get the global binding to work, but beggars can't be choosers. The most ideal would be a way to send keystrokes from GJS so it could all be done from one clean GJS script.
Gnome version: GNOME Shell 3.38.4
I use Material Shell, in case thats relevant