GLFW multiple windows and mouse (how to detect window under mouse)

I create multiple windowing system with GLFW and I manage mouse with focus on window. That means, if window is focused, then only this window receive mouse. But there is problem, when some window is closed, user must 2x click, once to focus window to start interact with it and second for desired action. Therefore I looking for new ideas, how to detect with mouse when I am under some window and not interac it with others?

If I don’t use focus on window, then window which is under another window, both windows receive mouse and click etc…

I found in documentatin glfwSetCursorEnterCallback() and cursor_callback(GLFWwindow * window, int entered); what is I am looking for, but problem is, as for all glfwCallbacks, functions must be static. And this leads to crash when there is more than one window.

It is possible use non static member function for glfwCursor? Or how to not crash program?

Here is my code:
(RenderFunction)

if (m_b_TargetTrue == true)
	{
		m_staticWindow = this;
		m_NSxmlView->MouseMove((NsInt)m_dMouseX, (NsInt)m_dMouseY);
		if (m_b_MoveWindow == true)
		{
			m_func_SetWindowPosition();
		}
	}
void wGWindow::m_func_CursosEnterCallback(GLFWwindow * window, int enter) // static
{
	if (enter)
{
	//m_staticWindow->m_b_TargetTrue = true; // it doesn't matter if this is only used or code below
	size_t size = MyDelegate::m_WindowSystem->m_func_GetNumbersOfWindows();
	for (size_t i = 0; i < size; i++)
	{
		if (window == MyDelegate::m_WindowSystem->m_func_GetWindow(i))
		{
			MyDelegate::m_WindowSystem->m_func_SetWindowSelected(i, true); // set m_b_TargetTrue = true
			break;
		}
	}
}
else
{
	size_t size = MyDelegate::m_WindowSystem->m_func_GetNumbersOfWindows();
	for (size_t i = 0; i < size; i++)
	{
		if (window == MyDelegate::m_WindowSystem->m_func_GetWindow(i))
		{
			MyDelegate::m_WindowSystem->m_func_SetWindowSelected(i, false); // set m_b_TargetTrue = false
			break;
		}
	}
}

}

The callback function passes the window pointer to your function. You can use this to call the appropriate member function. One approach would be to use a map of window pointer to your class pointer.

That’s what I am doing in my Callback function.
But I discover solution.
I used list and list iterator for selecting window, I am using it for rendering window too, and that was produce crash.
Instead use member iterator I create new in function and now it is working.

void  wGWindowSystem::m_func_SetWindowSelected(const size_t &n, const bool &b)
{
	std::list<wGWindow *>::iterator listWindowIterator; // use this instead member listWindowIterator
	listWindowIterator = m_listWindow.begin();
	std::advance(listWindowIterator, n);
	listWindowIterator._Ptr->_Myval->m_func_SetTarget(b);
}

You don’t need to maintain extra list for mapping glfw windows to your window objects. GLFW can do that for you with user data pointer in glfw window: http://www.glfw.org/docs/latest/window_guide.html#window_userptr

Here’s an example:

class MyWindow
{
public:
    MyWindow()
    {
        mWindow = glfwCreateWindow( ... );
        // now associate "this" object with mWindow object
        glfwSetWindowUserPointer(mWindow, this);
        // this will make glfw to call static onCursorEnter method
        glfwSetCursorEnterCallback(mWindow, onCursorEnter);
    }

     // non-static method    
    void onCursorEnter(bool entered)
    {
        // ...
    }

private:
    GLFWwindow* mWindow;

    // glfw callback which will forward call to object instance
    static void onCursorEnter(GLFWwindow* window, int entered)
    {
        // retrieve MyWindow object from glfw window
        MyWindow* self = (MyWindow*)glfwGetWindowUserPointer(window);
        self->onCursorEnter(entered != GLFW_FALSE);
    }
};

Btw, if you use std::list, never ever access its private members.
Instead of code like this:

listWindowIterator._Ptr->_Myval->m_func_SetTarget(b);

you need to write following code:

(*listWindowIterator)->m_func_SetTarget(b);

Everything that begins with underscore is private in STL.

1 Like

Thanks mmozeiko. I use list window for rendering all windows, but your solution with glfwSetWindowUserPointer is good and thanks for stl warning.