And why is it a problem?
As I said, it looks like it is inconsistent by itself. But I did not stumble on this issue on purpose.
In the game I am working on, during the processEvent phase, I forward every event (except sf::Event::Closed and sf::Event::Resized) to every object that is supposed to be interested. Inside the object, for each type of event, I retrieve useful information from the event. Eg. for sf::Event::MouseEntered:
const auto& mousePosition = renderWindow.mapPixelToCoords(sf::Mouse::getPosition(renderWindow));
This information is immediately copied into the target of a std::function, that is to be executed later on, typically during the update phase. Eg.:
pendingUpdate = [this, mousePosition] ()
{
updateHovered(mousePosition);
};
In the case of sf::Event::MouseEntered being fired first, the function updateHovered() does not work properly, ie. the object is not hovered despite the mouse being on top of it when that is the case after window resizing.
I did additional tests, to print the value of sf::Mouse::getPosition(renderWindow) for each event:
- When sf::Event::Resized is fired first, sf::Mouse::getPosition(renderWindow) gives the new value immediately, which is correct.
- When sf::Event::MouseEntered is fired first, sf::Mouse::getPosition(renderWindow) gives the new value immediately as well (before sf::Event::Resized being polled). This looks fine because another value would make no sense. But at this point, this value is mapPixelToCoords’ed, which stores coordinates relative to the old window size, ie. x and y are unchanged after mapPixelToCoords(), like they would be with the old window state (view not stretched). So there is a mix of the old and the new happening here, which is not a good thing.
I hope I am clear enough; I can provide a full use case with figures if there is a need for a better explanation.
Btw I forgot to mention my environment in the OP: Debian GNU/Linux 8 amd64.
Updated code to check the explained behaviour:
#include <iostream>
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow renderWindow(sf::VideoMode(800, 700), "Test event Resized");
renderWindow.setFramerateLimit(60);
std::cout << "[init] renderWindow.getPosition(): " << renderWindow.getPosition().x << ", " << renderWindow.getPosition().y << std::endl;
while (renderWindow.isOpen())
{
sf::Event event;
while (renderWindow.pollEvent(event))
{
std::cout << "event.type = " << event.type << std::endl;
std::cout << "sf::Mouse::getPosition(renderWindow) = " << sf::Mouse::getPosition(renderWindow).x << ", " << sf::Mouse::getPosition(renderWindow).y << std::endl;
switch (event.type)
{
case sf::Event::Closed :
{
renderWindow.close();
}
break;
case sf::Event::Resized :
{
std::cout << "[sf::Event::Resized] renderWindow.getPosition() = " << renderWindow.getPosition().x << ", " << renderWindow.getPosition().y << std::endl;
}
break;
case sf::Event::GainedFocus :
{
std::cout << "[sf::Event::GainedFocus] renderWindow.getPosition() = " << renderWindow.getPosition().x << ", " << renderWindow.getPosition().y << std::endl;
}
break;
case sf::Event::MouseEntered :
{
std::cout << "[sf::Event::MouseEntered] renderWindow.getPosition() = " << renderWindow.getPosition().x << ", " << renderWindow.getPosition().y << std::endl;
std::cout << "[sf::Event::MouseEntered] renderWindow.mapPixelToCoords(sf::Mouse::getPosition(renderWindow)) = " << renderWindow.mapPixelToCoords(sf::Mouse::getPosition(renderWindow)).x << ", " << renderWindow.mapPixelToCoords(sf::Mouse::getPosition(renderWindow)).y << std::endl;
}
break;
default :
break;
}
}
renderWindow.clear();
renderWindow.display();
}
return 0;
}