Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bring back iOS application delegates and fix many issues #6453

Merged
merged 5 commits into from
Dec 15, 2024
Merged
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Copy drag-drop feature back from SDL's appdelegate class
frenzibyte committed Dec 11, 2024
commit 3134295ba69d5906134f42cf035fa4e944dc27a0
10 changes: 10 additions & 0 deletions osu.Framework.iOS/GameApplicationDelegate.cs
Original file line number Diff line number Diff line change
@@ -19,6 +19,7 @@ namespace osu.Framework.iOS
/// </summary>
public abstract class GameApplicationDelegate : UIApplicationDelegate
{
internal event Action<string>? DragDrop;

private const string output_volume = "outputVolume";

@@ -41,6 +42,15 @@ public override bool FinishedLaunching(UIApplication application, NSDictionary l
return true;
}

public override bool OpenUrl(UIApplication application, NSUrl url, string sourceApplication, NSObject annotation)
{
// copied verbatim from SDL: https://github.com/libsdl-org/SDL/blob/d252a8fe126b998bd1b0f4e4cf52312cd11de378/src/video/uikit/SDL_uikitappdelegate.m#L508-L535
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you subclass SDLUIKitDelegate? Seems to be supported by SDL. Maybe we don't want the extra baggage that comes from the SDL implementation?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was the hope at first but it was an extremely complicated process. We haven't explored through the concept of "iOS binding projects" before, which is an essential key to expose such types in the C# world. And throughout a brief attempt from my end, it cannot be integrated within the SDL3-CS project, it has to be in a separate project, either SDL3-CS.iOSBindings or osu.Framework.iOS.SDLBindings, depending on what the end goal with the iOS binding project turns out.

It will be a multi-day effort with back-and-fourth discussions on where and how should it be implemented and whether it's going to cause issues if it's a separate project (looping back to the concern about the Android project being previously separate), so I ultimately gave up on it on the trust that SDL will not silently add crucial code in SDLUIKitDelegate.

// the hope is that the SDL app delegate class does not have such handling exist there, but Apple does not provide a corresponding notification to make that possible.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there some copy-paste error in this comment? I don't really understand what it's supposed to say.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no error, there are just some iOS terminologies mixed in the comment. Apple provides things called Notifications in the iOS frameworks which allow applications to intercept events happening on any existing NSObject (i.e. any object), as long as said object exposes said Notifications (there's more into this but I don't want to dwell any further).

The key point of this comment is that some functionalities that used to exist in SDLUIKitDelegate were moved out to "observer" notification handlers to keep SDL away from the AppDelegate class. See libsdl-org/SDL#6011 (comment). However, there's no equivalent notification for handling OpenUrl outside of AppDelegate class, hence the existence of this comment and the copy-pasted code.

NSUrl? fileUrl = url.FilePathUrl;
DragDrop?.Invoke(fileUrl != null ? fileUrl.Path! : url.AbsoluteString!);
return true;
}

/// <summary>
/// Creates the <see cref="Game"/> class to launch.
/// </summary>
3 changes: 3 additions & 0 deletions osu.Framework.iOS/IOSWindow.cs
Original file line number Diff line number Diff line change
@@ -47,6 +47,9 @@ public override void Create()

uiWindow = Runtime.GetNSObject<UIWindow>(WindowHandle);
updateSafeArea();

var appDelegate = (GameApplicationDelegate)UIApplication.SharedApplication.Delegate;
appDelegate.DragDrop += TriggerDragDrop;
}

protected override unsafe void RunMainLoop()
2 changes: 2 additions & 0 deletions osu.Framework/Platform/SDL3/SDL3Window.cs
Original file line number Diff line number Diff line change
@@ -666,6 +666,8 @@ internal virtual void SetIconFromGroup(IconGroup iconGroup)
/// </summary>
public event Action<string>? DragDrop;

protected void TriggerDragDrop(string filename) => DragDrop?.Invoke(filename);

#endregion

public void Dispose()
2 changes: 1 addition & 1 deletion osu.Framework/Platform/SDL3/SDL3Window_Input.cs
Original file line number Diff line number Diff line change
@@ -217,7 +217,7 @@ private void handleDropEvent(SDL_DropEvent evtDrop)
case SDL_EventType.SDL_EVENT_DROP_FILE:
string? str = evtDrop.GetData();
if (str != null)
DragDrop?.Invoke(str);
TriggerDragDrop(str);

break;
}