Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Controlling focus with multiple windows  (Read 471 times)

0 Members and 1 Guest are viewing this topic.

shawrie777

  • Newbie
  • *
  • Posts: 2
    • View Profile
Controlling focus with multiple windows
« on: May 01, 2020, 11:20:33 am »
Hi

I've created a fairly simple program to play a game, and when the player clicks to start a new game a second window pops up to let them choose options. The problem is that they can still click on and switch focus to the first window. How can I force focus to the second window until they've chosen? Note I'm not intending them to be unable to switch program, just between the windows of the program.

Thanks

Hapax

  • Hero Member
  • *****
  • Posts: 2999
  • My number of posts is shown in hexadecimal.
    • View Profile
Re: Controlling focus with multiple windows
« Reply #1 on: May 01, 2020, 06:18:05 pm »
A modal window? 8)

You could check events in the new window to see if it loses focus and if it does, request the focus again.
If you use this approach, I would suggest that you make sure it's only taking focus from your first window otherwise other programs/your operating system may have trouble.
Selba Ward - SFML drawables
Kairos - Timing Library
Rectangular Boundary Collision - Rectangular SAT Collision

@Hapaxiation - Hapaxia on Twitter

shawrie777

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: Controlling focus with multiple windows
« Reply #2 on: May 02, 2020, 01:23:04 pm »
Thanks! I hadn't heard the term modal window before, so didn't know what to search for! You say to check it's taking focus from the other window: does that mean I still need to run its event loop to see if it gained focus?

Hapax

  • Hero Member
  • *****
  • Posts: 2999
  • My number of posts is shown in hexadecimal.
    • View Profile
Re: Controlling focus with multiple windows
« Reply #3 on: May 02, 2020, 05:09:05 pm »
Haven't actually tried this and I'm not certain it's the right approach due to possibly affecting other programs too.

That said, the idea was that the modal window itself checks (it should have its own event loop, right?) to see if it loses focus and then requests focus again.
So, yes, the modal window would always still have its event loop running. The original window should process events too since it will still continue to receive them and may be considered crashed if they aren't processed.
Selba Ward - SFML drawables
Kairos - Timing Library
Rectangular Boundary Collision - Rectangular SAT Collision

@Hapaxiation - Hapaxia on Twitter

LucasM

  • Newbie
  • *
  • Posts: 3
    • View Profile
    • Email
Re: Controlling focus with multiple windows
« Reply #4 on: June 22, 2020, 12:13:24 am »
I figured out some basic code for a modal window loop.  Seemed to work ok, as was trying to figure it out and found this thread.  If it helps?

#include <SFML/Graphics.hpp>

/*
https://stackoverflow.com/questions/26741841/how-does-a-modal-dialogs-message-pump-interact-with-the-main-application-messag
They run on the same thread. The modal dialog spawns a nested message loop.
Both the nested message loop and the main application's message loop (or rather message handlers) are siamese twins in crime:
If one doesn't play by the rules, the respective other will suffer as well. – IInspectable
*/


//call from child
void mainWinMSGHandle(sf::Window &window, sf::Window &child);

void createPopUpWindow(sf::Window *parent, int num)
{
    sf::RenderWindow popUpWindow(sf::VideoMode(320,240), "HI " + std::to_string(num), sf::Style::Close);
    popUpWindow.setPosition(parent->getPosition() + sf::Vector2i(100,100));
    sf::Event event;
    while (popUpWindow.isOpen())
    {
        popUpWindow.clear(sf::Color::Cyan);
        popUpWindow.display();

        while(popUpWindow.pollEvent(event))
     {
        if(event.type == sf::Event::Closed)
            popUpWindow.close();
        if(event.type == sf::Event::LostFocus)
        {
            if(parent->hasFocus())
                popUpWindow.requestFocus();
        }
      }
        mainWinMSGHandle(*parent, popUpWindow);
       
        sf::sleep(sf::milliseconds(1));
    }

}

//child message loop blocking main window message loop so need to handle main from child
void mainWinMSGHandle(sf::Window &window, sf::Window &child)
{
    sf::Event event;
    while(window.pollEvent(event))
    {
    if(event.type == sf::Event::Closed)
    {
        child.close();
        window.close();
    }
    if(event.type == sf::Event::GainedFocus)
    {
        child.requestFocus();
    }
    }
}

int main()
{
    sf::RenderWindow window(sf::VideoMode(800,600),"Main Window");

    sf::Event event;
    int n = 0;

    while (window.isOpen())
    {
        window.clear(sf::Color::Magenta);
        window.display();

        window.waitEvent(event);
       
        if(event.type == sf::Event::Closed)
        {
            window.close();
        }
        if(event.type == sf::Event::MouseButtonPressed)
        {
            createPopUpWindow(&window, n++);
        }
    }

    return 0;
}
 

 

anything