diff --git a/Lib/idlelib/idle_test/test_stackviewer.py b/Lib/idlelib/idle_test/test_stackviewer.py index 2434d38e4ffe83e..341f158031d5f42 100644 --- a/Lib/idlelib/idle_test/test_stackviewer.py +++ b/Lib/idlelib/idle_test/test_stackviewer.py @@ -35,6 +35,8 @@ def test_init(self): isi(stackviewer.sc, ScrolledCanvas) isi(stackviewer.item, stackviewer.StackTreeItem) isi(stackviewer.node, TreeNode) + top = stackviewer.sc.frame.winfo_toplevel() + self.assertEqual(top.winfo_class(), 'Idle') if __name__ == '__main__': diff --git a/Lib/idlelib/idle_test/test_window.py b/Lib/idlelib/idle_test/test_window.py index 9b56d321a407d68..d8a77817205dc39 100644 --- a/Lib/idlelib/idle_test/test_window.py +++ b/Lib/idlelib/idle_test/test_window.py @@ -39,6 +39,11 @@ def test_init(self): win = window.ListedToplevel(self.root) self.assertIn(win, window.registry) self.assertEqual(win.focused_widget, win) + self.assertEqual(win.winfo_class(), 'Idle') + + def test_init_class_override(self): + win = window.ListedToplevel(self.root, class_='Other') + self.assertEqual(win.winfo_class(), 'Other') if __name__ == '__main__': diff --git a/Lib/idlelib/pyshell.py b/Lib/idlelib/pyshell.py index b1662491935e4a0..a07d14d919895ca 100755 --- a/Lib/idlelib/pyshell.py +++ b/Lib/idlelib/pyshell.py @@ -643,7 +643,7 @@ def remote_stack_viewer(self): return item = debugobj_r.StubObjectTreeItem(self.rpcclt, oid) from idlelib.tree import ScrolledCanvas, TreeNode - top = Toplevel(self.tkconsole.root) + top = Toplevel(self.tkconsole.root, class_='Idle') theme = idleConf.CurrentTheme() background = idleConf.GetHighlight(theme, 'normal')['background'] sc = ScrolledCanvas(top, bg=background, highlightthickness=0) diff --git a/Lib/idlelib/stackviewer.py b/Lib/idlelib/stackviewer.py index 95042d4debdc03b..268e2f1daeb98cc 100644 --- a/Lib/idlelib/stackviewer.py +++ b/Lib/idlelib/stackviewer.py @@ -11,7 +11,7 @@ def StackBrowser(root, exc, flist=None, top=None): global sc, item, node # For testing. if top is None: - top = tk.Toplevel(root) + top = tk.Toplevel(root, class_='Idle') sc = ScrolledCanvas(top, bg="white", highlightthickness=0) sc.frame.pack(expand=1, fill="both") item = StackTreeItem(exc, flist) diff --git a/Lib/idlelib/window.py b/Lib/idlelib/window.py index 460d5b67948dde2..a41d69927dcdd57 100644 --- a/Lib/idlelib/window.py +++ b/Lib/idlelib/window.py @@ -61,6 +61,10 @@ def call_callbacks(self): class ListedToplevel(Toplevel): def __init__(self, master, **kw): + # Set the WM_CLASS property so that X11 window managers group and + # label IDLE's windows under 'Idle' instead of the default + # 'Toplevel' (gh-66331). It matches the class name passed to Tk(). + kw.setdefault('class_', 'Idle') Toplevel.__init__(self, master, kw) registry.add(self) self.focused_widget = self diff --git a/Misc/NEWS.d/next/IDLE/2026-07-01-00-00-00.gh-issue-66331.wMcLaS.rst b/Misc/NEWS.d/next/IDLE/2026-07-01-00-00-00.gh-issue-66331.wMcLaS.rst new file mode 100644 index 000000000000000..e00e7c7d8fdc652 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2026-07-01-00-00-00.gh-issue-66331.wMcLaS.rst @@ -0,0 +1,3 @@ +Set the ``WM_CLASS`` window property of IDLE's windows to ``Idle`` on X11, +so that window managers group and label them correctly instead of using the +default ``Toplevel``.