Skip to content

Instantly share code, notes, and snippets.

@budRich
Last active October 23, 2021 17:06
Show Gist options
  • Save budRich/16765b5468201aa734d0ec1c0870fd0c to your computer and use it in GitHub Desktop.
Save budRich/16765b5468201aa734d0ec1c0870fd0c to your computer and use it in GitHub Desktop.
zen mode in i3wm

2021.10.23

Make windows floating before moving them to origin workspace.

2021.10.19

Use workspace name when appropriate.

2021.10.18

Fixed issue with calculating the next free workspace. When the zencontainer is created, if the last window of a workspace is used to create it. The current workspace will be the zen workspace.

2021.10.17

This script depends on i3list and i3var from i3ass.

When the command is triggered it will move the current window to a zen container. The zen container is a floating, tabbed, and zentered container on a clean workspace. If no zen container exist it will be created.

If the current window already is in the zen container it will get moved to the workspace it originally came from.


The previous version used two "ghost windows" to make a tiled container appear centered. But i figured why not use a floating container instead, script is a lot faster and experience better. Now it is also possible to set the height (also in percentage) of the container.


Available environment variables:

ZEN_WIDTH , ZEN_HEIGHT, ZEN_WORKSPACE, ZEN_VERBOSE

#!/bin/bash
# Copyright (C) 2017-2021 by budRich
#
# Permission to use, copy, modify, and/or
# distribute this software for any purpose with or
# without fee is hereby granted.
#
# i3zen - move current window to a "clean" workspace,
# put it in a centered, floating tabbed container.
#
# triggering the command on a window that is already
# "zen" will move it back to the workspace it came
# from.
#
# https://www.reddit.com/r/i3wm/comments/6x8ajm/oc_i3zen/
# https://www.reddit.com/r/unixporn/comments/6xbdtk/oci3_i3zen/
# https://gist.github.com/budRich/16765b5468201aa734d0ec1c0870fd0c
: "${ZEN_VERBOSE:=0}"
# ZEN_VERBOSE=1
# ZEN_WORKSPACE - the workspace number you want to
# use for zen leave it empty if you want the
# script to use the next empty ws.
: "${ZEN_WORKSPACE:=}"
# percentage of screen zen container will be when
# it is created
: "${ZEN_WIDTH:=60}"
: "${ZEN_HEIGHT:=90}"
ERM() { >&2 echo "$*" ;}
messy() {
((ZEN_VERBOSE)) && ERM "m $*"
_msgstring+="$*;"
}
declare -A i3list
eval "$(i3list -m centerzen)"
ws_zen=${i3list[WST]}
if [[ ! $ws_zen ]]; then
ws_raw=$(i3-msg -t get_workspaces)
new_zen=1
re='"num":([0-9]+)'
while [[ $ws_raw =~ $re ]]; do
ws_temp=${BASH_REMATCH[1]}
[[ $ZEN_WORKSPACE = "$ws_temp" ]] && taken=1
ws_raw=${ws_raw/\"num\":$ws_temp/}
((ws_temp > ws_free)) && ws_free=$ws_temp
done
[[ $ZEN_WORKSPACE && taken -ne 1 ]] \
&& ws_zen=$ZEN_WORKSPACE \
|| ws_zen=$((ws_free+1))
messy "[con_id=${i3list[AWC]}]" \
"move to workspace number $ws_zen," \
"floating disable," \
"split v, layout tabbed," \
"focus, focus parent"
messy "mark centerzen"
((ZEN_WIDTH < 0 || ZEN_WIDTH > 100)) && ZEN_WIDTH=100
((ZEN_HEIGHT < 0 || ZEN_HEIGHT > 100)) && ZEN_HEIGHT=100
width=$(( (i3list[WAW] * ZEN_WIDTH) / 100 ))
height=$(( (i3list[WAH] * ZEN_HEIGHT) / 100 ))
x=$(( i3list[WAX] + (i3list[WAW]-width) / 2 ))
y=$(( i3list[WAY] + (i3list[WAH]-height) / 2 ))
messy "[con_mark=centerzen] floating enable, workspace number $ws_zen"
messy "[con_id=${i3list[AWC]}] focus"
messy "[con_mark=centerzen]" \
"resize set $width $height ," \
"move position $x $y"
i3var set "zen${i3list[AWC]}" "${i3list[AWF]}:${i3list[WAN]}"
elif ((i3list[WSA] == ws_zen)); then
var_data=$(i3var get "zen${i3list[AWC]}")
[[ $var_data =~ (0|1):(.+) ]] && {
trg_ws=${BASH_REMATCH[2]}
((BASH_REMATCH[1])) \
&& trg_float_state=enable \
|| trg_float_state=disable
messy "[con_id=${i3list[AWC]}]" \
floating enable, \
"move to workspace $trg_ws," \
"floating $trg_float_state," \
"workspace $trg_ws"
i3var set "zen${i3list[AWC]}"
}
else
messy "[con_id=${i3list[AWC]}]" \
"floating disable," \
"move to mark centerzen," \
"focus, workspace number $ws_zen"
i3var set "zen${i3list[AWC]}" "${i3list[AWF]}:${i3list[WAN]}"
fi
((ZEN_VERBOSE)) || qflag=-q
[[ $_msgstring ]] && i3-msg ${qflag:-} "$_msgstring"
unset _msgstring
# the variable new_zen is only set when the zen container is created.
# here we test if that workspace still exist. If it doesn't we move
# the zencontainer back to that workspace.
((new_zen)) && {
re='"num":'"${i3list[WSA]}",
[[ $(i3-msg -t get_workspaces) =~ $re ]] || {
messy "[con_mark=centerzen]" \
move to workspace "${i3list[WAN]}", \
workspace "${i3list[WAN]}"
i3-msg ${qflag:-} "$_msgstring"
}
}
@Mange
Copy link

Mange commented May 12, 2018

I suggest not having the path to the other scripts hardcoded like that. :-)

I have all my own personal bin files under ~/.local/bin instead of ~/bin to keep ~ cleaner.
Wouldn't it be easier to rely on PATH instead?

(I could fix this locally, but then I cannot download newer versions of this file automatically from the Gist URL.)

@benjaminvdb
Copy link

benjaminvdb commented Oct 17, 2021

This works wonderfully to toss out some of my ultrawide monitor's screen real estate, when I want to focus on just one window. Before I used a keybinding to increase the left and right gaps, but this also meant I couldn't enable smart_gaps. This meant a border was shown even on workspaces with just one container. i3zen takes care of this. Thanks! 🙏

Just make sure you run i3zen with exec --no-startup-id, otherwise you see a loading indicator on the left and right ghost containers.

@budRich: is there a way to automatically close the ghost containers when the visible zen container is closed? If I close the zen container, the ghost containers are left open and the workspace isn't automatically deleted when I move to another workspace.

@budRich
Copy link
Author

budRich commented Oct 17, 2021

@benjaminvdb :D I had completely forgot about this script. I think I will take a look, and see if i can add the functionality you request. It is possible.

@Mange : yes you are right I will fix that as well.

@budRich
Copy link
Author

budRich commented Oct 17, 2021

@benjaminvdb , try the new version. I now make the zen container floating, and don't use any ghost containers. The centerzen container will automatically get destroyed when the last window leaves it.

@benjaminvdb
Copy link

benjaminvdb commented Oct 18, 2021

@budRich: it's great that you gave this script an update. Thanks so much!

EDIT: Upgrading to the latest version of i3ass solved the issue below 🥳 I hope you don't mind, but have a feature request: is it possible to add a setting (or make it default) that allows me to keep the zen container on the current workspace, if it's the only container there? Currently, it moves the container to ws9, because I usually have something on ws8. ws9 is beyond the limit I set for myself of 8 workspaces.

Entering zen mode works most of the time. Sometimes the script chooses an occupied workspace, and the floating zen container is placed on top of open windows. Also, when I rerun the script while a zen container is focussed, the zen container moves to the next empty workspace, instead of disabling zen mode. I haven't modified the script in any way, and I'm running it using the i3 keybinding below. Do you know what could be causing this?

bindsym $mod+y exec --no-startup-id "$HOME/bin/i3zen

@budRich
Copy link
Author

budRich commented Oct 18, 2021

@benjaminvdb Great to hear you got it working. Yeah, I applied a patch to i3ass just before updating i3zen, so latest at least version: 2021.10.17.0 of i3ass is needed.

I like the feature you request, but it is a bit tricky to implement, since we need to count the number of windows on the current workspace. Which is possible, but tricky, i have some ideas. A simpler, rougher way to achieve the functionality. Would be to always move to a new workspace (current behavior). Then test if the old workspace still exist. If it doesn't we moved the last window from that workspace, and we simply move the centerzen container back to the workspace (thus creating it again, and destroying the new). I don't think the moving back and forth will be noticeable, since the workspace will appear identical (just the centerzen container).

Thanks for the feedback!

@budRich
Copy link
Author

budRich commented Oct 18, 2021

@benjaminvdb , I updated the script with your feature request applied. (I used the last method described in my previous comment, because it worked).

@benjaminvdb
Copy link

@budRich That's really kind. Thanks a lot!

This version almost works for me. When I first run the script, the floating zen container is created on the current workspace. However, when I rerun it, the container is moved to the next empty workspace. That is, it's not 'undoing' the operation, which is what I'd expect.

I'm sorry for bothering you with this. I'm a developer myself, but I'm not too familiar with bash scripting and your i3ass programs, so I found it hard to follow your script, even though I can see it's well-structured.

@budRich
Copy link
Author

budRich commented Oct 20, 2021

@benjaminvdb I think the issues was related to workspace names, if the name of the workspace was just a number, it was no problems. but otherwise it got kind of borked out. I think i have fixed it now with the latest update.

You are not bothering me at all with this. I always wanted to get a stable version of this script. And we are soon there!

@benjaminvdb
Copy link

@budRich Unfortunately, the problem still persists. The zen container is created, but it is moved to a new empty workspace when I rerun the script. I use set $ws1 1 etc., in my i3 config to set workspace names. Let me know if there's anything I can do to help with debugging. Thanks again for your help!

@budRich
Copy link
Author

budRich commented Oct 23, 2021

@benjaminvdb I updated the script. But I am not sure it have fixed your issue. (I can't replicate your issue). But there was a "bug". i didn't realize that the windows in the zen container are not floating, they are considered tiled, even if the parent container is floating. Before realizing this I had issues not when the zen container was created, rather when windows where sent from it. But now it works for me 100%.

You can start the script like this:
ZEN_DEBUG=1 zen and it will print stuff to stderr about which commands was executed and such. (if you execute the zen command from a keybinding its a bit tricky to see this output, but for testing purposes you fire the command from the terminal). Also, when you try a new version of the script it is probably a good idea to either do it in a fresh session (log in/out from i3/X) or clear all marks (i3-msg unmark). It can also be helpful to look at the marks: i3-msg -t get_marks.

If you still have the issue, i guess it would be good to see exactly what workspaces and windows you have open before and after the zen container is created. You can make a dump of the i3 tree with the command: i3-msg -t get_tree , it will spit out a quite large minified json object. paste the output of that command, both before and after you have done i3zen.

you can use the script below and paste the content of i3treeop

be aware that the json can contain sensitive information in the form of the full title of windows and such

#!/bin/bash
i3-msg -t get_tree > /tmp/i3treeop
i3zen # if that is the name/path to the i3zen script
i3-msg -t get_tree >> /tmp/i3treeop

@benjaminvdb
Copy link

@budRich Thanks again for your help. The new version doesn't solve my issue yet, so I've included the output of i3treeop, like you suggested. I've also included the output of the first and second runs of ZEN_VERBOSE=1 i3zen.

i3treeop

{"id":94871215831936,"type":"root","orientation":"horizontal","scratchpad_state":"none","percent":null,"urgent":false,"marks":[],"focused":false,"layout":"splith","workspace_layout":"default","last_split_layout":"splith","border":"pixel","current_border_width":-1,"rect":{"x":0,"y":0,"width":1920,"height":1200},"deco_rect":{"x":0,"y":0,"width":0,"height":0},"window_rect":{"x":0,"y":0,"width":0,"height":0},"geometry":{"x":0,"y":0,"width":0,"height":0},"name":"root","window":null,"window_type":null,"nodes":[{"id":94871215812112,"type":"output","orientation":"none","scratchpad_state":"none","percent":0.5,"urgent":false,"marks":[],"focused":false,"layout":"output","workspace_layout":"default","last_split_layout":"splith","border":"pixel","current_border_width":-1,"rect":{"x":0,"y":0,"width":1920,"height":1200},"deco_rect":{"x":0,"y":0,"width":0,"height":0},"window_rect":{"x":0,"y":0,"width":0,"height":0},"geometry":{"x":0,"y":0,"width":0,"height":0},"name":"__i3","window":null,"window_type":null,"nodes":[{"id":94871215846928,"type":"con","orientation":"horizontal","scratchpad_state":"none","percent":null,"urgent":false,"marks":[],"focused":false,"output":"__i3","layout":"splith","workspace_layout":"default","last_split_layout":"splith","border":"pixel","current_border_width":-1,"rect":{"x":0,"y":0,"width":0,"height":0},"deco_rect":{"x":0,"y":0,"width":0,"height":0},"window_rect":{"x":0,"y":0,"width":0,"height":0},"geometry":{"x":0,"y":0,"width":0,"height":0},"name":"content","window":null,"window_type":null,"nodes":[{"id":94871215849920,"type":"workspace","orientation":"none","scratchpad_state":"none","percent":null,"urgent":false,"marks":[],"focused":false,"output":"__i3","layout":"splith","workspace_layout":"default","last_split_layout":"splith","border":"pixel","current_border_width":-1,"rect":{"x":0,"y":0,"width":0,"height":0},"deco_rect":{"x":0,"y":0,"width":0,"height":0},"window_rect":{"x":0,"y":0,"width":0,"height":0},"geometry":{"x":0,"y":0,"width":0,"height":0},"name":"__i3_scratch","num":-1,"gaps":{"inner":0,"outer":0,"top":0,"right":0,"bottom":0,"left":0},"window":null,"window_type":null,"nodes":[],"floating_nodes":[{"id":94871215885728,"type":"floating_con","orientation":"horizontal","scratchpad_state":"fresh","percent":null,"urgent":false,"marks":[],"focused":false,"output":"__i3","layout":"splith","workspace_layout":"default","last_split_layout":"splith","border":"pixel","current_border_width":-1,"rect":{"x":514,"y":342,"width":892,"height":516},"deco_rect":{"x":0,"y":0,"width":0,"height":0},"window_rect":{"x":0,"y":0,"width":0,"height":0},"geometry":{"x":0,"y":0,"width":0,"height":0},"name":null,"window":null,"window_type":null,"nodes":[{"id":94871215885248,"type":"con","orientation":"none","scratchpad_state":"none","percent":1.0,"urgent":false,"marks":[],"focused":false,"output":"__i3","layout":"splith","workspace_layout":"default","last_split_layout":"splith","border":"pixel","current_border_width":4,"rect":{"x":514,"y":342,"width":892,"height":516},"deco_rect":{"x":0,"y":0,"width":0,"height":0},"window_rect":{"x":4,"y":4,"width":884,"height":508},"geometry":{"x":0,"y":0,"width":884,"height":508},"name":"benny@talos:~","window":8388618,"window_type":"unknown","window_properties":{"class":"URxvt","instance":"__scratchpad","title":"benny@talos:~","transient_for":null},"nodes":[],"floating_nodes":[],"focus":[],"fullscreen_mode":0,"sticky":true,"floating":"user_on","swallows":[]}],"floating_nodes":[],"focus":[94871215885248],"fullscreen_mode":0,"sticky":false,"floating":"auto_off","swallows":[]},{"id":94871215906848,"type":"floating_con","orientation":"horizontal","scratchpad_state":"changed","percent":null,"urgent":false,"marks":[],"focused":false,"output":"__i3","layout":"splith","workspace_layout":"default","last_split_layout":"splith","border":"pixel","current_border_width":-1,"rect":{"x":209,"y":144,"width":1502,"height":888},"deco_rect":{"x":0,"y":0,"width":0,"height":0},"window_rect":{"x":0,"y":0,"width":0,"height":0},"geometry":{"x":0,"y":0,"width":0,"height":0},"name":null,"window":null,"window_type":null,"nodes":[{"id":94871215903728,"type":"con","orientation":"none","scratchpad_state":"none","percent":1.0,"urgent":false,"marks":[],"focused":false,"output":"__i3","layout":"splith","workspace_layout":"default","last_split_layout":"splith","border":"pixel","current_border_width":1,"rect":{"x":517,"y":333,"width":886,"height":510},"deco_rect":{"x":0,"y":0,"width":0,"height":0},"window_rect":{"x":4,"y":4,"width":884,"height":508},"geometry":{"x":0,"y":0,"width":884,"height":508},"name":"ranger","window":10485770,"window_type":"unknown","window_properties":{"class":"URxvt","instance":"__ranger","title":"ranger","transient_for":null},"nodes":[],"floating_nodes":[],"focus":[],"fullscreen_mode":0,"sticky":true,"floating":"user_on","swallows":[]}],"floating_nodes":[],"focus":[94871215903728],"fullscreen_mode":0,"sticky":false,"floating":"auto_off","swallows":[]}],"focus":[94871215885728,94871215906848],"fullscreen_mode":1,"sticky":false,"floating":"auto_off","swallows":[]}],"floating_nodes":[],"focus":[94871215849920],"fullscreen_mode":0,"sticky":false,"floating":"auto_off","swallows":[]}],"floating_nodes":[],"focus":[94871215846928],"fullscreen_mode":0,"sticky":false,"floating":"auto_off","swallows":[]},{"id":94871215852912,"type":"output","orientation":"none","scratchpad_state":"none","percent":0.5,"urgent":false,"marks":[],"focused":false,"layout":"output","workspace_layout":"default","last_split_layout":"splith","border":"pixel","current_border_width":-1,"rect":{"x":0,"y":0,"width":1920,"height":1200},"deco_rect":{"x":0,"y":0,"width":0,"height":0},"window_rect":{"x":0,"y":0,"width":0,"height":0},"geometry":{"x":0,"y":0,"width":0,"height":0},"name":"eDP-1","window":null,"window_type":null,"nodes":[{"id":94871215855904,"type":"dockarea","orientation":"none","scratchpad_state":"none","percent":null,"urgent":false,"marks":[],"focused":false,"output":"eDP-1","layout":"dockarea","workspace_layout":"default","last_split_layout":"splith","border":"pixel","current_border_width":-1,"rect":{"x":0,"y":0,"width":1920,"height":0},"deco_rect":{"x":0,"y":0,"width":0,"height":0},"window_rect":{"x":0,"y":0,"width":0,"height":0},"geometry":{"x":0,"y":0,"width":0,"height":0},"name":"topdock","window":null,"window_type":null,"nodes":[],"floating_nodes":[],"focus":[],"fullscreen_mode":0,"sticky":false,"floating":"auto_off","swallows":[{"dock":2,"insert_where":2}]},{"id":94871215859040,"type":"con","orientation":"horizontal","scratchpad_state":"none","percent":null,"urgent":false,"marks":[],"focused":false,"output":"eDP-1","layout":"splith","workspace_layout":"default","last_split_layout":"splith","border":"pixel","current_border_width":-1,"rect":{"x":0,"y":0,"width":1920,"height":1177},"deco_rect":{"x":0,"y":0,"width":0,"height":0},"window_rect":{"x":0,"y":0,"width":0,"height":0},"geometry":{"x":0,"y":0,"width":0,"height":0},"name":"content","window":null,"window_type":null,"nodes":[{"id":94871215865424,"type":"workspace","orientation":"horizontal","scratchpad_state":"none","percent":null,"urgent":false,"marks":[],"focused":false,"output":"eDP-1","layout":"splith","workspace_layout":"default","last_split_layout":"splith","border":"pixel","current_border_width":-1,"rect":{"x":0,"y":0,"width":1920,"height":1177},"deco_rect":{"x":0,"y":0,"width":0,"height":0},"window_rect":{"x":0,"y":0,"width":0,"height":0},"geometry":{"x":0,"y":0,"width":0,"height":0},"name":"1","num":1,"gaps":{"inner":0,"outer":0,"top":0,"right":0,"bottom":0,"left":0},"window":null,"window_type":null,"nodes":[{"id":94871215916816,"type":"con","orientation":"none","scratchpad_state":"none","percent":1.0,"urgent":false,"marks":[],"focused":true,"output":"eDP-1","layout":"splith","workspace_layout":"default","last_split_layout":"splith","border":"pixel","current_border_width":4,"rect":{"x":0,"y":0,"width":1920,"height":1177},"deco_rect":{"x":0,"y":0,"width":0,"height":0},"window_rect":{"x":0,"y":0,"width":1920,"height":1177},"geometry":{"x":0,"y":0,"width":884,"height":508},"name":"./dump_i3.sh","window":48234506,"window_type":"unknown","window_properties":{"class":"URxvt","instance":"urxvt","title":"./dump_i3.sh","transient_for":null},"nodes":[],"floating_nodes":[],"focus":[],"fullscreen_mode":0,"sticky":false,"floating":"auto_off","swallows":[]}],"floating_nodes":[],"focus":[94871215916816],"fullscreen_mode":1,"sticky":false,"floating":"auto_off","swallows":[]}],"floating_nodes":[],"focus":[94871215865424],"fullscreen_mode":0,"sticky":false,"floating":"auto_off","swallows":[]},{"id":94871215862160,"type":"dockarea","orientation":"none","scratchpad_state":"none","percent":null,"urgent":false,"marks":[],"focused":false,"output":"eDP-1","layout":"dockarea","workspace_layout":"default","last_split_layout":"splith","border":"pixel","current_border_width":-1,"rect":{"x":0,"y":1177,"width":1920,"height":23},"deco_rect":{"x":0,"y":0,"width":0,"height":0},"window_rect":{"x":0,"y":0,"width":0,"height":0},"geometry":{"x":0,"y":0,"width":0,"height":0},"name":"bottomdock","window":null,"window_type":null,"nodes":[{"id":94871215898224,"type":"con","orientation":"none","scratchpad_state":"none","percent":1.0,"urgent":false,"marks":[],"focused":false,"output":"eDP-1","layout":"splith","workspace_layout":"default","last_split_layout":"splith","border":"pixel","current_border_width":4,"rect":{"x":0,"y":1177,"width":1920,"height":23},"deco_rect":{"x":0,"y":0,"width":0,"height":0},"window_rect":{"x":0,"y":0,"width":1920,"height":23},"geometry":{"x":0,"y":1177,"width":1920,"height":23},"name":"i3bar for output eDP-1","window":29360134,"window_type":"unknown","window_properties":{"class":"i3bar","instance":"bar-0","title":"i3bar for output eDP-1","transient_for":null},"nodes":[],"floating_nodes":[],"focus":[],"fullscreen_mode":0,"sticky":false,"floating":"auto_off","swallows":[]}],"floating_nodes":[],"focus":[94871215898224],"fullscreen_mode":0,"sticky":false,"floating":"auto_off","swallows":[{"dock":3,"insert_where":2}]}],"floating_nodes":[],"focus":[94871215859040,94871215855904,94871215862160],"fullscreen_mode":0,"sticky":false,"floating":"auto_off","swallows":[]}],"floating_nodes":[],"focus":[94871215852912,94871215812112],"fullscreen_mode":0,"sticky":false,"floating":"auto_off","swallows":[]}
{"id":94871215831936,"type":"root","orientation":"horizontal","scratchpad_state":"none","percent":null,"urgent":false,"marks":["zen94871215916816=0:1"],"focused":false,"layout":"splith","workspace_layout":"default","last_split_layout":"splith","border":"pixel","current_border_width":-1,"rect":{"x":0,"y":0,"width":1920,"height":1200},"deco_rect":{"x":0,"y":0,"width":0,"height":0},"window_rect":{"x":0,"y":0,"width":0,"height":0},"geometry":{"x":0,"y":0,"width":0,"height":0},"name":"root","window":null,"window_type":null,"nodes":[{"id":94871215812112,"type":"output","orientation":"none","scratchpad_state":"none","percent":0.5,"urgent":false,"marks":[],"focused":false,"layout":"output","workspace_layout":"default","last_split_layout":"splith","border":"pixel","current_border_width":-1,"rect":{"x":0,"y":0,"width":1920,"height":1200},"deco_rect":{"x":0,"y":0,"width":0,"height":0},"window_rect":{"x":0,"y":0,"width":0,"height":0},"geometry":{"x":0,"y":0,"width":0,"height":0},"name":"__i3","window":null,"window_type":null,"nodes":[{"id":94871215846928,"type":"con","orientation":"horizontal","scratchpad_state":"none","percent":null,"urgent":false,"marks":[],"focused":false,"output":"__i3","layout":"splith","workspace_layout":"default","last_split_layout":"splith","border":"pixel","current_border_width":-1,"rect":{"x":0,"y":0,"width":0,"height":0},"deco_rect":{"x":0,"y":0,"width":0,"height":0},"window_rect":{"x":0,"y":0,"width":0,"height":0},"geometry":{"x":0,"y":0,"width":0,"height":0},"name":"content","window":null,"window_type":null,"nodes":[{"id":94871215849920,"type":"workspace","orientation":"none","scratchpad_state":"none","percent":null,"urgent":false,"marks":[],"focused":false,"output":"__i3","layout":"splith","workspace_layout":"default","last_split_layout":"splith","border":"pixel","current_border_width":-1,"rect":{"x":0,"y":0,"width":0,"height":0},"deco_rect":{"x":0,"y":0,"width":0,"height":0},"window_rect":{"x":0,"y":0,"width":0,"height":0},"geometry":{"x":0,"y":0,"width":0,"height":0},"name":"__i3_scratch","num":-1,"gaps":{"inner":0,"outer":0,"top":0,"right":0,"bottom":0,"left":0},"window":null,"window_type":null,"nodes":[],"floating_nodes":[{"id":94871215885728,"type":"floating_con","orientation":"horizontal","scratchpad_state":"fresh","percent":null,"urgent":false,"marks":[],"focused":false,"output":"__i3","layout":"splith","workspace_layout":"default","last_split_layout":"splith","border":"pixel","current_border_width":-1,"rect":{"x":514,"y":342,"width":892,"height":516},"deco_rect":{"x":0,"y":0,"width":0,"height":0},"window_rect":{"x":0,"y":0,"width":0,"height":0},"geometry":{"x":0,"y":0,"width":0,"height":0},"name":null,"window":null,"window_type":null,"nodes":[{"id":94871215885248,"type":"con","orientation":"none","scratchpad_state":"none","percent":1.0,"urgent":false,"marks":[],"focused":false,"output":"__i3","layout":"splith","workspace_layout":"default","last_split_layout":"splith","border":"pixel","current_border_width":4,"rect":{"x":514,"y":342,"width":892,"height":516},"deco_rect":{"x":0,"y":0,"width":0,"height":0},"window_rect":{"x":4,"y":4,"width":884,"height":508},"geometry":{"x":0,"y":0,"width":884,"height":508},"name":"benny@talos:~","window":8388618,"window_type":"unknown","window_properties":{"class":"URxvt","instance":"__scratchpad","title":"benny@talos:~","transient_for":null},"nodes":[],"floating_nodes":[],"focus":[],"fullscreen_mode":0,"sticky":true,"floating":"user_on","swallows":[]}],"floating_nodes":[],"focus":[94871215885248],"fullscreen_mode":0,"sticky":false,"floating":"auto_off","swallows":[]},{"id":94871215906848,"type":"floating_con","orientation":"horizontal","scratchpad_state":"changed","percent":null,"urgent":false,"marks":[],"focused":false,"output":"__i3","layout":"splith","workspace_layout":"default","last_split_layout":"splith","border":"pixel","current_border_width":-1,"rect":{"x":209,"y":144,"width":1502,"height":888},"deco_rect":{"x":0,"y":0,"width":0,"height":0},"window_rect":{"x":0,"y":0,"width":0,"height":0},"geometry":{"x":0,"y":0,"width":0,"height":0},"name":null,"window":null,"window_type":null,"nodes":[{"id":94871215903728,"type":"con","orientation":"none","scratchpad_state":"none","percent":1.0,"urgent":false,"marks":[],"focused":false,"output":"__i3","layout":"splith","workspace_layout":"default","last_split_layout":"splith","border":"pixel","current_border_width":1,"rect":{"x":517,"y":333,"width":886,"height":510},"deco_rect":{"x":0,"y":0,"width":0,"height":0},"window_rect":{"x":4,"y":4,"width":884,"height":508},"geometry":{"x":0,"y":0,"width":884,"height":508},"name":"ranger","window":10485770,"window_type":"unknown","window_properties":{"class":"URxvt","instance":"__ranger","title":"ranger","transient_for":null},"nodes":[],"floating_nodes":[],"focus":[],"fullscreen_mode":0,"sticky":true,"floating":"user_on","swallows":[]}],"floating_nodes":[],"focus":[94871215903728],"fullscreen_mode":0,"sticky":false,"floating":"auto_off","swallows":[]}],"focus":[94871215885728,94871215906848],"fullscreen_mode":1,"sticky":false,"floating":"auto_off","swallows":[]}],"floating_nodes":[],"focus":[94871215849920],"fullscreen_mode":0,"sticky":false,"floating":"auto_off","swallows":[]}],"floating_nodes":[],"focus":[94871215846928],"fullscreen_mode":0,"sticky":false,"floating":"auto_off","swallows":[]},{"id":94871215852912,"type":"output","orientation":"none","scratchpad_state":"none","percent":0.5,"urgent":false,"marks":[],"focused":false,"layout":"output","workspace_layout":"default","last_split_layout":"splith","border":"pixel","current_border_width":-1,"rect":{"x":0,"y":0,"width":1920,"height":1200},"deco_rect":{"x":0,"y":0,"width":0,"height":0},"window_rect":{"x":0,"y":0,"width":0,"height":0},"geometry":{"x":0,"y":0,"width":0,"height":0},"name":"eDP-1","window":null,"window_type":null,"nodes":[{"id":94871215855904,"type":"dockarea","orientation":"none","scratchpad_state":"none","percent":null,"urgent":false,"marks":[],"focused":false,"output":"eDP-1","layout":"dockarea","workspace_layout":"default","last_split_layout":"splith","border":"pixel","current_border_width":-1,"rect":{"x":0,"y":0,"width":1920,"height":0},"deco_rect":{"x":0,"y":0,"width":0,"height":0},"window_rect":{"x":0,"y":0,"width":0,"height":0},"geometry":{"x":0,"y":0,"width":0,"height":0},"name":"topdock","window":null,"window_type":null,"nodes":[],"floating_nodes":[],"focus":[],"fullscreen_mode":0,"sticky":false,"floating":"auto_off","swallows":[{"dock":2,"insert_where":2}]},{"id":94871215859040,"type":"con","orientation":"horizontal","scratchpad_state":"none","percent":null,"urgent":false,"marks":[],"focused":false,"output":"eDP-1","layout":"splith","workspace_layout":"default","last_split_layout":"splith","border":"pixel","current_border_width":-1,"rect":{"x":0,"y":0,"width":1920,"height":1177},"deco_rect":{"x":0,"y":0,"width":0,"height":0},"window_rect":{"x":0,"y":0,"width":0,"height":0},"geometry":{"x":0,"y":0,"width":0,"height":0},"name":"content","window":null,"window_type":null,"nodes":[{"id":94871215919808,"type":"workspace","orientation":"none","scratchpad_state":"none","percent":1.0,"urgent":false,"marks":[],"focused":false,"output":"eDP-1","layout":"splith","workspace_layout":"default","last_split_layout":"splith","border":"pixel","current_border_width":-1,"rect":{"x":0,"y":0,"width":1920,"height":1177},"deco_rect":{"x":0,"y":0,"width":0,"height":0},"window_rect":{"x":0,"y":0,"width":0,"height":0},"geometry":{"x":0,"y":0,"width":0,"height":0},"name":"1","num":1,"gaps":{"inner":0,"outer":0,"top":0,"right":0,"bottom":0,"left":0},"window":null,"window_type":null,"nodes":[],"floating_nodes":[{"id":94871215871504,"type":"floating_con","orientation":"horizontal","scratchpad_state":"none","percent":null,"urgent":false,"marks":[],"focused":false,"output":"eDP-1","layout":"splith","workspace_layout":"default","last_split_layout":"splith","border":"pixel","current_border_width":-1,"rect":{"x":384,"y":59,"width":1148,"height":1054},"deco_rect":{"x":0,"y":0,"width":0,"height":0},"window_rect":{"x":0,"y":0,"width":0,"height":0},"geometry":{"x":0,"y":0,"width":0,"height":0},"name":null,"window":null,"window_type":null,"nodes":[{"id":94871215928784,"type":"con","orientation":"horizontal","scratchpad_state":"none","percent":1.0,"urgent":false,"marks":["centerzen"],"focused":false,"output":"eDP-1","layout":"tabbed","workspace_layout":"default","last_split_layout":"splith","border":"pixel","current_border_width":-1,"rect":{"x":384,"y":59,"width":1148,"height":1054},"deco_rect":{"x":0,"y":0,"width":0,"height":0},"window_rect":{"x":0,"y":0,"width":0,"height":0},"geometry":{"x":0,"y":0,"width":0,"height":0},"name":null,"window":null,"window_type":null,"nodes":[{"id":94871215916816,"type":"con","orientation":"none","scratchpad_state":"none","percent":1.0,"urgent":false,"marks":[],"focused":true,"output":"eDP-1","layout":"splith","workspace_layout":"default","last_split_layout":"splith","border":"pixel","current_border_width":4,"rect":{"x":384,"y":59,"width":1148,"height":1054},"deco_rect":{"x":0,"y":0,"width":1148,"height":1},"window_rect":{"x":0,"y":0,"width":1148,"height":1054},"geometry":{"x":0,"y":0,"width":884,"height":508},"name":"./dump_i3.sh","window":48234506,"window_type":"unknown","window_properties":{"class":"URxvt","instance":"urxvt","title":"./dump_i3.sh","transient_for":null},"nodes":[],"floating_nodes":[],"focus":[],"fullscreen_mode":0,"sticky":false,"floating":"auto_off","swallows":[]}],"floating_nodes":[],"focus":[94871215916816],"fullscreen_mode":0,"sticky":false,"floating":"user_on","swallows":[]}],"floating_nodes":[],"focus":[94871215928784],"fullscreen_mode":0,"sticky":false,"floating":"auto_off","swallows":[]}],"focus":[94871215871504],"fullscreen_mode":1,"sticky":false,"floating":"auto_off","swallows":[]}],"floating_nodes":[],"focus":[94871215919808],"fullscreen_mode":0,"sticky":false,"floating":"auto_off","swallows":[]},{"id":94871215862160,"type":"dockarea","orientation":"none","scratchpad_state":"none","percent":null,"urgent":false,"marks":[],"focused":false,"output":"eDP-1","layout":"dockarea","workspace_layout":"default","last_split_layout":"splith","border":"pixel","current_border_width":-1,"rect":{"x":0,"y":1177,"width":1920,"height":23},"deco_rect":{"x":0,"y":0,"width":0,"height":0},"window_rect":{"x":0,"y":0,"width":0,"height":0},"geometry":{"x":0,"y":0,"width":0,"height":0},"name":"bottomdock","window":null,"window_type":null,"nodes":[{"id":94871215898224,"type":"con","orientation":"none","scratchpad_state":"none","percent":1.0,"urgent":false,"marks":[],"focused":false,"output":"eDP-1","layout":"splith","workspace_layout":"default","last_split_layout":"splith","border":"pixel","current_border_width":4,"rect":{"x":0,"y":1177,"width":1920,"height":23},"deco_rect":{"x":0,"y":0,"width":0,"height":0},"window_rect":{"x":0,"y":0,"width":1920,"height":23},"geometry":{"x":0,"y":1177,"width":1920,"height":23},"name":"i3bar for output eDP-1","window":29360134,"window_type":"unknown","window_properties":{"class":"i3bar","instance":"bar-0","title":"i3bar for output eDP-1","transient_for":null},"nodes":[],"floating_nodes":[],"focus":[],"fullscreen_mode":0,"sticky":false,"floating":"auto_off","swallows":[]}],"floating_nodes":[],"focus":[94871215898224],"fullscreen_mode":0,"sticky":false,"floating":"auto_off","swallows":[{"dock":3,"insert_where":2}]}],"floating_nodes":[],"focus":[94871215859040,94871215855904,94871215862160],"fullscreen_mode":0,"sticky":false,"floating":"auto_off","swallows":[]}],"floating_nodes":[],"focus":[94871215852912,94871215812112],"fullscreen_mode":0,"sticky":false,"floating":"auto_off","swallows":[]}

First run ZEN_VERBOSE=1 i3zen

[{"success":true},{"success":true},{"success":true},{"success":true},{"success":true},{"success":true},{"success":true},{"success":true},{"success":true},{"success":true},{"success":true},{"success":true}]
[{"success":true},{"success":true}]
Second run ZEN_VERBOSE=1 i3zen

[{"success":true},{"success":true},{"success":true},{"success":true}]

@budRich
Copy link
Author

budRich commented Oct 23, 2021

@benjaminvdb I see you are using i3-gaps... I am sorry, but I have never supported i3-gaps with the i3ass scripts. I think that in this case it makes the output of i3list (that gets evaled on line 41, is not right, that is what sets up the i3list array.

we use the following i3list keys:

i3list[AWC] # Active window container ID
i3list[WST] # target (containing the mark 'centerzen') workspace number
i3list[WAX WAY WAH WAW] # active workspace geometry (size and position)
i3list[AWF] # floating state of active window
i3list[WAN] # NAME of active workspace (not the number, well sometimes the number is the name..)
i3list[WSA] # NUMBER of active workspace

@benjaminvdb
Copy link

@budRich I'm so sorry for wasting your time. I hadn't noticed the remark in the i3ass repository that i3-gaps isn't supported 😞 I assumed i3-gaps was i3wm with gaps; I had no idea they were actually very different programs.

Maybe I can get it running in some way. If I do, I'll definitely let you know. Thanks again for your help 🙏

@budRich
Copy link
Author

budRich commented Oct 23, 2021

No worries ben. I am glad you gave me a reason to revisit this script, and I think I will add it back to i3ass . Regarding i3/i3gaps, I think the differences that matter for my scripts to work are all minor diffs between the output of i3-msg -t get_tree . For example. in i3-gaps there are some properties named "gaps": 15, or similar which ofc are not in the json from i3wm, but i think that there might be other differences as well, like the order of properties. as an example: in i3wm, "name":..., comes before "instance":... where it could be the otherway around in i3-gaps.

I usually just pipe the json through jq to prettify it and open it in a text editor to examine stuff like this, but i guess another good tool in this case would be diff. But it is somewhat tedious to work with this, since it would mean i need to have both versions of i3 installed, toggle between them to gather the output i need and stuff like that. The json is also a bit, awkward, since some properties if they are not set has a null value, f.i. "marks": while other properties are simply not present in the json if they are not set, f.i. "title_format":.

So getting i3ass to work on i3gaps is mostly a matter of finding these differences in the json output.

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