distro specific fixes
[distro-setup] / i3-set-layout
index 89780d17be88643f7d6dc34f78738e3dc0a0b7ec..9f8c24769732e468ead52986fa1fdbeba1aa33ed 100755 (executable)
@@ -1,4 +1,25 @@
 #!/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.
+
 
 import sys
 from i3ipc import Connection, Event
@@ -9,16 +30,16 @@ def find_parent(i3, window_id):
         Find the parent of a given window id
     """
 
-    def finder(con, parent):
+    def finder(con, parent, gp):
         if con.id == window_id:
-            return parent
+            return (parent, gp)
         for node in con.nodes:
-            res = finder(node, con)
+            res = finder(node, con, parent)
             if res:
                 return res
         return None
 
-    return finder(i3.get_tree(), None)
+    return finder(i3.get_tree(), None, None)
 
 
 def set_layout(i3):
@@ -28,10 +49,10 @@ def set_layout(i3):
         horizontal, depending on its width/height
     """
 
-
-
     win = i3.get_tree().find_focused()
-    parent = find_parent(i3, win.id)
+    # i don't use gp: todo: revert to original alternating_layout function
+    # which did not return gp.
+    parent, gp = find_parent(i3, win.id)
 
 
     # We never want to set the layout of a single window container,
@@ -39,21 +60,25 @@ def set_layout(i3):
     # this, it is stupid. So, eliminate single window container if we
     # are focused on one.
     #
-    # Alternatively, it could first focus the parent, but I think when
+    # Alternatively, we could first focus the parent, but I think when
     # layout changes, we expect new windows to be created within that
     # layout.
-    if (parent and len(parent.nodes) == 1):
-        gp = find_parent(i3, parent.id)
-        if (gp.nodes[0].id == parent.id):
-            if (gp.layout == 'splitv'):
-                i3.command('move down')
-            else: # splith or tabbed
-                i3.command('move right')
-        else:
-            if (gp.layout == 'splitv'):
-                i3.command('move up')
-            else:
-                i3.command('move left')
+    #
+    # Todo: if the direction we are moving has a split/tabbed container
+    # as a peer to parent, this will move our window into that container
+    # 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 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')
+        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')
     i3.command('layout ' + sys.argv[1])
 
 def main():