본문으로 건너뛰기

맥에서 한글 입력할 때 들어가는 이상한 문자와, 임시 조치 방법

· 약 4분

애플을 15년 가까이 쓰고 있는데, 애플에서 항상 따라오는 문제가 한글 입력 문제이다. 애플은 왜 한글 입력 문제을 방치하는걸까. 내가 처음 발견한 것도 4년이 넘었는데, 처음에는 vscode같은 에디터의 문제인줄 알았다. 맥용 옵시디언에서 저장하고, iOS에서 노트를 보는데 자꾸 이상한 문자들이 들어가는 것을 발견했다. 윈도우를 쓸 때마다 한글 입력이 원활함을 느낀다. 한글 뿐만아니라 한중일 모두 조합형 문자에서 몇 년째 발견되는 문제인데 왜 고치지 않는걸까. 일단 내가 임시 조치한 방법을 공유한다.

참고로 옵시디언까지는 테스트해봤는데, 아래쪽 구름입력기 부분은 아직 테스트를 안해봤다.

문제가 발생한 현상을 맥 에디터에서 본 경우​

맥 편집 중에는 보이지 않는다​

2년 전까지만해도, 네모 박스가 보였는데, V8 엔진 레벨에서 고친 것으로 보인다.

같은 내용을 iOS 에서 보면 발견된다.​

macOS CJK IME U+0008 삽입 버그

macOS에서 한글을 입력하다 백스페이스를 누르면, 눈에 보이지 않는 제어 문자 U+0008이 텍스트에 삽입된다. macOS에서는 정상으로 보이지만 iOS나 다른 기기에서 열면 네모(□)로 표시된다. 나처럼 예민한 사람에게는 보일텐데, 가끔 유튜브를 보다보면, 제목에 네모가 보이는 경우를 발견한다. 이건 한글뿐 아니라 중국어·일본어(CJK) 전반에 걸친 IME 문제다.

현상

  • 재현 조건: 조합 중인 한글 자소를 백스페이스로 지울 때 발생. 빠르게 타이핑할수록 더 자주 나타난다.
  • macOS에서는 안 보인다: 렌더러가 제어 문자를 무시하기 때문에 입력한 사람은 모른다.
    • VSCode에서는 보인다. 빨간 네모 박스에 BS같은 이상한게 랜더링된다.
  • 다른 기기에서 보인다: iOS, Windows, Linux에서 동일 파일을 열면 □ 또는 ^H로 표시된다.
  • 영향받는 앱: Obsidian, VS Code, 기타 Electron/Chromium 기반 앱 전반. 네이티브 Cocoa 앱(Pages, Notes, Mail)에서는 발생하지 않는다.
  • 미수정 기간: macOS 12 Monterey 이후 Sequoia(2025)까지 공식 패치가 없다.

원인

IME 조합 입력의 구조​

한글·CJK는 자소를 조합해 하나의 글자를 완성하는 조합 입력 (IME Composition) 방식으로 동작한다. 조합이 진행 중인 상태(미확정 문자, marked text)에서 백스페이스를 누르면 macOS IME가 두 가지 신호 중 하나를 앱에 전달한다.

  • 조합 취소 이벤트 → 정상 처리
  • 0x08 제어 문자를 텍스트 버퍼에 직접 삽입 → 버그

왜 Cocoa 앱은 괜찮고 웹 기반 (Electron 포함)은 터지는가​

아래 내용은 검증이 안된 내용이다. 못믿겠다.

macOS IME
└─ 조합 중 백스페이스
├─ Cocoa NSTextView → marked text 취소 처리 (정상)
└─ Electron/Chromium → 0x08을 텍스트 버퍼에 삽입 (버그)

NSTextView 기반 Cocoa 텍스트 스택은 IME의 marked text 이벤트를 직접 처리하도록 설계되어 있다. Electron/Chromium은 크로스플랫폼 렌더러 구조상 macOS IME API와 완전히 통합되지 않아 0x08이 그대로 스트림에 흘러들어간다.

왜 수정이 안 되는가​

Apple과 Chromium 모두 서로에게 책임을 넘기는 구조다.

  • Apple: "네이티브 앱에서는 정상 동작한다. 앱이 API를 잘못 사용하는 것."
  • Chromium: "macOS IME API는 Cocoa에 밀착 설계되어 있어 완전한 통합이 구조적으로 어렵다."

일본·중국 파워 유저들은 오래전부터 서드파티 IME(Google 일본어 입력, 搜狗 등)로 이탈해 이 버그를 경험하지 않는다. ==가장 큰 소리를 낼 수 있는 층이 이미 우회해버린 상태==라 Apple 내부 우선순위가 올라가지 않는다. ==재현 조건도 까다로워(빠른 타이핑 + 조합 중 백스페이스) QA에서 잡히기 어렵다.==

임시 조치: Obsidian

저장 시점에, 문제가 되는 문자, 캐릭터를 지워버리는 접근 방식이다. Obsidian Linter 앱을 사용한다.

기존 파일에서 현상 찾기​

터미널에서 0x08이 포함된 파일을 확인한다.

# 포함된 파일 목록
grep -rl $'\x08' .

# 줄 번호와 함께 확인
grep -Pn "\x08" 파일명.md

Obsidian Linter로 자동 제거​

Linter 플러그인 → Custom Regex Rule 추가:

항목값
Find[\b]
Replace(비워두기)

[\b]를 사용하는 이유: \b는 문자 클래스 [] 안에서 word boundary가 아닌 백스페이스(0x08)를 의미한다. \x08은 일부 JavaScript 정규식 엔진에서 지원하지 않을 수 있으므로 [\b]가 더 안전하다.

임시 조치: 입력기 변경 - 검증 중

구름 입력기 로 교체. 기본 IME 대신 구름 입력기가 IME 조합을 직접 관리하므로 0x08을 시스템에 넘기지 않는다. 설치: gureum.io

관련 이슈