Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 5 additions & 22 deletions src/UniGetUI.Avalonia/App.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -149,19 +149,6 @@ private static void StartMainWindow(IClassicDesktopStyleApplicationLifetime desk
};
}

if (CoreData.WasDaemon)
{
// Start silently: hide the window on first open only.
// Opened fires on every Show() in Avalonia, so we must unsubscribe
// immediately or every ShowFromTray() call would hide the window again.
void HideOnce(object? s, EventArgs e)
{
mainWindow.Opened -= HideOnce;
mainWindow.Hide();
}
mainWindow.Opened += HideOnce;
}

if (splash is not null)
{
var splashRef = splash;
Expand All @@ -173,9 +160,10 @@ void CloseSplashOnce(object? s, EventArgs e)
mainWindow.Opened += CloseSplashOnce;
}

// Framework auto-show already passed (we deferred via Dispatcher.Post),
// so we have to open the window ourselves.
mainWindow.Show();
// Framework auto-show already passed (we deferred via Dispatcher.Post), so we have to
// open the window ourselves. Daemon mode never shows it at all.
if (!CoreData.WasDaemon)
mainWindow.Show();

_ = StartupAsync(mainWindow);
}
Expand All @@ -194,12 +182,7 @@ private static async Task StartupAsync(MainWindow mainWindow)
// ShowDialog tries to attach to it as owner.
await Task.Yield();

// ShowDialog requires a visible owner. In daemon mode the main window
// is hidden, so temporarily show it and re-hide after the dialog closes.
bool reshide = CoreData.WasDaemon;
if (reshide) mainWindow.Show();
await new CrashReportWindow(report).ShowDialog(mainWindow);
if (reshide) mainWindow.Hide();
await mainWindow.ShowDialogAndRestoreVisibilityAsync(new CrashReportWindow(report));
}
catch { /* must not prevent normal startup */ }
}
Expand Down
4 changes: 2 additions & 2 deletions src/UniGetUI.Avalonia/Infrastructure/AvaloniaBootstrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,14 @@ await Dispatcher.UIThread.InvokeAsync(
private static async Task ShowIntegrityViolationDialogAsync()
{
if (MainWindow.Instance is not { } owner) return;
await new IntegrityViolationDialog().ShowDialog(owner);
await owner.ShowDialogAndRestoreVisibilityAsync(new IntegrityViolationDialog());
}

private static async Task ShowMissingDependencyDialogAsync(
ManagerDependency dep, int current, int total)
{
if (MainWindow.Instance is not { } owner) return;
await new MissingDependencyDialog(dep, current, total).ShowDialog(owner);
await owner.ShowDialogAndRestoreVisibilityAsync(new MissingDependencyDialog(dep, current, total));
}

private static Task InitializeSharedServicesAsync()
Expand Down
24 changes: 24 additions & 0 deletions src/UniGetUI.Avalonia/Views/MainWindow.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -829,6 +829,11 @@ private void SaveGeometryNow()
{
try
{
// Width/Height stay NaN until the window has been laid out, which never happens on a
// daemon launch the user has not opened yet. Saving then would persist a 0x0 size.
if (double.IsNaN(Width) || double.IsNaN(Height))
return;

int state = WindowState == WindowState.Maximized ? 1 : 0;
string geometry = $"v2,{Position.X},{Position.Y},{(int)Width},{(int)Height},{state}";
Settings.SetValue(Settings.K.WindowGeometry, geometry);
Expand Down Expand Up @@ -1556,6 +1561,25 @@ public async Task ShowManageIgnoredUpdatesAsync()
await ShowImmersiveDialogAsync(dialog);
}

// Immersive dialogs are hosted inside this window, so they are unreachable — and never complete —
// while it is off screen (daemon launch). Bring it up for the dialog and put it back after.
public async Task ShowDialogAndRestoreVisibilityAsync(ImmersiveDialog dialog)
{
bool reshide = !IsVisible;
if (reshide)
Show();

try
{
await dialog.ShowDialog(this);
}
finally
{
if (reshide)
Hide();
}
}

public async Task ShowImmersiveDialogAsync(ImmersiveDialog dialog)
{
var completion = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
Expand Down
Loading