diff --git a/core/session_pool.py b/core/session_pool.py index 14efbb7..14c1228 100644 --- a/core/session_pool.py +++ b/core/session_pool.py @@ -9,6 +9,15 @@ from typing import Dict, Optional, Tuple from core.ssh_client import ShellSession, SFTPSession +_CRITICAL_KEYS = ('ip', 'port', 'username', 'password', 'type', + 'access_key', 'secret_key', 'use_ssl') + + +def _server_changed(old: dict, new: dict) -> bool: + """Check if critical connection fields differ.""" + return any(old.get(k) != new.get(k) for k in _CRITICAL_KEYS) + + class SessionData: """Container for session data including the actual sessions and their metadata.""" def __init__(self, alias: str, server: dict, key_path: str): @@ -70,6 +79,11 @@ class SessionPool: self._sessions[alias] = session_data else: session_data = self._sessions[alias] + # Invalidate if server connection data changed + if _server_changed(session_data.server, server): + session_data.cleanup() + session_data.server = server + session_data.key_path = key_path # Update access time for LRU self._update_last_access(alias) @@ -108,6 +122,11 @@ class SessionPool: self._sessions[alias] = session_data else: session_data = self._sessions[alias] + # Invalidate if server connection data changed + if _server_changed(session_data.server, server): + session_data.cleanup() + session_data.server = server + session_data.key_path = key_path # Update access time for LRU self._update_last_access(alias) diff --git a/gui/app.py b/gui/app.py index 3117dca..a762fe4 100644 --- a/gui/app.py +++ b/gui/app.py @@ -299,9 +299,19 @@ class App(ctk.CTk): self.sidebar._select(new_alias) self.session_pool.rename_server(alias, new_alias) else: - info = self._tab_instances.get("info") - if info and hasattr(info, "refresh"): - info.refresh() + # Data may have changed (IP, port, password) — force reconnect + self._force_reconnect(alias) + + def _force_reconnect(self, alias: str): + """Force tabs to reconnect after server data changed.""" + # Invalidate cached SSH/SFTP sessions in pool + self.session_pool.disconnect_session(alias) + # Reset _current_alias so set_server() bypasses early return + for widget in self._tab_instances.values(): + if getattr(widget, '_current_alias', None) == alias: + widget._current_alias = None + # Re-trigger server selection (calls set_server on all tabs) + self._on_server_select(alias) def _delete_server(self, alias: str): if messagebox.askyesno(t("delete_server"), t("delete_confirm").format(alias=alias)): diff --git a/releases/ServerManager-v1.9.9-win-x64.exe b/releases/ServerManager-v1.9.9-win-x64.exe new file mode 100644 index 0000000..00c8b93 Binary files /dev/null and b/releases/ServerManager-v1.9.9-win-x64.exe differ diff --git a/version.py b/version.py index b370d8e..537ba19 100755 --- a/version.py +++ b/version.py @@ -1,6 +1,6 @@ """Version info for ServerManager.""" -__version__ = "1.9.8" +__version__ = "1.9.9" __app_name__ = "ServerManager" __author__ = "aibot777" __description__ = "Desktop GUI for managing remote servers"