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.