I have a GNOME (GNOME Shell 48.4) custom shortcut set up (on X11).
Shortcut: Meta+O
Command: a bash script open-file-path
Here is the code for the bash script
#!/usr/bin/env bash
source $HOME/.dotfiles/common_variables.env
FOCUSED_WINDOW=$(dbus-send --print-reply=literal --session --dest=org.gnome.Shell /org/gnome/Shell/Extensions/GnomeUtilsWindows org.gnome.Shell.Extensions.GnomeUtilsWindows.GetWindowFocused)
PID_OF_FOCUSED_WINDOW=$(echo "$FOCUSED_WINDOW" | jq -r '.pid')
WM_CLASS_OF_FOCUSED_WINDOW=$(echo "$FOCUSED_WINDOW" | jq -r '.wm_class')
if [[ "$WM_CLASS_OF_FOCUSED_WINDOW" == "${WM_CLASSES[VSCODIUM]}" ]]; then
// Not sure what to do here
exit 0
fi
# Function to return the first regular, readable, non-empty file
first_regular_file() {
while IFS= read -r f; do
# -f: is regular file
# -r: readable
# -s: non-empty
# ! -L: not a symbolic link
# Path does not include a hidden folder (no /.something/)
if [ -f "$f" ] && [ -r "$f" ] && [ -s "$f" ] && [ ! -L "$f" ] && { [[ "$f" == /home/* ]] || [[ "$f" == /media/* ]]; } && [[ "$f" != *"/."* ]]; then
echo "$f"
return 0
fi
done
}
# Try finding a file from /proc/<pid>/fd
file=$(find "/proc/$PID_OF_FOCUSED_WINDOW/fd" -type l 2>/dev/null | first_regular_file)
# Fallback: try /proc/<pid>/cmdline
if [ -z "$file" ]; then
file=$(tr '\0' '\n' < "/proc/$PID_OF_FOCUSED_WINDOW/cmdline" | first_regular_file)
fi
# Fallback: use lsof to find open files
if [ -z "$file" ]; then
file=$(lsof -p "$PID_OF_FOCUSED_WINDOW" -Fn 2>/dev/null | cut -c2- | first_regular_file)
fi
# Open file in Nemo or show notification
if [ -n "$file" ]; then
nemo "$file"
else
notify-send "Could not detect a regular file for the focused window."
fi
When I press Meta+O, While working on a file in a gui application, it open the parent directory of the file in the file browser?
This script does not work for some apps. One of them is vscode.
However, I set
{
"key": "meta+o",
"command": "revealFileInOS",
"when": "editorFocus"
},
In vscode.
I checked, it opens the file in file browser.
So, at this point I want to tell
if [[ "$WM_CLASS_OF_FOCUSED_WINDOW" == "${WM_CLASSES[VSCODIUM]}" ]]; then
// pass Meta+O keypress to focused window
// then exit
exit 0
fi
It can be
- EVENT_PROPAGATE or
- EVENT_STOP then emulate keypress Meta+O
I did some research and found that I can emulate keypress Meta+O using:
// dbus-send --print-reply=literal --session --dest=org.gnome.Shell /org/gnome/Shell/Extensions/GnomeUtilsWindows org.gnome.Shell.Extensions.GnomeUtilsWindows.EmitMetaO
EmitMetaO() {
// Create virtual keyboard device
const VirtualKeyboard = Clutter.get_default_backend()
.get_default_seat()
.create_virtual_device(Clutter.InputDeviceType.KEYBOARD_DEVICE);
// Clutter wants time in microseconds, so multiply event time by 1000
const eventTime = Clutter.get_current_event_time() * 1000;
VirtualKeyboard.notify_keyval(eventTime, Clutter.KEY_Super_L, Clutter.KeyState.PRESSED);
VirtualKeyboard.notify_keyval(eventTime, Clutter.KEY_O, Clutter.KeyState.PRESSED);
VirtualKeyboard.notify_keyval(eventTime, Clutter.KEY_O, Clutter.KeyState.RELEASED);
VirtualKeyboard.notify_keyval(eventTime, Clutter.KEY_Super_L, Clutter.KeyState.RELEASED);
}
When I try:
if [[ "$WM_CLASS_OF_FOCUSED_WINDOW" == "${WM_CLASSES[VSCODIUM]}" ]]; then
# Call your GNOME extension function EmitMetaO
dbus-send --print-reply=literal --session --dest=org.gnome.Shell /org/gnome/Shell/Extensions/GnomeUtilsWindows org.gnome.Shell.Extensions.GnomeUtilsWindows.EmitMetaO
exit 0
fi
It does not pass the keypress to vscode.
What can be done here?
Can something be done with gnome extension code. Or, some changes in the bash script will be enough.
NOTE: I have tried replacing dbus-send --print-reply=literal --session --dest=org.gnome.Shell /org/gnome/Shell/Extensions/GnomeUtilsWindows org.gnome.Shell.Extensions.GnomeUtilsWindows.EmitMetaO with xdotool key --clearmodifiers "Super_L+o". but it was not effective. What I need to understand is: when we create a custom shortcut in GNOME, what exactly happens? Is the keypress propagated to the application, or is it intercepted by GNOME? How can I make it propagate through a script to the focused window under a certain condition?