본질
samples/hwpctl_Action_Table__v1.1.hwp (16p, landscape, margin_bottom=0) 의 페이지 16 하단 자동번호(Page) 텍스트박스 (master page 글상자 — secIdx=0, paraIdx=0, controlIdx=0 anchored) 를 더블클릭 시:
| 환경 |
동작 |
| 한컴 |
문서 마지막 } 캐럿 (= master page 위 dblclick 을 본문 가장 가까운 caret 으로 fallback) |
| RHWP |
viewport 가 첫 페이지 부근으로 점프 (사용자 보고: "페이지 2, 3 이동", e2e 측정: scroll −11288px, visible pages = [0, 1]) |
정량 측정 (e2e, 2026-05-07)
rhwp-studio/e2e/body-outside-click-fallback.test.mjs + 정밀 측정 (페이지 번호 textbox bbox 정확한 위치 click).
Step 1 — Layout dump (page 15):
{ "controls": [
{"type": "shape", "x": 113.4, "y": 740, "w": 75.6, "h": 21.5,
"secIdx": 0, "paraIdx": 0, "controlIdx": 0}, // ← 자동번호 글상자
{"type": "shape", "x": 113.4, "y": 736.8, "w": 895.7, "h": 4, ...} // 단 구분선
]}
자동번호 글상자: secIdx=0, paraIdx=0, controlIdx=0 — section 0 의 paragraph 0 (master page) 에 anchored.
Step 2 — 글상자 정확한 위치 (151.2, 750.75) 단일 click:
scroll: 12023 → 12023 (delta=0)
isInPictureObjectSelection=true
selectedPicRef = {sec:0, ppi:0, ci:0, type:'shape'}
→ shape 객체 선택. scroll 변화 없음.
Step 3 — 같은 위치 더블 click:
scroll: 12023 → 735 (delta=−11288)
pos = {sec:0, para:0, char:0, ppi:0, ci:0, cellIdx:0}
isInTextBox=true ★
rectPg=0 ★ (cursor.getRect().pageIndex)
visible pages after dblclick: [0, 1] ★
→ isInTextBox=true 분기 진입, cursor 가 sec 0 paragraph 0 의 control 0 cell 0 (master page 글상자 안) 으로 이동, cursor.getRect().pageIndex = 0 (master page 가 first-attached 된 page 0 의 좌표 반환), scrollCaretIntoView 가 page 0 부근으로 스크롤.
코드 경로
input-handler-mouse.ts:onMouseDown 의 흐름:
- (single click) wasm.hitTest 가
parentParaIndex=0, controlIndex=0, cellIndex=0 등 cell hit 반환 (master page 글상자의 cell 0)
- (single click) 글상자가 picture 로도 인식되어
findPictureAtClick 이 shape ref 반환 → isInPictureObjectSelection 모드 진입
- (dblclick) 두 번째 mousedown 시 picture 모드 안에서 hit 의
isTextBox=true 분기 (input-handler-mouse.ts:643-657) 진입 → cursor.moveTo(hit) + this.updateCaret() 호출
updateCaret() 안의 scrollCaretIntoView(rect) (input-handler.ts:1505) 가 rect.pageIndex=0 (master page first-attached 페이지) 으로 스크롤 → 첫 페이지 점프
한컴 정합 정정 방향
A) findPictureAtClick / hit.isTextBox 분기에서 master page 출처 글상자는 제외 — paraIdx=0 으로 anchored 된 control (= master page 의 control) 은 일반 본문 fallback 으로 진행.
B) 또는 hit 의 cursorRect.pageIndex 가 click 페이지 (pageIdx) 와 다르면 fallback.
권장: A — 의미적으로 master page 위 click 은 본문 click. 한컴도 동일.
회귀 영역 (정정 시 점검)
- 일반 본문 글상자 (paraIdx > 0 또는 master page 외 origin) dblclick → textbox edit 진입 정상 동작 유지
- master page 글상자 single click → shape 객체 선택 모드는 보존? 또는 한컴 정합 (master page 위 click 은 무동작)?
- master page 의 자동번호(Page) 외 다른 control (그림, 이미지, 도형) 도 동일 점프 발생하는지 횡적 검증
우선순위
Medium — 단일 fixture 직접 재현. 다른 양식 (표지, 이력서 양식 등 master page 활용) 에서도 잠재적 재현 가능. 사용자 인지 시 page navigation 혼란 큼.
fixture
samples/hwpctl_Action_Table__v1.1.hwp
- 16 페이지, landscape (가로 297×210mm)
- margin_left=30, margin_right=30, margin_top=0, margin_bottom=0, margin_header=15, margin_footer=15 (mm)
- 바탕쪽 2개 (Both, 자동번호 Page 글상자 포함)
- 재현:
cd rhwp-studio && npx vite & node e2e/body-outside-click-fallback.test.mjs --mode=headless
참고
본질
samples/hwpctl_Action_Table__v1.1.hwp(16p, landscape, margin_bottom=0) 의 페이지 16 하단 자동번호(Page) 텍스트박스 (master page 글상자 — secIdx=0, paraIdx=0, controlIdx=0 anchored) 를 더블클릭 시:}캐럿 (= master page 위 dblclick 을 본문 가장 가까운 caret 으로 fallback)정량 측정 (e2e, 2026-05-07)
rhwp-studio/e2e/body-outside-click-fallback.test.mjs+ 정밀 측정 (페이지 번호 textbox bbox 정확한 위치 click).Step 1 — Layout dump (page 15):
{ "controls": [ {"type": "shape", "x": 113.4, "y": 740, "w": 75.6, "h": 21.5, "secIdx": 0, "paraIdx": 0, "controlIdx": 0}, // ← 자동번호 글상자 {"type": "shape", "x": 113.4, "y": 736.8, "w": 895.7, "h": 4, ...} // 단 구분선 ]}자동번호 글상자:
secIdx=0, paraIdx=0, controlIdx=0— section 0 의 paragraph 0 (master page) 에 anchored.Step 2 — 글상자 정확한 위치 (151.2, 750.75) 단일 click:
→ shape 객체 선택. scroll 변화 없음.
Step 3 — 같은 위치 더블 click:
→ isInTextBox=true 분기 진입, cursor 가 sec 0 paragraph 0 의 control 0 cell 0 (master page 글상자 안) 으로 이동,
cursor.getRect().pageIndex = 0(master page 가 first-attached 된 page 0 의 좌표 반환),scrollCaretIntoView가 page 0 부근으로 스크롤.코드 경로
input-handler-mouse.ts:onMouseDown 의 흐름:
parentParaIndex=0, controlIndex=0, cellIndex=0등 cell hit 반환 (master page 글상자의 cell 0)findPictureAtClick이 shape ref 반환 →isInPictureObjectSelection모드 진입isTextBox=true분기 (input-handler-mouse.ts:643-657) 진입 →cursor.moveTo(hit)+this.updateCaret()호출updateCaret()안의scrollCaretIntoView(rect)(input-handler.ts:1505) 가rect.pageIndex=0(master page first-attached 페이지) 으로 스크롤 → 첫 페이지 점프한컴 정합 정정 방향
A)
findPictureAtClick/hit.isTextBox분기에서 master page 출처 글상자는 제외 —paraIdx=0으로 anchored 된 control (= master page 의 control) 은 일반 본문 fallback 으로 진행.B) 또는 hit 의
cursorRect.pageIndex가 click 페이지 (pageIdx) 와 다르면 fallback.권장: A — 의미적으로 master page 위 click 은 본문 click. 한컴도 동일.
회귀 영역 (정정 시 점검)
우선순위
Medium — 단일 fixture 직접 재현. 다른 양식 (표지, 이력서 양식 등 master page 활용) 에서도 잠재적 재현 가능. 사용자 인지 시 page navigation 혼란 큼.
fixture
samples/hwpctl_Action_Table__v1.1.hwpcd rhwp-studio && npx vite & node e2e/body-outside-click-fallback.test.mjs --mode=headless참고
mydocs/troubleshootings/body_outside_click_fallback.mdrhwp-studio/e2e/body-outside-click-fallback.test.mjs