Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: holistic profile comparison #362

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 49 additions & 12 deletions autorandr.py
Original file line number Diff line number Diff line change
Expand Up @@ -756,19 +756,56 @@ def find_profiles(current_config, profiles):
detected_profiles = []
for profile_name, profile in profiles.items():
config = profile["config"]
matches = True
for name, output in config.items():
on = set()
missing_fingerprint = set()
missing_output_names = set()
fingerprint_mismatch = set()
closeness_scores = set()
profile_output_names = set(config.keys())

for name in profile_output_names:
output = config[name]

if not output.fingerprint:
missing_fingerprint.add(name)
continue
if name not in current_config or not output.fingerprint_equals(current_config[name]):
matches = False
break
if not matches or any((name not in config.keys() for name in current_config.keys() if current_config[name].fingerprint)):
elif name not in current_config:
missing_output_names.add(name)
continue
elif not output.fingerprint_equals(current_config[name]):
fingerprint_mismatch.add(name)
continue
elif "off" in output.options:
continue

on.add(name)

current_edid = current_config[name].edid
if output.edid is not None and current_edid is not None:
closeness_scores.add(max(match_asterisk(output.edid, current_edid), match_asterisk(current_edid, output.edid)))
else:
print(f'no edid match for output {name} in profile {profile_name}; current={current_edid}, output={output.edid}')
closeness_scores.append(0)

if len(fingerprint_mismatch) > 0:
print(f'have {len(fingerprint_mismatch)} ({", ".join(fingerprint_mismatch)}) mismatching fingerprint(s) for profile {profile_name}; omitting it.')
continue
if matches:
closeness = max(match_asterisk(output.edid, current_config[name].edid), match_asterisk(
current_config[name].edid, output.edid))
detected_profiles.append((closeness, profile_name))
elif len(missing_output_names) > 0:
print(f'have {len(missing_output_names)} missing output(s) ({", ".join(missing_output_names)}) for profile {profile_name}; omitting it.')
continue

current_output_names = [name for name in current_config.keys() if current_config[name].fingerprint]
possible_output_names = [name for name in current_output_names if name in on]

percent_present_in_profile = len(possible_output_names) / len(current_output_names)
percent_present_in_current_config = len(on) / len(possible_output_names)

closeness = sum(closeness_scores) / len(closeness_scores)

score = percent_present_in_profile * percent_present_in_current_config * closeness

detected_profiles.append((score, profile_name))

detected_profiles = [o[1] for o in sorted(detected_profiles, key=lambda x: -x[0])]
return detected_profiles

Expand Down Expand Up @@ -1094,9 +1131,9 @@ def generate_virtual_profile(configuration, modes, profile_name):
else:
shift_index = "height"
pos_specifier = "0x%s"

config_iter = reversed(configuration) if "reverse" in profile_name else iter(configuration)

for output in config_iter:
configuration[output].options = {}
if output in modes and configuration[output].edid:
Expand Down