Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
5091d36
Better sync modal stack on startup
PureWeen Feb 2, 2023
d4233a5
- fix up windows modal paths
PureWeen Feb 2, 2023
1ec4e36
- simplify window and add shell tests
PureWeen Feb 6, 2023
eaf5575
- add more tests and fix appearing on window
PureWeen Feb 6, 2023
abd613f
- cleanup from comments
PureWeen Feb 7, 2023
afc1289
- fix tizen
PureWeen Feb 7, 2023
f487f60
Update ModalNavigationManager.Tizen.cs
PureWeen Feb 7, 2023
e42c881
Update ModalNavigationManager.Tizen.cs
PureWeen Feb 7, 2023
cd7b81a
- review comment fixes
PureWeen Feb 8, 2023
54930f8
- remove the if
PureWeen Feb 8, 2023
da2bfc6
- add comments
PureWeen Feb 8, 2023
f29c92a
- more tests and more code
PureWeen Feb 10, 2023
8c2cebd
- fix up iOS tests
PureWeen Feb 11, 2023
89f3946
- see if this fixes crash on CI
PureWeen Feb 11, 2023
e11e7c5
- fix tests
PureWeen Feb 12, 2023
fa05ab3
- more tests and fixes for iOS
PureWeen Feb 13, 2023
191f943
Auto-format source code
Feb 13, 2023
7a08feb
- fix ordering for replacing root view
PureWeen Feb 14, 2023
6df3b51
- fix scoped fragments
PureWeen Feb 14, 2023
d81e3a4
- cleanup code
PureWeen Feb 14, 2023
6f5c3bd
- clarify
PureWeen Feb 16, 2023
3c17453
Merge branch 'main' into fix_modal_syncing
PureWeen Feb 16, 2023
c95a7f1
- remove if/debug for window lifecycle exceptions
PureWeen Feb 23, 2023
e23da1c
Merge branch 'main' into fix_modal_syncing
PureWeen Mar 1, 2023
2de9c5e
- fix unit test
PureWeen Mar 1, 2023
52b02f8
Merge branch 'main' into fix_modal_syncing
PureWeen Mar 1, 2023
bce95de
- cleanup modalwrapper
PureWeen Mar 1, 2023
f4fbc5c
- add loaded and unloaded
PureWeen Mar 1, 2023
334b129
Merge branch 'main' into fix_modal_syncing
PureWeen Mar 7, 2023
2a9a11a
- Add better exception if user calls pop modal with no modal page pre…
PureWeen Mar 7, 2023
30ffd8d
- fix test code for dismissing modals
PureWeen Mar 8, 2023
c74b697
Merge branch 'main' into fix_modal_syncing
PureWeen Mar 9, 2023
bf2e4b5
Merge branch 'main' into fix_modal_syncing
PureWeen Mar 14, 2023
43c148b
- fix define on MaybeNull
PureWeen Mar 14, 2023
ee78b12
Merge branch 'main' into fix_modal_syncing
PureWeen Mar 14, 2023
ac1e149
- fix up tests related to keyboard
PureWeen Mar 15, 2023
9a39a53
- fix compile error on compatibility
PureWeen Mar 15, 2023
a956239
- fix timing of setting parent on modal page
PureWeen Mar 15, 2023
2c45ed8
- fix shell and add tests
PureWeen Mar 15, 2023
2a49b9a
Auto-format source code
Mar 15, 2023
f05b2ba
Merge branch 'main' into fix_modal_syncing
PureWeen Mar 15, 2023
d39d677
- fix retrieving of CurrentPage
PureWeen Mar 15, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ protected override void OnNewIntent(Intent intent)

protected override void OnPause()
{
_layout.HideKeyboard(true);
_layout.HideKeyboard();

// Stop animations or other ongoing actions that could consume CPU
// Commit unsaved changes, build only if users expect such changes to be permanently saved when thy leave such as a draft email
Expand Down
2 changes: 1 addition & 1 deletion src/Compatibility/Core/src/iOS/Platform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@ async Task PresentModal(Page modal, bool animated)
SetRenderer(modal, modalRenderer);
}

var wrapper = new ModalWrapper(modalRenderer.Element.Handler as IPlatformViewHandler);
var wrapper = new ControlsModalWrapper(modalRenderer.Element.Handler as IPlatformViewHandler);

if (_modals.Count > 1)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ public override void ViewWillAppear(bool animated)

public override void ViewDidDisappear(bool animated)
{
CompletePendingNavigation(false);

base.ViewDidDisappear(animated);

if (!_appeared || Element == null)
Expand Down Expand Up @@ -379,9 +381,32 @@ void FindParentFlyoutPage()
_parentFlyoutPage = flyoutDetail;
}

TaskCompletionSource<bool> _pendingNavigationRequest;
ActionDisposable _removeLifecycleEvents;

void CompletePendingNavigation(bool success)
{
if (_pendingNavigationRequest is null)
return;

_removeLifecycleEvents?.Dispose();
_removeLifecycleEvents = null;

var pendingNavigationRequest = _pendingNavigationRequest;
_pendingNavigationRequest = null;

BeginInvokeOnMainThread(() =>
{
pendingNavigationRequest?.TrySetResult(success);
pendingNavigationRequest = null;
});
}

Task<bool> GetAppearedOrDisappearedTask(Page page)
{
var tcs = new TaskCompletionSource<bool>();
CompletePendingNavigation(false);

_pendingNavigationRequest = new TaskCompletionSource<bool>();

_ = page.ToPlatform(MauiContext);
var renderer = (IPlatformViewHandler)page.Handler;
Expand All @@ -392,24 +417,24 @@ Task<bool> GetAppearedOrDisappearedTask(Page page)
EventHandler appearing = null, disappearing = null;
appearing = (s, e) =>
{
parentViewController.Appearing -= appearing;
parentViewController.Disappearing -= disappearing;

BeginInvokeOnMainThread(() => { tcs.SetResult(true); });
CompletePendingNavigation(true);
};

disappearing = (s, e) =>
{
CompletePendingNavigation(false);
};

_removeLifecycleEvents = new ActionDisposable(() =>
{
parentViewController.Appearing -= appearing;
parentViewController.Disappearing -= disappearing;

BeginInvokeOnMainThread(() => { tcs.SetResult(false); });
};
});

parentViewController.Appearing += appearing;
parentViewController.Disappearing += disappearing;

return tcs.Task;
return _pendingNavigationRequest.Task;
}

void HandlePropertyChanged(object sender, PropertyChangedEventArgs e)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,29 @@ internal bool SendPop()
return false;
}

public override void ViewDidDisappear(bool animated)
{
// If this page is removed from the View Hierarchy we need to resolve any
// pending navigation operations
var sourcesToComplete = new List<TaskCompletionSource<bool>>();

foreach (var item in _completionTasks.Values)
{
sourcesToComplete.Add(item);
}

_completionTasks.Clear();

foreach (var source in sourcesToComplete)
source.TrySetResult(false);

_popCompletionTask?.TrySetResult(false);
_popCompletionTask = null;


base.ViewDidDisappear(animated);
}

public override void ViewWillAppear(bool animated)
{
if (_disposed)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ internal static void DisposeModalAndChildHandlers(this Maui.IElement view)
{
if (renderer.ViewController != null)
{
if (renderer.ViewController.ParentViewController is Platform.ModalWrapper modalWrapper)
if (renderer.ViewController.ParentViewController is Platform.ControlsModalWrapper modalWrapper)
modalWrapper.Dispose();
}

Expand Down
86 changes: 29 additions & 57 deletions src/Controls/src/Core/HandlerImpl/Window/Window.Impl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -417,16 +417,19 @@ internal void FinishedAddingWindowToApplication(Application application)

void SendWindowAppearing()
{
Page?.SendAppearing();
if (Navigation.ModalStack.Count == 0)
Page?.SendAppearing();
}

void SendWindowDisppearing()
{
Page?.SendDisappearing();
if (Navigation.ModalStack.Count == 0)
Page?.SendDisappearing();

IsActivated = false;
}

void OnModalPopped(Page modalPage)
internal void OnModalPopped(Page modalPage)
{
int index = _visualChildren.IndexOf(modalPage);
_visualChildren.Remove(modalPage);
Expand All @@ -438,15 +441,15 @@ void OnModalPopped(Page modalPage)
VisualDiagnostics.OnChildRemoved(this, modalPage, index);
}

bool OnModalPopping(Page modalPage)
internal bool OnModalPopping(Page modalPage)
{
var args = new ModalPoppingEventArgs(modalPage);
ModalPopping?.Invoke(this, args);
Application?.NotifyOfWindowModalEvent(args);
return args.Cancel;
}

void OnModalPushed(Page modalPage)
internal void OnModalPushed(Page modalPage)
{
_visualChildren.Add(modalPage);
var args = new ModalPushedEventArgs(modalPage);
Expand All @@ -455,21 +458,25 @@ void OnModalPushed(Page modalPage)
VisualDiagnostics.OnChildAdded(this, modalPage);
}

void OnModalPushing(Page modalPage)
internal void OnModalPushing(Page modalPage)
{
var args = new ModalPushingEventArgs(modalPage);
ModalPushing?.Invoke(this, args);
Application?.NotifyOfWindowModalEvent(args);
}

void OnPopCanceled()
internal void OnPopCanceled()
{
PopCanceled?.Invoke(this, EventArgs.Empty);
}

void IWindow.Created()
{
if (IsCreated)
throw new InvalidOperationException("Window was already created");

IsCreated = true;
IsDestroyed = false;

Created?.Invoke(this, EventArgs.Empty);
OnCreated();
Expand All @@ -478,13 +485,19 @@ void IWindow.Created()

void IWindow.Activated()
{
if (IsActivated)
throw new InvalidOperationException("Window was already activated");

IsActivated = true;
Activated?.Invoke(this, EventArgs.Empty);
OnActivated();
}

void IWindow.Deactivated()
{
if (!IsActivated)
throw new InvalidOperationException("Window was already deactivated");

IsActivated = false;
Deactivated?.Invoke(this, EventArgs.Empty);
OnDeactivated();
Expand All @@ -499,7 +512,12 @@ void IWindow.Stopped()

void IWindow.Destroying()
{
if (IsDestroyed)
throw new InvalidOperationException("Window was already destroyed");

IsDestroyed = true;
IsCreated = false;

SendWindowDisppearing();
Destroying?.Invoke(this, EventArgs.Empty);
OnDestroying();
Expand Down Expand Up @@ -613,8 +631,6 @@ void OnPageChanged(Page? oldPage, Page? newPage)
_menuBarTracker.Target = newPage;
}

ModalNavigationManager.SettingNewPage();

if (newPage != null)
{
newPage.HandlerChanged += OnPageHandlerChanged;
Expand Down Expand Up @@ -676,58 +692,14 @@ protected override IReadOnlyList<Page> GetModalStack()
return _owner.ModalNavigationManager.ModalStack;
}

protected override async Task<Page?> OnPopModal(bool animated)
protected override Task<Page?> OnPopModal(bool animated)
{
Page modal = _owner.ModalNavigationManager.ModalStack[_owner.ModalNavigationManager.ModalStack.Count - 1];
if (_owner.OnModalPopping(modal))
{
_owner.OnPopCanceled();
return null;
}

Page? nextPage;
if (modal.NavigationProxy.ModalStack.Count == 1)
{
nextPage = _owner.Page;
}
else
{
nextPage = _owner.ModalNavigationManager.ModalStack[_owner.ModalNavigationManager.ModalStack.Count - 2];
}

Page result = await _owner.ModalNavigationManager.PopModalAsync(animated);
result.Parent = null;
_owner.OnModalPopped(result);

modal.SendNavigatedFrom(new NavigatedFromEventArgs(nextPage));
nextPage?.SendNavigatedTo(new NavigatedToEventArgs(modal));

return result;
return _owner.ModalNavigationManager.PopModalAsync(animated);
Copy link
Member Author

Choose a reason for hiding this comment

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

I moved all of this code into ModalNavigationManager

}

protected override async Task OnPushModal(Page modal, bool animated)
protected override Task OnPushModal(Page modal, bool animated)
{
_owner.OnModalPushing(modal);

modal.Parent = _owner;

if (modal.NavigationProxy.ModalStack.Count == 0)
{
modal.NavigationProxy.Inner = this;
await _owner.ModalNavigationManager.PushModalAsync(modal, animated);
_owner.Page?.SendNavigatedFrom(new NavigatedFromEventArgs(modal));
modal.SendNavigatedTo(new NavigatedToEventArgs(_owner.Page));
}
else
{
var previousModalPage = modal.NavigationProxy.ModalStack[modal.NavigationProxy.ModalStack.Count - 1];
await _owner.ModalNavigationManager.PushModalAsync(modal, animated);
modal.NavigationProxy.Inner = this;
previousModalPage.SendNavigatedFrom(new NavigatedFromEventArgs(modal));
modal.SendNavigatedTo(new NavigatedToEventArgs(previousModalPage));
}

_owner.OnModalPushed(modal);
return _owner.ModalNavigationManager.PushModalAsync(modal, animated);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Controls/src/Core/Internals/MaybeNullWhenAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace System.Diagnostics.CodeAnalysis
{
#if !NETCOREAPP
#if !NETCOREAPP && !NETSTANDARD2_1_OR_GREATER

/// <summary>Specifies that null is allowed as an input even if the corresponding type disallows it.</summary>
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)]
Expand Down
Loading