diff --git a/snaptile.py b/snaptile.py index e74586b..4278195 100755 --- a/snaptile.py +++ b/snaptile.py @@ -97,7 +97,7 @@ def global_inital_states(): get_posmap(keymap, displ) ) -global disp, root, lastkey_state, posmap; +global disp, root, lastkey_state, posmap, isDualMonitor; def run(): @@ -105,6 +105,9 @@ def run(): opts, args = getopt.getopt(sys.argv[1:], "hdWk:") keyboardLayout = autodetectKeyboard() + + global isDualMonitor + isDualMonitor = False for opt in opts: @@ -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): @@ -175,7 +179,8 @@ def checkevt(_, __, handle=None): def handleevt(startkey, endkey): position( posmap[startkey], - posmap[endkey] + posmap[endkey], + isDualMonitor, ) if __name__ == '__main__': diff --git a/window.py b/window.py index a53faed..aeaf4d1 100644 --- a/window.py +++ b/window.py @@ -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 ( @@ -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]