데스크톱macOS설계

좁은 창은 빼지 않고 눕혔다

2026.08.07

어두운 맥 바탕화면 위에 크롬 창 세 개가 겹쳐 있고, 각 창의 윗변마다 아주 작은 병사들이 어깨를 맞대고 빽빽하게 늘어서 있다. 창마다 왼쪽 끝에 붉은 깃발이 달린 사다리가 바닥까지 걸쳐져 있고, 오른쪽 아래에 나무 트로이 목마가, 화면 맨 아래에 또 한 줄의 병사들이 있다

20초 동안 키보드도 마우스도 건드리지 않으면 해치가 열린다. 사다리가 내려오고 병사들이 쏟아져 나와서, 지금 열려 있는 창의 윗변을 점령한다.

위 스크린샷에서 병사들이 늘어선 저 가로줄은 그림이 아니다. 그 크롬 창의 윗변이다. 창을 옮기면 그 위에 선 병사들도 같이 따라간다.

키보드나 마우스를 건드리는 순간 전원 후퇴한다.

8월 7일 하루에 커밋을 셋 냈다. 페이지를 만들고, 기능을 늘리고, 써 둔 설명을 지웠다. 그 순서가 이 글이다.

선봉장이 사다리를 세울 때까지 아무도 안 올라간다

제일 신경 쓴 규칙이다.

한 명이 사다리를 어깨에 메고 창 밑까지 달려가서 세운다. 먼저 올라가 왼쪽 끝에 깃발을 꽂는다. 그전에는 아무도 올라가지 않는다.

창 하나를 점령하는 순서
1
선봉장이 달려간다사다리를 메고 창 밑까지 — 그전엔 아무도 안 움직인다
↓
2
깃발을 꽂는다먼저 올라가 왼쪽 끝에
↓
3
나머지가 오른다같은 사다리로 줄줄이, 어깨가 닿을 만큼 빽빽하게
↓
4
다음 창으로또 다른 선봉장이 사다리를 메고 나간다

이 단계를 생략하면 병사들이 창 위에 그냥 나타난다. 그러면 순간이동이지 점령이 아니다. 사다리는 장식이 아니라 「어떻게 저기 올라갔는가」에 대한 답이고, 그 답이 화면에 보여야 이야기가 성립한다.

넓은 창 하나에 스무 명 넘게 들어간다. 창을 하나도 남김없이 뺏고 나면 그 자리에서 다 같이 춤을 춘다.

거르던 창을 되살렸다

페이지를 올리고 나서 같은 날 두 번째 커밋으로 필터 두 개를 걷어냈다.

원래는 이렇게 적어 뒀었다.

너무 좁거나 화면 꼭대기에 붙은 창은 후보에서 뺍니다

넣을 때는 합리적이었다. 좁은 창에는 병사가 몇 명 안 들어가고, 화면 꼭대기에 붙은 창은 사다리를 세울 공간이 없다. 둘 다 제대로 보여줄 수 없는 경우라서 뺐다.

문제는 그 판단이 화면에는 「아무 일도 안 일어남」으로만 나타난다는 것이다. 걸러진 창을 보고 있는 사람에게는 앱이 꺼져 있는 것과 구별되지 않는다.

그래서 거르는 대신 행동을 줬다.

걸렀을 때
행동을 줬을 때
좁은 창후보에서 제외
좁은 창좁은 대로 두세 명만 올라간다
설 자리가 없는 창후보에서 제외
설 자리가 없는 창누워서 점령한다
코드짧다
코드길다
사용자가 보는 것아무 일도 안 일어난다
사용자가 보는 것뭔가 일어난다

필터는 코드를 줄이지만 세계를 줄인다. 조건에 안 맞는 경우를 없애면 그 경우를 다루지 않아도 되는데, 사용자 입장에서는 없어진 게 아니라 고장 난 것이다. 두세 명만 올라간 좁은 창은 멋있지는 않아도, 아무 일 없는 창보다 낫다.

그리고 「알려진 한계」에 적어 뒀던 그 줄을 지웠다. 한계였던 것이 동작이 됐으니 한계 목록에 있으면 틀린 설명이다.

설명을 여섯 문단 지웠다

세 번째 커밋이다. 페이지에서 이걸 전부 뺐다.

  • 「무슨 일이 일어나는가」의 도입 문단
  • 「창을 가리지 않습니다」
  • 「목마가 멈추는 이유」
  • 「창은 진짜 창입니다」
  • 「손대는 순간 후퇴」
  • 「권한을 하나도 요구하지 않습니다」

여섯 문단 다 사실이고, 다 좋은 말이었다. 그래서 쓸 때는 지울 이유가 없었다.

문제는 이게 전부 스크린샷 한 장이 이미 하고 있는 말이었다는 것이다. 창 위에 병사가 서 있는 그림을 보고 나면 「창은 진짜 창입니다」를 읽을 필요가 없다. 20초 뒤에 나타났다가 손대면 사라지는 건 한 번 켜 보면 3초 만에 안다.

남긴 것은 이 순서다.

스크린샷 → 다운로드 → 3단 카드 → 설치하기 → 메뉴 막대 → 알려진 한계

받고 나서 필요한 것만 남겼다. 받기 전에 궁금한 건 그림이 대답하고, 받고 나서 궁금한 건 글이 대답한다.

설정 창을 안 만들었다

메뉴 막대에 넷이 있다.

메뉴 막대
항목
하는 일
잠시 끄기
오버레이를 통째로 숨긴다. 다시 켜면 그대로 돌아온다
출격 대기
10초 · 20초 · 30초 · 1분 · 3분. 바로 적용되고 다음 실행 때도 기억한다
최장 점령
가장 오래 점령했던 시간. 알림도 배지도 없고 여기서만 보인다
종료
⌘Q

설정 창은 없다. 고를 것이 출격 대기 하나뿐인데 창을 띄우면, 그 창을 닫는 일이 설정을 바꾸는 일보다 번거로워진다.

「최장 점령」도 같은 생각으로 뒀다. 기록은 남기되 알림도 배지도 안 띄운다. 궁금한 사람만 메뉴를 열어 본다. 몰래 노는 앱이 자기 기록을 자랑하면 몰래가 아니다.

탭이 하나면 탭이 아니다

WebSwing 페이지에는 맥·윈도우 플랫폼 탭이 있다. 같은 구조로 만들다가 DeskTroy에는 안 넣었다.

지금은 맥뿐이다. 탭 하나짜리 탭 UI는 고를 것이 있다고 말해 놓고 고를 게 없는 화면이다. 윈도우 버전이 생기면 그때 넣으면 된다.

스크린샷에서 내 메모를 잘라냈다

히어로는 합성이 아니라 실제 실행 화면이다. 그런데 원본에는 메모 위젯과 바탕화면 파일 이름이 그대로 읽혔다.

공개 페이지에 개인 메모를 올릴 뻔했다.

잘라냈다. 실제 화면을 쓰는 것과 실제 화면을 그대로 올리는 것은 다른 일이다. 진짜라는 게 중요해서 실제 화면을 쓰는 건데, 진짜라서 딸려오는 것까지 내보낼 이유는 없다.

남은 것

Swift + SpriteKit으로 만들었다. 목마와 병사 그림은 이 프로젝트를 위해 그린 오리지널이다. zip은 유니버설(arm64 + x86_64)로 빌드해 애플 공증까지 마쳤다 — spctl 이 accepted / source=Notarized Developer ID 로 답한다.

한계는 남겨서 적어 뒀다.

  • 앱을 켠 화면 한 대에서만 돈다. 모니터가 여럿이어도 병사들이 화면 사이를 건너다니지 않는다
  • 전체 화면 앱 위에서는 창 정보를 읽을 수 없어 병사들이 화면 맨 아래에만 늘어선다
  • 화면 바닥에 너무 가까운 창은 후보에서 뺀다. 하단 대열과 겹친다

마지막 줄이 재미있다. 필터 두 개를 걷어내면서 하나는 남겼다. 남긴 이유는 「구현이 어려워서」가 아니라 겹쳐서 지저분해 보이기 때문이다. 앞의 둘은 걸러도 되는 줄 알았다가 아니었고, 이건 걸러야 하는 게 맞았다.

돌아보면 그날 한 일이 전부 지운 일이었다.

  • 거르던 창을 지웠다 → 세계가 넓어졌다
  • 써 둔 설명을 지웠다 → 페이지가 읽히게 됐다
  • 스크린샷에서 내 메모를 지웠다 → 올릴 수 있게 됐다

만드는 건 첫 커밋 하나로 끝났고, 나머지 둘은 만들면서 같이 붙어 온 것들을 떼는 일이었다. 필터도 설명도, 넣을 때는 다 이유가 있었다. 이유가 있다는 것과 있어야 한다는 것은 다르다.

같이 읽으면 좋은 글