Skip to content

Complete the touch pointer plugin teardown (unload leaks callbacks, interval, frame styles, zoom state) #42

Closed

Description

@jefBinomed

Issue originale de @GildasMorel le 2020-09-29, migrée depuis sfeir-open-source#81 (sfeir-open-source#81) lors de la consolidation vers l'organisation upstream.

The touch pointer is a plugin that add a pointer to the slide view.
From the presenter view, you can move the pointer by touching the slide view and it moves in the same way on stage view.

To activate this plugin, click on Presenter view "plugins" button menu and select "TouchPointerInput".
Then, to deactivate the plugin, click on the "Fermer" button at the top right.

When the plugin is activated, the pointer div is added on the fly to the view.
When the plugin is deactivated, it should be removed from the shadow DOM.

  • Checkout the develop branch
  • Open the file src\plugins\input\touch-pointer\index.js
  • Look for _removePointer function definition
  • The line pointer.remove(); doesn't work

You can see and confirm the problem by deactivating the plugin following the previous process and look for the pointer div in the dev tools.
If you activate / deactivate the plugin several times you'll see that you'll have several pointer div in the source code.

Activity

  1. jefBinomed commented on Aug 11, 2026

    @jefBinomed
    CollaboratorAuthor

    Re-tested on develop @ v0.6.0 — the reported symptom is gone, but the teardown is still incomplete

    pointer.remove() works now

    Measured on the real app, three activate/deactivate cycles from the presenter view, counting #pointer nodes in currentSlide.shadowRoot:

    cycle 1 → after activation: 1   |  after "Fermer": 0
    cycle 2 → after activation: 1   |  after "Fermer": 0
    cycle 3 → after activation: 1   |  after "Fermer": 0
    

    No accumulation. The 2020 code looked the pointer up in the light DOM; the current _removePointer queries currentSlide.shadowRoot.getElementById('pointer') (src/plugins/input/touch-pointer/index.ts), which resolves correctly.

    But unload() still leaks four things

    Re-scoping this issue rather than closing it, because "the remove process" is genuinely still broken — just not at the line the issue points to.

    1. callbacks grows without bound. Instrumented across the same three cycles:

    cycle 1 → callbacks = 1
    cycle 2 → callbacks = 2
    cycle 3 → callbacks = 3
    

    activateOnComponent pushes a new callback via plugin.instance.onEvent(...) on every activation (src/common/services/plugin.ts), and nothing ever purges the array. After N cycles every pointerMove is broadcast N times.

    2. The setInterval is never cleared. _setPointer schedules an interval to hide the pointer after 2s and stores it in this.interval. unload() does not clearInterval it, so it keeps firing for the lifetime of the page.

    3. Frame styles are not restored. _addPointer sets width, height, transitionDuration and cursor: zoom-in on #slideViewFrame. _removePointer removes the pointer div but leaves all four in place, so the slide frame keeps a zoom cursor with no zoom behind it.

    4. Deactivating while zoomed strands the view. The transform applied by _toggleZoom survives unload(), and this.zooming stays true. The slide is left off-screen with no way to bring it back short of a reload.

    Suggested fix — make the lifecycle symmetric in the base class

    Points 1–4 are one defect wearing four hats: Plugin declares init() / unload() but only init() is ever really implemented. The same gap exists in keyboard and touch, which register global listeners in init() and inherit the no-op unload().

    • Plugin.unload() (base) clears this.callbacks and resets initialized.
    • TouchPointerInput.unload() clears the interval, resets transform / cursor / transitionDuration on the frame, and sets zooming = false.
    • Keep a reference to the message handler so removeEventListener is actually possible — it is currently registered with an inline arrow function, so it can never be detached.

    Retitling to reflect what is actually left to do.

  2. changed the title [-]Fix the touch pointer remove process[/-] [+]Complete the touch pointer plugin teardown (unload leaks callbacks, interval, frame styles, zoom state)[/+] on Aug 11, 2026
  3. added 2 commits that reference this issue on Aug 13, 2026
  4. jefBinomed commented on Aug 13, 2026

    @jefBinomed
    CollaboratorAuthor

    Corrigé par #71, mergé dans develop (5a9afd6).

    Le teardown est désormais symétrique : Plugin.unload() purge les callbacks et initialized, touch-pointer nettoie son timer, restaure les styles du frame et remet le zoom à zéro, et keyboard/touch détachent leurs listeners. Vérifié sur l'app réelle : callbacks plafonne à 1 au lieu de grimper 1 → 2 → 3 sur trois cycles.

    Fermeture manuelle (le Closes #42 ne se déclenche que sur merge dans la branche par défaut, main).

  5. added a commit that references this issue on Aug 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions