Automatically copy selection to clipboard is no longer working correctly with tmux #18984

Open
opened 2026-01-31 06:30:22 +00:00 by claunia · 2 comments
Owner

Originally created by @andyneff on GitHub (Nov 30, 2022).

Originally assigned to: @zadjii-msft on GitHub.

Windows Terminal version

1.15.2875.0

Windows build number

10.0.22621.819

Other Software

tmux

  • 3.3a in Fedora Remix WSL
  • 1.8 when SSHed into CentOS 7
  • 3.2a on Ubuntu 22.04 WSL

Steps to reproduce

  1. Enable "Automatically copy selection to clipboard"
    image
    "copyFormatting": "all",
    "copyOnSelect": true,
  1. Start tmux
  2. I use the mouse to Scroll. If you need help it's: Ctrl + b then : and type set-window-option -g mouse on and press enter (Unless you are on tmux 1.8 and it's a lot more complicated)
  3. Scroll up in tmux buffer
  4. Press Shift + Left Click and drag on the text you want to Select. Holding Shift is important because this is doing a normal terminal "select" not a fancy Tmux select (which copies to tmuxes internal clipboard, not the real Windows one)
    image
  5. Scroll back down to the bottom so you can get out of scrolling mode
    image
  6. Paste in terminal (Shift right click)
  7. Now paste in terminal or any other application, and you will have the wrong text pasted

In this case it will paste 85, not the 10 I actually selected

Expected Behavior

This used to work, it was beautiful, and everything was bearable. The text I selected before scrolling back down was in my clipboard, and it pasted correctly. Now the "selection" was in same physical space but no longer over the text I initially selected, but this never mattered and not something I'd expect to change behavior

I expect it to paste 10 like it was until very recently

Actual Behavior

It pasted 85

Terminal is deciding to copy again at paste time.

Step 4 is important. Before step 7, if you paste outside of terminal, you will see that after step 5, the text in the Windows Clipboard is indeed correct, even after step 6. But as soon as I go to paste in Terminal, it "re copies" where the select text is and breaks everything.

It's also important

Originally created by @andyneff on GitHub (Nov 30, 2022). Originally assigned to: @zadjii-msft on GitHub. ### Windows Terminal version 1.15.2875.0 ### Windows build number 10.0.22621.819 ### Other Software tmux - 3.3a in Fedora Remix WSL - 1.8 when SSHed into CentOS 7 - 3.2a on Ubuntu 22.04 WSL ### Steps to reproduce 1. Enable "Automatically copy selection to clipboard" ![image](https://user-images.githubusercontent.com/7596961/204680678-8050e9c3-989e-491d-adab-fe3ffbe22160.png) ``` "copyFormatting": "all", "copyOnSelect": true, ``` 1. Start `tmux` 1. I use the mouse to Scroll. If you need help it's: Ctrl + b then `:` and type `set-window-option -g mouse on` and press enter (Unless you are on tmux 1.8 and it's a lot more complicated) 1. Scroll up in tmux buffer 1. Press Shift + Left Click and drag on the text you want to Select. Holding Shift is important because this is doing a normal terminal "select" not a fancy Tmux select (which copies to tmuxes internal clipboard, not the real Windows one) ![image](https://user-images.githubusercontent.com/7596961/204679903-5ec1f197-6900-42a9-96ce-5e0d8c860973.png) 1. Scroll back down to the bottom so you can get out of scrolling mode ![image](https://user-images.githubusercontent.com/7596961/204679941-f512ff35-b52a-41d8-b2ac-d636a7113c9b.png) 1. Paste in terminal (Shift right click) 1. Now paste in terminal or any other application, and you will have the wrong text pasted In this case it will paste 85, not the 10 I actually selected ### Expected Behavior This used to work, it was beautiful, and everything was bearable. The text I selected before scrolling back down was in my clipboard, and it pasted correctly. Now the "selection" was in same physical space but no longer over the text I initially selected, but this never mattered and not something I'd expect to change behavior I expect it to paste `10` like it was until very recently ### Actual Behavior It pasted `85` Terminal is deciding to copy _again_ at paste time. Step 4 is important. Before step 7, if you paste outside of terminal, you will see that after step 5, the text in the Windows Clipboard is indeed correct, even after step 6. But as soon as I go to paste in Terminal, it "re copies" where the select text is and breaks everything. It's also important
claunia added the Issue-BugIn-PRProduct-TerminalPriority-1Area-TerminalControl labels 2026-01-31 06:30:23 +00:00
Author
Owner

@zadjii-msft commented on GitHub (Nov 30, 2022):

Huh, this seems coincidentally timed with #14462 which was also literally just filed.~ I wonder if they're the same regression. I wouldn't be surprised. Weird to me that the selection in your screenshot seems anchored to the viewport.....~

Oh I wonder if I know what's happening. We're not dismissing the selection on the "scrolling" happening in the alt buffer. The selection remains anchored to where it was, but the content changes, and {something} is triggering us to re-copy the contents.

I bet this is different after all.

@zadjii-msft commented on GitHub (Nov 30, 2022): Huh, this seems coincidentally timed with #14462 which was also literally just filed.~ I wonder if they're the same regression. I wouldn't be surprised. Weird to me that the selection in your screenshot seems anchored to the viewport.....~ Oh I wonder if I know what's happening. We're not dismissing the selection on the "scrolling" happening in the alt buffer. The selection remains anchored to where it was, but the content changes, and {something} is triggering us to re-copy the contents. I bet this is different after all.
Author
Owner

@zadjii-msft commented on GitHub (Jan 5, 2023):

This is the suspicious code IMO

2d66dc44f5/src/cascadia/TerminalControl/ControlInteractivity.cpp (L256-L267)

This is the PointerPressed handler. In this case, at step 6 it seems to me like

  • we've already copied the text once, at step 4, in our PointerReleased handler.
  • _selectionNeedsToBeCopied=false at this point.
  • We get the mousedown and try to copy the selection.
    • Most of the time, this no-ops!
    • In the normal buffer, this really doesn't matter. In the normal buffer, the text contents (rarely) shift underneath the selection itself. So re-copying the selected text would just copy the same thing.
    • In this case however, the text did change from the time of the selection. So trying to copy again will copy the new text (in this case, 85).
  • Then we request a paste from the clipboard. Here things get a little tricky - I'm guessing the async nature of our copy handler means that the copy actually gets queued for after the pointerpress event, so we end up pasting the original contents.

Methinks that we can gate the copy on _selectionNeedsToBeCopied || !_core->CopyOnSelect(). Then we'll only do the first copy when we're not in copyOnSelect, or when we're in copyOnSelect, but we haven't yet copied.

@zadjii-msft commented on GitHub (Jan 5, 2023): This is the suspicious code IMO https://github.com/microsoft/terminal/blob/2d66dc44f5abef975bed86af12cb5facb6729a1a/src/cascadia/TerminalControl/ControlInteractivity.cpp#L256-L267 This is the `PointerPressed` handler. In this case, at step 6 it seems to me like * we've already copied the text once, at step 4, in our PointerReleased handler. * `_selectionNeedsToBeCopied=false` at this point. * We get the mousedown and _try to copy the selection_. * Most of the time, this no-ops! * In the normal buffer, this really doesn't matter. In the normal buffer, the text contents (rarely) shift underneath the selection itself. So re-copying the selected text would just copy the same thing. * In this case however, the text _did_ change from the time of the selection. So trying to copy again will copy the new text (in this case, `85`). * Then we request a paste from the clipboard. Here things get a little tricky - I'm guessing the async nature of our copy handler means that the copy actually gets queued for after the pointerpress event, so we end up pasting the original contents. Methinks that we can gate the copy on `_selectionNeedsToBeCopied || !_core->CopyOnSelect()`. Then we'll only do the first copy when we're _not in `copyOnSelect`_, or when we're in `copyOnSelect`, but we haven't yet copied.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#18984