SFML community forums

Help => Window => Topic started by: Hapax on June 11, 2015, 10:57:17 pm

Title: First GainedFocus Event Fails After Recreation Of Window
Post by: Hapax on June 11, 2015, 10:57:17 pm
The window doesn't seem to receive a GainedFocus event if the window is recreated after losing focus.

Here's an example:
#include <SFML/Graphics.hpp>

void createWindow(sf::RenderWindow& window)
{
        window.create(sf::VideoMode(800, 600), "Gained Focus Event Failing", sf::Style::Default);
}
int main()
{
        sf::RenderWindow window;
        createWindow(window);

        sf::Color color{ sf::Color::Green };

        while (window.isOpen())
        {
                sf::Event event;
                while (window.pollEvent(event))
                {
                        if (event.type == sf::Event::Closed || event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape)
                                window.close();
                        else if (event.type == sf::Event::LostFocus)
                        {
                                createWindow(window); // this stops GainedFocus from working
                                color = sf::Color::Red;
                        }
                        else if (event.type == sf::Event::GainedFocus)
                        {
                                //createWindow(window); // this is fine if commented out or not
                                color = sf::Color::Green;
                        }
                }

                window.clear(color);
                window.display();
        }

        return EXIT_SUCCESS;
}

The code changes the window to red when it's not in focus and green when it is in focus.

When the window is recreated after losing focus, when returning focus to the window, it doesn't receive the GainedFocus event and therefore no longer turns green.

In the code, if you comment out the createWindow line (before turning color to red), the event works fine. In addition, if you uncomment the createWindow line (before turning color to green), it makes no difference (lost focus still works immediately). In fact, even after regaining focus but not receiving the GainedFocus event, the window will still receive LostFocus events.

It's obvious that event is still for the correct window as you can still close the window that can't regain focus.


EDIT: Win7, VS2013, SFML2.3 debug and release (32-bit).



EDIT 2: modified thread subject title.
Title: Re: Window's Focus Events Failing After Recreation Of Window
Post by: eXpl0it3r on June 11, 2015, 11:12:52 pm
The title is misleading, because the event keeps working fine, it's just that the first gain event is not triggered. ;)
hasFocus() will also report the focus correctly.

#include <SFML/Graphics.hpp>
#include <iostream>

void createWindow(sf::RenderWindow& window)
{
    window.create(sf::VideoMode(800, 600), "Gained Focus Event Failing", sf::Style::Default);
}
int main()
{
    sf::RenderWindow window;
    createWindow(window);
       
        bool recreated = false;

    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed || event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape)
                window.close();
            else if (event.type == sf::Event::LostFocus)
            {
                std::cout << "LostFocus" << std::endl;
                               
                                if (!recreated)
                                {
                                        recreated = true;
                                        createWindow(window); // this stops GainedFocus from working
                                }
            }
            else if (event.type == sf::Event::GainedFocus)
            {
                //createWindow(window); // this is fine if commented out or not
                std::cout << "GainedFocus" << std::endl;
            }
                        else if (event.type == sf::Event::KeyReleased)
                        {
                                std::cout << "Has focus: " << window.hasFocus() << std::endl;
                               
                                if (event.key.code == sf::Keyboard::Space)
                                        createWindow(window); // this stops GainedFocus from working
                        }
        }

        window.clear();
        window.display();
    }
}

It's quite a corner case and someone will have to look at the underlying code whether this intentional or not. ;)
Title: Re: First GainedFocus Event Fails After Recreation Of Window
Post by: Hapax on June 11, 2015, 11:53:09 pm
I changed the subject to more accurately and concisely reflect the effect.

You're right that it's only the first GainedFocus event as after losing and regaining focus, it's fine. That is, as long as the window is recreated after losing focus again.

As you mention, hasFocus() does report perfectly. Your added key event code, by the way, can only have hasFocus() returning as true since it's checked in the event loop  ;)  It does, of course, prove that the window knows whether or not it has the focus so it's just the GainedFocus event that isn't being available.

It could be possible that this only occurs if the window is recreated while it doesn't have the focus.