Importing pyplot causes bouncing dock icon on mac #10137

Closed
ngoldbaum opened this Issue Jan 8, 2017 · 9 comments

Projects

None yet

3 participants

@ngoldbaum
Contributor

This is illustrated by the following gif:

image

Importing pyplot in the normal python repl causes the python rocket icon to appear but not bounce distractingly. Importing it inside IPython causes the icon to bounce annoyingly for almost a minute.

This is using a framework build of Python from Homebrew.

@tacaswell
Contributor

which backend are you using? Does running plt.ion() or %matplotlib help?

My knee-jerk / making this up as I go guess is: When IPython de-coupled from readline, it also decoupled from the PyOS_InputHook machinery. In the plain python case, the GUI is starting up (starting the bouncing), the GUI code installs the hook, and when it finishes starting up some how phones home to let the rocket know to stop bouncing because the gui main loop runs intercolated with the repl. In IPython, that hook is still installed, but does not matter because IPython is running through prompt toolkit. If you start up the IPython event loop integration the GUI will phone home and stop the bouncing.

Or I could be wildly off base.

@ngoldbaum
Contributor
ngoldbaum commented Jan 8, 2017 edited

This is using the MacOSX backend. Using plt.ion() or %matplotlib after the pyplot import doesn't stop the bouncing and using %matplotlib before doing the pyplot import just causes the icon to start bouncing.

@tacaswell
Contributor

Does it happen with the tk backend?

@ngoldbaum
Contributor

Nope, no rocket icon at all with TkAgg.

@Carreau Carreau added the bug label Jan 12, 2017
@Carreau
Member
Carreau commented Jan 12, 2017

I'm going to stay that's linked to #9312
I'm going to try to understand it. Ping @minrk.

@Carreau
Member
Carreau commented Jan 12, 2017

I'm going to say that this:

    if not window_count:
        return

Need to be removed as the eventloop integration need to run even if there is no windows... it appears to be working for me.
Alternative would be to make sure inputhook(context) does at least one loop even if no windows.. so along:

    global at_least_once
    if not window_count and not at_least_once:
        at_least_once = True
        return

@ngoldbaum would you mind trying ?
Also I suppose it stop bouncing as soon as you have your first window ?

@Carreau Carreau added this to the 5.2 milestone Jan 12, 2017
@Carreau
Member
Carreau commented Jan 12, 2017

The screen recording also make me happy because it is realistic in its typing, and make me feel less guilty about my horrendous typing.

@ngoldbaum
Contributor

Indeed, removing that

if not window_count:
    return

block fixes the issue for me. And as you suspected, creating a plot stops the bouncing.

@Carreau Carreau added a commit to Carreau/ipython that referenced this issue Jan 12, 2017
@Carreau Carreau Always run the OS X loop even if no windows.
Otherwise this can trigger infinite Python-Icon-In-Dock bouncing.
See #10137. I will guess that this is because application on OS X may
not have windows and still need to process events.

It may be that an alternative is to run the loop only once the first
time, but I'm unsure.

    at_least_once = False

    def inputhook(context):
	"""Inputhook for Cocoa (NSApp)"""
	NSApp = _NSApp()
	window_count = msg(
	    msg(NSApp, n('windows')),
	    n('count')
	)
	if not window_count and not at_least_once:
	    at_least_once = True
	    return
	_stop_on_read(context.fileno())
	msg(NSApp, n('run'))
	if not _triggered.is_set():
	    # app closed without firing callback,
	    # probably due to last window being closed.
	    # Run the loop manually in this case,
	    # since there may be events still to process (#9734)
	    CoreFoundation.CFRunLoopRun()

Closes #10137
260e988
@Carreau
Member
Carreau commented Jan 12, 2017

Submitted #10150, will wait for review of more qualified people.

@minrk minrk pushed a commit that closed this issue Jan 13, 2017
@Carreau Carreau Always run the OS X loop even if no windows.
Otherwise this can trigger infinite Python-Icon-In-Dock bouncing.
See #10137. I will guess that this is because application on OS X may
not have windows and still need to process events.

It may be that an alternative is to run the loop only once the first
time, but I'm unsure.

    at_least_once = False

    def inputhook(context):
	"""Inputhook for Cocoa (NSApp)"""
	NSApp = _NSApp()
	window_count = msg(
	    msg(NSApp, n('windows')),
	    n('count')
	)
	if not window_count and not at_least_once:
	    at_least_once = True
	    return
	_stop_on_read(context.fileno())
	msg(NSApp, n('run'))
	if not _triggered.is_set():
	    # app closed without firing callback,
	    # probably due to last window being closed.
	    # Run the loop manually in this case,
	    # since there may be events still to process (#9734)
	    CoreFoundation.CFRunLoopRun()

Closes #10137
260e988
@minrk minrk closed this in 260e988 Jan 13, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment