classification
Title: Visual Styles support to tk/tkinter file and message dialogs
Type: enhancement Stage: resolved
Components: Tkinter, Windows Versions: Python 3.6, Python 3.5
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: steve.dower Nosy List: Pat Thoyts, [HYBRID BEING], paul.moore, python-dev, serhiy.storchaka, steve.dower, terry.reedy, tim.golden, zach.ware
Priority: normal Keywords:

Created on 2016-06-13 21:59 by [HYBRID BEING], last changed 2016-07-18 04:42 by steve.dower. This issue is now closed.

Files
File name Uploaded Description Edit
python.exe.manifest Pat Thoyts, 2016-06-20 12:18 Example Windows manifest XML
Messages (10)
msg268477 - (view) Author: [HYBRID BEING] ([HYBRID BEING]) Date: 2016-06-13 21:59
This answer (http://stackoverflow.com/questions/33792008/python-tkinter-ttk-themed-message-box/33801260#33801260) to the Stack Overflow question states that Tkinter's messageboxes use non-themed controls due to the fact that python.exe and pythonw.exe lack manifest which notifies Windows that application supports Visual Styles.
Is there any specific reason it's not used?
msg268746 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2016-06-17 23:38
tkinter.messagebox is based on tkinter.commondialog, first written in 1997. Since it works as originally designed, it does not seem to have been significantly altered since before themed widgets. Upgrading would be an enhancement for future versions, not a bugfix for all versions.

The SO answer is correct that tkinter does not build the messagebox, but indeed calls into tk with, for message boxes, the command "tk_messageBox", to get the builtin box.

Since I am converting IDLE on 3.6 to use ttk where appropriate, I would very mush like to be able to get the better looking versions of the builtin dialogs -- and in 3.6 -- and on all 3 majore systems, not just Windows.  Since tkinter still supports 8.4 (should this change?) and ttk requires 8.5, this needs to be an option or at least version dependent.

I report this issue in a comment on 'patthoyts' answer.
msg268891 - (view) Author: [HYBRID BEING] ([HYBRID BEING]) Date: 2016-06-20 10:59
Ok, you sorta lost me. Would patthoyts's solution not work with Tk <8.5? As i understood (which i may did wrong), message box is returned by system (or is it actually Tk, and not system?), and it uses styled/non-styled controls based on calling process manifests, right? Then where does tkinter comes into equation?
Moreover, on OS X and Ubuntu message boxes seem to use themed controls (at least simple message boxes do) just fine.
msg268897 - (view) Author: Pat Thoyts (Pat Thoyts) * Date: 2016-06-20 12:18
As explained in the SO answer, in Tk on Windows the messagebox, file open dialog, save as dialog and in 8.6 up the font dialog are all system standard dialogs. Tk gets Windows to show the common dialog or messagebox and just wraps the Win32 API calls. As a result these dialogs are not themed using ttk as the various elements are not Tk controls at all.

The theming control is therefore provided by Windows and is controlled at an application level by the use of an RT_MANIFST resource. This contains various chunk of XML and one of these is used to declare that theming may be applied by the Visual Styles API. The Tk executables include this bit of manifest but the python exe does not.

You can test this out using the attached python.exe.manifest file. To allow this to work you have to remove the existing RT_MANIFEST resource from the python executable as an embedded resource overrides a sibling manifest file. I find the easiest way to work with this is to open the exe in Visual Studio and use the resources view to change the resource in place. You can copy the contents of the manifest file over the existing RT_MANIFEST resource or you can remove the embedded resource and let the system pick up the python.exe.manifest file from the same folder as python.exe.

This is not dependent on Tk version. All versions of Tk since around 8.0 have delegated to the Win32 MessageBox and GetOpenFileName API calls. With the introduction of Window XP and the Visual Styles API Microsoft added this requirement to declare support for theming via manifests. So if you have the right manifest and theming is enabled on your system then Tk 8.4 and 8.3 will all show themed common dialogs and messageboxes.

This does not affect OS X or X Windows. On X Windows Tk provides all these dialogs itself and so they use Tk widgets (or ttk widgets in more recent versions). On OS X I believe the messagebox and common dialogs are all system provided but it will have its own system for controlling that.

In short, python needs to merge it this manifest with the manifest being put in place already. The Visual Studio 'mt' tool can do that if you want to merge manifests.
msg268927 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2016-06-20 20:28
Pat, thank you for the explanation, xml, and link.  I was a bit confused by the overlapping yet different meanings of 'ttk theme' and 'Windows theme'.

For 3.6, I am converting IDLE to use ttk widgets.  From the example on the SO page, which links to https://i.stack.imgur.com/36MnO.png, the new Windows common controls better fit the default ttk theme on Windows.  However, for the same reason, the old set better fits standard tk widgets.  My impression from Stackoverflow tkinter questions is that most beginers start with tk widgets only.

Therefore, using the new set should not be forced on all Windows tkinter users.  Tkinter would need to be enhanced to optionally tell tk to use the new set.  I don't know if this is possible or how it would be done.  I leave this to Serhiy.

For an example, open IDLE on Windows with 3.6.0a2 or before.  Select Options => Configure IDLE => Highlighting.  Click [Save as New Custom Theme] to bring up a constructed entry box.  Without entering anything, click [Ok].  The commondialog messagebox error popup has an [Ok] button with a similar relief.

IDLE does not here use the commondialog entry messagebox because these disappear as soon as [Ok] is clicked, before error checking.  For an annoying example, select File => Open Module (Alt-m) and enter something that is not exactly 'idlelib.configdialog' (or 'idlelib.configDialog' before 3.6.0a2).  After dismissing the error box, one has to begin over.  I plan to replace with a custom validating entry popup.

> On X Windows Tk provides all these dialogs itself and so they use Tk widgets (or ttk widgets in more recent versions).

I wish these were available, at least as an option, on all systems.
msg269006 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2016-06-21 15:59
If someone wants to make a patch, the manifest we embed is in PC/python.manifest
msg269007 - (view) Author: Zachary Ware (zach.ware) * (Python committer) Date: 2016-06-21 16:16
I wonder whether this manifest change would affect other GUI toolkit packages (though frankly I'm having trouble finding any others that work with Python 3 on Windows...), positively or negatively.  Would it be possible to tie this to _tkinter.pyd instead of python{w}.exe?
msg269010 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2016-06-21 16:56
> Would it be possible to tie this to _tkinter.pyd instead of python{w}.exe?

Afraid not, Windows needs to load a different version of a particular DLL for the entire process. But at this stage it shouldn't negatively affect anyone. I'd even be okay adding it into 3.5.
msg270691 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2016-07-18 04:40
New changeset 7ffb7f3c345d by Steve Dower in branch '3.5':
Issue #27309: Enables proper Windows styles in python[w].exe manifest.
https://hg.python.org/cpython/rev/7ffb7f3c345d

New changeset da735eb8b7a2 by Steve Dower in branch 'default':
Issue #27309: Enables proper Windows styles in python[w].exe manifest.
https://hg.python.org/cpython/rev/da735eb8b7a2
msg270692 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2016-07-18 04:42
Updated the manifest to include the correct common controls DLL, which ensures the correct style is used for native dialogs.

I applied this to Python 3.5 and 3.6, since it's not a behavioural change and should not break any code, and arguably since it's been the recommended default for all apps targeting XP or later it's a bug that we weren't already doing it.
History
Date User Action Args
2016-07-18 04:42:01steve.dowersetstatus: open -> closed
versions: + Python 3.5
messages: + msg270692

assignee: steve.dower
resolution: fixed
stage: test needed -> resolved
2016-07-18 04:40:20python-devsetnosy: + python-dev
messages: + msg270691
2016-06-21 16:56:34steve.dowersetmessages: + msg269010
2016-06-21 16:16:03zach.waresetmessages: + msg269007
2016-06-21 15:59:21steve.dowersetmessages: + msg269006
2016-06-20 20:28:38terry.reedysetmessages: + msg268927
2016-06-20 12:18:46Pat Thoytssetfiles: + python.exe.manifest
nosy: + Pat Thoyts
messages: + msg268897

2016-06-20 10:59:16[HYBRID BEING]setmessages: + msg268891
2016-06-17 23:38:52terry.reedysettype: behavior -> enhancement
title: Visual Styles support -> Visual Styles support to tk/tkinter file and message dialogs
components: + Tkinter

nosy: + terry.reedy, serhiy.storchaka
versions: + Python 3.6, - Python 3.4, Python 3.5
messages: + msg268746
stage: test needed
2016-06-13 21:59:56[HYBRID BEING]create