-
Notifications
You must be signed in to change notification settings - Fork 495
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!: Option key as meta configuration #2486
Conversation
Here we re-implement support for option-as-meta by using the winit API: window.set_option_as_alt(oa) ...where oa is of type winit::platform::macos::OptionAsAlt. By relying on the winit API this way, we are now able to map only the left, only the right, or both of the two physical 'option' keys to the virtual key 'meta', which leaves the other 'option' key free so that it can be used to access the additional two layers of the input source. (E.g. with the u.s. english input source, option-c produces "ç" and option-shift-c produces "Ç".) This is done by setting the nvim variable: vim.g.neovide_input_macos_option_key_is_meta Possible values (defined by init::platform::macos::OptionAsAlt) are: "Both" "OnlyLeft" "OnlyRight" "None" The preëxisting variable vim.g.neovide_input_macos_alt_is_meta can still be used, and if true, it will internally result in the use of OptionAsAlt::Both. Separately, this commit fixes an issue where, in the event of a key-press like option-shift-command-y (with vim.g.neovide_input_macos_alt_is_meta set to true), neovide would produce the string "<M-S-D-y>" instead of "<M-D-Y>" because the `option` key was down, and format_normal_key() took this to imply that the key is "special" (i.e. in the same category as escape, return, F1, etc. as opposed to the category of printable characters), which led format_modifier_string() to include "S-" in its output. Also, in format_modifier_string(), the test for whether 'meta' is pressed has been simplified.
i think i nuked his stuff, it was just too hard to resolve that without just starting over ... if i get this working i will try to attempt again because then i will know what to change, and ill keep his stuff |
Yes, I think you should be able to keep most of the stuff in the Keyboard manager, but the rest probably needs to be rewritten anyway |
@fredizzimo so we are killing the entire old setting right? it seems like a lot of this window_wrapper code is trying to map old settings etc, but if we just make it a breaking change i assume all of this is a lot simpler |
so.... that is my first attempt. i really have no idea what a lot of this code was but i basically took a bunch of critical thinking guesses... my test case (pasted below) i wrote in the original issue, i notice the Option (right) + c produces Now i have to go test the different edge cases, test all settings values, etc. Can you see if I made any blindingly stupid mistakes? I left a lot of code out that seemed to not be needed anymore. Btw the test here did not work however...
So maybe this is a different problem unrelated to the issue, as i can definitely tell the meta key left/right IS working
|
@9mm, the general approach looks fine.
Ideally, we would want that the old setting continues to work or do nothing and give a warning about deprecation. But if it's too much work, we can add it as a breaking change in the release notes, and maybe add a sticky issue.
Do you mean that pressing |
I take that back, it actually did work. i think i had the config wrong also, i dont think its necessarily hard to keep the old option, but how do we manage that in the settings? i suppose it seems weird to keep old settings floating around as opposed to just putting breaking change info on the release notes as it seems like it's not a "hard" breaking change to fix, but this is my uneducated 2 cents |
specifically im referring to the key name in the struct. like we would have 2 keys for 2 different option settings |
src/window/keyboard_manager.rs
Outdated
|
||
#[cfg(not(target_os = "macos"))] | ||
{ | ||
self.meta_is_pressed = self.modifiers.state().alt_key(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This confuses me a bit, since no one calls the alt key meta anymore. More typically the windows key is called meta.
But I guess in this context it's ok, since Vim(Neovim) also refers to it as meta.
For the old value, in the code we should only ever use the new values, but at the parsing stage, we can support the old setting, and convert it to We can then show a warning using this system: Lines 18 to 37 in fcf5e87
But support for warnings need to be added, instead of just errors. |
ooooh great idea. ok I can do that |
Note to self of things to fix:
|
So one area I havent really learned about yet in rust is serde/serialization/deserialization. how would you handle this part?
It looks like its returning #[cfg(target_os = "macos")]
impl ParseFromValue for OptionAsMeta {
fn parse_from_value(&mut self, value: Value) {
let s = value.as_str().unwrap();
match OptionAsAlt::deserialize(s.into_deserializer()) as Result<OptionAsAlt, value::Error> {
Ok(oa) => *self = OptionAsMeta(oa),
Err(e) => error!("Setting neovide_input_macos_option_key_is_meta expected one of OnlyLeft, OnlyRight, Both, or None, but received {:?}: {:?}", e, value),
};
}
} I notice even if something is specified in the config, it comes back |
Ah, it seems the first time it does include extra quotes the first time 🤔 ill have to look at what this as_str is doing
|
That seems like something that would have to be fixed in Winit, their code looks like this You can try by defining your own enum type, and add the correct attributes, that also allows you to rename all values to neovide/src/settings/config.rs Line 37 in fcf5e87
You then need to convert that enum to the winit one, but that should be easy with a simple match statement. |
rust is intense lol I got a lot of what you just said done, however... I suppose the same problem exists. I dont fully understand why initially it passes a string with extra quotes, and then it passes a standard string. I do see that its properly doing kebab case... sort of.......
This is what the output is for my |
Oh nevermind...... i see, the expected values they actually set in the config are now properly kebab case as well. duh the question is still however... why is it double quoted the first time and not the other time... hmm
|
For the record I know I can use Is this expected behavior that |
It should not, but did you try to rename the None option yourself, above it |
Ok, all flags are removed. Everything works great... There's only one final issue... Right now I have a simple deprecation warning for the old setting via a This is only a warning though, it doesn't attempt to set the #[cfg(target_os = "macos")]
WindowSettingsChanged::InputMacosOptionKeyIsMeta(option) => {
self.set_macos_option_as_meta(option);
}
#[cfg(target_os = "macos")]
WindowSettingsChanged::InputMacosAltIsMeta(enabled) => {
if enabled {
error_msg!(concat!(
"neovide_input_macos_alt_is_meta has now been deprecated. ",
"Use neovide_input_macos_option_key_is_meta instead. ",
"Please check https://neovide.dev/configuration.html#macos-option-key-is-meta for more information.",
));
}
} IF I were to attempt to set I've actually re-typed this about 50 times and there's really no simple way to explain it... maybe it would be better to simply just ask, how would you do it? I need to basically update 2 things....
And both of these needs to stay in sync, if i were to do this legacy setting. The tricky bit is that 1) can be set for default events even if that setting isnt even in their config, so it creates race conditions, and even if i do use a flag, that flag must be kept in sync with 2) which doesnt look at flags at all, it just looks at the WindowSettings value |
The message is an error, not a warning, right? In that case I think it's fine to not do anything, it clearly tells what to do and if things don't work the users can blame themselves for not reading the message. So, it should be fine as it is. |
We just need to change |
Ok cool. it is an sorry for all the tons of noise on this... I just dont want to add junk to this amazing repo, and this tbh is my first time writing actual rust 💀 |
Ah beat me to it |
I did not fix the macOS Clippy warnings in my PR, so do you think you can do it here? I think the |
definitely, I was actually going to fix that stuff but stopped in case they were there for a reason haha. |
I actually don't see any code that would fix this bug:
As far as I can see the condition for Can you test that without these changes? |
Heres the most recent result of testing this PR. I copied the test cases I did above but just re-ran through them all again. LMK if this works. I am not sure the issue with shift, but heres the results:
Option (right) + c produces Meta (left) + Command + y produces Command + Meta (left option) + x = Command + Meta (left option) + Shift + x = |
Ah it's probably this change: #[cfg(target_os = "macos")]
if self.meta_is_pressed {
return key_event
.key_without_modifiers()
.to_text()
.map(|text| self.format_key_text(text, false));
} And yes, those results look correct. If you just can verify that |
Don't worry about those other clippy warnings, we will make sure to merge this first. |
Ah ok, I will revert those last 2 and i will test main quick |
I tested main. Assuming what you wrote is a typo and you meant the following, then this is what occurs on main: Meta (left) + Command + Shift + y = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great! Thank you, everything looks good now.
awesome!! Thank you for all your help |
updating #2046