input: carbon modifier bits were not correct for some modifiers

I went and downloaded a couple different programs that use
UCKeyTranslate and dumped their values since I cannot find the header
file and then wrote a unit test to make sure we stay accurate here.
This commit is contained in:
Mitchell Hashimoto
2023-08-12 15:32:18 -07:00
parent 923df53825
commit a8426a90dd

View File

@ -106,7 +106,7 @@ pub fn translate(
} else @compileError("space code not found"); } else @compileError("space code not found");
// Convert our mods from our format to the Carbon API format // Convert our mods from our format to the Carbon API format
const modifier_state: u32 = (MacMods{ const modifier_state: u32 = (CarbonMods{
.alt = if (mods.alt) true else false, .alt = if (mods.alt) true else false,
.ctrl = if (mods.ctrl) true else false, .ctrl = if (mods.ctrl) true else false,
.meta = if (mods.super) true else false, .meta = if (mods.super) true else false,
@ -162,28 +162,31 @@ pub fn translate(
/// Map to the modifiers format used by the UCKeyTranslate function. /// Map to the modifiers format used by the UCKeyTranslate function.
/// We use a u32 here because our bit arithmetic is all u32 anyways. /// We use a u32 here because our bit arithmetic is all u32 anyways.
const MacMods = packed struct(u32) { const CarbonMods = packed struct(u32) {
_padding_start: u16 = 0, _padding_start: u8 = 0,
caps_lock: bool = false,
shift: bool = false,
ctrl: bool = false,
alt: bool = false,
meta: bool = false, meta: bool = false,
num_lock: bool = false, shift: bool = false,
help: bool = false, caps_lock: bool = false,
function: bool = false, alt: bool = false,
_padding_end: u8 = 0, ctrl: bool = false,
_padding_end: u19 = 0,
/// Translate NSEventModifierFlags into the format used by UCKeyTranslate. /// Translate NSEventModifierFlags into the format used by UCKeyTranslate.
fn ucKeyTranslate(self: MacMods) u32 { fn ucKeyTranslate(self: CarbonMods) u32 {
const int: u32 = @bitCast(self); const int: u32 = @bitCast(self);
return (int >> 16) & 0xFF; return (int >> 8) & 0xFF;
} }
comptime { // We got this from dumping the values out of another program since
// Just to be super sure // I can't find the header for this anywhere. I find various modifier
const v: u32 = @bitCast(MacMods{ .shift = true }); // headers but they do not match this! 🥺
std.debug.assert(v == 1 << 17); test "expected values" {
const testing = std.testing;
try testing.expectEqual(@as(u32, 0x100), @as(u32, @bitCast(CarbonMods{ .meta = true })));
try testing.expectEqual(@as(u32, 0x200), @as(u32, @bitCast(CarbonMods{ .shift = true })));
try testing.expectEqual(@as(u32, 0x400), @as(u32, @bitCast(CarbonMods{ .caps_lock = true })));
try testing.expectEqual(@as(u32, 0x800), @as(u32, @bitCast(CarbonMods{ .alt = true })));
try testing.expectEqual(@as(u32, 0x1000), @as(u32, @bitCast(CarbonMods{ .ctrl = true })));
} }
}; };
@ -234,4 +237,10 @@ test {
// const result = try keymap.translate(&buf, &state, 0x12, .{ .shift = true }); // const result = try keymap.translate(&buf, &state, 0x12, .{ .shift = true });
// std.log.warn("map: text={s} dead={}", .{ result.text, result.composing }); // std.log.warn("map: text={s} dead={}", .{ result.text, result.composing });
// } // }
//
// // Scratch space
// {
// const result = try keymap.translate(&buf, &state, 0x00, .{ .ctrl = true });
// std.log.warn("map: text={s} dead={}", .{ result.text, result.composing });
// }
} }