Skip to content

Commit

Permalink
Community modules (#24848)
Browse files Browse the repository at this point in the history
  • Loading branch information
tzarc authored Feb 26, 2025
1 parent 63b0952 commit 1efc824
Show file tree
Hide file tree
Showing 37 changed files with 987 additions and 84 deletions.
4 changes: 4 additions & 0 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,7 @@ dd:
- data/constants/**
- data/mappings/**
- data/schemas/**
community_module:
- changed-files:
- any-glob-to-any-file:
- modules/**
1 change: 1 addition & 0 deletions .github/workflows/format.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ on:
- 'lib/arm_atsam/**'
- 'lib/lib8tion/**'
- 'lib/python/**'
- 'modules/**'
- 'platforms/**'
- 'quantum/**'
- 'tests/**'
Expand Down
122 changes: 85 additions & 37 deletions builddefs/build_keyboard.mk
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,39 @@ endif
ifneq ("$(wildcard $(KEYBOARD_PATH_1)/rules.mk)","")
include $(KEYBOARD_PATH_1)/rules.mk
endif
# Create dependencies on DD keyboard config - structure validated elsewhere
DD_CONFIG_FILES :=
ifneq ("$(wildcard $(KEYBOARD_PATH_1)/info.json)","")
DD_CONFIG_FILES += $(KEYBOARD_PATH_1)/info.json
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_2)/info.json)","")
DD_CONFIG_FILES += $(KEYBOARD_PATH_2)/info.json
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_3)/info.json)","")
DD_CONFIG_FILES += $(KEYBOARD_PATH_3)/info.json
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_4)/info.json)","")
DD_CONFIG_FILES += $(KEYBOARD_PATH_4)/info.json
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_5)/info.json)","")
DD_CONFIG_FILES += $(KEYBOARD_PATH_5)/info.json
endif

ifneq ("$(wildcard $(KEYBOARD_PATH_1)/keyboard.json)","")
DD_CONFIG_FILES += $(KEYBOARD_PATH_1)/keyboard.json
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_2)/keyboard.json)","")
DD_CONFIG_FILES += $(KEYBOARD_PATH_2)/keyboard.json
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_3)/keyboard.json)","")
DD_CONFIG_FILES += $(KEYBOARD_PATH_3)/keyboard.json
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_4)/keyboard.json)","")
DD_CONFIG_FILES += $(KEYBOARD_PATH_4)/keyboard.json
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_5)/keyboard.json)","")
DD_CONFIG_FILES += $(KEYBOARD_PATH_5)/keyboard.json
endif

MAIN_KEYMAP_PATH_1 := $(KEYBOARD_PATH_1)/keymaps/$(KEYMAP)
MAIN_KEYMAP_PATH_2 := $(KEYBOARD_PATH_2)/keymaps/$(KEYMAP)
Expand Down Expand Up @@ -207,17 +240,17 @@ ifneq ("$(wildcard $(KEYMAP_JSON))", "")
include $(INFO_RULES_MK)

# Add rules to generate the keymap files - indentation here is important
$(INTERMEDIATE_OUTPUT)/src/keymap.c: $(KEYMAP_JSON)
$(INTERMEDIATE_OUTPUT)/src/keymap.c: $(KEYMAP_JSON) $(DD_CONFIG_FILES)
@$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD)
$(eval CMD=$(QMK_BIN) json2c --quiet --output $(KEYMAP_C) $(KEYMAP_JSON))
@$(BUILD_CMD)

$(INTERMEDIATE_OUTPUT)/src/config.h: $(KEYMAP_JSON)
$(INTERMEDIATE_OUTPUT)/src/config.h: $(KEYMAP_JSON) $(DD_CONFIG_FILES)
@$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD)
$(eval CMD=$(QMK_BIN) generate-config-h --quiet --output $(KEYMAP_H) $(KEYMAP_JSON))
@$(BUILD_CMD)

$(INTERMEDIATE_OUTPUT)/src/keymap.h: $(KEYMAP_JSON)
$(INTERMEDIATE_OUTPUT)/src/keymap.h: $(KEYMAP_JSON) $(DD_CONFIG_FILES)
@$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD)
$(eval CMD=$(QMK_BIN) generate-keymap-h --quiet --output $(INTERMEDIATE_OUTPUT)/src/keymap.h $(KEYMAP_JSON))
@$(BUILD_CMD)
Expand All @@ -226,6 +259,32 @@ generated-files: $(INTERMEDIATE_OUTPUT)/src/config.h $(INTERMEDIATE_OUTPUT)/src/

endif

# Community modules
$(INTERMEDIATE_OUTPUT)/src/community_modules.h: $(KEYMAP_JSON) $(DD_CONFIG_FILES)
@$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD)
$(eval CMD=$(QMK_BIN) generate-community-modules-h -kb $(KEYBOARD) --quiet --output $(INTERMEDIATE_OUTPUT)/src/community_modules.h $(KEYMAP_JSON))
@$(BUILD_CMD)

$(INTERMEDIATE_OUTPUT)/src/community_modules.c: $(KEYMAP_JSON) $(DD_CONFIG_FILES)
@$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD)
$(eval CMD=$(QMK_BIN) generate-community-modules-c -kb $(KEYBOARD) --quiet --output $(INTERMEDIATE_OUTPUT)/src/community_modules.c $(KEYMAP_JSON))
@$(BUILD_CMD)

$(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.c: $(KEYMAP_JSON) $(DD_CONFIG_FILES)
@$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD)
$(eval CMD=$(QMK_BIN) generate-community-modules-introspection-c -kb $(KEYBOARD) --quiet --output $(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.c $(KEYMAP_JSON))
@$(BUILD_CMD)

$(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.h: $(KEYMAP_JSON) $(DD_CONFIG_FILES)
@$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD)
$(eval CMD=$(QMK_BIN) generate-community-modules-introspection-h -kb $(KEYBOARD) --quiet --output $(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.h $(KEYMAP_JSON))
@$(BUILD_CMD)

SRC += $(INTERMEDIATE_OUTPUT)/src/community_modules.c

generated-files: $(INTERMEDIATE_OUTPUT)/src/community_modules.h $(INTERMEDIATE_OUTPUT)/src/community_modules.c $(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.c $(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.h


include $(BUILDDEFS_PATH)/converters.mk

# Generate the board's version.h file.
Expand Down Expand Up @@ -315,6 +374,14 @@ endif

# Find all of the config.h files and add them to our CONFIG_H define.
CONFIG_H :=

define config_h_community_module_appender
ifneq ("$(wildcard $(1)/config.h)","")
CONFIG_H += $(1)/config.h
endif
endef
$(foreach module,$(COMMUNITY_MODULE_PATHS),$(eval $(call config_h_community_module_appender,$(module))))

ifneq ("$(wildcard $(KEYBOARD_PATH_5)/config.h)","")
CONFIG_H += $(KEYBOARD_PATH_5)/config.h
endif
Expand All @@ -332,6 +399,14 @@ ifneq ("$(wildcard $(KEYBOARD_PATH_1)/config.h)","")
endif

POST_CONFIG_H :=

define post_config_h_community_module_appender
ifneq ("$(wildcard $(1)/post_config.h)","")
POST_CONFIG_H += $(1)/post_config.h
endif
endef
$(foreach module,$(COMMUNITY_MODULE_PATHS),$(eval $(call post_config_h_community_module_appender,$(module))))

ifneq ("$(wildcard $(KEYBOARD_PATH_1)/post_config.h)","")
POST_CONFIG_H += $(KEYBOARD_PATH_1)/post_config.h
endif
Expand All @@ -348,40 +423,6 @@ ifneq ("$(wildcard $(KEYBOARD_PATH_5)/post_config.h)","")
POST_CONFIG_H += $(KEYBOARD_PATH_5)/post_config.h
endif

# Create dependencies on DD keyboard config - structure validated elsewhere
DD_CONFIG_FILES :=
ifneq ("$(wildcard $(KEYBOARD_PATH_1)/info.json)","")
DD_CONFIG_FILES += $(KEYBOARD_PATH_1)/info.json
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_2)/info.json)","")
DD_CONFIG_FILES += $(KEYBOARD_PATH_2)/info.json
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_3)/info.json)","")
DD_CONFIG_FILES += $(KEYBOARD_PATH_3)/info.json
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_4)/info.json)","")
DD_CONFIG_FILES += $(KEYBOARD_PATH_4)/info.json
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_5)/info.json)","")
DD_CONFIG_FILES += $(KEYBOARD_PATH_5)/info.json
endif

ifneq ("$(wildcard $(KEYBOARD_PATH_1)/keyboard.json)","")
DD_CONFIG_FILES += $(KEYBOARD_PATH_1)/keyboard.json
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_2)/keyboard.json)","")
DD_CONFIG_FILES += $(KEYBOARD_PATH_2)/keyboard.json
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_3)/keyboard.json)","")
DD_CONFIG_FILES += $(KEYBOARD_PATH_3)/keyboard.json
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_4)/keyboard.json)","")
DD_CONFIG_FILES += $(KEYBOARD_PATH_4)/keyboard.json
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_5)/keyboard.json)","")
DD_CONFIG_FILES += $(KEYBOARD_PATH_5)/keyboard.json
endif

CONFIG_H += $(INTERMEDIATE_OUTPUT)/src/info_config.h
KEYBOARD_SRC += $(INTERMEDIATE_OUTPUT)/src/default_keyboard.c

Expand Down Expand Up @@ -462,6 +503,13 @@ ifneq ("$(wildcard $(KEYBOARD_PATH_5)/post_rules.mk)","")
include $(KEYBOARD_PATH_5)/post_rules.mk
endif

define post_rules_mk_community_module_includer
ifneq ("$(wildcard $(1)/post_rules.mk)","")
include $(1)/post_rules.mk
endif
endef
$(foreach module,$(COMMUNITY_MODULE_PATHS),$(eval $(call post_rules_mk_community_module_includer,$(module))))

ifneq ("$(wildcard $(KEYMAP_PATH)/config.h)","")
CONFIG_H += $(KEYMAP_PATH)/config.h
endif
Expand Down
7 changes: 7 additions & 0 deletions data/constants/keycodes/keycodes_0.0.7.hjson
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"ranges": {
"0x77C0/0x003F": {
"define": "QK_COMMUNITY_MODULE"
}
}
}
25 changes: 25 additions & 0 deletions data/constants/module_hooks/0.1.0.hjson
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
keyboard_pre_init: {
ret_type: void
args: void
}
keyboard_post_init: {
ret_type: void
args: void
}
pre_process_record: {
ret_type: bool
args: uint16_t keycode, keyrecord_t *record
call_params: keycode, record
}
process_record: {
ret_type: bool
args: uint16_t keycode, keyrecord_t *record
call_params: keycode, record
}
post_process_record: {
ret_type: void
args: uint16_t keycode, keyrecord_t *record
call_params: keycode, record
}
}
26 changes: 26 additions & 0 deletions data/constants/module_hooks/1.0.0.hjson
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
housekeeping_task: {
ret_type: void
args: void
}
suspend_power_down: {
ret_type: void
args: void
}
suspend_wakeup_init: {
ret_type: void
args: void
}
shutdown: {
ret_type: bool
args: bool jump_to_bootloader
call_params: jump_to_bootloader
}
process_detected_host_os: {
ret_type: bool
args: os_variant_t os
call_params: os
guard: defined(OS_DETECTION_ENABLE)
header: os_detection.h
}
}
17 changes: 17 additions & 0 deletions data/schemas/community_module.jsonschema
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema#",
"$id": "qmk.community_module.v1",
"title": "Community Module Information",
"type": "object",
"required": ["module_name", "maintainer"]
"properties": {
"module_name": {"$ref": "qmk.definitions.v1#/text_identifier"},
"maintainer": {"$ref": "qmk.definitions.v1#/text_identifier"},
"url": {
"type": "string",
"format": "uri"
},
"keycodes": {"$ref": "qmk.definitions.v1#/keycode_decl_array"},
"features": {"$ref": "qmk.keyboard.v1#/definitions/features_config"},
}
}
17 changes: 12 additions & 5 deletions data/schemas/keyboard.jsonschema
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@
"pins": {"$ref": "qmk.definitions.v1#/mcu_pin_array"}
}
}
"features_config": {
"$ref": "qmk.definitions.v1#/boolean_array",
"propertyNames": {"$ref": "qmk.definitions.v1#/snake_case"},
"not": {"required": ["lto"]}
},
},
"type": "object",
"not": {"required": ["vendorId", "productId"]}, // reject via keys...
Expand Down Expand Up @@ -328,11 +333,7 @@
"enabled": {"type": "boolean"}
}
},
"features": {
"$ref": "qmk.definitions.v1#/boolean_array",
"propertyNames": {"$ref": "qmk.definitions.v1#/snake_case"},
"not": {"required": ["lto"]}
},
"features": { "$ref": "#/definitions/features_config" },
"indicators": {
"type": "object",
"properties": {
Expand Down Expand Up @@ -467,6 +468,12 @@
"rows": {"$ref": "qmk.definitions.v1#/mcu_pin_array"}
}
},
"modules": {
"type": "array",
"items": {
"type": "string"
}
},
"mouse_key": {
"type": "object",
"properties": {
Expand Down
6 changes: 6 additions & 0 deletions data/schemas/keymap.jsonschema
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@
"config": {"$ref": "qmk.keyboard.v1"},
"notes": {
"type": "string"
},
"modules": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
1 change: 1 addition & 0 deletions docs/_sidebar.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"items": [
{ "text": "Customizing Functionality", "link": "/custom_quantum_functions" },
{ "text": "Driver Installation with Zadig", "link": "/driver_installation_zadig" },
{ "text": "Community Modules", "link": "/features/community_modules" },
{ "text": "Keymap Overview", "link": "/keymap" },
{
"text": "Development Environments",
Expand Down
11 changes: 9 additions & 2 deletions docs/custom_quantum_functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,19 @@ This page does not assume any special knowledge about QMK, but reading [Understa
We have structured QMK as a hierarchy:

* Core (`_quantum`)
* Community Module (`_<module>`)
* Community Module -> Keyboard/Revision (`_<module>_kb`)
* Community Module -> Keymap (`_<module>_user`)
* Keyboard/Revision (`_kb`)
* Keymap (`_user`)

Each of the functions described below can be defined with a `_kb()` suffix or a `_user()` suffix. We intend for you to use the `_kb()` suffix at the Keyboard/Revision level, while the `_user()` suffix should be used at the Keymap level.

When defining functions at the Keyboard/Revision level it is important that your `_kb()` implementation call `_user()` before executing anything else- otherwise the keymap level function will never be called.
When defining functions at the Keyboard/Revision level it is important that your `_kb()` implementation call `_user()` at an appropriate location, otherwise the keymap level function will never be called.

Functions at the `_<module>_xxx()` level are intended to allow keyboards or keymaps to override or enhance the processing associated with a [community module](/features/community_modules).

When defining module overrides such as `process_record_<module>()`, the same pattern should be used; the module must invoke `process_record_<module>_kb()` as appropriate.

# Custom Keycodes

Expand Down Expand Up @@ -99,7 +106,7 @@ These are the three main initialization functions, listed in the order that they
* `keyboard_post_init_*` - Happens at the end of the firmware's startup process. This is where you'd want to put "customization" code, for the most part.

::: warning
For most people, the `keyboard_post_init_user` function is what you want to call. For instance, this is where you want to set up things for RGB Underglow.
For most people, the `keyboard_post_init_user` function is what you want to implement. For instance, this is where you want to set up things for RGB Underglow.
:::

## Keyboard Pre Initialization code
Expand Down
Loading

0 comments on commit 1efc824

Please sign in to comment.