using System.Linq; using System.Threading.Tasks; using Avalonia; using Avalonia.Controls; using Avalonia.Input; using Avalonia.Layout; using Avalonia.Media; using ClaudeDo.Ui.Localization; using ClaudeDo.Ui.Services; using ClaudeDo.Ui.ViewModels; using ClaudeDo.Ui.ViewModels.Islands; using ClaudeDo.Ui.ViewModels.Modals; using ClaudeDo.Ui.Views.Modals; namespace ClaudeDo.Ui.Views; public partial class MainWindow : Window { private bool _forceClose; public MainWindow() { InitializeComponent(); KeyDown += OnWindowKeyDown; DataContextChanged += OnDataContextChanged; UpdateMaxIcon(); } // Closing the main window kills every open Mission Control ConPTY session without // warning (App.axaml.cs: ShutdownMode.OnMainWindowClose). Ask first — never silently. protected override void OnClosing(WindowClosingEventArgs e) { if (!_forceClose && DataContext is IslandsShellViewModel { Dialogs: { } dialogs } vm && IslandsShellViewModel.RequiresCloseConfirmation(vm.OpenMissionControlSessionCount)) { e.Cancel = true; _ = ConfirmCloseWithOpenSessionsAsync(dialogs, vm.OpenMissionControlSessionCount); return; } base.OnClosing(e); } private async Task ConfirmCloseWithOpenSessionsAsync(IDialogService dialogs, int openSessionCount) { var confirmed = await dialogs.ConfirmAsync(Loc.T("vm.mainWindow.closeConfirm.message", openSessionCount)); if (!confirmed) return; _forceClose = true; Close(); } protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) { base.OnPropertyChanged(change); if (change.Property == WindowStateProperty) { UpdateMaxIcon(); if (DataContext is IslandsShellViewModel vm && vm.Tasks is not null) vm.Tasks.IsWindowVisible = WindowState != WindowState.Minimized; } if (change.Property == OffScreenMarginProperty) RootGrid.Margin = OffScreenMargin; } private void UpdateMaxIcon() { var key = WindowState == WindowState.Maximized ? "Icon.WinRestore" : "Icon.WinMax"; if (this.TryFindResource(key, out var geometry) && geometry is Geometry g) MaxIcon.Data = g; } private void OnDataContextChanged(object? sender, EventArgs e) { if (DataContext is IslandsShellViewModel vm) { vm.Dialogs = new WindowDialogService(this); vm.BringToFront = () => { if (WindowState == WindowState.Minimized) WindowState = WindowState.Normal; Activate(); }; if (vm.Tasks is not null) vm.Tasks.IsWindowVisible = WindowState != WindowState.Minimized; } } private void OnWindowKeyDown(object? sender, KeyEventArgs e) { if (e.Key == Key.Space && FocusManager?.GetFocusedElement() is not TextBox && DataContext is IslandsShellViewModel vm) { e.Handled = true; _ = vm.ToggleSelectedDoneAsync(); } } private void OnTitleBarPressed(object? sender, PointerPressedEventArgs e) { if (e.GetCurrentPoint(this).Properties.IsLeftButtonPressed) BeginMoveDrag(e); } private void OnMinimize(object? s, Avalonia.Interactivity.RoutedEventArgs e) => WindowState = WindowState.Minimized; private void OnToggleMax(object? s, Avalonia.Interactivity.RoutedEventArgs e) => WindowState = WindowState == WindowState.Maximized ? WindowState.Normal : WindowState.Maximized; private void OnClose(object? s, Avalonia.Interactivity.RoutedEventArgs e) => Close(); protected override void OnSizeChanged(SizeChangedEventArgs e) { base.OnSizeChanged(e); if (DataContext is IslandsShellViewModel vm) vm.WindowWidth = Bounds.Width; } }