par_term/session/
capture.rs1use super::{SessionPaneNode, SessionState, SessionTab, SessionWindow};
4use crate::app::window_state::WindowState;
5use crate::pane::PaneNode;
6use par_term_config::snapshot_types::TabSnapshot;
7use std::collections::HashMap;
8use winit::window::WindowId;
9
10pub fn capture_session(windows: &HashMap<WindowId, WindowState>) -> SessionState {
12 let mut session_windows = Vec::new();
13
14 for window_state in windows.values() {
15 let Some(window) = &window_state.window else {
16 continue;
17 };
18
19 let scale = window.scale_factor();
25 let window_pos = window.outer_position().unwrap_or_default();
26 let inner_size = window.inner_size();
27
28 let visible_tabs = window_state.tab_manager.visible_tabs();
31 let tabs: Vec<SessionTab> = visible_tabs
32 .iter()
33 .map(|tab| {
34 let pane_layout = tab.pane_manager.as_ref().and_then(|pm| pm.root()).and_then(
42 |root| match root {
43 PaneNode::Leaf(_) => None,
44 PaneNode::Split { .. } => Some(capture_pane_node(root)),
45 },
46 );
47
48 SessionTab {
49 snapshot: TabSnapshot {
50 cwd: tab.get_cwd(),
51 title: tab.title.clone(),
52 custom_color: tab.custom_color,
53 user_title: if tab.user_named {
54 Some(tab.title.clone())
55 } else {
56 None
57 },
58 custom_icon: tab.custom_icon.clone(),
59 },
60 pane_layout,
61 }
62 })
63 .collect();
64
65 let active_tab_id = window_state.tab_manager.active_tab_id();
67 let active_tab_index = active_tab_id
68 .and_then(|id| visible_tabs.iter().position(|t| t.id == id))
69 .unwrap_or(0);
70
71 session_windows.push(SessionWindow {
72 position: (
73 (window_pos.x as f64 / scale) as i32,
74 (window_pos.y as f64 / scale) as i32,
75 ),
76 size: (
77 (inner_size.width as f64 / scale) as u32,
78 (inner_size.height as f64 / scale) as u32,
79 ),
80 tabs,
81 active_tab_index,
82 tmux_session_name: window_state.tmux_state.tmux_session_name.clone(),
83 });
84 }
85
86 SessionState {
87 saved_at: chrono::Utc::now().to_rfc3339(),
88 windows: session_windows,
89 }
90}
91
92pub fn capture_pane_node(node: &PaneNode) -> SessionPaneNode {
94 match node {
95 PaneNode::Leaf(pane) => SessionPaneNode::Leaf {
96 cwd: pane.get_cwd(),
97 },
98 PaneNode::Split {
99 direction,
100 ratio,
101 first,
102 second,
103 } => SessionPaneNode::Split {
104 direction: *direction,
105 ratio: *ratio,
106 first: Box::new(capture_pane_node(first)),
107 second: Box::new(capture_pane_node(second)),
108 },
109 }
110}