pqrs-org / Karabiner-Elements

Karabiner-Elements is a powerful utility for keyboard customization on macOS Sierra (10.12) or later.
https://pqrs.org/osx/karabiner/
The Unlicense
18.72k stars 836 forks source link

Possible to operate conditionally on overlay (e.g. ChatGPT, Raycast, Alfred, etc.)? #3966

Open kfirfer opened 1 week ago

kfirfer commented 1 week ago

I’d like to disable certain keyboard shortcuts while using the overlays for ChatGPT, Raycast, and Alfred. Through EventViewer, I can find the bundle identifiers for these apps when I’m in their settings windows, but the overlays themselves don’t seem to register as the active application. Instead, the system considers the previously active application (before the overlay was triggered) as the foremost app.

For example, if I disable a keyboard shortcut in iTerm, then activate the ChatGPT or Raycast overlay while iTerm is open, the shortcut remains disabled because iTerm is still considered the active app.

Is there a way to disable keyboard shortcuts specifically in these overlays? I’m unsure if the overlays send any signals or set flags that would allow this, so I apologize if this request is for something technically unfeasible.

kfirfer commented 1 week ago

The closest I could get is with "hammerspoon" with this configuration:

function bringAppToFront(bundleID)
    local app = hs.application.get(bundleID)
    if app then
        app:activate()  -- Brings the app to the front
    else
        hs.application.launchOrFocusByBundleID(bundleID)  -- Launch or focus on the app
    end
end

-- Define the bundle ID of the app you want to monitor
local targetAppBundleID1 = "com.raycast.macos"
local targetAppBundleID2 = "com.openai.chat"

-- Create a window filter for the apps with the bundle IDs
local windowFilter = hs.window.filter.new(function(win)
    -- Check if the window belongs to the apps with the specified bundle IDs
    local appBundleId = win:application():bundleID()
    return appBundleId == targetAppBundleID1 or appBundleId == targetAppBundleID2
end)

-- Set up a listener for when the window is created (shown)
windowFilter:subscribe(hs.window.filter.windowCreated, function(window)
    -- Get the bundle ID of the window's application
    local appBundleId = window:application():bundleID()

    -- Bring the respective app to the front based on the bundle ID
    if appBundleId == targetAppBundleID1 then
        bringAppToFront(targetAppBundleID1)
    elseif appBundleId == targetAppBundleID2 then
        bringAppToFront(targetAppBundleID2)
    end
end)

I would like to know if there is a better or built-in solution.