Skip to content

Comments

Provide NavigationEventDispatcherOwner for non-android targets#2382

Merged
terrakok merged 18 commits intojb-mainfrom
navevent-int
Sep 10, 2025
Merged

Provide NavigationEventDispatcherOwner for non-android targets#2382
terrakok merged 18 commits intojb-mainfrom
navevent-int

Conversation

@terrakok
Copy link
Member

@terrakok terrakok commented Sep 8, 2025

Suppot the NavigationEventDispatcherOwner for a correct Navigation3 support on non-android targets.

Fixes CMP-7646 Support Navigation 3 for Compose Multiplatform

Testing

Manually checked the demo app

Release Notes

Highlights - Navigation

  • Provide required NavigationEventDispatcherOwner for a correct Navigation3 support.

@terrakok terrakok requested a review from MatkovIvan September 8, 2025 14:59
@MatkovIvan MatkovIvan changed the title Provide NavigationEventDispatcherOwner for non-android targets. Provide NavigationEventDispatcherOwner for non-android targets Sep 8, 2025
@terrakok
Copy link
Member Author

terrakok commented Sep 9, 2025

checked iOS layers with a dialog and a popup. works like a charm

nave.mp4

…lStore and NavigationEventDispatcher owners.

And instead of a new NavigationEventDispatcher in the UIKitComposeSceneLayer, a new UIKitNavigationEventInput is used
…ationEvent` and `NavigationEventHandler`. Remove unused dependencies and dump API.
Copy link
Member

@MatkovIvan MatkovIvan left a comment

Choose a reason for hiding this comment

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

Revert experimental annotations. Removing it means stabilization that we do not want to

@terrakok terrakok requested a review from MatkovIvan September 10, 2025 11:58
Copy link
Member

@MatkovIvan MatkovIvan left a comment

Choose a reason for hiding this comment

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

LGTM in general, but let's add proper metadata in depracation annotations to help with migration

import androidx.compose.ui.ExperimentalComposeUiApi
import kotlinx.coroutines.flow.Flow

@Deprecated("Use NavigationEventHandler instead")
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
@Deprecated("Use NavigationEventHandler instead")
@Deprecated(
message = "Use a {@link androidx.navigationevent.compose.NavigationEventHandler} instead",
replaceWith = ReplaceWith(
expression = "NavigationEventHandler(enabled, onBack)",
imports = arrayOf("androidx.navigationevent.compose.NavigationEventHandler"),
),
level = DeprecationLevel.WARNING, // TODO: Replace to ERROR in 1.11
)

Copy link
Member Author

Choose a reason for hiding this comment

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

KTIJ-35595 ReplaceWith works wrong with expect/actual and default arguments

@terrakok terrakok requested a review from ASalavei September 10, 2025 13:34
import androidx.navigationevent.NavigationEventDispatcherOwner

internal class IOSLifecycleOwner: LifecycleOwner, ViewModelStoreOwner {
internal class UIKitArchitectureComponentsOwner :

Choose a reason for hiding this comment

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

I'm not happy with the idea to put everything in a single class by the criteria that they are Owners interfaces.
Also, ViewModelStore placed here incorrectly. ViewModelStoreOwner and NavigationEventDispatcher should be implemented by the separate instances - either that can be separate classes or anonymous object.
It's up to you - you can do it in the current MR, or I'll fix it by myself later.

Copy link
Member Author

Choose a reason for hiding this comment

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

Since I've already refactored this part of the code let's give it to you. ok? I have no strict preferences here but it seems logical though because on other platforms we have these interfaces in a single place

@terrakok terrakok requested a review from ASalavei September 10, 2025 14:01
content = content
)
) {
val navigationEventDispatcherOwner = LocalInternalNavigationEventDispatcherOwner.current
Copy link

@ASalavei ASalavei Sep 10, 2025

Choose a reason for hiding this comment

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

Two different approaches where used in ComposeHostingViewController and here. Either this code should be used in ComposeSceneMediator once or it's looks like the optimal solution will be to:

  • make the navigationEventInput internal
  • Add input at the place where UIKitComposeSceneLayer is created
  • use onClose callback to remove input

density = rootView.density,
getTopLeftOffsetInWindow = { IntOffset.Zero } //full screen
)
).also { eventInput -> archComponentsOwner.navigationEventDispatcher.addInput(eventInput) }

Choose a reason for hiding this comment

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

The eventInput added here never removes. It should not be a big issue since navigationEventDispatcher and eventInput have the same lifetime, but it would be better to add event input in the viewControllerDidEnterWindowHierarchy and remove in viewControllerDidLeaveWindowHierarchy

@terrakok terrakok merged commit a428770 into jb-main Sep 10, 2025
10 checks passed
@terrakok terrakok deleted the navevent-int branch September 10, 2025 15:14
api(project(":compose:ui:ui-text"))
api(libs.skikoCommon)
implementation(libs.atomicFu)
implementation(project(":compose:ui:ui-backhandler"))
Copy link
Collaborator

@igordmn igordmn Oct 1, 2025

Choose a reason for hiding this comment

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

This probably broke backward compatibility for klibs due to KT-60874 [KLIB Resolve] Don't save transitive dependencies in manifest's depends property.

Please fix it before beta01, creating a stub project for backhandler

Copy link
Member

Choose a reason for hiding this comment

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

creating a stub project for backhandler

the project is still here and contains valid code. What's required is only restoring this dependency

Copy link
Member Author

Choose a reason for hiding this comment

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


* What went wrong:
Circular dependency between the following tasks:
:navigationevent:navigationevent-compose:compileDesktopMainJava
+--- :navigationevent:navigationevent-compose:compileKotlinDesktop
|    \--- :compose:ui:ui:desktopJar
|         +--- :compose:ui:ui:compileDesktopMainJava
|         |    +--- :compose:ui:ui:compileKotlinDesktop
|         |    |    \--- :compose:ui:ui-backhandler:desktopJar
|         |    |         +--- :compose:ui:ui-backhandler:compileDesktopMainJava
|         |    |         |    +--- :navigationevent:navigationevent-compose:desktopJar

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'll try to use a non-compose library then

Copy link
Member Author

Choose a reason for hiding this comment

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants