You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
xmonad/action-manager/actions.py

207 lines
5.8 KiB

import functions
import subprocess
import abc
import sys
import os.path
class AbstractControl(metaclass=abc.ABCMeta):
def __init__(self):
self.args = None
@property
def visible(self):
return self.enabled
@property
def enabled(self):
return True
def configure(self, argument_parser):
pass
def bind_arguments(self, args):
self.args = args
def periodic(self):
pass
def cleanup(self):
pass
def respond_to(self, command):
return False
def load_state(self, state):
pass
def dump_state(self):
return None
def create_pipe_command(self, command):
return 'echo {} | {}/command.sh {}'.format(command, os.path.abspath(sys.path[0]), os.path.abspath(self.args.command_pipe.name))
class VolumeControl(AbstractControl):
@property
def muted(self):
return self._muted
@muted.setter
def muted(self, muted):
if self._muted != muted:
try:
self._muted = muted
self._pactl('set-sink-mute', str(int(muted)))
except subprocess.CalledProcessError as e:
pass
@property
def volume(self):
return self._volume
@volume.setter
def volume(self, volume):
if self.muted:
self.muted = False
if self._volume != volume:
try:
self._volume = volume
self._pactl('set-sink-volume', str(volume))
except subprocess.CalledProcessError as e:
pass
def _pactl(self, command, arg):
for i in range(6):
subprocess.check_call(["pactl", command, str(i), arg])
def __init__(self):
super().__init__()
self._muted = False
self._volume = 0
def respond_to(self, command):
if command[0] == '=':
self.volume = int(command[1:])*9000
elif command == 'm1':
self.muted = True
elif command == 'm0':
self.muted = False
elif command == 'mt':
self.muted = not self.muted
elif command == '+':
self.volume+=3000
elif command == '-':
self.volume-=3000
elif command == 'r':
self.volume=30000
else:
return False
return True
def __str__(self):
return self.action_bars(functions.create_bars(self.volume) if not self.muted else ' (mute) ')
def action_bars(self, bars):
return ''.join([functions.action(self.create_pipe_command('=%d'%(i+1)), c, button=1) for i,c in zip(range(len(bars)), bars)])
def load_state(self, state):
self.volume = state['volume']
self.muted = state['muted']
def dump_state(self):
return dict(volume=self.volume, muted=self.muted)
class QuitControl(AbstractControl):
@property
def visible(self):
return False
def respond_to(self, command):
if command == 'q':
sys.exit(0)
elif command == 'refresh':
return True
class RedshiftControl(AbstractControl):
def __init__(self):
super().__init__()
self._redshift_proc = None
def configure(self, argument_parser):
argument_parser.add_argument('--redshift-enabled', help='Use the redshift module', action='store_true')
argument_parser.add_argument('--redshift-location', help='LAT:LON Your current location', type=str)
argument_parser.add_argument('--redshift-temperature', help='DAY:NIGHT Color temperature to set at daytime/night', type=str)
def bind_arguments(self, args):
super().bind_arguments(args)
if self.enabled and not self.redshift_error_message:
self.redshift_enabled = True
@property
def enabled(self):
return self.args.redshift_enabled
@property
def redshift_enabled(self):
return bool(self._redshift_proc)
@property
def redshift_error_message(self):
if self.enabled and not (self.args.redshift_location or self.args.redshift_temperature):
return "Missing parameter(s) --redshift-location and/or --redshift-temperature"
if self._redshift_proc is not None and self._redshift_proc.returncode is not None and self._redshift_proc.returncode != 0:
return self._redshift_proc.communicate()[1].replace("\n", ' ')
return None
@redshift_enabled.setter
def redshift_enabled(self, value):
if value == self.redshift_enabled:
return
if value:
self._redshift_proc = subprocess.Popen(['redshift', '-l', self.args.redshift_location, '-t', self.args.redshift_temperature], )
else:
self._redshift_proc.terminate()
def periodic(self):
if self._redshift_proc:
self._redshift_proc.poll()
if self._redshift_proc.returncode is not None:
self._redshift_proc = None
return True
def respond_to(self, command):
if command == 'redshift':
self.redshift_enabled = not self.redshift_enabled
return True
return False
def cleanup(self):
self.redshift_enabled = False
if self._redshift_proc:
self._redshift_proc.wait()
def __str__(self):
if not self.redshift_error_message:
return functions.action(self.create_pipe_command('redshift'), 'R' if self.redshift_enabled else 'r')
return 'E: '+self.redshift_error_message
def load_state(self, state):
self.redshift_enabled = state['redshift_enabled']
def dump_state(self):
return {'redshift_enabled': self.redshift_enabled}
class ChildReaperControl(AbstractControl):
@property
def visible(self):
return False
def periodic(self):
try:
os.wait3(os.WNOHANG)
except:
pass