]> git.donarmstrong.com Git - deb_pkgs/autorandr.git/commitdiff
Merge branch 'master' into master
authorPhillip Berndt <phillip.berndt@googlemail.com>
Thu, 16 Dec 2021 09:39:52 +0000 (10:39 +0100)
committerGitHub <noreply@github.com>
Thu, 16 Dec 2021 09:39:52 +0000 (10:39 +0100)
1  2 
autorandr.1
autorandr.py
contrib/bash_completion/autorandr
contrib/zsh_completion/_autorandr

diff --combined autorandr.1
index 698ac7c3fe70e768f512b467593e768d1c773640,6ff816c465ab27d6142128a4fe17b4ff78c5fd63..d20264b920e3963db2fb3d21a95d9e558f297608
@@@ -38,6 -38,9 +38,9 @@@ List only the current (active) configur
  .BR \-\-config
  Dump the variable values of your current xrandr setup
  .TP
+ .BR \-\-cycle
+ Cycle through all detected profiles
+ .TP
  .BR \-\-debug
  Enable verbose output
  .TP
@@@ -50,17 -53,28 +53,31 @@@ Don't change anything, only print the x
  .BR \-\-fingerprint
  Fingerprint the current hardware setup
  .TP
 +.BR \-\-match-edid
 +Match displays based on edid instead of name
 +.TP
  .BR \-\-force
  Force loading or reloading of a profile
  .TP
+ .BR \-\-list
+ List all profiles
+ .TP
  \fB\-\-skip\-options [\fIOPTION\fR] ...
  \fRSet a comma\-separated list of xrandr arguments to skip both in change detection and profile application. See \fBxrandr(1)\fR for xrandr arguments.
  .TP
  .BR \-\-version
  Show version information and exit
+ .SH FILES
+ Configuration files are searched for in the \fIautorandr
+ \fRdirectory in the colon separated list of paths in \fI$XDG_CONFIG_DIRS
+ \fR- or in \fI/etc/xdg
+ \fRif that var is not set.  They are then looked for in \fI~/.autorandr
+ \fRand if that doesn't exist, in \fI$XDG_CONFIG_HOME/autorandr
+ \fRor in \fI~/.config/autorandr\fR if that var is unset.
+ In each of those directories it looks for directories with \fIconfig\fR and
+ \fIsetup\fR in them.  It is best to manage these files with the
+ \fBautorandr\fR utility.
  .SH AUTHOR
  \fRPhillip Berndt <phillip.berndt@googlemail.com>
  .br
diff --combined autorandr.py
index 6ebd55261bf83d503acf5f1257ff05426b892411,7ad9736b136f516a7f0309a3b80b17f907b53809..24d8b3a9df0674291c91ac88756975fc08223315
@@@ -1,4 -1,4 +1,4 @@@
- #!/usr/bin/env python
+ #!/usr/bin/env python3
  # encoding: utf-8
  #
  # autorandr.py
@@@ -39,10 -39,14 +39,14 @@@ import tim
  import glob
  
  from collections import OrderedDict
- from distutils.version import LooseVersion as Version
  from functools import reduce
  from itertools import chain
  
+ try:
+     from packaging.version import Version
+ except ModuleNotFoundError:
+     from distutils.version import LooseVersion as Version
  if sys.version_info.major == 2:
      import ConfigParser as configparser
  else:
@@@ -76,12 -80,13 +80,14 @@@ Usage: autorandr [options
  --batch                 run autorandr for all users with active X11 sessions
  --current               only list current (active) configuration(s)
  --config                dump your current xrandr setup
+ --cycle                 automatically load the next detected profile
  --debug                 enable verbose output
  --detected              only list detected (available) configuration(s)
  --dry-run               don't change anything, only print the xrandr commands
  --fingerprint           fingerprint your current hardware setup
 +--match-edid            match diplays based on edid instead of name
  --force                 force (re)loading of a profile / overwrite exiting files
+ --list                  list configurations
  --skip-options <option> comma separated list of xrandr arguments (e.g. "gamma")
                          to skip both in detecting changes and applying a profile
  --version               show version information and exit
@@@ -594,36 -599,6 +600,36 @@@ def match_asterisk(pattern, data)
      return matched * 1. / total
  
  
 +def update_profiles_edid(profiles, config):
 +    edid_map = {}
 +    for c in config:
 +        if config[c].edid is not None:
 +            edid_map[config[c].edid] = c
 +
 +    for p in profiles:
 +        profile_config = profiles[p]["config"]
 +
 +        for edid in edid_map:
 +            for c in profile_config.keys():
 +                if profile_config[c].edid != edid or c == edid_map[edid]:
 +                    continue
 +
 +                print("%s: renaming display %s to %s" % (p, c, edid_map[edid]))
 +
 +                tmp_disp = profile_config[c]
 +
 +                if edid_map[edid] in profile_config:
 +                    # Swap the two entries
 +                    profile_config[c] = profile_config[edid_map[edid]]
 +                    profile_config[c].output = c
 +                else:
 +                    # Object is reassigned to another key, drop this one
 +                    del profile_config[c]
 +
 +                profile_config[edid_map[edid]] = tmp_disp
 +                profile_config[edid_map[edid]].output = edid_map[edid]
 +
 +
  def find_profiles(current_config, profiles):
      "Find profiles matching the currently connected outputs, sorting asterisk matches to the back"
      detected_profiles = []
@@@ -1240,9 -1215,9 +1246,9 @@@ def read_config(options, directory)
  def main(argv):
      try:
          opts, args = getopt.getopt(argv[1:], "s:r:l:d:cfh",
-                                    ["batch", "dry-run", "change", "default=", "save=", "remove=", "load=",
+                                    ["batch", "dry-run", "change", "cycle", "default=", "save=", "remove=", "load=",
                                      "force", "fingerprint", "config", "debug", "skip-options=", "help",
-                                     "current", "detected", "version", "match-edid"])
 -                                    "list", "current", "detected", "version"])
++                                    "list", "current", "detected", "version", "match-edid"])
      except getopt.GetoptError as e:
          print("Failed to parse options: {0}.\n"
                "Use --help to get usage information.".format(str(e)),
              profiles.update(load_profiles(profile_path))
              profile_symlinks.update(get_symlinks(profile_path))
              read_config(options, profile_path)
 -        # Sort by mtime
 -        sort_direction = -1
 -        if "--cycle" in options:
 -            # When cycling through profiles, put the profile least recently used to the top of the list
 -            sort_direction = 1
 -        profiles = OrderedDict(sorted(profiles.items(), key=lambda x: sort_direction * x[1]["config-mtime"]))
      except Exception as e:
          raise AutorandrException("Failed to load profiles", e)
  
 -    profile_symlinks = {k: v for k, v in profile_symlinks.items() if v in (x[0] for x in virtual_profiles) or v in profiles}
 -
      exec_scripts(None, "predetect")
      config, modes = parse_xrandr_output()
  
-     # Sort by descending mtime
-     profiles = OrderedDict(sorted(profiles.items(), key=lambda x: -x[1]["config-mtime"]))
 +    if "--match-edid" in options:
 +        update_profiles_edid(profiles, config)
 +
++    # Sort by mtime
++    sort_direction = -1
++    if "--cycle" in options:
++        # When cycling through profiles, put the profile least recently used to the top of the list
++        sort_direction = 1
++    profiles = OrderedDict(sorted(profiles.items(), key=lambda x: sort_direction * x[1]["config-mtime"]))
 +    profile_symlinks = {k: v for k, v in profile_symlinks.items() if v in (x[0] for x in virtual_profiles) or v in profiles}
 +
      if "--fingerprint" in options:
          output_setup(config, sys.stdout)
          sys.exit(0)
          best_index = 9999
          for profile_name in profiles.keys():
              if profile_blocked(os.path.join(profile_path, profile_name), block_script_metadata):
-                 if "--current" not in options and "--detected" not in options:
+                 if not any(opt in options for opt in ("--current", "--detected", "--list")):
                      print("%s (blocked)" % profile_name)
                  continue
              props = []
+             is_current_profile = profile_name in current_profiles
              if profile_name in detected_profiles:
                  if len(detected_profiles) == 1:
                      index = 1
                  else:
                      index = detected_profiles.index(profile_name) + 1
                      props.append("(detected) (%d%s match)" % (index, ["st", "nd", "rd"][index - 1] if index < 4 else "th"))
-                 if ("-c" in options or "--change" in options) and index < best_index:
-                     load_profile = profile_name
-                     best_index = index
+                 if index < best_index:
+                     if "-c" in options or "--change" in options or ("--cycle" in options and not is_current_profile):
+                         load_profile = profile_name
+                         best_index = index
              elif "--detected" in options:
                  continue
-             if profile_name in current_profiles:
+             if is_current_profile:
                  props.append("(current)")
              elif "--current" in options:
                  continue
-             if "--current" in options or "--detected" in options:
+             if any(opt in options for opt in ("--current", "--detected", "--list")):
                  print("%s" % (profile_name, ))
              else:
                  print("%s%s%s" % (profile_name, " " if props else "", " ".join(props)))
  
      if "-d" in options:
          options["--default"] = options["-d"]
-     if not load_profile and "--default" in options and ("-c" in options or "--change" in options):
+     if not load_profile and "--default" in options and ("-c" in options or "--change" in options or "--cycle" in options):
          load_profile = options["--default"]
  
      if load_profile:
                  scripts_path = profile["path"]
              except KeyError:
                  raise AutorandrException("Failed to load profile '%s': Profile not found" % load_profile)
-             if load_profile in detected_profiles and detected_profiles[0] != load_profile:
+             if "--dry-run" not in options:
                  update_mtime(os.path.join(scripts_path, "config"))
          add_unused_outputs(config, load_config)
          if load_config == dict(config) and "-f" not in options and "--force" not in options:
index f7bef4f2bdb479469939b3fa0d6d78d3eee608d4,904ef8035e557e34a20b381d6a3ccbe9872b1418..0af11ec70834a7b2e0bdeb3a95f1f0a75d6c8ce2
@@@ -10,7 -10,7 +10,7 @@@ _autorandr (
        prev="${COMP_WORDS[COMP_CWORD-1]}"
  
        opts="-h -c -s -r -l -d"
-       lopts="--help --change --save --remove --load --default --force --fingerprint --match-edid --config --dry-run"
 -      lopts="--help --change --cycle --save --remove --load --list --default --force --fingerprint --config --dry-run"
++      lopts="--help --change --cycle --save --remove --load --list --default --force --fingerprint  --match-edid --config --dry-run"
  
        # find system-level autorandr dirs
        OIFS="$IFS"
index e17fc00e275b9b51672d52cb640fc589b7975282,848f614aaaf646e594faac0ad7b9e31ee0a8d4a3..1667f0c560a75a030c9613e89a9b387468ed4991
@@@ -28,12 -28,13 +28,14 @@@ _autorandr () 
         "($exclude)"{-r,--remove}"[remove profile]:profile:__autorandr_saved_profile" \
         --batch"[run autorandr for all users]" \
         --current"[list current active configurations]" \
+        --cycle"[cycle through all detected profiles]" \
         --config"[dump current xrandr setup]" \
         --debug"[enable verbose output]" \
         --dry-run"[don't change anything]" \
         --fingerprint"[fingerprint current hardware]" \
 +       --match-edid"[match displays using edid]" \
         --force"[force loading of a profile]" \
+        --list"[list all profiles]" \
         --skip-options"[skip xrandr options]:xrandr options:_values -s , options gamma brightness panning transform primary mode pos rate" \
         --version"[show version]"
  }