Skip to main content

par_term/app/
mod.rs

1//! Application module for par-term
2//!
3//! This module contains the main application logic, including:
4//! - `App`: Entry point that initializes and runs the event loop
5//! - `WindowManager`: Manages multiple windows and coordinates menu events
6//! - `WindowState`: Per-window state including terminal, renderer, and UI
7
8use crate::cli::RuntimeOptions;
9use crate::config::Config;
10use anyhow::Result;
11use std::sync::Arc;
12use tokio::runtime::Runtime;
13use winit::event_loop::{ControlFlow, EventLoop};
14
15pub mod anti_idle;
16pub mod bell;
17pub mod config_updates;
18pub mod copy_mode_handler;
19pub mod debug_state;
20mod file_transfers;
21pub mod handler;
22pub mod input_events;
23pub mod keyboard_handlers;
24pub mod mouse;
25pub mod mouse_events;
26mod notifications;
27pub mod render_cache;
28pub mod renderer_init;
29pub mod scroll_ops;
30pub mod search_highlight;
31pub mod tab_ops;
32pub mod text_selection;
33mod tmux_handler;
34mod triggers;
35pub mod url_hover;
36pub mod window_manager;
37pub mod window_state;
38
39pub use window_manager::WindowManager;
40
41/// Main application entry point
42pub struct App {
43    config: Config,
44    runtime: Arc<Runtime>,
45    runtime_options: RuntimeOptions,
46}
47
48impl App {
49    /// Create a new application
50    pub fn new(runtime: Arc<Runtime>, runtime_options: RuntimeOptions) -> Result<Self> {
51        let mut config = Config::load()?;
52
53        // Apply CLI shader override if specified
54        if let Some(ref shader) = runtime_options.shader {
55            config.custom_shader = Some(shader.clone());
56            config.custom_shader_enabled = true;
57            log::info!("CLI override: using shader '{}'", shader);
58        }
59
60        // Apply CLI session logging override if specified
61        if runtime_options.log_session {
62            config.auto_log_sessions = true;
63            log::info!("CLI override: session logging enabled");
64        }
65
66        // Apply config log level (unless CLI --log-level was specified)
67        if runtime_options.log_level.is_none() {
68            crate::debug::set_log_level(config.log_level.to_level_filter());
69            log::info!("Config log level: {}", config.log_level.display_name());
70        }
71
72        Ok(Self {
73            config,
74            runtime,
75            runtime_options,
76        })
77    }
78
79    /// Run the application
80    pub fn run(self) -> Result<()> {
81        let event_loop = EventLoop::new()?;
82        // Use Wait for power-efficient event handling
83        // Combined with WaitUntil in about_to_wait for precise timing
84        event_loop.set_control_flow(ControlFlow::Wait);
85
86        let mut window_manager =
87            WindowManager::new(self.config, self.runtime, self.runtime_options);
88
89        event_loop.run_app(&mut window_manager)?;
90
91        Ok(())
92    }
93}