@@ -14,15 +14,22 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
1414#include <zmk/event_manager.h>
1515#include <zmk/events/ble_active_profile_changed.h>
1616#include <zmk/events/endpoint_changed.h>
17+ #include <zmk/events/preferred_transport_changed.h>
1718#include <zmk/usb.h>
1819#include <zmk/ble.h>
1920#include <zmk/endpoints.h>
2021
22+ static const char TRANSPORT_SYMBOL_NONE [] = LV_SYMBOL_CLOSE ;
23+ static const char TRANSPORT_SYMBOL_BLE [] = LV_SYMBOL_WIFI ;
24+ static const char TRANSPORT_SYMBOL_USB [] = LV_SYMBOL_USB ;
25+ static const char TRANSPORT_SYMBOL_UNKNOWN [] = "?" ;
26+
2127static sys_slist_t widgets = SYS_SLIST_STATIC_INIT (& widgets );
2228
2329struct output_status_state {
2430 struct zmk_endpoint_instance selected_endpoint ;
2531 enum zmk_transport preferred_transport ;
32+ int active_profile_index ;
2633 bool active_profile_connected ;
2734 bool active_profile_bonded ;
2835};
@@ -31,48 +38,67 @@ static struct output_status_state get_state(const zmk_event_t *_eh) {
3138 return (struct output_status_state ){
3239 .selected_endpoint = zmk_endpoint_get_selected (),
3340 .preferred_transport = zmk_endpoint_get_preferred_transport (),
41+ .active_profile_index = zmk_ble_active_profile_index (),
3442 .active_profile_connected = zmk_ble_active_profile_is_connected (),
3543 .active_profile_bonded = !zmk_ble_active_profile_is_open (),
3644 };
3745}
3846
47+ static const char * symbol_for_transport (enum zmk_transport transport ) {
48+ switch (transport ) {
49+ case ZMK_TRANSPORT_NONE :
50+ return TRANSPORT_SYMBOL_NONE ;
51+ case ZMK_TRANSPORT_BLE :
52+ return TRANSPORT_SYMBOL_BLE ;
53+ case ZMK_TRANSPORT_USB :
54+ return TRANSPORT_SYMBOL_USB ;
55+ default :
56+ return TRANSPORT_SYMBOL_UNKNOWN ;
57+ }
58+ }
59+
3960static void set_status_symbol (lv_obj_t * label , struct output_status_state state ) {
4061 char text [20 ] = {};
4162
4263 enum zmk_transport transport = state .selected_endpoint .transport ;
43- bool connected = transport != ZMK_TRANSPORT_NONE ;
64+ const char * transport_symbol = symbol_for_transport ( transport ) ;
4465
45- // If we aren't connected, show what we're *trying* to connect to.
46- if (!connected ) {
47- transport = state .preferred_transport ;
48- }
49-
50- switch (transport ) {
51- case ZMK_TRANSPORT_NONE :
52- strcat (text , LV_SYMBOL_CLOSE );
53- break ;
66+ bool connected = transport != ZMK_TRANSPORT_NONE ;
5467
55- case ZMK_TRANSPORT_USB :
56- strcat (text , LV_SYMBOL_USB );
57- if (!connected ) {
58- strcat (text , " " LV_SYMBOL_CLOSE );
68+ // If we are ble is connected or the preferred_transport show the active profile status
69+ // This allows you to navigate through the active ble profiles, even when they are unable
70+ // to be connected to.
71+ if (transport == ZMK_TRANSPORT_BLE || state .preferred_transport == ZMK_TRANSPORT_BLE ) {
72+ const char * active_profile_status = "?" ;
73+
74+ // When the preferred transport if ble but it is disconneted, the state is represented
75+ // by the active_profile_status, just display the ble symbol. This is like this
76+ // so it will display the active transport (eg. usb) when we are connected to it
77+ // but still keep displaying the ble profile.
78+ if (transport == ZMK_TRANSPORT_NONE ) {
79+ transport_symbol = TRANSPORT_SYMBOL_BLE ;
5980 }
60- break ;
6181
62- case ZMK_TRANSPORT_BLE :
6382 if (state .active_profile_bonded ) {
6483 if (state .active_profile_connected ) {
65- snprintf (text , sizeof (text ), LV_SYMBOL_WIFI " %i " LV_SYMBOL_OK ,
66- state .selected_endpoint .ble .profile_index + 1 );
84+ active_profile_status = LV_SYMBOL_OK ;
6785 } else {
68- snprintf (text , sizeof (text ), LV_SYMBOL_WIFI " %i " LV_SYMBOL_CLOSE ,
69- state .selected_endpoint .ble .profile_index + 1 );
86+ active_profile_status = LV_SYMBOL_CLOSE ;
7087 }
7188 } else {
72- snprintf (text , sizeof (text ), LV_SYMBOL_WIFI " %i " LV_SYMBOL_SETTINGS ,
73- state .selected_endpoint .ble .profile_index + 1 );
89+ active_profile_status = LV_SYMBOL_SETTINGS ;
7490 }
75- break ;
91+
92+ snprintf (text , sizeof (text ), "%s %i %s" , transport_symbol , state .active_profile_index + 1 ,
93+ active_profile_status );
94+
95+ } else if (!connected && state .preferred_transport != ZMK_TRANSPORT_NONE ) {
96+ // When we are not connected but have a preferred transport
97+ // indicate that we are disconnected from it.
98+ snprintf (text , sizeof (text ), "%s " LV_SYMBOL_CLOSE ,
99+ symbol_for_transport (state .preferred_transport ));
100+ } else {
101+ strcat (text , transport_symbol );
76102 }
77103
78104 lv_label_set_text (label , text );
@@ -86,6 +112,7 @@ static void output_status_update_cb(struct output_status_state state) {
86112ZMK_DISPLAY_WIDGET_LISTENER (widget_output_status , struct output_status_state ,
87113 output_status_update_cb , get_state )
88114ZMK_SUBSCRIPTION (widget_output_status , zmk_endpoint_changed );
115+ ZMK_SUBSCRIPTION (widget_output_status , zmk_preferred_transport_changed );
89116// We don't get an endpoint changed event when the active profile connects/disconnects
90117// but there wasn't another endpoint to switch from/to, so update on BLE events too.
91118#if defined(CONFIG_ZMK_BLE )
0 commit comments