Skip to content

Instantly share code, notes, and snippets.

@timfenney
Last active March 29, 2019 20:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save timfenney/7a6bc989a7d8634a3fb6f70337ca8892 to your computer and use it in GitHub Desktop.
Save timfenney/7a6bc989a7d8634a3fb6f70337ca8892 to your computer and use it in GitHub Desktop.
A short tiling script. Goals include minimal dependencies and few LOC, as it is to run in qubes os dom0.
#!/usr/bin/python2.7
# tiling.py
# Simple tiling for GTK
#
# NB: most of this was cribbed from some poor dev who isn't going to get
# the credit until I find his blog post again. Hopefully will update with
# the source shortly :-|
#
# `tiling.py width height x y -d 1`
# All dimensions and coordinates are given as percentages of the screen,
# so `tiling.py 50 50 25 25 -d 1` would give you a window that's 50% of your
# screen's height and width, and positioned in the center of your screen.
# The `-d` argument indicates the presence (1) or absence (0) of window
# decorations. Remember to give the script executing right with
# `chmod +x tiling`.
#
# Warning: This solution is not particularly beautiful, and of course has
# no warranty express or implied, and may break the universe, set your dog
# on fire, or make a politician into a real human being.
from gtk.gdk import *
import argparse
import os
TITLE_BAR = 22 # Put the height of your title bar here
# Parse the command line arguments
parser = argparse.ArgumentParser(description="Simple tiling for GTK")
if 'TILING_SIDE_GAP' in os.environ.keys():
parser.add_argument("--side_gap", type=int, default=os.environ['TILING_SIDE_GAP'], help="Size of side borders in pixels")
else:
parser.add_argument("--side_gap", type=int, help="Size of side borders in pixels", required=True)
if 'TILING_TOP_GAP' in os.environ.keys():
parser.add_argument("--top_gap", type=int, default=os.environ['TILING_TOP_GAP'], help="Top border size in pixels")
else:
parser.add_argument("--top_gap", type=int, help="Top border size in pixels", required=True)
if 'TILING_BOTTOM_GAP' in os.environ.keys():
parser.add_argument("--bottom_gap", type=int, default=os.environ['TILING_BOTTOM_GAP'], help="Bottom border size in pixels")
else:
parser.add_argument("--bottom_gap", type=int, help="Bottom border size in pixels", required=True)
if 'TILING_INNER_GAP' in os.environ.keys():
parser.add_argument("--inner_gap", type=int, default=os.environ['TILING_INNER_GAP'], help="Inner border size in pixels")
else:
parser.add_argument("--inner_gap", type=int, help="Inner border size in pixels", required=True)
parser.add_argument("-d", type=int, choices=[0, 1], default=1, help="1 for window decorations, 0 for none")
parser.add_argument("--vertical_position", type=str, choices=['full', 'top', 'bottom'], default='full', help="`full` for full height, `top` for top half, `bottom` for bottom half", required=True)
parser.add_argument("--horizontal_position", type=str, choices=['full', 'left_2', 'right_2', 'left', 'right', 'center'],
default='full', help="`full` for full width, `left_2` for left 2 columns, `right_2` for right 2 columns, `left` for leftmost column, `center` for center column, `right` for rightmost column", required=True)
args = parser.parse_args()
win = window_foreign_new((get_default_root_window().property_get('_NET_ACTIVE_WINDOW')[2][0]))
state = win.property_get('_NET_WM_STATE')[2]
# Get the screen's width and height
screen_width = screen_width()
screen_height = screen_height()
# Compute coordinates inside framed coordinates
inner_x_orig = 0
inner_y_orig = 0
inner_x_width = 3840 - args.side_gap * 2
inner_y_height = 2160 - args.top_gap - args.bottom_gap
if args.horizontal_position == 'full':
inner_window_x = inner_x_orig
inner_window_width = inner_x_width
elif args.horizontal_position == 'left_2':
inner_window_x = inner_x_orig
inner_window_width = inner_x_width / 3 * 2 - args.inner_gap / 3
elif args.horizontal_position == 'left':
inner_window_x = inner_x_orig
inner_window_width = inner_x_width / 3 - args.inner_gap / 3 * 2
elif args.horizontal_position == 'center':
inner_window_x = inner_x_width / 3 + args.inner_gap / 3
inner_window_width = inner_x_width / 3 - args.inner_gap / 3 * 2
elif args.horizontal_position == 'right_2':
inner_window_x = inner_x_width / 3 + args.inner_gap / 3
inner_window_width = inner_x_width / 3 * 2 - args.inner_gap / 3
elif args.horizontal_position == 'right':
inner_window_x = inner_x_width / 3 * 2 + args.inner_gap / 3 * 2
inner_window_width = inner_x_width / 3 - args.inner_gap / 3 * 2
if args.vertical_position == 'full':
inner_window_y = inner_y_orig
inner_window_height = inner_y_height
elif args.vertical_position == 'top':
inner_window_y = inner_y_orig
inner_window_height = inner_y_height / 2 - args.inner_gap / 2
elif args.vertical_position == 'bottom':
inner_window_y = inner_y_height / 2 + args.inner_gap / 2
inner_window_height = inner_y_height / 2 - args.inner_gap / 2
x = inner_window_x + args.side_gap
y = inner_window_y + args.top_gap
w = inner_window_width
h = inner_window_height
# Check whether decorations are desired
if args.d == 1:
win.set_decorations(DECOR_TITLE) # or DECOR_ALL for all decorations
win.move_resize(x, y, w, (h - TITLE_BAR))
if args.d == 0:
win.set_decorations(0)
win.move_resize(x, y, w, h)
# win.hide() # This hides the window, don't do it!!
print win.get_origin()
print '//////'
print win.get_root_origin()
print '//////'
print state
# Apply changes to window
window_process_all_updates()
flush()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment