Skip to content

Commit

Permalink
Make game unfocused on incoming call
Browse files Browse the repository at this point in the history
  • Loading branch information
frenzibyte committed Dec 17, 2024
1 parent 3642268 commit 555f00b
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 0 deletions.
44 changes: 44 additions & 0 deletions osu.Framework.iOS/IOSCallObserver.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Linq;
using CallKit;
using Foundation;

namespace osu.Framework.iOS
{
internal class IOSCallObserver : NSObject, ICXCallObserverDelegate
{
private readonly Action onCall;
private readonly Action onCallEnded;

private readonly CXCallController callController;

public IOSCallObserver(Action onCall, Action onCallEnded)
{
this.onCall = onCall;
this.onCallEnded = onCallEnded;

callController = new CXCallController();
callController.CallObserver.SetDelegate(this, null);

if (callController.CallObserver.Calls.Any(c => !c.HasEnded))
onCall();
}

public void CallChanged(CXCallObserver callObserver, CXCall call)
{
if (!call.HasEnded)
onCall();
else
onCallEnded();
}

protected override void Dispose(bool disposing)
{
callController.Dispose();
base.Dispose(disposing);
}
}
}
48 changes: 48 additions & 0 deletions osu.Framework.iOS/IOSWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using osu.Framework.Graphics;
using osu.Framework.Platform;
using osu.Framework.Platform.SDL3;
using SDL;
using static SDL.SDL3;
using UIKit;

Expand All @@ -22,6 +23,8 @@ internal class IOSWindow : SDL3MobileWindow

public UIWindow UIWindow => uiWindow!;

private IOSCallObserver callObserver;

public override Size Size
{
get => base.Size;
Expand Down Expand Up @@ -50,8 +53,53 @@ public override void Create()

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

// osu! cannot operate when a call takes place, as the audio is completely cut from the game, making it behave in unexpected manner.
// while this is o!f code, it's simpler to do this here rather than in osu!.
// we can reconsider this if there are framework consumers which find this behaviour undesirable.
callObserver = new IOSCallObserver(onCall, onCallEnded);
updateFocused();
}

private bool appInForeground;
private bool inCall;

protected override void HandleEvent(SDL_Event e)
{
switch (e.Type)
{
case SDL_EventType.SDL_EVENT_WINDOW_MINIMIZED:
case SDL_EventType.SDL_EVENT_WINDOW_FOCUS_LOST:
appInForeground = false;
updateFocused();
break;

case SDL_EventType.SDL_EVENT_WINDOW_RESTORED:
case SDL_EventType.SDL_EVENT_WINDOW_FOCUS_GAINED:
appInForeground = true;
updateFocused();
break;

default:
base.HandleEvent(e);
break;
}
}

private void onCall()
{
inCall = true;
updateFocused();
}

private void onCallEnded()
{
inCall = false;
updateFocused();
}

private void updateFocused() => Focused = appInForeground && !inCall;

protected override unsafe void RunMainLoop()
{
// Delegate running the main loop to CADisplayLink.
Expand Down

0 comments on commit 555f00b

Please sign in to comment.