Skip to content

Instantly share code, notes, and snippets.

@truebit
Last active March 15, 2026 17:55
Show Gist options
  • Select an option

  • Save truebit/d79b8018666d65e95970f208d8f5d149 to your computer and use it in GitHub Desktop.

Select an option

Save truebit/d79b8018666d65e95970f208d8f5d149 to your computer and use it in GitHub Desktop.
Kitty Terminal: pull down from top like iTerm2
local spaces = require("hs.spaces") -- https://github.com/asmagill/hs._asm.spaces
-- Switch kitty
hs.hotkey.bind({'command'}, 'escape', function () -- change your own hotkey combo here, available keys could be found here:https://www.hammerspoon.org/docs/hs.hotkey.html#bind
local BUNDLE_ID = 'net.kovidgoyal.kitty' -- more accurate to avoid mismatching on browser titles
function getMainWindow(app)
-- get main window from app
local win = nil
while win == nil do
win = app:mainWindow()
end
return win
end
function moveWindow(kitty, space, mainScreen)
-- move to main space
local win = getMainWindow(kitty)
if win:isFullScreen() then
hs.eventtap.keyStroke('fn', 'f', 0, kitty)
end
winFrame = win:frame()
scrFrame = mainScreen:fullFrame()
winFrame.w = scrFrame.w
winFrame.y = scrFrame.y
winFrame.x = scrFrame.x
win:setFrame(winFrame, 0)
spaces.moveWindowToSpace(win, space)
if win:isFullScreen() then
hs.eventtap.keyStroke('fn', 'f', 0, kitty)
end
win:focus()
end
local kitty = hs.application.get(BUNDLE_ID)
if kitty ~= nil and kitty:isFrontmost() then
kitty:hide()
else
local space = spaces.activeSpaceOnScreen()
local mainScreen = hs.screen.mainScreen()
if kitty == nil and hs.application.launchOrFocusByBundleID(BUNDLE_ID) then
local appWatcher = nil
appWatcher = hs.application.watcher.new(function(name, event, app)
if event == hs.application.watcher.launched and app:bundleID() == BUNDLE_ID then
getMainWindow(app):move(hs.geometry({x=0,y=0,w=1,h=0.4})) -- move kitty window on top, you could set the window percentage here
app:hide()
moveWindow(app, space, mainScreen)
appWatcher:stop()
end
end)
appWatcher:start()
end
if kitty ~= nil then
moveWindow(kitty, space, mainScreen)
end
end
end)
# make your kitty window borderless
hide_window_decorations titlebar-and-corners
# make kitty app quit entirely instead of leaving null window, which made the script hard to detect kitty window
macos_quit_when_last_window_closed yes
# this one is optional, would quit kitty tab more quickly
confirm_os_window_close 0
# this one is optional, as hammerspoon script would move window in script line 45
remember_window_size yes
@CassandraCat

Copy link
Copy Markdown
Screen.Recording.2024-01-22.at.21.20.59.-.01.mp4

@truebit

truebit commented Jan 23, 2024

Copy link
Copy Markdown
Author

My solution only supports multi hardware screen switch and display like iTerm2 top-down window.
According to your video, you modified my script to adapt your requirement. If that's not what you intended to, follow this gist carefully, espcially the kitty configuration.

@CassandraCat

Copy link
Copy Markdown

I just modified the percentage of the screen display and set the height to 1

@truebit

truebit commented Jan 23, 2024 via email

Copy link
Copy Markdown
Author

@CassandraCat

Copy link
Copy Markdown

πŸ‘ŒπŸ», thanks~

@ildar-aim

Copy link
Copy Markdown

Hello , I am trying to hide kitty on switching to another workspace by CTRL+1/2/3/4 (losing focus)

Do you know probably how to overcome this error (binding to system hotkey )?

2024-03-22 10:01:12: 10:01:12 ERROR:   LuaSkin: hs.hotkey:enable() keycode: 18, mods: 0x1000, RegisterEventHotKey failed: -9878
2024-03-22 10:01:12: 10:01:12 ERROR:   LuaSkin: This hotkey is already registered. It may be a duplicate in your Hammerspoon config, or it may be registered by macOS. See System Preferences->Keyboard->Shortcuts

here is not working code for CTRL+1 hotkey

-- 09:57:05.838  INFO   wezterm_gui::termwindow::keyevent     > key_event KeyEvent { key: Char('1'), modifiers:{CTRL}, leds: (empty), repeat_count: 1, key_is_down: false, raw: Some(RawKeyEvent { key: Char('1'), modifiers: NONE, leds: (empty), phys_code: Some(K1), raw_code: 18, repeat_count: 1, key_is_down: false, handled: Handled(false) }) }
hs.hotkey.bind({"ctrl"}, 18, function () -- change your own hotkey combo here, available keys could be found here:https://www.hammerspoon.org/docs/hs.hotkey.html#bind
  local BUNDLE_ID = 'net.kovidgoyal.kitty' -- more accurate to avoid mismatching on browser titles

  local kitty = hs.application.get(BUNDLE_ID)
  if kitty ~= nil and kitty:isFrontmost() then
    kitty:hide()
  end
end)

@truebit

truebit commented Mar 22, 2024

Copy link
Copy Markdown
Author

Hello , I am trying to hide kitty on switching to another workspace by CTRL+1/2/3/4 (losing focus)

Do you know probably how to overcome this error (binding to system hotkey )?

2024-03-22 10:01:12: 10:01:12 ERROR:   LuaSkin: hs.hotkey:enable() keycode: 18, mods: 0x1000, RegisterEventHotKey failed: -9878
2024-03-22 10:01:12: 10:01:12 ERROR:   LuaSkin: This hotkey is already registered. It may be a duplicate in your Hammerspoon config, or it may be registered by macOS. See System Preferences->Keyboard->Shortcuts

here is not working code for CTRL+1 hotkey

-- 09:57:05.838  INFO   wezterm_gui::termwindow::keyevent     > key_event KeyEvent { key: Char('1'), modifiers:{CTRL}, leds: (empty), repeat_count: 1, key_is_down: false, raw: Some(RawKeyEvent { key: Char('1'), modifiers: NONE, leds: (empty), phys_code: Some(K1), raw_code: 18, repeat_count: 1, key_is_down: false, handled: Handled(false) }) }
hs.hotkey.bind({"ctrl"}, 18, function () -- change your own hotkey combo here, available keys could be found here:https://www.hammerspoon.org/docs/hs.hotkey.html#bind
  local BUNDLE_ID = 'net.kovidgoyal.kitty' -- more accurate to avoid mismatching on browser titles

  local kitty = hs.application.get(BUNDLE_ID)
  if kitty ~= nil and kitty:isFrontmost() then
    kitty:hide()
  end
end)

The error message already told you: "This hotkey is already registered. It may be a duplicate in your Hammerspoon config, or it may be registered by macOS. See System Preferences->Keyboard->Shortcuts"

@ildar-aim

Copy link
Copy Markdown

I set CTRL + 1/2/3/4 to switch between spaces intentionally in System Preferences->Keyboard->Shortcuts.
The question is
Is it possible to chain something else via hammerspoon in addition to system action?
Ok I see the question is not related to the gist.

Anyway thank you for your efforts!

@CassandraCat

Copy link
Copy Markdown

"moveWindowToSpace" function is not working properly.

@truebit

truebit commented Mar 5, 2026

Copy link
Copy Markdown
Author

"moveWindowToSpace" function is not working properly.

see this comment to do the trick

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment