기능을 빨리 고르고 싶을 때마다 상세 패널 전체를 읽게 하면 흐름이 무거워진다. 반대로 작은 메뉴에 모든 입력과 설명을 넣으면 쉽게 이해하기 어렵다. 북극성에서는 작은 팝업과 기존 상세 화면에 서로 다른 일을 맡기고 두 화면이 같은 프로젝트 문맥을 이어 읽게 했다.

팝업을 열었다는 사실은 실행이 아니다

아이콘과 퍼즐은 기능을 고르는 입구다. 현재 흐름에서 선택한 항목의 메뉴는 Python·노트북 실행과 사용 방법·관리 같은 선택으로 이어진다. 등록·고정·메뉴 열기가 자동으로 업무를 시작한다는 뜻은 아니다. 실제 실행 동작을 골랐을 때 runner로 들어간다.

바로 실행은 현재 탭과 저장된 기본 입력을 읽는다. 그 기본값으로 필요한 계정·대상·내용이 유효하지 않으면 상세 입력을 열어 준비하도록 하는 분기도 있다. 모든 기능을 무조건 한 번 클릭으로 실행하는 편의로 소개하지 않는다. 자주 쓰는 선택은 짧게, 현재 입력을 검토해야 하는 경우는 더 깊게 보내는 방식이다.

설명은 실행 메뉴 안에서 경쟁하지 않게 한다

사용 방법은 기존 오른쪽 입력 화면을 열고 showUsage를 켠다. 상세에는 어떤 기능인지, 어떻게 쓰는지와 작업 순서가 있다. 같은 설명을 팝업에 다시 만들지 않아 정의와 사용법의 정본이 갈라지지 않게 한다.

기능이 바뀌면 상세 설명과 입력 계약을 같이 고쳐야 한다. 작은 메뉴는 그 기능으로 들어가는 입구로 남는다. 관리 화면은 활성화·고정·등록을 다루고 실행 폼은 이번 입력을 다룬다. 네 화면을 같은 종류의 설정 화면이라고 부르면 사용자는 어디서 무엇을 바꿀지 찾기 어렵다. 레이아웃의 깊이를 역할에 맞게 나누는 일이 필요했다.

실제 웹 View 위에 보이는 창에도 계약이 필요하다

현재 확장 팝업은 실제 WebContentsView 위에 표시할 별도 자식 창이다. 전용 preload와 제한된action 스키마를 사용하고 sender·mainFrame·URL을 검사한다. 외부 웹페이지가 그 메뉴 권한을 얻는 구조로 만들지 않는다. 작은 UI도 권한 있는 앱 화면이라는 점은 같다.

폭과 높이는 화면 작업영역에 맞춰 제한하고 새 창 열기와 탐색을 거절한다. 이 코드가 모든 보안 문제를 해결한 인증이라는 뜻은 아니다. 내가 주목한 것은 CSS의 큰 z-index 하나로 모든 창과 권한이 해결된다고 가정하지 않은 점이다. 메뉴가 어디에서 뜨고 누가 요청할 수 있는지 실제 앱 구조에서 확인해야 했다.

열린 뒤 문맥이 바뀌면 처음 대상을 다시 추측하지 않는다

bootstrap은 팝업을 열 때 프로필·프로젝트·탭을 잡고 refresh 뒤와 동작 전에check한다. 그 사이 선택이 바뀌면STALE_PLUGIN_POPUP이다. 메뉴를 열었던 시점과 실제 클릭 시점이 다를 수 있기 때문이다. 비슷한 새 탭에 동작을 넘기지 않는다.

Escape와 닫기는 원래 퍼즐 포커스로 돌아가는 경로가 있고 blur는 팝업을 닫는다. 늦게 닫힌 창이 사용자의 새 포커스를 빼앗지 않도록 현재 문맥을 다시 본다. 이것은 화면이 작다고 사소한 문제가 아니었다. 빠른 선택일수록 사용자는 현재 보는 탭에 적용된다고 기대하므로 오래된 메뉴가 다른 대상에 적용되는 일을 막아야 했다.

바로가기의 성공도 실제 확인한 수준으로 남긴다

기존 문서는 팝업·상세·관리와 포커스·키보드·사용 중지의 시험 범위를 나눠 남긴다. 폴더 열기도 OS API의 오류 없는 반환과 Explorer 화면을 직접 판독한 검수를 구분했다. 링크가 눌렸다는 사실보다 어느 경계의 결과를 읽었는지 적는 방식이다. 저장 모체 폴더를 여는 바로가기와 특정 성공 실행의 결과 폴더도 다르다. 어느 자료를 여는 버튼인지 이름과 검증 대상을 맞춘다.

이번 집필에서는 코드를 읽고 원래 팝업을 실행하지 않았다. 공유 상태 문구 모듈도 합성 자료만 다룬다. 내가 공유하려는 화면 원칙은 작은 메뉴가 모든 설명을 담는 것이 아니라 빠른 선택에서 필요한 입력·근거·관리로 자연스럽게 이어 주는 것이다. 깊이가 나뉘어도 현재 대상과 실행의 뜻은 하나로 이어져야 한다. 이것이 에이전트와 사람이 같은 도구를 편하게 쓰게 하는 조건이었다.