ICEFiction 개발기 ⑧: 아이콘이 □로 보였다 — 맥에 그 글자가 없어서 (v0.10.2)
사이드바의 폴더 아이콘이 빈 사각형이었다. 버그가 아니라 macOS에 그 기호를 그릴 글꼴이 하나도 없었다. 원인을 따라가다 보니, 통과한 줄 알았던 검사 세 개가 맥에서만 조용히 깨져 있었다.
맥에 앱을 설치하고 사이드바를 봤더니 "폴더 추가" 자리에 빈 사각형(□)이 하나 놓여 있었다. 아이콘이 안 그려진 것이다.
버그를 찾으려고 코드를 열었는데, 그 자리에 있는 건 멀쩡한 문자 하나였다. 🗀(U+1F5C0, FOLDER). 윈도우에서 개발할 때는 폴더 모양으로 잘 보였던 글자다.
맥에는 그 글자를 그릴 글꼴이 없다
확인해 보니 원인이 코드가 아니었다. macOS 전체에 그 문자를 그릴 글꼴이 하나도 없다.
🗀는 생김새가 이모지처럼 보이지만 이모지가 아니다. 그래서 Apple Color Emoji에도 없고, Apple Symbols에도, 시스템 기본 글꼴에도 없다. 글꼴을 못 찾으면 macOS는 LastResort라는 최후의 글꼴로 떨어지는데, 그게 그려 주는 것이 바로 그 빈 사각형이다.
윈도우에는 Segoe UI Symbol 안에 이 글자가 들어 있다. 그래서 개발하는 동안에는 아무 문제가 없었다. 이식하고 나서야 드러나는 종류의 문제였다.
바로 위 툴바의 "📁 폴더 열기"는 멀쩡했는데, 그건 📁(U+1F4C1)가 진짜 이모지라서다. 같은 폴더 그림인데 하나는 나오고 하나는 안 나온다.
같은 이유로 깨진 자리를 전부 찾아보니 여섯 곳이었다. 폴더 아이콘 네 곳, 그리고 문단 정렬의 왼쪽·오른쪽 버튼(⯇ ⯈). 정렬 버튼은 가운데·양쪽만 보이고 좌우는 사각형이었을 것이다 — 아직 눌러 보지 않아서 몰랐던 것이다.
대체할 글자를 고르는 것도 확인이 필요했다. 다른 폴더 기호(🗁 U+1F5C1, 🖿 U+1F5BF)도 전부 맥에 없었다. 결국 폴더는 ❑(U+2751), 정렬 좌우는 ◂ ▸로 바꿨다. 기존 섹션 아이콘(✎ ✦ ✍)과 같은 글꼴 계열이라 톤도 맞는다.
솔직히 ❑는 폴더보다는 그림자 있는 사각형으로 읽힌다. 단색 폴더 글리프가 맥에 없다는 게 근본 문제라, 모양을 제대로 살리려면 글꼴 대신 SVG로 그려야 한다. 그건 다음으로 넘겼다.
슬라이더만으로는 0.1을 맞출 수가 없다
설정 화면에서 문단 간격을 조절해 보니 슬라이더 하나뿐이었다. 0.7em을 정확히 맞추려면 손가락으로 더듬어야 하고, 지금 값이 얼마인지는 옆의 글자로만 알 수 있다.
숫자칸과 위아래 화살표를 붙였다. 이제 조절하는 방법이 네 가지다 — 슬라이더 끌기, 숫자 직접 입력, ▴▾ 누르기, 숫자칸에서 방향키. 글자 크기·줄 간격·문단 간격·들여쓰기 폭·표지 제목 크기, 앱에 있던 슬라이더 다섯 곳 전부에 넣었다.
여기서 따로 다뤄야 했던 게 부동소수점이다. 자바스크립트에서 0.7 + 0.1은 0.8이 아니라 0.7999999999999999다. 그대로 두면 그 값이 CSS로 내려간다. 스텝 단위로 반올림해 막고, 0에서 2까지 스무 번 올려도 오차가 쌓이지 않는 것을 테스트로 고정했다.
그리고 숫자칸에 커서가 있는 동안 화살표를 눌러도 숫자가 안 움직이는 버그가 있었다. 값은 바뀌고 원고도 실제로 벌어지는데 화면의 숫자만 그대로여서, 고장처럼 보인다. 타이핑 중에 표기를 밖에서 덮어쓰지 않도록 막아 둔 장치가 화살표 입력까지 막고 있었다. 이건 사람이 아니라 E2E가 먼저 짚었다.
Ctrl+A가 맥에서는 전체 선택이 아니다
아이콘을 고친 뒤 검사를 돌렸더니 두 개가 실패했다. 하나는 "일부만 골라 가운데 정렬하면 엉뚱한 줄까지 정렬된다"였다. 원고를 다루는 기능이 깨진 것이라 심각해 보였다.
내가 방금 고친 것 때문인지 확인하려고, 손대기 전 상태를 별도 폴더에 꺼내 같은 검사를 돌렸다. 똑같이 실패했다. 내가 만든 문제가 아니었다. 그런데 그건 곧 이미 배포한 버전에 들어 있다는 뜻이었다.
실패 메시지에 찍힌 원고 내용을 보니, 지웠어야 할 안내 문단이 그대로 남아 있고 그 아래에 새 문단이 덧붙어 있었다. 검사는 이렇게 시작한다.
Ctrl+A → 전체 선택 → 새 원고 입력
맥에서는 Ctrl+A가 전체 선택이 아니다. CodeMirror의 맥 키맵에서 Ctrl-a는 "줄 처음으로 이동"이다. 전체 선택은 Cmd+A다. 앱은 처음부터 플랫폼에 맞게(Mod-) 바인딩해 두었는데, 검사 코드만 Control+로 못박혀 있었다.
그래서 원고가 지워지지 않은 채 글자가 덧입력되고, 그 뒤 단계들이 줄줄이 어긋났다. 정렬이 엉뚱한 줄을 잡은 것도 정렬이 고장 난 게 아니라 문서가 검사가 가정한 모양이 아니었기 때문이다. 제품은 멀쩡했다.
수정키를 플랫폼에 맞추자 32개가 전부 통과했다.
두 번째 실패는 "삽화 프롬프트 초안이 비어 있다"였다. 이것도 제품이 아니었다. 창이 뜬 바로 그 순간 값을 읽어서, 아직 채워지기 전의 빈칸을 잡은 것이다. 실제로 열어 보면 초안이 제대로 들어 있다. 화면 갱신은 클릭보다 한 박자 늦으니, 자동 검사에서 값을 확인할 때는 기다렸다 읽는 것이 원칙이다.
목록에 없는 검사는 아무도 안 본다
세 번째가 더 뼈아팠다. AI 첨부 관련 검사 하나가 계속 실패하고 있었다. 예전에는 "AI가 이미지를 직접 못 봅니다"라고 안내했는데, 지금은 파일 경로를 주고 AI가 직접 열어 보게 바뀌었다. 앱이 좋아진 것이고, 검사만 옛 문구를 찾고 있었다.
문제는 이 검사가 배포 검사 목록(npm test)에 들어 있지 않았다는 점이다. 그래서 배포할 때 아무도 안 돌렸고, 실패한 채로 남아 있었다. 지난 개발일지에도 "이번 작업과 무관한 기존 실패"라고 적어 두고 넘겼던 흔적이 있다. 무관한 건 맞았지만, 무관하다고 적어 둔 채로 두 번이나 지나간 것이다.
문구를 현재 동작에 맞추고, 그 검사를 목록에 넣었다. 이제 같은 일이 생기면 배포 전에 걸린다.
태그 하나로 두 플랫폼
여기까지 고쳐 놓고 보니 배포 경로가 반쪽이었다. 태그를 밀면 맥용 dmg는 서명·공증까지 자동으로 나오는데, 윈도우용 exe는 윈도우 컴퓨터에서 손으로 만들어 올려야 했다.
윈도우 빌드도 CI에 넣었다. 이제 태그 하나를 밀면 양쪽이 같은 시점에, 같은 코드로 나온다. 둘 다 타입 검사와 테스트를 통과해야 설치 파일이 만들어진다.
한 가지 신경 쓴 것은, 두 빌드가 같은 태그에서 동시에 돌면서 릴리스를 서로 만들려고 다툴 수 있다는 점이었다. 양쪽에 "상대가 먼저 만들었으면 그걸 쓴다"는 방어를 넣었다.
실제로 v0.10.2를 밀어 보니 윈도우가 2분 26초, 맥이 3분 51초에 끝났고 둘 다 릴리스에 붙었다. 내려받아 확인한 dmg는 앱과 껍데기 둘 다 공증이 유효했다.
이번에 배운 것
- 맥에 없는 글자가 생각보다 많다. 이모지처럼 보인다고 이모지가 아니다. 아이콘을 글꼴 문자로 쓸 거면 대상 OS에서 실제로 그려지는지 확인해야 한다.
- 검사가 실패했을 때 제품을 먼저 의심하면 시간을 잃는다. 고치기 전 상태를 꺼내 같은 검사를 돌려 보는 것이 가장 빠른 판별법이었다. 이번에는 세 건 모두 검사가 낡은 것이었다.
- 자동 검사도 플랫폼을 탄다. 단축키 하나 때문에 검사 전체가 조용히 어긋날 수 있다. 그리고 그 실패는 엉뚱한 곳에서 터진다.
- 목록에 없는 검사는 존재하지 않는 것과 같다. "무관한 기존 실패"라고 적는 순간 그건 방치된다.
v0.10.2는 GitHub 릴리스에서 내려받을 수 있다. 앱을 쓰고 있으면 켤 때 알림이 뜬다.