나는 한 가지 일을 하는 Mac 앱을 만들었다: 키보드를 청소하게 해준다

발행: (2026년 3월 29일 PM 07:36 GMT+9)
14 분 소요
원문: Dev.to

Source: Dev.to

위에 제공된 Source 링크만 그대로 두고, 번역하고자 하는 본문 텍스트를 알려주시면 한국어로 번역해 드리겠습니다.
(코드 블록, URL, 마크다운 형식 등은 그대로 유지됩니다.)

문제

모든 MacBook 사용자는 이 순간을 알고 있습니다:

  • 키보드를 닦기 위해 천을 잡고, 키를 누르는 순간 Spotlight가 열립니다.
  • 트랙패드를 스치면 커서가 화면을 가로질러 움직입니다.
  • 기능 키 행을 닦으면 볼륨이 변하고, 밝기가 낮아지며, 음악이 끊깁니다.

기계를 청소하려고 하는데, 기계가 청소를 명령으로 계속 해석합니다.

겉보기에 사소해 보이지만, 그렇지 않습니다.

이 작은 불편함 때문에 Mac Pause를 만들게 되었습니다. 이를 만들면서 macOS가 실제로 어떻게 동작하는지 많은 것을 배웠습니다.

기존 우회 방법이 통하지 않는 이유

  • Shut down – 빠른 초기화를 위한 과도한 방법.
  • Lock the screen – 키와 제어가 여전히 예상치 못한 방식으로 작동합니다.
  • Be careful – “키보드를 조심스럽게 청소하는 것”은 목적에 어긋납니다.

부족했던 것은 간단했습니다: macOS에서 모든 입력을 일시적으로 안전하게 중단하여 어떤 표면을 터치해도 문제가 없도록 하는 방법.

비전

  • Small – “MVP 나중에 확장하겠다”가 아니라 전체 제품을 의미합니다.
  • One‑job menu‑bar utility:
    1. 청소 세션을 시작합니다.
    2. 키보드와 포인터 입력을 차단합니다.
    3. 사용자가 의도적으로 잠금을 해제할 때만 종료합니다.
    4. 문제가 발생했을 경우를 대비해 안전 타임아웃을 포함합니다.

설정 패널에 40개의 옵션이 없습니다. 구독도 없습니다. 시스템 튜너 야망도 없습니다. 한 문장으로 앱이 무엇을 하는지 설명할 수 있어야 하며, 그렇지 않다면 범위가 잘못된 것입니다.

“당연히 Mac에 청소 모드가 있어야죠.” – 내가 목표로 했던 반응입니다.

기술적 현실

macOS는 깊은 보안 계층을 가진 정교한 운영 체제입니다. 키보드와 마우스 입력을 가로채고 차단하려는 앱은 바로 할 수 없습니다. 명시적인 사용자 권한을 얻어야 합니다:

  • 접근성
  • 입력 모니터링

이러한 권한은 보안에 필수적이지만, “한 가지 간단한 기능” 유틸리티에게는 즉각적인 마찰을 일으킵니다. 권한 부여 흐름이 혼란스럽거나 공격적으로 느껴지면 사용자는 앱을 신뢰하지 않아 권한을 부여하지 않을 것입니다.

이벤트 억제

일반적인 (커널이 아닌) 앱의 실용적인 접근 방식은 이벤트 억제입니다:

  • 입력 이벤트를 가로챕니다.
  • 시스템의 나머지 부분에 도달하지 못하도록 차단합니다.
  • 여전히 신뢰할 수 있는 잠금 해제 경로를 유지합니다.

잠금 해제 경로는 협상할 수 없습니다. 모든 입력을 차단하고 멈춰버리는 유틸리티는 노트북을 벽돌처럼 만들게 됩니다. Mac Pause는 다음이 필요했습니다:

  1. 의도적인 잠금 해제 메커니즘.
  2. 상황에 관계없이 항상 제어를 복구하는 강제 타임아웃.

Root cause: Function keys (brightness, volume, media controls) sometimes travel through a legacy system‑defined event pipeline, separate from regular keyboard events. So “keyboard blocked” didn’t actually mean “all keyboard‑looking input blocked.”

예상치 못한 도전 과제

Function‑Key Quirk

키 차단과 마우스 입력 차단이 정상적으로 동작하고 있었습니다. 모든 것이 괜찮아 보였지만, 기능 키 행을 테스트로 닦아내자 볼륨이 바뀌었습니다.

Root cause: Function keys (brightness, volume, media controls) sometimes travel through a legacy system‑defined event pipeline, separate from regular keyboard events. So “keyboard blocked” didn’t actually mean “all keyboard‑looking input blocked.”

문제의 처음 90 %는 주말에 해결할 수 있지만, 마지막 10 %는 OS 가정이 시험대에 오르는 부분입니다.

Unlock Mechanism Design

단순히 “Escape를 눌러 종료”하는 방식은 Escape 키 자체를 닦아낼 가능성이 높아 작동하지 않습니다. 다음과 같은 방법이 필요했습니다:

  • 터치할 수 없는 단일 키에 의존하지 않음.
  • 청소 중에 실수로 트리거될 가능성이 낮음.
  • 의도된 행동처럼 느껴짐 (안전성 관련).

Solution: Hold‑based chordRight Shift + Escape 를 짧은 시간 동안 누르고 있으면 잠금 해제.

  • 실수로 발동될 가능성이 낮음.
  • Escape 키만 청소할 수 있음 (Right Shift만 누르지 않으면 됨).
  • 누르고 있는 시간 요구가 의도된 행동임을 나타냄.

Permission‑Setup Flow Bug

한때 권한 프롬프트가 전체 화면 시스템 오버레이처럼 동작해 닫기 어려웠습니다. “갇힌 느낌”이 들지 않게 설계된 앱이 설정 중에 사용자를 가두는 상황이었습니다.

Redesign:

  • 더 작은 유틸리티 창.
  • 필요한 권한과 해당 권한을 찾는 위치에 대한 명확한 안내.
  • macOS가 일관되지 않을 때(예: 정확한 설정 페이지에 대한 딥링크가 없는 경우) 정직한 메시지 제공.

이러한 차분한 흐름은 전체 앱을 개선했습니다. 시스템 특이점에 대해 정직하게 알리는 것이 매번 완벽히 동작한다는 척보다 더 좋은 UX임이 밝혀졌습니다.

Packaging & Identity

macOS 개인정보 권한은 앱이 어떻게 패키징되고 식별되는지에 민감합니다. 개발 중에 순수 실행 파일을 실행하는 것은 올바르게 서명되고 번들된 앱을 실행하는 것과 다릅니다. 이는 다음에 영향을 미칩니다:

  • 시스템이 부여된 권한을 기억하는지 여부.
  • 사용자에게 표시되는 권한 프롬프트의 형태.

요점

  1. 권한은 핵심 UX이며, 부수적인 기능이 아닙니다.
  2. 이벤트 파이프라인은 다를 수 있습니다 (일반 키 vs. 기능 키).
  3. 잠금 해제 메커니즘은 안전하면서도 청소 세션 중에 접근 가능해야 합니다.
  4. 투명하고 차분한 온보딩이 화려하지만 혼란스러운 대화 상자보다 효과적입니다.
  5. 패키징은 프라이버시 권한과 사용자 신뢰에 중요한 역할을 합니다.

최종 생각

Mac Pause 개념은 직관적이었지만, 이를 구현하려면 macOS의 보안 및 이벤트‑처리 내부를 깊이 파고들어야 했습니다. 그 결과는 존재하면 당연하게 느껴지는, 단일 목적의 작은 유틸리티가 되었습니다—제가 달성하고자 했던 바로 그 반응입니다.

Mac Pause – 화면 청소를 위한 작은 메뉴‑바 유틸리티

앱이 하는 일

  • 청소 세션 시작 – 무장을 위한 카운트다운이 마우스를 놓을 시간을 줍니다.
  • 입력 차단 – 모든 것이 청소되는 동안.
  • 종료Right Shift + Escape를 누른 채로 하거나 자동 타임아웃이 세션을 종료하도록 합니다.

중요한 추가 기능

  • 부분 잠금 모드 – 키보드 전용 또는 포인터 전용으로 목표 청소.
  • 고정 배경 모드 – 화면 자체를 청소할 때 유용합니다.
  • 로그인 시 자동 실행 지원.
  • 보이는 오버레이 – 앱이 활성화된 것을 항상 알 수 있습니다.

배포

앱은 직접 다운로드(앱 스토어 외) 형태로 제공되어 검토 절차와 샌드박스 제한을 피하고, 작은 유틸리티에 발생하는 마찰을 줄입니다.

패키징이 중요한 이유

개발 중 시스템 설정에 필수 권한이 부여된 것으로 표시되었지만 앱이 여전히 입력을 차단하지 못하는 혼란스러운 상황을 겪었습니다. 해결은 코드 변경이 아니라 올바른 패키징이었습니다:

  1. 안정적인 번들 식별자를 가진 실제 .app 번들.
  2. 앱 아이콘.
  3. 배포용 깔끔한 zip 파일.

안정적인 번들 ID와 올바른 패키징은 유틸리티가 신뢰성 있게 동작하는 것과 “대부분” 동작하는 것의 차이를 만듭니다.

작은 도구 다듬기

핵심 기능인 입력 차단은 전체 노력의 일부분에 불과했습니다. 대부분의 작업은 다음과 같습니다:

  • 권한 흐름(접근성 및 입력 모니터링).
  • 기능키와 잠금 해제 안전성에 대한 엣지 케이스.
  • 패키징 및 배포.
  • 사용자가 키보드와 마우스에 대한 전체 제어를 허용하도록 신뢰할 수 있는 경험 제공.

전체 제품이 단일 상호작용이라면 모든 거친 부분이 눈에 띄므로 높은 수준의 다듬기가 필수적입니다.

Source:

시작하기

다운로드 및 설치

  1. Download 최신 MacPause‑.zip 파일을 릴리즈 페이지에서 다운로드합니다.
  2. Unzip 파일을 압축 해제합니다.
  3. Open Mac Pause.app을 엽니다.
  4. (선택 사항) Drag하여 /Applications 폴더에 넣어 설치된 상태로 유지합니다.

첫 실행 단계

  • macOS에서 개발자를 확인할 수 없다는 경고가 나오면, right‑click(우클릭) 후 Open을 선택합니다.
  • 요청 시 AccessibilityInput Monitoring 권한을 부여합니다 (시스템 설정 → 개인정보 및 보안).
  • Input Monitoring을 활성화한 후 앱을 Quit(종료)하고 reopen(다시 열기)합니다; macOS는 권한을 인식하기 위해 앱을 한 번 재시작해야 할 때가 많습니다.

Gatekeeper 차단?

Gatekeeper가 여전히 앱을 차단한다면, 터미널에서 격리 플래그를 제거합니다:

xattr -dr com.apple.quarantine "/Applications/Mac Pause.app"

직접 빌드하기

# Build the .app bundle
./Scripts/build_app_bundle.sh

# Run the bundled app
./Scripts/run_bundled_app.sh

Note: macOS 13 이상이 필요합니다.

오픈 소스

전체 소스 코드는 GitHub에서 확인할 수 있습니다:

🔗 github.com/gloverola/macPause

유틸리티가 유용하다고 생각되시면, 저장소에 ⭐를 눌러 주세요 – 더 많은 사람들이 프로젝트를 발견하는 데 도움이 됩니다.

0 조회
Back to Blog

관련 글

더 보기 »

Neovim 0.12.0

텍스트 NVIM v0.12.0 빌드 유형: Release LuaJIT 2.1.1774638290 릴리즈 노트 - 체인지로그 https://github.com/neovim/neovim/commit/fc7e5cf6c93fef08effc183087a2c8cc9bf...