Hot Key Cheat Sheet?

Do you maybe have the duplicates in some disabled preset? Or in some other app?
By default it will return all triggers from all presets and all apps.

The palette is displayed using the Show Palette of Macros KM action. I created that palette using a handy macro that @noisneil shared: Create and Populate a 'Show Palette of Macros' Macro.

Also, the order of the palette entries was adjusted using @DanThomas's Palette Organizer.

Yes. By triggering all of these with the right-modifiers I now obviously have more left-modifiers available for other purposes.

Right-βŒ₯⌘P triggered from BTT. I also added a KM-native trigger: βŒƒF12.

Since the palette entries run the underlying KM macros, this could all be run without BTT; but generally I'll use the BTT right-modifier Keyboard Shortcuts.


To save time, I created a simple KM macro that generates the required AppleScript to launch macros from BTT. Here are two examples, the first without a parameter and the second with one.

-- Show .BTT Palatte

tell application "Keyboard Maestro Engine"
	do script "8F5F1AED-8BD7-4911-BD47-E76D39D502CA"
end tell

-- Set Action Color

property theP : "red"

tell application "Keyboard Maestro Engine"
	do script "7ECFBA5D-3708-403D-9A58-0666C1246AD4" with parameter theP
end tell

BTW, @Frank1 since my earlier post, I've added a few items. The image in the above post has been updated.

Here's what this looks like in the KM editor.


Once the Setapp version of BTT is updated, I'll explore the technique @Andreas_Hegenberg has shared in this thread and/or the forthcoming Floating Palettes you mentioned. In the meantime, this approach works quite nicely.

Apart from the fact that I don’t know what the difference is between "Show Palette of Macros" and "Show Macro Group / show Palette", I more or less understand what you have set up. :slightly_smiling_face:

Probably you want it exactly like this, but just in case, you can also show/hide your palette with eg. right ⌘ (alone) instead of Right-βŒ₯⌘P. BTT offers more than KM when it comes to string triggers. BTT can also do this only with modifiers.

There are two options for a Key Sequence that triggers your KM shortcut for the palette.

(1) Tap right ⌘, shows the palette, tap again hides the palette.

(2) Press and hold right ⌘, shows the palette, releasing the key hides the palette.

(2) seems very convenient to me. But that is of course a matter of opinion. :slightly_smiling_face:

The Show Palette of Macros action, is harder to set up, but more flexible. It allows you to select the specific macros to include. That's where @noisneil's macro that I mentioned above is so helpful: just select the desired macros, run his macro, and a on-action macro is created that includes the Show Palette of Macros action.

Note, there is a typo on the Show Palette of Macros wiki page:

The Show Palette of Macros action (v8+) allows you to display a palette of selected actions macros and select which one to execute.


Thanks, that sounds nice. I'll poke around and see if I can figure that out. I'm a BTT newbie.

Ah, sorry, I could have posted that. It is a key sequence, very simple :slightly_smiling_face:

And 0.2 s is a good value because the normal shortcuts with r⌘ + letter are not disturbed.

1 Like

Thanks for directing me and suggesting the 0.2s value. The Deutsch dialog is a bonus! :grinning:

1 Like

Hi, @Frank1. I did set this up as you suggested and am loving it. Thanks so much for the help!

It was my pleasure. You have helped me more than once. :slightly_smiling_face:

1 Like

Anyone able to share this implementation using the new Floating Menu feature?

@Andreas_Hegenberg - I'm not sure if that's a bug, but when I add this code to Floating Menu -> Web Item -> Web View Config -> HTML or URL, nothing happens. More precisely, the BTTWindowWillBecomeVisible function is undefined. If I manually add it via console, the help screen works.

<html>
  <head>
    <style>
      #triggerList {
        height: 100%;
        display: grid;
        grid-template-columns: 1fr 1fr 1fr;
        align-items: left;
        justify-content: space-between;
      }

      .trigger {
        border-radius: 4px;
        background: lightblue;
        padding: 4px;
        margin: 4px;
        border: 1 px solid gray;
        display: flex;
        flex-direction: column;
        justify-content: space-around;
        align-items: center;
        align-content: center;
      }

      .trigger:hover {
        cursor: hand;
        background: gray;
      }
    </style>
    <script>
async function BTTWindowWillBecomeVisible() {
	let bundleIdentifier = await callBTT('get_string_variable', {
		variable_name: 'BTTActiveAppBundleIdentifier'
	});

	const allKeyboardShortcutsJSONString = await callBTT("get_triggers", {
		trigger_type: "BTTTriggerTypeKeyboardShortcut",
		trigger_app_bundle_identifier: bundleIdentifier
	});

	let allTriggersJSONArray = JSON.parse(allKeyboardShortcutsJSONString);
    let allKeyboardShortcuts = "";

    for (const trigger of allTriggersJSONArray) {
      if (trigger.BTTShortcutModifierKeys) {
        const shortcut = `<div class="trigger" onclick="callBTT('execute_assigned_actions_for_trigger', {uuid: '${
          trigger.BTTUUID
        }'})"><span><b>${
          trigger?.BTTTriggerConfig?.BTTLeftRightModifierDifferentiation
            ? getModifiersForBitmask(
                trigger.BTTAdditionalConfiguration,
                true
              )
            : getModifiersForBitmask(trigger.BTTShortcutModifierKeys, false)
        }${getKeycodeStringForKeycode(
          trigger.BTTShortcutKeyCode
        )}</b></span> <span>${getActionNameForID(
          trigger.BTTPredefinedActionType,
          trigger
        )}</span></div>`;
        allKeyboardShortcuts = allKeyboardShortcuts + shortcut;
      }
    }

    document.getElementById("triggerList").innerHTML = allKeyboardShortcuts;

	returnToBTT(allKeyboardShortcutsJSONString);
};

function getKeycodeStringForKeycode(keycode) {
        switch (keycode) {
          case 0x00: {
            return "A";
          }
          case 0x01: {
            return "S";
          }
          case 0x02: {
            return "D";
          }
          case 0x03: {
            return "F";
          }
          case 0x04: {
            return "H";
          }
          case 0x05: {
            return "G";
          }
          case 0x06: {
            return "Z";
          }
          case 0x07: {
            return "X";
          }
          case 0x08: {
            return "C";
          }
          case 0x09: {
            return "V";
          }
          case 0x0b: {
            return "B";
          }
          case 0x0c: {
            return "Q";
          }
          case 0x0d: {
            return "W";
          }
          case 0x0e: {
            return "E";
          }
          case 0x0f: {
            return "R";
          }
          case 0x10: {
            return "Y";
          }
          case 0x11: {
            return "T";
          }
          case 0x12: {
            return "1";
          }
          case 0x13: {
            return "2";
          }
          case 0x14: {
            return "3";
          }
          case 0x15: {
            return "4";
          }
          case 0x16: {
            return "6";
          }
          case 0x17: {
            return "5";
          }
          case 0x18: {
            return "=";
          }
          case 0x19: {
            return "9";
          }
          case 0x1a: {
            return "7";
          }
          case 0x1b: {
            return "-";
          }
          case 0x1c: {
            return "8";
          }
          case 0x1d: {
            return "0";
          }
          case 0x1e: {
            return "]";
          }
          case 0x1f: {
            return "O";
          }
          case 0x20: {
            return "U";
          }
          case 0x21: {
            return "[";
          }
          case 0x22: {
            return "I";
          }
          case 0x23: {
            return "P";
          }
          case 0x25: {
            return "L";
          }
          case 0x26: {
            return "J";
          }
          case 0x27: {
            return '"';
          }
          case 0x28: {
            return "K";
          }
          case 0x29: {
            return ";";
          }
          case 0x2a: {
            return "\\";
          }
          case 0x2b: {
            return ",";
          }
          case 0x2c: {
            return "/";
          }
          case 0x2d: {
            return "N";
          }
          case 0x2e: {
            return "M";
          }
          case 0x2f: {
            return ".";
          }
          case 0x32: {
            return "?";
          }
          case 0x41: {
            return ".";
          }
          case 0x43: {
            return "*";
          }
          case 0x45: {
            return "+";
          }
          case 0x47: {
            return "?";
          }
          case 0x4b: {
            return "%";
          }
          case 0x4c: {
            return "return";
          }
          case 0x4e: {
            return "-";
          }
          case 0x51: {
            return "=";
          }
          case 0x52: {
            return "0";
          }
          case 0x53: {
            return "1";
          }
          case 0x54: {
            return "2";
          }
          case 0x55: {
            return "3";
          }
          case 0x56: {
            return "4";
          }
          case 0x57: {
            return "5";
          }
          case 0x58: {
            return "6";
          }
          case 0x59: {
            return "7";
          }
          case 0x5b: {
            return "8";
          }
          case 0x5c: {
            return "9";
          }
          case 0x24: {
            return "Return";
          }
          case 0x30: {
            return "Tab";
          }
          case 0x31: {
            return "Space";
          }
          case 0x33: {
            return "Delete";
          }
          case 0x35: {
            return "Escape";
          }
          case 0x37: {
            return "Command";
          }
          case 0x38: {
            return "Shift";
          }
          case 0x39: {
            return "CapsLock";
          }
          case 0x3a: {
            return "Option";
          }
          case 0x3b: {
            return "Control";
          }
          case 0x3c: {
            return "RightShift";
          }
          case 0x3d: {
            return "RightOption";
          }
          case 0x3e: {
            return "RightControl";
          }
          case 0x3f: {
            return "Function";
          }
          case 0x40: {
            return "F17";
          }
          case 0x48: {
            return "VolumeUp";
          }
          case 0x49: {
            return "VolumeDown";
          }
          case 0x4a: {
            return "Mute";
          }
          case 0x4f: {
            return "F18";
          }
          case 0x50: {
            return "F19";
          }
          case 0x5a: {
            return "F20";
          }
          case 0x60: {
            return "F5";
          }
          case 0x61: {
            return "F6";
          }
          case 0x62: {
            return "F7";
          }
          case 0x63: {
            return "F3";
          }
          case 0x64: {
            return "F8";
          }
          case 0x65: {
            return "F9";
          }
          case 0x67: {
            return "F11";
          }
          case 0x69: {
            return "F13";
          }
          case 0x6a: {
            return "F16";
          }
          case 0x6b: {
            return "F14";
          }
          case 0x6d: {
            return "F10";
          }
          case 0x6f: {
            return "F12";
          }
          case 0x71: {
            return "F15";
          }
          case 0x72: {
            return "Help";
          }
          case 0x73: {
            return "Home";
          }
          case 0x74: {
            return "PageUp";
          }
          case 0x75: {
            return "ForwardDelete";
          }
          case 0x76: {
            return "F4";
          }
          case 0x77: {
            return "End";
          }
          case 0x78: {
            return "F2";
          }
          case 0x79: {
            return "PageDown";
          }
          case 0x7a: {
            return "F1";
          }
          case 0x7b: {
            return "LeftArrow";
          }
          case 0x7c: {
            return "RightArrow";
          }
          case 0x7d: {
            return "DownArrow";
          }
          case 0x7e: {
            return "UpArrow";
          }
          default: {
            return "??";
          }
        }
      }

function getModifiersForBitmask(bitMask, leftRight) {
    console.log("modifier", bitMask);
    if (bitMask === 0 || bitMask === -1) {
      return "";
    }
    var modifierString = "";

    if (leftRight && (bitMask & 0x00000001 || bitMask & 0x00002000)) {
      if (bitMask & 0x00000001) {
        modifierString += "βŒƒ(L)";
      }
      if (bitMask & 0x00002000) {
        modifierString += "βŒƒ(R)";
      }
    } else {
      if (bitMask & (1 << 18)) {
        modifierString += "βŒƒ";
      }
    }

    if (leftRight && (bitMask & 0x00000002 || bitMask & 0x00000004)) {
      if (bitMask & 0x00000002) {
        modifierString += "⇧(L)";
      }
      if (bitMask & 0x00000004) {
        modifierString += "⇧(R)";
      }
    } else {
      if (bitMask & (1 << 17)) {
        modifierString += "⇧";
      }
    }

    if (leftRight && (bitMask & 0x00000010 || bitMask & 0x00000008)) {
      if (bitMask & 0x00000010) {
        modifierString += "⌘(R)";
      }
      if (bitMask & 0x00000008) {
        modifierString += "⌘(L)";
      }
    } else {
      if (bitMask & (1 << 20)) {
        modifierString += "⌘";
      }
    }

    if (leftRight && (bitMask & 0x00000020 || bitMask & 0x00000040)) {
      if (bitMask & 0x00000020) {
        modifierString += "βŒ₯(L)";
      }
      if (bitMask & 0x00000040) {
        modifierString += "βŒ₯(R)";
      }
    } else {
      if (bitMask & (1 << 19)) {
        modifierString += "βŒ₯";
      }
    }

    if (bitMask & (1 << 23)) {
      modifierString += "fn";
    }

    console.log("modifierstring", modifierString);
    return modifierString;
}

function getShortcutString(value) {
        var kCommand = 0x37;
        var kShift = 0x38;
        var kOption = 0x3a;
        var kControl = 0x3b;
        var kRightCommand = 0x36;
        var kRightShift = 0x3c;
        var kRightOption = 0x3d;
        var kRightControl = 0x3e;
        var kFunction = 0x3f;
        var modsString = "";
        if (
          value.length > 2 &&
          parseInt(value.substring(0, 2), 10) === kFunction
        ) {
          modsString = "fn " + modsString;
          value = value.substring(3);
        }
        if (
          value.length > 2 &&
          parseInt(value.substring(0, 2), 10) === kControl
        ) {
          modsString += "βŒƒ";
          value = value.substring(3);
        }
        if (
          value.length > 2 &&
          parseInt(value.substring(0, 2), 10) === kOption
        ) {
          modsString += "βŒ₯";
          value = value.substring(3);
        }
        if (
          value.length > 2 &&
          parseInt(value.substring(0, 2), 10) === kShift
        ) {
          modsString += "⇧";
          value = value.substring(3);
        }
        if (
          value.length > 2 &&
          parseInt(value.substring(0, 2), 10) === kCommand
        ) {
          modsString += "⌘";
          value = value.substring(3);
        }
        if (value.length > 2 && value.substring(0, 2) === "aL") {
          modsString = "lβŒ₯ " + modsString;
          value = value.substring(3);
        }
        if (
          value.length > 2 &&
          parseInt(value.substring(0, 2), 10) === kRightOption
        ) {
          modsString = "rβŒ₯ " + modsString;
          value = value.substring(3);
        }
        if (value.length > 2 && value.substring(0, 2) === "sL") {
          modsString = "l⇧ " + modsString;
          value = value.substring(3);
        }
        if (
          value.length > 2 &&
          parseInt(value.substring(0, 2), 10) === kRightShift
        ) {
          modsString = "l⇧ " + modsString;
          value = value.substring(3);
        }
        if (value.length > 2 && value.substring(0, 2) === "cL") {
          modsString = "l⌘ " + modsString;
          value = value.substring(3);
        }
        if (
          value.length > 2 &&
          parseInt(value.substring(0, 2), 10) === kRightCommand
        ) {
          modsString = "r⌘ " + modsString;
          value = value.substring(3);
        }
        if (value.length > 2 && value.substring(0, 2) === "rL") {
          modsString = "lβŒƒ " + modsString;
          value = value.substring(3);
        }
        if (
          value.length > 2 &&
          parseInt(value.substring(0, 2), 10) === kRightControl
        ) {
          modsString = "rβŒƒ " + modsString;
          value = value.substring(3);
        }
        return (
          modsString + " " + getKeycodeStringForKeycode(parseInt(value, 10))
        );
      }

      function getActionNameForID(aid, trigger) {
        switch (aid) {
          case -1: {
            if (trigger.BTTTriggerType === 630) {
              return "Open Group";
            }
            if (trigger.BTTShortcutToSend) {
              return (
                "Execute Keyboard Shortcut: " +
                getShortcutString(trigger.BTTShortcutToSend)
              );
            }
            return "No Action";
          }

          default:
            return trigger.BTTPredefinedActionName;
        }
      }
          </script>
  </head>
  <body>
    <div id="triggerList"></div>
  </body>
</html>

Right now all I get is this:

Same thing happens if I add HTML excluding the script in Web View Config and script in Script with "Always run when menu item becomes visible".

Anyone more knowledgeable than me on this one? Having something like this would be amazing.

1 Like

I'll work on this soon!

2 Likes

Wow this is great and would be really useful, given the uncountable shortcuts that I have in BTT lol

1 Like

@Andreas_Hegenberg Can I run this code in Custom Floating Menu -> Web Item -> Web View Config (http link to my html with inline javascript)?

It's crashing with "Can't find variable callBTT".

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Keyboard Shortcuts</title>
    <style>
        body {
            font-family: Arial, sans-serif;
        }
        .container {
            column-count: 1; /* Start with one column */
            column-gap: 20px;
            max-height: 400px; /* Adjust the maximum height as needed */
            overflow-y: auto;
        }
    </style>
</head>
<body>
    <div class="container" id="shortcutsContainer"></div>

    <script>
        async function getAppKeyboardShortcuts() {
            const bundleIdentifier = await callBTT('get_string_variable', {
                variable_name: 'BTTActiveAppBundleIdentifier'
            })

            const allKeyboardShortcutsJSONString = await callBTT('get_triggers', {
                trigger_type: 'BTTTriggerTypeKeyboardShortcut',
                // trigger_app_bundle_identifier: 'com.apple.Safari'
                trigger_app_bundle_identifier: bundleIdentifier
            })

            allTriggersJSONArray = JSON.parse(allKeyboardShortcutsJSONString)
            const allKeyboardShortcuts = []

            for (const trigger of allTriggersJSONArray) {
                if (!trigger.BTTShortcutModifierKeys || trigger.BTTShortcutModifierKeys === -1)
                    continue

                // BTTLog('trying mod: ' + trigger.BTTShortcutModifierKeys)
                const mod = getModifiersForBitmask(trigger.BTTShortcutModifierKeys, false)
                const key = getKeycodeStringForKeycode(trigger.BTTShortcutKeyCode)

                allKeyboardShortcuts.push(mod + key)
            }

            return allKeyboardShortcuts
        }

        function addShortcutsToContainer(shortcuts) {
            const container = document.getElementById("shortcutsContainer");

            let totalHeight = 0;

            for (const shortcut of shortcuts) {
                const shortcutElement = document.createElement("p");
                shortcutElement.textContent = shortcut;
                container.appendChild(shortcutElement);
                totalHeight += shortcutElement.clientHeight;
            }

            if (totalHeight > container.clientHeight) {
                container.style.columnCount = 2; // If content exceeds height, use two columns
            }
        }

        function getKeycodeStringForKeycode(keycode) {
            switch (keycode) {
                case 0x00:
                    {
                        return "A";
                    }
                case 0x01:
                    {
                        return "S";
                    }
                case 0x02:
                    {
                        return "D";
                    }
                case 0x03:
                    {
                        return "F";
                    }
                case 0x04:
                    {
                        return "H";
                    }
                case 0x05:
                    {
                        return "G";
                    }
                case 0x06:
                    {
                        return "Z";
                    }
                case 0x07:
                    {
                        return "X";
                    }
                case 0x08:
                    {
                        return "C";
                    }
                case 0x09:
                    {
                        return "V";
                    }
                case 0x0b:
                    {
                        return "B";
                    }
                case 0x0c:
                    {
                        return "Q";
                    }
                case 0x0d:
                    {
                        return "W";
                    }
                case 0x0e:
                    {
                        return "E";
                    }
                case 0x0f:
                    {
                        return "R";
                    }
                case 0x10:
                    {
                        return "Y";
                    }
                case 0x11:
                    {
                        return "T";
                    }
                case 0x12:
                    {
                        return "1";
                    }
                case 0x13:
                    {
                        return "2";
                    }
                case 0x14:
                    {
                        return "3";
                    }
                case 0x15:
                    {
                        return "4";
                    }
                case 0x16:
                    {
                        return "6";
                    }
                case 0x17:
                    {
                        return "5";
                    }
                case 0x18:
                    {
                        return "=";
                    }
                case 0x19:
                    {
                        return "9";
                    }
                case 0x1a:
                    {
                        return "7";
                    }
                case 0x1b:
                    {
                        return "-";
                    }
                case 0x1c:
                    {
                        return "8";
                    }
                case 0x1d:
                    {
                        return "0";
                    }
                case 0x1e:
                    {
                        return "]";
                    }
                case 0x1f:
                    {
                        return "O";
                    }
                case 0x20:
                    {
                        return "U";
                    }
                case 0x21:
                    {
                        return "[";
                    }
                case 0x22:
                    {
                        return "I";
                    }
                case 0x23:
                    {
                        return "P";
                    }
                case 0x25:
                    {
                        return "L";
                    }
                case 0x26:
                    {
                        return "J";
                    }
                case 0x27:
                    {
                        return '"';
                    }
                case 0x28:
                    {
                        return "K";
                    }
                case 0x29:
                    {
                        return ";";
                    }
                case 0x2a:
                    {
                        return "\\";
                    }
                case 0x2b:
                    {
                        return ",";
                    }
                case 0x2c:
                    {
                        return "/";
                    }
                case 0x2d:
                    {
                        return "N";
                    }
                case 0x2e:
                    {
                        return "M";
                    }
                case 0x2f:
                    {
                        return ".";
                    }
                case 0x32:
                    {
                        return "?";
                    }
                case 0x41:
                    {
                        return ".";
                    }
                case 0x43:
                    {
                        return "*";
                    }
                case 0x45:
                    {
                        return "+";
                    }
                case 0x47:
                    {
                        return "?";
                    }
                case 0x4b:
                    {
                        return "%";
                    }
                case 0x4c:
                    {
                        return "return";
                    }
                case 0x4e:
                    {
                        return "-";
                    }
                case 0x51:
                    {
                        return "=";
                    }
                case 0x52:
                    {
                        return "0";
                    }
                case 0x53:
                    {
                        return "1";
                    }
                case 0x54:
                    {
                        return "2";
                    }
                case 0x55:
                    {
                        return "3";
                    }
                case 0x56:
                    {
                        return "4";
                    }
                case 0x57:
                    {
                        return "5";
                    }
                case 0x58:
                    {
                        return "6";
                    }
                case 0x59:
                    {
                        return "7";
                    }
                case 0x5b:
                    {
                        return "8";
                    }
                case 0x5c:
                    {
                        return "9";
                    }
                case 0x24:
                    {
                        return "Return";
                    }
                case 0x30:
                    {
                        return "Tab";
                    }
                case 0x31:
                    {
                        return "Space";
                    }
                case 0x33:
                    {
                        return "Delete";
                    }
                case 0x35:
                    {
                        return "Escape";
                    }
                case 0x37:
                    {
                        return "Command";
                    }
                case 0x38:
                    {
                        return "Shift";
                    }
                case 0x39:
                    {
                        return "CapsLock";
                    }
                case 0x3a:
                    {
                        return "Option";
                    }
                case 0x3b:
                    {
                        return "Control";
                    }
                case 0x3c:
                    {
                        return "RightShift";
                    }
                case 0x3d:
                    {
                        return "RightOption";
                    }
                case 0x3e:
                    {
                        return "RightControl";
                    }
                case 0x3f:
                    {
                        return "Function";
                    }
                case 0x40:
                    {
                        return "F17";
                    }
                case 0x48:
                    {
                        return "VolumeUp";
                    }
                case 0x49:
                    {
                        return "VolumeDown";
                    }
                case 0x4a:
                    {
                        return "Mute";
                    }
                case 0x4f:
                    {
                        return "F18";
                    }
                case 0x50:
                    {
                        return "F19";
                    }
                case 0x5a:
                    {
                        return "F20";
                    }
                case 0x60:
                    {
                        return "F5";
                    }
                case 0x61:
                    {
                        return "F6";
                    }
                case 0x62:
                    {
                        return "F7";
                    }
                case 0x63:
                    {
                        return "F3";
                    }
                case 0x64:
                    {
                        return "F8";
                    }
                case 0x65:
                    {
                        return "F9";
                    }
                case 0x67:
                    {
                        return "F11";
                    }
                case 0x69:
                    {
                        return "F13";
                    }
                case 0x6a:
                    {
                        return "F16";
                    }
                case 0x6b:
                    {
                        return "F14";
                    }
                case 0x6d:
                    {
                        return "F10";
                    }
                case 0x6f:
                    {
                        return "F12";
                    }
                case 0x71:
                    {
                        return "F15";
                    }
                case 0x72:
                    {
                        return "Help";
                    }
                case 0x73:
                    {
                        return "Home";
                    }
                case 0x74:
                    {
                        return "PageUp";
                    }
                case 0x75:
                    {
                        return "ForwardDelete";
                    }
                case 0x76:
                    {
                        return "F4";
                    }
                case 0x77:
                    {
                        return "End";
                    }
                case 0x78:
                    {
                        return "F2";
                    }
                case 0x79:
                    {
                        return "PageDown";
                    }
                case 0x7a:
                    {
                        return "F1";
                    }
                case 0x7b:
                    {
                        return "LeftArrow";
                    }
                case 0x7c:
                    {
                        return "RightArrow";
                    }
                case 0x7d:
                    {
                        return "DownArrow";
                    }
                case 0x7e:
                    {
                        return "UpArrow";
                    }
                default:
                    {
                        return "??";
                    }
            }
        }

        function getModifiersForBitmask(bitMask, leftRight) {
            console.log("modifier", bitMask);

            if (bitMask === 0 || bitMask === -1) {
                return "";
            }
            var modifierString = "";

            if (leftRight && (bitMask & 0x00000001 || bitMask & 0x00002000)) {
                if (bitMask & 0x00000001) {
                    modifierString += "βŒƒ(L)";
                }
                if (bitMask & 0x00002000) {
                    modifierString += "βŒƒ(R)";
                }
            } else {
                if (bitMask & (1 << 18)) {
                    modifierString += "βŒƒ";
                }
            }

            if (leftRight && (bitMask & 0x00000002 || bitMask & 0x00000004)) {
                if (bitMask & 0x00000002) {
                    modifierString += "⇧(L)";
                }
                if (bitMask & 0x00000004) {
                    modifierString += "⇧(R)";
                }
            } else {
                if (bitMask & (1 << 17)) {
                    modifierString += "⇧";
                }
            }

            if (leftRight && (bitMask & 0x00000010 || bitMask & 0x00000008)) {
                if (bitMask & 0x00000010) {
                    modifierString += "⌘(R)";
                }
                if (bitMask & 0x00000008) {
                    modifierString += "⌘(L)";
                }
            } else {
                if (bitMask & (1 << 20)) {
                    modifierString += "⌘";
                }
            }

            if (leftRight && (bitMask & 0x00000020 || bitMask & 0x00000040)) {
                if (bitMask & 0x00000020) {
                    modifierString += "βŒ₯(L)";
                }
                if (bitMask & 0x00000040) {
                    modifierString += "βŒ₯(R)";
                }
            } else {
                if (bitMask & (1 << 19)) {
                    modifierString += "βŒ₯";
                }
            }

            if (bitMask & (1 << 23)) {
                modifierString += "fn";
            }

            console.log("modifierstring", modifierString);
            return modifierString;
        }

        setTimeout(() => {
            // Fetch keyboard shortcuts for the currently focused application
            const allKeyboardShortcuts = getAppKeyboardShortcuts()

            // const allKeyboardShortcuts = ['β‡§βŒ˜H','βŒ₯]','βŒ₯[','⌘H','⌘L','βŒƒβŒ˜H','βŒƒO','βŒ₯[','βŒ₯]','⌘Y'];

            // Add the shortcuts to the container
            addShortcutsToContainer(allKeyboardShortcuts);
        }, 2000)
    </script>
</body>
</html>

I kinda fixed that js error with having an anonymous async function on top in <script> but document.createElement now hangs. I'm pretty stuck at this.

My millionth attempt at this consists of this html in "Web View Config":

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Keyboard Shortcuts</title>
    <style>
        body {
            font-family: Arial, sans-serif;
        }
        .container {
            column-count: 1; /* Start with one column */
            column-gap: 20px;
            max-height: 400px; /* Adjust the maximum height as needed */
            overflow-y: auto;
        }
    </style>
</head>
</html>

...and this "Real JavaScript" in Script:

(async () => {
    // Fetch currently focused application
    const bundleIdentifier = await get_string_variable({
        variable_name: 'BTTActiveAppBundleIdentifier'
    })

    // Fetch keyboard shortcuts for the currently focused application
    const allKeyboardShortcuts = await getAppKeyboardShortcuts(bundleIdentifier)

    // const allKeyboardShortcuts = ['β‡§βŒ˜H','βŒ₯]','βŒ₯[','⌘H','⌘L','βŒƒβŒ˜H','βŒƒO','βŒ₯[','βŒ₯]','⌘Y'];

    BTTLog('?????????????????? start creating elements')
    // Create the container and add it to the body
    const container = document.createElement("div");
    BTTLog('createElement done')
    container.className = "container";
    container.id = "shortcutsContainer";
    document.body.appendChild(container);
    BTTLog('1314134134134 appendChild done')
    // Add the shortcuts to the container

    BTTLog('CALLING addShortcutsToContainer...')
    addShortcutsToContainer(allKeyboardShortcuts);
    BTTLog('addShortcutsToContainer DONE!!!')

    BTTLog("drawing done ################")

    async function getAppKeyboardShortcuts(appId) {
        BTTLog('getting keys for ' + appId)

        const allKeyboardShortcutsJSONString = await get_triggers({
            trigger_type: 'BTTTriggerTypeKeyboardShortcut',
            trigger_app_bundle_identifier: appId
        })

        BTTLog('await get_triggers done! @!!!!!!#!$$!$$!!$')

        allTriggersJSONArray = JSON.parse(allKeyboardShortcutsJSONString)
        const allKeyboardShortcuts = []

        for (const trigger of allTriggersJSONArray) {
            if (!trigger.BTTShortcutModifierKeys || trigger.BTTShortcutModifierKeys === -1)
                continue

            const mod = getModifiersForBitmask(trigger.BTTShortcutModifierKeys, false)
            const key = getKeycodeStringForKeycode(trigger.BTTShortcutKeyCode)

            allKeyboardShortcuts.push(mod + key)
        }

        BTTLog('allKeyboardShortcuts ready: ' + allKeyboardShortcuts)
        return allKeyboardShortcuts
    }

    function createShortcutElement(shortcut) {
        const shortcutElement = document.createElement("p");
        shortcutElement.textContent = shortcut;
        shortcutElement.style.margin = "0";
        shortcutElement.style.padding = "0";
        return shortcutElement;
    }

    function addShortcutsToContainer(shortcuts) {
        const container = document.getElementById("shortcutsContainer");

        let totalHeight = 0;

        for (const shortcut of shortcuts) {
            const shortcutElement = createShortcutElement(shortcut);
            container.appendChild(shortcutElement);
            totalHeight += shortcutElement.clientHeight;
        }

        if (totalHeight > container.clientHeight) {
            container.style.columnCount = 2; // If content exceeds height, use two columns
        }
    }

    function getKeycodeStringForKeycode(keycode) {
        switch (keycode) {
            case 0x00: {
                return "A";
            }
            case 0x01: {
                return "S";
            }
            case 0x02: {
                return "D";
            }
            case 0x03: {
                return "F";
            }
            case 0x04: {
                return "H";
            }
            case 0x05: {
                return "G";
            }
            case 0x06: {
                return "Z";
            }
            case 0x07: {
                return "X";
            }
            case 0x08: {
                return "C";
            }
            case 0x09: {
                return "V";
            }
            case 0x0b: {
                return "B";
            }
            case 0x0c: {
                return "Q";
            }
            case 0x0d: {
                return "W";
            }
            case 0x0e: {
                return "E";
            }
            case 0x0f: {
                return "R";
            }
            case 0x10: {
                return "Y";
            }
            case 0x11: {
                return "T";
            }
            case 0x12: {
                return "1";
            }
            case 0x13: {
                return "2";
            }
            case 0x14: {
                return "3";
            }
            case 0x15: {
                return "4";
            }
            case 0x16: {
                return "6";
            }
            case 0x17: {
                return "5";
            }
            case 0x18: {
                return "=";
            }
            case 0x19: {
                return "9";
            }
            case 0x1a: {
                return "7";
            }
            case 0x1b: {
                return "-";
            }
            case 0x1c: {
                return "8";
            }
            case 0x1d: {
                return "0";
            }
            case 0x1e: {
                return "]";
            }
            case 0x1f: {
                return "O";
            }
            case 0x20: {
                return "U";
            }
            case 0x21: {
                return "[";
            }
            case 0x22: {
                return "I";
            }
            case 0x23: {
                return "P";
            }
            case 0x25: {
                return "L";
            }
            case 0x26: {
                return "J";
            }
            case 0x27: {
                return '"';
            }
            case 0x28: {
                return "K";
            }
            case 0x29: {
                return ";";
            }
            case 0x2a: {
                return "\\";
            }
            case 0x2b: {
                return ",";
            }
            case 0x2c: {
                return "/";
            }
            case 0x2d: {
                return "N";
            }
            case 0x2e: {
                return "M";
            }
            case 0x2f: {
                return ".";
            }
            case 0x32: {
                return "?";
            }
            case 0x41: {
                return ".";
            }
            case 0x43: {
                return "*";
            }
            case 0x45: {
                return "+";
            }
            case 0x47: {
                return "?";
            }
            case 0x4b: {
                return "%";
            }
            case 0x4c: {
                return "return";
            }
            case 0x4e: {
                return "-";
            }
            case 0x51: {
                return "=";
            }
            case 0x52: {
                return "0";
            }
            case 0x53: {
                return "1";
            }
            case 0x54: {
                return "2";
            }
            case 0x55: {
                return "3";
            }
            case 0x56: {
                return "4";
            }
            case 0x57: {
                return "5";
            }
            case 0x58: {
                return "6";
            }
            case 0x59: {
                return "7";
            }
            case 0x5b: {
                return "8";
            }
            case 0x5c: {
                return "9";
            }
            case 0x24: {
                return "Return";
            }
            case 0x30: {
                return "Tab";
            }
            case 0x31: {
                return "Space";
            }
            case 0x33: {
                return "Delete";
            }
            case 0x35: {
                return "Escape";
            }
            case 0x37: {
                return "Command";
            }
            case 0x38: {
                return "Shift";
            }
            case 0x39: {
                return "CapsLock";
            }
            case 0x3a: {
                return "Option";
            }
            case 0x3b: {
                return "Control";
            }
            case 0x3c: {
                return "RightShift";
            }
            case 0x3d: {
                return "RightOption";
            }
            case 0x3e: {
                return "RightControl";
            }
            case 0x3f: {
                return "Function";
            }
            case 0x40: {
                return "F17";
            }
            case 0x48: {
                return "VolumeUp";
            }
            case 0x49: {
                return "VolumeDown";
            }
            case 0x4a: {
                return "Mute";
            }
            case 0x4f: {
                return "F18";
            }
            case 0x50: {
                return "F19";
            }
            case 0x5a: {
                return "F20";
            }
            case 0x60: {
                return "F5";
            }
            case 0x61: {
                return "F6";
            }
            case 0x62: {
                return "F7";
            }
            case 0x63: {
                return "F3";
            }
            case 0x64: {
                return "F8";
            }
            case 0x65: {
                return "F9";
            }
            case 0x67: {
                return "F11";
            }
            case 0x69: {
                return "F13";
            }
            case 0x6a: {
                return "F16";
            }
            case 0x6b: {
                return "F14";
            }
            case 0x6d: {
                return "F10";
            }
            case 0x6f: {
                return "F12";
            }
            case 0x71: {
                return "F15";
            }
            case 0x72: {
                return "Help";
            }
            case 0x73: {
                return "Home";
            }
            case 0x74: {
                return "PageUp";
            }
            case 0x75: {
                return "ForwardDelete";
            }
            case 0x76: {
                return "F4";
            }
            case 0x77: {
                return "End";
            }
            case 0x78: {
                return "F2";
            }
            case 0x79: {
                return "PageDown";
            }
            case 0x7a: {
                return "F1";
            }
            case 0x7b: {
                return "LeftArrow";
            }
            case 0x7c: {
                return "RightArrow";
            }
            case 0x7d: {
                return "DownArrow";
            }
            case 0x7e: {
                return "UpArrow";
            }
            default: {
                return "??";
            }
        }
    }

    function getModifiersForBitmask(bitMask, leftRight) {
        console.log("modifier", bitMask);

        if (bitMask === 0 || bitMask === -1) {
            return "";
        }
        var modifierString = "";

        if (leftRight && (bitMask & 0x00000001 || bitMask & 0x00002000)) {
            if (bitMask & 0x00000001) {
                modifierString += "βŒƒ(L)";
            }
            if (bitMask & 0x00002000) {
                modifierString += "βŒƒ(R)";
            }
        } else {
            if (bitMask & (1 << 18)) {
                modifierString += "βŒƒ";
            }
        }

        if (leftRight && (bitMask & 0x00000002 || bitMask & 0x00000004)) {
            if (bitMask & 0x00000002) {
                modifierString += "⇧(L)";
            }
            if (bitMask & 0x00000004) {
                modifierString += "⇧(R)";
            }
        } else {
            if (bitMask & (1 << 17)) {
                modifierString += "⇧";
            }
        }

        if (leftRight && (bitMask & 0x00000010 || bitMask & 0x00000008)) {
            if (bitMask & 0x00000010) {
                modifierString += "⌘(R)";
            }
            if (bitMask & 0x00000008) {
                modifierString += "⌘(L)";
            }
        } else {
            if (bitMask & (1 << 20)) {
                modifierString += "⌘";
            }
        }

        if (leftRight && (bitMask & 0x00000020 || bitMask & 0x00000040)) {
            if (bitMask & 0x00000020) {
                modifierString += "βŒ₯(L)";
            }
            if (bitMask & 0x00000040) {
                modifierString += "βŒ₯(R)";
            }
        } else {
            if (bitMask & (1 << 19)) {
                modifierString += "βŒ₯";
            }
        }

        if (bitMask & (1 << 23)) {
            modifierString += "fn";
        }

        console.log("modifierstring", modifierString);
        return modifierString;
    }

    returnToBTT('done');
})()

Always Run When Menu Item Becomes Visible is enabled.
The BTTLog('createElement done') line never hits the log.

Your first one kind of works for me, there was just some issues with async await (await getAppKeyboardShortcuts()).
You could do it like this to automatically update whenever the active app changes. However I have already made good progress on a SwiftUI version of this :slight_smile:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Keyboard Shortcuts</title>
    <style>
      body {
        font-family: Arial, sans-serif;
      }
      .container {
        column-count: 1; /* Start with one column */
        column-gap: 20px;
        max-height: 400px; /* Adjust the maximum height as needed */
        overflow-y: auto;
      }
    </style>
  </head>
  <body>
    <div class="container" id="shortcutsContainer"></div>

    <script>
      async function getAppKeyboardShortcuts() {
        const bundleIdentifier = await callBTT("get_string_variable", {
          variable_name: "BTTActiveAppBundleIdentifier",
        });

        const allKeyboardShortcutsJSONString = await callBTT("get_triggers", {
          trigger_type: "BTTTriggerTypeKeyboardShortcut",
          // trigger_app_bundle_identifier: 'com.apple.Safari'
          trigger_app_bundle_identifier: bundleIdentifier,
        });

        allTriggersJSONArray = JSON.parse(allKeyboardShortcutsJSONString);
        const allKeyboardShortcuts = [];

        for (const trigger of allTriggersJSONArray) {
          if (
            !trigger.BTTShortcutModifierKeys ||
            trigger.BTTShortcutModifierKeys === -1
          )
            continue;

          // BTTLog('trying mod: ' + trigger.BTTShortcutModifierKeys)
          const mod = getModifiersForBitmask(
            trigger.BTTShortcutModifierKeys,
            false
          );
          const key = getKeycodeStringForKeycode(trigger.BTTShortcutKeyCode);

          allKeyboardShortcuts.push(mod + key);
        }

        return allKeyboardShortcuts;
      }

      function addShortcutsToContainer(shortcuts) {
        const container = document.getElementById("shortcutsContainer");

        let totalHeight = 0;

        for (const shortcut of shortcuts) {
          const shortcutElement = document.createElement("p");
          shortcutElement.textContent = shortcut;
          container.appendChild(shortcutElement);
          totalHeight += shortcutElement.clientHeight;
        }

        if (totalHeight > container.clientHeight) {
          container.style.columnCount = 2; // If content exceeds height, use two columns
        }
      }

      function getKeycodeStringForKeycode(keycode) {
        switch (keycode) {
          case 0x00: {
            return "A";
          }
          case 0x01: {
            return "S";
          }
          case 0x02: {
            return "D";
          }
          case 0x03: {
            return "F";
          }
          case 0x04: {
            return "H";
          }
          case 0x05: {
            return "G";
          }
          case 0x06: {
            return "Z";
          }
          case 0x07: {
            return "X";
          }
          case 0x08: {
            return "C";
          }
          case 0x09: {
            return "V";
          }
          case 0x0b: {
            return "B";
          }
          case 0x0c: {
            return "Q";
          }
          case 0x0d: {
            return "W";
          }
          case 0x0e: {
            return "E";
          }
          case 0x0f: {
            return "R";
          }
          case 0x10: {
            return "Y";
          }
          case 0x11: {
            return "T";
          }
          case 0x12: {
            return "1";
          }
          case 0x13: {
            return "2";
          }
          case 0x14: {
            return "3";
          }
          case 0x15: {
            return "4";
          }
          case 0x16: {
            return "6";
          }
          case 0x17: {
            return "5";
          }
          case 0x18: {
            return "=";
          }
          case 0x19: {
            return "9";
          }
          case 0x1a: {
            return "7";
          }
          case 0x1b: {
            return "-";
          }
          case 0x1c: {
            return "8";
          }
          case 0x1d: {
            return "0";
          }
          case 0x1e: {
            return "]";
          }
          case 0x1f: {
            return "O";
          }
          case 0x20: {
            return "U";
          }
          case 0x21: {
            return "[";
          }
          case 0x22: {
            return "I";
          }
          case 0x23: {
            return "P";
          }
          case 0x25: {
            return "L";
          }
          case 0x26: {
            return "J";
          }
          case 0x27: {
            return '"';
          }
          case 0x28: {
            return "K";
          }
          case 0x29: {
            return ";";
          }
          case 0x2a: {
            return "\\";
          }
          case 0x2b: {
            return ",";
          }
          case 0x2c: {
            return "/";
          }
          case 0x2d: {
            return "N";
          }
          case 0x2e: {
            return "M";
          }
          case 0x2f: {
            return ".";
          }
          case 0x32: {
            return "?";
          }
          case 0x41: {
            return ".";
          }
          case 0x43: {
            return "*";
          }
          case 0x45: {
            return "+";
          }
          case 0x47: {
            return "?";
          }
          case 0x4b: {
            return "%";
          }
          case 0x4c: {
            return "return";
          }
          case 0x4e: {
            return "-";
          }
          case 0x51: {
            return "=";
          }
          case 0x52: {
            return "0";
          }
          case 0x53: {
            return "1";
          }
          case 0x54: {
            return "2";
          }
          case 0x55: {
            return "3";
          }
          case 0x56: {
            return "4";
          }
          case 0x57: {
            return "5";
          }
          case 0x58: {
            return "6";
          }
          case 0x59: {
            return "7";
          }
          case 0x5b: {
            return "8";
          }
          case 0x5c: {
            return "9";
          }
          case 0x24: {
            return "Return";
          }
          case 0x30: {
            return "Tab";
          }
          case 0x31: {
            return "Space";
          }
          case 0x33: {
            return "Delete";
          }
          case 0x35: {
            return "Escape";
          }
          case 0x37: {
            return "Command";
          }
          case 0x38: {
            return "Shift";
          }
          case 0x39: {
            return "CapsLock";
          }
          case 0x3a: {
            return "Option";
          }
          case 0x3b: {
            return "Control";
          }
          case 0x3c: {
            return "RightShift";
          }
          case 0x3d: {
            return "RightOption";
          }
          case 0x3e: {
            return "RightControl";
          }
          case 0x3f: {
            return "Function";
          }
          case 0x40: {
            return "F17";
          }
          case 0x48: {
            return "VolumeUp";
          }
          case 0x49: {
            return "VolumeDown";
          }
          case 0x4a: {
            return "Mute";
          }
          case 0x4f: {
            return "F18";
          }
          case 0x50: {
            return "F19";
          }
          case 0x5a: {
            return "F20";
          }
          case 0x60: {
            return "F5";
          }
          case 0x61: {
            return "F6";
          }
          case 0x62: {
            return "F7";
          }
          case 0x63: {
            return "F3";
          }
          case 0x64: {
            return "F8";
          }
          case 0x65: {
            return "F9";
          }
          case 0x67: {
            return "F11";
          }
          case 0x69: {
            return "F13";
          }
          case 0x6a: {
            return "F16";
          }
          case 0x6b: {
            return "F14";
          }
          case 0x6d: {
            return "F10";
          }
          case 0x6f: {
            return "F12";
          }
          case 0x71: {
            return "F15";
          }
          case 0x72: {
            return "Help";
          }
          case 0x73: {
            return "Home";
          }
          case 0x74: {
            return "PageUp";
          }
          case 0x75: {
            return "ForwardDelete";
          }
          case 0x76: {
            return "F4";
          }
          case 0x77: {
            return "End";
          }
          case 0x78: {
            return "F2";
          }
          case 0x79: {
            return "PageDown";
          }
          case 0x7a: {
            return "F1";
          }
          case 0x7b: {
            return "LeftArrow";
          }
          case 0x7c: {
            return "RightArrow";
          }
          case 0x7d: {
            return "DownArrow";
          }
          case 0x7e: {
            return "UpArrow";
          }
          default: {
            return "??";
          }
        }
      }

      function getModifiersForBitmask(bitMask, leftRight) {
        console.log("modifier", bitMask);

        if (bitMask === 0 || bitMask === -1) {
          return "";
        }
        var modifierString = "";

        if (leftRight && (bitMask & 0x00000001 || bitMask & 0x00002000)) {
          if (bitMask & 0x00000001) {
            modifierString += "βŒƒ(L)";
          }
          if (bitMask & 0x00002000) {
            modifierString += "βŒƒ(R)";
          }
        } else {
          if (bitMask & (1 << 18)) {
            modifierString += "βŒƒ";
          }
        }

        if (leftRight && (bitMask & 0x00000002 || bitMask & 0x00000004)) {
          if (bitMask & 0x00000002) {
            modifierString += "⇧(L)";
          }
          if (bitMask & 0x00000004) {
            modifierString += "⇧(R)";
          }
        } else {
          if (bitMask & (1 << 17)) {
            modifierString += "⇧";
          }
        }

        if (leftRight && (bitMask & 0x00000010 || bitMask & 0x00000008)) {
          if (bitMask & 0x00000010) {
            modifierString += "⌘(R)";
          }
          if (bitMask & 0x00000008) {
            modifierString += "⌘(L)";
          }
        } else {
          if (bitMask & (1 << 20)) {
            modifierString += "⌘";
          }
        }

        if (leftRight && (bitMask & 0x00000020 || bitMask & 0x00000040)) {
          if (bitMask & 0x00000020) {
            modifierString += "βŒ₯(L)";
          }
          if (bitMask & 0x00000040) {
            modifierString += "βŒ₯(R)";
          }
        } else {
          if (bitMask & (1 << 19)) {
            modifierString += "βŒ₯";
          }
        }

        if (bitMask & (1 << 23)) {
          modifierString += "fn";
        }

        console.log("modifierstring", modifierString);
        return modifierString;
      }

      setTimeout(async () => {
        console.log("starting");
        // Fetch keyboard shortcuts for the currently focused application
        const allKeyboardShortcuts = await getAppKeyboardShortcuts();
        console.log("got shortcuts", allKeyboardShortcuts);

        // const allKeyboardShortcuts = ['β‡§βŒ˜H','βŒ₯]','βŒ₯[','⌘H','⌘L','βŒƒβŒ˜H','βŒƒO','βŒ₯[','βŒ₯]','⌘Y'];

        // Add the shortcuts to the container
        addShortcutsToContainer(allKeyboardShortcuts);
      }, 2000);

      async function BTTNotification(note) {
        setTimeout(async () => {
          let data = JSON.parse(note);

          console.log(data.note, data.name);

          if (get_string_variable !== undefined) {
            console.log(data.note, data.name);

            // example to get the currently active app, this works for any BTT variable you define:
            if (
              data.note == "BTTVariableChanged" &&
              (data.name == "BTTActiveAppBundleIdentifier" ||
                data.name == "BTTActiveWindowTitle")
            ) {
              const allKeyboardShortcuts = await getAppKeyboardShortcuts();
              console.log("got shortcuts", allKeyboardShortcuts);

              // const allKeyboardShortcuts = ['β‡§βŒ˜H','βŒ₯]','βŒ₯[','⌘H','⌘L','βŒƒβŒ˜H','βŒƒO','βŒ₯[','βŒ₯]','⌘Y'];
              const container = document.getElementById("shortcutsContainer");
              container.innerHTML = '';
              // Add the shortcuts to the container
              addShortcutsToContainer(allKeyboardShortcuts);
            }
          }
        }, 200);
      }
    </script>
  </body>
</html>

2 Likes

I'm really looking forward for the SwiftUI feature :slight_smile:
Any tips on how it'll look like? :hugs:


Not the best implementation, but it's good enough for me at this point.

1 Like


:ok_hand::tada:

2 Likes

very nice!

1 Like