Repository navigation
feat(devices): add MX Ergo, LIFT, LIFT for Business and MX Anywhere 2S (beta, untested) - #180
Merged
Merged
Conversation
Beta descriptors for three requested devices (#119, #144, #78), built from the Logi Options+ device catalogue (PIDs, programmable CIDs, capabilities) and cross-checked against Solaar's CID names. Untested on hardware. - MX Ergo (0xb01d BT, 0x406f Unifying): middle, back, forward, tilt left/right (0x5B/0x5D), precision-mode button (0xED). 2 Easy-Switch hosts. - LIFT (0xb031) and LIFT for Business (0xb033): middle, back, forward, DPI button (0xFD). 3 hosts. - MX Anywhere 2S (0xb01a BT, 0x406a Unifying): middle, back, forward, tilt left/right. 3 hosts. Feature flags follow scripts/optionsplus_extractor/capabilities.py: battery, adjustableDpi (Options+ pointerSpeed), hiResWheel, reprogControls and smoothScroll on; no SmartShift or thumb wheel. Every control keeps the firmware's native action by default and is remappable. No product images are available, so hotspots and Easy-Switch slots use placeholder coordinates; Editor Mode can position them once images are added. The dpi block is the importer fallback (200-4000/50) and only affects --simulate-all; on hardware the range is read from 0x2201. Tests: DeviceSpec entries for all four, plus checks that the Unifying WPIDs resolve and that Easy-Switch slot counts match the host counts. README devices table regenerated.
…s and MX Anywhere 2S Use Logitech's product gallery shots, cropped to their opaque bounds and capped at 1200px tall, and place hotspots and Easy-Switch slots on them instead of the placeholder grid. - MX Ergo: top-down shot for buttons and Easy-Switch (the channel lights sit under the Easy-Switch button on top), three-quarter shot for the device card. - LIFT / LIFT for Business: top three-quarter shot for buttons, underside shot for Easy-Switch. - MX Anywhere 2S: top-down and three-quarter shots. No underside shot is available, so there is no back image and the Easy-Switch tab stays hidden for it. Adds a test that the referenced image files exist.
# Conflicts: # tests/test_device_registry.cpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds beta descriptors for three requested devices.
Refs #119 (MX Ergo), #144 (LIFT), #78 (MX Anywhere 2S). The issues aren't auto-closed, so they can stay open until someone confirms on hardware.
Devices
specialKeys.programmable)mx-ergo0xb01d(BT),0x406f(Unifying)lift0xb031lift-for-business0xb033mx-anywhere-2s0xb01a(BT),0x406a(Unifying)Controls are ordered by CID ascending from index 2, the same rule as
optionsplus_extractor/canonicalize.sort_buttons. Every control defaults to"default", which means not diverted, so the firmware's own behaviour stays in place until the user remaps something:dpi-cycle, because that would divert the button by default on hardware nobody has tested.Feature flags
The mapping is the same as
scripts/optionsplus_extractor/capabilities.py:hasBatteryStatus. LIFT also hasunified_battery, so it should resolve to 0x1004; MX Ergo and MX Anywhere 2S have no unified-battery flag, so they should resolve to 0x1000. Either way the variant is picked at runtime by the capability table.pointerSpeed.pointerSpeed(0x2205) is leftfalse, as the importer does.scroll_wheel_capabilities.high_resolution.specialKeys.programmable.mouseThumbWheelOverride. LIFT's Options+ "virtual thumbwheel" (hold back/forward and scroll) is a software feature Logitune doesn't have.DPI
Options+ gives no sensor range for these three, and Solaar has no static entries for them; it discovers them at runtime. DPI is therefore left to runtime discovery:
DeviceSessionreads min/max/step from AdjustableDPI (0x2201) at connect. Thedpiblock (200–4000, step 50) is the importer's own fallback (dpi_from_capabilities). It only matters for--simulate-alland for validatingcycleRing, and none of these descriptors sets a ring.Images, hotspots, Easy-Switch
Images are Logitech's own product gallery shots with transparent backgrounds, taken from logitech.com product pages. MX Anywhere 2S is end-of-life and its page is gone, so its shots come from Logitech's asset server, using the URLs on its old product page. Each image is cropped to the product and capped at 1200px tall. Hotspot and Easy-Switch coordinates are measured on those crops.
front(device card)side(Buttons, Point & Scroll)back(Easy-Switch)mx-ergoliftlift-for-businessmx-anywhere-2sSideNavkeeps the Easy-Switch tab hidden, which is existing behaviour. The threeeasySwitchSlotsstay in the descriptor, so the tab appears if an underside image is added later.flow.hostCount, so MX Ergo has 2 channels.I checked every Buttons, Point & Scroll and Easy-Switch page, plus the home carousel, in
--simulate-all.Schema and UI support
pointerscroll hotspot stands for the ball.2b031_ext1on the same PID0xb031, so it uses the same descriptor. Hotspot mirroring only becomes relevant once there are images.Tests
DeviceSpecentries for all four descriptors intests/test_device_registry.cpp.UnifyingWpidsResolveToTheirDescriptor:0x406fand0x406aresolve.FindsByPidonly covers the first PID.EasySwitchSlotCountMatchesHostCount: 2 for MX Ergo, 3 for the others.ProductImagesExistOnDisk: every referenced image file exists, and MX Anywhere 2S has no back image.scripts/generate-readme-devices.py.devices/schema.json.logitune-tests838/838, and the pre-push hook ran the full suite. All descriptors load (strict) in--simulate-allwith noJsonDevicewarnings.Needs hardware
Anyone with one of these devices (see the issues): run
logituneand check the following.DPI range:) matches the device.The tilt and precision/DPI buttons are the least certain.
🤖 Generated with Claude Code