Skip to content

jshiell/minilogi

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MiniLogi

Important

This exists so that I can avoid Logi Options+ for managing my Logitech MX Mechanical Mini. It hasn't been tested with anything else, and I make no pretence towards supporting general use cases. It's supplied as-is, and make melt your machine/end reality/just break. It's also entirely vibe-coded, so caveat emptor.

A minimalist command-line tool for macOS that enumerates Logitech wireless devices paired to a Unifying or Bolt receiver, and lets you read and switch the OS layout, Fn key mode, and backlight state of HID++ 2.0 keyboards.

Requirements

  • macOS (uses IOKit HID)
  • Clang with C++17 support (ships with Xcode Command Line Tools)
  • A Logitech Unifying or Bolt USB receiver

Build

make

Produces ./minilogi. No external dependencies.

Usage

minilogi [-q] <command>
Command Description
ls List all receivers and their paired devices
get-layout Show the current OS layout of all paired keyboards
get-battery Show the battery level of all paired devices
get-fn Show whether Fn keys are in standard or media mode
get-backlight Show the backlight state of all paired keyboards
set-layout=<os> Switch all paired keyboards to the given OS layout
set-fn=<mode> Switch all paired keyboards to the given Fn key mode
set-backlight=<state> Turn backlight on or off on all paired keyboards

-q suppresses all output; the exit code still reflects success or failure.

set-layout values

mac, windows, linux, ios, android, chromeos

set-fn values

standard — F1–F12 are the primary action (press Fn for media keys)
media — media keys are the primary action (press Fn for F1–F12)

set-backlight values

on — enable the backlight
off — disable the backlight

Exit codes

  • 0 — success (finding no paired devices is not a failure)
  • 1 — argument error, no receiver found, receiver could not be opened, or set-layout/set-fn/set-backlight failed to apply to a keyboard

Examples

$ minilogi ls
HID++ Device Enumerator
==================================================================

Found 2 receiver(s).

Receiver : USB Receiver (PID 0xC531)
  Slot   Type            Name
  --------------------------------------------------
  (no paired devices found)

Receiver : USB Receiver (PID 0xC548)
  Slot   Type            Name
  --------------------------------------------------
  1      Keyboard        MX Mechanical Mini
$ minilogi get-battery
HID++ Battery Reporter
==================================================================

Found 2 receiver(s).

Receiver : USB Receiver (PID 0xC548)
  Slot 1  MX Mechanical Mini             100%  discharging

Receiver : USB Receiver (PID 0xC531)
  (no HID++ 2.0 devices found)
$ minilogi get-layout
HID++ Layout Reporter
==================================================================

Found 2 receiver(s).

Receiver : USB Receiver (PID 0xC548)
  Slot 1  MX Mechanical Mini             Mac

Receiver : USB Receiver (PID 0xC531)
  (no HID++ 2.0 keyboards found)
$ minilogi get-fn
HID++ Fn Key Reporter
==================================================================

Found 2 receiver(s).

Receiver : USB Receiver (PID 0xC548)
  Slot 1  MX Mechanical Mini             standard (F1-F12 primary)

Receiver : USB Receiver (PID 0xC531)
  (no HID++ 2.0 keyboards found)
$ minilogi get-backlight
HID++ Backlight Reporter
==================================================================

Found 2 receiver(s).

Receiver : USB Receiver (PID 0xC548)
  Slot 1  MX Mechanical Mini             off

Receiver : USB Receiver (PID 0xC531)
  (no HID++ 2.0 keyboards found)
$ minilogi set-layout=mac
HID++ Layout Switcher
==================================================================

Found 2 receiver(s).

Receiver : USB Receiver (PID 0xC531)
  (no HID++ 2.0 keyboards found)

Receiver : USB Receiver (PID 0xC548)
  Slot 1  MX Mechanical Mini             already Mac layout
$ minilogi set-fn=standard
HID++ Fn Key Switcher
==================================================================

Found 2 receiver(s).

Receiver : USB Receiver (PID 0xC548)
  Slot 1  MX Mechanical Mini             already standard

Receiver : USB Receiver (PID 0xC531)
  (no HID++ 2.0 keyboards found)
$ minilogi set-backlight=on
HID++ Backlight Switcher
==================================================================

Found 2 receiver(s).

Receiver : USB Receiver (PID 0xC548)
  Slot 1  MX Mechanical Mini            switched to on

Receiver : USB Receiver (PID 0xC531)
  (no HID++ 2.0 keyboards found)

Run at login (LaunchAgent)

The included plist org.infernus.minilogi.set-mac-layout.plist registers a LaunchAgent that runs minilogi -q set-layout=mac once each time you log in, keeping all paired keyboards on Mac layout automatically.

Why a LaunchAgent and not a LaunchDaemon?
IOKit HID requires a user GUI session to open input devices. LaunchDaemons run as root with no session attached and cannot reach the HID stack. A LaunchAgent running in the Aqua session type works correctly.

Install

  1. Build, sign, and copy the binary to /usr/local/bin/:

    sudo make install
    

    The install target signs the binary with an ad-hoc signature before copying it. Ad-hoc signatures are tied to the binary's content hash, so you must re-grant Input Monitoring access after every reinstall (see Notes below).

  2. Grant Input Monitoring access to /usr/local/bin/minilogi in
    System Settings → Privacy & Security → Input Monitoring.

  3. Copy the plist to your user LaunchAgents directory:

    sudo make install-launchagent
    
  4. Load it for the current session (or simply log out and back in):

    launchctl load ~/Library/LaunchAgents/org.infernus.minilogi.set-mac-layout.plist
    

The agent runs once at login and exits. Output (if any) is written to /tmp/minilogi.log.

Uninstall

launchctl unload ~/Library/LaunchAgents/org.infernus.minilogi.set-mac-layout.plist
rm ~/Library/LaunchAgents/org.infernus.minilogi.set-mac-layout.plist

Customise the layout

To use a different layout, edit the plist and change set-layout=mac to your preferred value (windows, linux, ios, android, or chromeos), then reload the agent:

launchctl unload ~/Library/LaunchAgents/org.infernus.minilogi.set-mac-layout.plist
launchctl load  ~/Library/LaunchAgents/org.infernus.minilogi.set-mac-layout.plist

Supported receivers

Receiver PID(s)
Bolt any Logitech PID at UsagePage 0xFF00
Unifying 0xC52B, 0xC531, 0xC532, 0xC534

Notes

  • Only HID++ 2.0 devices are supported. Older HID++ 1.0 devices paired to a receiver will not appear in any command's output.
  • macOS requires Input Monitoring permission to open HID receivers. The binary is ad-hoc signed by default, meaning macOS ties the TCC grant to the binary's content hash. After every make install you must re-grant Input Monitoring access in System Settings → Privacy & Security → Input Monitoring (remove the old entry and add the new binary). If you have an Apple Developer ID certificate you can supply it via make install SIGN="Developer ID Application: Your Name (TEAMID)" to get a stable identity that survives rebuilds.
  • The first enumeration after a receiver is plugged in (or a device wakes from sleep) takes up to ~1.5 s per slot. Subsequent runs are much faster (~0.4 s total for a warm receiver).

About

Minimal Logitech keyboard control

Topics

Resources

Stars

Watchers

Forks

Contributors