use super::charset::Charset;
use super::render_backend::RenderBackend;
use super::theme::Theme;
use super::video_buffer::{VideoBuffer, render_fullscreen_shadow};
use crate::app::app_state::AppState;
use crate::app::config_manager::AppConfig;
use crate::input::keyboard_mode::KeyboardMode;
use crate::lockscreen::auth::is_os_auth_available;
use crate::ui::ui_render;
use crate::window::manager::WindowManager;
use crate::window::number_overlay;
use std::io::{self, Write};
#[allow(clippy::too_many_arguments)]
pub fn render_frame(
video_buffer: &mut VideoBuffer,
backend: &mut Box<dyn RenderBackend>,
stdout: &mut io::Stdout,
window_manager: &mut WindowManager,
app_state: &mut AppState,
charset: &Charset,
theme: &Theme,
app_config: &AppConfig,
has_clipboard_content: bool,
has_selection: bool,
) -> io::Result<bool> {
let (cols, rows) = backend.dimensions();
ui_render::render_background(video_buffer, charset, theme);
let focus = window_manager.get_focus();
ui_render::render_top_bar_widgets(
video_buffer,
&mut app_state.top_bar,
focus,
has_clipboard_content,
has_selection,
app_config.show_date_in_clock,
theme,
charset,
);
let keyboard_mode_active = !matches!(app_state.keyboard_mode, KeyboardMode::Normal);
let windows_closed = window_manager.render_all(
video_buffer,
charset,
theme,
app_state.tint_terminal,
keyboard_mode_active,
);
window_manager.render_snap_preview(video_buffer, charset, theme);
if app_state.show_window_number_overlay {
number_overlay::render_window_numbers(video_buffer, window_manager, theme);
}
if app_state.auto_tiling_enabled {
window_manager.render_pivot(video_buffer, charset, theme, app_config.tiling_gaps);
}
ui_render::render_button_bar(
video_buffer,
window_manager,
&app_state.auto_tiling_button,
app_state.auto_tiling_enabled,
&app_state.keyboard_mode,
theme,
);
let has_modal = app_state.active_prompt.is_some()
|| app_state.active_slight_input.is_some()
|| app_state.active_calendar.is_some()
|| app_state.active_config_window.is_some()
|| app_state.active_pin_setup.is_some()
|| app_state.active_help_window.is_some()
|| app_state.active_about_window.is_some()
|| app_state.active_winmode_help_window.is_some()
|| app_state.active_error_dialog.is_some();
if has_modal {
render_fullscreen_shadow(video_buffer, theme);
}
if let Some(ref prompt) = app_state.active_prompt {
prompt.render(video_buffer, charset, theme);
}
if let Some(ref slight_input) = app_state.active_slight_input {
slight_input.render(video_buffer, charset, theme);
}
if let Some(ref calendar) = app_state.active_calendar {
ui_render::render_calendar(video_buffer, calendar, charset, theme, cols, rows);
}
if let Some(ref config_win) = app_state.active_config_window {
config_win.render(
video_buffer,
charset,
theme,
app_config,
app_state.tint_terminal,
is_os_auth_available(),
);
}
if let Some(ref pin_setup) = app_state.active_pin_setup {
pin_setup.render(video_buffer, charset, theme);
}
if let Some(ref help_win) = app_state.active_help_window {
help_win.render(video_buffer, charset, theme);
}
if let Some(ref about_win) = app_state.active_about_window {
about_win.render(video_buffer, charset, theme);
}
if let Some(ref winmode_help_win) = app_state.active_winmode_help_window {
winmode_help_win.render(video_buffer, charset, theme);
}
if let Some(ref error_dialog) = app_state.active_error_dialog {
error_dialog.render(video_buffer, charset, theme);
}
let toast_expired = app_state
.active_toast
.as_ref()
.is_some_and(|t| t.is_expired());
if toast_expired {
app_state.active_toast = None;
}
if let Some(ref toast) = app_state.active_toast {
toast.render(video_buffer, charset, theme);
}
if app_state.context_menu.visible {
app_state.context_menu.render(video_buffer, charset, theme);
}
if app_state.taskbar_menu.visible {
app_state.taskbar_menu.render(video_buffer, charset, theme);
}
if app_state.system_menu.visible {
app_state.system_menu.render(video_buffer, charset, theme);
}
if app_state.lockscreen.is_active() {
app_state.lockscreen.render(video_buffer, charset, theme);
}
backend.restore_cursor_area();
backend.present(video_buffer)?;
backend.update_cursor();
backend.draw_cursor();
stdout.flush()?;
Ok(windows_closed)
}