Skip to content

fix(tui): prevent clipboard copy from blocking async event loop on Linux#123

Merged
echobt merged 1 commit intomainfrom
fix/clipboard-blocking-login-screen
Feb 5, 2026
Merged

fix(tui): prevent clipboard copy from blocking async event loop on Linux#123
echobt merged 1 commit intomainfrom
fix/clipboard-blocking-login-screen

Conversation

@echobt
Copy link
Contributor

@echobt echobt commented Feb 5, 2026

Problem

Pressing the 'c' key on the Welcome screen (LoginScreen) while waiting for browser authentication caused the TUI to freeze/block completely, making the application unresponsive.

Root Cause

The safe_clipboard_copy() function in cortex-tui/src/runner/terminal.rs uses arboard's blocking .wait() call on Linux to ensure the clipboard manager receives the data. However, this call can hang indefinitely when no clipboard manager is available (e.g., SSH sessions without X11/Wayland forwarding).

Solution

Spawn the blocking clipboard operation in a separate thread with a 2-second timeout. If the operation times out or fails, return false gracefully with a warning log message.

This ensures:

  • ✅ Clipboard copy works correctly on systems with clipboard support
  • ✅ Clipboard copy fails gracefully (returns false) on systems without clipboard support, without blocking the UI
  • ✅ The async event loop remains responsive
  • ✅ User feedback is preserved (Copied! notification only shows on success)

Testing

  • Tested compilation with cargo check -p cortex-tui
  • Verified no clippy warnings in the modified file

The safe_clipboard_copy() function was using arboard's blocking .wait()
call on Linux which could hang indefinitely when no clipboard manager
is available (e.g., SSH sessions without X11/Wayland forwarding). This
caused the TUI to freeze when pressing 'c' on the login screen.

Fix: Spawn the blocking clipboard operation in a separate thread with a
2-second timeout. If the operation times out or fails, return false
gracefully with a warning log message.

This ensures:
- Clipboard copy works correctly on systems with clipboard support
- Clipboard copy fails gracefully (returns false) on systems without
  clipboard support, without blocking the UI
- The async event loop remains responsive
@greptile-apps
Copy link

greptile-apps bot commented Feb 5, 2026

Greptile Overview

Greptile Summary

Fixed a critical blocking issue on Linux where pressing 'c' during the login screen would freeze the TUI indefinitely when no clipboard manager was available. The solution spawns clipboard operations in a separate thread with a 2-second timeout, ensuring the async event loop remains responsive while preserving correct clipboard behavior on systems with clipboard support.

Confidence Score: 5/5

  • This PR is safe to merge with no identified issues
  • The implementation correctly addresses the blocking issue using standard Rust concurrency primitives (mpsc channel with timeout). The code is well-structured, properly handles all error cases, includes comprehensive documentation, and maintains backward compatibility for Windows and other platforms
  • No files require special attention

Important Files Changed

Filename Overview
src/cortex-tui/src/runner/terminal.rs Refactored Linux clipboard copy to use threaded timeout, preventing UI freezes when clipboard manager is unavailable

Sequence Diagram

sequenceDiagram
    participant User
    participant LoginScreen
    participant safe_clipboard_copy
    participant Thread
    participant Clipboard
    participant ClipboardManager

    User->>LoginScreen: Press 'c' key
    LoginScreen->>safe_clipboard_copy: safe_clipboard_copy(url)
    
    alt Linux
        safe_clipboard_copy->>Thread: spawn thread
        safe_clipboard_copy->>safe_clipboard_copy: create mpsc channel
        
        Thread->>Clipboard: Clipboard::new()
        alt Clipboard available
            Clipboard-->>Thread: Ok(clipboard)
            Thread->>ClipboardManager: clipboard.set().wait().text()
            alt Manager receives data
                ClipboardManager-->>Thread: Ok()
                Thread->>safe_clipboard_copy: send(true)
            else Manager error
                ClipboardManager-->>Thread: Err(e)
                Thread->>Thread: warn log
                Thread->>safe_clipboard_copy: send(false)
            end
        else Clipboard unavailable
            Clipboard-->>Thread: Err(e)
            Thread->>Thread: debug log
            Thread->>safe_clipboard_copy: send(false)
        end
        
        safe_clipboard_copy->>safe_clipboard_copy: recv_timeout(2s)
        alt Received within timeout
            safe_clipboard_copy-->>LoginScreen: result (true/false)
        else Timeout
            safe_clipboard_copy->>safe_clipboard_copy: warn log
            safe_clipboard_copy-->>LoginScreen: false
        else Disconnected
            safe_clipboard_copy->>safe_clipboard_copy: warn log
            safe_clipboard_copy-->>LoginScreen: false
        end
    else Windows/Other
        safe_clipboard_copy->>Clipboard: Clipboard::new()
        Clipboard-->>safe_clipboard_copy: Ok/Err
        safe_clipboard_copy->>Clipboard: set_text()
        Clipboard-->>safe_clipboard_copy: Ok/Err
        safe_clipboard_copy-->>LoginScreen: result
    end
    
    alt Success
        LoginScreen->>LoginScreen: Show "Copied!" notification
    else Failure
        LoginScreen->>LoginScreen: No notification
    end
Loading

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 file reviewed, no comments

Edit Code Review Agent Settings | Greptile

@echobt echobt merged commit 636985c into main Feb 5, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant