Search results from flutter.dev and Stackoverflow only have words talking about that "The global position at which the pointer contacted the screen.", and "The local position in the coordinate system of the event receiver at which the pointer contacted the screen.". It's not easy to understand but we can easily test it by ourselves. So let's do it.

First I created a board which contains the GestureDetector widget and some other things around it to make sure the position of the GestureDetector widget wasn't just the same as the screen.

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Gestures Test'),
      ),
      body: Column(
        children: [
          Expanded(
            child: Row(
              children: [
                Container(
                  width: 100,
                ),
                Expanded(
                  child: GestureDetector(
                    onPanUpdate: (detail) {
                      print(
                          'Global Position:${detail.globalPosition.dx}, ${detail.globalPosition.dy}');
                      print(
                          'Local Position:${detail.localPosition.dx}, ${detail.localPosition.dy}');
                    },
                    child: Container(
                      width: double.infinity,
                      height: double.infinity,
                      color: Colors.grey,
                      child: Stack(
                        children: [
                          Container(
                            color: Colors.red,
                            width: 12,
                            height: 12,
                          ),
                        ],
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ),
          Container(
            width: 100,
          ),
        ],
      ),
    );
  }
}

Which looks like this:

Then we run it and check the debug console.

Here we can see the local position's dx is smaller than global position's dx, and it's dy is smaller too, which means the axis of the local position is different. It starts from the top-left corner of the grey block.

So if you want to move a child in a Stack, you can wrap the GestureDetector outside of the Stack to get the relative position from the localPosition, then update the left and right parameter of the Position widget.