First of all these give you the wrong sizes, just using the frame sizes should be enough (don't add the left/top position to the width/height)
var menu_width = ggui_frame_l[array_l] + ggui_frame_w[array_w]; var menu_height = ggui_frame_t[array_t] + ggui_frame_h[array_h];
I also don't see why you divide the pixel size with the number of elements along the axis, they represent the same ratio if evenly spaced and that means translating between them should "just work". Though you'll need to make sure the output stays in range:
clamp( round((mouse_x - menu_x)/menu_width), 0, menu_w - 1)
(And also note that "If evenly spaced" might cause issues with the more esoteric layouts since nothing forces a menu to actually be evenly spaced, you can place frames anywhere and fill them with whatever you want)
Did you check the code in ggui_draw that draws the rectangle over the currently selected item? It converts from grid coordinates to screen pixel coordinates so it might help a bit here. You could even skip having to do the reverse computation (grid coordinates from screen coordinates) if you loop over all menu options, compute their corresponding frame coordinates (using this code), and then use point_in_rectangle to check if the mouse cursor is over that frame. Slow, but 100% accurate.
(Note that drawmenux/drawmenuy, the scroll offset, are computed at the beginning of the function)