I'm using matplotlib 2.0.0 installed via anaconda with ipython 4.2.0 on mac os x 10.9.5. Since upgrading to matplotlib 2.0.0, whenever I start a matplotlib-enabled session (e.g., ipython --matplotlib) or a new window is created, it steals focus from the OS. I'm using the TkAgg backend, though the same thing happens with Qt5.
This is particularly a problem for some test codes that create a large number of windows while running; I effectively cannot access the OS at all when the tests are running, even the terminal, so I can't kill the thread.
Any suggestions on what might have happened with this latest upgrade? Since this was anaconda-installed, I can't rule out a change in the backends rather than with matplotlib, but I think the relevant expertise is likelier to be here.
Using the Agg backend seems to stop stealing focus for my python 2.7, Mac OS X 10.10.5. This bug is annoying me too. Unfortunately, Agg is only a bandaid solution.
Edit: Nevermind, I just found the discussion around #12188 which (hopefully) will also fix #8246 in the next release. Fingers crossed.🍀
Has anyone looked at this? This behaviour is especially annoying if working in a jupyter notebook because after matplotlib stole the focus the user needs to use the mouse to select the notebook to have the focus again before being able to execute the next cell.
What I found a bit surprising is that even if I select the inline or notebook backend the focus is stolen (although these two backends do not even create a window to plot).
This was annoying me enough that I tracked it down. It's an IPython thing and nothing to do with matplotlib per se. The cause is that as soon as you start processing events on a QApplication the MacOS dock entry is created and the application is activated. I couldn't find a way to stop the application being immediately activated (or to easily deactivate it once it's first activated), so my fix is to not process any Qt events in the IPython event hook until a window has been created, e.g. a matplotlib figure is shown.
It's working nicely. The only downside is that people using the IPython/Qt event loop integration for things other than plotting (via %gui qt) might notice the change in behaviour because Qt timers etc won't fire until they create a QWidget somewhere. Realistically I think that's a tiny edge case, but to solve it properly would require %pylab/matplotlib.pyplot to set a flag that %gui qt wouldn't and then make the patch behaviour be conditional on that flag. I don't have time to do that now or shepherd through the resulting PR so I'm including the patch here for what it's worth.
The only downside is that people using the IPython/Qt event loop integration for things other than plotting
I think it is a little worse, if people were sloppy and relied on IPython to create the qapplication from them, the first attempt at creating a a QWidget would abort their process.
That said, @pag can you open a PR to IPython with that patch (and ping me, I can help review / shepherd it through there). A slightly simpler change may be to only process events if someone else has created a QAppliaction and never have IPython create one. I have in the past had the opposite view on this, but am starting to change my mind.
This is also rcParams['figure.raise_window']
#figure.raise_window : True # Raise the GUI window to front when show() is called.
which will prevent new windows from stealing focus.
@tacaswell with the patch a QApplication is still created at the moment of GUI loop integration (i.e. the moment that you run %gui qt or %pylab qt) but no events are processed until a top-level QWidget exists, so nothing will crash here that didn't crash before. The dock icon is created at the point of QApplication creation, but it only steals focus when the event loop begins.
Activity
eas342 commented on Jun 14, 2017
Using the Agg backend seems to stop stealing focus for my python 2.7, Mac OS X 10.10.5. This bug is annoying me too. Unfortunately, Agg is only a bandaid solution.
tacaswell commented on Jun 14, 2017
#6384 #6378 and #596
This was likely intentional, but I am not sure exactly what change caused it.
For running tests and background tasks using a non-interactive backend is the right thing to do any way (or to not use plt.show + plt.ion()).
tacaswell commented on Aug 13, 2017
Flagging this a critical to make sure we talk about it.
StefanD986 commented on Oct 31, 2018
Edit: Nevermind, I just found the discussion around #12188 which (hopefully) will also fix #8246 in the next release. Fingers crossed.🍀
Has anyone looked at this? This behaviour is especially annoying if working in a jupyter notebook because after matplotlib stole the focus the user needs to use the mouse to select the notebook to have the focus again before being able to execute the next cell.
What I found a bit surprising is that even if I select the inline or notebook backend the focus is stolen (although these two backends do not even create a window to plot).
I am on OSX 10.14,
Python 3.7
matplotlib 3.0.0
patnr commented on Jun 25, 2019
Is there any solution or hack to address this?
Although bring-to-front is nice, I really want to avoid loosing the focus from the terminal.
Tested with:
In the last case, the focus is not stolen for window creation until I've created and closed some figures to begin with.
m-a-r-o-u commented on Nov 28, 2021
This is still a problem for:
At least for ipython --pylab start up
pag commented on Dec 2, 2021
This was annoying me enough that I tracked it down. It's an IPython thing and nothing to do with matplotlib per se. The cause is that as soon as you start processing events on a QApplication the MacOS dock entry is created and the application is activated. I couldn't find a way to stop the application being immediately activated (or to easily deactivate it once it's first activated), so my fix is to not process any Qt events in the IPython event hook until a window has been created, e.g. a matplotlib figure is shown.
https://gist.github.com/pag/f7d1ebbd1b14fe9058bf68d73a52bc84
It's working nicely. The only downside is that people using the IPython/Qt event loop integration for things other than plotting (via %gui qt) might notice the change in behaviour because Qt timers etc won't fire until they create a QWidget somewhere. Realistically I think that's a tiny edge case, but to solve it properly would require %pylab/matplotlib.pyplot to set a flag that %gui qt wouldn't and then make the patch behaviour be conditional on that flag. I don't have time to do that now or shepherd through the resulting PR so I'm including the patch here for what it's worth.
tacaswell commented on Dec 2, 2021
I think it is a little worse, if people were sloppy and relied on IPython to create the qapplication from them, the first attempt at creating a a QWidget would abort their process.
That said, @pag can you open a PR to IPython with that patch (and ping me, I can help review / shepherd it through there). A slightly simpler change may be to only process events if someone else has created a QAppliaction and never have IPython create one. I have in the past had the opposite view on this, but am starting to change my mind.
This is also rcParams['figure.raise_window']
which will prevent new windows from stealing focus.
pag commented on Dec 3, 2021
@tacaswell with the patch a QApplication is still created at the moment of GUI loop integration (i.e. the moment that you run %gui qt or %pylab qt) but no events are processed until a top-level QWidget exists, so nothing will crash here that didn't crash before. The dock icon is created at the point of QApplication creation, but it only steals focus when the event loop begins.
tacaswell commented on Dec 6, 2021
@pag 🐑 Sorry, I did not read the diff correctly, sorry about that.
I still think you should consider opening this as a PR to IPython (if you have not done so already and the notification is just lost in my inbox).
choucavalier commented on Feb 1, 2022
hey! was a PR opened for that in IPython? if so, what's the link?
tacaswell commented on Apr 30, 2022
There is at least an issue on the IPython side to track this ipython/ipython#13617
tacaswell commented on Apr 30, 2022
I am going to close this because: