bpo-43655: Tkinter and IDLE dialog windows are now recognized as dialogs by window managers on macOS and X Window (#25187)

This commit is contained in:
Serhiy Storchaka 2021-04-25 13:07:58 +03:00 committed by GitHub
parent 8cc3cfa8af
commit 3bb3fb3be0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 25 additions and 7 deletions

View file

@ -4,6 +4,7 @@
from tkinter import Toplevel, Listbox, StringVar, TclError from tkinter import Toplevel, Listbox, StringVar, TclError
from tkinter.ttk import Frame, Button, Checkbutton, Entry, Label, Scrollbar from tkinter.ttk import Frame, Button, Checkbutton, Entry, Label, Scrollbar
from tkinter import messagebox from tkinter import messagebox
from tkinter.simpledialog import _setup_dialog
import string import string
import sys import sys
@ -63,6 +64,7 @@ def __init__(self, parent, title, action, current_key_sequences,
self.resizable(height=False, width=False) self.resizable(height=False, width=False)
self.title(title) self.title(title)
self.transient(parent) self.transient(parent)
_setup_dialog(self)
self.grab_set() self.grab_set()
self.protocol("WM_DELETE_WINDOW", self.cancel) self.protocol("WM_DELETE_WINDOW", self.cancel)
self.parent = parent self.parent = parent

View file

@ -28,6 +28,7 @@
from tkinter.ttk import Frame, Button, Entry, Label, Checkbutton from tkinter.ttk import Frame, Button, Entry, Label, Checkbutton
from tkinter import filedialog from tkinter import filedialog
from tkinter.font import Font from tkinter.font import Font
from tkinter.simpledialog import _setup_dialog
class Query(Toplevel): class Query(Toplevel):
"""Base class for getting verified answer from a user. """Base class for getting verified answer from a user.
@ -60,13 +61,8 @@ def __init__(self, parent, title, message, *, text0='', used_names={},
if not _utest: # Otherwise fail when directly run unittest. if not _utest: # Otherwise fail when directly run unittest.
self.grab_set() self.grab_set()
windowingsystem = self.tk.call('tk', 'windowingsystem') _setup_dialog(self)
if windowingsystem == 'aqua': if self._windowingsystem == 'aqua':
try:
self.tk.call('::tk::unsupported::MacWindowStyle', 'style',
self._w, 'moveableModal', '')
except:
pass
self.bind("<Command-.>", self.cancel) self.bind("<Command-.>", self.cancel)
self.bind('<Key-Escape>', self.cancel) self.bind('<Key-Escape>', self.cancel)
self.protocol("WM_DELETE_WINDOW", self.cancel) self.protocol("WM_DELETE_WINDOW", self.cancel)

View file

@ -2,6 +2,7 @@
from tkinter import Toplevel from tkinter import Toplevel
from tkinter.ttk import Frame, Entry, Label, Button, Checkbutton, Radiobutton from tkinter.ttk import Frame, Entry, Label, Button, Checkbutton, Radiobutton
from tkinter.simpledialog import _setup_dialog
class SearchDialogBase: class SearchDialogBase:
@ -83,6 +84,7 @@ def create_widgets(self):
top.protocol("WM_DELETE_WINDOW", self.close) top.protocol("WM_DELETE_WINDOW", self.close)
top.wm_title(self.title) top.wm_title(self.title)
top.wm_iconname(self.icon) top.wm_iconname(self.icon)
_setup_dialog(top)
self.top = top self.top = top
self.frame = Frame(top, padding="5px") self.frame = Frame(top, padding="5px")
self.frame.grid(sticky="nwes") self.frame.grid(sticky="nwes")

View file

@ -24,6 +24,7 @@
) )
from tkinter.dialog import Dialog from tkinter.dialog import Dialog
from tkinter import commondialog from tkinter import commondialog
from tkinter.simpledialog import _setup_dialog
dialogstates = {} dialogstates = {}
@ -62,6 +63,7 @@ def __init__(self, master, title=None):
self.top = Toplevel(master) self.top = Toplevel(master)
self.top.title(title) self.top.title(title)
self.top.iconname(title) self.top.iconname(title)
_setup_dialog(self.top)
self.botframe = Frame(self.top) self.botframe = Frame(self.top)
self.botframe.pack(side=BOTTOM, fill=X) self.botframe.pack(side=BOTTOM, fill=X)

View file

@ -40,6 +40,9 @@ def __init__(self, master,
if title: if title:
self.root.title(title) self.root.title(title)
self.root.iconname(title) self.root.iconname(title)
_setup_dialog(self.root)
self.message = Message(self.root, text=text, aspect=400) self.message = Message(self.root, text=text, aspect=400)
self.message.pack(expand=1, fill=BOTH) self.message.pack(expand=1, fill=BOTH)
self.frame = Frame(self.root) self.frame = Frame(self.root)
@ -115,6 +118,8 @@ def __init__(self, parent, title = None):
if title: if title:
self.title(title) self.title(title)
_setup_dialog(self)
self.parent = parent self.parent = parent
self.result = None self.result = None
@ -252,6 +257,13 @@ def _place_window(w, parent=None):
w.wm_deiconify() # Become visible at the desired location w.wm_deiconify() # Become visible at the desired location
def _setup_dialog(w):
if w._windowingsystem == "aqua":
w.tk.call("::tk::unsupported::MacWindowStyle", "style",
w, "moveableModal", "")
elif w._windowingsystem == "x11":
w.wm_attributes("-type", "dialog")
# -------------------------------------------------------------------- # --------------------------------------------------------------------
# convenience dialogues # convenience dialogues

View file

@ -0,0 +1,2 @@
IDLE dialog windows are now recognized as dialogs by window managers on
macOS and X Window.

View file

@ -0,0 +1,2 @@
:mod:`tkinter` dialog windows are now recognized as dialogs by window
managers on macOS and X Window.