herbstluftwm / herbstluftwm

A manual tiling window manager for X11
http://herbstluftwm.org/
Other
1.1k stars 71 forks source link

Implement an `auto_remove_empty_frames` setting #1492

Open Barbaross93 opened 2 years ago

Barbaross93 commented 2 years ago

As discussed in IRC, it would be convenient to have an auto_remove_empty_frames setting that automatically removes frames when they become empty; such as after closing the last window, shifting the last window to another frame, or move_index on the last window in the frame.

kriansa commented 2 years ago

I'm not aware of what's been discussed before, but just for the sake of reference (and while this is not a solution for this issue), you can bind a key to close_and_remove so that after closing the last window in the frame, that frame will also be removed, which is close to your first request.

Barbaross93 commented 2 years ago

@kriansa Yes, I am aware of close_and_remove, and thanks for bringing it up for posterity. That is, as you said, only one part of the solution. IIRC, @t-wissmann suggested the setting approach in IRC. I'm wondering if this means that close_and_remove should be deprecated and/or if there should also be something like move_index_and_remove?

etosan commented 2 years ago

Sorry @Barbaross93 I am heavy both close and close_and_remove and also remove user. Removing close_and_remove would really sadden me as it would break many of my workflows - I think I am even responsible for close_and_remove existing. If you guys think hlwm would be better with it removed, what can I really do (?), but if I can I would like to block it's removal.

Barbaross93 commented 2 years ago

I'm not suggesting we remove anything. I was brainstorming alternative ideas in my last comment. The only thing I actually want to see and makes the most sense to me is an auto_remove_empty_frames setting.

etosan commented 2 years ago

Sorry @Barbaross93 for jumping to conclusions, my bad. Setting itself (as it seems toggleable) is orthogonal to my needs when off, and thus doesn't concern me.

BBoal commented 1 year ago

@Barbaross93, I've implemented your idea in my opinionated workflow. Here's my code, so you can adapt for yourself if you find it helpful. Cheers!

_hc()   { herbstclient "$@";}
_bind() { _hc keybind "$@";}

## Function that detaches focused client to a dedicated frame if, in a multiple
## client frame near the monitor's edge the shift command is executed in
## direction of mentioned edge. Empty frames are closed in the process.
_shift_or_detach() {
    split_dir="$2"
    # parsing movement to split options
    [[ "$2" == "up" ]] && split_dir="top"
    [[ "$2" == "down" ]] && split_dir="bottom"
    # If you're shifting right the empty frame to close is on the left (opposite dir)
    declare -A previous_frame     # declaring associative arrays is mandatory
    previous_frame=([left]=right [down]=up [up]=down [right]=left)

    _bind "$1" silent or \
                  , and \
            + compare tags.focus.curframe_wcount = 1 \
            + shift "$2" \
                     + focus -e "${previous_frame[$2]}" \
                     + close_and_remove \
         , shift "$2" \
         , and \
            + compare tags.focus.curframe_wcount gt 1 \
            + split "${split_dir}" 0.5 + shift "$2"
}
_shift_or_detach Super+Shift+h left
_shift_or_detach Super+Shift+j down
_shift_or_detach Super+Shift+k up
_shift_or_detach Super+Shift+l right
Barbaross93 commented 1 year ago

Thanks @BBoal ! This definitely looks useful to me. I ended up poking around your herbstluftwm-config repo and I was curious about this script. Does it move all clients into a frame? How would one use it? I have a script that can swap the clients between two frames, which I find super useful, but I'd be interested in simplifying it's implementation

BBoal commented 1 year ago

@Barbaross93, you're welcome! For convenience, I use that script in line 163 of my autostart, in the same loop where I assign the numeric keys to the workspaces. In my case, for example, pressing the key chord Mod3+Shift+Control+3 will send the focused frame and all the clients in it, to tag 3 (R0 according to my config). Under the hood, the root frame of tag 3 is split in half and a new frame is created and populated with the clients of the previous focused one, which is removed at the end of the script. I don't want to sound pretentious, but in my opinion, you'll also find the snippets in the close/remove section very helpful. Herbstluftwm rocks! A big "Thank you!" to @t-wissmann and all the contributors.