def _under_pointer(self) -> tuple[window.WindowType, Surface | None, float, float] | None:
        """
        Find which window and surface is currently under the pointer, if any.
        """
        # Warning: this method is a bit difficult to follow and has liberal use of
        # typing.cast. Make sure you're familiar with how the scene-graph tree is laid
        # out (see diagram in __init__ above).
        assert self.qtile is not None

        maybe_node = self.windows_tree.node.node_at(self.cursor.x, self.cursor.y)
        if maybe_node is None:
            # We didn't find any node, so there is no window under the pointer.
            return None

        node, sx, sy = maybe_node

        if node.type == SceneNodeType.BUFFER:
            # Buffer nodes can be any surface or subsurface (nested in subtrees) of a
            # client or Internal window. In all cases we will get a wlr_scene_buffer,
            # but only client surfaces will have a wlr_scene_surface.
            scene_buffer = cast(SceneBuffer, SceneBuffer.from_node(node))

            if scene_surface := SceneSurface.from_buffer(scene_buffer):
                # We got a node that is part of a window, walk up the scene graph to
                # find the window object. It could also be an XDG popup, which can be
                # the child of either an XDG window or a layer shell window.
                win = self.win_from_node(node)
                return win, scene_surface.surface, sx, sy

            # We didn't get a wlr_scene_surface, so we're dealing with an internal window
            # Internal windows have a scenetree for borders. The parent's data we will use to cast to an internal window
            parent_tree = cast(SceneTree, node.parent)
            win = cast(window.Internal, parent_tree.node.data)
            return win, None, sx, sy

        if node.type == SceneNodeType.RECT:
            # Rect nodes are only used for window borders. Their immediate parent is the
            # window container, which gives us the window at .data.
            # We have to differentiate between internal windows and normal windows
            parent_tree = cast(SceneTree, node.parent)
            if isinstance(parent_tree.node.data, window.Internal):
                win = cast(window.Internal, parent_tree.node.data)
            else:
                win = cast(window.Window, parent_tree.node.data)
            return win, None, sx, sy

        logger.warning("Couldn't determine what was under the pointer. Please report.")
        return None

        Find which window and surface is currently under the pointer, if any.
        
libqtile/backend/wayland/core.py