From 9287fb6c4e3e1409650a384df5ada76b0e27e986 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 1 Jul 2026 08:00:16 +0300 Subject: [PATCH] gh-66331: Set correct WM_CLASS on X11 for IDLE windows Set the WM_CLASS of IDLE's long-lived windows (window-list windows and the stack viewers) to "Idle" instead of the default "Toplevel", so that window managers group and label them correctly. --- Lib/idlelib/idle_test/test_stackviewer.py | 2 ++ Lib/idlelib/idle_test/test_window.py | 5 +++++ Lib/idlelib/pyshell.py | 2 +- Lib/idlelib/stackviewer.py | 2 +- Lib/idlelib/window.py | 4 ++++ .../next/IDLE/2026-07-01-00-00-00.gh-issue-66331.wMcLaS.rst | 3 +++ 6 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/IDLE/2026-07-01-00-00-00.gh-issue-66331.wMcLaS.rst diff --git a/Lib/idlelib/idle_test/test_stackviewer.py b/Lib/idlelib/idle_test/test_stackviewer.py index 2434d38e4ffe83..341f158031d5f4 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 9b56d321a407d6..d8a77817205dc3 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 b1662491935e4a..a07d14d919895c 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 95042d4debdc03..268e2f1daeb98c 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 460d5b67948dde..a41d69927dcdd5 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 00000000000000..e00e7c7d8fdc65 --- /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``.