summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--examples/xmonad181
2 files changed, 182 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index 5455444..f79530b 100644
--- a/Makefile
+++ b/Makefile
@@ -65,7 +65,7 @@ PYFILES = __main__.py colour.py curve.py monitor.py solar.py icc.py adhoc.py
CBINDINGS = $(foreach B,$(SERVER_BINDINGS),blueshift_$(B).so)
# Configuration script example files
EXAMPLES = comprehensive sleepmode crtc-detection crtc-searching logarithmic \
- xmobar xpybar stored-settings current-settings
+ xmobar xpybar stored-settings current-settings xmonad
# Build rules
diff --git a/examples/xmonad b/examples/xmonad
new file mode 100644
index 0000000..1445f85
--- /dev/null
+++ b/examples/xmonad
@@ -0,0 +1,181 @@
+# -*- python -*-
+
+# This configuration scripts read the xmonad log to detect
+# which workspace you are viewing.
+
+
+# Copyright © 2014 Mattias Andrée (maandree@member.fsf.org)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+# This requires the following in your xmonad logHook:
+#
+# dynamicLogString defaultPP
+# { ppSort = getSortByXineramaRule
+# } >>= xmonadPropLog
+#
+# It also requires (to be modified or) that each workspace's name
+# is the workspaces index or the workspaces index followed by dash.
+# The first workspaces must 1. For example:
+#
+# workspaces = ["1", "2", "3", "4", "5", "6", "7", "8-mail", "9-video"]
+#
+# Additionally python3-xlib is required to be installed.
+
+
+import Xlib.display
+
+
+# Gamma (red, green and blue), per monitor.
+gammas = [[1.16, 1.15, 1.11],
+ [1.10, 1.16, 1.10]]
+
+# Brightness, per workspace.
+_ = 1
+brightnesses = [_, _, _, _, _, _, _, 0.8, _]
+
+# Temperature, per workspace.
+_ = 5000
+temperatures = [_, _, _, _, _, _, _, 3000, 6500]
+
+# Additional brightness modifier for monitors there the rat is not located.
+non_rat_brightness = 0.8
+
+
+wait_period = 0.2 # TODO it is better to wait for updates
+'''
+:float The number of seconds to wait before invoking `periodically` again
+'''
+
+fadein_time = None
+'''
+:float? The number of seconds used to fade in on start, `None` for no fading
+'''
+
+fadeout_time = None
+'''
+:float? The number of seconds used to fade out on exit, `None` for no fading
+'''
+
+# Acquire connection to X
+x_display = Xlib.display.Display()
+# Get root windows for the default screen
+x_screen = x_display.screen(x_display.get_default_screen())
+x_root = x_screen.root
+# Get atoms used by xmonad's log
+x_utf8 = x_display.intern_atom('UTF8_STRING')
+xmonad = x_display.get_atom('_XMONAD_LOG')
+
+# Close X connection on exit
+close_c_bindings_ = close_c_bindings
+def close_c_bindings():
+ close_c_bindings_()
+ x_display.close()
+
+
+def reset():
+ '''
+ Invoked to reset the displays
+ '''
+ for monitor in range(len(gammas)):
+ start_over()
+ gamma(*gammas[monitor])
+ randr(monitor)
+
+
+def get_workspaces():
+ '''
+ Get the currently visible workspaces
+
+ @return :(list<int>, int) The indices of the visible workspaces, in the order of the outputs,
+ and the index of the outout that the rat cursor is over
+ '''
+ log = x_root.get_full_property(xmonad, x_utf8).value
+ log = log.split(' : ')[0]
+ buf = None
+ rat = 0
+ visible = []
+ for c in log:
+ if buf is not None:
+ buf += c
+ if c in ']>':
+ if c == ']':
+ rat = len(visible)
+ visible.append(int(buf.split('-')[0]))
+ buf = None
+ elif c in '[<':
+ buf = ''
+ return ([w - 1 for w in visible], rat)
+
+
+last = -1
+def periodically(year, month, day, hour, minute, second, weekday, fade):
+ '''
+ :(int, int, int, int, int, int, int, float?)?→void Place holder for periodically invoked function
+
+ Invoked periodically
+
+ If you want to control at what to invoke this function next time
+ you can set the value of the global variable `wait_period` to the
+ number of seconds to wait before invoking this function again.
+ The value does not need to be an integer.
+
+ @param year:int The year
+ @param month:int The month, 1 = January, 12 = December
+ @param day:int The day, minimum value is 1, probable maximum value is 31 (*)
+ @param hour:int The hour, minimum value is 0, maximum value is 23
+ @param minute:int The minute, minimum value is 0, maximum value is 59
+ @param second:int The second, minimum value is 0, probable maximum value is 60 (**)
+ @param weekday:int The weekday, 1 = Monday, 7 = Sunday
+ @param fade:float? Blueshift can use this function to fade into a state when it start
+ or exits. `fade` can either be negative, zero or positive or `None`,
+ but the magnitude of value cannot exceed 1. When Blueshift starts,
+ the this function will be invoked multiple with the time parameters
+ of the time it is invoked and each time `fade` will increase towards
+ 1, starting at 0, when the value is 1, the settings should be applied
+ to 100 %. After this this function will be invoked once again with
+ `fade` being `None`. When Blueshift exits the same behaviour is used
+ except, `fade` decrease towards -1 but start slightly below 0, when
+ -1 is reached all settings should be normal. Then Blueshift will NOT
+ invoke this function with `fade` being `None`, instead it will by
+ itself revert all settings and quit.
+
+ (*) Can be exceeded if the calendar system is changed, like in 1712-(02)Feb-30
+ (**) See https://en.wikipedia.org/wiki/Leap_second
+ '''
+ global last
+
+ # Get active workspaces and check if something changed
+ (visible, rat) = get_workspaces()
+ summary = 0
+ for w in visible:
+ summary = summary * 9 + w
+ summary = summary * 9 + rat
+ if summary == last:
+ return
+ last = summary
+
+ # Update adjustments
+ monitor = -1
+ for workspace in visible:
+ monitor += 1
+ start_over()
+
+ cie_brightness(brightnesses[workspace] * (1 if rat == monitor else non_rat_brightness))
+ temperature(temperatures[workspace], lambda t : divide_by_maximum(cmf_10deg(t)))
+ gamma(*gammas[monitor])
+
+ randr(monitor)
+