X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=autorandr.py;h=812329ddf72e78d8dd01bc158fa37cc74ed1cdc1;hb=9d4f09ed4f66a25d2f580f60ad4fda024e573b71;hp=dbcf8753d2d08bf16f93aa425abc38936b53e064;hpb=9e93a611cc00e5cbeddc9d8a7cb5bc93f111a060;p=deb_pkgs%2Fautorandr.git diff --git a/autorandr.py b/autorandr.py index dbcf875..812329d 100755 --- a/autorandr.py +++ b/autorandr.py @@ -23,6 +23,7 @@ # from __future__ import print_function +import time import binascii import copy @@ -40,6 +41,10 @@ from distutils.version import LooseVersion as Version from functools import reduce from itertools import chain +try: + input = raw_input +except NameError: + pass virtual_profiles = [ # (name, description, callback) @@ -524,6 +529,25 @@ def update_mtime(filename): except: return False +def call_and_retry(*args, **kwargs): + """Wrapper around subprocess.call that retries failed calls. + + This function calls subprocess.call and on non-zero exit states, + waits a second and then retries once. This mitigates #47, + a timing issue with some drivers. + """ + kwargs_redirected = dict(kwargs) + if hasattr(subprocess, "DEVNULL"): + kwargs_redirected["stdout"] = getattr(subprocess, "DEVNULL") + else: + kwargs_redirected["stdout"] = open(os.devnull, "w") + kwargs_redirected["stderr"] = kwargs_redirected["stdout"] + retval = subprocess.call(*args, **kwargs_redirected) + if retval != 0: + time.sleep(1) + retval = subprocess.call(*args, **kwargs) + return retval + def apply_configuration(new_configuration, current_configuration, dry_run=False): "Apply a configuration" outputs = sorted(new_configuration.keys(), key=lambda x: new_configuration[x].sort_key) @@ -577,13 +601,13 @@ def apply_configuration(new_configuration, current_configuration, dry_run=False) # Perform pe-change auxiliary changes if auxiliary_changes_pre: argv = base_argv + list(chain.from_iterable(auxiliary_changes_pre)) - if subprocess.call(argv) != 0: + if call_and_retry(argv) != 0: raise AutorandrException("Command failed: %s" % " ".join(argv)) # Disable unused outputs, but make sure that there always is at least one active screen disable_keep = 0 if remain_active_count else 1 if len(disable_outputs) > disable_keep: - if subprocess.call(base_argv + list(chain.from_iterable(disable_outputs[:-1] if disable_keep else disable_outputs))) != 0: + if call_and_retry(base_argv + list(chain.from_iterable(disable_outputs[:-1] if disable_keep else disable_outputs))) != 0: # Disabling the outputs failed. Retry with the next command: # Sometimes disabling of outputs fails due to an invalid RRSetScreenSize. # This does not occur if simultaneously the primary screen is reset. @@ -602,7 +626,7 @@ def apply_configuration(new_configuration, current_configuration, dry_run=False) operations = disable_outputs + enable_outputs for index in range(0, len(operations), 2): argv = base_argv + list(chain.from_iterable(operations[index:index+2])) - if subprocess.call(argv) != 0: + if call_and_retry(argv) != 0: raise AutorandrException("Command failed: %s" % " ".join(argv)) def is_equal_configuration(source_configuration, target_configuration): @@ -801,11 +825,23 @@ def main(argv): if options["--remove"] not in profiles.keys(): raise AutorandrException("Cannot remove profile '%s':\nThis profile does not exist." % options["--remove"]) try: + remove = True profile_folder = os.path.join(profile_path, options["--remove"]) - shutil.rmtree(profile_folder) + profile_dirlist = os.listdir(profile_folder) + profile_dirlist.remove("config") + profile_dirlist.remove("setup") + if profile_dirlist: + print("Profile folder '%s' contains the following additional files:\n---\n%s\n---" % (options["--remove"], "\n".join(profile_dirlist))) + response = input("Do you really want to remove profile '%s'? If so, type 'yes': " % options["--remove"]).strip() + if response != "yes": + remove = False + if remove is True: + shutil.rmtree(profile_folder) + print("Removed profile '%s'" % options["--remove"]) + else: + print("Profile '%s' was not removed" % options["--remove"]) except Exception as e: raise AutorandrException("Failed to remove profile '%s'" % (options["--remove"],), e) - print("Removed profile '%s'" % options["--remove"]) sys.exit(0) if "-h" in options or "--help" in options: @@ -882,6 +918,9 @@ def main(argv): "PROFILE_FOLDER": scripts_path, } exec_scripts(scripts_path, "preswitch", script_metadata) + if "--debug" in options: + print("Going to run:") + apply_configuration(load_config, config, True) apply_configuration(load_config, config, False) exec_scripts(scripts_path, "postswitch", script_metadata) except Exception as e: