psychopy.org | Reference | Downloads | Github

Retina display windows opening in wrong place in 1.90.0 Py2 version

screen

#1

I’m on a 2017 Macbook Pro with retina display. When I open a window, with or without fullscreening, it centers it on the top-left corner of the screen. This occurs whether I open the window on screen index 0 or 1 (notably, when opening on screen index 1, it puts it in the top left of THAT screen). Everything is on the pyglet backend. By default new windows are opened at 0,0, and it looks like that’s being mapped to the top-left corner now instead of the center of the screen. Notably, it does not do this on 1.85.6 on the same displays. I can’t figure out where that’s actually determined in the code or how it changed from 1.85.6. Help?


#2

This issue is still present in 1.90.1. Where exactly does PsychoPy determine where to open the window? I can’t find it in the relevant class.


#3

OK. I have located the source of the bug. I have an inelegant fix, but I still don’t understand where it’s coming from. @jon your input would be appreciated.

The key issue is some kind of weird interplay between lines 164 and 204-206 in pygletbackend.py in the backends sub-folder of visual.window.

Line 164 sets the size of the window for retina displays. The output is, effectively, double whatever you put in to your PsychoPy code. So if you try to make a 1440 x 1080 window, this line will output a win.size array of [2880, 2160]. This is necessary for stimuli to display properly on retina displays.

Lines 204-206 computes where to position the window if no position is provided when the window is created.

        if not win.pos:
            # work out where the centre should be 
            win.pos = [(thisScreen.width - win.size[0]) / 2,
                        (thisScreen.height - win.size[1]) / 2]

I have a retina display that tells thisScreen.width that its width is 1440 pixels. Ah, but win.size on a retina display has been doubled. So, it’s subtracting 2880 from 1440, dividing that by 2, and putting the top-left corner of the window at x = -720.

What I can’t figure out is why thisScreen is reporting in “corrected” retina pixels while everything that uses win.size needs “actual” (doubled) pixels. The inelegant solution is to simply compute win.pos differently depending on whether win.useRetina is true. That’s what I’m going to submit as a BF shortly, but I feel like this is going to cause more problems later if we don’t figure out where it’s originating from.

Note that this only matters for non-fullscreen windows, by the way. Fullscreen windows are just fine.