-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Interactive Highlights should lock with touchSnag #1495
Comments
I went through the commits that @jessegreenberg reverted in phetsims/mean-share-and-balance#125 and brought those changes back in the above commit. Keeping an eye out on CT now to track down the resulting bugs. |
Looking at CT I see the
|
Here's a patch that is helping for debugging: Subject: [PATCH] debugging
---
Index: js/accessibility/voicing/InteractiveHighlighting.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/accessibility/voicing/InteractiveHighlighting.ts b/js/accessibility/voicing/InteractiveHighlighting.ts
--- a/js/accessibility/voicing/InteractiveHighlighting.ts (revision b17aec4f2bcd482f6276e6d646209e4a626affd9)
+++ b/js/accessibility/voicing/InteractiveHighlighting.ts (date 1706031067168)
@@ -13,6 +13,7 @@
import { Highlight } from '../../overlays/HighlightOverlay.js';
import TEmitter from '../../../../axon/js/TEmitter.js';
import memoize from '../../../../phet-core/js/memoize.js';
+import Property from '../../../../axon/js/Property.js';
// constants
// option keys for InteractiveHighlighting, each of these will have a setter and getter and values are applied with mutate()
@@ -22,6 +23,8 @@
'interactiveHighlightEnabled'
];
+let instanceCounter = 0;
+
type SelfOptions = {
interactiveHighlight?: Highlight;
interactiveHighlightLayerable?: boolean;
@@ -47,6 +50,8 @@
// at one time.
private _pointer: null | Pointer = null;
+ private _pointerProperty: Property<null | Pointer>;
+
// A map that collects all of the Displays that this InteractiveHighlighting Node is
// attached to, mapping the unique ID of the Instance Trail to the Display. We need a reference to the
// Displays to activate the Focus Property associated with highlighting, and to add/remove listeners when
@@ -83,7 +88,10 @@
// while the pointer is down over something that uses InteractiveHighlighting.
private readonly _pointerListener: TInputListener;
+ private readonly interactiveID: number = instanceCounter;
+
public constructor( ...args: IntentionalAny[] ) {
+ instanceCounter++;
super( ...args );
this._activationListener = {
@@ -94,6 +102,15 @@
down: this._onPointerDown.bind( this )
};
+ this._pointerProperty = new Property( this._pointer );
+
+ this._pointerProperty.link( pointer => {
+ console.log( 'interactiveID: ', this.interactiveID );
+ this._pointer = pointer;
+ console.log( 'pointer changed', pointer );
+
+ } );
+
this._changedInstanceListener = this.onChangedInstance.bind( this );
this.changedInstanceEmitter.addListener( this._changedInstanceListener );
@@ -284,7 +301,8 @@
* a down event or move event which could do further updates on the event Pointer or FocusManager.
*/
private _onPointerEntered( event: SceneryEvent<MouseEvent | TouchEvent | PointerEvent> ): void {
-
+ console.log( 'pointer number: ', this.interactiveID );
+ console.log( 'pointer entered value: ', this._pointerProperty.value );
let lockPointer = false;
const displays = Object.values( this.displays );
@@ -344,7 +362,8 @@
* deactivate the HighlightOverlay. This can also fire when visibility/pickability of the Node changes.
*/
private _onPointerExited( event: SceneryEvent<MouseEvent | TouchEvent | PointerEvent> ): void {
-
+ console.log( 'pointer number: ', this.interactiveID );
+ console.log( 'pointer exiting', this._pointerProperty.value );
const displays = Object.values( this.displays );
for ( let i = 0; i < displays.length; i++ ) {
const display = displays[ i ];
@@ -359,7 +378,7 @@
// We do not want to remove the lockedPointerFocus if this event trail has nothing
// to do with the node that is receiving a locked focus.
event.trail.containsNode( lockedPointerFocus.trail.lastNode() ) ) ) {
-
+ console.log( 'going to release', this._pointerProperty.value );
// unlock and remove pointer listeners
this._onPointerRelease( event );
}
@@ -371,8 +390,7 @@
* event, the pointerFocusProperty will have been set first from the `enter` event.
*/
private _onPointerDown( event: SceneryEvent<MouseEvent | TouchEvent | PointerEvent> ): void {
-
- if ( this._pointer === null ) {
+ if ( this._pointerProperty.value === null ) {
let lockPointer = false;
const displays = Object.values( this.displays );
@@ -405,16 +423,20 @@
* @param [event] - may be called during interrupt or cancel, in which case there is no event
*/
private _onPointerRelease( event?: SceneryEvent<MouseEvent | TouchEvent | PointerEvent> ): void {
-
+ console.log( 'current pointer value: ', this._pointerProperty.value );
const displays = Object.values( this.displays );
for ( let i = 0; i < displays.length; i++ ) {
const display = displays[ i ];
display.focusManager.lockedPointerFocusProperty.value = null;
}
-
- if ( this._pointer && this._pointer.listeners.includes( this._pointerListener ) ) {
- this._pointer.removeInputListener( this._pointerListener );
- this._pointer = null;
+ if ( this._pointerProperty.value && this._pointerProperty.value.listeners.includes( this._pointerListener ) ) {
+ console.log( 'removing listener' );
+ this._pointerProperty.value.removeInputListener( this._pointerListener );
+ this._pointerProperty.value = null;
+ }
+ else {
+ console.log( 'Pointer Number: ', this.interactiveID );
+ console.log( 'no pointer', this._pointerProperty.value );
}
}
@@ -437,11 +459,12 @@
* Save the Pointer and add a listener to it to remove highlights when a pointer is released/cancelled.
*/
private savePointer( eventPointer: Pointer ): void {
- assert && assert( this._pointer === null,
+ assert && assert( this._pointerProperty.value === null,
'It should be impossible to already have a Pointer before locking from touchSnag' );
- this._pointer = eventPointer;
- this._pointer.addInputListener( this._pointerListener );
+ console.log( 'pointer assigned' );
+ this._pointerProperty.value = eventPointer;
+ this._pointerProperty.value.addInputListener( this._pointerListener );
}
/**
@@ -457,10 +480,16 @@
// If the event Pointer is attached to a PressListener there is some activation input happening, so
// we should "lock" the highlight to this target until the pointer is released.
if ( eventPointer.attachedListener && eventPointer.attachedListener.listener instanceof PressListener ) {
- assert && assert( this._pointer === null,
+ console.log( 'pointer number: ', this.interactiveID );
+ console.log( 'pointer value', this._pointerProperty.value );
+ if ( this._pointerProperty.value !== null ) {
+ debugger;
+ }
+ assert && assert( this._pointerProperty.value === null,
'It should be impossible to already have a Pointer before locking from touchSnag' );
// A COPY of the focus is saved to the Property because we need the value of the Trail at this event.
+ console.log( 'pointer locked focus set' );
focusManager.lockedPointerFocusProperty.set( new Focus( newFocus.display, newFocus.trail.copy() ) );
pointerLock = true;
} |
This is still failing many sims on CT. Is there anything I can do to help with this?
|
@zepumph we are currently meeting with @jessegreenberg after having done some investigation on our own that did not get very far. |
…e Pointer when lockedPointerFocusProperty.value is set to null, see phetsims/mean-share-and-balance#125 and #1495
@jbphet @marlitas and I paired on this issue for a while today. We found a a problem in InteractiveHighlighting where it was not updating itself if the Hopefully fixed by adding a listener to |
There was a small grammar thing I committed above (@jessegreenberg please feel free to change if I didn't get the right sentiment). The commit looks good to me, I think I'm more curious about what is updating lockedPointerFocusProperty outside of InteractiveHighlight... is that expected and okay? I probably don't actually need the details. Just was curious. Thanks for the fix Jesse! |
It is probably not the best software design, but Unfortunately, I am seeing the assertion from this commit on CT so we are not finished yet. Adding my assignment back but I might not be able to revisit until next week. This issue blocks RCs, if anyone needs to publish we should revert all commits in this issue.
EDIT: Changed my mind again. We will look into this soon. This is an example where branching processes would be helpful. |
Here are the currently known CT errors from this issue: geometric-optics-basics : multitouch-fuzz : unbuilt mean-share-and-balance : multitouch-fuzz : unbuilt EDIT: Here is what I see on CT I let MSaB and RaP fuzz for ten minutes with EDIT: Found a way to reproduce the problem thanks to a stack trace from the Tambo failure.
EDIT: These steps cause problems for published sims as well. I believe that this is not a new problem, but that it is being caught by a new assertion. |
…ved or made invisible, see #1495
OK - I think I found the fix. The listener was not being cleared when the Node was removed the scene graph. In addition, setting of the |
I just did a quick review. For the most part, the behavior and the code look good. I have two observations:
I'm going to unassign myself but leave @marlitas take a look before passing it back to @jessegreenberg. |
I agree with the comments @jbphet made above and have no other notes. Concerning the second point... We might run into this odd behavior again in the fourth screen of Mean Share and Balance, but I think it will be best to address it at that time rather than try to do it proactively without active development. |
Thank you both for the review - that is a great point. I made the note a TODO and will come back to this next week. But for now, CT is clear and this is no longer blocking publication. |
See if this related issue is fixed: phetsims/scenery-phet#708 |
In the above commits I made two changes. First, the highlights lock into place more frequently. I noticed in buoyancy that the highlights didn't lock because the dragging doesn't use a PressListener. Locking only when the attached listener is a PressListener is added in 026b2e6 and it wasn't clear why. So I removed that part and it behaves more like it did before this issue. Then I convinced myself that 992ac9f replaces an old option of FocusDisplayedController called I let sims that support alt input run locally with Ill let CT test this for a few iterations before closing. |
There are two green columns in CT since these commits. I think we are ready to close. |
From phetsims/mean-share-and-balance#125.
Interactive Highlights don't work well for cases of touchSnag. I tried a solution in that issue but it didn't work (ended up reverting). So this issue is to fix it in a better way.
Example of the problem from @Nancy-Salpepi. The higlight should lock to the interactive component once the drag listener gets attached to the Pointer.
Visuals
Highlt.disappears.mov
The text was updated successfully, but these errors were encountered: