xrandroll/main.py

127 lines
4.5 KiB
Python
Raw Normal View History

2020-01-31 18:54:01 +00:00
from copy import deepcopy
2020-01-31 16:46:06 +00:00
import subprocess
import sys
2020-01-31 17:27:59 +00:00
from PySide2.QtCore import QFile, QObject
2020-01-31 16:46:06 +00:00
from PySide2.QtUiTools import QUiLoader
2020-01-31 17:27:59 +00:00
from PySide2.QtWidgets import QApplication, QGraphicsScene
from monitor_item import MonitorItem
2020-01-31 16:46:06 +00:00
def parse_monitor(line):
parts = line.split()
name = parts[0]
primary = "primary" in parts
2020-01-31 18:54:01 +00:00
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
2020-01-31 16:46:06 +00:00
return (
name,
primary,
int(res_x),
int(res_y),
int(w_in_mm),
int(h_in_mm),
int(pos_x),
int(pos_y),
2020-01-31 18:54:01 +00:00
enabled
2020-01-31 16:46:06 +00:00
)
2020-01-31 17:27:59 +00:00
class Window(QObject):
def __init__(self, ui):
super().__init__()
self.ui = ui
ui.show()
self.ui.screenCombo.currentTextChanged.connect(self.monitor_selected)
2020-01-31 18:54:01 +00:00
self.ui.horizontalScale.valueChanged.connect(self.updateScaleLabels)
self.ui.verticalScale.valueChanged.connect(self.updateScaleLabels)
2020-01-31 17:27:59 +00:00
self.xrandr_info = {}
self.get_xrandr_info()
2020-01-31 18:54:01 +00:00
self.orig_xrandr_info = deepcopy(self.xrandr_info)
2020-01-31 17:27:59 +00:00
self.fill_ui()
def fill_ui(self):
"""Load data from xrandr and setup the whole thing."""
self.scene = QGraphicsScene(self)
self.ui.sceneView.setScene(self.scene)
self.ui.screenCombo.clear()
for name, monitor in self.xrandr_info.items():
self.ui.screenCombo.addItem(name)
2020-01-31 18:54:01 +00:00
mon_item = MonitorItem(0, 0, monitor["res_x"], monitor["res_y"], name=name, primary=monitor['primary'])
2020-01-31 17:27:59 +00:00
mon_item.setPos(monitor["pos_x"], monitor["pos_y"])
self.scene.addItem(mon_item)
monitor["item"] = mon_item
self.adjust_view()
def adjust_view(self):
self.ui.sceneView.ensureVisible(self.scene.sceneRect(), 100, 100)
scale_factor = 0.7 * min(
self.ui.sceneView.width() / self.scene.sceneRect().width(),
self.ui.sceneView.height() / self.scene.sceneRect().height(),
2020-01-31 16:46:06 +00:00
)
2020-01-31 17:27:59 +00:00
self.ui.sceneView.scale(scale_factor, scale_factor)
def get_xrandr_info(self):
data = subprocess.check_output(["xrandr"]).decode("utf-8").splitlines()
2020-01-31 18:54:01 +00:00
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
2020-01-31 17:27:59 +00:00
def monitor_selected(self, name):
2020-01-31 18:54:01 +00:00
# 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()}%')
2020-01-31 16:46:06 +00:00
if __name__ == "__main__":
app = QApplication(sys.argv)
ui_file = QFile("main.ui")
ui_file.open(QFile.ReadOnly)
loader = QUiLoader()
2020-01-31 17:27:59 +00:00
window = Window(loader.load(ui_file))
2020-01-31 16:46:06 +00:00
sys.exit(app.exec_())