diff options
| author | Yves Wang <zhengjia.wang@nxp.com> | 2025-11-27 16:52:26 +0800 |
|---|---|---|
| committer | Torsten Tejlmand Rasmussen <torsten.rasmussen@nordicsemi.no> | 2025-12-04 14:52:35 +0100 |
| commit | ffb54593b899c42fe70e55d26e02d4cd4a9ca53d (patch) | |
| tree | a6daabf8f2373e00ced9291967dba844fa0919dc /guiconfig.py | |
| parent | 601f63d035ba355fefb69387de1a9bc5cc2201ab (diff) | |
guiconfig: Add dark mode
TK under Windows/Linux did not have a native support for dark mode.
Signed-off-by: Yves Wang <zhengjia.wang@nxp.com>
Diffstat (limited to 'guiconfig.py')
| -rwxr-xr-x | guiconfig.py | 132 |
1 files changed, 126 insertions, 6 deletions
diff --git a/guiconfig.py b/guiconfig.py index 45c0d9d..21f034e 100755 --- a/guiconfig.py +++ b/guiconfig.py @@ -271,6 +271,47 @@ def _needs_save(): # No need to prompt for save return False +def _detect_system_dark_mode(): + if sys.platform == "win32": + try: + import winreg + registry = winreg.ConnectRegistry(None, winreg.HKEY_CURRENT_USER) + key = winreg.OpenKey(registry, + r"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize") + value, _ = winreg.QueryValueEx(key, "AppsUseLightTheme") + winreg.CloseKey(key) + return value == 0 + except (ImportError, OSError, WindowsError) as _: + return False + + elif sys.platform.startswith("linux"): + if os.getenv('GTK_THEME', '').lower().find('dark') != -1: + return True + + import subprocess + try: + result = subprocess.run( + ["gsettings", "get", "org.gnome.desktop.interface", "gtk-theme"], + capture_output=True, text=True + ) + if "dark" in result.stdout.lower(): + return True + except (subprocess.SubprocessError, OSError) as _: + pass + + try: + result = subprocess.run( + ["kreadconfig5", "--group", "General", "--key", "ColorScheme"], + capture_output=True, text=True + ) + if "dark" in result.stdout.lower(): + return True + except (subprocess.SubprocessError, OSError) as _: + return False + + # TK 8.6.9+ supports dark mode natively on macOS + return False + def _create_id_to_node(): global _id_to_node @@ -393,6 +434,8 @@ def _fix_treeview_issues(): def _init_misc_ui(): # Does misc. UI initialization, like setting the title, icon, and theme + global _dark_mode + _dark_mode = _detect_system_dark_mode() _root.title(_kconf.mainmenu_text) # iconphoto() isn't available in Python 2's Tkinter @@ -404,10 +447,69 @@ def _init_misc_ui(): # Use the 'clam' theme on *nix if it's available. It looks nicer than the # 'default' theme. - if _root.tk.call("tk", "windowingsystem") == "x11": + if _dark_mode: style = ttk.Style() - if "clam" in style.theme_names(): - style.theme_use("clam") + _root.configure(bg='#2b2b2b') + + style.theme_use('clam') + + style.configure(".", + background='#2b2b2b', + foreground='#ffffff', + fieldbackground='#3c3c3c', + bordercolor='#404040', + darkcolor='#222222', + lightcolor='#404040', + selectbackground='#5a5a5a', + selectforeground='#ffffff') + + style.configure("Treeview", + background='#3c3c3c', + foreground='#ffffff', + fieldbackground='#3c3c3c') + style.configure("Treeview.Heading", + background='#404040', + foreground='#ffffff') + style.map("Treeview.Heading", + background=[('active', '#5a5a5a')], + foreground=[('active', '#ffffff')]) + style.map('Treeview', + background=[('selected', '#5a5a5a')], + foreground=[('selected', '#ffffff')]) + + style.configure("TButton", + background='#404040', + foreground='#ffffff',) + style.map("TButton", + background=[('active', '#5a5a5a')]) + + style.configure("TEntry", + fieldbackground='#3c3c3c', + foreground='#ffffff', + insertcolor='#ffffff') + + style.configure("TLabel", + background='#2b2b2b', + foreground='#ffffff') + + style.configure("TFrame", + background='#2b2b2b') + + style.configure("TCheckbutton", + background='#2b2b2b', + foreground='#ffffff', + focuscolor='none') + style.map("TCheckbutton", + background=[('active', '#3c3c3c')], + foreground=[('active', '#ffffff')]) + + style.configure("TPanedwindow", + background='#2b2b2b') + else: + if _root.tk.call("tk", "windowingsystem") == "x11": + style = ttk.Style() + if "clam" in style.theme_names(): + style.theme_use("clam") def _create_top_widgets(): @@ -584,12 +686,22 @@ def _create_kconfig_desc(parent): frame = ttk.Frame(parent) - desc = Text(frame, height=12, wrap="none", borderwidth=0, - state="disabled") - desc.grid(column=0, row=0, sticky="nsew") + if _dark_mode: + desc = Text(frame, height=12, wrap="word", borderwidth=0, + state="disabled", + bg='#3c3c3c', + fg='#ffffff', + insertbackground='#ffffff', + selectbackground='#5a5a5a', + selectforeground='#ffffff', + relief='flat') + else: + desc = Text(frame, height=12, wrap="word", borderwidth=0, + state="disabled") # Work around not being to Ctrl-C/V text from a disabled Text widget, with a # tip found in https://stackoverflow.com/questions/3842155/is-there-a-way-to-make-the-tkinter-text-widget-read-only + desc.grid(column=0, row=0, sticky="nsew") desc.bind("<1>", lambda _: desc.focus_set()) _add_vscrollbar(frame, desc) @@ -1194,6 +1306,10 @@ def _set_val_dialog(node, parent): sym = node.item dialog = Toplevel(parent) + + if _dark_mode: + dialog.configure(bg='#2b2b2b') + dialog.title("Enter {} value".format(TYPE_TO_STR[sym.type])) dialog.resizable(False, False) dialog.transient(parent) @@ -1780,6 +1896,10 @@ def _jump_to_dialog(_=None): dialog = Toplevel(_root) + + if _dark_mode: + dialog.configure(bg='#2b2b2b') + dialog.geometry("+{}+{}".format( _root.winfo_rootx() + 50, _root.winfo_rooty() + 50)) dialog.title("Jump to symbol/choice/menu/comment") |
