Search code examples
c++sfmlcpu-usage

Sfml lostFocus / gainedFocus cpu usage


Why when I run this simple code and just doing nothing CPU usage by this app is around 0.4%

#include <SFML/Graphics.hpp>

int main()
{
    sf::RenderWindow window(sf::VideoMode(800, 800), "hi", sf::Style::Close | sf::Style::Titlebar);
    window.setFramerateLimit(60);
    sf::Event event;

    bool lostFocus = false;

    while (window.isOpen())
    {
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
            else if (event.type == sf::Event::LostFocus)
                lostFocus = true;
            else if (event.type == sf::Event::GainedFocus)
                lostFocus = false;
        }
        if (!lostFocus)
        {
            window.clear(sf::Color::White);
            window.display();
        }
    }
}

But when I click on other app, CPU usage by this app increases to 12%.
Does GainedFocus actually eat so much cpu power or what?
(I just wanted to make a simple pause of game and saw this cpu usage)


Solution

  • As already mentioned, when your window doesn't have focus and you're not updating the window, the loop goes into a hot spin where it's continuously checking for events. When you've lost focus, you instead want to block and wait for a GainedFocus event to occur. As a very simple example, you could do something like

    void block_until_gained_focus(sf::Window& window) {
        sf::Event event;
        while (true) {
            if (window.waitEvent(event) && event.type == sf::Event::GainedFocus) {
                return;
            }
        }
    }
    

    Then your main game loop could look something like

    while (window.isOpen())
    {
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
            else if (event.type == sf::Event::LostFocus)
                wait_until_gained_focus(window);
        }
        window.clear(sf::Color::White);
        window.display();
    }
    

    Now if you wanted to do additional work while focus is lost you'll need a different implementation, but the key here is to use waitEvent instead of pollEvent.