macOS: A couple input regressions from 7121 (#7132)
Fixes #7131 See individual commit messages. I'm running them through the same tests as #7121 to verify manually that behavior.pull/7127/head
commit
6a876ef8ec
|
|
@ -6,7 +6,13 @@ extension NSEvent {
|
||||||
///
|
///
|
||||||
/// This will not set the "text" or "composing" fields since these can't safely be set
|
/// This will not set the "text" or "composing" fields since these can't safely be set
|
||||||
/// with the information or lifetimes given.
|
/// with the information or lifetimes given.
|
||||||
func ghosttyKeyEvent(_ action: ghostty_input_action_e) -> ghostty_input_key_s {
|
///
|
||||||
|
/// The translationMods should be set to the modifiers used for actual character
|
||||||
|
/// translation if available.
|
||||||
|
func ghosttyKeyEvent(
|
||||||
|
_ action: ghostty_input_action_e,
|
||||||
|
translationMods: NSEvent.ModifierFlags? = nil
|
||||||
|
) -> ghostty_input_key_s {
|
||||||
var key_ev: ghostty_input_key_s = .init()
|
var key_ev: ghostty_input_key_s = .init()
|
||||||
key_ev.action = action
|
key_ev.action = action
|
||||||
key_ev.keycode = UInt32(keyCode)
|
key_ev.keycode = UInt32(keyCode)
|
||||||
|
|
@ -22,15 +28,19 @@ extension NSEvent {
|
||||||
// so far: control and command never contribute to the translation of text,
|
// so far: control and command never contribute to the translation of text,
|
||||||
// assume everything else did.
|
// assume everything else did.
|
||||||
key_ev.mods = Ghostty.ghosttyMods(modifierFlags)
|
key_ev.mods = Ghostty.ghosttyMods(modifierFlags)
|
||||||
key_ev.consumed_mods = Ghostty.ghosttyMods(modifierFlags.subtracting([.control, .command]))
|
key_ev.consumed_mods = Ghostty.ghosttyMods(
|
||||||
|
(translationMods ?? modifierFlags)
|
||||||
|
.subtracting([.control, .command]))
|
||||||
|
|
||||||
// Our unshifted codepoint is the codepoint with no modifiers. We
|
// Our unshifted codepoint is the codepoint with no modifiers. We
|
||||||
// ignore multi-codepoint values.
|
// ignore multi-codepoint values.
|
||||||
key_ev.unshifted_codepoint = 0
|
key_ev.unshifted_codepoint = 0
|
||||||
if let charactersIgnoringModifiers,
|
if type == .keyDown || type == .keyUp {
|
||||||
let codepoint = charactersIgnoringModifiers.unicodeScalars.first
|
if let charactersIgnoringModifiers,
|
||||||
{
|
let codepoint = charactersIgnoringModifiers.unicodeScalars.first
|
||||||
key_ev.unshifted_codepoint = codepoint.value
|
{
|
||||||
|
key_ev.unshifted_codepoint = codepoint.value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return key_ev
|
return key_ev
|
||||||
|
|
|
||||||
|
|
@ -961,13 +961,19 @@ extension Ghostty {
|
||||||
// These never have "composing" set to true because these are the
|
// These never have "composing" set to true because these are the
|
||||||
// result of a composition.
|
// result of a composition.
|
||||||
for text in list {
|
for text in list {
|
||||||
_ = keyAction(action, event: translationEvent, text: text)
|
_ = keyAction(
|
||||||
|
action,
|
||||||
|
event: event,
|
||||||
|
translationEvent: translationEvent,
|
||||||
|
text: text
|
||||||
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// We have no accumulated text so this is a normal key event.
|
// We have no accumulated text so this is a normal key event.
|
||||||
_ = keyAction(
|
_ = keyAction(
|
||||||
action,
|
action,
|
||||||
event: translationEvent,
|
event: event,
|
||||||
|
translationEvent: translationEvent,
|
||||||
text: translationEvent.ghosttyCharacters,
|
text: translationEvent.ghosttyCharacters,
|
||||||
composing: markedText.length > 0
|
composing: markedText.length > 0
|
||||||
)
|
)
|
||||||
|
|
@ -1040,16 +1046,6 @@ extension Ghostty {
|
||||||
|
|
||||||
let equivalent: String
|
let equivalent: String
|
||||||
switch (event.charactersIgnoringModifiers) {
|
switch (event.charactersIgnoringModifiers) {
|
||||||
case "/":
|
|
||||||
// Treat C-/ as C-_. We do this because C-/ makes macOS make a beep
|
|
||||||
// sound and we don't like the beep sound.
|
|
||||||
if (!event.modifierFlags.contains(.control) ||
|
|
||||||
!event.modifierFlags.isDisjoint(with: [.shift, .command, .option])) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
equivalent = "_"
|
|
||||||
|
|
||||||
case "\r":
|
case "\r":
|
||||||
// Pass C-<return> through verbatim
|
// Pass C-<return> through verbatim
|
||||||
// (prevent the default context menu equivalent)
|
// (prevent the default context menu equivalent)
|
||||||
|
|
@ -1165,12 +1161,13 @@ extension Ghostty {
|
||||||
private func keyAction(
|
private func keyAction(
|
||||||
_ action: ghostty_input_action_e,
|
_ action: ghostty_input_action_e,
|
||||||
event: NSEvent,
|
event: NSEvent,
|
||||||
|
translationEvent: NSEvent? = nil,
|
||||||
text: String? = nil,
|
text: String? = nil,
|
||||||
composing: Bool = false
|
composing: Bool = false
|
||||||
) -> Bool {
|
) -> Bool {
|
||||||
guard let surface = self.surface else { return false }
|
guard let surface = self.surface else { return false }
|
||||||
|
|
||||||
var key_ev = event.ghosttyKeyEvent(action)
|
var key_ev = event.ghosttyKeyEvent(action, translationMods: translationEvent?.modifierFlags)
|
||||||
key_ev.composing = composing
|
key_ev.composing = composing
|
||||||
if let text {
|
if let text {
|
||||||
return text.withCString { ptr in
|
return text.withCString { ptr in
|
||||||
|
|
|
||||||
|
|
@ -150,21 +150,25 @@ pub const Mods = packed struct(Mods.Backing) {
|
||||||
/// like macos-option-as-alt. The translation mods should be used for
|
/// like macos-option-as-alt. The translation mods should be used for
|
||||||
/// translation but never sent back in for the key callback.
|
/// translation but never sent back in for the key callback.
|
||||||
pub fn translation(self: Mods, option_as_alt: config.OptionAsAlt) Mods {
|
pub fn translation(self: Mods, option_as_alt: config.OptionAsAlt) Mods {
|
||||||
// We currently only process macos-option-as-alt so other
|
var result = self;
|
||||||
// platforms don't need to do anything.
|
|
||||||
if (comptime !builtin.target.os.tag.isDarwin()) return self;
|
|
||||||
|
|
||||||
// Alt has to be set only on the correct side
|
// Control is never used for translation.
|
||||||
switch (option_as_alt) {
|
result.ctrl = false;
|
||||||
.false => return self,
|
|
||||||
.true => {},
|
// macos-option-as-alt for darwin
|
||||||
.left => if (self.sides.alt == .right) return self,
|
if (comptime builtin.target.os.tag.isDarwin()) alt: {
|
||||||
.right => if (self.sides.alt == .left) return self,
|
// Alt has to be set only on the correct side
|
||||||
|
switch (option_as_alt) {
|
||||||
|
.false => break :alt,
|
||||||
|
.true => {},
|
||||||
|
.left => if (self.sides.alt == .right) break :alt,
|
||||||
|
.right => if (self.sides.alt == .left) break :alt,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unset alt
|
||||||
|
result.alt = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unset alt
|
|
||||||
var result = self;
|
|
||||||
result.alt = false;
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -186,6 +190,14 @@ pub const Mods = packed struct(Mods.Backing) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "translation removes control" {
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
const mods: Mods = .{ .ctrl = true };
|
||||||
|
const result = mods.translation(.true);
|
||||||
|
try testing.expectEqual(Mods{}, result);
|
||||||
|
}
|
||||||
|
|
||||||
test "translation macos-option-as-alt" {
|
test "translation macos-option-as-alt" {
|
||||||
if (comptime !builtin.target.os.tag.isDarwin()) return error.SkipZigTest;
|
if (comptime !builtin.target.os.tag.isDarwin()) return error.SkipZigTest;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue