# Ctrl+Z Undo Functionality Audit ## Executive Summary This audit identifies all text input fields in the ServerManager project and analyzes their undo functionality. The primary issue is that CTkEntry widgets do not have undo enabled by default, causing Ctrl+Z to fail in forms like the server edit dialog. ## Input Widgets Inventory ### 1. Server Dialog (`gui/server_dialog.py`) - **Lines 48, 53, 73, 92, 99, 107, 120**: CTkEntry widgets for server form fields - `alias_entry`: Server alias field - `ip_entry`: IP address field - `port_entry`: Port field - `user_entry`: Username field - `password_entry`: Password field (masked) - `totp_entry`: TOTP secret field - `notes_entry`: Notes field - **Issue**: None have undo enabled by default - **Status**: BROKEN - Ctrl+Z does not work ### 2. Sidebar (`gui/sidebar.py`) - **Line 30**: `search_entry` - CTkEntry for server search - **Issue**: No undo enabled - **Status**: BROKEN - Ctrl+Z does not work ### 3. TOTP Tab (`gui/tabs/totp_tab.py`) - **Line 103**: `secret_entry` - CTkEntry for TOTP secret (masked) - **Issue**: No undo enabled - **Status**: BROKEN - Ctrl+Z does not work ### 4. Files Tab (`gui/tabs/files_tab.py`) - **Line 131**: `_local_path_entry` - CTkEntry for local path input - **Line 177**: `_remote_path_entry` - CTkEntry for remote path input - **Issue**: No undo enabled - **Status**: BROKEN - Ctrl+Z does not work ### 5. Keys Tab (`gui/tabs/keys_tab.py`) - **Lines 25, 42**: CTkTextbox widgets (used as read-only displays) - **Status**: Not applicable (disabled state prevents editing) ### 6. Setup Tab (`gui/tabs/setup_tab.py`) - **Line 208**: `log` - CTkTextbox for installation logs (disabled state) - **Status**: Not applicable (disabled state prevents editing) ### 7. Terminal Widget (`gui/widgets/terminal_widget.py`) - **Line 208**: `_text` - tk.Text widget for terminal emulation - **Status**: FUNCTIONAL - Has dedicated Ctrl+Z handler that sends `\x1a` to SSH session (not traditional undo) - **Note**: This is intentional behavior for terminal functionality ## Root Cause Analysis ### Primary Issue CustomTkinter's `CTkEntry` wraps `tk.Entry` internally but does not enable undo by default. Unlike `tk.Text` which has undo enabled by default, `tk.Entry` has `undo=False` by default. ### Technical Details 1. **Default Behavior**: `tk.Entry` (and by extension `CTkEntry`) has `undo=False` by default 2. **Undo Requirement**: To enable Ctrl+Z, `undo=True` must be explicitly set on the underlying tk.Entry 3. **CustomTkinter Limitation**: CTkEntry does not expose the undo parameter in its constructor 4. **Terminal Override**: The terminal widget has a specific handler for Ctrl+Z that sends `\x1a` (EOF signal) rather than performing text undo ## Specific Fixes ### Fix 1: Server Dialog (Main Bug Report) **File**: `gui/server_dialog.py` **Lines**: 48, 53, 73, 92, 99, 107, 120 **Current Code**: ```python self.alias_entry = ctk.CTkEntry(self, placeholder_text=t("placeholder_alias")) self.ip_entry = ctk.CTkEntry(self, placeholder_text=t("placeholder_ip")) # ... other entries ``` **Fixed Code**: ```python self.alias_entry = ctk.CTkEntry(self, placeholder_text=t("placeholder_alias")) self.alias_entry.configure(state="normal", undo=True) # Enable undo on internal tk.Entry self.ip_entry = ctk.CTkEntry(self, placeholder_text=t("placeholder_ip")) self.ip_entry.configure(state="normal", undo=True) # Enable undo on internal tk.Entry # ... apply same fix to all other CTkEntry instances ``` **Alternative Fix** (Better approach): Since CTkEntry doesn't directly support undo parameter, we need to access the internal tk.Entry widget: ```python # After creating CTkEntry, access the internal tk.Entry self.alias_entry = ctk.CTkEntry(self, placeholder_text=t("placeholder_alias")) internal_tk_entry = self.alias_entry._entry # Access internal tk.Entry internal_tk_entry.config(undo=True) # Enable undo ``` ### Fix 2: Sidebar Search **File**: `gui/sidebar.py` **Line**: 30 **Current Code**: ```python self.search_entry = ctk.CTkEntry(self, placeholder_text=t("search"), textvariable=self.search_var) ``` **Fixed Code**: ```python self.search_entry = ctk.CTkEntry(self, placeholder_text=t("search"), textvariable=self.search_var) internal_tk_entry = self.search_entry._entry internal_tk_entry.config(undo=True) ``` ### Fix 3: TOTP Tab Secret Entry **File**: `gui/tabs/totp_tab.py` **Line**: 103 **Current Code**: ```python self.secret_entry = ctk.CTkEntry( entry_row, show="*", placeholder_text=t("totp_secret_placeholder"), font=ctk.CTkFont(family="Consolas", size=12) ) ``` **Fixed Code**: ```python self.secret_entry = ctk.CTkEntry( entry_row, show="*", placeholder_text=t("totp_secret_placeholder"), font=ctk.CTkFont(family="Consolas", size=12) ) internal_tk_entry = self.secret_entry._entry internal_tk_entry.config(undo=True) ``` ### Fix 4: Files Tab Path Entries **File**: `gui/tabs/files_tab.py` **Lines**: 131, 177 **Current Code**: ```python self._local_path_entry = ctk.CTkEntry(left_header, height=28) self._remote_path_entry = ctk.CTkEntry(right_header, height=28) ``` **Fixed Code**: ```python self._local_path_entry = ctk.CTkEntry(left_header, height=28) internal_tk_entry = self._local_path_entry._entry internal_tk_entry.config(undo=True) self._remote_path_entry = ctk.CTkEntry(right_header, height=28) internal_tk_entry = self._remote_path_entry._entry internal_tk_entry.config(undo=True) ``` ## Additional Considerations ### Keyboard Event Handlers The terminal widget (`gui/widgets/terminal_widget.py`) has extensive keyboard event handlers that intercept Ctrl+Z: - **Line 222**: `` bound to `_on_ctrl_z` which sends `\x1a` to SSH - **Line 228**: `` handler that processes Ctrl+key combinations by keycode - **Lines 700-719**: Physical keycode mapping for layout-independent Ctrl+key handling This is intentional behavior for terminal functionality and should remain unchanged. ### Potential Side Effects Enabling undo on password fields (lines 99 in server_dialog.py) could theoretically allow users to undo password entry, though this is generally harmless since passwords are masked. ## Recommended Action Plan 1. **Immediate**: Apply the internal tk.Entry configuration fix to all CTkEntry widgets 2. **Verification**: Test Ctrl+Z functionality in all form fields 3. **Documentation**: Add a utility function to simplify undo-enabled CTkEntry creation 4. **Future Enhancement**: Request CustomTkinter to add native undo support to CTkEntry ## Risk Assessment - **Low Risk**: The fix involves accessing internal widgets and configuring them, which is safe and commonly done - **Compatibility**: Changes are backward compatible - **Performance**: No performance impact expected - **Scope**: Limited to input field configuration ## Test Cases After implementing the fix, verify: 1. Ctrl+Z works in server edit form fields 2. Ctrl+Y works for redo (if supported) 3. Multiple undo levels work properly 4. Text deletion/replacement can be undone 5. Terminal functionality remains intact (Ctrl+Z still sends EOF to SSH)