Closed leiserfg closed 7 years ago
also, tdrop works well
Does anyone have a method for OSX?
Edit: I have solved this using BetterTouchTool
@dbousamra How did you do this with BTT?
@dbousamra Could you do this on https://github.com/jwilm/alacritty ???
@zx1986 I recommend Alfred
. Create a Hotkey
workflow for any app you want to launch it or toggle visibility of it.
@NightMachinary
How did you do this with BTT?
I've got it working with a global keyboard trigger to "show/hide a specific application", but would be great to hear if anyone is doing it differently.
There's also https://github.com/koekeishiya/skhd
I build kitty in ~/git/other/kitty/
, and start kitty with ctrl+return using this line in my .skhdrc
ctrl - return : open ~/git/other/kitty/kitty/launcher/kitty.app -n --args --single-instance --title="zsh"
I tried many ways of doing this and eventually settled on Hammerspoon. I prefer it because it's free, flexible, easy to set up programmatically in my dotfiles, and fast. (That last point is important. For example, you can avoid installing external software and instead make a shortcut in System Preferences for an Automator "Service", but there's a second-long delay after pressing the keys.)
Putting this in ~/.hammerspoon/init.lua will show/hide kitty when you press CtrlSpace:
hs.hotkey.bind({"ctrl"}, "space", function()
local app = hs.application.get("kitty")
if app then
if not app:mainWindow() then
app:selectMenuItem({"kitty", "New OS window"})
elseif app:isFrontmost() then
app:hide()
else
app:activate()
end
else
hs.application.launchOrFocus("kitty")
end
end)
Or, if you want it to always open a new window:
hs.hotkey.bind({"ctrl"}, "space", function()
local app = hs.application.get("kitty")
if app then
app:selectMenuItem({"kitty", "New OS window"})
else
hs.application.launchOrFocus("kitty")
end
end)
@mk12 Very nice this inspired me to make this which turns Kitty into a drop down quake and iTerm like style, i bound it to F15
which is the Break/Pause key because c+spc
is frequently used to trigger auto complete in vscode and other editor. paired with hide_window_decorations yes
in kitty.conf
it makes for a very viable alternative to iTerm
hs.hotkey.bind({}, "F15", function()
local app = hs.application.get("kitty")
if app then
if not app:mainWindow() then
app:selectMenuItem({"kitty", "New OS window"})
elseif app:isFrontmost() then
app:hide()
else
app:activate()
end
else
hs.application.launchOrFocus("kitty")
app = hs.application.get("kitty")
end
app:mainWindow():moveToUnit'[100,50,0,0]'
app:mainWindow().setShadows(false)
end)
@NightMachinary
How did you do this with BTT?
I've got it working with a global keyboard trigger to "show/hide a specific application", but would be great to hear if anyone is doing it differently.
This doesn't seem to work if kitty is in legacy full screen mode
macos_traditional_fullscreen true
And specifically for i3: https://github.com/LandingEllipse/kitti3
I suggest adding it to integrations.rst
.
Not a dropdown, but a very simple solution to run Kitty instead of default terminal via standard Ctrl+Alt+T shortcut:
lxqt-config-globalkeyshortcuts
)/home/USER/.local/kitty.app/bin/kitty
replacing USER
with your username (alas neither $USER
nor $HOME
can be used here)This also allows to avoid manual desktop integration steps: https://sw.kovidgoyal.net/kitty/binary.html#desktop-integration-on-linux
@webberwang @NightMachinary
Is there a way this will open over fullscreen apps in MacOS? I have the shortcut opening kitty in BTT but it switches me out of the 'space' if im in a fullscreen app
I created a phoenix script which does this. But only in mac!
brew install --cask phoenix
copy the following file to ~/.phoenix.js
https://github.com/lukesmurray/bootstrap/blob/master/.phoenix.js
Use cmd+` (backtick) to get the dropdown.
These are the relevant lines. You can make your own shortcut
For those running yabai and skhd on macOS, this will give you a pretty good approximation of a drop down terminal. It binds CMD + `. It could probably be optimized and some yabai rules and signals could implement a little more logic and functionality, but it works well enough for me. Just drop this in your skhdrc and adjust to your liking.
# SKHD
default < cmd - 0x32 : /path/to/helper
# Helper File
# NOTE: Add a port if you control of that instance.
function kitty_quake() {
HOMEBREW=/opt/homebrew/bin
QUAKE=($($HOMEBREW/yabai -m query --windows --space |jq '.[]|select(.title=="Quake")|.id,.minimized,.border'))
if [[ ${#QUAKE} -eq 0 ]]; then
open -a kitty.app -n --args -1 --title="Quake" -o \
tab_title_template="Quake: {index}" --listen-on="tcp:localhost:$PORT" \
&>/dev/null & disown;
while [[ ${#QUAKE[@]} -ne 3 ]];
do
QUAKE=($($HOMEBREW/yabai -m query --windows --space|jq '.[]|select(.title=="Quake")|.id,.minimized,.border'))
done
$HOMEBREW/yabai -m window "${QUAKE[0]}" --toggle sticky;
$HOMEBREW/yabai -m window "${QUAKE[0]}" --move abs:0:0;
$HOMEBREW/yabai -m window "${QUAKE[0]}" --resize abs:10000:450;
$HOMEBREW/yabai -m window "${QUAKE[0]}" --opacity 0.95;
elif [[ ${QUAKE[1]} -eq 1 ]]; then
$HOMEBREW/yabai -m window "${QUAKE[0]}" --deminimize;
$HOMEBREW/yabai -m window "${QUAKE[0]}" --move abs:0:0;
$HOMEBREW/yabai -m window "${QUAKE[0]}" --resize abs:10000:450;
$HOMEBREW/yabai -m window "${QUAKE[0]}" --opacity 0.95;
$HOMEBREW/yabai -m window "${QUAKE[0]}" --focus "${QUAKE[0]}";
[[ ${QUAKE[2]} -eq 0 ]] && $HOMEBREW/yabai -m window "${QUAKE[0]}" --toggle border || :
elif [[ ${QUAKE[1]} -eq 0 ]]; then
[[ ${QUAKE[2]} -eq 1 ]] && $HOMEBREW/yabai -m window "${QUAKE[0]}" --toggle border || :
$HOMEBREW/yabai -m window "${QUAKE[0]}" --opacity 0.001;
$HOMEBREW/yabai -m window "${QUAKE[0]}" --minimize;
else
echo quake failed
fi
}
@typkrft This works really well, but I was playing with it and don't understand well enough, is there a way to modify this to run a command on startup?
@typkrft This works really well, but I was playing with it and don't understand well enough, is there a way to modify this to run a command on startup?
This is kind of a constantly tweaked script for me. This needs to be cleaned up and improved a lot. The current iteration I'm using is below. I've added some comments to try and explain what's going on.
EDIT: See the comment below, which should clean this up a bit.
EDIT: Implemented comment below.
EDIT: Added dependency GetWindowID and removed calls to query all windows to try and avoid slowdowns.
function kitty_quake() {
KITTY=$(pgrep -a -f ".*kitty.*")
QUAKE=$(osascript -l JavaScript -e 'Application("System Events").processes.whose({name: "kitty"}).windows.whose({name: "Quake"}).name()')
if [[ $KITTY == "" ]]; then
open -a kitty -n --args -1 --listen-on=unix:/tmp/kitty -o macos_quit_when_last_window_closed=no false
while [[ $KITTY == "" ]]
do
KITTY=$(pgrep -a -f ".*kitty.*")
done
open -a kitty -n --args -1 --listen-on=unix:/tmp/kitty --title=Quake
while [[ $QUAKE != "Quake" ]]
do
QUAKE=$(osascript -l JavaScript -e 'Application("System Events").processes.whose({name: "kitty"}).windows.whose({name: "Quake"}).name()')
done
WINDOW_ID=$(GetWindowID kitty 'Quake')
yabai -m window $WINDOW_ID --toggle sticky
yabai -m window $WINDOW_ID --move abs:0:0
yabai -m window $WINDOW_ID --resize abs:10000:450
yabai -m window $WINDOW_ID --opacity 0.95
exit 0
elif [[ $KITTY != "" && $QUAKE == "" ]]; then
open -a kitty -n --args -1 --listen-on=unix:/tmp/kitty --title=Quake
while [[ $QUAKE != "Quake" ]]
do
QUAKE=$(osascript -l JavaScript -e 'Application("System Events").processes.whose({name: "kitty"}).windows.whose({name: "Quake"}).name()')
done
WINDOW_ID=$(GetWindowID kitty 'Quake')
yabai -m window $WINDOW_ID --toggle sticky
yabai -m window $WINDOW_ID --move abs:0:0
yabai -m window $WINDOW_ID --resize abs:10000:450
yabai -m window $WINDOW_ID --opacity 0.95
elif [[ $KITTY != "" && $QUAKE != "" ]]; then
WINDOW_ID=$(GetWindowID kitty 'Quake')
INFO=$(yabai -m query --windows --window $WINDOW_ID | jq '.border, .minimized')
BORDER=$(echo $INFO | awk '{print $1}')
MINI=$(echo $INFO | awk '{print $2}')
if [[ $MINI -eq 1 ]]; then
[[ $BORDER -eq 1 ]] && yabai -m window "$WNDOW_ID" --toggle border || :
yabai -m window "$WINDOW_ID" --deminimize;
yabai -m window "$WINDOW_ID" --opacity 0.95;
[[ $BORDER -eq 0 ]] && yabai -m window "$WNDOW_ID" --toggle border || :
yabai -m window "$WINDOW_ID" --focus "$WINDOW_ID";
elif [[ $MINI -eq 0 ]]; then
[[ $BORDER -eq 1 ]] && yabai -m window "$WINDOW_ID" --toggle border || :
yabai -m window "$WINDOW_ID" --opacity 0.001;
yabai -m window "$WINDOW_ID" --minimize;
fi
fi
}
There's still a lot that needs to be tweaked, could be simplified, or written more effectively. A few things that would be very helpful would be if kitty could be started without a window, If we could negate inherited window titles, maybe by setting --title to an empty string or something, and if kitty didn't activate, which includes de-minimizing the last window after the second to last window is closed. In addition, if you restart your mac it will likely reopen kitty depending on settings, and when you invoke kitty for the first time despite using the -1 flag it will open a new instance. macOS is particular and peculiar in the way it handles window management, so I've not created issues for any of these things.
Also querying with yabai can take a long time, proabaly due to this which causes opening and closing to take a while sometimes. This was somewhat addressed in the last edit.
If you want to start kitty without a window run it as
kitty -o macos_quit_when_last_window_closed=no false
@webberwang @NightMachinary
Is there a way this will open over fullscreen apps in MacOS? I have the shortcut opening kitty in BTT but it switches me out of the 'space' if im in a fullscreen app
This does not open over fullscreen apps, but it does switch back to the fullscreen app when you hide Kitty. It's a somewhat ugly hack, but...: it works for me in BetterTouchTool
@mk12 @exoticus thank you for this suggestion!
I use the following setup to get Kitty working Quake style with opacity effects on full screens in macOS:
-- Kitty configuration
hs.hotkey.bind({"cmd"}, "g", function()
-- Get current space
local currentSpace = hs.spaces.focusedSpace()
-- Get kitty app
local app = hs.application.get("kitty")
-- If app already open:
if app then
-- If no main window, then open a new window
if not app:mainWindow() then
app:selectMenuItem("New OS Window", true)
-- If app is already in front, then hide it
elseif app:isFrontmost() then
app:hide()
-- If there is a main window somewhere, bring it to current space and to front
else
-- First move the main window to the current space
hs.spaces.moveWindowToSpace(app:mainWindow(), currentSpace)
-- Activate the app
app:activate()
-- Raise the main window and position correctly
app:mainWindow():raise()
app:mainWindow():moveToUnit('0.0,0.0,1.0,1.0')
end
-- If app not open, open it
else
hs.application.launchOrFocus("kitty")
app = hs.application.get("kitty")
end
-- hs.spaces.gotoSpace(currentSpace)
end)
@mk12 Very nice this inspired me to make this which turns Kitty into a drop down quake and iTerm like style, i bound it to
F15
which is the Break/Pause key becausec+spc
is frequently used to trigger auto complete in vscode and other editor. paired withhide_window_decorations yes
inkitty.conf
it makes for a very viable alternative toiTerm
hs.hotkey.bind({}, "F15", function() local app = hs.application.get("kitty") if app then if not app:mainWindow() then app:selectMenuItem({"kitty", "New OS window"}) elseif app:isFrontmost() then app:hide() else app:activate() end else hs.application.launchOrFocus("kitty") app = hs.application.get("kitty") end app:mainWindow():moveToUnit'[100,50,0,0]' app:mainWindow().setShadows(false) end)
This is awesome. Although I experienced two bugs with it:
(1) If you close Kitty using CMD+W, then this script won't work anymore. (2) The first run of Kitty doesn't show it at the top. It start at center. Subsequent show/hides of Kitty bring it to the top though.
I tried many ways of doing this and eventually settled on Hammerspoon. I prefer it because it's free, flexible, easy to set up programmatically in my dotfiles, and fast. (That last point is important. For example, you can avoid installing external software and instead make a shortcut in System Preferences for an Automator "Service", but there's a second-long delay after pressing the keys.)
Putting this in ~/.hammerspoon/init.lua will show/hide kitty when you press CtrlSpace:
hs.hotkey.bind({"ctrl"}, "space", function() local app = hs.application.get("kitty") if app then if not app:mainWindow() then app:selectMenuItem({"kitty", "New OS window"}) elseif app:isFrontmost() then app:hide() else app:activate() end else hs.application.launchOrFocus("kitty") end end)
Or, if you want it to always open a new window:
hs.hotkey.bind({"ctrl"}, "space", function() local app = hs.application.get("kitty") if app then app:selectMenuItem({"kitty", "New OS window"}) else hs.application.launchOrFocus("kitty") end end)
If you set macos_hide_from_tasks yes
this doesn't work properly since there is no menu item to select when kitty is in focus.
I would therefore recommend to use the launchOrFocus
method instead
-- toggle kitty
hs.hotkey.bind({"alt"}, "space", function()
local app = hs.application.get("kitty")
if app:isFrontmost() then
app:hide()
else
hs.application.launchOrFocus(app:name())
end
end)
wanted to share my revision of one of the scripts using skhd / yabai from above. (@typkrft )
function kitty_quake() {
KITTY=$(pgrep -a -f ".*kitty.*")
QUAKE=$(GetWindowID kitty "$1")
if [[ $KITTY == "" ]]; then
open -a kitty -n --args -1 --session="/Users/craigoej/.config/kitty/${1}.conf" --listen-on=unix:/tmp/kitty -o macos_quit_when_last_window_closed=no false
while [[ $KITTY == "" ]]
do
KITTY=$(pgrep -a -f ".*kitty.*")
done
open /Applications/kitty.app -n --args --single-instance --session "/Users/craigoej/.config/kitty/${1}.conf" --listen-on=unix:/tmp/kitty
while [[ $QUAKE != "$1" ]]
do
QUAKE=$(GetWindowID kitty "$1")
done
WINDOW_ID=$(GetWindowID kitty "${1}")
yabai -m window $WINDOW_ID --toggle sticky
yabai -m window $WINDOW_ID --move abs:0:0
yabai -m window $WINDOW_ID --resize abs:10000:450
yabai -m window $WINDOW_ID --opacity 0.95
exit 0
elif [[ $KITTY != "" && $QUAKE == "" ]]; then
open /Applications/kitty.app -n --args --single-instance --session "/Users/craigoej/.config/kitty/${1}.conf" --listen-on=unix:/tmp/kitty
while [[ $QUAKE != "${1}" ]]
do
QUAKE=$(GetWindowID kitty "$1")
done
WINDOW_ID=$(GetWindowID kitty "${1}")
yabai -m window $WINDOW_ID --toggle sticky
yabai -m window $WINDOW_ID --move abs:0:0
yabai -m window $WINDOW_ID --resize abs:10000:450
yabai -m window $WINDOW_ID --opacity 0.95
elif [[ $KITTY != "" && $QUAKE != "" ]]; then
WINDOW_ID=$(GetWindowID kitty "${1}")
INFO=$(yabai -m query --windows --window $WINDOW_ID )
BORDER=$(echo $INFO | jq '.["has-border"]')
FOCUS=$(echo $INFO | jq '.["has-focus"]')
MINI=$(echo $INFO | jq '.["is-minimized"]')
echo $MINI
echo $WINDOW_ID
echo $BORDER
echo $MINI
if [[ $MINI == "true" ]]; then
echo "a"
[[ $FOCUS == "false" ]] || :
echo "b"
yabai -m window "${WINDOW_ID}" --deminimize "${WINDOW_ID}";
#yabai -m window "${WINDOW_ID}" --opacity 0.95;
yabai -m window "$WINDOW_ID" --focus "$WINDOW_ID";
elif [[ $MINI -eq "false" ]]; then
if [[ $FOCUS == "false" ]]; then
yabai -m window "$WINDOW_ID" --focus "$WINDOW_ID";
else
yabai -m window "$WINDOW_ID" --opacity 0.001;
yabai -m window "$WINDOW_ID" --minimize ${WINDOW_ID};
fi
fi
fi
}
kitty_quake $1
and you call it like this
ctrl - return : ~/bin/kitty_quake.sh "whatever"
changes:
I have it open a tmuxinator session defined in the session config.
Code below allows you to spawn your terminal from the screen your mouse is on.
local app = hs.application.get("kitty")
local win = app:focusedWindow()
local appscreen = win:screen()
local mousescreen = hs.mouse.getCurrentScreen()
if app then
if appscreen == mousescreen then
if app:isFrontmost() then
app:hide()
else
app:activate()
app:mainWindow():moveToUnit'[100,50,0,100]'
end
else
win:moveToScreen(mousescreen)
if app:isHidden() then
app:activate()
app:mainWindow():moveToUnit'[100,50,0,100]'
end
end
end
app:mainWidnow().setShadows(false)
end)
I created a phoenix script which does this. But only in mac!
brew install --cask phoenix
copy the following file to
~/.phoenix.js
https://github.com/lukesmurray/bootstrap/blob/master/.phoenix.js
Use cmd+` (backtick) to get the dropdown.
These are the relevant lines. You can make your own shortcut
It worked like a charm! Ty bro!
Did you, or anyone else, find a way to make this move the terminal to the desktop you are on. So you have this "floating window" effect like iTerm2.
This works, but it doesn't function like a "drop-down" terminal, if that makes sense.
This is already a quite long thread with many ideas and solutions but I would like to propose that this functionality becomes a native feature of Kitty. I'm aware that Kitty is a cross-platform application so the feature probably needs to be developed individually for every supported platform. However I believe that only Kitty truly knows which of the opened windows is the "Quake-style" window, so it can provide the best user experience.
For example I wrote my own Phoenix script based on solutions presented here but it also has its drawbacks: For instance it's not possible to find out which of the opened Kitty windows is the pulldown window so the script will place the current active window to the top half of my screen. Also the script can only hide/show all Kitty windows at once, but I only want to toggle the pulldown window.
In my workflow I usually have one pulldown terminal window and sometimes additional (OS) windows which should not interfere with the pulldown functionality.
This may be a limitation of Phoenix so if somebody has a better idea of implementing this for macOS please let me know 😃
Just an FYI, if you use the GNOME desktop environment, there's a quake-mode extension available that works pretty well (it's even more customizable than iTerm2 on Mac). I discovered it after installing gnome-shell-extensions using apt-get, and despite being listed as 'Manually Installed', it was already there. Alternatively, you can visit the dev page to install it yourself. It is said to be "Developed for usage tilix on Wayland but can manage almost any application." I can confirm that it works perfectly with Kitty on Wayland, too.
I wanted to create the iTerm hotkey window behaviour exactly with Kitty and Hammerspoon and ended up combining the approach from @exoticus and @mk12 - https://github.com/kovidgoyal/kitty/issues/45#issuecomment-573196169
with this gist from @asmagill for capturing the ctrl double tap in Hammerspoon - https://gist.github.com/asmagill/c38f75fff9d9ef43d1226329fc1436e4
Here is how you can do it. Add the following module (from the gist above) to a file called ~/.hammerspoon/ctrldouble.lua
:
local alert = require("hs.alert")
local timer = require("hs.timer")
local eventtap = require("hs.eventtap")
local events = eventtap.event.types
local module = {}
-- Save this in your Hammerspoon configuration directiorn (~/.hammerspoon/)
-- You either override timeFrame and action here or after including this file from another, e.g.
--
-- ctrlDoublePress = require("ctrlDoublePress")
-- ctrlDoublePress.timeFrame = 2
-- ctrlDoublePress.action = function()
-- do something special
-- end
-- how quickly must the two single ctrl taps occur?
module.timeFrame = 1
-- what to do when the double tap of ctrl occurs
module.action = function()
alert("You double tapped ctrl!")
end
-- Synopsis:
-- what we're looking for is 4 events within a set time period and no intervening other key events:
-- flagsChanged with only ctrl = true
-- flagsChanged with all = false
-- flagsChanged with only ctrl = true
-- flagsChanged with all = false
local timeFirstControl, firstDown, secondDown = 0, false, false
-- verify that no keyboard flags are being pressed
local noFlags = function(ev)
local result = true
for k,v in pairs(ev:getFlags()) do
if v then
result = false
break
end
end
return result
end
-- verify that *only* the ctrl key flag is being pressed
local onlyCtrl = function(ev)
local result = ev:getFlags().ctrl
for k,v in pairs(ev:getFlags()) do
if k ~= "ctrl" and v then
result = false
break
end
end
return result
end
-- the actual workhorse
module.eventWatcher = eventtap.new({events.flagsChanged, events.keyDown}, function(ev)
-- if it's been too long; previous state doesn't matter
if (timer.secondsSinceEpoch() - timeFirstControl) > module.timeFrame then
timeFirstControl, firstDown, secondDown = 0, false, false
end
if ev:getType() == events.flagsChanged then
if noFlags(ev) and firstDown and secondDown then -- ctrl up and we've seen two, so do action
if module.action then module.action() end
timeFirstControl, firstDown, secondDown = 0, false, false
elseif onlyCtrl(ev) and not firstDown then -- ctrl down and it's a first
firstDown = true
timeFirstControl = timer.secondsSinceEpoch()
elseif onlyCtrl(ev) and firstDown then -- ctrl down and it's the second
secondDown = true
elseif not noFlags(ev) then -- otherwise reset and start over
timeFirstControl, firstDown, secondDown = 0, false, false
end
else -- it was a key press, so not a lone ctrl char -- we don't care about it
timeFirstControl, firstDown, secondDown = 0, false, false
end
return false
end):start()
return module
Then, add this code (based off of @exoticus @mk12) to your ~/.hammerspoon/init.lua
config file (or your own one if you use a different name) :
ctrlDoublePress = require("ctrldouble")
ctrlDoublePress.action = function()
local app = hs.application.get("kitty")
if app then
if not app:mainWindow() then
app:selectMenuItem({"kitty", "New OS window"})
elseif app:isFrontmost() then
app:hide()
else
app:activate()
end
else
hs.application.launchOrFocus("kitty")
app = hs.application.get("kitty")
end
app:mainWindow():moveToUnit'[100,50,0,0]'
end
Works like a charm on MacOS. I've remapped my capslock to ctrl and this exactly recreates the Iterm hotkey window behaviour (much faster and lower resource usage thanks to kitty)
@prajnak Does your solution work with multiple opened OS windows of Kitty? Will it only show / hide the hotkey window while other windows are still shown?
@svenjacobs it will hide/show the last active kitty window.. But that's ok for now for me.
With hammerspoon it is better to select applications with bundleID()
not with name()
just because if there is at least one window with an active title matching the search string in hs.application.get()
method, hammerspoon will select it (docs). For example, if you are on this page or on the kitty documentation page, trying to invoke the shortcut to open a new window will not have the expected result because the tab title contains "kitty".
The BundleID
can be obtained with codesign -dr - /path/to/Application.app
in identifier
field or via the hammerspoon console:
> kitty = hs.application.get("kitty")
> kitty:bundleID()
net.kovidgoyal.kitty
And while in most cases getting the application by name
will work, it's a little better to get it by bundleID
, respectively just replace value for get()
method from name
to bundleID
, i.e. local app = hs.application.get("net.kovidgoyal.kitty")
I've adapted the script slightly as it didn't work for me when I'm not focused on kitty and in a different Space. My use case is that I want Kitty opened permanently in one space but still be able to bring up new kitty window instances while I'm working in other spaces.
hs.hotkey.bind({"ctrl"}, "space", function()
local app = hs.application.get("kitty")
local currentSpace = hs.spaces.focusedSpace()
if app then
-- There are times where main window is found and other times not
-- This check ensures that we have a main window ID set in cases where
-- it is found or set to -1 in cases where it is not found
-- this ensures that the new window call can be executed later.
if not app:mainWindow() then
mainWindowSpace = -1
else
mainWindowSpace = hs.spaces.windowSpaces( app:mainWindow():id())[1]
end
if mainWindowSpace ~= currentSpace then
app:selectMenuItem({"Shell", "New OS Window"})
hs.timer.doAfter(1, function()
app:focusedWindow():moveToUnit'[100,50,0,0]'
end)
elseif app:isFrontmost() then
app:hide()
else
app:activate()
end
else
hs.application.launchOrFocus("kitty")
app = hs.application.get("kitty")
end
end)
It has something to do with how app:mainWindow is defined. The main window kept referring back to one already opened.
I also wrote a Hammerspoon script for this: https://gist.github.com/truebit/d79b8018666d65e95970f208d8f5d149; the script supports:
I also wrote a Hammerspoon script for this: https://gist.github.com/truebit/d79b8018666d65e95970f208d8f5d149; the script supports:
* multi window and space show/hide; * more accurate kitty app detection using bundle id; * automatically move kitty window to the top of the screen; * additional kitty config to make script more robustly;
@truebit hi!
getMainWindow(app):move(hs.geometry({x=0,y=0,w=0.6,h=0.4}))
The width of the Kitty window is always the width of the monitor And if the stage manager for macOS is enabled, the X coordinate of the Kitty window is not 0 but more to the right
@I-Want-ToBelieve I tried on 13.5.1 (22G90) and 14.1 (23B74), there's no issue. maybe you could use default stage manager settings or tell me the reproducible steps
@truebit It's probably because I didn't set up the kitty config posted in your gist.
Now I use yabai and no longer enable stage manager.
I am more familiar with JavaScript than Lua, so I switched to the above solution of phoenix and yabai.
Sorry to bother you.
By the way, I was using mac 13.6 before
Easiest way I found on Mac OS without third party apps.
Open automator -> New Quick Action. Drag the "Run Shell Script" from the left side to the right side and type:
nohup /Applications/kitty.app/Contents/MacOS/kitty -1 1> /dev/null 2> /dev/null &
Save it with a name like Start Kitty
Go in System Settings -> Keyboard Shortcuts -> Services tab -> General -> Start Kitty
. Assign keystroke.
Voilà .
Another native way for macOS
is to do the following:
Open Apple's "Script Editor" app and select "New Document".
Once in the document, ensure the dropdown is set to "Applescript" (should be by default).
Add the following code
do shell script "/path/to/kitty"
Save this with file format as "Text" (so you can version control it in git
). It will have the *.applescript
extension.
Export as an "Application" with everything unchecked and "Sign to run Locally" with a name like "Kitty".
Now you have an executable icon. You can drag it into "Applications" folder if you would like. You can also now Spotlight search "Kitty" and run it as with any other app.
Bonus step: Add the kitty icon to the executable by doing the following:
This is not possible to do in a cross-platform manner, as it depends on the details of the desktop environment/window manager. Really this function should be implemented in the window manager, so it can be performed with any window.
For instance, I use a tiling window manager, and I have a key binding to instantly bring up a terminal.