Skip to content

Commit

Permalink
Merge pull request #23720 from peppy/fix-mouse-disappear-screenshot-fail
Browse files Browse the repository at this point in the history
Fix mouse cursor potentially disappearing for good if screenshot capture fails
  • Loading branch information
bdach authored Jun 1, 2023
2 parents 4daf1fc + 289f0e9 commit f828992
Showing 1 changed file with 52 additions and 46 deletions.
98 changes: 52 additions & 46 deletions osu.Game/Graphics/ScreenshotManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
using osu.Framework.Threading;
using osu.Game.Configuration;
using osu.Game.Input.Bindings;
using osu.Game.Online.Multiplayer;
using osu.Game.Overlays;
using osu.Game.Overlays.Notifications;
using SixLabors.ImageSharp;
Expand Down Expand Up @@ -69,7 +70,7 @@ public bool OnPressed(KeyBindingPressEvent<GlobalAction> e)
{
case GlobalAction.TakeScreenshot:
shutter.Play();
TakeScreenshotAsync();
TakeScreenshotAsync().FireAndForget();
return true;
}

Expand All @@ -86,70 +87,75 @@ public Task TakeScreenshotAsync() => Task.Run(async () =>
{
Interlocked.Increment(ref screenShotTasks);

if (!captureMenuCursor.Value)
try
{
cursorVisibility.Value = false;
if (!captureMenuCursor.Value)
{
cursorVisibility.Value = false;

// We need to wait for at most 3 draw nodes to be drawn, following which we can be assured at least one DrawNode has been generated/drawn with the set value
const int frames_to_wait = 3;
// We need to wait for at most 3 draw nodes to be drawn, following which we can be assured at least one DrawNode has been generated/drawn with the set value
const int frames_to_wait = 3;

int framesWaited = 0;
int framesWaited = 0;

using (var framesWaitedEvent = new ManualResetEventSlim(false))
{
ScheduledDelegate waitDelegate = host.DrawThread.Scheduler.AddDelayed(() =>
using (var framesWaitedEvent = new ManualResetEventSlim(false))
{
if (framesWaited++ >= frames_to_wait)
// ReSharper disable once AccessToDisposedClosure
framesWaitedEvent.Set();
}, 10, true);
ScheduledDelegate waitDelegate = host.DrawThread.Scheduler.AddDelayed(() =>
{
if (framesWaited++ >= frames_to_wait)
// ReSharper disable once AccessToDisposedClosure
framesWaitedEvent.Set();
}, 10, true);

if (!framesWaitedEvent.Wait(1000))
throw new TimeoutException("Screenshot data did not arrive in a timely fashion");
if (!framesWaitedEvent.Wait(1000))
throw new TimeoutException("Screenshot data did not arrive in a timely fashion");

waitDelegate.Cancel();
waitDelegate.Cancel();
}
}
}

using (var image = await host.TakeScreenshotAsync().ConfigureAwait(false))
{
if (Interlocked.Decrement(ref screenShotTasks) == 0 && cursorVisibility.Value == false)
cursorVisibility.Value = true;

host.GetClipboard()?.SetImage(image);
using (var image = await host.TakeScreenshotAsync().ConfigureAwait(false))
{
host.GetClipboard()?.SetImage(image);

(string filename, var stream) = getWritableStream();
(string filename, var stream) = getWritableStream();

if (filename == null) return;
if (filename == null) return;

using (stream)
{
switch (screenshotFormat.Value)
using (stream)
{
case ScreenshotFormat.Png:
await image.SaveAsPngAsync(stream).ConfigureAwait(false);
break;
switch (screenshotFormat.Value)
{
case ScreenshotFormat.Png:
await image.SaveAsPngAsync(stream).ConfigureAwait(false);
break;

case ScreenshotFormat.Jpg:
const int jpeg_quality = 92;
case ScreenshotFormat.Jpg:
const int jpeg_quality = 92;

await image.SaveAsJpegAsync(stream, new JpegEncoder { Quality = jpeg_quality }).ConfigureAwait(false);
break;
await image.SaveAsJpegAsync(stream, new JpegEncoder { Quality = jpeg_quality }).ConfigureAwait(false);
break;

default:
throw new InvalidOperationException($"Unknown enum member {nameof(ScreenshotFormat)} {screenshotFormat.Value}.");
default:
throw new InvalidOperationException($"Unknown enum member {nameof(ScreenshotFormat)} {screenshotFormat.Value}.");
}
}
}

notificationOverlay.Post(new SimpleNotification
{
Text = $"Screenshot {filename} saved!",
Activated = () =>
notificationOverlay.Post(new SimpleNotification
{
storage.PresentFileExternally(filename);
return true;
}
});
Text = $"Screenshot {filename} saved!",
Activated = () =>
{
storage.PresentFileExternally(filename);
return true;
}
});
}
}
finally
{
if (Interlocked.Decrement(ref screenShotTasks) == 0)
cursorVisibility.Value = true;
}
});

Expand Down

0 comments on commit f828992

Please sign in to comment.