SFML community forums

Help => Window => Topic started by: AdrianM on December 06, 2010, 12:31:14 pm

Title: [MAC OS X - SFML2] GetMouseX() after SetCursorPosition(x,y)
Post by: AdrianM on December 06, 2010, 12:31:14 pm
This example won't output 400,300 after pressing 's'. Why is that? What is the correct way of doing it?

Code: [Select]

////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Graphics.hpp>
#include <map>
#include <math.h>



////////////////////////////////////////////////////////////
/// Entry point of application
///
/// \return Application exit code
///
////////////////////////////////////////////////////////////
int main()
{    
    // Create the main window
    sf::RenderWindow window(sf::VideoMode(800, 600), "SFML Shader");
   
    // Create a clock to measure the total time elapsed
    sf::Clock clock;
   
    // Start the game loop
    while (window.IsOpened())
    {
        // Process events
        sf::Event event;
        while (window.GetEvent(event))
        {
            // Close window : exit
            if (event.Type == sf::Event::Closed)
                window.Close();

            if (event.Type == sf::Event::KeyPressed)
            {
                // Escape key : exit
                if (event.Key.Code == sf::Key::Escape)
                    window.Close();

                if (event.Key.Code == sf::Key::S)
                {
                    window.SetCursorPosition(400, 300);
                    printf("%d %d\n", window.GetInput().GetMouseX(), window.GetInput().GetMouseY());
                }
            }

            if (event.Type == sf::Event::MouseMoved)
            {
                printf("%d %d\n", event.MouseMove.X, event.MouseMove.Y);
            }
        }

        // Finally, display the rendered frame on screen
        window.Display();
    }
   
    return EXIT_SUCCESS;
}
Title: [MAC OS X - SFML2] GetMouseX() after SetCursorPosition(x,y)
Post by: Laurent on December 06, 2010, 12:53:48 pm
The input object of the window is not notified instantly, you may have to wait for the next iteration until you see the new mouse coordinates.
Title: [MAC OS X - SFML2] GetMouseX() after SetCursorPosition(x,y)
Post by: AdrianM on December 06, 2010, 01:05:00 pm
Is there a way to force an iteration? Or is there a way to get the cursor coordinates updated so i don't wait for another iteration?

Also, an iteration should happen really fast so i think i might get away with not needing an instant update, but this code won't constantly print 400 300 after pressing 's'. Am i doing something wrong here?



Code: [Select]

////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Graphics.hpp>
#include <map>
#include <math.h>



////////////////////////////////////////////////////////////
/// Entry point of application
///
/// \return Application exit code
///
////////////////////////////////////////////////////////////
int main()
{    
    // Create the main window
    sf::RenderWindow window(sf::VideoMode(800, 600), "SFML Shader");
   
    // Create a clock to measure the total time elapsed
    sf::Clock clock;
   
    // Start the game loop
    while (window.IsOpened())
    {
        // Process events
        sf::Event event;
        while (window.GetEvent(event))
        {
            // Close window : exit
            if (event.Type == sf::Event::Closed)
                window.Close();

            if (event.Type == sf::Event::KeyPressed)
            {
                // Escape key : exit
                if (event.Key.Code == sf::Key::Escape)
                    window.Close();

                if (event.Key.Code == sf::Key::S)
                {
                    window.SetCursorPosition(400, 300);
                    printf("%d %d\n", window.GetInput().GetMouseX(), window.GetInput().GetMouseY());
                }
            }

            if (event.Type == sf::Event::MouseMoved)
            {
                printf("%d %d\n", event.MouseMove.X, event.MouseMove.Y);
            }
        }

    printf("%d %d\n", window.GetInput().GetMouseX(), window.GetInput().GetMouseY());

        // Finally, display the rendered frame on screen
        window.Display();
    }
   
    return EXIT_SUCCESS;
}
Title: [MAC OS X - SFML2] GetMouseX() after SetCursorPosition(x,y)
Post by: Laurent on December 06, 2010, 01:32:04 pm
What does it print?

And please fix your indentation, your code is hard to read.
Title: [MAC OS X - SFML2] GetMouseX() after SetCursorPosition(x,y)
Post by: AdrianM on December 06, 2010, 01:42:10 pm
Sorry for the indentation, it's fixed now. The code outputs the last position  the mouse was at, before calling window.SetCursorPosition.
Title: [MAC OS X - SFML2] GetMouseX() after SetCursorPosition(x,y)
Post by: Laurent on December 06, 2010, 02:14:28 pm
This is probably specific to OS X. I tried to look at the code, but I can't even find where events are handled :D

So you'll have to wait for Hiura's answer.
Title: [MAC OS X - SFML2] GetMouseX() after SetCursorPosition(x,y)
Post by: AdrianM on December 06, 2010, 02:16:58 pm
Okay, looking forward to hearing from Hiura then! Thanks for your help!
Title: [MAC OS X - SFML2] GetMouseX() after SetCursorPosition(x,y)
Post by: Laurent on December 06, 2010, 02:21:23 pm
Quote
I can't even find where events are handled

My working copy was not up-to-date at all, sorry. Anyway I still can't answer the question.

Note for Hiura: basically we need to know if CGDisplayMoveCursorToPoint generates a MouseMoved event.
Title: [MAC OS X - SFML2] GetMouseX() after SetCursorPosition(x,y)
Post by: Hiura on December 06, 2010, 07:25:34 pm
Well, Laurent, you do all the work for me! Thanks  :D

Will be fix ASAP (very likely on Thursday).
Title: [MAC OS X - SFML2] GetMouseX() after SetCursorPosition(x,y)
Post by: AdrianM on December 09, 2010, 02:39:44 pm
Any news on this fix? I really need it :D
Title: [MAC OS X - SFML2] GetMouseX() after SetCursorPosition(x,y)
Post by: Hiura on December 09, 2010, 03:34:12 pm
Sorry, you have to wait until tomorrow at least. I've got a huge homework assignment due this evening so... arghhh... ^^'
Title: [MAC OS X - SFML2] GetMouseX() after SetCursorPosition(x,y)
Post by: Hiura on December 10, 2010, 09:33:07 am
I spot another potential problem. Laurent, what is the desired behaviour of the mouse position before any mouse move event ? Currently in my implementation the first pos is (0,0). Is it the same on win/unix ?
Title: [MAC OS X - SFML2] GetMouseX() after SetCursorPosition(x,y)
Post by: Laurent on December 10, 2010, 10:44:30 am
What do you mean? The cursor is where it is ;) and the mouse position stored in sf::Input is (0, 0). There's nothing related to the platform-specific implementation.
Title: [MAC OS X - SFML2] GetMouseX() after SetCursorPosition(x,y)
Post by: Hiura on December 10, 2010, 01:47:02 pm
Code: [Select]
#include <SFML/Graphics.hpp>
#include <iostream>
int main()
{
sf::RenderWindow window(sf::VideoMode(800, 600), "SFML event check");
while (window.IsOpened())
{
sf::Event event;
while (window.GetEvent(event))
{
if (event.Type == sf::Event::Closed)
window.Close();

if (event.Type == sf::Event::KeyPressed)
{
if (event.Key.Code == sf::Key::Escape) {
window.Close();
}

if (event.Key.Code == sf::Key::C) {
std::cout << "mouse @(" << window.GetInput().GetMouseX() << "," << window.GetInput().GetMouseY() << ")" << std::endl;
}
}

if (event.Type == sf::Event::MouseMoved)
{
std::cout << event.MouseMove.X << " " << event.MouseMove.Y << std::endl;
}
}

window.Clear();
window.Display();
}

return EXIT_SUCCESS;
}

For example if I run that kind of program and I never move my cursor and press C I get
Code: [Select]
mouse @(0,0)
wherever the cursor really is. (But if I move it at least once, I get MouseMoved event and then the cursor pos is correct.)

Am I wrong if I say this is NOT what you want ?
Title: [MAC OS X - SFML2] GetMouseX() after SetCursorPosition(x,y)
Post by: Laurent on December 10, 2010, 02:29:13 pm
That's what I meant:
Quote
the mouse position stored in sf::Input is (0, 0)

As sf::Input is based on events, we can't have anything else by default. There's no function in SFML to retrieve the cursor position directly from the OS, everything is based on events.
Title: [MAC OS X - SFML2] GetMouseX() after SetCursorPosition(x,y)
Post by: Hiura on December 10, 2010, 03:34:20 pm
You don't plan to change this behaviour, do you ?

If you do plan to modify this I've got an idea (meanly inspired by some code pattern I've seen in obj-c).

BTW, I've committed a fix for the original bug.  :wink:
Title: [MAC OS X - SFML2] GetMouseX() after SetCursorPosition(x,y)
Post by: Laurent on December 10, 2010, 03:56:43 pm
Quote
You don't plan to change this behaviour, do you ?

No, unless I decide to plug sf::Input to the OS rather than to sf::Event. This is in the task list but I don't think that I'll do it, actually.

Quote
If you do plan to modify this I've got an idea (meanly inspired by some code pattern I've seen in obj-c).

Do we really need an "idea"? Calling the GetCursorPos() function of the OS API should be enough ;)
Title: [MAC OS X - SFML2] GetMouseX() after SetCursorPosition(x,y)
Post by: Hiura on December 10, 2010, 04:06:36 pm
In fact, I wasn't thinking about Input class at all.

We could have in Window class something like a friend method with our WindowImpl and when we ask for a new WindowImpl, we give as parameter a Window such that the WindowImpl could call the friend method to set the initial cursor pos.

However, it may look a little bit overkill compared to calling the GetCursorPos() function inside Input... At least all the OS-impl is in the same place. :roll: