Created
June 11, 2020 10:03
-
-
Save windwp/e5ada09aa8bfcb11da9961cebdde9c9b to your computer and use it in GitHub Desktop.
update i3 swallow
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
#----------------------------------------------- | |
# used to swallow a terminal window in i3 | |
# | |
# INSTALL | |
# Install python 3 and install i3ipc libary | |
# pip3 install i3ipc | |
# download this scrript and put it to your i3 config folder and run | |
# chmod +x $HOME/.config/i3/i3-swallow.py | |
# python3 $HOME/.config/i3/i3-swallow.py | |
# | |
# You can add this script to your i3 config file. | |
# exec --no-startup-id python3 $HOME/.config/i3/i3-swallow.py | |
# reload i3 and try run xclock | |
#---------------------------------------------------- | |
# | |
# this version will try to get the last position when you close graphic appliation | |
# It can't restore if the graphic appliation is on top of layout ,It restore 80% position | |
import i3ipc | |
import subprocess | |
from time import sleep | |
import pprint | |
swallowDict={} | |
i3 = i3ipc.Connection() | |
def unMarkAllNode(node,marked): | |
for mark in node.marks: | |
if mark==marked: | |
i3.command('[con_id=%s] unmark' % (node.id)) | |
return True | |
for node in node.nodes: | |
if(unMarkAllNode(node,marked)): | |
return True | |
return False | |
def hideSwallowParent(node, windowId, swallowId): | |
if(str(node.window) == str(windowId)): | |
global swallowDict | |
i3.command('[con_id=%s] focus' % swallowId) | |
i3.command('[con_id=%s] move to scratchpad' % node.id) | |
i3.command('[con_id=%s] mark swallowParent' % node.parent.id) | |
swallowDict[str(swallowId)] = { | |
"id": node.id, | |
"layout": node.layout, | |
"index":node.parent.nodes.index(node), | |
"parent_nodes":len(node.parent.nodes)-1, # minus to hided window, | |
} | |
return True | |
for node in node.nodes: | |
if(hideSwallowParent(node, windowId, swallowId)): | |
return True | |
return False | |
def getParentNodePid(node): | |
# get parent of pid because terminal spwan shell(zsh or fish) and then spawn that child process | |
output = subprocess.getoutput( | |
"ps -o ppid= -p $(ps -o ppid= -p $(xprop -id %d _NET_WM_PID | cut -d' ' -f3 ))" % (node.window)) | |
return output | |
def getWindowIdfromPId(pid): | |
output = subprocess.getoutput("xdotool search -pid %s" % pid) | |
return output | |
def on_new(self, event): | |
workspace = i3.get_tree().find_focused().workspace() | |
# if we can find parent have pid container map to any node in workspace we will hide it | |
parentContainerPid = getParentNodePid(event.container) | |
parentContainerWid = getWindowIdfromPId(parentContainerPid) | |
for item in workspace.nodes: | |
hideSwallowParent(item, parentContainerWid, event.container.id) | |
def on_close(self, event): | |
global swallowDict | |
swallow = swallowDict.get(str(event.container.id)) | |
if swallow != None: | |
focusWindow=i3.get_tree().find_focused() | |
workspace = i3.get_tree().find_focused().root() | |
window = i3.get_tree().find_by_id(swallow["id"]) | |
if window != None: | |
del swallowDict[str(event.container.id)] | |
i3.command( | |
'[con_id=%s] scratchpad show;floating disable;focus' % (window.id)) | |
i3.command('[con_id=%s] move container to mark swallowParent'% (window.id)) | |
parentMarked=workspace.find_marked("swallowParent") | |
targetWindow=None | |
if (swallow["index"] < len(focusWindow.parent.nodes)): | |
targetWindow = focusWindow.parent.nodes[swallow['index']] | |
if( targetWindow==None and len(parentMarked)>0 and len(parentMarked[0].nodes)>0): | |
if (swallow["index"] < len(parentMarked[0].nodes)): | |
targetWindow = parentMarked[0].nodes[swallow['index']] | |
if(targetWindow!=None): | |
i3.command('[con_id=%s] swap container with con_id %d'% (window.id,targetWindow.id)) | |
i3.command('[con_id=%s] focus'% (window.id)) | |
def on_move(self,event): | |
swallow = swallowDict.get(str(event.container.id)) | |
if swallow != None: | |
focusWindow=i3.get_tree().find_focused() | |
if focusWindow!=None: | |
for item in focusWindow.workspace().nodes: | |
unMarkAllNode(item,'swallowParent') | |
i3.command('[con_id=%s] mark swallowParent' % focusWindow.parent.id) | |
swallow["layout"]=focusWindow.layout | |
swallow["index"]=focusWindow.parent.nodes.index(focusWindow) | |
swallow["parent_nodes"]=len(focusWindow.parent.nodes) | |
def on_binding(self,event): | |
pass | |
# Subscribe to events | |
i3.on("window::new", on_new) | |
i3.on("window::move",on_move) | |
i3.on("window::close",on_close) | |
i3.on("binding",on_binding) | |
i3.main() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment