minikin / popover

Popover for Flutter. A popover is a transient view that appears above other content onscreen when you tap a control or in an area.
https://pub.dev/packages/popover
MIT License
166 stars 54 forks source link

Popover is pointing incorrectly #69

Open prateekmedia opened 1 year ago

prateekmedia commented 1 year ago

Describe the bug Whenever I use responsive_framework or add packages like window_manager (for Desktop to add borders in the app window) the popup arrow points incorrectly and to the wrong place (see Screenshot section and Additional context section for problem and possible solution).

To Reproduce Steps to reproduce the behavior:

  1. Add responsive_framework and set it up for rescaling (you can also try in the example of it)
  2. Add popover to a widget
  3. Click on that widget
  4. See that popover is shifted

Expected behavior It should exactly point to the widget.

Screenshots popoverss .

Desktop (please complete the following information):

Smartphone (please complete the following information):

Additional context On the other hand super_tooltip works perfectly and points exactly to the widget, Here is the link where they do the computing. https://github.com/escamoteur/super_tooltip/blob/40ca162d284a6f665880dea03ac28cea3c040966/lib/super_tooltip.dart#L236-L239

minikin commented 1 year ago

@prateekmedia Thank you for the report!

I've never used window_manager or responsive_framework, and more likely, I won't use them soon. So if this issue is vital to you, please feel free to create a PR if you'd like to fix this issue.

prateekmedia commented 1 year ago

Actually this is above those packages, if you see this issue it means its something wrong with how the position is getting calculated and its not something I am experienced with, that's why I attached a reference code of super_tooltip which does this perfectly.

minikin commented 1 year ago

We can keep this issue open until we have more reports like this and someone who wants to volunteer to work on this issue.

socramm9 commented 1 year ago

I am also facing the issue that the Position is wrong calculated on MacOs

iOS:

Bildschirm­foto 2023-04-03 um 23 58 36

MacOs:

Bildschirm­foto 2023-04-03 um 23 59 55
intonarumori commented 1 year ago

I've experienced similar issues and found that the popover is misplaced usually if you provide the wrong context to the showPopover function.

When you have a button to present the popover, it's best to capture the context from the button itself, so when the popover package queries findRenderObject it will find the exact render object that is associated with the pressed widget.

Here's an example how to do that:

class CustomButton extends StatelessWidget {
  final Function(BuildContext context) onPressed;
  const CustomButton({super.key, required this.onPressed});

  @override
  Widget build(BuildContext context) {
    return TextButton(onPressed: () => onPressed(context), child: Text('Some button'));
  }
}

...

class SomeWidget extends StatelessWidget {
  const SomeWidget({super.key});

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        CustomButton(
          onPressed: (context) {
            showPopover(
              context: context,
              bodyBuilder: (context) => Container(color: Colors.red),
              onPop: () => print('Popover was popped!'),
              direction: PopoverDirection.bottom,
              width: 200,
              height: 200,
              arrowHeight: 15,
              arrowWidth: 30,
            );
          },
        )
      ],
    );
  }
}

If I don't do this the source object bounds might be calculated from the parent widget of the button or some other ancestor. Hope this helps.

socramm9 commented 1 year ago

Issue can be also closed from my part I figured out what was the issue.

class MainApp extends StatelessWidget {
  const MainApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      builder: (context, child) {
        return Column(
          children: [
            Container(
              height: 50,
              decoration: BoxDecoration(
                color: Theme.of(context).primaryColor,
              ),
            ),
            Expanded(child: child!),
          ],
        );
      },
      home: const Scaffold(
        body: PopoverTest(),
      ),
    );
  }
}

I was using the builder property from MaterialApp to render a custom Toolbar for my app.

Bildschirmfoto 2023-06-24 um 13 03 12

Moving the Logic away from the builder fixes the issue.

class MainApp extends StatelessWidget {
  const MainApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Column(
        children: [
          Container(
            height: 50,
            decoration: BoxDecoration(
              color: Theme.of(context).primaryColor,
            ),
          ),
          const Expanded(
            child: Scaffold(
              body: PopoverTest(),
            ),
          )
        ],
      ),
    );
  }
}
Bildschirmfoto 2023-06-24 um 13 07 06

This happens because the Popover is build using RawDialogRoute and this route is also affected by my builder.

prateekmedia commented 1 year ago

But many a time builder is required for widgets like BotToast or WindowManager or even ResponsiveFramework

Merrit commented 9 months ago

Same issue, it was pointing at the card parenting my button; I wrapped the button that launches the popover with a Builder to give it a fresh context, now it points directly to the button as expected. :+1:

angelocordero commented 5 months ago

This is not an issue about which context the popover uses. This is an issue about the popover location calculation.

Apparently, the calculations result in incorrect positioning when the parent is scaled, like using responsive_framework or FittedBox