From b93dd78088415d879d065dbddcb2a9a3aed1215a Mon Sep 17 00:00:00 2001 From: B Stack Date: Mon, 26 Sep 2022 11:29:46 -0400 Subject: add basic multimonitor support --- xsft.py | 133 ++++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 70 insertions(+), 63 deletions(-) (limited to 'xsft.py') diff --git a/xsft.py b/xsft.py index d7d01e5..91720a7 100755 --- a/xsft.py +++ b/xsft.py @@ -1,21 +1,20 @@ #!/usr/bin/python3 # Licensed under the GNU GPLv3+ +# Authors: nicholasbishop, bgstack15 +# 2022-09-26-2 10:56 added basic 2-monitor support. -import math -import os +import math, os, ast import subprocess import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk - def xrandr(args): cmd = ['xrandr'] + args return subprocess.check_output(cmd).decode('utf-8') - def get_connected_outputs(): for line in xrandr([]).splitlines(): if line.startswith(' '): @@ -24,26 +23,25 @@ def get_connected_outputs(): if words[1] == 'connected': yield words[0] - def set_brightness_and_gamma(outputs, brightness, gamma): + #print(f"DEBUG (sbag): {outputs}, {brightness}, {gamma}") args = [] - for output in outputs: - args += ['--output', output, - '--brightness', str(brightness), - '--gamma', '{}:{}:{}'.format(gamma[0], gamma[1], gamma[2])] + x = 0 + while x < len(outputs): + args += ['--output', outputs[x], + '--brightness', str(brightness[x]), + '--gamma', '{}:{}:{}'.format(gamma[x][0], gamma[x][1], gamma[x][2])] + x = x + 1 print(' '.join(args)) xrandr(args) - def color_temperature_to_rgb(kelvin): """Adapted from tannerhelland.com/4435.""" temp = kelvin / 100.0 if temp <= 66: red = 255 - green = temp green = 99.4708025861 * math.log(green) - 161.1195681661 - if temp <= 19: blue = 0 else: @@ -52,12 +50,9 @@ def color_temperature_to_rgb(kelvin): else: red = temp - 60 red = 329.698727446 * math.pow(red, -0.1332047592) - green = temp - 60 green = 288.1221695283 * math.pow(green, -0.0755148492) - blue = 255 - def clamp(val): if val < 0: return 0 @@ -65,37 +60,43 @@ def color_temperature_to_rgb(kelvin): return 255 else: return val - return [clamp(red), clamp(green), clamp(blue)] - def temperature_to_gamma(kelvin): rgb = color_temperature_to_rgb(kelvin) fac = sum(rgb) / 3 - for i in range(3): rgb[i] /= (fac) - return rgb - class MyWindow(Gtk.Window): def __init__(self, conf): Gtk.Window.__init__(self, title="xrandr-slightly-fewer-tears") self.set_default_size(640, -1) - + self.set_default_icon_name("display") self.conf = conf - self.box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, border_width=10) self.add(self.box) - - self.brightness_checkbutton = self.add_checkbutton( - 'Brightness', conf.brightness_enabled) - self.brightness = self.add_hscale(20, 100, conf.brightness) - - self.temperature_checkbutton = self.add_checkbutton( - 'Temperature (K)', conf.temperature_enabled) - self.temperature = self.add_hscale(2000, 10000, conf.temperature) + _ = get_connected_outputs() + self.outputs = [] + for i in _: + self.outputs.append(i) + #print(f"outputs = {self.outputs}") + #print(f"len(outputs) = {len(self.outputs)}") + x = 0 + self.brightness_checkbutton = [] + self.brightness = [] + self.temperature_checkbutton = [] + self.temperature = [] + while x < len(self.outputs): + self.brightness_checkbutton.append(self.add_checkbutton( + f"Brightness {self.outputs[x]}", conf.brightness_enabled[x])) + self.brightness.append(self.add_hscale(20, 100, conf.brightness[x])) + self.temperature_checkbutton.append(self.add_checkbutton( + 'Temperature (K)', False)) + self.temperature.append(self.add_hscale(2000, 10000, conf.temperature[x])) + print(x) + x = x + 1 # Update immediately so that saved values are loaded on startup self.update() @@ -116,49 +117,56 @@ class MyWindow(Gtk.Window): return scale def save_conf(self): - self.conf.brightness_enabled = self.brightness_checkbutton.get_active() - self.conf.temperature_enabled = self.temperature_checkbutton.get_active() - self.conf.brightness = self.brightness.get_value() - self.conf.temperature = self.temperature.get_value() + self.conf.brightness_enabled = [] + self.conf.temperature_enabled = [] + self.conf.brightness = [] + self.conf.temperature = [] + x = 0 + while x < len(self.outputs): + self.conf.brightness_enabled.append(self.brightness_checkbutton[x].get_active()) + self.conf.temperature_enabled.append(self.temperature_checkbutton[x].get_active()) + self.conf.brightness.append(self.brightness[x].get_value()) + self.conf.temperature.append(self.temperature[x].get_value()) + x = x + 1 self.conf.save() def update(self): - if self.brightness_checkbutton.get_active(): - brightness = self.brightness.get_value() / 100.0 - if brightness < 0.2: - brightness = 0.2 - else: - brightness = 1.0 - - if self.temperature_checkbutton.get_active(): - gamma = temperature_to_gamma(self.temperature.get_value()) - else: - gamma = (1, 1, 1) - - set_brightness_and_gamma(get_connected_outputs(), brightness, gamma) - + x = 0 + brightness = [] + gamma = [] + while x < len(self.outputs): + brightness.append(1) + if self.brightness_checkbutton[x].get_active(): + brightness[x] = self.brightness[x].get_value() / 100.0 + if brightness[x] < 0.2: + brightness[x] = 0.2 + else: + brightness[x] = 1.0 + gamma.append((1,1,1)) + if self.temperature_checkbutton[x].get_active(): + gamma[x] = temperature_to_gamma(self.temperature[x].get_value()) + else: + gamma[x] = (1, 1, 1) + x = x + 1 + set_brightness_and_gamma(self.outputs, brightness, gamma) self.save_conf() - class Config(object): def __init__(self): self.pardir = os.path.join(os.getenv('HOME'), '.config', 'xrandr-slightly-fewer-tears') self.path = os.path.join(self.pardir, 'xsft.conf') - # key:default self.items = { - 'brightness': 80.0, - 'brightness_enabled': True, - 'temperature': 5500.0, - 'temperature_enabled': True + 'brightness': [80.0,80.0], + 'brightness_enabled': [True, True], + 'temperature': [5500.0, 5500.0], + 'temperature_enabled': [True, True] } - # Set defaults for key in self.items: setattr(self, key, self.items[key]) - try: self.load() except IOError: @@ -169,14 +177,14 @@ class Config(object): for line in conf_file.readlines(): parts = line.split('=') key = parts[0] - val_str = parts[1] - + val_str = ast.literal_eval(parts[1]) default = self.items.get(key) + #print(f"Default = {default}, val_str={val_str} {type(val_str)}") if default is not None: - if isinstance(default, bool): - val = bool(val_str) + if isinstance(default[0], bool): + val = [bool(x) for x in val_str] else: - val = float(val_str) + val = [float(x) for x in val_str] setattr(self, key, val) def save(self): @@ -185,9 +193,9 @@ class Config(object): with open(self.path, 'w') as conf_file: for key in self.items: val = getattr(self, key) + #print('DEBUG(save): {}={}\n'.format(key, val)) conf_file.write('{}={}\n'.format(key, val)) - def main(): conf = Config() win = MyWindow(conf) @@ -195,6 +203,5 @@ def main(): win.show_all() Gtk.main() - if __name__ == '__main__': main() -- cgit