Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions snaptile.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,17 @@ def global_inital_states():
get_posmap(keymap, displ)
)

global disp, root, lastkey_state, posmap;
global disp, root, lastkey_state, posmap, isDualMonitor;


def run():
mask = None

opts, args = getopt.getopt(sys.argv[1:], "hdWk:")
keyboardLayout = autodetectKeyboard()

global isDualMonitor

isDualMonitor = False

for opt in opts:
Expand Down Expand Up @@ -141,6 +144,7 @@ def run():
GObject.io_add_watch(root.display, GObject.IO_IN, checkevt)
print('Snaptile running. Press CTRL+C to quit.')
signal.signal(signal.SIGINT, signal.SIG_DFL)
signal.signal(signal.SIGTERM, signal.SIG_DFL)
Gtk.main()

def checkevt(_, __, handle=None):
Expand Down Expand Up @@ -175,7 +179,8 @@ def checkevt(_, __, handle=None):
def handleevt(startkey, endkey):
position(
posmap[startkey],
posmap[endkey]
posmap[endkey],
isDualMonitor,
)

if __name__ == '__main__':
Expand Down
75 changes: 50 additions & 25 deletions window.py
Original file line number Diff line number Diff line change
@@ -1,52 +1,68 @@
from gi.repository import Gdk

def position(startpos, endpos):
def position(startpos, endpos, dualMonitor):
window, screen = active_window()
if window is None:
return
window.unmaximize()
window.set_shadow_width(0, 0, 0, 0)
workarea = screen.get_monitor_workarea(screen.get_monitor_at_window(window))

offx, offy = offsets(window)
display = Gdk.Display.get_default()
if dualMonitor:
monitor = get_target_monitor(display, startpos[1])
workarea = monitor.get_workarea()
end_monitor = get_target_monitor(display, endpos[1])
end_workarea = end_monitor.get_workarea()
else:
monitor = screen.get_monitor_at_window(window)
workarea = screen.get_monitor_workarea(monitor)
# same screen -> same workarea on both corners
end_workarea = workarea

w, h = (workarea.width / 4, workarea.height / 3)
end_w, end_h = (end_workarea.width / 4, end_workarea.height / 3)

pos = (
min(startpos[0], endpos[0]),
min(startpos[1], endpos[1])
# each contain top left and bottom right position of the respective cell
first_corner = (
(startpos[1] % 4) * w + workarea.x,
startpos[0] * h + workarea.y,
(startpos[1] % 4 + 1) * w + workarea.x,
(startpos[0] + 1) * h + workarea.y,
)
dims = (
max(abs(endpos[0] - startpos[0]) + 1, 1),
max(abs(endpos[1] - startpos[1]) + 1, 1)
second_corner = (
(endpos[1] % 4) * end_w + end_workarea.x,
endpos[0] * end_h + end_workarea.y,
(endpos[1] % 4 + 1) * end_w + end_workarea.x,
(endpos[0] + 1) * end_h + end_workarea.y,
)

top_left, bottom_right = (
# use top left corner of cells (0 & 1)
(min(first_corner[0], second_corner[0]), min(first_corner[1], second_corner[1])),
# use bottom right corner of cells (2 & 3)
(max(first_corner[2], second_corner[2]), max(first_corner[3], second_corner[3])),
)

multiscreen_offset = get_multi_screen_offset(screen, window)
dims = (
bottom_right[0] - top_left[0],
bottom_right[1] - top_left[1],
)

window.move_resize(
pos[1] * w + multiscreen_offset,
pos[0] * h,
w * dims[1] - (offx * 2),
h * dims[0]- (offx + offy)
*top_left,
*dims,
)


def active_window():
screen = Gdk.Screen.get_default()
window = screen.get_active_window()

if no_window(screen, window):
return None
return None, None

return (window, screen)

def get_multi_screen_offset(screen,window):
monitor = screen.get_monitor_at_window(window)
monitor_geometry = screen.get_monitor_geometry(monitor)
return monitor_geometry.x

def offsets(window):
origin = window.get_origin()
root = window.get_root_origin()
return (origin.x - root.x, origin.y - root.y)


def no_window(screen, window):
return (
Expand All @@ -58,3 +74,12 @@ def no_window(screen, window):
) or
window.get_type_hint().value_name == 'GDK_WINDOW_TYPE_HINT_DESKTOP'
)


def get_target_monitor(display, x):
# NOTE: only works for up to 2 monitors!!
left_monitor = display.get_monitor_at_point(0, 0)
right_monitor = display.get_monitor(1) \
if left_monitor == display.get_monitor(0) \
else display.get_monitor(0)
return [left_monitor, right_monitor][x // 4]