Skip to content

Commit 728a42d

Browse files
authored
Merge pull request #303 from winnerspiros/copilot/fix-vulkan-issues-on-android
Bump ppy.osu.Framework to 2026.505.1 (Vortice.Vulkan 3.2.1 + gray-rectangle fix)
2 parents d469090 + 70b3968 commit 728a42d

37 files changed

Lines changed: 833 additions & 201 deletions

.github/workflows/ci.yml

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,8 +234,52 @@ jobs:
234234
- name: Authenticate to GitHub Packages
235235
run: dotnet nuget update source winnerspiros-github --username ${{ github.actor }} --password ${{ secrets.GITHUB_TOKEN }} --store-password-in-clear-text
236236

237-
- name: Set Xcode version
238-
run: sudo xcode-select -s /Applications/Xcode_26.3.app
237+
# https://github.com/dotnet/macios/issues/19157
238+
# https://github.com/actions/runner-images/issues/12758
239+
- name: Use Xcode 26.4
240+
run: |
241+
# Pin to Xcode 26.4 — the .NET iOS workload (net10.0_26.4) requires exactly Xcode 26.4.
242+
# Using Xcode 26.5 causes a hard build failure: "requires Xcode 26.4, current is 26.5".
243+
# Fix: MacOSX.sdk in Xcode 26.4 is a minimal stub. Replace it with a symlink to the
244+
# real versioned SDK found across Xcode installs. Real SDKs have hundreds of headers;
245+
# stubs have ≤1.
246+
ACTIVE_XCODE="/Applications/Xcode_26.4.app"
247+
sudo xcode-select -switch "$ACTIVE_XCODE"
248+
SDKS_DIR="$ACTIVE_XCODE/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs"
249+
MACOS_SDK="$SDKS_DIR/MacOSX.sdk"
250+
REAL_SDK=""
251+
# Search ALL Xcode_26.x.app installs (including active) for versioned MacOSX[N].sdk.
252+
# Validate by usr/include header count: stubs ≤1 file, real SDKs have hundreds.
253+
for xapp in $(ls -d /Applications/Xcode_26.*.app 2>/dev/null | sort -rV); do
254+
sdk_dir="$xapp/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs"
255+
[ -d "$sdk_dir" ] || continue
256+
for sdk in $(ls "$sdk_dir" 2>/dev/null | grep '^MacOSX[0-9].*\.sdk$' | sort -rV); do
257+
cand="$sdk_dir/$sdk"
258+
hdr_count=$(ls "$cand/usr/include" 2>/dev/null | wc -l | tr -d ' ')
259+
if [ "${hdr_count:-0}" -gt 5 ]; then
260+
REAL_SDK="$cand"
261+
break 2
262+
fi
263+
done
264+
done
265+
# Fallback: CommandLineTools
266+
if [ -z "$REAL_SDK" ]; then
267+
for sdk in $(ls /Library/Developer/CommandLineTools/SDKs 2>/dev/null | grep '^MacOSX[0-9].*\.sdk$' | sort -rV); do
268+
cand="/Library/Developer/CommandLineTools/SDKs/$sdk"
269+
hdr_count=$(ls "$cand/usr/include" 2>/dev/null | wc -l | tr -d ' ')
270+
if [ "${hdr_count:-0}" -gt 5 ]; then
271+
REAL_SDK="$cand"
272+
break
273+
fi
274+
done
275+
fi
276+
if [ -n "$REAL_SDK" ]; then
277+
sudo rm -rf "$MACOS_SDK"
278+
sudo ln -sfn "$REAL_SDK" "$MACOS_SDK"
279+
echo "Created MacOSX.sdk symlink -> $REAL_SDK"
280+
else
281+
echo "WARNING: no valid macOS SDK found; build may fail"
282+
fi
239283
240284
- name: Install .NET Workloads
241285
run: dotnet workload install ios

osu.Android.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@
9999
</PropertyGroup>
100100

101101
<ItemGroup>
102-
<PackageReference Include="ppy.osu.Framework.Android" Version="2026.504.3" />
102+
<PackageReference Include="ppy.osu.Framework.Android" Version="2026.505.1" />
103103
<!-- `ppy.osu.Framework.NativeLibs` is a transitive dependency of `ppy.osu.Framework`
104104
that ships desktop-only natives (Linux/macOS/Windows) under `runtimes/<rid>/native/`
105105
— including a bare Linux `libbass.so`/`libbass_fx.so`/`libbassmix.so` for linux-arm64.

osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,11 @@ public void TestReport()
253253
InputManager.MoveMouseTo(btn);
254254
InputManager.Click(MouseButton.Left);
255255
});
256+
AddStep("Set reason to other", () =>
257+
{
258+
var reason = this.ChildrenOfType<OsuEnumDropdown<CommentReportReason>>().Single();
259+
reason.Current.Value = CommentReportReason.Other;
260+
});
256261
AddStep("Try to report", () =>
257262
{
258263
var btn = this.ChildrenOfType<ReportCommentPopover>().Single().ChildrenOfType<RoundedButton>().Single();
@@ -261,12 +266,10 @@ public void TestReport()
261266
});
262267
AddWaitStep("Wait", 3);
263268
AddAssert("Nothing happened", () => this.ChildrenOfType<ReportCommentPopover>().Any());
264-
AddStep("Set report data", () =>
269+
AddStep("Add comment", () =>
265270
{
266271
var field = this.ChildrenOfType<ReportCommentPopover>().Single().ChildrenOfType<OsuTextBox>().First();
267272
field.Current.Value = report_text;
268-
var reason = this.ChildrenOfType<OsuEnumDropdown<CommentReportReason>>().Single();
269-
reason.Current.Value = CommentReportReason.Other;
270273
});
271274
AddStep("Try to report", () =>
272275
{
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
2+
// See the LICENCE file in the repository root for full licence text.
3+
4+
using System.Linq;
5+
using System.Net.Http;
6+
using NUnit.Framework;
7+
using osu.Framework.Extensions;
8+
using osu.Framework.Graphics;
9+
using osu.Framework.Graphics.Cursor;
10+
using osu.Framework.Graphics.UserInterface;
11+
using osu.Framework.Testing;
12+
using osu.Game.Graphics;
13+
using osu.Game.Graphics.Containers;
14+
using osu.Game.Graphics.UserInterface;
15+
using osu.Game.Graphics.UserInterfaceV2;
16+
using osu.Game.Online.API;
17+
using osu.Game.Online.API.Requests;
18+
using osu.Game.Overlays.Chat;
19+
20+
namespace osu.Game.Tests.Visual.Online
21+
{
22+
public partial class TestSceneReportPopover : OsuTestScene
23+
{
24+
private DummyAPIAccess dummyAPI => (DummyAPIAccess)API;
25+
26+
private ReportPopoverContainer popover = null!;
27+
28+
[SetUpSteps]
29+
public void SetUp()
30+
{
31+
AddStep("create popover", () =>
32+
{
33+
Child = new PopoverContainer
34+
{
35+
RelativeSizeAxes = Axes.Both,
36+
Child = popover = new ReportPopoverContainer(),
37+
};
38+
});
39+
}
40+
41+
[Test]
42+
public void TestSuccess()
43+
{
44+
ChatReportRequest pendingRequest = null!;
45+
46+
AddStep("setup request handling", () =>
47+
{
48+
dummyAPI.HandleRequest += request =>
49+
{
50+
if (request is ChatReportRequest chatReportRequest)
51+
{
52+
pendingRequest = chatReportRequest;
53+
return true;
54+
}
55+
56+
return false;
57+
};
58+
});
59+
AddStep("show popover", () => popover.ShowPopover());
60+
AddStep("input reason", () => this.ChildrenOfType<OsuTextBox>().First().Text = "reason");
61+
AddStep("send report", () => this.ChildrenOfType<Button>().First().TriggerClick());
62+
AddUntilStep("wait for loading layer to hide", () => this.ChildrenOfType<LoadingLayer>().First().IsPresent, () => Is.True);
63+
AddWaitStep("wait some", 3);
64+
AddStep("complete request", () => pendingRequest.TriggerSuccess());
65+
AddUntilStep("wait for loading layer to hide", () => this.ChildrenOfType<LoadingLayer>().First().IsPresent, () => Is.False);
66+
AddAssert("ensure form is not present", () => this.ChildrenOfType<ReverseChildIDFillFlowContainer<Drawable>>().First().IsPresent, () => Is.False);
67+
AddAssert("ensure confirmation is present", () => this.ChildrenOfType<ReportPopover<ChatReportReason>.ReportConfirmation>().First().IsPresent, () => Is.True);
68+
AddUntilStep("wait for popover to hide", () => this.ChildrenOfType<ReportPopoverContainer.TestReportPopover>().First().IsPresent, () => Is.False);
69+
}
70+
71+
[Test]
72+
public void TestFailure()
73+
{
74+
ChatReportRequest pendingRequest = null!;
75+
76+
AddStep("setup request handling", () =>
77+
{
78+
dummyAPI.HandleRequest += request =>
79+
{
80+
if (request is ChatReportRequest chatReportRequest)
81+
{
82+
pendingRequest = chatReportRequest;
83+
return true;
84+
}
85+
86+
return false;
87+
};
88+
});
89+
AddStep("show popover", () => popover.ShowPopover());
90+
AddStep("input reason", () => this.ChildrenOfType<OsuTextBox>().First().Text = "reason");
91+
AddStep("send report", () => this.ChildrenOfType<Button>().First().TriggerClick());
92+
AddUntilStep("wait for loading layer to hide", () => this.ChildrenOfType<LoadingLayer>().First().IsPresent, () => Is.True);
93+
AddWaitStep("wait some", 3);
94+
AddStep("fail request", () => pendingRequest.TriggerFailure(new APIException("test error", new HttpRequestException("test error"))));
95+
AddUntilStep("wait for loading layer to hide", () => this.ChildrenOfType<LoadingLayer>().First().IsPresent, () => Is.False);
96+
AddAssert("ensure form is present", () => this.ChildrenOfType<ReverseChildIDFillFlowContainer<Drawable>>().First().IsPresent, () => Is.True);
97+
AddAssert("ensure error is present", () => this.ChildrenOfType<ErrorTextFlowContainer>().First().IsPresent, () => Is.True);
98+
AddAssert("ensure confirmation is not present", () => this.ChildrenOfType<ReportPopover<ChatReportReason>.ReportConfirmation>().First().IsPresent, () => Is.False);
99+
}
100+
101+
protected partial class ReportPopoverContainer : Drawable, IHasPopover
102+
{
103+
public Popover GetPopover() => new TestReportPopover("test");
104+
105+
public partial class TestReportPopover : ReportPopover<ChatReportReason>
106+
{
107+
private IAPIProvider api { get; set; } = null!;
108+
109+
public TestReportPopover(string name)
110+
: base($"Report {name}?")
111+
{
112+
}
113+
114+
protected override APIRequest GetRequest(ChatReportReason reason, string comment) => new ChatReportRequest(1, reason, comment);
115+
}
116+
}
117+
}
118+
}

0 commit comments

Comments
 (0)