From 875eb72c51d667a3ad10e1433bca2c69bbed84e1 Mon Sep 17 00:00:00 2001 From: Dominik Jain Date: Sun, 9 Nov 2025 01:47:31 +0100 Subject: [PATCH] Add 'Copy Dashboard URL' function to GUI window --- src/serena/agent.py | 3 +++ src/serena/gui_log_viewer.py | 20 ++++++++++++++++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/serena/agent.py b/src/serena/agent.py index 61a56de7..b8f56661 100644 --- a/src/serena/agent.py +++ b/src/serena/agent.py @@ -188,6 +188,9 @@ class SerenaAgent: process = multiprocessing.Process(target=self._open_dashboard, args=(dashboard_url,)) process.start() process.join(timeout=1) + # inform the GUI window (if any) + if self._gui_log_viewer is not None: + self._gui_log_viewer.set_dashboard_url(dashboard_url) def get_current_tasks(self) -> list[TaskExecutor.TaskInfo]: """ diff --git a/src/serena/gui_log_viewer.py b/src/serena/gui_log_viewer.py index f46d8c30..c9a43e01 100644 --- a/src/serena/gui_log_viewer.py +++ b/src/serena/gui_log_viewer.py @@ -55,6 +55,7 @@ class GuiLogViewer: self.message_queue = queue.Queue() self.running = False self.log_thread = None + self.menubar: tk.Menu | None = None self.tool_names = [] # List to store tool names for highlighting # Define colors for different log levels @@ -98,6 +99,17 @@ class GuiLogViewer: """ self.tool_names = tool_names + def set_dashboard_url(self, url: str) -> None: + def copy_url(): + self.root.clipboard_clear() + self.root.clipboard_append(url) + log.info(f"Copied dashboard URL to clipboard: {url}") + + if self.menubar is not None: + dashboard_menu = tk.Menu(self.menubar, tearoff=0) + dashboard_menu.add_command(label="Copy URL", command=copy_url) # type: ignore + self.menubar.add_cascade(label="Dashboard", menu=dashboard_menu) + def add_log(self, message): """ Add a log message to the viewer. @@ -287,11 +299,11 @@ class GuiLogViewer: # Create menu bar if self.mode == "dashboard": - menubar = tk.Menu(self.root) - server_menu = tk.Menu(menubar, tearoff=0) + self.menubar = tk.Menu(self.root) + server_menu = tk.Menu(self.menubar, tearoff=0) server_menu.add_command(label="Shutdown", command=self._shutdown_server) # type: ignore - menubar.add_cascade(label="Server", menu=server_menu) - self.root.config(menu=menubar) + self.menubar.add_cascade(label="Server", menu=server_menu) + self.root.config(menu=self.menubar) # Configure icons icon_16 = tk.PhotoImage(file=dashboard_path / "serena-icon-16.png")