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

🐛 Can't open a Flyout with a navigatorKey #764

Closed
WinXaito opened this issue Mar 10, 2023 · 3 comments · Fixed by #768
Closed

🐛 Can't open a Flyout with a navigatorKey #764

WinXaito opened this issue Mar 10, 2023 · 3 comments · Fixed by #768
Labels
bug Something isn't working

Comments

@WinXaito
Copy link
Collaborator

I have a title bar like that:

image

This bar is outside the navigation and global to all page.

For this usage, I asked for #538 (thanks for that @bdlukaa)

After the upgrade of fluent_ui (from 4.1.5 to 4.4.1), I'm facing the following issue:

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: 'package:flutter/src/rendering/object.dart': Failed assertion: line 2961 pos 14: 'renderer.parent != null': is not true.
#0      _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:51:61)
#1      _AssertionError._throwNew (dart:core-patch/errors_patch.dart:40:5)
#2      RenderObject.getTransformTo (package:flutter/src/rendering/object.dart:2961:14)
#3      RenderBox.localToGlobal (package:flutter/src/rendering/box.dart:2661:39)
#4      FlyoutController.showFlyout (package:fluent_ui/src/controls/flyouts/flyout.dart:569:19)
#5      _ActionState.showMenu (package:dncui/src/controls/core/mw_window_caption.dart:190:16)

The problem is caused by this line (https://github.com/bdlukaa/fluent_ui/blob/master/lib/src/controls/flyouts/flyout.dart#L569 and line 572).

If I comment , ancestor: navigatorBox, that's work !

image

The code for open the flyout:

controller.showFlyout(
      navigatorKey: widget.action.navigationKey,
      builder: widget.action.flyoutBuilder!,
      position: position,
      placementMode: FlyoutPlacementMode.bottomRight,
      margin: 0,
      // additionalOffset: -kWindowCaptionHeight,
);
@WinXaito WinXaito changed the title 🐛 🐛 Can't open a Flyout with a navigatorKey Mar 10, 2023
@bdlukaa bdlukaa added the bug Something isn't working label Mar 13, 2023
@bdlukaa
Copy link
Owner

bdlukaa commented Mar 13, 2023

If ancestor is not provided, the position of the flyout is likely to be incorrect in a nested Navigator context (using go_router's ShellNavigator, for example)

From the documentation of the RenderBox.localToGlobal function:

If ancestor is non-null, this function converts the given point to the coordinate system of ancestor (which must be an ancestor of this render object) instead of to the global coordinate system.

This is what it looks like if the , ancestor: navigatorBox is commented in a nested Navigator context (It uses shellNavigatorKey from the example app):

Expected

image

Actual

image

On the other hand, if the Navigator is not a parent of the Flyout, this error will be thrown (as of renderer.parent != null). I'm not sure that removing the reference to the navigator box is the way to go.

Your code may need to be updated to support a global navigator context

@WinXaito
Copy link
Collaborator Author

WinXaito commented Mar 14, 2023

Yeah, I tried to create a new Navigator on the new tree, but that's not what I want:

image

My tree:

image

The app bar is builded like that:

return FluentApp(
  ...
  builder: (context, child) {
    return CoreView(
      child: child ?? const Text('internal error'),
      ...
    );
  },
);

The appbar is constructed in the CoreView widget, and the content of the page is in the child variable. So, the Navigator is in child and my CoreView widget is not an ancestor of him.

Maybe we can add the possibility to pass a custom navigator ancestor (aka pass à null ancestor, otherwise we use the default navigator key..)

Your code may need to be updated to support a global navigator context

I have one, but because my AppBar is not routed, that doesn't work.. And I don't know how to do that differently.

@WinXaito
Copy link
Collaborator Author

WinXaito commented Mar 14, 2023

In fact, I found the problem.

You calculate the position with the ancestor like that:

    final targetBox = context.findRenderObject() as RenderBox;
    final targetSize = targetBox.size;
    final targetOffset =
        targetBox.localToGlobal(Offset.zero/*, ancestor: navigatorBox*/) +
            Offset(0, targetSize.height);
    final targetRect =
        targetBox.localToGlobal(Offset.zero/*, ancestor: navigatorBox*/) &
            targetSize;

But I give him the position manually, so the position is used like that:

targetOffset: position ?? targetOffset,

Si for resolve this problem, we simply must don't calculate the targetOffset if the position is gave.

If you are ok with that, I will make a PR. - Edit: see #768

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
2 participants