From d6d34aacced4276253e8e34b8849308d4753a1b3 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Mon, 10 Mar 2014 01:54:56 +0100 Subject: add example that uses xmonad's log to determine active workspaces, allowing you to have different adjustments on different workspaces and monitors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- examples/xmonad | 181 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 examples/xmonad (limited to 'examples') 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 . + + +# 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) 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) + -- cgit v1.2.3-70-g09d2