-
Notifications
You must be signed in to change notification settings - Fork 690
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
macOS: "option-as-alt" defaults to "true" for US keyboard layouts (#2930
) A common issue for US-centric users of a terminal is that the "option" key on macOS is not treated as the "alt" key in the terminal. ## Background macOS does not have an "alt" key, but instead has an "option" key. The "option" key is used for a variety of purposes, but the troublesome behavior for some (and expected/desired behavior for others) is that it is used to input special characters. For example, on a US standard layout, `option-b` inputs `∫`. This is not a typically desired character when using a terminal and most users will instead expect that `option-b` maps to `alt-b` for keybinding purposes with whatever shell, TUI, editor, etc. they're using. On non-US layouts, the "option" key is a critical modifier key for inputting certain characters in the same way "shift" is a critical modifier key for inputting certain characters on US layouts. We previously tried to change the default for `macos-option-as-alt` to `left` (so that the left option key behaves as alt) because I had the wrong assumption that international users always used the right option key with terminals or were used to this. But very quickly beta users with different layouts (such as German, I believe) noted that this is not the case and broke their idiomatic input behavior. This behavior was therefore reverted. ## Solution This confusing behavior happened frequently enough that I decided to implement the more complex behavior in this commit. The new behavior is that when a US layout is active, `macos-option-as-alt` defaults to true if it is unset. When a non-US layout is active, `macos-option-as-alt` defaults to false if it is unset. This happens live as users change their keyboard layout. **An important goal of Ghostty is to have zero-config defaults** that satisfy the majority of users. Fiddling with configurations is -- for most -- an annoying task and software that works well enough out of the box is delightful. Based on surveying beta users, I believe this commit will result in less configuration for the majority of users. ## Other Terminals This behavior is unique amongst terminals as far as I know. Terminal.app, Kitty, iTerm2, Alacritty (I stopped checking there) all default to the default macOS behavior (option is option and special characters are inputted). All of the aforementioned terminals have a setting to change this behavior, identical to Ghostty (or, Ghostty identical to them perhaps since they all predate Ghostty). I couldn't find any history where users requested the behavior of defaulting this to something else for US based keyboards. That's interesting since this has come up so frequently during the Ghostty beta!
- Loading branch information
Showing
7 changed files
with
166 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
const std = @import("std"); | ||
const OptionAsAlt = @import("../config.zig").OptionAsAlt; | ||
|
||
/// Keyboard layouts. | ||
/// | ||
/// These aren't heavily used in Ghostty and having a fully comprehensive | ||
/// list is not important. We only need to distinguish between a few | ||
/// different layouts for some nice-to-have features, such as setting a default | ||
/// value for "macos-option-as-alt". | ||
pub const Layout = enum { | ||
// Unknown, unmapped layout. Ghostty should not make any assumptions | ||
// about the layout of the keyboard. | ||
unknown, | ||
|
||
// The remaining should be fairly self-explanatory: | ||
us_standard, | ||
us_international, | ||
|
||
/// Map an Apple keyboard layout ID to a value in this enum. The layout | ||
/// ID can be retrieved using Carbon's TIKeyboardLayoutGetInputSourceProperty | ||
/// function. | ||
/// | ||
/// Even though our layout supports "unknown", we return null if we don't | ||
/// recognize the layout ID so callers can detect this scenario. | ||
pub fn mapAppleId(id: []const u8) ?Layout { | ||
if (std.mem.eql(u8, id, "com.apple.keylayout.US")) { | ||
return .us_standard; | ||
} else if (std.mem.eql(u8, id, "com.apple.keylayout.USInternational")) { | ||
return .us_international; | ||
} | ||
|
||
return null; | ||
} | ||
|
||
/// Returns the default macos-option-as-alt value for this layout. | ||
/// | ||
/// We apply some heuristics to change the default based on the keyboard | ||
/// layout if "macos-option-as-alt" is unset. We do this because on some | ||
/// keyboard layouts such as US standard layouts, users generally expect | ||
/// an input such as option-b to map to alt-b but macOS by default will | ||
/// convert it to the codepoint "∫". | ||
/// | ||
/// This behavior however is desired on international layout where the | ||
/// option key is used for important, regularly used inputs. | ||
pub fn detectOptionAsAlt(self: Layout) OptionAsAlt { | ||
return switch (self) { | ||
// On US standard, the option key is typically used as alt | ||
// and not as a modifier for other codepoints. For example, | ||
// option-B = ∫ but usually the user wants alt-B. | ||
.us_standard, | ||
.us_international, | ||
=> .true, | ||
|
||
.unknown, | ||
=> .false, | ||
}; | ||
} | ||
}; |