How can I propagate a GNOME custom shortcut keypress (Meta+O) through a script to VSCode?

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);
}

The code is in gnome-utils-by-blueray453/windowFunctions.js at eabdb18e319de9e71b3d0371f171599ba108e5a0 · blueray453/gnome-utils-by-blueray453 · GitHub

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?

I think the issue is pinpointed

the following code is absolutely fine. it does what it is supposed to do

EmitMetaO() {
    let wins = this._get_normal_windows_given_wm_class(VSCODIUM);

    wins.forEach(win => {
        let win_workspace = win.get_workspace();
        win_workspace.activate_with_focus(win, 0);
    });

    const VirtualKeyboard = Clutter.get_default_backend()
        .get_default_seat()
        .create_virtual_device(Clutter.InputDeviceType.KEYBOARD_DEVICE);

    // GLib.timeout_add(GLib.PRIORITY_DEFAULT, 200, () => {
        const eventTime = Clutter.get_current_event_time() * 1000;

        // Press Ctrl
    VirtualKeyboard.notify_keyval(eventTime, Clutter.KEY_Super_L, Clutter.KeyState.PRESSED);
        // Press E
        VirtualKeyboard.notify_keyval(eventTime, Clutter.KEY_o, Clutter.KeyState.PRESSED);
        // Release E
        VirtualKeyboard.notify_keyval(eventTime, Clutter.KEY_o, Clutter.KeyState.RELEASED);
        // Release Ctrl
    VirtualKeyboard.notify_keyval(eventTime, Clutter.KEY_Super_L, Clutter.KeyState.RELEASED);

    //     return GLib.SOUoRCE_REMOVE;
    // });
}

but when it press Meta+O, the code goes to gnome extension and run open-file-path instead of running on vscode.

So, it creates a loop.

Meta+O - Meta+O - Meta+O, it never goes to the window.

What can be done here?

  • I can disable the keybinding at the beginning and enable at the end

is there any other option?