Skip to content
Open
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
44 changes: 39 additions & 5 deletions src/Starward/Features/Background/AppBackground.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,14 @@ private async Task ChangeBackgroundImageAsync(string file, CancellationToken can

private SemaphoreSlim _videoSemaphore = new SemaphoreSlim(1, 1);

private bool _windowHidden;

private bool _windowMinimized;

private bool _sessionLocked;

private bool ShouldPauseVideo => _windowHidden || _windowMinimized || _sessionLocked;


private void StartMediaPlayer(string file)
{
Expand Down Expand Up @@ -402,6 +410,11 @@ private void StartMediaPlayer(string file)
_mediaPlayer.VideoFrameAvailable += MediaPlayer_VideoFrameAvailable;
_mediaPlayer.MediaFailed += MediaPlayer_MediaFailed;
_mediaPlayer.Play();
// 若窗口当前不处于可播放状态(最小化、隐藏或锁屏),暂停新建的播放器
if (ShouldPauseVideo)
{
_mediaPlayer.Pause();
}
}


Expand Down Expand Up @@ -592,16 +605,37 @@ private void OnMainWindowStateChanged(object _, MainWindowStateChangedMessage me
{
try
{
// 各暂停条件由对应窗口消息独立维护,播放或暂停由聚合状态统一决定
if (message.Hide)
{
_windowHidden = true;
}
if (message.Activate)
{
// 激活只代表窗口回到屏幕前,不改变最小化和锁屏状态
_windowHidden = false;
}
if (message.Minimized is bool minimized)
{
_windowMinimized = minimized;
}
if (message.SessionLock)
{
_sessionLocked = true;
}
if (message.SessionUnlock)
{
_sessionLocked = false;
}
if (_mediaPlayer is not null)
{
var state = _mediaPlayer.PlaybackSession.PlaybackState;
if (message.Activate && state is not MediaPlaybackState.Playing)
if (ShouldPauseVideo)
{
_mediaPlayer.Play();
_mediaPlayer.Pause();
}
else if (message.Hide || message.SessionLock)
else if (_mediaPlayer.PlaybackSession.PlaybackState is not MediaPlaybackState.Playing)
{
_mediaPlayer.Pause();
_mediaPlayer.Play();
}
}
}
Expand Down
19 changes: 18 additions & 1 deletion src/Starward/Features/ViewHost/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,9 @@ public override void Hide()
private DateTimeOffset _lastActivatedTime = DateTimeOffset.Now;


private bool _isMinimized;


protected override nint WindowSubclassProc(HWND hWnd, uint uMsg, nint wParam, nint lParam, nuint uIdSubclass, nint dwRefData)
{
if (uMsg == (uint)User32.WindowMessage.WM_ACTIVATE || uMsg == (uint)User32.WindowMessage.WM_POINTERACTIVATE)
Expand Down Expand Up @@ -205,6 +208,19 @@ protected override nint WindowSubclassProc(HWND hWnd, uint uMsg, nint wParam, ni
return IntPtr.Zero;
}
}
else if (uMsg == (uint)User32.WindowMessage.WM_SIZE)
{
// 窗口最小化或还原,通知动态背景暂停或恢复
if (wParam is 0 or 1 or 2)
{
bool minimized = wParam is 1;
if (minimized != _isMinimized)
{
_isMinimized = minimized;
WeakReferenceMessenger.Default.Send(new MainWindowStateChangedMessage { Minimized = minimized, CurrentTime = DateTimeOffset.Now });
}
}
}
else if (uMsg == (uint)User32.WindowMessage.WM_WTSSESSION_CHANGE)
{
if (wParam == 0x7)
Expand All @@ -215,7 +231,8 @@ protected override nint WindowSubclassProc(HWND hWnd, uint uMsg, nint wParam, ni
}
else if (wParam == 0x8)
{
// WTS_SESSION_UNLOCK
// WTS_SESSION_UNLOCK
WeakReferenceMessenger.Default.Send(new MainWindowStateChangedMessage { SessionUnlock = true, CurrentTime = DateTimeOffset.Now });
}
}
else if (uMsg == (uint)User32.WindowMessage.WM_DEVICECHANGE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ internal class MainWindowStateChangedMessage
public bool SessionLock { get; set; }


public bool SessionUnlock { get; set; }


public bool? Minimized { get; set; }


public DateTimeOffset CurrentTime { get; set; }


Expand Down