Mouse is lost when break point is hit (linux, glfw 3.3.7)

Hello,

On my up-to-date Archlinux system I am developing an OpenGL application in C++ and I am using GLFW for the window stuff. For different reasons I would like to disable the cursor with

glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);

My problem is that it makes debugging almost impossible, because when the execution is paused, my cursor is still “lost”. My question is similar to this one: https://github.com/glfw/glfw/issues/530, the difference is that when the breakpoint is hit, and I alt+tab to e.g. my browser I still don’t have the mouse.
I discovered that after calling glfwPollEvents() I am getting back the cursor. (however if my app crashed I cannot continue debugging to reach to the next call of glfwPollEvents)

I created an example app to demonstrate it (it is mostly a copy from learnopengl.com)

#include <glad/glad.h>
#include <GLFW/glfw3.h>

#include <iostream>

void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow *window);

const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;

int main()
{
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
    if (!window)
    {
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

    glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); 

    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        std::cout << "Failed to initialize GLAD" << std::endl;
        return -1;
    }

    while (!glfwWindowShouldClose(window))
    {
        processInput(window);

        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        glfwSwapBuffers(window);
        glfwPollEvents();

        static int j = 0; // <--------------- add breakpoint here
        if (j == 10)
        {
            std::cout << "10!" << std::endl;  // <----- or here
        }
        std::cout << j++ << std::endl;
    }

    glfwTerminate();
    return 0;
}

void processInput(GLFWwindow *window)
{
    if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
        glfwSetWindowShouldClose(window, true);
}

void framebuffer_size_callback(GLFWwindow* /*window*/, int width, int height)
{
    glViewport(0, 0, width, height);
}

I reproduced it with different Desktop Environments, window managers like: LXDE, LxQt, XFCE, Budgie, with the same result.
Also I tested it with different versions of GLFW (3.3.4, 3.3.7).

So in short: if the execution is stopped (breakpoint or crash) my mouse is lost, so it is almost impossible to debug the app.
Any idea? I think this is a bug. Do you agree?
Thanks

According to my understanding all grabs for a client are automatically terminated when a client exits.

So in your case I’m guessing this only occurs when execution is stopped in the debugger - i.e. a breakpoint is hit, the app is paused by the debugger, or an exception is triggered (crash) which is intercepted by the debugger and the app is in a paused state.

This is thus exactly the same problem as Cursor isn't restored when breakpoint is hit · Issue #530 · glfw/glfw · GitHub, and only applies when debugging.

In my view the X protocol is at fault here - a grab should be lost when the application looses focus (for example to the debugger). This is what happens on Windows. However on Windows there is another similar problem - fullscreen applications on single monitors become impossible to debug as you can’t return to the debugger and you have to kill the app (which can be hard). These two behaviours are not related to GLFW exclusively as they are OS / display server issues.

Sadly there is no simple robust application level solution to this. It might be possible to get the debugger to run some code to ungrab the cursor on a breakpoint, and for exceptions (crashes) you can catch the signal prior to the debugger and ungrab the cursor (note doing so on Max OS X is hard as you need to work with Mach exceptions, and on Windows use SEH).