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 렌더러의 차이를 명확히 이해하고 프로젝트 요구사항에 맞춰 선택하는 것이 중요하다.

Flutter 3 Web에서 마우스 우클릭 컨텍스트 메뉴 처리