use winit::event::WindowEvent;
use winit::event_loop::ActiveEventLoop;
use winit::window::WindowId;
use par_term_settings_ui::{ShaderInstallResult, ShaderUninstallResult};
use crate::settings_window::{SettingsWindow, SettingsWindowAction};
use super::WindowManager;
use super::update_checker::to_settings_update_result;
fn shader_install_wrapper(force: bool) -> Result<ShaderInstallResult, String> {
let r = crate::shader_installer::install_shaders_with_manifest(force)?;
Ok(ShaderInstallResult {
installed: r.installed,
skipped: r.skipped,
removed: r.removed,
})
}
fn shader_uninstall_wrapper(force: bool) -> Result<ShaderUninstallResult, String> {
let r = crate::shader_installer::uninstall_shaders(force)?;
Ok(ShaderUninstallResult {
removed: r.removed,
kept: r.kept,
needs_confirmation: !r.needs_confirmation.is_empty(),
})
}
impl WindowManager {
pub fn open_settings_window(&mut self, event_loop: &ActiveEventLoop) {
if let Some(settings_window) = &self.settings_window {
settings_window.focus();
return;
}
let config = self.config.clone();
let runtime = std::sync::Arc::clone(&self.runtime);
let supported_vsync_modes: Vec<crate::config::VsyncMode> = self
.windows
.values()
.next()
.and_then(|ws| ws.renderer.as_ref())
.map(|renderer| {
[
crate::config::VsyncMode::Immediate,
crate::config::VsyncMode::Mailbox,
crate::config::VsyncMode::Fifo,
]
.into_iter()
.filter(|mode| renderer.is_vsync_mode_supported(*mode))
.collect()
})
.unwrap_or_else(|| vec![crate::config::VsyncMode::Fifo]);
match runtime.block_on(SettingsWindow::new(
event_loop,
config,
supported_vsync_modes,
)) {
Ok(mut settings_window) => {
log::info!("Opened settings window {:?}", settings_window.window_id());
settings_window.settings_ui.app_version = env!("CARGO_PKG_VERSION");
settings_window
.settings_ui
.shell_integration_detected_shell_fn =
Some(crate::shell_integration_installer::detected_shell);
settings_window
.settings_ui
.shell_integration_is_installed_fn =
Some(crate::shell_integration_installer::is_installed);
settings_window.settings_ui.shader_has_files_fn =
Some(crate::shader_installer::has_shader_files);
settings_window.settings_ui.shader_count_files_fn =
Some(crate::shader_installer::count_shader_files);
settings_window.settings_ui.shader_detect_modified_fn =
Some(crate::shader_installer::detect_modified_bundled_shaders);
settings_window.settings_ui.shader_install_fn = Some(shader_install_wrapper);
settings_window.settings_ui.shader_uninstall_fn = Some(shader_uninstall_wrapper);
settings_window.settings_ui.last_update_result = self
.last_update_result
.as_ref()
.map(to_settings_update_result);
let profiles = self
.windows
.values()
.next()
.map(|ws| ws.overlay_ui.profile_manager.to_vec())
.unwrap_or_default();
settings_window.settings_ui.sync_profiles(profiles);
if let Some(ws) = self.windows.values().next() {
settings_window.settings_ui.available_agent_ids = ws
.agent_state
.available_agents
.iter()
.map(|a| (a.identity.clone(), a.name.clone()))
.collect();
}
self.settings_window = Some(settings_window);
self.sync_arrangements_to_settings();
}
Err(e) => {
log::error!("Failed to create settings window: {}", e);
}
}
}
pub fn close_settings_window(&mut self) {
if let Some(settings_window) = self.settings_window.take() {
let collapsed = settings_window.settings_ui.collapsed_sections_snapshot();
if !collapsed.is_empty() || !self.config.collapsed_settings_sections.is_empty() {
self.config.collapsed_settings_sections = collapsed.clone();
for window_state in self.windows.values_mut() {
window_state.config.collapsed_settings_sections = collapsed.clone();
}
}
if let Err(e) = self.config.save() {
log::error!("Failed to persist config on settings window close: {}", e);
}
log::info!("Closed settings window");
}
}
pub fn is_settings_window(&self, window_id: WindowId) -> bool {
self.settings_window
.as_ref()
.is_some_and(|sw| sw.window_id() == window_id)
}
pub fn handle_settings_window_event(
&mut self,
event: WindowEvent,
) -> Option<SettingsWindowAction> {
if let Some(settings_window) = &mut self.settings_window {
let action = settings_window.handle_window_event(event);
if settings_window.should_close() {
self.close_settings_window();
return Some(SettingsWindowAction::Close);
}
return Some(action);
}
None
}
pub fn apply_shader_from_editor(&mut self, source: &str) -> Result<(), String> {
let mut last_error = None;
for window_state in self.windows.values_mut() {
if let Some(renderer) = &mut window_state.renderer {
match renderer.reload_shader_from_source(source) {
Ok(()) => {
window_state.focus_state.needs_redraw = true;
if let Some(window) = &window_state.window {
window.request_redraw();
}
}
Err(e) => {
last_error = Some(format!("{:#}", e));
}
}
}
}
if let Some(settings_window) = &mut self.settings_window {
if let Some(ref err) = last_error {
settings_window.set_shader_error(Some(err.clone()));
} else {
settings_window.clear_shader_error();
}
}
last_error.map_or(Ok(()), Err)
}
pub fn apply_cursor_shader_from_editor(&mut self, source: &str) -> Result<(), String> {
let mut last_error = None;
for window_state in self.windows.values_mut() {
if let Some(renderer) = &mut window_state.renderer {
match renderer.reload_cursor_shader_from_source(source) {
Ok(()) => {
window_state.focus_state.needs_redraw = true;
if let Some(window) = &window_state.window {
window.request_redraw();
}
}
Err(e) => {
last_error = Some(format!("{:#}", e));
}
}
}
}
if let Some(settings_window) = &mut self.settings_window {
if let Some(ref err) = last_error {
settings_window.set_cursor_shader_error(Some(err.clone()));
} else {
settings_window.clear_cursor_shader_error();
}
}
last_error.map_or(Ok(()), Err)
}
pub fn request_settings_redraw(&self) {
if let Some(settings_window) = &self.settings_window {
settings_window.request_redraw();
}
}
}