diff --git a/__pycache__/common_tools.cpython-312.pyc b/__pycache__/common_tools.cpython-312.pyc index bb299c7..70ccf6b 100644 Binary files a/__pycache__/common_tools.cpython-312.pyc and b/__pycache__/common_tools.cpython-312.pyc differ diff --git a/common_tools.py b/common_tools.py index 1be0ade..e321658 100755 --- a/common_tools.py +++ b/common_tools.py @@ -119,6 +119,89 @@ class LxTools(tk.Tk): def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + @staticmethod + def center_window_cross_platform(window, width, height): + """ + Centers a window on the primary monitor in a way that works on both X11 and Wayland + + Args: + window: The tkinter window to center + width: Window width + height: Window height + """ + # Calculate the position before showing the window + + # First attempt: Try to use GDK if available (works on both X11 and Wayland) + try: + import gi + gi.require_version('Gdk', '3.0') + from gi.repository import Gdk + + display = Gdk.Display.get_default() + monitor = display.get_primary_monitor() or display.get_monitor(0) + geometry = monitor.get_geometry() + scale_factor = monitor.get_scale_factor() + + # Calculate center position on primary monitor + x = geometry.x + (geometry.width - width // scale_factor) // 2 + y = geometry.y + (geometry.height - height // scale_factor) // 2 + + # Set window geometry + window.geometry(f"{width}x{height}+{x}+{y}") + return + except (ImportError, AttributeError): + pass + + # Second attempt: Try xrandr for X11 + try: + import subprocess + output = subprocess.check_output(["xrandr", "--query"], universal_newlines=True) + + # Parse the output to find the primary monitor + primary_info = None + for line in output.splitlines(): + if "primary" in line: + parts = line.split() + for part in parts: + if "x" in part and "+" in part: + primary_info = part + break + break + + if primary_info: + # Parse the geometry: WIDTHxHEIGHT+X+Y + geometry = primary_info.split("+") + dimensions = geometry[0].split("x") + primary_width = int(dimensions[0]) + primary_height = int(dimensions[1]) + primary_x = int(geometry[1]) + primary_y = int(geometry[2]) + + # Calculate center position on primary monitor + x = primary_x + (primary_width - width) // 2 + y = primary_y + (primary_height - height) // 2 + + # Set window geometry + window.geometry(f"{width}x{height}+{x}+{y}") + return + except (subprocess.SubprocessError, ImportError, IndexError, ValueError): + pass + + # Final fallback: Use standard Tkinter method + screen_width = window.winfo_screenwidth() + screen_height = window.winfo_screenheight() + + # Try to make an educated guess for multi-monitor setups + # If screen width is much larger than height, assume multiple monitors side by side + if screen_width > screen_height * 1.8: # Heuristic for detecting multiple monitors + # Assume primary monitor is on the left half + screen_width = screen_width // 2 + + x = (screen_width - width) // 2 + y = (screen_height - height) // 2 + window.geometry(f"{width}x{height}+{x}+{y}") + + @staticmethod def get_file_name(path: Path, i: int = 5) -> List[str]: """ diff --git a/new_window_for_add_trace_test.py b/new_window_for_add_trace_test.py new file mode 100644 index 0000000..fd87687 --- /dev/null +++ b/new_window_for_add_trace_test.py @@ -0,0 +1,45 @@ +#!/usr/bin/python3 + +import tkinter as tk + +class MainWindow(tk.Tk): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + self.title("Trace-Test-Window") + self.geometry("400x300") + self.text_label = tk.StringVar() + self.text_forground = tk.StringVar(value="red") + self.text_label.set("This is the main window") + self.label = tk.Label(self, textvariable=self.text_label) + self.label.grid(row=0, column=0, padx=10, pady=10) + self.label.grid_remove() + + self.button_text = tk.StringVar() + self.button_text.set("Drück für andere Text anzeige") + self.button = tk.Button(self, textvariable=self.button_text, command=self.toggle_lable) + self.button.grid(row=1, column=0, padx=10, pady=10) + + self.text_label.trace_add("write", self.update_label) + self.text_forground.trace_add("write", self.update_label) + + def update_label(self, *args): + self.label.configure(foreground=self.text_forground.get()) + + if self.text_label.get(): + self.label.grid() + else: + self.label.grid_remove() + + def toggle_lable(self): + + if 'main window' in self.text_label.get(): + self.text_label.set("gewechseltes label") + self.button_text.set("Drück für main window") + else: + self.text_label.set("This is the main window") + self.button_text.set("Drück für andere Text anzeige") + +if __name__ == "__main__": + window = MainWindow() + window.mainloop() diff --git a/wirepy.py b/wirepy.py index fe4549c..0ecc69e 100755 --- a/wirepy.py +++ b/wirepy.py @@ -29,17 +29,22 @@ class Wirepy(tk.Tk): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + # Hide the window initially + self.withdraw() + self.my_tool_tip = None self.x_width = AppConfig.UI_CONFIG["window_size"][0] self.y_height = AppConfig.UI_CONFIG["window_size"][1] - self.monitor_center_x = int(self.winfo_screenwidth() / 2 - (self.x_width / 2)) - self.monitor_center_y = int(self.winfo_screenheight() / 2 - (self.y_height / 2)) - self.resizable(AppConfig.UI_CONFIG["resizable_window"][0], AppConfig.UI_CONFIG["resizable_window"][1]) + + # Set the window size + self.geometry(f"{self.x_width}x{self.y_height}") + self.resizable(AppConfig.UI_CONFIG["resizable_window"][0], + AppConfig.UI_CONFIG["resizable_window"][1]) self.title(AppConfig.UI_CONFIG["window_title"]) - self.geometry(f"{self.x_width}x{self.y_height}+{self.monitor_center_x}+{self.monitor_center_y}") + self.columnconfigure(0, weight=1) self.rowconfigure(0, weight=1) - self.tk.call("source", f"{AppConfig.SYSTEM_PATHS["tcl_path"]}/water.tcl") + self.tk.call("source", f"{AppConfig.SYSTEM_PATHS['tcl_path']}/water.tcl") ConfigManager.init(AppConfig.SETTINGS_FILE) theme = ConfigManager.get("theme") ThemeManager.change_theme(self, theme) @@ -50,7 +55,14 @@ class Wirepy(tk.Tk): # Set it as the window icon self.iconphoto(True, self.wg_icon) + # Add the widgets FrameWidgets(self).grid() + + # Center the window on the primary monitor + LxTools.center_window_cross_platform(self, self.x_width, self.y_height) + + # Now show the window after it has been positioned + self.after(10, self.deiconify) class FrameWidgets(ttk.Frame): @@ -362,18 +374,7 @@ class FrameWidgets(ttk.Frame): AppConfig.IMAGE_PATHS["icon_error"], AppConfig.IMAGE_PATHS["icon_msg"] ) - ) - - def tooltip(self, tip) -> None: - """ - Aktualisiert die Tooltip-Einstellung im ConfigManager - Args: - tip (bool): True zum Deaktivieren, False zum Aktivieren von Tooltips - """ - # Beachten Sie die umgekehrte Logik: tip=True bedeutet Tooltips deaktivieren - ConfigManager.set("tooltip", not tip) - # Aktualisieren Sie die lokale Variable für sofortige Wirkung - self.tooltip_state = not tip + ) @staticmethod def about() -> None: @@ -389,107 +390,6 @@ class FrameWidgets(ttk.Frame): "Use without warranty!\n") LxTools.msg_window(AppConfig.IMAGE_PATHS["icon_vpn"], AppConfig.IMAGE_PATHS["icon_vpn"], _("Info"), msg_t, _("Go to Wire-Py git"), link_btn) - - def update_ui_for_update_status(self, res): - """Update UI elements based on update check result""" - print(f"Updating UI for result: {res}") # Debug output - - # First, clean up any existing UI elements - if hasattr(self, 'update_btn') and self.update_btn.winfo_exists(): - self.update_btn.grid_forget() - - # Reset all variables to ensure fresh state - self.update_label.set("") - self.update_tooltip.set("") - self.update_foreground.set("black") - - if res == "False": - self.set_update.set(value=1) - self.update_label.set(_("Update search off")) - self.update_tooltip.set(_("Updates you have disabled")) - self.update_foreground.set("red") - - # Display the label - self.updates_lb.configure( - textvariable=self.update_label, - foreground=self.update_foreground.get() - ) - self.updates_lb.grid(column=4, columnspan=3, row=0, padx=10) - Tooltip(self.updates_lb, self.update_tooltip.get(), self.tooltip_state) - - elif res == "No Internet Connection!": - self.update_label.set(_("No Server Connection!")) - self.update_foreground.set("red") - - # Display the label - self.updates_lb.configure( - textvariable=self.update_label, - foreground=self.update_foreground.get() - ) - self.updates_lb.grid(column=4, columnspan=3, row=0, padx=10) - - elif res == "No Updates": - self.update_label.set(_("No Updates")) - self.update_tooltip.set(_("Congratulations! Wire-Py is up to date")) - self.update_foreground.set("black") - - # Display the label - self.updates_lb.configure( - textvariable=self.update_label, - foreground=self.update_foreground.get() - ) - self.updates_lb.grid(column=4, columnspan=3, row=0, padx=10) - Tooltip(self.updates_lb, self.update_tooltip.get(), self.tooltip_state) - - else: - # We have an update available - self.set_update.set(value=0) - update_text = f"Update {res} {_('available!')}" - - # Hide the label if it's visible - if self.updates_lb.winfo_ismapped(): - self.updates_lb.grid_forget() - - # Create or update the update button - if not hasattr(self, 'update_btn') or not self.update_btn.winfo_exists(): - # Create the update button if it doesn't exist yet - self.update_btn = ttk.Menubutton(self.menu_frame, text=update_text) - self.update_btn.grid(column=4, columnspan=3, row=0, padx=0) - Tooltip(self.update_btn, _("Click to download new version"), self.tooltip_state) - - self.download = tk.Menu(self, relief="flat") - self.update_btn.configure(menu=self.download, style="Toolbutton") - self.download.add_command( - label=_("Download"), - command=lambda: GiteaUpdate.download( - f"{AppConfig.DOWNLOAD_URL}/{res}.zip", - res, - AppConfig.IMAGE_PATHS["icon_info"], - AppConfig.IMAGE_PATHS["icon_vpn"], - AppConfig.IMAGE_PATHS["icon_error"], - AppConfig.IMAGE_PATHS["icon_msg"] - ) - ) - else: - # Update the existing update button - self.update_btn.configure(text=update_text) - # Make sure it's visible - self.update_btn.grid(column=4, columnspan=3, row=0, padx=0) - - # Update the download command - if hasattr(self, 'download'): - self.download.entryconfigure( - 0, # First entry in the menu - command=lambda: GiteaUpdate.download( - f"{AppConfig.DOWNLOAD_URL}/{res}.zip", - res, - AppConfig.IMAGE_PATHS["icon_info"], - AppConfig.IMAGE_PATHS["icon_vpn"], - AppConfig.IMAGE_PATHS["icon_error"], - AppConfig.IMAGE_PATHS["icon_msg"] - ) - ) - def update_setting(self, update_res) -> None: """write off or on in file Args: @@ -532,15 +432,12 @@ class FrameWidgets(ttk.Frame): # If tooltips are disabled, the menu option should be to enable them self.tooltip_label.set(_("Enable Tooltips")) - def tooltips_toggle(self): """Toggles tooltips on/off and updates the menu label""" # Toggle the boolean state new_bool_state = not self.tooltip_state.get() - # Save the converted value in the configuration ConfigManager.set("tooltips", str(new_bool_state)) - print(f"Tooltips are now: {new_bool_state} in ConfigManager") # Update the tooltip_state variable for immediate effect self.tooltip_state.set(new_bool_state) @@ -551,7 +448,6 @@ class FrameWidgets(ttk.Frame): # This assumes it's the third item (index 2) in your menu self.settings.entryconfigure(1, label=self.tooltip_label.get()) - def update_theme_label(self) -> str: """Update the theme label based on current theme""" current_theme = ConfigManager.get("theme")