diff --git a/xrandroll/main.py b/xrandroll/main.py index 1ce9394..598afa1 100644 --- a/xrandroll/main.py +++ b/xrandroll/main.py @@ -346,6 +346,23 @@ class Window(QObject): mon["item"].update_visuals(mon) self.adjust_view() + def possible_snaps(self, name): + """Return two lists of values to which the x and y position + of monitor "name" could snap to.""" + snaps_x = [] + snaps_y = [] + + for monitor, data in self.xrandr_info.items(): + if monitor == name: + continue + else: + mod_x, mod_y = [int(x) for x in data["current_mode"].split("x")] + snaps_x.append(data["pos_x"]) + snaps_x.append(data["pos_x"] + mod_x) + snaps_y.append(data["pos_y"]) + snaps_y.append(data["pos_y"] + mod_y) + return snaps_x, snaps_y + def adjust_view(self): self.ui.sceneView.resetTransform() self.ui.sceneView.ensureVisible(self.scene.sceneRect(), 100, 100) diff --git a/xrandroll/monitor_item.py b/xrandroll/monitor_item.py index b06102c..34f85c5 100644 --- a/xrandroll/monitor_item.py +++ b/xrandroll/monitor_item.py @@ -73,10 +73,21 @@ class MonitorItem(QGraphicsRectItem, QObject): self.window.pos_label.hide() def mouseMoveEvent(self, event): + snaps_x, snaps_y = self.window.possible_snaps(self.name) view = event.widget().parent() click_pos = event.buttonDownScreenPos(Qt.LeftButton) current_pos = event.screenPos() - self.setPos( - view.mapToScene(view.mapFromScene(self.orig_pos) + current_pos - click_pos) - ) + new_pos = view.mapFromScene(self.orig_pos) + current_pos - click_pos + new_pos = view.mapToScene(new_pos) + if not event.modifiers() & Qt.AltModifier: + # Check for snaps + x = new_pos.x() + delta_x = min((abs(x - sx), i) for i, sx in enumerate(snaps_x)) + if delta_x[0] < 50: # snap + new_pos.setX(int(snaps_x[delta_x[1]])) + y = new_pos.y() + delta_y = min((abs(y - sy), i) for i, sy in enumerate(snaps_y)) + if delta_y[0] < 50: # snap + new_pos.setY(int(snaps_y[delta_y[1]])) + self.setPos(new_pos) self.window.show_pos(int(self.pos().x()), int(self.pos().y()))