Skip to content

Instantly share code, notes, and snippets.

@predragnikolic
Last active April 30, 2025 19:50
Show Gist options
  • Save predragnikolic/71248630920d7be330d83b60cbbf6388 to your computer and use it in GitHub Desktop.
Save predragnikolic/71248630920d7be330d83b60cbbf6388 to your computer and use it in GitHub Desktop.
Resize Openbox
#!/usr/bin/env bash
OFFSET_RE="\+([-0-9]+)\+([-0-9]+)"
# Get the window position
pos=($(xwininfo -id $(xdotool getactivewindow) |
sed -nr "s/^.*geometry .*$OFFSET_RE.*$/\1 \2/p"))
# Loop through each screen and compare the offset with the window
# coordinates.
while read name width height xoff yoff
do
if [ "${pos[0]}" -ge "$xoff" \
-a "${pos[1]}" -ge "$yoff" \
-a "${pos[0]}" -lt "$(($xoff+$width))" \
-a "${pos[1]}" -lt "$(($yoff+$height))" ]
then
monitor=$name
fi
done < <(xrandr | grep -w connected |
sed -r "s/^([^ ]*).*\b([-0-9]+)x([-0-9]+)$OFFSET_RE.*$/\1 \2 \3 \4 \5/" |
sort -nk4,5)
# If we found a monitor, echo it out, otherwise print an error.
if [ ! -z "$monitor" ]
then
echo $monitor
exit 0
else
echo "Couldn't find any monitor for the current window." >&2
exit 1
fi
#!/usr/bin/env python3
import sys
import subprocess
import re
GAP_SIZE = 20 # Define the gap size
def get_active_window_id():
"""Gets the ID of the currently active window using xprop."""
try:
result = subprocess.run(['xprop', '-root', '_NET_ACTIVE_WINDOW'], capture_output=True, text=True, check=True)
match = re.search(r'window id # (0x[0-9a-f]+)', result.stdout)
if match:
return match.group(1)
else:
return None
except subprocess.CalledProcessError:
return None
def get_window_geometry(win_id):
"""Gets the geometry (x, y, width, height) of a window using xwininfo."""
if not win_id:
return None
try:
result = subprocess.run(['xwininfo', '-id', win_id], capture_output=True, text=True, check=True)
print(f"xwininfo output for ID {win_id}:\n{result.stdout}")
x_match = re.search(r'Absolute upper-left X:\s+(\d+)', result.stdout)
y_match = re.search(r'Absolute upper-left Y:\s+(\d+)', result.stdout)
width_match = re.search(r'Width:\s+(\d+)', result.stdout)
height_match = re.search(r'Height:\s+(\d+)', result.stdout)
if x_match and y_match and width_match and height_match:
return int(x_match.group(1)), int(y_match.group(1)), int(width_match.group(1)), int(height_match.group(1))
else:
print(f"get_window_geometry: Could not parse geometry for window ID: {win_id}")
return None
except subprocess.CalledProcessError as e:
print(f"get_window_geometry: Error getting window geometry for ID {win_id}: {e}")
print(f"Stderr: {e.stderr}")
return None
def get_screen_geometry():
# Get the active screen name using the provided shell script
screen_name_process = subprocess.run(['./get_screen_name.sh'], capture_output=True, text=True, check=True)
screen_name = screen_name_process.stdout.strip()
print(f"Active screen name: {screen_name}")
# Get the output of xrandr
xrandr_process = subprocess.run(['xrandr'], capture_output=True, text=True, check=True)
xrandr_output = xrandr_process.stdout
# Parse the xrandr output to find the resolution of the active screen
for line in xrandr_output.splitlines():
if screen_name in line and "connected" in line:
# Extract width and height using regex
match = re.search(r'(\d+)x(\d+)', line)
if match:
width = int(match.group(1))
height = int(match.group(2))
print(f"Screen Width: {width}, Height: {height}")
return width, height
else:
print(f"Could not find resolution in xrandr output for screen: {screen_name}")
return None
print(f"Screen name '{screen_name}' not found in xrandr output.")
return None
def move_window(win_id, x, y):
"""Moves a window using xdotool."""
subprocess.run(['xdotool', 'windowmove', win_id, str(int(x)), str(int(y))])
def resize_window(win_id, width, height):
"""Resizes a window using xdotool."""
subprocess.run(['xdotool', 'windowsize', '--sync', win_id, str(int(width)), str(int(height))])
def handle_arrow_resize_move(direction):
active_win_id = get_active_window_id()
screen_width, screen_height = get_screen_geometry() or (0, 0)
print(f'screen_width: {screen_width}, screen_height: {screen_height}')
if active_win_id and screen_width > 0 and screen_height > 0:
win_x, win_y, win_width, win_height = get_window_geometry(active_win_id) or (0, 0, 0, 0)
print(f'Initial win_x: {win_x}, win_y: {win_y}, win_width: {win_width}, win_height: {win_height}')
width_small_screen = screen_width / 3 - GAP_SIZE - 10
width_half_screen = screen_width / 2 - GAP_SIZE
width_big_screen = screen_width / 1.5- GAP_SIZE - 10
print('win_width', win_width)
print('width_small_screen', width_small_screen)
height_small_screen = screen_height * 0.4 - GAP_SIZE
height_half_screen = screen_height * 0.5 - GAP_SIZE
height_big_screen = screen_height * 0.6 - GAP_SIZE
if direction == "left":
if win_x == screen_width - win_width - GAP_SIZE and win_width == width_small_screen:
move_window(active_win_id, GAP_SIZE + width_small_screen + GAP_SIZE, win_y)
return
if win_x == GAP_SIZE + width_small_screen + GAP_SIZE and win_width == width_small_screen:
move_window(active_win_id, GAP_SIZE, win_y)
return
if width_half_screen - 100 <= win_width <= width_half_screen + 100:
resize_window(active_win_id, width_small_screen, win_height)
elif win_width < width_half_screen - 100:
resize_window(active_win_id, width_big_screen, win_height)
else:
resize_window(active_win_id, width_half_screen, win_height)
move_window(active_win_id, GAP_SIZE, win_y)
elif direction == "right":
if win_x == GAP_SIZE and win_width == width_small_screen:
move_window(active_win_id, GAP_SIZE + width_small_screen + GAP_SIZE, win_y)
return
if win_x == GAP_SIZE + win_width + GAP_SIZE and win_width == width_small_screen:
move_window(active_win_id, screen_width - win_width - GAP_SIZE, win_y)
return
if width_half_screen - 100 <= win_width <= width_half_screen + 100:
resize_window(active_win_id, width_small_screen, win_height)
elif win_width < width_half_screen - 100:
resize_window(active_win_id, width_big_screen, win_height)
else:
resize_window(active_win_id, width_half_screen, win_height)
_, _, win_width, _ = get_window_geometry(active_win_id) or (0, 0, 0, 0)
x = screen_width - win_width - GAP_SIZE
move_window(active_win_id, x, win_y)
elif direction == "up":
if height_half_screen - 100 <= win_height <= height_half_screen + 100:
resize_window(active_win_id, win_width, height_small_screen - 20)
elif win_height < height_half_screen - 100:
resize_window(active_win_id, win_width, height_big_screen - 20)
else:
resize_window(active_win_id, win_width, height_half_screen - 20)
move_window(active_win_id, win_x, GAP_SIZE)
elif direction == "down":
if height_half_screen - 100 <= win_height <= height_half_screen + 100:
resize_window(active_win_id, win_width, height_small_screen)
elif win_height < height_half_screen - 100:
resize_window(active_win_id, win_width, height_big_screen)
else:
resize_window(active_win_id, win_width, height_half_screen)
_, _, _, win_height = get_window_geometry(active_win_id) or (0, 0, 0, 0)
y = screen_height - win_height - GAP_SIZE
move_window(active_win_id, win_x, y)
def main():
global GAP_SIZE
GAP_SIZE = 20
if len(sys.argv) == 2 and sys.argv[1] in ["left", "right", "up", "down"]:
handle_arrow_resize_move(sys.argv[1])
else:
print(f"This script is intended to be executed by Openbox keybindings with a gap of {GAP_SIZE}px.")
print("Configure keybindings for Super + Arrows to run:")
print("`python3 /path/to/your/script.py left`")
print("`python3 /path/to/your/script.py right`")
print("`python3 /path/to/your/script.py up`")
print("`python3 /path/to/your/script.py down`")
if __name__ == "__main__":
main()
@predragnikolic
Copy link
Author

predragnikolic commented Apr 28, 2025

 <keybind key="W-Left">
      <action name="Execute">
        <command>/home/predrag/Documents/sandbox/wm/resize.py left</command>
      </action>
    </keybind>
    <keybind key="W-Right">
      <action name="Execute">
        <command>/home/predrag/Documents/sandbox/wm/resize.py right</command>
      </action>
    </keybind>
    <keybind key="W-Down">
      <action name="Execute">
        <command>/home/predrag/Documents/sandbox/wm/resize.py down</command>
      </action>
    </keybind>
    <keybind key="W-Up">
      <action name="Execute">
        <command>/home/predrag/Documents/sandbox/wm/resize.py up</command>
      </action>
    </keybind>
    ```

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment