From 4f18154681341ca9534e956806748d41ce5cd54a Mon Sep 17 00:00:00 2001
From: David Sehnal <dsehnal@users.noreply.github.com>
Date: Mon, 20 Mar 2023 09:15:51 +0100
Subject: [PATCH] Marking improvements (#750)

* better marking identify

* changelog

* tweak

* type tweak

* simplify ui mouse move handling

---------

Co-authored-by: Alexander Rose <alexander.rose@weirdbyte.de>
---
 CHANGELOG.md                                  | 1 +
 src/mol-canvas3d/helper/interaction-events.ts | 8 ++++++--
 src/mol-plugin-ui/controls.tsx                | 9 ++-------
 src/mol-plugin-ui/viewport.tsx                | 9 ++-------
 src/mol-util/input/input-observer.ts          | 9 +++++++--
 5 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 531fe8938..336e7c0ce 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,7 @@ Note that since we don't clearly distinguish between a public and private interf
 - Fix occlusion artefact with non-canvas viewport and pixel-ratio > 1
 - Update nodejs-shims conditionals to handle polyfilled document object in NodeJS environment.
 - Ensure marking edges are at least one pixel wide
+- Only trigger marking when mouse is directly over canvas
 - Fix blurry occlusion in screenshots
 
 ## [v3.31.4] - 2023-02-24
diff --git a/src/mol-canvas3d/helper/interaction-events.ts b/src/mol-canvas3d/helper/interaction-events.ts
index 30145c951..7afcabe63 100644
--- a/src/mol-canvas3d/helper/interaction-events.ts
+++ b/src/mol-canvas3d/helper/interaction-events.ts
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2023 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
@@ -197,8 +197,12 @@ export class Canvas3dInteractionHelper {
             this.drag(x, y, buttons, button, modifiers);
         });
 
-        input.move.subscribe(({ x, y, inside, buttons, button, modifiers }) => {
+        input.move.subscribe(({ x, y, inside, buttons, button, modifiers, onElement }) => {
             if (!inside || this.isInteracting) return;
+            if (!onElement) {
+                this.leave();
+                return;
+            }
             // console.log('move');
             this.move(x, y, buttons, button, modifiers);
         });
diff --git a/src/mol-plugin-ui/controls.tsx b/src/mol-plugin-ui/controls.tsx
index 44f9e9a71..2aa8241cd 100644
--- a/src/mol-plugin-ui/controls.tsx
+++ b/src/mol-plugin-ui/controls.tsx
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2023 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
@@ -240,14 +240,9 @@ export class SelectionViewportControls extends PluginUIComponent {
         this.subscribe(this.plugin.behaviors.interaction.selectionMode, () => this.forceUpdate());
     }
 
-    onMouseMove = (e: React.MouseEvent) => {
-        // ignore mouse moves when no button is held
-        if (e.buttons === 0) e.stopPropagation();
-    };
-
     render() {
         if (!this.plugin.selectionMode) return null;
-        return <div className='msp-selection-viewport-controls' onMouseMove={this.onMouseMove}>
+        return <div className='msp-selection-viewport-controls'>
             <StructureSelectionActionsControls />
         </div>;
     }
diff --git a/src/mol-plugin-ui/viewport.tsx b/src/mol-plugin-ui/viewport.tsx
index 6d0c45df7..0dff3983f 100644
--- a/src/mol-plugin-ui/viewport.tsx
+++ b/src/mol-plugin-ui/viewport.tsx
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2023 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  * @author David Sehnal <david.sehnal@gmail.com>
@@ -76,13 +76,8 @@ export class ViewportControls extends PluginUIComponent<ViewportControlsProps, V
         return <IconButton svg={icon} toggleState={isOn} onClick={onClick} title={title} style={{ background: 'transparent' }} />;
     }
 
-    onMouseMove = (e: React.MouseEvent) => {
-        // ignore mouse moves when no button is held
-        if (e.buttons === 0) e.stopPropagation();
-    };
-
     render() {
-        return <div className={'msp-viewport-controls'} onMouseMove={this.onMouseMove}>
+        return <div className={'msp-viewport-controls'}>
             <div className='msp-viewport-controls-buttons'>
                 <div>
                     <div className='msp-semi-transparent-background' />
diff --git a/src/mol-util/input/input-observer.ts b/src/mol-util/input/input-observer.ts
index f83b7e11a..d5455f0c4 100644
--- a/src/mol-util/input/input-observer.ts
+++ b/src/mol-util/input/input-observer.ts
@@ -163,6 +163,9 @@ export type MoveInput = {
     pageX: number,
     pageY: number,
     inside: boolean,
+    // Move is subscribed to window element
+    // This indicates that the event originated from the element the InputObserver was created on
+    onElement: boolean
 } & BaseInput
 
 export type PinchInput = {
@@ -202,6 +205,7 @@ type PointerEvent = {
     clientY: number
     pageX: number
     pageY: number
+    target: EventTarget | null
 
     preventDefault?: () => void
 }
@@ -446,7 +450,8 @@ namespace InputObserver {
                 clientX: (t0.clientX + t1.clientX) / 2,
                 clientY: (t0.clientY + t1.clientY) / 2,
                 pageX: (t0.pageX + t1.pageX) / 2,
-                pageY: (t0.pageY + t1.pageY) / 2
+                pageY: (t0.pageY + t1.pageY) / 2,
+                target: ev.target
             };
         }
 
@@ -592,7 +597,7 @@ namespace InputObserver {
             const { pageX, pageY } = ev;
             const [x, y] = pointerEnd;
             const inside = insideBounds(pointerEnd);
-            move.next({ x, y, pageX, pageY, buttons, button, modifiers: getModifierKeys(), inside });
+            move.next({ x, y, pageX, pageY, buttons, button, modifiers: getModifierKeys(), inside, onElement: ev.target === element });
 
             if (dragging === DraggingState.Stopped) return;
 
-- 
GitLab