Skip to content

Commit 84ef4c6

Browse files
CahbOleksandr Mazur
authored andcommitted
fix: clipboard content lost on Linux after copy
ClipboardContext was created locally and dropped immediately, causing the app to lose X11/Wayland selection ownership before any paste. Move the context into RootComponent as a persistent field for the app's lifetime. Route RecordsComponent's direct clipboard call through Action::CopyToClipboard so all copy paths go via one place. Signed-off-by: Oleksandr Mazur <cahbua@gmail.com>
1 parent 38b7c6c commit 84ef4c6

2 files changed

Lines changed: 9 additions & 9 deletions

File tree

crates/tui/src/component/records_component.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! Component showing in real time incoming kafka records.
22
33
use app::{configuration::TimestampFormat, search::ValidSearchQuery};
4-
use copypasta::{ClipboardContext, ClipboardProvider};
54
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
65
use lib::ExportedKafkaRecord;
76
use ratatui::{
@@ -235,13 +234,13 @@ impl Component for RecordsComponent {
235234
KeyCode::Char('c') => {
236235
if let Some(s) = self.state.selected() {
237236
let record = self.records.get(s).unwrap();
238-
let mut ctx = ClipboardContext::new().unwrap();
239237
let exported_record: ExportedKafkaRecord = record.into();
240-
self.action_tx.as_ref().unwrap().send(Action::Notification(
241-
Notification::new(Level::Info, "Copied to clipboard".to_string()),
242-
))?;
243-
ctx.set_contents(serde_json::to_string_pretty(&exported_record)?)
244-
.unwrap();
238+
self.action_tx
239+
.as_ref()
240+
.unwrap()
241+
.send(Action::CopyToClipboard(
242+
serde_json::to_string_pretty(&exported_record)?,
243+
))?;
245244
}
246245
}
247246
KeyCode::Char('f') => self.follow(!self.follow)?,

crates/tui/src/component/root_component.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ pub(crate) struct RootComponent {
3636
focus_history: Vec<ComponentName>,
3737
focus_order: Vec<ComponentName>,
3838
action_tx: Option<UnboundedSender<Action>>,
39+
clipboard: ClipboardContext,
3940
}
4041

4142
impl RootComponent {
@@ -93,6 +94,7 @@ impl RootComponent {
9394
focus_history: vec![],
9495
state,
9596
action_tx: None,
97+
clipboard: ClipboardContext::new().expect("Failed to initialize clipboard"),
9698
}
9799
}
98100

@@ -349,15 +351,14 @@ impl Component for RootComponent {
349351
self.notify_footer()?;
350352
}
351353
Action::CopyToClipboard(ref content) => {
352-
let mut ctx = ClipboardContext::new().unwrap();
353354
self.action_tx
354355
.as_ref()
355356
.unwrap()
356357
.send(Action::Notification(Notification::new(
357358
Level::Info,
358359
"Copied to clipboard".to_string(),
359360
)))?;
360-
ctx.set_contents(content.to_string()).unwrap();
361+
self.clipboard.set_contents(content.to_string()).unwrap();
361362
}
362363
_ => (),
363364
}

0 commit comments

Comments
 (0)