frameless_window.dart 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. import 'package:flutter/services.dart';
  2. import 'package:flutter/material.dart';
  3. import 'dart:io' show Platform;
  4. class CocoaWindowChannel {
  5. CocoaWindowChannel._();
  6. final MethodChannel _channel = const MethodChannel("flutter/cocoaWindow");
  7. static final CocoaWindowChannel instance = CocoaWindowChannel._();
  8. Future<void> setWindowPosition(Offset offset) async {
  9. await _channel.invokeMethod("setWindowPosition", [offset.dx, offset.dy]);
  10. }
  11. Future<List<double>> getWindowPosition() async {
  12. final raw = await _channel.invokeMethod("getWindowPosition");
  13. final arr = raw as List<dynamic>;
  14. final List<double> result = arr.map((s) => s as double).toList();
  15. return result;
  16. }
  17. Future<void> zoom() async {
  18. await _channel.invokeMethod("zoom");
  19. }
  20. }
  21. class MoveWindowDetector extends StatefulWidget {
  22. const MoveWindowDetector({Key? key, this.child}) : super(key: key);
  23. final Widget? child;
  24. @override
  25. MoveWindowDetectorState createState() => MoveWindowDetectorState();
  26. }
  27. class MoveWindowDetectorState extends State<MoveWindowDetector> {
  28. double winX = 0;
  29. double winY = 0;
  30. @override
  31. Widget build(BuildContext context) {
  32. if (!Platform.isMacOS) {
  33. return widget.child ?? Container();
  34. }
  35. return GestureDetector(
  36. // https://stackoverflow.com/questions/52965799/flutter-gesturedetector-not-working-with-containers-in-stack
  37. behavior: HitTestBehavior.translucent,
  38. onDoubleTap: () async {
  39. await CocoaWindowChannel.instance.zoom();
  40. },
  41. onPanStart: (DragStartDetails details) {
  42. winX = details.globalPosition.dx;
  43. winY = details.globalPosition.dy;
  44. },
  45. onPanUpdate: (DragUpdateDetails details) async {
  46. final windowPos = await CocoaWindowChannel.instance.getWindowPosition();
  47. final double dx = windowPos[0];
  48. final double dy = windowPos[1];
  49. final deltaX = details.globalPosition.dx - winX;
  50. final deltaY = details.globalPosition.dy - winY;
  51. await CocoaWindowChannel.instance
  52. .setWindowPosition(Offset(dx + deltaX, dy - deltaY));
  53. },
  54. child: widget.child,
  55. );
  56. }
  57. }