Flutter 3 Web에서 마우스 우클릭 컨텍스트 메뉴 처리
문제 상황
사내 관리 도구를 Flutter Web으로 마이그레이션하던 중, 특정 영역에서 우클릭 시 커스텀 컨텍스트 메뉴를 표시해야 하는 요구사항이 있었다. 브라우저 기본 메뉴가 함께 뜨는 문제가 발생했다.
시도한 방법들
1. GestureDetector의 onSecondaryTap
GestureDetector(
onSecondaryTap: () {
_showCustomMenu();
},
child: Container(...),
)
커스텀 메뉴는 표시되지만 브라우저 기본 메뉴가 여전히 나타났다. Flutter의 제스처 시스템만으로는 브라우저 이벤트를 완전히 제어할 수 없었다.
2. HtmlElementView와 JS 인터럽트
HTML Renderer를 사용하는 경우 직접적인 DOM 접근이 가능했다. index.html에 전역 핸들러를 추가했다.
// web/index.html
window.addEventListener('contextmenu', (e) => {
if (e.target.closest('.custom-context-area')) {
e.preventDefault();
}
});
Flutter 측에서는 HtmlElementView에 클래스를 지정했다.
import 'dart:ui' as ui;
import 'dart:html' as html;
void _registerContextArea() {
final element = html.DivElement()
..classes.add('custom-context-area')
..style.width = '100%'
..style.height = '100%';
ui.platformViewRegistry.registerViewFactory(
'context-area',
(int viewId) => element,
);
}
결과
CanvasKit 렌더러에서는 동작하지 않았지만, HTML 렌더러 환경에서는 의도대로 작동했다. 프로젝트 특성상 HTML 렌더러를 사용하기로 결정했고, flutter build web --web-renderer html 옵션으로 빌드했다.
교훈
Flutter Web은 여전히 네이티브 웹 API에 의존해야 하는 경우가 많다. 특히 브라우저 기본 동작을 제어할 때는 platform channel이나 JS interop을 적극 활용해야 한다. CanvasKit과 HTML 렌더러의 차이를 명확히 이해하고 프로젝트 요구사항에 맞춰 선택하는 것이 중요하다.