jean-emmanuel / open-stage-control

Libre and modular OSC / MIDI controller
https://openstagecontrol.ammd.net
GNU General Public License v3.0
705 stars 90 forks source link

[Bug] Frame Widget touch event issues #848

Closed shamanicvocalarts closed 4 months ago

shamanicvocalarts commented 4 months ago

Bug Report: Frame Widget Touch Event Issues

Summary: The Frame widget in Open Stage Control captures touch events incorrectly, which affects the functionality of other UI elements in the application.

Description: When using the Frame widget to embed a web page, the widget exhibits the following issues with touch event handling:

  1. Capture of Touch Events: The Frame widget captures touch events, preventing touch interactions with other widgets in the application.
  2. Touch Event Registration: Touch events are not registered correctly when other widgets are touched before the Frame widget.
  3. Out-of-Bounds Touch Registration (Windows and Android): On Windows and Android, touches outside of the Frame widget are registered as within the frame if they happen after the frame has been touched.

Steps to Reproduce:

  1. Add a Frame widget to an Open Stage Control interface.
  2. Embed any URL in the Frame widget.
  3. Interact with other widgets on the interface.
  4. Observe how touch events are handled, especially after interacting with the Frame widget.
  5. Test multitouch using Multi Touch Test to observe the described behavior.

Expected Behavior:

Actual Behavior:

Environment:

Possible Fix: As per chatgpt guidance,as I am not a web developer, adding touch event listeners to the iframe and stopping event propagation may address the issue. Here's a proposed modification:

constructor(options) {
    super({...options, html: html`
        <inner>
            <iframe class="frame" src="" sandbox="allow-scripts allow-same-origin allow-forms"></iframe>
        </inner>`
    })

    if (!this.getProp('border')) this.container.classList.add('noborder')

    this.frame = DOM.get(this.widget, '.frame')[0]
    this.errorText = html`<span>${locales('iframe_unauthorized')}<span>`
    this.errorTextMounted = false

    // Add touch event listeners to the iframe
    this.frame.addEventListener('touchstart', this.handleTouchEvent.bind(this), true);
    this.frame.addEventListener('touchmove', this.handleTouchEvent.bind(this), true);
    this.frame.addEventListener('touchend', this.handleTouchEvent.bind(this), true);
}

handleTouchEvent(event) {
    console.log('Touch event:', event.type);
    event.preventDefault();
    event.stopPropagation();
}

Additional Information: If any additional debugging or information is required, please feel free to reach out. I am willing to assist further in resolving this issue.

jean-emmanuel commented 4 months ago

Thank you for the very detailed report. However it's not possible to allow interacting with the content of an iframe while at the same time preventing it from capturing touch events within an a multitouch interaction that started inside the frame. I'm afraid that's just how iframes work in a browser. At best you could set the frame's interaction property to false if/when you don't need to interact with its content.

shamanicvocalarts commented 4 months ago

Thanks for this response @jean-emmanuel , after some testing with Chataigne I can confirm you are correct. I will close this issue & instead open a discussion on Discourse to discuss workarounds / alternatives.