Files
gopeed/ui/flutter/lib/shared/widgets/browser_context_menu_region.dart

82 lines
2.3 KiB
Dart

import 'package:flutter/foundation.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'browser_context_menu_region_stub.dart'
if (dart.library.js_interop) 'browser_context_menu_region_web.dart'
as platform;
/// Keeps the browser menu out of an application's context-menu region on Web.
///
/// Captured themes carry the policy into shadcn's menu and submenu overlays.
/// Overlay regions defer to their children so a full-screen positioning layer
/// does not suppress the browser menu over the rest of the page.
class BrowserContextMenuRegion extends StatelessWidget {
const BrowserContextMenuRegion({super.key, required this.child});
final Widget child;
@override
Widget build(BuildContext context) {
if (!kIsWeb) return child;
return _ContextMenuTheme(
child: _ContextMenuRegion(behavior: HitTestBehavior.translucent, child: child),
);
}
}
class _ContextMenuTheme extends InheritedTheme {
const _ContextMenuTheme({required super.child});
@override
Widget wrap(BuildContext context, Widget child) {
return _ContextMenuTheme(child: _ContextMenuRegion(child: child));
}
@override
bool updateShouldNotify(_ContextMenuTheme oldWidget) => false;
}
class _ContextMenuRegion extends SingleChildRenderObjectWidget {
const _ContextMenuRegion({this.behavior = HitTestBehavior.deferToChild, required super.child});
final HitTestBehavior behavior;
@override
RenderObject createRenderObject(BuildContext context) {
return _RenderContextMenuRegion(View.of(context).viewId, behavior);
}
@override
void updateRenderObject(BuildContext context, _RenderContextMenuRegion renderObject) {
renderObject
..viewId = View.of(context).viewId
..behavior = behavior;
}
}
class _RenderContextMenuRegion extends RenderProxyBoxWithHitTestBehavior {
_RenderContextMenuRegion(this._viewId, HitTestBehavior behavior) : super(behavior: behavior);
int _viewId;
set viewId(int value) {
if (value == _viewId) return;
if (attached) platform.unregisterRegion(this, _viewId);
_viewId = value;
if (attached) platform.registerRegion(this, _viewId);
}
@override
void attach(PipelineOwner owner) {
super.attach(owner);
platform.registerRegion(this, _viewId);
}
@override
void detach() {
platform.unregisterRegion(this, _viewId);
super.detach();
}
}