use winit::event_loop::ActiveEventLoop;
use winit::window::WindowId;
use crate::arrangements::ArrangementId;
use super::WindowManager;
impl WindowManager {
pub fn save_arrangement(&mut self, name: String, event_loop: &ActiveEventLoop) {
if let Some(existing) = self.arrangement_manager.find_by_name(&name) {
let existing_id = existing.id;
self.arrangement_manager.remove(&existing_id);
log::info!("Overwriting existing arrangement '{}'", name);
}
let arrangement = crate::arrangements::capture::capture_arrangement(
name.clone(),
&self.windows,
event_loop,
);
log::info!(
"Saved arrangement '{}' with {} windows",
name,
arrangement.windows.len()
);
self.arrangement_manager.add(arrangement);
if let Err(e) = crate::arrangements::storage::save_arrangements(&self.arrangement_manager) {
log::error!("Failed to save arrangements: {}", e);
}
self.sync_arrangements_to_settings();
}
pub fn replace_arrangement(&mut self, id: ArrangementId, event_loop: &ActiveEventLoop) {
let name = match self.arrangement_manager.get(&id) {
Some(a) => a.name.clone(),
None => {
log::error!("replace_arrangement: arrangement not found: {}", id);
return;
}
};
let original_order = self
.arrangement_manager
.get(&id)
.map(|a| a.order)
.unwrap_or(0);
let mut new_arrangement = crate::arrangements::capture::capture_arrangement(
name.clone(),
&self.windows,
event_loop,
);
new_arrangement.id = id;
new_arrangement.order = original_order;
log::info!(
"Replaced arrangement '{}' with current layout ({} windows)",
name,
new_arrangement.windows.len()
);
self.arrangement_manager.update(new_arrangement);
if let Err(e) = crate::arrangements::storage::save_arrangements(&self.arrangement_manager) {
log::error!("Failed to save arrangements after replace: {}", e);
}
self.sync_arrangements_to_settings();
}
pub fn restore_arrangement(&mut self, id: ArrangementId, event_loop: &ActiveEventLoop) {
let arrangement = match self.arrangement_manager.get(&id) {
Some(a) => a.clone(),
None => {
log::error!("Arrangement not found: {}", id);
return;
}
};
log::info!(
"Restoring arrangement '{}' ({} windows)",
arrangement.name,
arrangement.windows.len()
);
let window_ids: Vec<WindowId> = self.windows.keys().copied().collect();
for window_id in window_ids {
if let Some(window_state) = self.windows.remove(&window_id) {
drop(window_state);
}
}
let available_monitors: Vec<_> = event_loop.available_monitors().collect();
let monitor_mapping = crate::arrangements::restore::build_monitor_mapping(
&arrangement.monitor_layout,
&available_monitors,
);
for (i, window_snapshot) in arrangement.windows.iter().enumerate() {
let Some((x, y, w, h)) = crate::arrangements::restore::compute_restore_position(
window_snapshot,
&monitor_mapping,
&available_monitors,
) else {
log::warn!("Could not compute position for window {} in arrangement", i);
continue;
};
let tab_cwds: Vec<Option<String>> = if window_snapshot.tmux_session_name.is_some() {
vec![None]
} else {
crate::arrangements::restore::tab_cwds(&arrangement, i)
};
let created_window_id = self.create_window_with_overrides(
event_loop,
(x, y),
(w, h),
&tab_cwds,
window_snapshot.active_tab_index,
);
if let Some(window_id) = created_window_id
&& let Some(window_state) = self.windows.get_mut(&window_id)
{
if let Some(ref session_name) = window_snapshot.tmux_session_name
&& window_state.config.tmux_enabled
&& !session_name.is_empty()
{
if let Err(e) = window_state.initiate_tmux_gateway(Some(session_name)) {
log::warn!("Arrangement restore: tmux auto-connect failed: {}", e);
}
} else {
let tabs = window_state.tab_manager.tabs_mut();
for (tab_idx, snapshot) in window_snapshot.tabs.iter().enumerate() {
if let Some(tab) = tabs.get_mut(tab_idx) {
if let Some(ref user_title) = snapshot.user_title {
tab.set_title(user_title);
tab.user_named = true;
}
if let Some(color) = snapshot.custom_color {
tab.set_custom_color(color);
}
if let Some(ref icon) = snapshot.custom_icon {
tab.custom_icon = Some(icon.clone());
}
}
}
}
}
}
if self.windows.is_empty() {
log::warn!("Arrangement had no restorable windows, creating default window");
self.create_window(event_loop);
}
}
pub fn restore_arrangement_by_name(
&mut self,
name: &str,
event_loop: &ActiveEventLoop,
) -> bool {
if let Some(arrangement) = self.arrangement_manager.find_by_name(name) {
let id = arrangement.id;
self.restore_arrangement(id, event_loop);
true
} else {
log::warn!("Arrangement not found by name: {}", name);
false
}
}
pub fn delete_arrangement(&mut self, id: ArrangementId) {
if let Some(removed) = self.arrangement_manager.remove(&id) {
log::info!("Deleted arrangement '{}'", removed.name);
if let Err(e) =
crate::arrangements::storage::save_arrangements(&self.arrangement_manager)
{
log::error!("Failed to save arrangements after delete: {}", e);
}
self.sync_arrangements_to_settings();
}
}
pub fn rename_arrangement(&mut self, id: ArrangementId, new_name: String) {
if let Some(arrangement) = self.arrangement_manager.get_mut(&id) {
log::info!(
"Renamed arrangement '{}' -> '{}'",
arrangement.name,
new_name
);
arrangement.name = new_name;
if let Err(e) =
crate::arrangements::storage::save_arrangements(&self.arrangement_manager)
{
log::error!("Failed to save arrangements after rename: {}", e);
}
self.sync_arrangements_to_settings();
}
}
pub fn move_arrangement_up(&mut self, id: ArrangementId) {
self.arrangement_manager.move_up(&id);
if let Err(e) = crate::arrangements::storage::save_arrangements(&self.arrangement_manager) {
log::error!("Failed to save arrangements after reorder: {}", e);
}
self.sync_arrangements_to_settings();
}
pub fn move_arrangement_down(&mut self, id: ArrangementId) {
self.arrangement_manager.move_down(&id);
if let Err(e) = crate::arrangements::storage::save_arrangements(&self.arrangement_manager) {
log::error!("Failed to save arrangements after reorder: {}", e);
}
self.sync_arrangements_to_settings();
}
pub fn sync_arrangements_to_settings(&mut self) {
if let Some(sw) = &mut self.settings_window {
sw.settings_ui.arrangement_manager = self.arrangement_manager.clone();
}
}
}