Skip to content

Instantly share code, notes, and snippets.

@zrajm
Last active March 7, 2025 23:44
Show Gist options
  • Select an option

  • Save zrajm/3621cc90d9bc30d06bbe926fc8b2692a to your computer and use it in GitHub Desktop.

Select an option

Save zrajm/3621cc90d9bc30d06bbe926fc8b2692a to your computer and use it in GitHub Desktop.
Openbox Keybindings for Window Tiling (using windows key + arrow keys).
<!--
Keybindings for Window Tiling
=============================
For the below code to work insert it into the <keyboard> section of your
openbox config. On Lubuntu it's called `~/.config/openbox/lubuntu-rc.xml`, and
on Arch `~/.config/openbox/rc.xml`. To reload the config after modifying it,
you can either logout and login again, or run the command
openbox -\-reconfigure
(The backslash is an XML workaround for this comment to work, the shell doesn't
care about it.)
How to Use It
=============
Windows key + arrows: Resizes a window to half-screen. Combinations (e.g.
Windows-Up followed by Windows-Left) can be used to resize to quarter-screen.
Twice in the same direction (e.g. Windows-Right + Windows-Right) will maximize
a window.
Window-Space: Toggles window decorations/borders (i.e. switches title bar,
close button etc on/off). For this to be really screen maximizing you might
want to also remove the one pixel border around each window, but this can only
be done by putting `<keepBorder>no</keepBorder>` inside the `<theme>` of your
openbox config. (It cannot be toggled for each individual window,
unfortunately, at least not on Openbox 3.6.1.) Even with decorations turned off
the usual keybindings Alt-F4 to close, Alt + mouse to drag around etc. still
works.
Quirks
======
Terminal (and maybe some other?) windows are resized in steps (the step size
depends on the size of the font used in the window). These windows may not
completely fill out the expected part of the screen, leaving gaps between
windows. The below code tries to minimize the problem in two ways:
First: I scale terminal windows to 50.5% of the screen, rather than the
expected 50%. (Well, actually I use the fraction '101/200' for syntax reasons,
but you get the point.) This seems to work for me (causing my terminals to ever
so slightly go outside the screen sometimes). Search for `x-terminal-emulator'
below to see how this is done.
Second: To cut down the annoyance of the gaps between the windows, I place the
windows so that any gaps appear along the edges of the screen, rather than
between the windows. The hope is that this will cause the least distraction if
you have set your window manager to raise windows as the mouse pointer enter
them. By having no gap between the windows, there's no risk that you'll
accidentally enter a background window (causing that to suddenly raise to the
top) as you move the pointer between windows. (The drawback is that, if you're
in the habit of shoving the pointer to the edge of the screen to get it out of
the way, you might instead accidentally raise a background window that way.)
There's really no way of solving this, only trade offs. If you don't like my
preferred behavior there are comments in the code below to help you change it.
Simply search for comments containing 'at screen edge', and enable the
commented code just before that (the change needs to be done in four places,
one for each arrow key).
/zrajm [2020-05-15]
-->
<!-- Windows-Space: Toggle window decorations. -->
<keybind key="W-space">
<action name="ToggleDecorations"/>
</keybind>
<!-- Windows-Left: Left half of screen. -->
<keybind key="W-Left">
<action name="Raise"/>
<action name="If"><query target="default">
<maximized>no</maximized>
<maximizedvertical>yes</maximizedvertical>
</query><then>
<!-- Only vertically maximized: Maximize completely. -->
<action name="Maximize"/>
</then><else>
<action name="If"><query target="default">
<maximizedhorizontal>no</maximizedhorizontal>
</query><then>
<!-- Not horizontally maximized: Maximize vertically. -->
<action name="Maximize"><direction>vertical</direction></action>
</then></action>
<!-- Halve window width. -->
<action name="Unmaximize"><direction>horizontal</direction></action>
<action name="If">
<query target="default"><name>x-terminal-emulator</name></query>
<then><action name="MoveResizeTo"><width client="yes">101/200</width></action></then>
<else><action name="MoveResizeTo"><width client="yes">1/2</width></action></else>
</action>
<!-- Put on left half of screen. -->
<action name="MoveResizeTo">
<x client="yes">-50%</x> <!-- right edge at screen midpoint -->
<!--x client="yes">0</x--> <!-- left edge at screen edge -->
</action>
</else></action>
</keybind>
<!-- Windows-Right: Right half screen. -->
<keybind key="W-Right">
<action name="Raise"/>
<action name="If"><query target="default">
<maximized>no</maximized>
<maximizedvertical>yes</maximizedvertical>
</query><then>
<!-- Only vertically maximized: Maximize completely. -->
<action name="Maximize"/>
</then><else>
<action name="If"><query target="default">
<maximizedhorizontal>no</maximizedhorizontal>
</query><then>
<!-- Not horizontally maximized: Maximize vertically. -->
<action name="Maximize"><direction>vertical</direction></action>
</then></action>
<!-- Halve window width. -->
<action name="Unmaximize"><direction>horizontal</direction></action>
<action name="If">
<query target="default"><name>x-terminal-emulator</name></query>
<then><action name="MoveResizeTo"><width client="yes">101/200</width></action></then>
<else><action name="MoveResizeTo"><width client="yes">1/2</width></action></else>
</action>
<!-- Put on right half of screen. -->
<action name="MoveResizeTo">
<x client="yes">50%</x> <!-- left edge at screen midpoint -->
<!--x client="yes">-0</x--> <!-- right edge at screen edge -->
</action>
</else></action>
</keybind>
<!-- Windows-Up: Upper half of screen. -->
<keybind key="W-Up">
<action name="Raise"/>
<action name="If"><query target="default">
<maximized>no</maximized>
<maximizedhorizontal>yes</maximizedhorizontal>
</query><then>
<!-- Only horizontally maximized: Maximize completely. -->
<action name="Maximize"/>
</then><else>
<action name="If"><query target="default">
<maximizedvertical>no</maximizedvertical>
</query><then>
<!-- Not vertically maximized: Maximize horizontally. -->
<action name="Maximize"><direction>horizontal</direction></action>
</then></action>
<!-- Halve window height. -->
<action name="Unmaximize"><direction>vertical</direction></action>
<action name="If">
<query target="default"><name>x-terminal-emulator</name></query>
<then><action name="MoveResizeTo"><height client="yes">101/200</height></action></then>
<else><action name="MoveResizeTo"><height client="yes">1/2</height></action></else>
</action>
<!-- Put on upper half of screen. -->
<action name="MoveResizeTo">
<y client="yes">-50%</y> <!-- bottom edge at screen midpoint -->
<!--x client="yes">0</x--> <!-- top edge at screen edge -->
</action>
</else></action>
</keybind>
<!-- Windows-Down: Lower half of screen. -->
<keybind key="W-Down">
<action name="Raise"/>
<action name="If"><query target="default">
<maximized>no</maximized>
<maximizedhorizontal>yes</maximizedhorizontal>
</query><then>
<!-- Only horizontally maximized: Maximize completely. -->
<action name="Maximize"/>
</then><else>
<action name="If"><query target="default">
<maximizedvertical>no</maximizedvertical>
</query><then>
<!-- Not vertically maximized: Maximize horizontally. -->
<action name="Maximize"><direction>horizontal</direction></action>
</then></action>
<!-- Halve window height. -->
<action name="Unmaximize"><direction>vertical</direction></action>
<action name="If">
<query target="default"><name>x-terminal-emulator</name></query>
<then><action name="MoveResizeTo"><height client="yes">101/200</height></action></then>
<else><action name="MoveResizeTo"><height client="yes">1/2</height></action></else>
</action>
<!-- Put on lower half of screen. -->
<action name="MoveResizeTo">
<y client="yes">50%</y> <!-- top edge at screen midpoint -->
<!--x client="yes">-0</x--> <!-- bottom edge at screen edge -->
</action>
</else></action>
</keybind>
<!--=========================================================================-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment