Last device behavior

This commit is contained in:
Nick Conway 2023-06-02 20:54:54 -04:00
parent fed2cf69da
commit d99c8403c7
No known key found for this signature in database
GPG Key ID: AA850592E4C1D453
12 changed files with 163 additions and 0 deletions

View File

@ -57,6 +57,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)

View File

@ -692,6 +692,17 @@ config ZMK_KEYMAP_SENSORS_DEFAULT_TRIGGERS_PER_ROTATION
endif # ZMK_KEYMAP_SENSORS
choice CBPRINTF_IMPLEMENTATION
default CBPRINTF_NANO
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"

View File

@ -21,6 +21,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>

View 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>;
};
};
};

View 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

View File

@ -26,6 +26,7 @@ int zmk_ble_prof_select(uint8_t index);
void zmk_ble_clear_all_bonds(void);
int zmk_ble_prof_disconnect(uint8_t index);
int zmk_ble_last_profile_index();
int zmk_ble_active_profile_index(void);
int zmk_ble_profile_index(const bt_addr_le_t *addr);
bt_addr_le_t *zmk_ble_profile_address(uint8_t index);

View File

@ -68,6 +68,8 @@ int zmk_endpoints_toggle_transport(void);
*/
struct zmk_endpoint_instance zmk_endpoints_selected(void);
struct zmk_endpoint_instance zmk_last_endpoint();
int zmk_endpoints_send_report(uint16_t usage_page);
#if IS_ENABLED(CONFIG_ZMK_POINTING)

View 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)

View File

@ -60,6 +60,7 @@ enum advertising_type {
BT_GAP_ADV_FAST_INT_MIN_2, 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
@ -252,6 +253,7 @@ void zmk_ble_clear_all_bonds(void) {
update_advertising();
};
int zmk_ble_last_profile_index() { return last_profile; }
int zmk_ble_active_profile_index(void) { return active_profile; }
int zmk_ble_profile_index(const bt_addr_le_t *addr) {
@ -296,6 +298,7 @@ int zmk_ble_prof_select(uint8_t index) {
return 0;
}
last_profile = active_profile;
active_profile = index;
ble_save_profile();

View File

@ -27,6 +27,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
COND_CODE_1(IS_ENABLED(CONFIG_ZMK_BLE), (ZMK_TRANSPORT_BLE), (ZMK_TRANSPORT_USB))
static struct zmk_endpoint_instance current_instance = {};
static struct zmk_endpoint_instance last_instance = {};
static enum zmk_transport preferred_transport =
ZMK_TRANSPORT_USB; /* Used if multiple endpoints are ready */
@ -347,6 +348,7 @@ static void update_current_endpoint(void) {
// Cancel all current keypresses so keys don't stay held on the old endpoint.
zmk_endpoints_clear_current();
last_instance = current_instance;
current_instance = new_instance;
char endpoint_str[ZMK_ENDPOINT_STR_LEN];

View 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
```

View File

@ -80,6 +80,7 @@ module.exports = {
"keymaps/behaviors/reset",
"keymaps/behaviors/bluetooth",
"keymaps/behaviors/outputs",
"keymaps/behaviors/last-device",
"keymaps/behaviors/underglow",
"keymaps/behaviors/backlight",
"keymaps/behaviors/power",