See PR #276
So, I’ve done a bit of bug-hunting (and in the process submitted a pull request for an unrelated issue #274) and found the bug-causing sequence:
- User presses Ok on
DlgFromDict
- This fires
psychoJS.window.adjustScreenSize()
which requests a fullscreen transition from the browser - At the same time,
experimentInit()
sets up the Slider, and at some point, calls_estimateBoundingBox()
- In
_estimateBoundingBox()
,this._tickPositions_px
is set usingtickPositions.map()
tickPositions.map()
usesto_px()
with athis._win
argument- BUG OCCURS HERE:
to_px()
usesthis._win.size
to converttickPositions
from PsychoPy dimension units to browser pixel units - Finally, the initial label positions,
this._labelPositions_px
, are set fromthis._tickPositions_px
The problem at Step 6 is that this._win.size
represents the current window size. At this point, this._win.size
may still be the pre-fullscreen window size, so the labels are placed in the correct positions for the pre-fullscreen window. However, once post-fullscreen, the labels will be in the wrong positions.
The main issue is that Step 2 is async, so it cannot be guaranteed which state the window is in.
You can easily reproduce the bug by:
-
Option 1: Make your window very small before pressing Ok on
DlgFromDict
. Once fullscreen, the labels will be grouped in the center of the window. This is becausethis._win.size
is small. -
Option 2: Wait until fullscreen is achieved, and then fire
experimentInit()
again. This re-initializes the Sliders, and the labels will be in the correct positions. -
Option 3: Manually fullscreen the window before pressing Ok on
DlgFromDict
. The labels will be in the correct positions because the window size has not changed
Possible fix:
- Add a timeout between closing
DlgFromDict
and triggeringScheduler.Event.NEXT
. InDlgFromDict
>close: function() ...
:
Replace (line 288 on GitHub):
self._dialogComponent.status = PsychoJS.Status.FINISHED;
With:
if (self._psychoJS._window.fullscr) {
setTimeout(() => self._dialogComponent.status = PsychoJS.Status.FINISHED, 2000);
} else {
self._dialogComponent.status = PsychoJS.Status.FINISHED;
}
This sets a timeout for 2000ms before continuing. In my quick testing, a minimum of around 500ms seemed to work too, but 2000ms hopefully gives some buffer space without making the experiment appear to be frozen.
(I tried a fix that listened for the fullscreenchange
event, but at least in my quick testing, it still required a delay to guarantee the resize was complete)