I'm building a Python desktop app that uses both pystray (for a system tray icon) and Tkinter (for message boxes and dialogs). Everything works fine except for one issue on Windows 11: when I open a tkinter.messagebox (or any Tkinter window) from a pystray menu callback, the window appears unfocused or behind other windows
Note that my program works on Windows 10.
What I’ve tried
Setting
root.attributes("-topmost", True)androot.focus_force()Calling
root.lift()orroot.after()to delay focusRunning
Tk()in the main threadUsing a dedicated
GuiDispatcherclass to marshal UI calls to the main Tkinter thread
The problem persists intermittently — sometimes it works, sometimes the window still opens in the background.
System info
Windows 11 23H2
Python 3.13
pystray 0.19.5
tkinter (standard)
What I’d like to know
Is this a known limitation or bug with Tkinter on Windows 11 when invoked from non-main threads?
Any best practices for combining pystray and Tkinter in multi-threaded apps?
Here's a minimal reproducible example:
import threading
import tkinter as tk
from tkinter import messagebox
import pystray
from PIL import Image, ImageDraw
def create_icon_image():
img = Image.new('RGB', (64, 64), (30, 144, 255))
d = ImageDraw.Draw(img)
d.rectangle([16, 16, 48, 48], fill=(255, 255, 255))
return img
def show_messagebox():
root = tk.Tk()
root.withdraw()
messagebox.showinfo("Test", "Window opened from tray menu", parent=root)
root.destroy()
def on_click(icon, item):
threading.Thread(target=show_messagebox, daemon=True).start()
icon = pystray.Icon(
"test_icon",
create_icon_image(),
"Test Tray",
menu=pystray.Menu(pystray.MenuItem("Show message", on_click))
)
icon.run()