I was recently annoyed that alt/meta don't generate scancodes when swap_opt_cmd is on, and patched it (diff attached). This passes the original scancodes through unmodified, even when the keycodes are translated (e.g. Fn+F1 sends scancodes for Fn and F1, but keycode for brightness down). Works for me, though I'm not sure if this is a good approach overall.
--- a/drivers/hid/hid-apple.c 2017-03-04 01:34:38.655588991 -0500 +++ b/drivers/hid/hid-apple.c 2017-03-04 01:47:08.082599141 -0500 @@ -177,6 +177,15 @@ return NULL; } +static void input_event_with_scancode(struct input_dev *input, + __u8 type, __u16 code, unsigned int hid, __s32 value) +{ + if (type == EV_KEY && + (!test_bit(code, input->key)) == value) + input_event(input, EV_MSC, MSC_SCAN, hid); + input_event(input, type, code, value); +} + static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, struct hid_usage *usage, __s32 value) { @@ -185,7 +194,8 @@ if (usage->code == KEY_FN) { asc->fn_on = !!value; - input_event(input, usage->type, usage->code, value); + input_event_with_scancode(input, usage->type, usage->code, + usage->hid, value); return 1; } @@ -217,8 +227,8 @@ else clear_bit(usage->code, asc->pressed_fn); - input_event(input, usage->type, trans->to, - value); + input_event_with_scancode(input, usage->type, + trans->to, usage->hid, value); return 1; } @@ -238,8 +248,8 @@ clear_bit(usage->code, asc->pressed_numlock); - input_event(input, usage->type, trans->to, - value); + input_event_with_scancode(input, usage->type, + trans->to, usage->hid, value); } return 1; @@ -250,7 +260,8 @@ if (asc->quirks & APPLE_ISO_KEYBOARD) { trans = apple_find_translation(apple_iso_keyboard, usage->code); if (trans) { - input_event(input, usage->type, trans->to, value); + input_event_with_scancode(input, usage->type, + trans->to, usage->hid, value); return 1; } } @@ -259,7 +270,8 @@ if (swap_opt_cmd) { trans = apple_find_translation(swapped_option_cmd_keys, usage->code); if (trans) { - input_event(input, usage->type, trans->to, value); + input_event_with_scancode(input, usage->type, + trans->to, usage->hid, value); return 1; } }