]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-42685: Improve placing of simple query windows. (GH-23856)
authorSerhiy Storchaka <storchaka@gmail.com>
Thu, 24 Dec 2020 18:26:28 +0000 (20:26 +0200)
committerGitHub <noreply@github.com>
Thu, 24 Dec 2020 18:26:28 +0000 (20:26 +0200)
* If parent is specified and mapped, the query widget is
  centered at the center of parent. Its position and size
  can be corrected so that it fits in the virtual root window.
* Otherwise it is centered at the center of the screen.

Lib/tkinter/simpledialog.py
Misc/NEWS.d/next/Library/2020-12-19-17-32-43.bpo-42685.kwZlwp.rst [new file with mode: 0644]

index b882d47c961bdbf889d67273e12b5969a86a639c..638da87c8765d334a1563b3fa20864f58431383a 100644 (file)
@@ -55,36 +55,8 @@ class SimpleDialog:
                 b.config(relief=RIDGE, borderwidth=8)
             b.pack(side=LEFT, fill=BOTH, expand=1)
         self.root.protocol('WM_DELETE_WINDOW', self.wm_delete_window)
-        self._set_transient(master)
-
-    def _set_transient(self, master, relx=0.5, rely=0.3):
-        widget = self.root
-        widget.withdraw() # Remain invisible while we figure out the geometry
-        widget.transient(master)
-        widget.update_idletasks() # Actualize geometry information
-        if master.winfo_ismapped():
-            m_width = master.winfo_width()
-            m_height = master.winfo_height()
-            m_x = master.winfo_rootx()
-            m_y = master.winfo_rooty()
-        else:
-            m_width = master.winfo_screenwidth()
-            m_height = master.winfo_screenheight()
-            m_x = m_y = 0
-        w_width = widget.winfo_reqwidth()
-        w_height = widget.winfo_reqheight()
-        x = m_x + (m_width - w_width) * relx
-        y = m_y + (m_height - w_height) * rely
-        if x+w_width > master.winfo_screenwidth():
-            x = master.winfo_screenwidth() - w_width
-        elif x < 0:
-            x = 0
-        if y+w_height > master.winfo_screenheight():
-            y = master.winfo_screenheight() - w_height
-        elif y < 0:
-            y = 0
-        widget.geometry("+%d+%d" % (x, y))
-        widget.deiconify() # Become visible at the desired location
+        self.root.transient(master)
+        _place_window(self.root, master)
 
     def go(self):
         self.root.wait_visibility()
@@ -157,11 +129,7 @@ class Dialog(Toplevel):
 
         self.protocol("WM_DELETE_WINDOW", self.cancel)
 
-        if parent is not None:
-            self.geometry("+%d+%d" % (parent.winfo_rootx()+50,
-                                      parent.winfo_rooty()+50))
-
-        self.deiconify() # become visible now
+        _place_window(self, parent)
 
         self.initial_focus.focus_set()
 
@@ -251,6 +219,37 @@ class Dialog(Toplevel):
         pass # override
 
 
+# Place a toplevel window at the center of parent or screen
+# It is a Python implementation of ::tk::PlaceWindow.
+def _place_window(w, parent=None):
+    w.wm_withdraw() # Remain invisible while we figure out the geometry
+    w.update_idletasks() # Actualize geometry information
+
+    minwidth = w.winfo_reqwidth()
+    minheight = w.winfo_reqheight()
+    maxwidth = w.winfo_vrootwidth()
+    maxheight = w.winfo_vrootheight()
+    if parent is not None and parent.winfo_ismapped():
+        x = parent.winfo_rootx() + (parent.winfo_width() - minwidth) // 2
+        y = parent.winfo_rooty() + (parent.winfo_height() - minheight) // 2
+        vrootx = w.winfo_vrootx()
+        vrooty = w.winfo_vrooty()
+        x = min(x, vrootx + maxwidth - minwidth)
+        x = max(x, vrootx)
+        y = min(y, vrooty + maxheight - minheight)
+        y = max(y, vrooty)
+        if w._windowingsystem == 'aqua':
+            # Avoid the native menu bar which sits on top of everything.
+            y = max(y, 22)
+    else:
+        x = (w.winfo_screenwidth() - minwidth) // 2
+        y = (w.winfo_screenheight() - minheight) // 2
+
+    w.wm_maxsize(maxwidth, maxheight)
+    w.wm_geometry('+%d+%d' % (x, y))
+    w.wm_deiconify() # Become visible at the desired location
+
+
 # --------------------------------------------------------------------
 # convenience dialogues
 
diff --git a/Misc/NEWS.d/next/Library/2020-12-19-17-32-43.bpo-42685.kwZlwp.rst b/Misc/NEWS.d/next/Library/2020-12-19-17-32-43.bpo-42685.kwZlwp.rst
new file mode 100644 (file)
index 0000000..068546a
--- /dev/null
@@ -0,0 +1,4 @@
+Improved placing of simple query windows in Tkinter (such as
+:func:`tkinter.simpledialog.askinteger`). They are now centered at the
+center of the parent window if it is specified and shown, otherwise at the
+center of the screen.