warpdotdev / Warp

Warp is a modern, Rust-based terminal with AI built in so you and your team can build great software, faster.
https://warp.dev
Other
20.85k stars 355 forks source link

Option to fully quit app when last window closed #4114

Open milesromeno opened 7 months ago

milesromeno commented 7 months ago

Discord username (optional)

No response

Describe the solution you'd like?

I use yabai + skhd to achieve a keyboard-based window tiling manager in my MacOS desktop environment. I have cmd + q binded to close an application window like usual, and cmd + \ binded to spawn a new Warp instance via open -n /Applications/Warp.app, so I can have multiple terminals side by side or on different desktops being managed by yabai. The default behavior of Warp makes this problematic -- if I run cmd + \ 3 times to spawn 3 new instances of Warp.app, pressing cmd + q 3 times to close all of them does not actually quit any of the Warp instances. They begin stacking on my taskbar dock as dead processes which I have to go manually force-quit.

image

Rebinding my cmd + q to quit an application (the defalt behavior of cmd + shift + w) as opposed to closing a window is not an acceptable solution as that totally messes with the tiling manager workflow - if I have 3 Warp windows open across multiple Desktops running various processes, I do not want cmd + q to instantly close all 3; I instead want it to only close the window that my tiling manager is currently focused on, and fully kill the app process if the last window is closed, like it does for Firefox. And I am not going to memorize all the application specific keybinds for spawning and closing a new instance, or have two different keybindings for closing apps - those are not reasonable demands. My tiling manager should uniformly handle the opening and killing of all application windows/applications.

I understand that Warp insists on being open as a process even when no windows exist to make new windows spawn faster, but this behavior is commonly disliked by people (developers) coming from linux/windows, and it would be awesome if you included an option to disable it. I really like Warp and do not want this to be what forces me to find an alternative.

At this point all I can think of is to create a script that checks the number of open windows, and conditionally closes or kills based on if there are > 0 windows remaining, and I should not have to do that.

Alternatively, if there is anyway for me to create a new Warp window instead of a process (open -n) as a command that i can bind cmd + \ to execute in my .skhdrc, that would be a fine solution. I did a brief man open and did not see any flags that allow for this. As far as I know, the only way is for me to manually go focus on a pre-existing Warp window, and then press cmd + n, preventing me from being able to spawn a terminal anywhere I want regardless of what app I currently am focusing on, contrary to the philosophy of tiling managers). If my only other opened Warp window is on Desktop 1, and I am Desktop 4 wanting to spawn a new terminal window, I will have to go back to Desktop 1, focus on Warp, press cmd + n, then manually move the new Window to Desktop 4.

Is your feature request related to a problem? Please describe.

No response

Additional context

No response

How important is this feature to you?

5 (Can't work without it!)

Warp Internal (ignore) - linear-label:39cc6478-1249-4ee7-950b-c428edfeecd1

None

dannyneira commented 7 months ago

Thanks for this feature request @milesromeno! As you noted CMD-Q works to close the app entirely, but not within the workflow you have.

To anyone else interested in this feature, please add a 👍 to the original post at the top to signal that you want this feature, and subscribe if you'd like to be notified.

nielsbom commented 7 months ago

I think this would be fixed with #395, right?

netpro2k commented 7 months ago

I am also using warp with skhd and was using open -n and was annoyed by the multiple app instances. I found the url scheme almost does what I want:

cmd - return : open "warp://action/new_window?path=~"

This does open a new window keeping a single instance of warp, but after opening a new window in the current space it often also attempts to switch spaces to another warp window that was already open. I am not quite sure which window it decides to switch to, or when it doesn't decide to switch (I think maybe if I last closed a warp window in a space it ends up switching to that one?).

If the new_window url scheme didn't do the space switching it would be preferred to launching multiple instances with open -n since it is noticeably faster and seems to be more inline with the "intended" workflow warp imagines. Still using warp since I love the other features but this tiny quirk is driving me mad.

netpro2k commented 7 months ago

While I do think it would be nice if the url scheme worked this way (or had an option to). I found a workaround to my problem using yabai. If I set window_origin_display to cursor new warp windows will alway appear on the display/space my mouse is on, which is the behavior I want.

milesromeno commented 4 months ago

While I do think it would be nice if the url scheme worked this way (or had an option to). I found a workaround to my problem using yabai. If I set window_origin_display to cursor new warp windows will alway appear on the display/space my mouse is on, which is the behavior I want.

The appeal of yabai+skhd for me is a keyboard-only experience, so needing to worry about where my mouse cursor had last been moved is an irritation. Or, does your mouse automatically get set to the desktop space that you switch to via keyboard shortcuts, so you never actually have to physically touch your mouse?

milesromeno commented 4 months ago

After multiple months of trying to ignore this mini-irritation dozens of times per day, I've finally settled on a workaround until this trivial feature gets implemented into Warp

brew uninstall warp
brew install iterm2 
# iTerm Settings > General > Closing > "Quit when all windows are closed"

Sad that this was enough to offset all the cool advantages of Warp, but it is seriously so annoying for keyboard power users. Please let me know when this toggle becomes available in Warp.

tarkh commented 4 months ago

You can try to open Warp through URI if it's already running, so its icons will stack in the Dock. I've setup my yabai + skhd + warp like this:

skhdrc

# Close window
alt + shift - q : yabai -m window --close

# Terminal
alt - return : $HOME/.config/skhd/run_warp.sh

run_warp.sh

#!/usr/bin/env bash

APPPATH=/Applications/Warp.app
URI='warp://action/new_window?path=~/'

# Detect if Warp is running
if ! [[ $( ps -A | grep $APPPATH | grep -v grep | awk '{print $1}' ) ]]; then
    # If not, open new app
    open -a "$APPPATH"
else
    # Warp opened, so create a new window
    ! open ${URI} > /dev/null 2>&1 && {
        # Some failsafe logic
        while IFS="" read -r pid; do
            kill -15 "${pid}"
        done < <(ps -A | grep $APPPATH | grep -v grep | awk '{print $1}')
        open -a "$APPPATH"
    }
fi
avichandra2k1 commented 1 month ago

If you use hammerspoon, you can achieve the exact desired behaviour of opening a new warp window in the current space, albeit with some lag sometimes.

NOTE: You will need to turn on switching spaces via mission control. The default behaviour is via ctrl+n where n is the space.

I added this to my init.lua for cmd+return to start a new warp window:

hs.hotkey.bind({"cmd"}, "return", function()
    local originalSpace = hs.spaces.focusedSpace()
    local warp = hs.application.get("Warp")

    if warp then
        warp:activate()
        hs.timer.usleep(100000)  -- Wait for 100ms
        hs.eventtap.keyStroke({"cmd"}, "n")
        hs.timer.usleep(100000)  -- Wait for another 100ms

        local currentSpace = hs.spaces.focusedSpace()
        local warpWindows = warp:allWindows()
        local newWindow = nil

        for _, window in ipairs(warpWindows) do
            if hs.spaces.windowSpaces(window)[1] ~= currentSpace then
                newWindow = window
                hs.spaces.moveWindowToSpace(window, currentSpace)
                break
            end
        end

        -- Switch back to the original space
        hs.timer.doAfter(0.1, function()
            -- Find the index of the original space
            local allSpaces = hs.spaces.allSpaces()
            local spaceIndex = 0
            for displayUUID, spaces in pairs(allSpaces) do
                for i, spaceID in ipairs(spaces) do
                    if spaceID == originalSpace then
                        spaceIndex = i
                        break
                    end
                end
                if spaceIndex ~= 0 then break end
            end

            -- Switch to the original space
            if spaceIndex > 0 then
                hs.eventtap.keyStroke({"ctrl"}, tostring(spaceIndex))
            end

            -- Focus the new Warp window
            if newWindow then
                hs.timer.doAfter(0.1, function()
                    newWindow:focus()
                end)
            end
        end)
    else
        hs.application.launchOrFocus("Warp")
    end
end)

This will open a new warp window of the same instance (does not create multiple processes). If warp is open somewhere else, it'll switch back to the previous space (which is where the lag comes from, maybe tweaking sleep will help speed).

Not sure why warp devs aren't adding this, it's literally core behaviour to any i3 esque workflow.

P.S. this doesn't use yabai, but I use yabai without the scripting addition. I'm feel like this can be almost instant if I had it but that requires SIP to be disabled.

Mazorius commented 3 weeks ago

Hi,

it would be nice to have the option like in iTerm2, that if I close the last window with for example exit the application is fully closed.

Thanks in advance