def get_sibling_screens( current: Geometry, screens: Iterable[Geometry]) -> Dict[Ordinal, List[Geometry]]: """Given a screen and the list of active screens, return the sibling ones. Each list is ordered from the nearest screen to the furthest one. """ horizontal_screens = [ g for g in screens if current.horizontally_overlap(g) ] vertical_screens = [g for g in screens if current.vertically_overlap(g)] return { Ordinal.SOUTH: sorted([g for g in vertical_screens if g.y > current.y], key=lambda g: g.y), Ordinal.NORTH: sorted([g for g in vertical_screens if g.y < current.y], key=lambda g: -1 * g.y), Ordinal.EAST: sorted([g for g in horizontal_screens if g.x > current.x], key=lambda g: g.x), Ordinal.WEST: sorted([g for g in horizontal_screens if g.x < current.x], key=lambda g: -1 * g.x) }
def test_sibling_nominal(self): siblings = {Ordinal.EAST: [Geometry(1, 0, 1, 1), Geometry(2, 0, 1, 1)]} assert ewmh_m2m.screen.get_sibling_screen(siblings, Ordinal.EAST, no_wrap=False) == Geometry( 1, 0, 1, 1)
def test_sibling_no_wrap(self): siblings = { Ordinal.EAST: [Geometry(1, 0, 1, 1), Geometry(2, 0, 1, 1)], Ordinal.WEST: [] } assert ewmh_m2m.screen.get_sibling_screen( siblings, Ordinal.WEST, no_wrap=True) is None
def test_not_overlap(self): g1 = Geometry(0, 0, 10, 10) g2 = Geometry(100, 0, 10, 10) g3 = Geometry(0, 100, 10, 10) assert not g1.overlap(g2) assert not g2.overlap(g1) assert not g1.overlap(g3) assert not g3.overlap(g1)
def get_screens() -> Set[Geometry]: """Get the list of active screens. Its geometry represents each screen.""" return { Geometry(x=s[0], y=s[1], w=s[2], h=s[3]) for s in xpybutil.xinerama.get_monitors() }
def test_siblings_single_screen(self): current = Geometry(0, 0, 10, 10) screens = [current] siblings = ewmh_m2m.screen.get_sibling_screens(current, screens) assert siblings == {o: [] for o in list(Ordinal)}
def move_to_screen(args): window = ActiveWindow() initial_window_geometry = window.geometry screens = get_screens() _logger.debug("Detected screens: %s", screens) containing_screen = Geometry( *xpybutil.rect.get_monitor_area(initial_window_geometry, screens)) _logger.debug("Containing screen: %s", containing_screen) window_state = window.maximized window.maximized = (False, False) window_geometry = window.geometry relative_geometry = window_geometry.build_relative(containing_screen) new_screen = get_sibling_screen( get_sibling_screens(containing_screen, screens), args.direction, args.no_wrap) if not new_screen: _logger.fatal("No sibling screen found") else: new_window_geometry = relative_geometry.build_absolute(new_screen) _logger.debug("New window geometry: %s", new_window_geometry) window.geometry = new_window_geometry window.maximized = window_state window.conn.flush()
def test_siblings(self): screens = sorted( [Geometry(x, y, 1, 1) for x in range(5) for y in range(5)], key=lambda g: random.random()) current = Geometry(2, 2, 1, 1) siblings = ewmh_m2m.screen.get_sibling_screens(current, screens) assert siblings == { Ordinal.NORTH: [Geometry(2, 1, 1, 1), Geometry(2, 0, 1, 1)], Ordinal.EAST: [Geometry(3, 2, 1, 1), Geometry(4, 2, 1, 1)], Ordinal.SOUTH: [Geometry(2, 3, 1, 1), Geometry(2, 4, 1, 1)], Ordinal.WEST: [Geometry(1, 2, 1, 1), Geometry(0, 2, 1, 1)] }
def test_siblings_vertical(self): current = Geometry(0, 20, 10, 10) screens = sorted([ Geometry(0, 0, 10, 10), Geometry(0, 10, 10, 10), current, Geometry(0, 30, 10, 10), Geometry(0, 40, 10, 10) ], key=lambda g: random.random()) siblings = ewmh_m2m.screen.get_sibling_screens(current, screens) assert siblings == { Ordinal.EAST: [], Ordinal.WEST: [], Ordinal.SOUTH: [Geometry(0, 30, 10, 10), Geometry(0, 40, 10, 10)], Ordinal.NORTH: [Geometry(0, 10, 10, 10), Geometry(0, 0, 10, 10)] }
def test_siblings_gh_issue_14(self): """ Inspired by issue 14: https://github.com/AlexisBRENON/ewmh_m2m/issues/14 """ screens = { Geometry(2960, 0, 1920, 1200), Geometry(0, 176, 1280, 1024), Geometry(1280, 150, 1680, 1050) } current = Geometry(0, 176, 1280, 1024) siblings = ewmh_m2m.screen.get_sibling_screens(current, screens) assert siblings[Ordinal.EAST] == [ Geometry(1280, 150, 1680, 1050), Geometry(2960, 0, 1920, 1200) ]
def geometry(self) -> Geometry: """Geometry of the window""" g = xpybutil.window.get_geometry(self.window) return Geometry(x=g[0], y=g[1], w=g[2], h=g[3])
def test_overlap(self): g1 = Geometry(0, 0, 10, 10) g2 = Geometry(1, 1, 8, 8) assert g1.overlap(g2) assert g2.overlap(g1)
def test_horizontally_not_overlap(self): g1 = Geometry(0, 0, 1, 1) g2 = Geometry(10, 10, 1, 1) assert not g1.horizontally_overlap(g2) assert not g2.horizontally_overlap(g1)
def test_vertically_overlap(self): g1 = Geometry(0, 0, 10, 10) g2 = Geometry(0, 100, 10, 10) assert g1.vertically_overlap(g2) assert g2.vertically_overlap(g1)
def test_horizontally_overlap(self): g1 = Geometry(0, 0, 10, 10) g2 = Geometry(100, 0, 10, 10) assert g1.horizontally_overlap(g2) assert g2.horizontally_overlap(g1)