i think this fixes i3 issues
authorIan Kelling <ian@iankelling.org>
Wed, 5 Jun 2024 21:44:50 +0000 (17:44 -0400)
committerIan Kelling <ian@iankelling.org>
Wed, 5 Jun 2024 21:44:50 +0000 (17:44 -0400)
brc2
ffp
i3-auto-layout-toggle
i3-event-hook
i3-set-layout
i3-split-maybe
i3-split-push
i3-sway/common.conf

diff --git a/brc2 b/brc2
index 7699add59555e0dcb824686d4ee2835c12dd0867..8406dab33a401d26c380d39051b2a2c492b8e4a8 100644 (file)
--- 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 3ada2fce4a9af1c02249e3e52ab6c628c1febabc..cf331e07810cfcf45970be7d808280a7527728ad 100755 (executable)
--- 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
 
index e879bdab966179e0bfceb477acd1d1b1c2d56cc3..f7330a366af8c3b0395ad07ecbabe1565c2439df 100755 (executable)
@@ -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
index 01514a648d6017aa0b2f5bf58f9c6b38433946d7..196e6081296f73f0fe343f86918226f223294c25 100755 (executable)
@@ -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()
 
 
index fc6866668a2480e7282046a9b12c318d8618b6ca..6e28c717fdb5444e10de445d6603f52daccfc150 100755 (executable)
@@ -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')
index d8bd54c67745bfb06b073d6e8165b8395d7a68ec..0a98c90b3927ed8a499b56f05441b3959bd4fc54 100755 (executable)
@@ -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
index a9f76e52afece96693ddfb3b876b0d56d289de76..f78ca9acde1dec0cbe5240d22a0bd754bbf1386e 100755 (executable)
@@ -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)
index fc3236be81cf7af0215fb5d3c5267759389889ec..738cd0ddd7ba8ed48190c3c3a8f902c618f65378 100644 (file)
@@ -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