1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use rmux_proto::RmuxError;
use super::super::attach_support::ActiveAttachIdentity;
use super::super::RequestHandler;
use super::menu::PopupMenuAction;
use super::state::ClientOverlayState;
use crate::renderer::OverlayRect;
impl RequestHandler {
pub(super) async fn apply_popup_menu_action(
&self,
attach_pid: u32,
identity: Option<ActiveAttachIdentity>,
action: PopupMenuAction,
) -> Result<(), RmuxError> {
match action {
PopupMenuAction::Close => {
self.clear_interactive_overlay_for_optional_identity(attach_pid, identity, true)
.await?;
}
PopupMenuAction::Paste => {
let bytes = {
let state = self.state.lock().await;
state
.buffers
.stack_head()
.and_then(|name| state.buffers.get(name))
.map(ToOwned::to_owned)
.unwrap_or_default()
};
let popup_write = {
let mut active_attach = self.active_attach.lock().await;
let active = active_attach
.by_pid
.get_mut(&attach_pid)
.filter(|active| {
identity.is_none_or(|identity| identity.matches_active(active))
})
.ok_or_else(|| {
RmuxError::Server("attached client disappeared".to_owned())
})?;
if let Some(ClientOverlayState::Popup(popup)) = active.overlay.as_mut() {
popup.nested_menu = None;
Some(
popup
.job
.as_ref()
.and_then(|job| job.enqueue_write(&bytes).ok()),
)
} else {
None
}
};
if let Some(popup_write) = popup_write {
if let Some(receipt) = popup_write {
let _ = receipt.wait().await;
}
self.refresh_interactive_overlay_for_optional_identity(attach_pid, identity)
.await?;
}
}
PopupMenuAction::FillSpace | PopupMenuAction::Centre => {
let popup_resize = {
let mut active_attach = self.active_attach.lock().await;
let active = active_attach
.by_pid
.get_mut(&attach_pid)
.filter(|active| {
identity.is_none_or(|identity| identity.matches_active(active))
})
.ok_or_else(|| {
RmuxError::Server("attached client disappeared".to_owned())
})?;
let client_size = active.client_size;
if let Some(ClientOverlayState::Popup(popup)) = active.overlay.as_mut() {
popup.nested_menu = None;
match action {
PopupMenuAction::FillSpace => {
popup.rect = OverlayRect {
x: 0,
y: 0,
width: client_size.cols.max(1),
height: client_size.rows.max(1),
};
popup.preferred_width = popup.rect.width;
popup.preferred_height = popup.rect.height;
}
PopupMenuAction::Centre => {
popup.rect.x =
client_size.cols.saturating_sub(popup.rect.width) / 2;
popup.rect.y =
client_size.rows.saturating_sub(popup.rect.height) / 2;
}
_ => {}
}
let content_size = popup.content_size();
popup
.surface
.lock()
.expect("popup surface")
.resize(content_size);
Some(
popup
.job
.as_ref()
.and_then(|job| job.enqueue_resize(content_size).ok()),
)
} else {
None
}
};
if let Some(popup_resize) = popup_resize {
if let Some(receipt) = popup_resize {
let _ = receipt.wait().await;
}
self.refresh_interactive_overlay_for_optional_identity(attach_pid, identity)
.await?;
}
}
PopupMenuAction::HorizontalPane | PopupMenuAction::VerticalPane => {
self.clear_interactive_overlay_for_optional_identity(attach_pid, identity, true)
.await?;
}
}
Ok(())
}
}