Accept-Language headers aren't used in a particularly good way by browsers and servers. If used better, they would be a particularly good solution.
The idea you mentioned of browsers allowing the header to be set on a per-site basis would be particularly good.
Another very good solution would be for servers to assign weight to the languages they support, and to combine their weights with the Accept-Language weights to choose the best language in common.
But even as they're implemented and used now, Accept-Language headers are already a way better approach than geo-ip.
The idea you mentioned of browsers allowing the header to be set on a per-site basis would be particularly good.
Another very good solution would be for servers to assign weight to the languages they support, and to combine their weights with the Accept-Language weights to choose the best language in common.
But even as they're implemented and used now, Accept-Language headers are already a way better approach than geo-ip.