From d71a677ee90eda983979c65788d1eb416c888153 Mon Sep 17 00:00:00 2001 From: Roberto Alsina Date: Fri, 31 Jan 2020 15:54:01 -0300 Subject: [PATCH] Support disabled monitors, other bits --- main.py | 75 ++++++++++++++++++++++++---------- main.ui | 106 +++++++++++++++++++++++++++++++++++++++--------- monitor_item.py | 4 ++ 3 files changed, 144 insertions(+), 41 deletions(-) diff --git a/main.py b/main.py index ba57af5..85ada4b 100644 --- a/main.py +++ b/main.py @@ -1,3 +1,4 @@ +from copy import deepcopy import subprocess import sys @@ -12,10 +13,14 @@ def parse_monitor(line): parts = line.split() name = parts[0] primary = "primary" in parts - w_in_mm, h_in_mm = [p.split("mm")[0] for p in parts if p.endswith("mm")] - res_x, res_y = [p for p in parts if "x" in p][0].split("+")[0].split("x") - pos_x, pos_y = [p for p in parts if "x" in p][0].split("+")[1:] - print(name, pos_x, pos_y) + if '+' in line: # Is enabled + enabled = True + res_x, res_y = [p for p in parts if "x" in p][0].split("+")[0].split("x") + pos_x, pos_y = [p for p in parts if "x" in p][0].split("+")[1:] + w_in_mm, h_in_mm = [p.split("mm")[0] for p in parts if p.endswith("mm")] + else: + enabled = False + res_x = res_y = pos_x = pos_y = w_in_mm = h_in_mm = 0 return ( name, primary, @@ -25,6 +30,7 @@ def parse_monitor(line): int(h_in_mm), int(pos_x), int(pos_y), + enabled ) @@ -34,8 +40,11 @@ class Window(QObject): self.ui = ui ui.show() self.ui.screenCombo.currentTextChanged.connect(self.monitor_selected) + self.ui.horizontalScale.valueChanged.connect(self.updateScaleLabels) + self.ui.verticalScale.valueChanged.connect(self.updateScaleLabels) self.xrandr_info = {} self.get_xrandr_info() + self.orig_xrandr_info = deepcopy(self.xrandr_info) self.fill_ui() def fill_ui(self): @@ -46,7 +55,7 @@ class Window(QObject): for name, monitor in self.xrandr_info.items(): self.ui.screenCombo.addItem(name) - mon_item = MonitorItem(0, 0, monitor["res_x"], monitor["res_y"], name=name) + mon_item = MonitorItem(0, 0, monitor["res_x"], monitor["res_y"], name=name, primary=monitor['primary']) mon_item.setPos(monitor["pos_x"], monitor["pos_y"]) self.scene.addItem(mon_item) monitor["item"] = mon_item @@ -62,24 +71,48 @@ class Window(QObject): def get_xrandr_info(self): data = subprocess.check_output(["xrandr"]).decode("utf-8").splitlines() - outputs = [x for x in data if x and x[0] not in "S \t"] - for o in outputs: - name, primary, res_x, res_y, w_in_mm, h_in_mm, pos_x, pos_y = parse_monitor( - o - ) - self.xrandr_info[name] = dict( - primary=primary, - res_x=res_x, - res_y=res_y, - w_in_mm=w_in_mm, - h_in_mm=h_in_mm, - pos_x=pos_x, - pos_y=pos_y, - ) - + name = None + for line in data: + if line and line[0] not in "S \t": # Output line + name, primary, res_x, res_y, w_in_mm, h_in_mm, pos_x, pos_y, enabled = parse_monitor( + line + ) + self.xrandr_info[name] = dict( + primary=primary, + res_x=res_x, + res_y=res_y, + w_in_mm=w_in_mm, + h_in_mm=h_in_mm, + pos_x=pos_x, + pos_y=pos_y, + modes=[], + current_mode=None, + enabled=enabled, + ) + elif line[0] == ' ': # A mode + mode_name = line.strip().split()[0] + self.xrandr_info[name]['modes'].append(mode_name) + if '*' in line: + print(f'Current mode for {name}: {mode_name}') + self.xrandr_info[name]['current_mode'] = mode_name + def monitor_selected(self, name): - print(name) + # Show modes + self.ui.modes.clear() + for mode in self.xrandr_info[name]['modes']: + self.ui.modes.addItem(mode) + self.ui.modes.setCurrentText(self.xrandr_info[name]['current_mode']) + mod_x, mod_y = [int(x) for x in self.xrandr_info[name]['current_mode'].split('x')] + h_scale = self.xrandr_info[name]['res_x'] / mod_x + v_scale = self.xrandr_info[name]['res_y'] / mod_y + self.ui.horizontalScale.setValue(h_scale * 100) + self.ui.verticalScale.setValue(v_scale * 100) + self.ui.primary.setChecked(self.xrandr_info[name]['primary']) + self.ui.enabled.setChecked(self.xrandr_info[name]['enabled']) + def updateScaleLabels(self): + self.ui.horizontalScaleLabel.setText(f'{self.ui.horizontalScale.value()}%') + self.ui.verticalScaleLabel.setText(f'{self.ui.verticalScale.value()}%') if __name__ == "__main__": app = QApplication(sys.argv) diff --git a/main.ui b/main.ui index f5c9c37..85a7b9b 100644 --- a/main.ui +++ b/main.ui @@ -20,9 +20,9 @@ - 0 + 1 - + Global Settings @@ -72,7 +72,7 @@ - + Qt::LeftToRight @@ -91,17 +91,21 @@ - + + + QComboBox::AdjustToContents + + - + Enabled - + Primary @@ -115,7 +119,11 @@ - + + + QComboBox::AdjustToContents + + @@ -125,7 +133,11 @@ - + + + QComboBox::AdjustToContents + + @@ -135,34 +147,88 @@ - - - - - - Qt::Horizontal + + + QComboBox::AdjustToContents - Horizontal Scale + Horizontal Scale: - Vertical Scale + Vertical Scale: + + + + + + + 400 + + + 5 + + + 25 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + + + + + + + + + + + - - - Qt::Horizontal - + + + + + + 400 + + + 5 + + + 25 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + + + + + + + + + diff --git a/monitor_item.py b/monitor_item.py index 8d17377..945d97a 100644 --- a/monitor_item.py +++ b/monitor_item.py @@ -1,9 +1,11 @@ from PySide2.QtCore import Qt from PySide2.QtWidgets import QGraphicsRectItem, QGraphicsTextItem +from PySide2.QtGui import QBrush, QPen class MonitorItem(QGraphicsRectItem): def __init__(self, *a, **kw): + primary = kw.pop('primary') super().__init__(*a, **kw) self.setAcceptedMouseButtons(Qt.LeftButton) self.label = QGraphicsTextItem(kw["name"], self) @@ -12,6 +14,8 @@ class MonitorItem(QGraphicsRectItem): self.rect().height() / self.label.boundingRect().height(), ) self.label.setScale(label_scale) + if primary: + self.setBrush(QBrush('#eee8d5', Qt.SolidPattern)) def mousePressEvent(self, event): self.setCursor(Qt.ClosedHandCursor)