def main_dock_hook(): ''' Entry point for ``thinkpad-dock-hook``. It interprets the key values from the caller and start up another interpreter with the actual ``thinkpad-dock`` script. ''' parser = argparse.ArgumentParser() parser.add_argument('action', help='`on` or `off`') parser.add_argument("-v", dest='verbose', action="count", help='Enable verbose output. Can be supplied multiple ' 'times for even more verbosity.') options = parser.parse_args() tps.config.set_up_logging(options.verbose) user = get_graphicsl_user() if user is None: logger.warning('Unable to get graphical user. Ignoring trigger.') sys.exit(0) tps.check_call([ 'sudo', '-u', user, '-i', 'env', 'DISPLAY=:0.0', '/usr/bin/thinkpad-dock', options.action, '--via-hook' ], logger)
def main_rotate_hook(): ''' Entry point for ``thinkpad-rotate-hook``. It interprets the key values from the caller and start up another interpreter with the actual ``thinkpad-rotate`` script. ''' parser = argparse.ArgumentParser() parser.add_argument('ignored_one') parser.add_argument('ignored_two') parser.add_argument('ignored_three') parser.add_argument('key', help='Keycode') parser.add_argument("-v", dest='verbose', action="count", help='Enable verbose output. Can be supplied multiple ' 'times for even more verbosity.') options = parser.parse_args() tps.config.set_up_logging(options.verbose) key = options.key if key in ('00000001', '00005009'): set_to = '' elif key in ('00000000', '0000500a'): set_to = 'normal' else: logger.error('Unexpected keycode %s given in rotate-hook', key) sys.exit(1) tps.check_call([ 'sudo', '-u', get_graphicsl_user(), '-i', 'env', 'DISPLAY=:0.0', '/usr/bin/thinkpad-rotate', set_to, '--via-hook', ], logger)
def main_rotate_hook(): ''' Entry point for ``thinkpad-rotate-hook``. It interprets the key values from the caller and start up another interpreter with the actual ``thinkpad-rotate`` script. ''' parser = argparse.ArgumentParser() parser.add_argument('direction', nargs='?', help='Direction to rotate to.') parser.add_argument('--via-hook', required=True, help='ID of hook that called this program') parser.add_argument("-v", dest='verbose', action="count", help='Enable verbose output. Can be supplied multiple ' 'times for even more verbosity.') options = parser.parse_args() tps.config.set_up_logging(options.verbose) if options.direction is not None: direction = [options.direction, '--force-direction'] else: direction = [] user = get_graphicsl_user() if user is None: logger.warning('Unable to get graphical user. Ignoring trigger.') sys.exit(0) tps.check_call([ 'sudo', '-u', user, '-i', 'env', 'DISPLAY=:0.0', '/usr/local/bin/thinkpad-rotate' ] + direction + ['--via-hook', options.via_hook], logger)
def set_subpixel_order(direction): ''' Sets the text subpixel anti-alias order. :param tps.Direction direction: New direction :returns: None ''' if tps.has_program('xfconf-query'): try: tps.check_call([ 'xfconf-query', '-c', 'xsettings', '-p', '/Xft/RGBA', '-s', direction.subpixel ], logger) except subprocess.CalledProcessError as e: logger.error(e) elif tps.has_program('gsettings'): try: schemas = tps.check_output(['gsettings', 'list-schemas'], logger).decode().split('\n') schema = 'org.gnome.settings-daemon.plugins.xsettings' if schema in schemas: tps.check_call([ 'gsettings', 'set', schema, 'rgba-order', direction.subpixel ], logger) else: logger.warning('gsettings is installed, but the "{}" schema ' 'is not available'.format(schema)) except subprocess.CalledProcessError as e: logger.error(e) else: logger.warning('neither xfconf-query nor gsettings is installed')
def set_subpixel_order(direction): ''' Sets the text subpixel anti-alias order. :param tps.Direction direction: New direction :returns: None ''' if tps.has_program('xfconf-query'): try: tps.check_call(['xfconf-query', '-c', 'xsettings', '-p', '/Xft/RGBA', '-s', direction.subpixel], logger) except subprocess.CalledProcessError as e: logger.error(e) elif tps.has_program('gsettings'): try: schemas = tps.check_output( ['gsettings', 'list-schemas'], logger).decode().split('\n') schema = 'org.gnome.settings-daemon.plugins.xsettings' if schema in schemas: tps.check_call(['gsettings', 'set', schema, 'rgba-order', direction.subpixel], logger) else: logger.warning('gsettings is installed, but the "{}" schema ' 'is not available'.format(schema)) except subprocess.CalledProcessError as e: logger.error(e) else: logger.warning('neither xfconf-query nor gsettings is installed')
def toggle(program, state): ''' Toggles the running state of the given progam. If state is true, the program will be spawned. :param str program: Name of the program :param bool state: Desired state :returns: None ''' if state: try: tps.check_output(['pgrep', program], logger) except subprocess.CalledProcessError: if tps.has_program(program): logger.debug(program) subprocess.Popen([program]) else: logger.warning('{} is not installed'.format(program)) else: try: tps.check_output(['pgrep', program], logger) tps.check_call(['killall', program], logger) except subprocess.CalledProcessError: pass
def disable(screen): ''' Disables the given screen using ``xrandr``. :param str screen: Name of the output to disable :returns: None ''' tps.check_call(['xrandr', '--output', screen, '--off'], logger)
def set_wacom_touch(device_id, state): ''' Changes the Wacom Touch property of the given device. ''' tps.check_call([ 'xinput', 'set-prop', str(device_id), 'Wacom Enable Touch', '1' if state else '0' ], logger)
def rotate_wacom_device(device, direction): ''' Rotates a Wacom® device. :type device: int :type direction: tps.Direction ''' tps.check_call(['xsetwacom', 'set', str(device), 'rotate', direction.xsetwacom], logger)
def set_volume(loudness): ''' Sets the volume to the given loudness. :param str loudness: Loudness value as string with percent ''' sinks = get_pulseaudio_sinks() for sink in sinks: tps.check_call(['pactl', 'set-sink-volume', sink, loudness], logger)
def map_wacom_device_to_output(device, output): ''' Maps a Wacom® device to a specific output. :type device: int :type output: str ''' tps.check_call(['xsetwacom', 'set', str(device), 'MapToOutput', output], logger)
def rotate(screen, direction): ''' Rotates the screen into the direction. :param str screen: Name of the output to rotate :param tps.Direction direction: New direction :returns: None ''' tps.check_call( ['xrandr', '--output', screen, '--rotate', direction.xrandr], logger)
def map_rotate_input_device(device, matrix): """ Rotates an input device. :type device: int :type direction: tps.Direction """ tps.check_call( ["xinput", "set-prop", str(device), "Coordinate Transformation Matrix"] + list(map(str, matrix)), logger )
def rotate(screen, direction): ''' Rotates the screen into the direction. :param str screen: Name of the output to rotate :param tps.Direction direction: New direction :returns: None ''' tps.check_call(['xrandr', '--output', screen, '--rotate', direction.xrandr], logger)
def map_rotate_input_device(device, matrix): ''' Rotates an input device. :type device: int :type direction: tps.Direction ''' tps.check_call( ['xinput', 'set-prop', str(device), 'Coordinate Transformation Matrix'] + list(map(str, matrix)), logger )
def map_rotate_input_device(device, matrix): ''' Rotates an input device. :type device: int :type direction: tps.Direction ''' tps.check_call([ 'xinput', 'set-prop', str(device), 'Coordinate Transformation Matrix' ] + list(map(str, matrix)), logger)
def unmute(loudness): ''' Unmutes the speakers and sets them to the given loudness. :param str loudness: Loudness value as string with percent ''' sinks = get_pulseaudio_sinks() for sink in sinks: tps.check_call(['pactl', 'set-sink-mute', sink, '0'], logger) set_volume(loudness)
def set_volume(loudness): ''' Sets the volume to the given loudness. :param str loudness: Loudness value as string with percent ''' if not tps.has_program('pactl'): logger.warning('pactl is not installed') return tps.check_call(['pactl', 'set-sink-volume', '0', loudness], logger)
def set_xinput_state(device, state): """ Sets the device state. :param device: ``xinput`` ID of devicwe :type device: int :param state: Whether device should be enabled :type state: bool """ set_to = "1" if state else "0" tps.check_call(["xinput", "set-prop", str(device), "Device Enabled", set_to], logger)
def set_brightness(brightness): ''' Sets the brightness with ``xbacklight``. :param str brightness: Percent value of brightness, e. g. ``60%`` :returns: None ''' if not tps.has_program('xbacklight'): logger.warning('xbacklight is not installed') return tps.check_call(['xbacklight', '-set', brightness], logger)
def main_mutemic(): ''' Entry point for ``thinkpad-mutemic``. ''' parser = argparse.ArgumentParser() parser.add_argument("-v", dest='verbose', action="count", help='Enable verbose output. Can be supplied multiple ' 'times for even more verbosity.') options = parser.parse_args() tps.config.set_up_logging(options.verbose) tps.check_call(['amixer', 'sset', "'Capture',0", 'toggle'], logger)
def set_xinput_state(device, state): ''' Sets the device state. :param device: ``xinput`` ID of devicwe :type device: int :param state: Whether device should be enabled :type state: bool ''' set_to = '1' if state else '0' tps.check_call(['xinput', 'set-prop', str(device), 'Device Enabled', set_to], logger)
def restart(connection): ''' Disables and enables the given connection if it exists. :param str connection: Name of the connection :returns: None ''' if not tps.has_program('nmcli'): logger.warning('nmcli is not installed') return tps.check_call(['nmcli', 'con', 'up', 'id', connection], logger)
def unmute(loudness): ''' Unmutes the speakers and sets them to the given loudness. :param str loudness: Loudness value as string with percent ''' if not tps.has_program('pactl'): logger.warning('pactl is not installed') return tps.check_call(['pactl', 'set-sink-volume', '0', loudness], logger) tps.check_call(['pactl', 'set-sink-mute', '0', '0'], logger)
def map_rotate_wacom_device(device, output, direction): tps.check_call( ['xsetwacom', 'set', str(device), 'rotate', direction.xsetwacom], logger) tps.check_call(['xsetwacom', 'set', str(device), 'MapToOutput', output], logger) # In March 2020 I first noticed that the pen input did not work any more # after rotating. Restarting the X11 server got it to work again. It seems # that for some reason the device gets disabled when it is rotated in the # latest versions of `xsetwacom`. Just enabling it afterwards is a simple # fix for that issue. set_xinput_state(str(device), True)
def wacom_rotate_reset(device): ''' Resets the “Wacom Rotation” property of devices. In GH-117__ we noticed that in Ubuntu the ``xrandr`` rotation command will also rotate some input devices. This is probably meant in a good way but interferes with our rotation here. Therefore we reset the “Wacom Rotation” after setting the transformation matrix. __ https://github.com/martin-ueding/thinkpad-scripts/issues/117 ''' if has_device_property(device, 'Wacom Rotation'): command = ['xinput', 'set-prop', str(device), 'Wacom Rotation', '0'] tps.check_call(command, logger)
def main_rotate_hook(): ''' Entry point for ``thinkpad-rotate-hook``. It interprets the key values from the caller and start up another interpreter with the actual ``thinkpad-rotate`` script. ''' parser = argparse.ArgumentParser() parser.add_argument('ignored_one') parser.add_argument('ignored_two') parser.add_argument('ignored_three') parser.add_argument('key', help='Keycode') parser.add_argument("-v", dest='verbose', action="count", help='Enable verbose output. Can be supplied multiple ' 'times for even more verbosity.') options = parser.parse_args() tps.config.set_up_logging(options.verbose) key = options.key if key in ('00000001', '00005009'): set_to = '' elif key in ('00000000', '0000500a'): set_to = 'normal' else: logger.error('Unexpected keycode %s given in rotate-hook', key) sys.exit(1) user = get_graphicsl_user() if user is None: logger.warning('Unable to get graphical user. Ignoring trigger.') sys.exit(0) tps.check_call([ 'sudo', '-u', user, '-i', 'env', 'DISPLAY=:0.0', '/usr/bin/thinkpad-rotate', set_to, '--via-hook', ], logger)
def set_wifi(state): ''' Sets the wifi hardware to the given state. :param bool state: Desired state :returns: None ''' if not tps.has_program('nmcli'): logger.warning('nmcli is not installed') return if get_nmcli_version() >= (0, 9, 10): command = ['nmcli', 'radio', 'wifi', 'on' if state else 'off'] else: command = ['nmcli', 'nm', 'wifi', 'on' if state else 'off'] tps.check_call(command, logger)
def set_launcher(autohide): ''' Sets the autohide property of the Unity launcher. In the back, this uses ``dconf``. If that is not installed, this just fails with a warning. :param bool autohide: True if autohide is desired ''' if not tps.has_program('dconf'): logger.warning('dconf is not installed') return set_to = '1' if autohide else '0' tps.check_call(['dconf', 'write', '/org/compiz/profiles/unity/plugins/unityshell/launcher-hide-mode', set_to], logger)
def enable(screen, primary=False, position=None): ''' Enables given screen using ``xrandr``. :param str screen: Name of the output to enable :param bool primary: Set output as primary :param tuple position: Tuple with (0) relative position and (1) other output. This could be ``('right-of', 'LVDS1')``. :returns: None ''' command = ['xrandr', '--output', screen, '--auto'] if position is not None: command += ['--{}'.format(position[0]), position[1]] if primary: command += ['--primary'] tps.check_call(command, logger)
def set_launcher(autohide): ''' Sets the autohide property of the Unity launcher. In the back, this uses ``dconf``. If that is not installed, this just fails with a warning. :param bool autohide: True if autohide is desired ''' if not tps.has_program('dconf'): logger.warning('dconf is not installed') return set_to = '1' if autohide else '0' tps.check_call([ 'dconf', 'write', '/org/compiz/profiles/unity/plugins/unityshell/launcher-hide-mode', set_to ], logger)
def main_dock_hook(): ''' Entry point for ``thinkpad-dock-hook``. It interprets the key values from the caller and start up another interpreter with the actual ``thinkpad-dock`` script. ''' parser = argparse.ArgumentParser() parser.add_argument('action', help='Keycode') parser.add_argument("-v", dest='verbose', action="count", help='Enable verbose output. Can be supplied multiple ' 'times for even more verbosity.') options = parser.parse_args() tps.config.set_up_logging(options.verbose) tps.check_call([ 'sudo', '-u', get_graphicsl_user(), '-i', 'env', 'DISPLAY=:0.0', '/usr/bin/thinkpad-dock', options.action ], logger)
def set_wacom_touch(device_id, state): ''' Changes the Wacom Touch property of the given device. ''' tps.check_call(['xinput', 'set-prop', str(device_id), 'Wacom Enable Touch', '1' if state else '0'], logger)
def set_wacom_touch(device_id, state): """ Changes the Wacom Touch property of the given device. """ tps.check_call(["xinput", "set-prop", str(device_id), "Wacom Enable Touch", "1" if state else "0"], logger)
def toggle_virtual_terminal(): ''' ''' assert can_use_chvt() tps.check_call(['sudo', '-n', 'chvt', '6'], logger) tps.check_call(['sudo', '-n', 'chvt', '7'], logger)
def toggle_virtual_terminal(): """ """ assert can_use_chvt() tps.check_call(["sudo", "-n", "chvt", "6"], logger) tps.check_call(["sudo", "-n", "chvt", "7"], logger)
def map_rotate_wacom_device(device, output, direction): tps.check_call(['xsetwacom', 'set', str(device), 'rotate', direction.xsetwacom], logger) tps.check_call(['xsetwacom', 'set', str(device), 'MapToOutput', output], logger)
def set_wacom_touch(device_id, state): ''' Changes the Wacom Touch property of the given device. ''' tps.check_call(['xsetwacom', '--set', str(device_id), 'Touch', 'On' if state else 'Off'], logger)