Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: default layer setter #2222

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

elpekenin
Copy link
Contributor

I plan to do a PR to persistently change the default layer, for multi-layout uses (eg win/mac or qwerty/dvorak)

However, while activating the layer or to'ing into it is similar, it wouldn't mimic the behavior of default layer. Thus, the follow-up PR needs an API of this kind.

Notes:

  • New event for default layer changes?
  • I dont quite like the function's name and log texts, ideas are welcome.

@elpekenin elpekenin requested a review from a team as a code owner March 23, 2024 11:29
Copy link
Contributor

@huber-th huber-th left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Being able to set the default layer on startup would be wonderful for multi layout configurations.

app/src/keymap.c Outdated Show resolved Hide resolved
app/src/keymap.c Outdated Show resolved Hide resolved
@huber-th
Copy link
Contributor

huber-th commented Mar 23, 2024

If I may add an idea to be considered in your follow up PR. Might be worth to consider being able to trigger automatic layout changes on BLE profile change.

Not sure how this would be best made configurable (maybe via KConfig?, Could ZMK remember default layer per profile?), but it would be convenient if someone with Windows and macOS system for example, could configure a default layer for each BLE profile and one for USB to automatically trigger a default layer change depending on which profile is activated.

@huber-th
Copy link
Contributor

I acknowledge the potential advantage of the planned behavior for users with dual systems, but after thinking about it a bit more I'm wondering whether this proposed change should be directly integrated into the feature's implementation itself rather than as its separate PR.

@caksoylar caksoylar added core Core functionality/behavior of ZMK behaviors labels Mar 25, 2024
@elpekenin
Copy link
Contributor Author

elpekenin commented Mar 25, 2024

I dont mind either way, the idea of making a small PR was to start rolling it and see if it had missed a small edge case or whatever.

Also making two different PRs with the respective self-contained logic seemed better review-wise.

I already have the code (or at least, its first revision) written & slightly tested it (with to instead of setting default layer at ZMK level). So, if collabs think it is better to keep everything together just let me know and i will push it on this branch too

@huber-th
Copy link
Contributor

huber-th commented Apr 4, 2024

I dont mind either way, the idea of making a small PR was to start rolling it and see if it had missed a small edge case or whatever.

Also making two different PRs with the respective self-contained logic seemed better review-wise.

Sorry, I have been quite busy lately. Personally, I would recommend adding everything related to this feature in one PR so when it's merged it adds the full feature.

I tested your code from your personal repo and I would recommend to incorporate it into this PR for full review/testing of the complete feature.

@elpekenin
Copy link
Contributor Author

Aight, will do.

Again, my main idea was go test if default layer setting really worked well before relying on it for the behavior, for easier debug when (if) edge cases poped up.

Will add it to make the process faster and keep it together. Glad to hear the current implementation (layer toggle instead of default layer, which is worse) is working fine for you

Copy link
Contributor

@petejohanson petejohanson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One major concern regarding the usage of the endpoints API. Thanks for the PR!

Comment on lines 23 to 26
struct default_layer_settings_t {
uint8_t usb[ZMK_ENDPOINT_USB_COUNT];
uint8_t ble[ZMK_ENDPOINT_BLE_COUNT];
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is too tied to the details of the transports, IMHO. You should be more agnostic, e.g.

Suggested change
struct default_layer_settings_t {
uint8_t usb[ZMK_ENDPOINT_USB_COUNT];
uint8_t ble[ZMK_ENDPOINT_BLE_COUNT];
};
struct default_layer_settings_t {
uint8_t endpoint_defaults[ZMK_ENDPOINT_COUNT];
};

And then code that needs to set/load the setting would simply call zmk_endpoint_instance_to_index to determine which setting to pull out of that array consistently.

The advantage here, whenever we do eventually support some other new transport (e.g. some custom 2.4Ghz protocol, or maybe HID over i2c), this code will adjust automatically.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what i get for not looking closely at the codebase, i ended up reinventing the wheel 😝

Im still a bit worried about issues when user has old settings stored (eg move layers around and whatnot).
Any ideas that could help with that? Imho code shouldn't worry too much about those scenarios and let the user be the one in charge of deteting/fixing. But if there is some easy/robust idea, i can sure add it.

If nothing gets added i will add some warn messge in docs as in "beware the stored settings might break when you tweak the keymap"

Copy link
Contributor

@caksoylar caksoylar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two other docs pieces need updating in addition to below comments:

break;
}

int ret = settings_save_one("default_layer/settings", &default_layers, sizeof(default_layers));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to apply debouncing here like most other settings that save to flash?


## Default Layer

The default layer behavior allows configuring a different default layer, for example to test DVORAK while keeping QWERTY on another layer, or moving a couple keycodes around for Windows/Mac usage.
Copy link
Contributor

@caksoylar caksoylar Apr 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like this needs a little more information on the default layer concept, since it wasn't modifiable from 0 until this. I'd at least note here that the default (default) layer is the first defined one, that it cannot be changed or deactivated by other behaviors in this section.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On this note, I've used the default layer concept differently on the ROTR to have an encoder scroll in a momentary layer change the layer you return to when that momentary layer is released, skipping layers tagged to be momentary only. I think there's reasoning behind an endpoint agnostic default layer mechanism too, perhaps a pair of bool props in the behaviour to choose whether it respects endpoints and saves to flash?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the docs check, will get them updated tomorrow.

As per the delayed writing, Im not sure whether it is needed. Based on my understanding of Zephyr's docs, it only triggers a write if the value has changed (eg: differs from what the flash contains already).

If that is correct, I dont think an inmediate write is bad (wearing down memory - wise) but for sure is in terms of consistency with codebase, will update too.

@Nick-Munnich
Copy link
Contributor

#1500 seems like it could be relevant here and hasn't been mentioned yet, just dropping a link.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
behaviors core Core functionality/behavior of ZMK
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants