From 9aa3368a5c8d60684a0fff7ca7fcf92db5ca8501 Mon Sep 17 00:00:00 2001 From: Thiago Kenji Okada Date: Sun, 23 Oct 2016 16:03:55 -0200 Subject: [PATCH 1/2] Added new redshift module --- docs/conf.py | 3 +- i3pystatus/redshift.py | 130 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 i3pystatus/redshift.py diff --git a/docs/conf.py b/docs/conf.py index d1948e0..1921276 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -24,7 +24,7 @@ MOCK_MODULES = [ "netifaces", "psutil", "lxml.html", "lxml.cssselect", "lxml", "praw", - "gi.repository", "dbus.mainloop.glib", "dbus", + "gi", "gi.repository", "dbus.mainloop.glib", "dbus", "pywapi", "basiciw", "i3pystatus.pulseaudio.pulse", "notmuch", @@ -46,6 +46,7 @@ MOCK_MODULES = [ "i3ipc", "dateutil.parser", "dateutil.relativedelta", + "redshift_gtk.statusicon", ] for mod_name in MOCK_MODULES: diff --git a/i3pystatus/redshift.py b/i3pystatus/redshift.py new file mode 100644 index 0000000..8947367 --- /dev/null +++ b/i3pystatus/redshift.py @@ -0,0 +1,130 @@ +import signal +import threading + +import gi +gi.require_version('Gtk', '3.0') # nopep8 +from gi.repository import Gtk, GLib +from redshift_gtk.statusicon import RedshiftController + +from i3pystatus import IntervalModule, formatp + + +class Redshift(IntervalModule): + """ + Show status and control redshift - http://jonls.dk/redshift/. + + This module runs a instace of redshift by itself, since it needs to parse + its output, so you should remove redshift/redshift-gtk from your i3 config + before using this module. + + Requires `redshift` and `redshift-gtk`. + + .. rubric:: Available formatters + + * `{inhibit}` — show if redshift is currently On or Off (using `toggle_inhibit` callback) + * `{latitude}` — location latitude + * `{longitude}` — location longitude + * `{period}` — current period (Day or Night) + * `{temperature}` — current screen temperature in Kelvin scale (K) + + """ + settings = ( + ("color", "Text color"), + ("error_color", "Text color when an error occurs"), + "format", + ("format_inhibit", + "List of 2 strings for `{inhibit}`, the first is shown when Redshift is On and the second is shown when Off"), + ("redshift_parameters", "List of parameters to pass to redshift binary"), + ) + + color = "#ffffff" + error_color = "#ff0000" + format = "{inhibit} {temperature}K" + format_inhibit = ["On", "Off"] + on_leftclick = "toggle_inhibit" + redshift_parameters = [] + + def init(self): + self._controller = RedshiftController(self.redshift_parameters) + + self.inhibit = self._controller.inhibited + self.period = self._controller.period + self.temperature = self._controller.temperature + self.latitude, self.longitude = self._controller.location + self.error = "" + + # Setup signals to property changes + self._controller.connect('inhibit-changed', self.inhibit_change_cb) + self._controller.connect('period-changed', self.period_change_cb) + self._controller.connect('temperature-changed', self.temperature_change_cb) + self._controller.connect('location-changed', self.location_change_cb) + self._controller.connect('error-occured', self.error_occured_cb) + + def terminate_child(data=None): + self._controller.terminate_child() + return False + + # Install signal handlers + GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, signal.SIGTERM, + terminate_child, None) + GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, signal.SIGINT, + terminate_child, None) + + try: + t = threading.Thread(target=Gtk.main) + t.daemon = True + t.start() + except Exception as e: + self._controller.kill_child() + self.output = { + "full_text": "Error creating new thread!", + "color": self.error_color + } + + # State update functions + def inhibit_change_cb(self, controller, inhibit): + """Callback when controller changes inhibition status""" + self.inhibit = inhibit + + def period_change_cb(self, controller, period): + """Callback when controller changes period""" + self.period = period + + def temperature_change_cb(self, controller, temperature): + """Callback when controller changes temperature""" + self.temperature = temperature + + def location_change_cb(self, controller, latitude, longitude): + """Callback when controlled changes location""" + self.latitude = latitude + self.longitude = longitude + + def error_occured_cb(self, controller, error): + """Callback when an error occurs in the controller""" + self.error = error + + def toggle_inhibit(self): + """Enable/disable redshift""" + if self.inhibit: + self._controller.set_inhibit(False) + else: + self._controller.set_inhibit(True) + + def run(self): + if self.error: + fdict = {"error": self.error} + color = self.error_color + else: + fdict = { + "inhibit": self.format_inhibit[int(self.inhibit)], + "period": self.period, + "temperature": self.temperature, + "latitude": self.latitude, + "longitude": self.longitude, + } + color = self.color + + self.output = { + "full_text": formatp(self.format, **fdict), + "color": color, + } From c76be588c2f345283d8e8b510bd63d0687eed274 Mon Sep 17 00:00:00 2001 From: Thiago Kenji Okada Date: Sun, 23 Oct 2016 16:20:35 -0200 Subject: [PATCH 2/2] Speed up user feedback --- i3pystatus/redshift.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/i3pystatus/redshift.py b/i3pystatus/redshift.py index 8947367..545781e 100644 --- a/i3pystatus/redshift.py +++ b/i3pystatus/redshift.py @@ -54,7 +54,6 @@ class Redshift(IntervalModule): self.error = "" # Setup signals to property changes - self._controller.connect('inhibit-changed', self.inhibit_change_cb) self._controller.connect('period-changed', self.period_change_cb) self._controller.connect('temperature-changed', self.temperature_change_cb) self._controller.connect('location-changed', self.location_change_cb) @@ -81,11 +80,6 @@ class Redshift(IntervalModule): "color": self.error_color } - # State update functions - def inhibit_change_cb(self, controller, inhibit): - """Callback when controller changes inhibition status""" - self.inhibit = inhibit - def period_change_cb(self, controller, period): """Callback when controller changes period""" self.period = period @@ -107,8 +101,10 @@ class Redshift(IntervalModule): """Enable/disable redshift""" if self.inhibit: self._controller.set_inhibit(False) + self.inhibit = False else: self._controller.set_inhibit(True) + self.inhibit = True def run(self): if self.error: