From 5d22e55d6b2cb233b8c68794f704acefb1a58647 Mon Sep 17 00:00:00 2001 From: TheGeneralist <180094941+thegeneralist01@users.noreply.github.com> Date: Sat, 6 Jun 2026 19:13:25 +0200 Subject: [PATCH 1/4] Map Logitech mouse Button3 to Fn with Hyper override --- modules/darwin/karabiner.nix | 43 +++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/modules/darwin/karabiner.nix b/modules/darwin/karabiner.nix index 102ccac..feded39 100644 --- a/modules/darwin/karabiner.nix +++ b/modules/darwin/karabiner.nix @@ -104,12 +104,8 @@ let is_pointing_device = true; }; - # Middle click sends Fn; side buttons navigate back and forward. + # Side buttons navigate back and forward. logitechMouseSimpleModifications = [ - { - from.pointing_button = "button3"; - to = [ { apple_vendor_top_case_key_code = "keyboard_fn"; } ]; - } { from.pointing_button = "button4"; to = [ @@ -133,6 +129,39 @@ let complex_modifications = { name = "Complex Modifications"; rules = [ + { + description = "Logitech mouse Button3 sends Fn, or middle click with Hyper"; + manipulators = [ + { + from = { + pointing_button = "button3"; + modifiers.mandatory = hyperModifiers; + }; + to = [ { pointing_button = "button3"; } ]; + conditions = [ + { + type = "device_if"; + identifiers = [ logitechMouseIdentifiers ]; + } + ]; + type = "basic"; + } + { + from = { + pointing_button = "button3"; + modifiers.optional = [ "any" ]; + }; + to = [ { apple_vendor_top_case_key_code = "keyboard_fn"; } ]; + conditions = [ + { + type = "device_if"; + identifiers = [ logitechMouseIdentifiers ]; + } + ]; + type = "basic"; + } + ]; + } # { # description = "Change numbers to symbols and vice versa"; # manipulators = manipulators; @@ -143,7 +172,9 @@ let { from = { key_code = "caps_lock"; - modifiers = { optional = [ "any" ]; }; + modifiers = { + optional = [ "any" ]; + }; }; to = [ { From 21d4ba3eb50347e9901aa16bfc5c3b8ab4310135 Mon Sep 17 00:00:00 2001 From: TheGeneralist <180094941+thegeneralist01@users.noreply.github.com> Date: Sat, 6 Jun 2026 22:18:17 +0200 Subject: [PATCH 2/4] Gate man cache generation on Linux and extend Karabiner mappings --- modules/common/home-manager.nix | 23 ++++++++++---- modules/darwin/karabiner.nix | 54 +++++++++++++++++++++++++++++++-- 2 files changed, 69 insertions(+), 8 deletions(-) diff --git a/modules/common/home-manager.nix b/modules/common/home-manager.nix index 3c068ef..0302853 100644 --- a/modules/common/home-manager.nix +++ b/modules/common/home-manager.nix @@ -1,19 +1,30 @@ -{ inputs, lib, os, ... }: +{ + inputs, + lib, + os, + ... +}: let isDarwin = os == "darwin"; isLinux = os == "linux"; -in { +in +{ imports = lib.optional isDarwin inputs.home-manager.darwinModules.home-manager ++ lib.optional isLinux inputs.home-manager.nixosModules.home-manager; home-manager = { - useGlobalPkgs = true; + useGlobalPkgs = true; useUserPackages = true; backupFileExtension = lib.mkDefault "home.bak"; }; - home-manager.sharedModules = [{ - programs.home-manager.enable = true; - }]; + home-manager.sharedModules = [ + { + programs = { + home-manager.enable = true; + man.generateCaches = isLinux; + }; + } + ]; } diff --git a/modules/darwin/karabiner.nix b/modules/darwin/karabiner.nix index feded39..53f2112 100644 --- a/modules/darwin/karabiner.nix +++ b/modules/darwin/karabiner.nix @@ -86,7 +86,7 @@ let is_keyboard = true; }; - # Swap the G213's Windows/Alt modifiers. + # Swap the G213's Windows/Alt modifiers and map Application to Fn. logitechG213SimpleModifications = [ { from.key_code = "left_command"; @@ -96,6 +96,10 @@ let from.key_code = "left_option"; to = [ { key_code = "left_command"; } ]; } + { + from.key_code = "application"; + to = [ { apple_vendor_top_case_key_code = "keyboard_fn"; } ]; + } ]; logitechMouseIdentifiers = { @@ -130,8 +134,35 @@ let name = "Complex Modifications"; rules = [ { - description = "Logitech mouse Button3 sends Fn, or middle click with Hyper"; + description = "Logitech mouse Button3 sends Fn, or middle click with Hyper or Button2"; manipulators = [ + { + from.pointing_button = "button2"; + to = [ + { pointing_button = "button2"; } + { + set_variable = { + name = "logitech_mouse_button2_held"; + value = 1; + }; + } + ]; + to_after_key_up = [ + { + set_variable = { + name = "logitech_mouse_button2_held"; + value = 0; + }; + } + ]; + conditions = [ + { + type = "device_if"; + identifiers = [ logitechMouseIdentifiers ]; + } + ]; + type = "basic"; + } { from = { pointing_button = "button3"; @@ -146,6 +177,25 @@ let ]; type = "basic"; } + { + from = { + pointing_button = "button3"; + modifiers.optional = [ "any" ]; + }; + to = [ { pointing_button = "button3"; } ]; + conditions = [ + { + type = "device_if"; + identifiers = [ logitechMouseIdentifiers ]; + } + { + type = "variable_if"; + name = "logitech_mouse_button2_held"; + value = 1; + } + ]; + type = "basic"; + } { from = { pointing_button = "button3"; From 26f0f6867fa0aba9e007468e7dcdeb11e6286461 Mon Sep 17 00:00:00 2001 From: TheGeneralist <180094941+thegeneralist01@users.noreply.github.com> Date: Sun, 7 Jun 2026 11:12:06 +0200 Subject: [PATCH 3/4] Extend Logitech Button3 passthrough mappings --- modules/darwin/karabiner.nix | 65 +++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/modules/darwin/karabiner.nix b/modules/darwin/karabiner.nix index 53f2112..d42182c 100644 --- a/modules/darwin/karabiner.nix +++ b/modules/darwin/karabiner.nix @@ -134,8 +134,35 @@ let name = "Complex Modifications"; rules = [ { - description = "Logitech mouse Button3 sends Fn, or middle click with Hyper or Button2"; + description = "Logitech mouse Button3 sends Fn, or middle click with Hyper, Shift, Button1, or Button2"; manipulators = [ + { + from.pointing_button = "button1"; + to = [ + { pointing_button = "button1"; } + { + set_variable = { + name = "logitech_mouse_button1_held"; + value = 1; + }; + } + ]; + to_after_key_up = [ + { + set_variable = { + name = "logitech_mouse_button1_held"; + value = 0; + }; + } + ]; + conditions = [ + { + type = "device_if"; + identifiers = [ logitechMouseIdentifiers ]; + } + ]; + type = "basic"; + } { from.pointing_button = "button2"; to = [ @@ -163,6 +190,25 @@ let ]; type = "basic"; } + { + from = { + pointing_button = "button3"; + modifiers.optional = [ "any" ]; + }; + to = [ { pointing_button = "button3"; } ]; + conditions = [ + { + type = "device_if"; + identifiers = [ logitechMouseIdentifiers ]; + } + { + type = "variable_if"; + name = "logitech_mouse_button1_held"; + value = 1; + } + ]; + type = "basic"; + } { from = { pointing_button = "button3"; @@ -177,6 +223,23 @@ let ]; type = "basic"; } + { + from = { + pointing_button = "button3"; + modifiers = { + mandatory = [ "shift" ]; + optional = [ "any" ]; + }; + }; + to = [ { pointing_button = "button3"; } ]; + conditions = [ + { + type = "device_if"; + identifiers = [ logitechMouseIdentifiers ]; + } + ]; + type = "basic"; + } { from = { pointing_button = "button3"; From bb70a4f40588b01ff3f41d0405576b00095ccd3a Mon Sep 17 00:00:00 2001 From: TheGeneralist <180094941+thegeneralist01@users.noreply.github.com> Date: Sun, 7 Jun 2026 12:51:43 +0200 Subject: [PATCH 4/4] Fix Logitech mouse button chord handling --- modules/darwin/karabiner.nix | 48 +++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/modules/darwin/karabiner.nix b/modules/darwin/karabiner.nix index d42182c..3edc55b 100644 --- a/modules/darwin/karabiner.nix +++ b/modules/darwin/karabiner.nix @@ -136,15 +136,29 @@ let { description = "Logitech mouse Button3 sends Fn, or middle click with Hyper, Shift, Button1, or Button2"; manipulators = [ + # Keep the forwarded button as the only `to` event so Karabiner + # preserves its down state. A variable in the same `to` sequence + # either releases the button immediately or resets too early, so + # detect Button3 through `to_if_other_key_pressed` instead. { from.pointing_button = "button1"; - to = [ - { pointing_button = "button1"; } + to = [ { from_event = true; } ]; + to_if_other_key_pressed = [ { - set_variable = { - name = "logitech_mouse_button1_held"; - value = 1; - }; + other_keys = [ + { + pointing_button = "button3"; + modifiers.optional = [ "any" ]; + } + ]; + to = [ + { + set_variable = { + name = "logitech_mouse_button1_held"; + value = 1; + }; + } + ]; } ]; to_after_key_up = [ @@ -165,13 +179,23 @@ let } { from.pointing_button = "button2"; - to = [ - { pointing_button = "button2"; } + to = [ { from_event = true; } ]; + to_if_other_key_pressed = [ { - set_variable = { - name = "logitech_mouse_button2_held"; - value = 1; - }; + other_keys = [ + { + pointing_button = "button3"; + modifiers.optional = [ "any" ]; + } + ]; + to = [ + { + set_variable = { + name = "logitech_mouse_button2_held"; + value = 1; + }; + } + ]; } ]; to_after_key_up = [