Files
server-manager/plans/ctrl-z-undo-audit.md
chrome-storm-c442 7b0e7dd6ac fix: editable alias in server dialog + Ctrl+Z undo for all input fields
- Alias field no longer disabled when editing server profile
- Duplicate alias check on rename, session pool migration
- Enable undo (Ctrl+Z) on all CTkEntry widgets across the project

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 05:17:21 -05:00

6.9 KiB

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:

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:

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:

# 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

File: gui/sidebar.py Line: 30 Current Code:

self.search_entry = ctk.CTkEntry(self, placeholder_text=t("search"), textvariable=self.search_var)

Fixed Code:

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:

self.secret_entry = ctk.CTkEntry(
    entry_row, show="*",
    placeholder_text=t("totp_secret_placeholder"),
    font=ctk.CTkFont(family="Consolas", size=12)
)

Fixed Code:

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:

self._local_path_entry = ctk.CTkEntry(left_header, height=28)
self._remote_path_entry = ctk.CTkEntry(right_header, height=28)

Fixed Code:

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: <Control-z> bound to _on_ctrl_z which sends \x1a to SSH
  • Line 228: <Control-Key> 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.

  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)