Use rcParams to control default "raise window" behavior (Qt,Gtk,Tk,Wx) by immaxchen · Pull Request #15440 · matplotlib/matplotlib · GitHub
Skip to content

Use rcParams to control default "raise window" behavior (Qt,Gtk,Tk,Wx) - #15440

Merged
jklymak merged 2 commits into
matplotlib:masterfrom
immaxchen:add-rcparams-to-control-raise-window-behavior-gh8692
Jan 28, 2020
Merged

Use rcParams to control default "raise window" behavior (Qt,Gtk,Tk,Wx)#15440
jklymak merged 2 commits into
matplotlib:masterfrom
immaxchen:add-rcparams-to-control-raise-window-behavior-gh8692

Conversation

@immaxchen

@immaxchen immaxchen commented Oct 18, 2019

Copy link
Copy Markdown
Contributor

PR Summary

Address Issue #8692

A new rcParms entry have been added: "figure.raise_window"
Now it is possible to disable the default "raise GUI window" behavior
This change apply to & tested on Qt4, Qt5, Gtk3, Tk and Wx backends (OS: CentOS7, Win7)
Has document it in the 'whats new' section

Known Issue:
Gtk3 have to use a small trick to force the screen update, better solutions welcome
Qt4 "raise window" pop-out "Figure is ready", have to click the notification manually

Side Note:
Wx backend didn't implement the "raise window" behavior before
Don't have a Mac to work on macosx backend
Manually tested with the attached python script

test_raise_window.txt

PR Checklist

  • Has Pytest style unit tests
  • Code is Flake 8 compliant
  • New features are documented, with examples if plot related
  • Documentation is sphinx and numpydoc compliant
  • Added an entry to doc/users/next_whats_new/ if major new feature (follow instructions in README.rst there)
  • Documented in doc/api/api_changes.rst if API changed in a backward-incompatible way

@immaxchen

Copy link
Copy Markdown
Contributor Author

@immaxchen

Copy link
Copy Markdown
Contributor Author

Also tested on Windows7, working as expected.

@timhoffm timhoffm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Looks good apart from the what's new message 👍.

Could you sqash your commits if possible? - Otherwise we'll do it before merging.

Comment on lines +5 to +7
A new rcParms entry have been added: with the ``figure.raise_window`` option
now it is possible to disable the default "raise GUI window" behavior when
calling ``plt.show`` or ``plt.pause`` methods.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new config option rcParams['figure.raise_window'] allows to disable
raising the plot window when calling plt.show or plt.pause methods.

Should be sufficient and more straight forward.

… (Qt,Gtk,Tk,Wx)

A new rcParms entry have been added: "figure.raise_window"
Now it is possible to disable the default "raise GUI window" behavior
This change apply to & tested on Qt, Gtk, Tk and Wx backends (CentOS7 & Win7)
Has document it in the 'whats new' section
@immaxchen
immaxchen force-pushed the add-rcparams-to-control-raise-window-behavior-gh8692 branch from 5e76728 to 1b4c4ad Compare October 24, 2019 13:02
@immaxchen

immaxchen commented Oct 24, 2019

Copy link
Copy Markdown
Contributor Author

Great thanks for the help on the message, i'm not a native speaker. 😂
Have tried to rebase it, am i doing it right?

@timhoffm timhoffm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rebase is correct 👍

What do you mean by: Qt4 "raise window" pop-out "Figure is ready", have to click the notification manually.

# show the figure window
self.window.show()
self.window.present()
self.canvas.draw()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does GTK3 need a draw now?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I am testing with Gtk3 and turn off the "raise window", I encountered a strange behavior, that the GUI window is reluctant to update, and the whole program get stuck, loop is not running, until I move/switch the GUI window or moving my mouse cursor on the canvas, it can continue to run/update.
After debug and tracing, I found the program is stuck inside the Gtk.main_iteration() here:

    def flush_events(self):
        # docstring inherited
        Gdk.threads_enter()
        while Gtk.events_pending():
            Gtk.main_iteration()
        Gdk.flush()
        Gdk.threads_leave()

By looking into the doc, it says if there is no event queued, main_iteration will block until the next event is noticed, but that's very strange since we have already checked with events_pending, if there is no event it should not go into the while-loop. Nevertheless, I changed using Gtk.gtk_main_iteration_do(False) which the doc states that it won't block, however, that's not working, the program still get stuck inside gtk_main_iteration_do. Finally, I come up with a solution: to call window.queue_draw() right after window.show() and successfully I don't have to waving my mouse cursor over the canvas any more. And I found that this is exactly what canvas.draw() is doing, and the same approach is also used in the backend_wx.py, so I suppose this is the right way to do it? I am not familiar with the GUI stuff so I have no idea what's happening, please feel free to correct me.
This is the full report, HaHa!! Thank you so much for your patience reading this mumbo jumbo!! 😜

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you test with draw_idle instead?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tested, won't update, need stick to draw

@immaxchen

immaxchen commented Oct 25, 2019

Copy link
Copy Markdown
Contributor Author

image

This is what I saw when I'm testing on my machine using pyqt=4 (cannot actually "raise" to top automatically, instead, have to click on the notification to bring up the window)
But using qt5 can actually bring the window to the top as expected

@timhoffm

Copy link
Copy Markdown
Member

So instead of the window, a "Figure 1 is ready" message is popping to the front?

@immaxchen

Copy link
Copy Markdown
Contributor Author

Yes! and it is exactly the one shown in the top-right corner of my attached image.

@timhoffm

timhoffm commented Oct 26, 2019

Copy link
Copy Markdown
Member

Hm, I don't find any related "... is ready" text in our code base. So who is generating that message? You are seeing this only in Qt4, not Qt5, and you are on master?

@QuLogic

QuLogic commented Oct 27, 2019

Copy link
Copy Markdown
Member

The message is triggered by your window manager, which isn't allowing focus stealing.

@immaxchen

Copy link
Copy Markdown
Contributor Author

Yes! only in Qt4, not Qt5, and on master.
It is not generated by mpl, it's a Gnome thing (related post: here and here)
But don't know why only Qt4 is suffering this.

@timhoffm

Copy link
Copy Markdown
Member

Given that Qt4 is end of life and major distributions are defaulting to Qt5, I wouldn‘t wollt too much if we can‘t get this fixed for Qt4.

@immaxchen

Copy link
Copy Markdown
Contributor Author

Sure, so is there anything else I need to do?

@timhoffm

Copy link
Copy Markdown
Member

I don‘t think so. I still want to take a closer look at the GTK redraw.

@immaxchen

Copy link
Copy Markdown
Contributor Author

OK, thanks!

@anntzer

anntzer commented Dec 7, 2019

Copy link
Copy Markdown
Contributor

In general this looks nice.
How does this interact with rcParams["tk.window_focus"]? If they are overlapping in functionality should tk.window_focus be deprecated?

@efiring

efiring commented Dec 10, 2019

Copy link
Copy Markdown
Member

This looks very helpful (based on a quick scan).

One thought occurs to me: would it make sense to have this controlled by an optional keyword argument to plt.show? That way it could be controlled locally instead of only globally. It would require adding the keyword argument to the intermediate Figure.show and each Backend.show as well. I think the setting of the default by rcParam could stay in the backends.

@immaxchen

Copy link
Copy Markdown
Contributor Author

Thanks for the advice, seems reasonable to me. But they could be discussed & handled in separated issue & PR, IMHO.

@carlosgmartin

Copy link
Copy Markdown
Contributor

Any update on this?

@efiring efiring left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should get this in ASAP. I don't see how it can do any real harm, and it is an important feature requiring minimal code.

@anntzer

anntzer commented Jan 13, 2020

Copy link
Copy Markdown
Contributor

I think the whatsnew should at least mention that this doesn't work on the macos backend (which is fine); clarifying (as above) the interaction with the tk.window_focus rc would be nice as well.

@efiring

efiring commented Jan 13, 2020

Copy link
Copy Markdown
Member

@anntzer Good points. If this goes in, will you want to support the rcParam in your mplcairo backend?

@anntzer

anntzer commented Jan 13, 2020

Copy link
Copy Markdown
Contributor

I haven't actually checked, but I'm almost certain mplcairo will work just fine with it because it just inherits the show() methods from the various backend-dependent but renderer-independent base classes (similarly, you can see that here the changes are in qt5.py wx.py etc. and not qt5agg.py/qt5cairo.py wxagg.py/wxcairo.py etc.).

@efiring efiring added this to the v3.3.0 milestone Jan 13, 2020
@immaxchen

Copy link
Copy Markdown
Contributor Author

I think this functionality is not exactly identical to the rcParams["tk.window_focus"].
According to the information from SO, the code used here only displays the window above all other windows (set attributes topmost as True), not necessarily steal the focus from another window.
On the other hand, rcParams["tk.window_focus"] tries to steal focus by using Win32 API.

@immaxchen

Copy link
Copy Markdown
Contributor Author

Add this to whatsnew?

MacOSX backend is currently not supported.
To control the focus stealing behavior for Tk backends, use rcParams["tk.window_focus"] instead.

@tacaswell tacaswell left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

conditional on adding a note about OSX not being supported (or explicitly listing the backends that are supported).

@immaxchen

Copy link
Copy Markdown
Contributor Author

done~

@jklymak
jklymak merged commit 01e267c into matplotlib:master Jan 28, 2020
@jklymak

jklymak commented Jan 28, 2020

Copy link
Copy Markdown
Member

Thanks @immaxchen

@carlosgmartin

Copy link
Copy Markdown
Contributor

Is there a fix for OSX?

@pczhang-tony

pczhang-tony commented Jun 10, 2021

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants