DAY 04작업 4일째

끄는 동안에도 카드가 코어를 따라오게 했다

코어를 놓을 때 한 번에 하던 카드 방향 판단을 끄는 중에 하게 바꾸고, 모니터를 넘는 순간만 조각을 잠깐 감추게 했다.

놓는 순간에 깜빡이며 자리를 잡았다

코어를 끌어 다른 모니터로 넘기고 손을 놓으면, 위젯이 한 번 깜빡인 뒤 카드와 목록이 새 자리를 잡았다. 열려 있던 카드도 그때 반대편으로 옮겨 갔다. 끄는 동안에는 카드가 원래 방향을 고집해서, 화면 가장자리로 가면 카드 일부가 화면 밖으로 나가기도 했다.

일부러 그렇게 만든 동작이었다. 카드가 나오는 좌우 방향과 목록이 열리는 위아래 방향을 끄는 동안에는 고정하고, 놓은 뒤에만 다시 정했다. 예전 위젯은 방향이 바뀌면 창 크기가 바뀌었고, 창을 옮기는 순간과 내용을 다시 그리는 순간이 한 프레임 어긋나 내용이 튀었다. 그래서 크기가 바뀔 일을 끄는 동안 미뤄 두고, 놓을 때 위젯을 잠깐 감춘 사이에 한 번만 바꿨다.

Electron으로 옮기면서 창은 모니터 하나를 통째로 덮고 크기가 바뀌지 않게 됐다. 방향이 바뀌어도 창 안에서 조각의 위치만 바뀐다. 방향을 미뤄 둘 이유가 사라졌는데 미루는 동작만 남아 있었다.

방향을 끄는 중에 정한다

코어가 움직일 때마다 방향을 다시 계산하게 했다. 모니터 가운데를 넘으면 카드가 그 자리에서 반대편으로 넘어가고, 화면 위쪽에 닿아 목록이 위로 열릴 자리가 없으면 아래로 열린다.

그대로 두면 경계선 위에 코어를 올려 둔 채 손이 조금만 떨려도 카드가 좌우로 계속 뒤집힌다. 그래서 방향마다 경계에 여백을 뒀다.

방향바뀌는 조건
카드 좌우코어 중심이 모니터 가운데를 40px 넘어갔을 때
목록 위로코어 위쪽에 목록 높이보다 20px 더 남을 때
목록 아래로코어 위쪽에 목록이 들어갈 자리가 없을 때

여백 안에서는 지금 방향을 그대로 둔다. 방향이 바뀐 카드와 목록, 채팅 카드는 새 자리에서 0.14초 동안 흐릿하게 나타난다. 순간이동처럼 보이지 않게 하려는 짧은 전환이다.

이 판단을 끄는 중에만 쓰면 안 됐다. 위젯은 0.5초마다 세션 상태를 읽고 다시 배치하는데, 그때 쓰던 방향 판단은 여백 없이 가운데만 봤다. 여백 안에 코어를 놓으면 놓은 직후의 갱신에서 방향이 다시 뒤집힌다. 그래서 끄는 중과 평소 갱신이 같은 판단 함수를 쓰게 했다.

function sides(isFresh) {
  const mid = S.left + coreSize() / 2 - (S.area.x + S.area.width / 2)
  let willLeft = S.isCardsLeft
  if (isFresh) willLeft = mid > 0
  else if (mid > SIDE_MARGIN) willLeft = true
  else if (mid < -SIDE_MARGIN) willLeft = false
  // 목록의 위아래도 같은 방식
}

isFresh는 처음 띄울 때와 다른 모니터로 막 넘어갔을 때다. 이때는 이전 방향이 의미가 없어서 여백 없이 새로 정한다.

모니터를 넘을 때만 잠깐 감춘다

다른 모니터로 넘어갈 때는 여전히 창을 옮겨야 한다. 창은 메인 프로세스가 옮기고 조각은 페이지가 배치하니, 둘을 같은 프레임에 맞출 수 없다. 창이 새 모니터로 간 사이에 조각이 예전 모니터 기준 좌표에 한 프레임 그려지면 튄다.

그래서 코어 중심이 모니터 경계를 넘는 순간 위젯을 투명하게 하고, 메인 프로세스에 창 이동을 부탁한다. 새 모니터의 작업 영역을 돌려받으면 방향을 새로 정하고 배치한 뒤, 두 프레임 뒤에 다시 보이게 한다. 창이 옮겨 가는 동안 들어온 마우스 움직임은 위치만 기록하고 배치는 하지 않는다. 기다리는 동안 이동 요청이 겹쳐 나가지 않게 하려는 것이다.

손을 놓았을 때 하던 재배치와 깜빡임은 없앴다. 놓기 전에 이미 자리가 맞춰져 있어서 위치만 저장한다.

감수한 것

모니터를 넘는 순간에는 위젯이 두 프레임쯤 사라진다. 놓을 때마다 깜빡이던 것보다는 드물고 짧다. 여백 때문에 코어가 가운데를 조금 넘은 정도로는 카드가 원래 쪽에 남는다. 손이 떨려 뒤집히는 것보다 낫다고 봤다.

기록 #08 · 2026.10.06