psychopy.org | Reference | Downloads | Github

Mouse focus with gui.Dlg when a window is open (in Windows 10 only)

I have a program where, for various reasons, I have a visual.window open, and then I present a dialog using gui.Dlg. On MacOS, this works just fine. On Windows 10, the mouse does not work inside the dialog box until you click outside the psychopy window or alt-tab out and back. I can’t figure out a way around this.

Windows 10 is known to have issues with tracking the active window, so I’m not sure if there’s anything to be done at this end. I’m open to ideas, however.

You might need to explicitly activate that window, e.g:

I’m having sort of the opposite problem. The mouse focus does not shift to the dialog box, which is separate from the window. I also can’t call anything after Dlg.show() until OK or Cancel has been clicked. The dialog box is not a pyglet object, it is a pyQT object. Does pyQT have a winhandler in the same way that I can call from PsychoPy?

Update: It does, kind of. The way “show” works for gui.Dlg objects prevents any further code from being executed until OK or Cancel has been clicked. However, the qtgui module’s “show” function calls display, which calls exec_(), and that does include a call to self.activateWindow(), as well as self.raise_().

By all rights that should allow you to interact with the dialog with the mouse, even with a pyglet window open, but it does not. Clearly this is only for pyglet windows and not the wxpython windows the builder uses, because it doesn’t happen there (though I’m unsure whether the builder uses the qtgui code). The dialogs also work correctly as long as there is no pyglet window open.

My guess is that this is related to Windows’s general tendency to stop things from stealing focus from an active window. I also can’t find a way to make the pyglet window give up its focus before showing the dialog. Open to suggestions.

Update: Ugly fix. Solved with making the window set_visible(visible=False) before calling Dlg.show(), then setting it to true again after the dialog is closed. This introduced a further problem: when you set a pyglet window to invisible, it freezes the mouse state as whatever it was at that moment, so I needed to make sure it did that part on mouse up rather than mouse down. Marking solved and leaving for reference if anyone else ever needs to solve this problem with rubber bands and chewing gum.