Last device behavior
This commit is contained in:
parent
b276a3bfb0
commit
b043f2ad15
15 changed files with 197 additions and 0 deletions
2
.github/workflows/build-user-config.yml
vendored
2
.github/workflows/build-user-config.yml
vendored
|
@ -18,6 +18,8 @@ on:
|
|||
default: "bin"
|
||||
required: false
|
||||
type: string
|
||||
artifact_name:
|
||||
description: "Artifact output file name"
|
||||
archive_name:
|
||||
description: "Archive output file name"
|
||||
default: "firmware"
|
||||
|
|
|
@ -47,6 +47,8 @@ if ((NOT CONFIG_ZMK_SPLIT) OR CONFIG_ZMK_SPLIT_ROLE_CENTRAL)
|
|||
target_sources(app PRIVATE src/behaviors/behavior_momentary_layer.c)
|
||||
target_sources(app PRIVATE src/behaviors/behavior_mod_morph.c)
|
||||
target_sources(app PRIVATE src/behaviors/behavior_outputs.c)
|
||||
target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_LAST_DEVICE app PRIVATE src/behaviors/behavior_last_device.c)
|
||||
target_sources(app PRIVATE src/behaviors/behavior_tap_dance.c)
|
||||
target_sources(app PRIVATE src/behaviors/behavior_toggle_layer.c)
|
||||
target_sources(app PRIVATE src/behaviors/behavior_to_layer.c)
|
||||
target_sources(app PRIVATE src/behaviors/behavior_transparent.c)
|
||||
|
|
|
@ -523,6 +523,12 @@ choice CBPRINTF_IMPLEMENTATION
|
|||
|
||||
endchoice
|
||||
|
||||
DT_COMPAT_ZMK_BEHAVIOR_LAST_DEVICE := zmk,behavior-last-device
|
||||
|
||||
config ZMK_BEHAVIOR_LAST_DEVICE
|
||||
bool
|
||||
default $(dt_compat_enabled,$(DT_COMPAT_ZMK_BEHAVIOR_LAST_DEVICE))
|
||||
|
||||
module = ZMK
|
||||
module-str = zmk
|
||||
source "subsys/logging/Kconfig.template.log_config"
|
||||
|
|
29
app/drivers/zephyr/dts/bindings/gpio/microchip,mcp23017.yaml
Normal file
29
app/drivers/zephyr/dts/bindings/gpio/microchip,mcp23017.yaml
Normal file
|
@ -0,0 +1,29 @@
|
|||
#
|
||||
# Copyright (c) 2020 Geanix ApS
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
description: >
|
||||
This is a representation of the Microchip MCP23017 I2C Gpio Expander.
|
||||
|
||||
compatible: "microchip,mcp23017"
|
||||
|
||||
include: [gpio-controller.yaml, i2c-device.yaml]
|
||||
|
||||
properties:
|
||||
label:
|
||||
required: true
|
||||
|
||||
"#gpio-cells":
|
||||
const: 2
|
||||
|
||||
ngpios:
|
||||
type: int
|
||||
required: true
|
||||
const: 16
|
||||
description: Number of gpios supported
|
||||
|
||||
gpio-cells:
|
||||
- pin
|
||||
- flags
|
|
@ -15,6 +15,7 @@
|
|||
#include <behaviors/bluetooth.dtsi>
|
||||
#include <behaviors/ext_power.dtsi>
|
||||
#include <behaviors/outputs.dtsi>
|
||||
#include <behaviors/last_device.dtsi>
|
||||
#include <behaviors/caps_word.dtsi>
|
||||
#include <behaviors/key_repeat.dtsi>
|
||||
#include <behaviors/backlight.dtsi>
|
||||
|
|
17
app/dts/behaviors/last_device.dtsi
Normal file
17
app/dts/behaviors/last_device.dtsi
Normal file
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2022 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <dt-bindings/zmk/keys.h>
|
||||
|
||||
/ {
|
||||
behaviors {
|
||||
/omit-if-no-ref/ last_dev: last_device {
|
||||
compatible = "zmk,behavior-last-device";
|
||||
label = "LAST_DEVICE";
|
||||
#binding-cells = <0>;
|
||||
};
|
||||
};
|
||||
};
|
8
app/dts/bindings/behaviors/zmk,behavior-last-device.yaml
Normal file
8
app/dts/bindings/behaviors/zmk,behavior-last-device.yaml
Normal file
|
@ -0,0 +1,8 @@
|
|||
# Copyright (c) 2022 The ZMK Contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
description: Last Device Behavior
|
||||
|
||||
compatible: "zmk,behavior-last-device"
|
||||
|
||||
include: zero_param.yaml
|
|
@ -16,4 +16,5 @@ properties:
|
|||
description: The default time to wait (in milliseconds) before triggering the next behavior in the macro bindings list.
|
||||
tap-ms:
|
||||
type: int
|
||||
default: 100
|
||||
description: The default time to wait (in milliseconds) between the press and release events on a tapped macro behavior binding
|
||||
|
|
|
@ -25,8 +25,10 @@ int zmk_ble_prof_next();
|
|||
int zmk_ble_prof_prev();
|
||||
int zmk_ble_prof_select(uint8_t index);
|
||||
|
||||
int zmk_ble_last_profile_index();
|
||||
int zmk_ble_active_profile_index();
|
||||
bt_addr_le_t *zmk_ble_active_profile_addr();
|
||||
bool zmk_ble_profile_is_open(uint8_t profile);
|
||||
bool zmk_ble_active_profile_is_open();
|
||||
bool zmk_ble_active_profile_is_connected();
|
||||
char *zmk_ble_active_profile_name();
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
int zmk_endpoints_select(enum zmk_endpoint endpoint);
|
||||
int zmk_endpoints_toggle();
|
||||
enum zmk_endpoint zmk_preferred_endpoint();
|
||||
enum zmk_endpoint zmk_last_endpoint();
|
||||
enum zmk_endpoint zmk_endpoints_selected();
|
||||
|
||||
int zmk_endpoints_send_report(uint16_t usage_page);
|
||||
|
|
96
app/src/behaviors/behavior_last_device.c
Normal file
96
app/src/behaviors/behavior_last_device.c
Normal file
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Copyright (c) 2022 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <device.h>
|
||||
#include <drivers/behavior.h>
|
||||
#include <logging/log.h>
|
||||
#include <zmk/behavior.h>
|
||||
#include <zmk/ble.h>
|
||||
#include <zmk/endpoints.h>
|
||||
#include <zmk/hid.h>
|
||||
#include <dt-bindings/zmk/hid_usage_pages.h>
|
||||
#include <zmk/usb_hid.h>
|
||||
#include <zmk/hog.h>
|
||||
#include <zmk/event_manager.h>
|
||||
#include <zmk/events/ble_active_profile_changed.h>
|
||||
#include <zmk/events/usb_conn_state_changed.h>
|
||||
#include <zmk/events/endpoint_selection_changed.h>
|
||||
|
||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||
|
||||
#define DT_DRV_COMPAT zmk_behavior_last_device
|
||||
|
||||
int8_t last_device;
|
||||
bool skip_next_endpoint_change = false;
|
||||
|
||||
static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
|
||||
struct zmk_behavior_binding_event event) {
|
||||
if (last_device == -1) {
|
||||
LOG_DBG("Toggling output");
|
||||
zmk_endpoints_toggle();
|
||||
} else {
|
||||
LOG_DBG("Switching to last ble device: %d", last_device);
|
||||
zmk_ble_prof_select(last_device);
|
||||
if (zmk_endpoints_selected() == ZMK_ENDPOINT_USB) {
|
||||
LOG_DBG("Toggling output");
|
||||
zmk_endpoints_toggle();
|
||||
}
|
||||
}
|
||||
|
||||
return ZMK_BEHAVIOR_OPAQUE;
|
||||
}
|
||||
|
||||
static int behavior_last_device_init(const struct device *dev) { return 0; }
|
||||
|
||||
static const struct behavior_driver_api behavior_last_device_driver_api = {
|
||||
.binding_pressed = on_keymap_binding_pressed,
|
||||
};
|
||||
|
||||
static void update_last_device_ble_index(uint8_t profile) {
|
||||
if (!zmk_ble_profile_is_open(profile)) {
|
||||
last_device = profile;
|
||||
LOG_DBG("Last device set to %d", last_device);
|
||||
}
|
||||
};
|
||||
|
||||
static int last_device_listener(const zmk_event_t *eh) {
|
||||
if (as_zmk_endpoint_selection_changed(eh) != NULL) {
|
||||
if (zmk_preferred_endpoint() == zmk_endpoints_selected()) {
|
||||
if (!skip_next_endpoint_change) {
|
||||
if (zmk_endpoints_selected() == ZMK_ENDPOINT_USB) {
|
||||
update_last_device_ble_index(zmk_ble_active_profile_index());
|
||||
} else {
|
||||
last_device = -1;
|
||||
LOG_DBG("Last device set to %d", last_device);
|
||||
}
|
||||
} else {
|
||||
skip_next_endpoint_change = false;
|
||||
}
|
||||
} else if (zmk_endpoints_selected() == ZMK_ENDPOINT_BLE &&
|
||||
zmk_preferred_endpoint() == ZMK_ENDPOINT_USB) {
|
||||
LOG_DBG("USB disconnected");
|
||||
update_last_device_ble_index(zmk_ble_last_profile_index());
|
||||
} else {
|
||||
LOG_DBG("Skipping next endpoint change");
|
||||
skip_next_endpoint_change = true;
|
||||
}
|
||||
}
|
||||
if (as_zmk_ble_active_profile_changed(eh) != NULL &&
|
||||
zmk_endpoints_selected() == ZMK_ENDPOINT_BLE) {
|
||||
update_last_device_ble_index(zmk_ble_last_profile_index());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ZMK_LISTENER(last_device_listener, last_device_listener);
|
||||
ZMK_SUBSCRIPTION(last_device_listener, zmk_endpoint_selection_changed);
|
||||
ZMK_SUBSCRIPTION(last_device_listener, zmk_ble_active_profile_changed);
|
||||
|
||||
#define LAST_DEVICE_INST(n) \
|
||||
DEVICE_DT_INST_DEFINE(n, behavior_last_device_init, NULL, NULL, NULL, APPLICATION, \
|
||||
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_last_device_driver_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(LAST_DEVICE_INST)
|
|
@ -66,6 +66,7 @@ enum advertising_type {
|
|||
BT_GAP_ADV_FAST_INT_MAX_2, NULL)
|
||||
|
||||
static struct zmk_ble_profile profiles[ZMK_BLE_PROFILE_COUNT];
|
||||
static uint8_t last_profile;
|
||||
static uint8_t active_profile;
|
||||
|
||||
#define DEVICE_NAME CONFIG_BT_DEVICE_NAME
|
||||
|
@ -99,6 +100,10 @@ static void raise_profile_changed_event_callback(struct k_work *work) {
|
|||
|
||||
K_WORK_DEFINE(raise_profile_changed_event_work, raise_profile_changed_event_callback);
|
||||
|
||||
bool zmk_ble_profile_is_open(uint8_t profile) {
|
||||
return !bt_addr_le_cmp(&profiles[profile].peer, BT_ADDR_LE_ANY);
|
||||
}
|
||||
|
||||
bool zmk_ble_active_profile_is_open() {
|
||||
return !bt_addr_le_cmp(&profiles[active_profile].peer, BT_ADDR_LE_ANY);
|
||||
}
|
||||
|
@ -228,6 +233,7 @@ int zmk_ble_clear_bonds() {
|
|||
return 0;
|
||||
};
|
||||
|
||||
int zmk_ble_last_profile_index() { return last_profile; }
|
||||
int zmk_ble_active_profile_index() { return active_profile; }
|
||||
|
||||
#if IS_ENABLED(CONFIG_SETTINGS)
|
||||
|
@ -256,6 +262,7 @@ int zmk_ble_prof_select(uint8_t index) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
last_profile = active_profile;
|
||||
active_profile = index;
|
||||
ble_save_profile();
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
|||
#define DEFAULT_ENDPOINT \
|
||||
COND_CODE_1(IS_ENABLED(CONFIG_ZMK_BLE), (ZMK_ENDPOINT_BLE), (ZMK_ENDPOINT_USB))
|
||||
|
||||
static enum zmk_endpoint last_endpoint = DEFAULT_ENDPOINT;
|
||||
static enum zmk_endpoint current_endpoint = DEFAULT_ENDPOINT;
|
||||
static enum zmk_endpoint preferred_endpoint =
|
||||
ZMK_ENDPOINT_USB; /* Used if multiple endpoints are ready */
|
||||
|
@ -62,6 +63,8 @@ int zmk_endpoints_select(enum zmk_endpoint endpoint) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
enum zmk_endpoint zmk_last_endpoint() { return last_endpoint; }
|
||||
enum zmk_endpoint zmk_preferred_endpoint() { return preferred_endpoint; }
|
||||
enum zmk_endpoint zmk_endpoints_selected() { return current_endpoint; }
|
||||
|
||||
int zmk_endpoints_toggle() {
|
||||
|
@ -240,6 +243,7 @@ static void update_current_endpoint() {
|
|||
/* Cancel all current keypresses so keys don't stay held on the old endpoint. */
|
||||
disconnect_current_endpoint();
|
||||
|
||||
last_endpoint = current_endpoint;
|
||||
current_endpoint = new_endpoint;
|
||||
LOG_INF("Endpoint changed: %d", current_endpoint);
|
||||
|
||||
|
|
19
docs/docs/behaviors/last-device.md
Normal file
19
docs/docs/behaviors/last-device.md
Normal file
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
title: Last Device Behavior
|
||||
sidebar_label: Reset
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
The last device behavior switches to the last connected device, whether it be bluetooth or USB.
|
||||
|
||||
### Behavior Binding
|
||||
|
||||
- Reference: `&last_dev`
|
||||
- Parameters: None
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
&last_dev
|
||||
```
|
|
@ -39,6 +39,7 @@ module.exports = {
|
|||
"behaviors/reset",
|
||||
"behaviors/bluetooth",
|
||||
"behaviors/outputs",
|
||||
"behaviors/last-device",
|
||||
"behaviors/underglow",
|
||||
"behaviors/backlight",
|
||||
"behaviors/power",
|
||||
|
|
Loading…
Add table
Reference in a new issue