using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Input;
using ytLive.Helpers;
using ytLive.Models;
namespace ytLive.ViewModels;
public partial class MainViewModel
{
private const string WindowKeyPrefix = "window:";
private const string PickerKeyPrefix = "picker:";
/// True for session-scoped capture keys that must not persist
/// across a reload: "picker:" picks (OS GraphicsCapturePicker) and "window:"
/// pins (an HWND can be recycled to a different window after restart).
private static bool IsTransientCaptureKey(string? key)
{
if (string.IsNullOrWhiteSpace(key)) return false;
return key.StartsWith(WindowKeyPrefix, StringComparison.OrdinalIgnoreCase)
|| key.StartsWith(PickerKeyPrefix, StringComparison.OrdinalIgnoreCase);
}
/// True when the given capture key is a window pin whose window is
/// still among the enumerated open windows — the pin then outranks
/// auto-detection (see OnFullscreenMonitorChanged).
private bool IsAliveWindowPin(string? key)
{
if (string.IsNullOrWhiteSpace(key)
|| !key.StartsWith(WindowKeyPrefix, StringComparison.OrdinalIgnoreCase)) return false;
var hwndText = key.AsSpan(WindowKeyPrefix.Length).TrimStart();
if (hwndText.Length >= 2 && hwndText[0] == '0' && (hwndText[1] == 'x' || hwndText[1] == 'X'))
hwndText = hwndText[2..];
var hwnd = long.TryParse(hwndText, System.Globalization.NumberStyles.HexNumber,
System.Globalization.CultureInfo.InvariantCulture, out var value) ? value : 0;
foreach (var window in _windowEnumerator.Enumerate())
if (window.Hwnd == hwnd)
return true;
return false;
}
/// ScreenCaptureManager's session failed (the pinned window closed,
/// a monitor went away, a transient pick expired, …). For a transient
/// session-scoped key the pin no longer resolves — fall back to the automatic
/// capture (game → desktop → static), mirroring the reload heal.
private void OnScreenCaptureFailed(string key, string message)
{
AppLog.Write($"ScreenCaptureManager: capture '{key}' failed: {message}");
if (!IsTransientCaptureKey(key)) return;
var pinned = AllBackgrounds().FirstOrDefault(b => b.CaptureKey == key);
if (pinned == null) return;
ReacquireScreenCaptures();
}
/// Open windows offered to the "Capture Window…" submenu (session
/// snapshot; refresh via ).
public ObservableCollection OpenWindows { get; } = new();
public ICommand RefreshWindowsCommand { get; }
public ICommand CaptureWindowCommand { get; }
private void RefreshOpenWindows()
{
var windows = _windowEnumerator.Enumerate();
OpenWindows.Clear();
foreach (var window in windows)
OpenWindows.Add(window);
}
}