From 7ed3b98c4d3678d982c33741f1f42727144e66ce Mon Sep 17 00:00:00 2001 From: Ian Kelling Date: Wed, 5 Jun 2024 17:44:50 -0400 Subject: [PATCH] i think this fixes i3 issues --- brc2 | 2 +- ffp | 21 +++++++++ i3-auto-layout-toggle | 4 ++ i3-event-hook | 103 +++++++++++++++++++++++++++++++++++------- i3-set-layout | 4 +- i3-split-maybe | 24 +++++++++- i3-split-push | 29 ++++++++++-- i3-sway/common.conf | 33 ++++++-------- 8 files changed, 178 insertions(+), 42 deletions(-) diff --git a/brc2 b/brc2 index 7699add..8406dab 100644 --- a/brc2 +++ b/brc2 @@ -2036,7 +2036,7 @@ apache-apply-repo() { apache-apply() { for file; do - if head -n1 "$file"| grep -E '^#!/bin/bash\b' &>/dev/null; then + if head -n1 "$file"| grep -E '^#!/' &>/dev/null; then { head -n1 "$file" apache-header diff --git a/ffp b/ffp index 3ada2fc..cf331e0 100755 --- a/ffp +++ b/ffp @@ -1,4 +1,25 @@ #!/bin/bash +# I, Ian Kelling, follow the GNU license recommendations at +# https://www.gnu.org/licenses/license-recommendations.en.html. They +# recommend that small programs, < 300 lines, be licensed under the +# Apache License 2.0. This file contains or is part of one or more small +# programs. If a small program grows beyond 300 lines, I plan to change +# to a recommended GPL license. + +# Copyright 2024 Ian Kelling + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + volume=0 diff --git a/i3-auto-layout-toggle b/i3-auto-layout-toggle index e879bda..f7330a3 100755 --- a/i3-auto-layout-toggle +++ b/i3-auto-layout-toggle @@ -24,8 +24,12 @@ set -e; . /usr/local/lib/bash-bear; set +e f=/tmp/iank-i3-no-auto +# todo: if it is disabled, update the status bar. + if [[ -e $f ]]; then + echo "enabling" rm -f $f else + echo "disabling" touch $f fi diff --git a/i3-event-hook b/i3-event-hook index 01514a6..196e608 100755 --- a/i3-event-hook +++ b/i3-event-hook @@ -1,5 +1,38 @@ #!/usr/bin/env python3 +# I, Ian Kelling, follow the GNU license recommendations at +# https://www.gnu.org/licenses/license-recommendations.en.html. They +# recommend that small programs, < 300 lines, be licensed under the +# Apache License 2.0. This file contains or is part of one or more small +# programs. If a small program grows beyond 300 lines, I plan to change +# to a recommended GPL license. + +# Copyright 2024 Ian Kelling + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + + +# This gets rid of all single window containers. +# If a single window container was nested in another, +# it ignores that, but I don't generally expect to create them and +# we change focus enough that we would kill them off. + +# Note: I spent a lot of time figuring out how to do this properly, +# https://github.com/i3/i3/issues/3808 there are a bunch of links +# which suggest either float toggle; float toggle, which doesn't put windows back in the same place, or doing a move, which only actually works if you are moving in a direction which does not have a container there, else your window joins the container, and . + + import sys import os from i3ipc import Connection, Event @@ -11,11 +44,11 @@ def find_parent(i3, window_id): Find the parent of a given window id """ - def finder(con, parent, gp): + def finder(con, parent, workspace): if con.id == window_id: - return (parent, gp) + return (parent, workspace) for node in con.nodes: - res = finder(node, con, parent) + res = finder(node, con, con if con and con.type == 'workspace' else workspace) if res: return res return None @@ -23,6 +56,33 @@ def find_parent(i3, window_id): return finder(i3.get_tree(), None, None) +def kill_single_win_containers(i3, e, node, parent): + if len(parent.nodes) == 1 and len(node.nodes) == 0: + print("d1: killing parent") + # parent is a single window container, kill it. + + # Note: based on testing, + # i3 takes care of not calling this program for + # events which we create within it. Otherwise, + # we could create our disabling file here + # and delete it later if it wasn't already there. + i3.command('[con_id=%s] focus' % node.id) + i3.command('mark i3ha') + i3.command('focus parent') + i3.command('focus parent') + i3.command('mark i3hb') + i3.command('[con_mark="i3ha"] focus') + i3.command('move window to mark i3hb') + i3.command('unmark i3ha') + i3.command('unmark i3hb') + # back to our original focus + i3.command('[con_id=%s] focus' % e.container.id) + elif len(node.nodes) >= 1: + for child in node.nodes: + kill_single_win_containers(i3, e, child, node) + + + def focus_hook(i3, e): """ Set the layout/split for the currently @@ -33,27 +93,36 @@ def focus_hook(i3, e): if os.path.isfile("/tmp/iank-i3-no-auto"): return + # I identify container vs a real windows by the fact that it has nodes. + # looking through the data, another notable difference is that it has + # 'window': None, + # 'window_type': None, + + parent, workspace = find_parent(i3, e.container.id) # debugging - #pprint(vars(e)) + #exit(0) - parent, gp = find_parent(i3, e.container.id) + if not workspace: + return + #pprint(vars(workspace)) + #print() + for pnode in workspace.nodes: + # debugging + # if (len(pnode.nodes) >= 1): + # print("pnodes: ", pnode.nodes) - # This gets rid of tabbed container with single windows. - #if (parent and gp and parent.layout == 'tabbed' and len(parent.nodes) == 1): - # This gets rid of all single window containers. - if (parent and gp and len(parent.nodes) == 1): - i3.command('mark i3ha') - i3.command('focus parent') - i3.command('focus parent') - i3.command('mark i3hb') - i3.command('[con_mark="i3ha"] focus') - i3.command('move window to mark i3hb') - i3.command('unmark i3ha') - i3.command('unmark i3hb') + for node in pnode.nodes: + kill_single_win_containers(i3, e, node, pnode) def main(): i3 = Connection() i3.on(Event.WINDOW_FOCUS, focus_hook) + # if we don't have move, and we move a window out of a container, + # leaving behind a single window container, then we move it back, it + # will go into the container. We could expect that if we do it + # quickly, but it would be unexpected after a few seconds and we + # forget that it was a container. + i3.on(Event.WINDOW_MOVE, focus_hook) i3.main() diff --git a/i3-set-layout b/i3-set-layout index fc68666..6e28c71 100755 --- a/i3-set-layout +++ b/i3-set-layout @@ -29,6 +29,8 @@ def set_layout(i3): """ win = i3.get_tree().find_focused() + # i don't use gp: todo: revert to original alternating_layout function + # which did not return gp. parent, gp = find_parent(i3, win.id) @@ -46,7 +48,7 @@ def set_layout(i3): # instead of what we want. And in fact, the whole logic below is # incorrect and based on testing which did not realize that fact. # - if (parent and gp and len(parent.nodes) == 1): + if (parent and parent.type == 'con' and len(parent.nodes) == 1): # https://unix.stackexchange.com/questions/173754/how-to-move-a-window-up-to-the-level-of-its-parent-window-in-i3wm i3.command('mark i3ha') i3.command('focus parent') diff --git a/i3-split-maybe b/i3-split-maybe index d8bd54c..0a98c90 100755 --- a/i3-split-maybe +++ b/i3-split-maybe @@ -1,5 +1,27 @@ #!/usr/bin/python3 +# I, Ian Kelling, follow the GNU license recommendations at +# https://www.gnu.org/licenses/license-recommendations.en.html. They +# recommend that small programs, < 300 lines, be licensed under the +# Apache License 2.0. This file contains or is part of one or more small +# programs. If a small program grows beyond 300 lines, I plan to change +# to a recommended GPL license. + +# Copyright 2024 Ian Kelling + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + # This anticipates when we want to tab windows. There are 2 options of # when to do it: just after a window is created, or just before a window # is created. @@ -24,7 +46,7 @@ # so I close them out in # # I have a keybind which disables both, it runs /b/ds/i3-auto-layout-toggle - +# import sys import os diff --git a/i3-split-push b/i3-split-push index a9f76e5..f78ca9a 100755 --- a/i3-split-push +++ b/i3-split-push @@ -1,3 +1,24 @@ +# I, Ian Kelling, follow the GNU license recommendations at +# https://www.gnu.org/licenses/license-recommendations.en.html. They +# recommend that small programs, < 300 lines, be licensed under the +# Apache License 2.0. This file contains or is part of one or more small +# programs. If a small program grows beyond 300 lines, I plan to change +# to a recommended GPL license. + +# Copyright 2024 Ian Kelling + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + #!/usr/bin/python3 # There are only 2 cases where I want single window split containers. @@ -14,7 +35,8 @@ # direction to move the current window. Since we have a hook that erases # all single window split containers on focus change, we can consider a # single window split container to indicate the split we want. - +# +# import sys from i3ipc import Connection, Event # for debugging @@ -53,13 +75,13 @@ def set_layout(i3): layout = parent.layout if (parent and gp and len(parent.nodes) == 1): - i3.command('focus ' + direction) - exists = False if os.path.exists('/tmp/iank-i3-no-auto'): exists = True else: open('/tmp/iank-i3-no-auto', 'a') + i3.command('focus ' + direction) + if (layout == 'splith'): i3.command('split horizontal') @@ -77,7 +99,6 @@ def set_layout(i3): i3.command('move ' + direction) - def main(): i3 = Connection() set_layout(i3) diff --git a/i3-sway/common.conf b/i3-sway/common.conf index fc3236b..738cd0d 100644 --- a/i3-sway/common.conf +++ b/i3-sway/common.conf @@ -9,6 +9,7 @@ # todo: think whether this is useful: https://github.com/tmfink/i3-wk-switch # todo: see comment by Jakstern551 here for tip about jumping to windows +# https://old.reddit.com/r/i3wm/comments/k8m4k4/share_your_i3_tips_and_tricks_that_you_have/ # https://i3wm.org/docs/userguide.html#keybindings #To get the current mapping of your keys, use xmodmap -pke. To @@ -43,8 +44,12 @@ bindsym $mod+7 $ex "/a/bin/ds/laptop-xrandr" bindsym $mod+1 focus parent bindsym $mod+shift+1 focus child -# undo split: https://github.com/i3/i3/issues/3808 -bindsym $mod+grave floating toggle; floating toggle + +# note, i used to have a key: "floating toggle; floating toggle" to +# as undo split, as suggested here https://github.com/i3/i3/issues/3808 +# but something +# +bindsym $mod+grave floating toggle bindsym $mod+equal $ex "i3-set-layout splith" # move firefox to current workspace. # https://i3wm.org/docs/userguide.html#keybindings @@ -62,14 +67,6 @@ bindsym $mod+t $ex "i3-set-layout splitv" #bindsym $mod+Shift+t move workspace to output up bindsym $mod+Shift+t move workspace to output right -# todo: consider a command that moves a window, and erases any single -# container window left behind. - -# todo: consider a command which alters things as if the current window -# had been created into a single window split. For horizontal split, -# this would be like: focus left, split vertical, focus right, move -# left. With that, we could totally eliminate single window containers. - bindsym $mod+g $ex "i3-set-layout tabbed" @@ -114,7 +111,7 @@ bindsym $mod+Shift+x move container to workspace 6 bindsym $mod+x workspace 6 -# todo, in newer i3, make this split toggle +# todo, in newer i3, consider split toggle bindsym $mod+v split vertical bindsym $mod+Shift+v split horizontal # @@ -166,8 +163,6 @@ bindcode $mod+65 $ex obs-auto-scene-switch-toggle; floating toggle; sticky enabl # change focus between tiling / floating windows bindcode $mod+shift+65 focus mode_toggle -# Use Mouse+$mod to drag floating windows to their wanted position -floating_modifier $mod bindsym $mod+shift+h $ex /b/ds/stream-clip hc bindsym $mod+j $ex "i3-split-maybe"; exec emacsclient -c @@ -199,9 +194,11 @@ bindsym $mod+End $ex "/b/ds/toggle-mute" # title bars but no borders. i tried this out a bit #default_border normal 0 -default_border pixel 4 + +# default border is like 2 pixels +default_border pixel # for debugging -default_border normal 10 +#default_border normal 10 # I dont see a way to make processing windows act like normal windows, # this does it. @@ -214,6 +211,6 @@ default_border normal 10 # this is the processing window for my app named focus. for_window [class="focus" instance="focus"] floating disable -# client.focused #4c7899 #285577 #ffffff #2e9ef4 #ff4400 -# client.focused_inactive #333333 #5f676a #ffffff #484e50 #DBEEF4 -# client.unfocused #333333 #222222 #888888 #292d2e #B8C8CD +client.focused #4c7899 #285577 #ffffff #2e9ef4 #ff4400 +client.focused_inactive #333333 #5f676a #ffffff #484e50 #DBEEF4 +client.unfocused #333333 #222222 #888888 #292d2e #B8C8CD -- 2.30.2