From 883465d9fb29cd793684ee0ac688ff3517cf8bc0 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Mon, 22 Sep 2025 00:01:23 +0100 Subject: Add generic handling to cycle LED/RGB Matrix flags (#24649) --- lib/python/qmk/info.py | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'lib/python/qmk/info.py') diff --git a/lib/python/qmk/info.py b/lib/python/qmk/info.py index f63228b2bc..59a64095e7 100644 --- a/lib/python/qmk/info.py +++ b/lib/python/qmk/info.py @@ -800,6 +800,14 @@ def _extract_led_config(info_data, keyboard): if info_data[feature].get('layout', None) and not info_data[feature].get('led_count', None): info_data[feature]['led_count'] = len(info_data[feature]['layout']) + if info_data[feature].get('layout', None) and not info_data[feature].get('flag_steps', None): + flags = {0xFF, 0} + # if only a single flag is used, assume only all+none flags + unique_flags = set(x.get('flags', 0) for x in info_data[feature]['layout']) + if len(unique_flags) > 1: + flags.update(unique_flags) + info_data[feature]['flag_steps'] = sorted(list(flags), reverse=True) + return info_data -- cgit v1.2.3 From 6e35013bc2e30af022cdb8c176e869c5c94ee17a Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Sat, 8 Nov 2025 20:48:48 +0000 Subject: Generate `CUSTOM_MATRIX = lite` without `matrix_pins.custom` (#25453) --- keyboards/argyle/keyboard.json | 1 - keyboards/keychron/c2_pro/info.json | 1 - keyboards/keychron/q1v2/info.json | 1 - lib/python/qmk/cli/generate/rules_mk.py | 9 ++++--- lib/python/qmk/info.py | 42 +++++++++++++++++++++------------ 5 files changed, 31 insertions(+), 23 deletions(-) (limited to 'lib/python/qmk/info.py') diff --git a/keyboards/argyle/keyboard.json b/keyboards/argyle/keyboard.json index a7bfc335df..d97f067be8 100755 --- a/keyboards/argyle/keyboard.json +++ b/keyboards/argyle/keyboard.json @@ -11,7 +11,6 @@ }, "matrix_pins": { "cols": ["D1", "D4", "D5", "D6", "D7", "B0", "NO_PIN", "NO_PIN", "NO_PIN", "NO_PIN", "NO_PIN", "NO_PIN", "NO_PIN", "NO_PIN"], - "custom": true, "custom_lite": true, "rows": ["D0", "C3", "B1", "B2", "B3"] }, diff --git a/keyboards/keychron/c2_pro/info.json b/keyboards/keychron/c2_pro/info.json index 9c0e1ac72e..8a7d0968b1 100644 --- a/keyboards/keychron/c2_pro/info.json +++ b/keyboards/keychron/c2_pro/info.json @@ -26,7 +26,6 @@ "matrix_pins": { "cols": ["A10", "A9", "A8", "B1", "B0", "A7", "A6", "A5", "A4", "A3", "A2", "NO_PIN", "NO_PIN", "NO_PIN", "NO_PIN", "NO_PIN", "NO_PIN", "NO_PIN", "NO_PIN", "C14"], "rows": ["B5", "B4", "B3", "A15", "A14", "A13"], - "custom": true, "custom_lite": true }, "diode_direction": "ROW2COL" diff --git a/keyboards/keychron/q1v2/info.json b/keyboards/keychron/q1v2/info.json index f0342254fa..ba6f908bbb 100644 --- a/keyboards/keychron/q1v2/info.json +++ b/keyboards/keychron/q1v2/info.json @@ -27,7 +27,6 @@ "matrix_pins": { "cols": ["C14", "C15", "A0", "A1", "A2", "A3", "A4", "A5", null, null, null, null, null, null, null, null], "rows": ["B5", "B4", "B3", "A15", "A14", "A13"], - "custom": true, "custom_lite": true }, "diode_direction": "ROW2COL", diff --git a/lib/python/qmk/cli/generate/rules_mk.py b/lib/python/qmk/cli/generate/rules_mk.py index 358a22fd1d..16084bded1 100755 --- a/lib/python/qmk/cli/generate/rules_mk.py +++ b/lib/python/qmk/cli/generate/rules_mk.py @@ -96,11 +96,10 @@ def generate_rules_mk(cli): rules_mk_lines.append(generate_rule('SPLIT_TRANSPORT', 'custom')) # Set CUSTOM_MATRIX, if needed - if kb_info_json.get('matrix_pins', {}).get('custom'): - if kb_info_json.get('matrix_pins', {}).get('custom_lite'): - rules_mk_lines.append(generate_rule('CUSTOM_MATRIX', 'lite')) - else: - rules_mk_lines.append(generate_rule('CUSTOM_MATRIX', 'yes')) + if kb_info_json.get('matrix_pins', {}).get('custom_lite'): + rules_mk_lines.append(generate_rule('CUSTOM_MATRIX', 'lite')) + elif kb_info_json.get('matrix_pins', {}).get('custom'): + rules_mk_lines.append(generate_rule('CUSTOM_MATRIX', 'yes')) if converter: rules_mk_lines.append(generate_rule('CONVERT_TO', converter)) diff --git a/lib/python/qmk/info.py b/lib/python/qmk/info.py index 59a64095e7..e6d51e1239 100644 --- a/lib/python/qmk/info.py +++ b/lib/python/qmk/info.py @@ -302,6 +302,24 @@ def _extract_features(info_data, rules): return info_data +def _extract_matrix_rules(info_data, rules): + """Find all the features enabled in rules.mk. + """ + if rules.get('CUSTOM_MATRIX', 'no') != 'no': + if 'matrix_pins' in info_data and 'custom' in info_data['matrix_pins']: + _log_warning(info_data, 'Custom Matrix is specified in both info.json and rules.mk, the rules.mk values win.') + + if 'matrix_pins' not in info_data: + info_data['matrix_pins'] = {} + + if rules['CUSTOM_MATRIX'] == 'lite': + info_data['matrix_pins']['custom_lite'] = True + else: + info_data['matrix_pins']['custom'] = True + + return info_data + + def _pin_name(pin): """Returns the proper representation for a pin. """ @@ -552,7 +570,6 @@ def _extract_matrix_info(info_data, config_c): row_pins = config_c.get('MATRIX_ROW_PINS', '').replace('{', '').replace('}', '').strip() col_pins = config_c.get('MATRIX_COL_PINS', '').replace('{', '').replace('}', '').strip() direct_pins = config_c.get('DIRECT_PINS', '').replace(' ', '')[1:-1] - info_snippet = {} if 'MATRIX_ROWS' in config_c and 'MATRIX_COLS' in config_c: if 'matrix_size' in info_data: @@ -567,26 +584,20 @@ def _extract_matrix_info(info_data, config_c): if 'matrix_pins' in info_data and 'cols' in info_data['matrix_pins'] and 'rows' in info_data['matrix_pins']: _log_warning(info_data, 'Matrix pins are specified in both info.json and config.h, the config.h values win.') - info_snippet['cols'] = _extract_pins(col_pins) - info_snippet['rows'] = _extract_pins(row_pins) + if 'matrix_pins' not in info_data: + info_data['matrix_pins'] = {} + + info_data['matrix_pins']['cols'] = _extract_pins(col_pins) + info_data['matrix_pins']['rows'] = _extract_pins(row_pins) if direct_pins: if 'matrix_pins' in info_data and 'direct' in info_data['matrix_pins']: _log_warning(info_data, 'Direct pins are specified in both info.json and config.h, the config.h values win.') - info_snippet['direct'] = _extract_direct_matrix(direct_pins) - - if config_c.get('CUSTOM_MATRIX', 'no') != 'no': - if 'matrix_pins' in info_data and 'custom' in info_data['matrix_pins']: - _log_warning(info_data, 'Custom Matrix is specified in both info.json and config.h, the config.h values win.') - - info_snippet['custom'] = True - - if config_c['CUSTOM_MATRIX'] == 'lite': - info_snippet['custom_lite'] = True + if 'matrix_pins' not in info_data: + info_data['matrix_pins'] = {} - if info_snippet: - info_data['matrix_pins'] = info_snippet + info_data['matrix_pins']['direct'] = _extract_direct_matrix(direct_pins) return info_data @@ -755,6 +766,7 @@ def _extract_rules_mk(info_data, rules): # Merge in config values that can't be easily mapped _extract_features(info_data, rules) + _extract_matrix_rules(info_data, rules) return info_data -- cgit v1.2.3 From 53de903fb89d4138fdc38f98d266db0fec9548b1 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Sun, 23 Nov 2025 11:21:55 +0000 Subject: Better defaulting of `{RGB,LED}_MATRIX_DEFAULT_FLAGS` (#25785) --- lib/python/qmk/info.py | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) (limited to 'lib/python/qmk/info.py') diff --git a/lib/python/qmk/info.py b/lib/python/qmk/info.py index e6d51e1239..a0b8fe72b6 100644 --- a/lib/python/qmk/info.py +++ b/lib/python/qmk/info.py @@ -5,6 +5,7 @@ import os from pathlib import Path import jsonschema from dotty_dict import dotty +from enum import IntFlag from milc import cli @@ -21,6 +22,15 @@ true_values = ['1', 'on', 'yes'] false_values = ['0', 'off', 'no'] +class LedFlags(IntFlag): + ALL = 0xFF + NONE = 0x00 + MODIFIER = 0x01 + UNDERGLOW = 0x02 + KEYLIGHT = 0x04 + INDICATOR = 0x08 + + def _keyboard_in_layout_name(keyboard, layout): """Validate that a layout macro does not contain name of keyboard """ @@ -813,12 +823,23 @@ def _extract_led_config(info_data, keyboard): info_data[feature]['led_count'] = len(info_data[feature]['layout']) if info_data[feature].get('layout', None) and not info_data[feature].get('flag_steps', None): - flags = {0xFF, 0} + flags = {LedFlags.ALL, LedFlags.NONE} + default_flags = {LedFlags.MODIFIER | LedFlags.KEYLIGHT, LedFlags.UNDERGLOW} + # if only a single flag is used, assume only all+none flags - unique_flags = set(x.get('flags', 0) for x in info_data[feature]['layout']) - if len(unique_flags) > 1: - flags.update(unique_flags) - info_data[feature]['flag_steps'] = sorted(list(flags), reverse=True) + kb_flags = set(x.get('flags', LedFlags.NONE) for x in info_data[feature]['layout']) + if len(kb_flags) > 1: + # check if any part of LED flag is with the defaults + unique_flags = set() + for candidate in default_flags: + if any(candidate & flag for flag in kb_flags): + unique_flags.add(candidate) + + # if we still have a single flag, assume only all+none + if len(unique_flags) > 1: + flags.update(unique_flags) + + info_data[feature]['flag_steps'] = sorted([int(flag) for flag in flags], reverse=True) return info_data -- cgit v1.2.3