Bladeren bron

feat: call onTap* of TerminalView only if event not handled by Terminal

Georg Wechslberger 3 jaren geleden
bovenliggende
commit
e81014193c
3 gewijzigde bestanden met toevoegingen van 53 en 43 verwijderingen
  1. 4 1
      lib/src/terminal.dart
  2. 47 40
      lib/src/ui/gesture/gesture_handler.dart
  3. 2 2
      lib/src/ui/render.dart

+ 4 - 1
lib/src/terminal.dart

@@ -241,7 +241,8 @@ class Terminal with Observable implements TerminalState, EscapeHandler {
     }
   }
 
-  void mouseInput(
+  // Handle a mouse event and return true if it was handled.
+  bool mouseInput(
     TerminalMouseButton button,
     TerminalMouseButtonState buttonState,
     CellOffset position,
@@ -255,7 +256,9 @@ class Terminal with Observable implements TerminalState, EscapeHandler {
     ));
     if (output != null) {
       onOutput?.call(output);
+      return true;
     }
+    return false;
   }
 
   /// Resize the terminal screen. [newWidth] and [newHeight] should be greater

+ 47 - 40
lib/src/ui/gesture/gesture_handler.dart

@@ -79,70 +79,77 @@ class _TerminalGestureHandlerState extends State<TerminalGestureHandler> {
   bool get _shouldSendTapEvent =>
       widget.terminalController.shouldSendPointerInput(PointerInput.tap);
 
-  void onTapDown(TapDownDetails details) {
-    widget.onTapDown?.call(details);
+  void _tapDown(
+    GestureTapDownCallback? callback,
+    TapDownDetails details,
+    TerminalMouseButton button, {
+    bool forceCallback = false,
+  }) {
+    // Check if the terminal should and can handle the tap down event.
+    var handled = false;
     if (_shouldSendTapEvent) {
-      renderTerminal.mouseEvent(
-        TerminalMouseButton.left,
+      handled = renderTerminal.mouseEvent(
+        button,
         TerminalMouseButtonState.down,
         details.localPosition,
       );
     }
+    // If the event was not handled by the terminal, use the supplied callback.
+    if (!handled || forceCallback) {
+      callback?.call(details);
+    }
   }
 
-  void onSingleTapUp(TapUpDetails details) {
-    widget.onSingleTapUp?.call(details);
+  void _tapUp(
+    GestureTapUpCallback? callback,
+    TapUpDetails details,
+    TerminalMouseButton button, {
+    bool forceCallback = false,
+  }) {
+    // Check if the terminal should and can handle the tap up event.
+    var handled = false;
     if (_shouldSendTapEvent) {
-      renderTerminal.mouseEvent(
-        TerminalMouseButton.left,
+      handled = renderTerminal.mouseEvent(
+        button,
         TerminalMouseButtonState.up,
         details.localPosition,
       );
     }
+    // If the event was not handled by the terminal, use the supplied callback.
+    if (!handled && forceCallback) {
+      callback?.call(details);
+    }
+  }
+
+  void onTapDown(TapDownDetails details) {
+    // onTapDown is special, as it will always call the supplied callback.
+    // The TerminalView depends on it to bring the terminal into focus.
+    _tapDown(
+      widget.onTapDown,
+      details,
+      TerminalMouseButton.left,
+      forceCallback: true,
+    );
+  }
+
+  void onSingleTapUp(TapUpDetails details) {
+    _tapUp(widget.onSingleTapUp, details, TerminalMouseButton.left);
   }
 
   void onSecondaryTapDown(TapDownDetails details) {
-    widget.onSecondaryTapDown?.call(details);
-    if (_shouldSendTapEvent) {
-      renderTerminal.mouseEvent(
-        TerminalMouseButton.right,
-        TerminalMouseButtonState.down,
-        details.localPosition,
-      );
-    }
+    _tapDown(widget.onSecondaryTapDown, details, TerminalMouseButton.right);
   }
 
   void onSecondaryTapUp(TapUpDetails details) {
-    widget.onSecondaryTapUp?.call(details);
-    if (_shouldSendTapEvent) {
-      renderTerminal.mouseEvent(
-        TerminalMouseButton.right,
-        TerminalMouseButtonState.up,
-        details.localPosition,
-      );
-    }
+    _tapUp(widget.onSecondaryTapUp, details, TerminalMouseButton.right);
   }
 
   void onTertiaryTapDown(TapDownDetails details) {
-    widget.onTertiaryTapDown?.call(details);
-    if (_shouldSendTapEvent) {
-      renderTerminal.mouseEvent(
-        TerminalMouseButton.middle,
-        TerminalMouseButtonState.down,
-        details.localPosition,
-      );
-    }
+    _tapDown(widget.onTertiaryTapDown, details, TerminalMouseButton.middle);
   }
 
   void onTertiaryTapUp(TapUpDetails details) {
-    widget.onTertiaryTapUp?.call(details);
-    if (_shouldSendTapEvent) {
-      renderTerminal.mouseEvent(
-        TerminalMouseButton.middle,
-        TerminalMouseButtonState.up,
-        details.localPosition,
-      );
-    }
+    _tapUp(widget.onTertiaryTapUp, details, TerminalMouseButton.right);
   }
 
   void onDoubleTapDown(TapDownDetails details) {

+ 2 - 2
lib/src/ui/render.dart

@@ -294,13 +294,13 @@ class RenderTerminal extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
   }
 
   /// Send a mouse event at [offset] with [button] being currently in [buttonState].
-  void mouseEvent(
+  bool mouseEvent(
     TerminalMouseButton button,
     TerminalMouseButtonState buttonState,
     Offset offset,
   ) {
     final position = getCellOffset(offset);
-    _terminal.mouseInput(button, buttonState, position);
+    return _terminal.mouseInput(button, buttonState, position);
   }
 
   void _notifyEditableRect() {