TRENDSHIFT 딥다이브 · 2026.06.02

OpenLogi 딥다이브
— Rust로 다시 쓴 "로지텍 옵션+", HID++로 마우스를 직접 만진다

로지텍 공식 소프트웨어(Logi Options+)를 안 깔고도 마우스 버튼을 다시 매핑하고, DPI와 SmartShift를 바꾸는 로컬 우선(local-first) 데스크톱 앱. 계정도 없고 텔레메트리도 없다. 전부 Rust로 짜였고, 마우스와는 로지텍의 비공개 프로토콜 HID++로 직접 대화한다. UI는 Zed 팀이 만든 GPU 가속 프레임워크 GPUI로 그리고, 설정은 클라우드가 아니라 내 디스크의 평범한 TOML 파일에 남는다. 10개 크레이트로 잘게 나뉜 Rust 워크스페이스 구조 자체가 좋은 교재다. (저장소: AprilNEA/OpenLogi · ★ 117 · TrendShift 데일리 7위 · 2026 신규 · MIT/Apache-2.0 듀얼 라이선스)
목차
  1. 한줄 요약
  2. 왜 지금 주목받는가
  3. 기술 스택 전체 지도
  4. 아키텍처 심화 분석
  5. 디렉토리 구조 해부
  6. 학습 포인트 (기술별)
  7. 하드웨어·시스템 요구사항
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 학습 로드맵
  10. 핵심 키워드 사전
  11. 참고 링크

1한줄 요약

이 프로젝트가 정확히 무엇을 하는가

OpenLogi는 로지텍 마우스(MX Master 계열 등)를 "공식 앱 없이" 길들이는 오픈소스 도구다. 옆 버튼(뒤로/앞으로)을 원하는 동작으로 바꾸고, DPI(마우스 민감도)를 프리셋으로 전환하고, 스크롤 휠의 SmartShift(걸쇠식 ↔ 자유회전) 모드를 토글한다. 앱이 켜진 동안 앞에 떠 있는 프로그램에 따라 버튼 의미를 자동으로 바꿔주는 "앱별 프로필"까지 지원한다.

핵심 차별점은 local-first(로컬 우선)다. 로지텍 계정 로그인도, 사용 데이터 수집(텔레메트리)도, 무거운 백그라운드 서비스도 없다. 설정은 ~/.config/openlogi/config.toml이라는 사람이 읽을 수 있는 텍스트 파일 하나에 저장된다. 현재 macOS·Linux를 정식 지원하고, Windows는 미테스트 preview 상태다(버전 0.x, 활발히 개발 중).

한 장면으로 이해하기

"순정 내비 대신 직접 깐 오픈소스 펌웨어"

새 마우스를 사면 제조사 앱(Logi Options+)을 깔라고 한다. 편하지만 계정을 요구하고, 백그라운드에서 늘 돌고, 가끔 클라우드와 통신한다. 마치 자동차의 순정 내비게이션 같다 — 잘 되지만 내 통제 밖이다.

OpenLogi는 같은 마우스에 직접 만든 가벼운 펌웨어 콘솔을 물리는 것과 같다. 버튼·DPI·휠 설정을 마우스 칩에 직접 써넣되, 그 과정과 데이터가 전부 내 손 안에 있다. 비결은 로지텍이 쓰는 통신 규약 HID++를 OpenLogi가 그대로 구사한다는 점이다.

2왜 지금 주목받는가

트렌딩 이유와 기존 도구(Logi Options+ · Solaar) 대비 차별점
먼저 알아둘 용어
HID / HID++
HID(Human Interface Device)는 키보드·마우스 같은 입력기기가 OS와 대화하는 USB 표준이다. 기본 HID로는 "커서 이동·클릭" 정도만 표현된다. HID++는 로지텍이 그 위에 얹은 비공개 확장 프로토콜로, DPI 변경·배터리 조회·버튼 재정의처럼 "표준 HID에 없는 고급 기능"을 기기에 직접 명령한다. OpenLogi의 심장이 바로 이 HID++ 구현이다.

1. "공식 앱이 싫다"는 수요를 정확히 때림

Logi Options+는 기능은 많지만 무겁고, 계정을 요구하고, 백그라운드 상주에 가끔 클라우드와 통신한다. "마우스 버튼 하나 바꾸려고 이걸 다 깔아야 하나"라는 불만은 오래된 것이다. OpenLogi는 그 불만에 "계정 없음 · 텔레메트리 없음 · TOML 한 파일"로 답한다. 프라이버시·경량·통제권을 한꺼번에 파는 셈이라, local-first 흐름을 타고 빠르게 입소문이 났다.

기존 공식 소프트웨어의 불편
계정 · 상주 서비스 · 불투명한 통신

설정을 바꾸려면 로그인하고, 앱은 항상 떠 있어야 하며, 내 설정이 어디에 어떻게 저장되는지 사용자가 알기 어렵다. "내 마우스인데 내가 통제하지 못한다"는 감각.

OpenLogi의 접근
로컬에서 끝, 통신은 옵트인

설정은 디스크의 config.toml에 원자적으로 저장된다. 네트워크를 타는 건 (1) 기기 이미지를 받아오는 것(2) 기본 꺼져 있는 업데이트 확인뿐. 버튼 리매핑은 OS 이벤트를 가로채서, DPI/SmartShift는 HID++로 기기에 직접 쓴다.

2. macOS·Linux에서 로지텍 마우스를 제대로 다루는 드문 오픈소스

리눅스에는 Solaar라는 훌륭한 HID++ 도구가 오래 있었지만, Rust 기반 크로스플랫폼 로컬 우선 도구는 사각지대였다. OpenLogi는 macOS의 CGEventTap·접근성 권한·앞 앱 감지와 Linux의 evdev+uinput·udev 후킹을 모두 정면으로 구현해, "옆버튼을 앱별로 다르게 쓰고 싶다"는 구체적 갈증을 양 플랫폼에서 푼다. README도 Solaar와 Mouser에게 감사를 표한다.

3. "전부 Rust"라는 기술적 매력

입력 후킹·USB 통신처럼 보통 C/C++로 짜던 저수준 영역을 전부 Rust로, 그것도 10개 크레이트로 깔끔하게 분리해 구현했다. 게다가 UI는 Electron이 아니라 Zed의 GPUI로 그려서 "네이티브·가벼움"을 끝까지 밀어붙였다. Rust·시스템 프로그래밍·GPUI에 관심 있는 개발자들에게 "읽고 배울 가치가 있는 레퍼런스"로 회자되는 것이 트렌딩의 두 번째 축이다.

왜 개발자들이 코드를 열어보나

대부분의 마우스 유틸리티는 블랙박스다. OpenLogi는 "HID++ 패킷을 어떻게 만들고, OS 이벤트를 어떻게 가로채고, 그걸 어떻게 크레이트로 나누는가"를 통째로 공개한다. 즉 결과물(앱)뿐 아니라 제작 과정 전체가 교재다. 별 117개의 작은 신생 저장소가 TrendShift 상위에 오른 이유가 여기 있다 — 스타 수보다 "관심의 질"이 높다.

4. 신생·미완성이라는 점은 솔직하게

버전은 아직 0.x(저장소 릴리스 v0.0.1, 워크스페이스 내부 버전 0.3.4)이고 README가 "활발히 개발 중, 기능·설정이 바뀔 수 있음"을 명시한다. 일부 액션(미디어 키 등)은 "실제 이벤트 대신 의도만 로그로 남기는" 상태이고, 중간/모드시프트/썸휠 버튼 캡처는 "설정은 되지만 하드웨어 캡처는 미구현"이다. 완성품이 아니라 "성장하는 프로젝트"라는 전제를 깔고 보는 게 정확하다.

3기술 스택 전체 지도

언어 비중 Rust 97.6% · Shell 1.8% · Nix 0.6% — 거의 순수 Rust 단일 언어 프로젝트

OpenLogi는 Cargo 워크스페이스 하나에 10개 크레이트(+ xtask)를 담은 모노레포다. Edition은 최신 2024, 최소 지원 Rust 버전(MSRV)은 1.88, 의존성 해석기는 resolver = "3". "프런트엔드/백엔드"가 아니라 "GUI 계층 · 프로토콜 계층 · OS 후킹 계층"으로 나눠 보는 게 이 프로젝트엔 맞다.

GUI 계층 — GPUI (Zed의 UI 프레임워크)

분류크레이트역할
UI 프레임워크gpui · gpui_platform (zed-industries/zed)GPU 가속 네이티브 렌더링. Electron 없이 데스크톱 UI를 그린다
컴포넌트 라이브러리gpui-component (longbridge)버튼·리스트·캐러셀 등 재사용 UI 부품. 아이콘은 lucide SVG
아이콘 에셋gpui-component-assetsIconName enum이 매크로로 생성되는 SVG 묶음(컴포넌트와 같은 rev로 고정)
눈여겨볼 선택
git rev 고정(pinning)
gpui는 Zed 저장소의 기본 브랜치를 따라가고, gpui-component특정 커밋(rev)으로 못 박혀 있다. 매크로로 생성되는 아이콘 enum과 SVG 에셋이 "정확히 같은 버전"이어야 깨지지 않기 때문. 정확한 zed 커밋은 Cargo.lock에 핀으로 박고, 올릴 때는 cargo update로 의도적으로 보조를 맞춘다. 외부 git 의존성을 안전하게 다루는 실전 패턴이다.

프로토콜·HID 계층 — HID++ over async-hid

분류크레이트/라이브러리역할
HID++ 프로토콜openlogi-hidpp (패키지명 hidpp)로지텍 HID++ 패킷 조립/파싱. 프로젝트의 심장
크로스플랫폼 HIDasync-hid 0.4OS별 HID 장치 열기/읽기/쓰기를 async로 추상화
비동기 런타임tokio (rt·macros·sync·time) · futures-lite장치 I/O를 논블로킹으로 처리
직렬화serde · serde_json · toml 0.8설정(TOML)·에셋 레지스트리(JSON) 읽고 쓰기
왜 직접 만든 hidpp인가
openlogi-hidpp (vendored/fork)
Cargo.toml을 보면 hidpp = { package = "openlogi-hidpp", path = "crates/openlogi-hidpp" } — 즉 crates.io의 hidpp를 그대로 쓰지 않고 워크스페이스 안으로 들여와 직접 관리한다. 프로토콜을 자기 요구에 맞게 고치고, 버전을 워크스페이스와 묶어 통제하려는 선택. README는 원작자 @lushidpp 크레이트에 감사를 표한다.

OS 후킹·시스템 계층 — macOS Core Graphics / Linux evdev

분류크레이트/라이브러리역할
이벤트 후킹openlogi-hook + core-graphics 0.25macOS CGEventTap으로 마우스 옆버튼을 가로채 재매핑
플랫폼 FFIobjc2 · objc2-app-kit (NSWorkspace)앞 앱(bundle id) 감지. core-foundation·core-graphics는 CGEventTap 이벤트 탭 자체에 사용
HTTP 클라이언트ureq 3 (rustls·json)기기 이미지 fetch · 업데이트 매니페스트 확인
해시sha2 0.10다운로드 무결성 검증(SHA256SUMS)
CLIclap 4 (derive·env)openlogi list/diag/assets 명령 트리
에러·로깅anyhow · thiserror 2 · tracing · tracing-subscriber에러 처리 + 구조적 로그(OPENLOGI_LOG=debug)

개발·배포 도구 체인

릴리스 프로파일
lto = "fat" · codegen-units = 1 · strip = "symbols"
배포 빌드를 작고 빠르게 만드는 3종 세트. LTO(Link-Time Optimization)로 모든 코드 단위를 통합 최적화(fat/full LTO)하고, codegen-units=1로 컴파일 병렬성을 포기하는 대신 최적화 품질을 높이며, strip=symbols로 디버그 심볼을 떼어 바이너리 용량을 줄인다. "데스크톱 앱은 가벼워야 한다"는 철학의 컴파일러 설정판.

4아키텍처 심화 분석

크레이트 의존 그래프 + 핵심 설계 패턴

설계의 큰 원칙은 "순수 로직과 부수효과(HID·OS·네트워크)의 분리"다. 한가운데 openlogi-core가 있는데, 이 크레이트는 HID도 async도 모른다 — 오직 타입·설정·경로·버튼/액션 카탈로그 같은 "순수한 규칙"만 담는다. 부수효과는 바깥쪽 크레이트(hid·hook·assets)가 떠맡는다. 덕분에 핵심 로직은 하드웨어 없이도 테스트할 수 있다.

사용자 입력 / OS 이벤트 │ (마우스 옆버튼) │ (GUI 조작) ▼ ▼ openlogi-hook openlogi-gui (macOS CGEventTap) (GPUI 데스크톱 앱) 옆버튼 가로채기 + 마우스 다이어그램 + 앞 앱 bundle id 감지 액션 피커 + 기기 캐러셀 │ │ └───────────┬───────────┘ ▼ openlogi-core ◀── 순수 로직(HID/async 없음) 타입 · TOML 설정 · 경로 · 버튼/액션 카탈로그 │ ┌────────┼─────────────┐ ▼ ▼ ▼ openlogi-hid openlogi-assets config.toml DPI 0x2201 기기 이미지 (원자적 쓰기) SmartShift 레지스트리 + 0x2111 쓰기 R2 캐시 fetch │ ▼ openlogi-hidpp ── async-hid ──▶ Logi Bolt 리시버 / (HID++ 패킷) 블루투스 / 유선 │ ▼ 로지텍 마우스 하드웨어

패턴 1 — 코어를 순수하게 유지(Hexagonal에 가까운 분리)

openlogi-core가 "HID 없음 · async 없음"이라는 건 의도적인 경계 설정이다. 버튼이 어떤 액션에 묶이는지, 앱별 오버레이가 어떻게 합쳐지는지 같은 의사결정 규칙은 코어에 두고, 실제로 기기에 패킷을 쏘거나 OS 이벤트를 잡는 I/O는 어댑터 크레이트로 민다. 이렇게 하면 코어는 단위 테스트가 쉽고, 나중에 Linux/Windows 후킹을 추가해도 코어를 안 건드린다.

패턴 2 — HID++ "feature page" 호출

HID++ 2.0에서 기기 기능은 feature ID로 식별된다. OpenLogi가 쓰는 두 개가 README·USAGE에 그대로 노출된다.

Feature ID이름OpenLogi에서의 용도
0x2201Adjustable DPIDPI 읽기/쓰기, 프리셋 순환(Cycle)·지정(Set)
0x2111Smart Shift스크롤 휠 걸쇠식 ↔ 자유회전 토글

흐름은 항상 "기기 열기 → 어떤 feature가 있는지 조회 → 해당 feature page에 요청 패킷 전송 → 응답 파싱"이다. CLI의 openlogi diag features는 활성 기기가 보고하는 모든 feature를 덤프하고, diag dpi는 "읽기→쓰기→되읽기→복원"으로 안전하게 동작을 점검한다.

feature page 비유

마우스를 "기능별 창구가 늘어선 관공서"라고 보자. 0x2201 창구는 DPI 담당, 0x2111 창구는 휠 모드 담당이다. OpenLogi는 먼저 "오늘 어떤 창구가 열려 있나(feature 조회)"를 묻고, 열린 창구에만 정해진 양식(패킷)으로 민원을 넣는다. 기기마다 열린 창구가 다르므로, 무턱대고 명령하지 않고 항상 먼저 물어보는 게 안전장치다.

패턴 3 — OS 이벤트 탭으로 "버튼 재매핑"

DPI·SmartShift는 기기에 직접 쓰지만, 버튼 재매핑은 결이 다르다. 옆버튼을 "Undo"로 바꾸려면 OS 차원에서 그 클릭을 가로채 다른 입력으로 바꿔치기해야 한다. macOS에서는 CGEventTap(Core Graphics 이벤트 탭)이 그 역할을 하고, 이를 쓰려면 접근성(Accessibility) 권한이 필요하다. 동시에 objc2 / NSWorkspace로 "지금 앞에 있는 앱의 bundle id"를 감지해, 앱별 프로필(per-app overlay)을 실시간으로 적용한다.

플랫폼 종속의 현실
후킹은 OS마다 완전히 다르다

macOS는 CGEventTap, Linux는 evdev+uinput으로 각각 구현돼 있다. Windows 후킹은 현재 미테스트 preview 상태다. DPI/SmartShift(HID++) 쪽은 크로스플랫폼에 가깝고, "버튼 재매핑"도 macOS·Linux는 정식 지원한다.

패턴 4 — 설정은 원자적 쓰기 + 스키마 버전

설정 파일에는 schema_version = 1이 박혀 있다. 나중에 구조가 바뀌어도 마이그레이션 기준점을 갖기 위함이다. 저장은 원자적(atomic)으로 — 임시 파일에 다 쓴 뒤 한 번에 교체 — 처리해, 쓰는 도중 앱이 죽어도 설정이 깨지지 않게 한다. 기기별 설정은 HID++ 식별자(예: MX Master 4 = 2b042)를 키로 묶는다.

5디렉토리 구조 해부

10개 크레이트 + 빌드 자동화가 어떻게 나뉘는가
OpenLogi/ ├── Cargo.toml # 워크스페이스 정의(resolver=3, 멤버 목록, 공통 의존성) ├── Cargo.lock # zed/gpui git 커밋까지 고정하는 잠금 파일 ├── rust-toolchain.toml # 툴체인 고정(Edition 2024 / MSRV 1.88) ├── rustfmt.toml # 포맷 규칙 ├── prek.toml # pre-commit 훅 설정 ├── release-plz.toml # 릴리스 자동화 ├── devenv.nix / .yaml # Nix 기반 재현 가능 개발 셸 ├── .cargo/config.toml # macOS 전용 cargo 'runner'(개발 시 .app 번들로 실행) ├── .github/workflows/ # CI + 릴리스(R2 업로드, 매니페스트 생성) ├── docs/ # README가 가리키는 USAGE / CONFIGURATION / DEVELOPMENT ├── design/icon/ # 앱 아이콘 소스 ├── scripts/ # cargo-run-macos.sh 등 보조 스크립트 ├── src/ # 'openlogi' 바이너리 = openlogi-cli의 얇은 래퍼 ├── xtask/ # 빌드/패키징 자동화 바이너리(DMG·아이콘·매니페스트) └── crates/ ├── openlogi-core/ # [순수] 타입·TOML 설정·경로·버튼/액션 카탈로그 ├── openlogi-inject/ # [OS] OS 입력 합성 어댑터(재매핑 이벤트 주입) ├── openlogi-hidpp/ # [프로토콜] HID++ 패킷 조립/파싱(패키지명 hidpp) ├── openlogi-hid/ # [I/O] async-hid 위에서 DPI(0x2201)·SmartShift(0x2111) ├── openlogi-assets/ # [네트워크] 기기 이미지 레지스트리 + R2 캐시 fetch ├── openlogi-cli/ # [엔트리] clap 명령 트리 + run() ├── openlogi-agent-core/ # [IPC] 에이전트 간 IPC 프로토콜 타입 정의 ├── openlogi-agent/ # [데몬] 백그라운드 에이전트 바이너리 ├── openlogi-gui/ # [엔트리] GPUI 데스크톱 앱 바이너리 └── openlogi-hook/ # [OS] macOS CGEventTap + 접근성 + 앞 앱 감지
크레이트성격핵심 책임
openlogi-core순수 로직HID·async·OS를 전혀 모름. 설정 스키마, 버튼→액션 매핑 규칙, 경로 계산. 테스트하기 가장 쉬운 중심
openlogi-hidpp프로토콜HID++ 메시지 바이트 레이아웃. feature page 요청/응답 직렬화
openlogi-hid장치 I/Oenumerate()로 기기 탐색, DPI/SmartShift 쓰기. async-hid 어댑터
openlogi-assets네트워크기기 렌더 이미지의 스키마 + assets.openlogi.org 캐시 fetch
openlogi-cli진입점(CLI)list·diag·assets sync 명령 구현
openlogi-gui진입점(GUI)마우스 다이어그램·액션 피커·DPI 프리셋·기기 캐러셀
openlogi-hookOS 후킹macOS 이벤트 탭으로 옆버튼 가로채기 + 앱별 프로필 전환
xtask빌드 도구DMG 패키징, .icns 생성, 업데이트 매니페스트 생성
왜 이렇게 잘게 쪼갰을까

한 덩어리(monolithic crate)로 짜도 동작은 한다. 하지만 크레이트 경계 = 컴파일 단위 = 의존성 방향의 강제선이다. "GUI가 HID를 직접 만지지 못하게", "코어가 네트워크를 모르게" 같은 규칙을 폴더 구조가 아니라 컴파일러가 강제하도록 만든 것이다. 컴파일 캐시도 크레이트 단위라 빌드도 빨라진다. 큰 Rust 프로젝트의 정석 설계를 작은 앱에서 깔끔하게 보여주는 사례다.

6학습 포인트 (기술별)

이 레포에서 무엇을, 어떻게 배울 것인가

① Cargo 워크스페이스 설계

Cargo.toml[workspace.dependencies]로 버전을 한 곳에서 관리하고, 각 크레이트는 { workspace = true }로 끌어다 쓰는 패턴을 그대로 따라 해보자. [workspace.lints]unsafe_code = "deny", clippy pedantic, unwrap_used/expect_used = "warn"을 전 크레이트에 일괄 적용하는 것도 실무에서 바로 쓰는 기법이다.

실습 아이디어

빈 워크스페이스를 만들고 core(순수)·io(부수효과)·cli(진입점) 3개 크레이트로 나눠, "cli → io → core" 한 방향 의존만 허용되도록 짜보기. core에서 io를 import하면 컴파일 에러가 나는지 확인.

② HID / HID++ 저수준 통신

async-hid로 HID 장치를 열고 리포트를 읽는 최소 예제부터 시작하자. 그다음 HID++의 "feature 조회 → feature page 호출" 구조를 이해하면, OpenLogi가 왜 diag features로 먼저 능력을 묻고 diag dpi로 "읽기→쓰기→되읽기→복원"을 하는지 자연스럽게 읽힌다.

실습 아이디어

가진 HID 기기(아무 키보드/마우스)를 async-hid로 enumerate해서 vendor/product id와 리포트를 콘솔에 찍어보기. 로지텍 기기가 있다면 OpenLogi의 diag features 출력과 대조.

③ GPUI — Electron 없는 네이티브 데스크톱 UI

Zed가 만든 GPUI는 "Rust로 GPU 가속 UI를 그린다"는 비교적 새 패러다임이다. OpenLogi는 거기에 gpui-component(longbridge)를 얹어 실제 컴포넌트(캐러셀·리스트·피커)를 구성한다. git rev 고정으로 외부 UI 라이브러리를 안전하게 묶는 법도 함께 배울 수 있다.

실습 아이디어

GPUI "hello world" 창을 띄우고 버튼 클릭 → 상태 변경 → 리렌더의 흐름을 익히기. 그다음 OpenLogi의 openlogi-gui에서 "기기 캐러셀"이 상태를 어떻게 들고 있는지 따라 읽기.

④ 플랫폼 시스템 프로그래밍(CGEventTap · evdev · objc2)

macOS는 core-graphics(CGEventTap)와 objc2/objc2-app-kit(NSWorkspace로 앞 앱 감지), Linux는 evdev+uinput으로 OS 이벤트를 가로채는 코드가 모두 공개돼 있어 플랫폼 FFI의 살아있는 예제다. 워크스페이스가 unsafe_code = "deny"이면서도 FFI가 필요한 크레이트는 #[expect(unsafe_code, reason="...")]로 국소 허용하는 패턴도 눈여겨보자.

실습 아이디어

macOS에서 CGEventTap으로 특정 키 입력을 로그로 찍는 최소 프로그램 만들기(접근성 권한 요청 포함). "이벤트를 보기만 할지, 변형/소비할지"의 차이를 체험. Linux라면 evdev로 같은 실습 가능.

⑤ 배포 파이프라인 — xtask · DMG · 자체 업데이트

xtask로 빌드 자동화를 코드화하고, create-dmg로 macOS DMG를 만들고, Cloudflare R2에 올린 latest.json 매니페스트로 자체 업데이트 채널을 운영하는 전 과정이 공개돼 있다. "내 데스크톱 앱을 어떻게 서명·배포·업데이트하나"의 실전 청사진.

7하드웨어·시스템 요구사항

무엇이 있어야 돌리고, 무엇을 빌드할 수 있나
항목요구사항
운영체제(실행)macOS · Linux 정식 지원. Windows는 미테스트 preview(evdev+uinput·udev·systemd·deb/rpm 패키지까지 Linux 인프라 완비)
대상 기기로지텍 HID++ 마우스(MX Master 계열 등). Logi Bolt 리시버 · 블루투스 직결 · 유선 · Unifying 리시버 모두 지원
권한버튼 재매핑에 접근성(Accessibility) 권한 필요
충돌 주의설치 전 Logi Options+를 반드시 종료 — 둘이 같은 리시버의 HID++ 접근권을 두고 다툰다(하나만 점유 가능)
설치(사용자)서명·공증된 .dmg를 릴리스에서 받거나 brew install --cask aprilnea/tap/openlogi
빌드(개발자)Stable Rust(Edition 2024, MSRV 1.88), macOS는 Xcode 16+ & Metal Toolchain(GPUI 셰이더 컴파일), 패키징엔 create-dmg
개발 빌드 함정
GPUI는 Metal 셰이더 컴파일러를 탄다

GPUI의 gpui_macos 빌드 스크립트가 Apple의 metal 셰이더 컴파일러를 요구한다. Nix(devenv) 환경에서는 DEVELOPER_DIR·SDKROOT 등 환경변수가 맞지 않으면 _write/_sysconf 같은 심볼 링크 에러가 난다. devenv.nix를 바꾼 뒤엔 direnv reload로 셸을 다시 로드해야 한다 — 이 디테일이 DEVELOPMENT.md에 길게 적혀 있을 만큼 흔한 함정이다.

8직접 해볼 수 있는 실습 과제

난이도별로 손에 잡히는 과제 5개
난이도 ★ — 워밍업

1. 빌드해서 CLI로 내 마우스 들여다보기

저장소를 클론하고 cargo run -p openlogi --release -- list로 페어링된 기기(슬롯·코드명·온라인·배터리)를 출력해본다. 이어 openlogi diag features로 내 마우스가 보고하는 HID++ feature 목록을 덤프해, 0x2201/0x2111이 실제로 보이는지 확인.

난이도 ★★ — 설정 다루기

2. TOML만으로 앱별 프로필 만들기

~/.config/openlogi/config.toml을 직접 편집해, VS Code가 앞에 있을 때만 Back 버튼이 Undo가 되도록 per_app_bindings."com.microsoft.VSCode" 블록을 추가한다. 앱 포커스를 바꿔가며 동작이 실시간으로 전환되는지 관찰.

난이도 ★★★ — 프로토콜 읽기

3. DPI 변경의 왕복(round-trip) 추적

OPENLOGI_LOG=debug openlogi diag dpi를 돌리며 "읽기→쓰기→되읽기→복원" 시퀀스의 로그를 따라간다. openlogi-hidpp 소스에서 0x2201 요청 패킷이 어떤 바이트로 조립되는지 코드와 로그를 1:1로 맞춰보기.

난이도 ★★★★ — 새 액션 추가

4. 버튼 액션 카탈로그에 항목 하나 추가

openlogi-core의 버튼/액션 카탈로그(41개 내장 액션)에 새 액션을 정의하고, openlogi-hook이 그 액션을 실제 OS 이벤트로 변환하도록 연결한다. "순수 코어에 규칙 추가 → 부수효과 어댑터에서 실행"이라는 경계가 왜 편한지 체감.

난이도 ★★★★★ — 플랫폼 확장

5. Linux 후킹 스텁을 진짜로 채우기

현재 Unsupported로 비어 있는 Linux 이벤트 훅을 evdev/libinput 기반으로 일부라도 구현해본다. 코어·HID 계층은 건드리지 않고 openlogi-hook만 확장하면 된다는 설계의 장점을 직접 확인. (가장 임팩트 큰 기여 지점이기도 하다.)

9관련 기술 심화 학습 로드맵

4주 코스로 "Rust 시스템 데스크톱 앱"을 내 것으로
주차주제할 일
1주차Rust 워크스페이스 & 모듈 경계다중 크레이트 워크스페이스 구성, [workspace.dependencies]·[workspace.lints] 적용, "순수 코어 + 어댑터" 분리 직접 구현
2주차HID & 비동기 I/Oasync-hid로 기기 열기/리포트 읽기, tokio 기초, HID++ feature page 개념과 0x2201·0x2111 분석
3주차GPUI 네이티브 UIGPUI 창·상태·이벤트 루프, gpui-component로 리스트/캐러셀 만들기, git rev 고정으로 외부 UI 의존성 관리
4주차OS 후킹 & 배포macOS CGEventTap·접근성·앞 앱 감지, xtask+create-dmg 패키징, R2 정적 매니페스트로 자체 업데이트 채널
학습 순서의 논리

일부러 "안에서 밖으로" 순서다. 1주차에 경계(코어/어댑터)를 먼저 몸에 익혀야, 이후 HID·UI·OS 후킹이라는 서로 다른 "부수효과"들이 왜 각자의 크레이트로 격리되는지가 자연스럽게 이해된다. 마지막 주차의 배포까지 마치면, "기능 → 패키징 → 업데이트"의 데스크톱 앱 전체 수명주기를 한 바퀴 돌게 된다.

10핵심 키워드 사전

이 문서에 나온 주요 용어 정리
PROTOCOL
HID++ (feature page · feature ID)
로지텍이 표준 HID 위에 얹은 비공개 확장 프로토콜. 기능마다 feature ID(예: 0x2201 DPI, 0x2111 SmartShift)가 있고, 해당 "feature page"에 정해진 패킷을 보내 명령한다.
CONCEPT
local-first (로컬 우선)
데이터·설정·동작이 기본적으로 내 기기에 머물고, 네트워크는 선택(opt-in)인 설계 철학. OpenLogi는 설정을 디스크 TOML에 두고 텔레메트리·계정을 없앴다.
UI FRAMEWORK
GPUI
코드 에디터 Zed를 만든 팀이 개발한 Rust용 GPU 가속 UI 프레임워크. Electron(웹뷰)이 아닌 네이티브 렌더링으로 가볍고 빠른 데스크톱 앱을 만든다.
macOS API
CGEventTap (Core Graphics Event Tap)
macOS에서 마우스·키보드 입력 스트림에 끼어들어 이벤트를 관찰·변형·소비하는 API. OpenLogi는 이걸로 옆버튼 클릭을 가로채 다른 동작으로 바꾼다. 사용에 접근성 권한이 필요하다.
HARDWARE
SmartShift · DPI · Logi Bolt
SmartShift는 스크롤 휠을 "한 칸씩 걸리는 모드 ↔ 자유롭게 도는 모드"로 전환하는 기능. DPI는 마우스 이동 민감도(높을수록 작은 손동작에 커서가 많이 움직임). Logi Bolt는 로지텍의 보안 USB 수신기(Unifying의 후속).
RUST/BUILD
workspace · crate · xtask · MSRV · LTO
crate는 Rust의 컴파일·배포 단위, workspace는 여러 crate를 한 저장소로 묶는 단위. xtask는 빌드 자동화를 워크스페이스 멤버 바이너리로 두는 관례. MSRV는 최소 지원 Rust 버전(여기선 1.88). LTO는 링크 시점 최적화로 바이너리를 더 빠르고 작게 만든다.
INFRA
devenv/Nix · Cloudflare R2 · updater manifest
devenv/Nix는 "누가 빌드해도 똑같은" 재현 가능한 개발 환경을 만든다. Cloudflare R2는 S3 호환 오브젝트 스토리지로, OpenLogi는 여기에 DMG와 latest.json(업데이트 매니페스트)을 올려 자체 업데이트 채널을 운영한다.

11참고 링크

원문과 함께 보면 좋은 자료