virtual_profiles = [
# (name, description, callback)
("common", "Clone all connected outputs at the largest common resolution", None),
+ ("clone-largest", "Clone all connected outputs with the largest resolution (scaled down if necessary)", None),
("horizontal", "Stack all connected outputs horizontally at their largest resolution", None),
("vertical", "Stack all connected outputs vertically at their largest resolution", None),
]
# at least.)
# - Some implementations can not handle --transform at all, so avoid it unless
# necessary. (See https://github.com/phillipberndt/autorandr/issues/37)
+ # - Some implementations can not handle --panning without specifying --fb
+ # explicitly, so avoid it unless necessary.
+ # (See https://github.com/phillipberndt/autorandr/issues/72)
auxiliary_changes_pre = []
disable_outputs = []
option_vector = new_configuration[output].option_vector
if xrandr_version() >= Version("1.3.0"):
- if "transform" in current_configuration[output].options:
- auxiliary_changes_pre.append(["--output", output, "--transform", "none"])
- else:
- try:
- transform_index = option_vector.index("--transform")
- if option_vector[transform_index+1] == XrandrOutput.XRANDR_DEFAULTS["transform"]:
- option_vector = option_vector[:transform_index] + option_vector[transform_index+2:]
- except ValueError:
- pass
+ for option in ("transform", "panning"):
+ if option in current_configuration[output].options:
+ auxiliary_changes_pre.append(["--output", output, "--%s" % option, "none"])
+ else:
+ try:
+ option_index = option_vector.index("--%s" % option)
+ if option_vector[option_index+1] == XrandrOutput.XRANDR_DEFAULTS[option]:
+ option_vector = option_vector[:option_index] + option_vector[option_index+2:]
+ except ValueError:
+ pass
enable_outputs.append(option_vector)
shift += int(mode[shift_index])
else:
configuration[output].options["off"] = None
+ elif profile_name == "clone-largest":
+ biggest_resolution = sorted([output_modes[0] for output, output_modes in modes.items()], key=lambda x: int(x["width"])*int(x["height"]), reverse=True)[0]
+ for output in configuration:
+ configuration[output].options = {}
+ if output in modes and configuration[output].edid:
+ mode = sorted(modes[output], key=lambda a: int(a["width"])*int(a["height"]) + (10**6 if a["preferred"] else 0))[-1]
+ configuration[output].options["mode"] = mode["name"]
+ configuration[output].options["rate"] = mode["rate"]
+ configuration[output].options["pos"] = "0x0"
+ scale = max(float(biggest_resolution["width"]) / float(mode["width"]) ,float(biggest_resolution["height"]) / float(mode["height"]))
+ mov_x = (float(mode["width"])*scale-float(biggest_resolution["width"]))/-2
+ mov_y = (float(mode["height"])*scale-float(biggest_resolution["height"]))/-2
+ configuration[output].options["transform"] = "{},0,{},0,{},{},0,0,1".format(scale, mov_x, scale, mov_y)
+ else:
+ configuration[output].options["off"] = None
return configuration
def print_profile_differences(one, another):
"Print help and exit"
print(help_text)
for profile in virtual_profiles:
- print(" %-10s %s" % profile[:2])
+ name, description = profile[:2]
+ description = [ description ]
+ max_width = 78-18
+ while len(description[0]) > max_width + 1:
+ left_over = description[0][max_width:]
+ description[0] = description[0][:max_width] + "-"
+ description.insert(1, " %-15s %s" % ("", left_over))
+ description = "\n".join(description)
+ print(" %-15s %s" % (name, description))
sys.exit(0)
def exec_scripts(profile_path, script_name, meta_information=None):
display = process_environ["DISPLAY"] if "DISPLAY" in process_environ else None
# To allow scripts to detect batch invocation (especially useful for predetect)
- process_environ["AUTORANDR_BATCH_PID"] = os.getpid()
+ process_environ["AUTORANDR_BATCH_PID"] = str(os.getpid())
if display and display not in X11_displays_done:
try: