Advertisement

Debugging GLFW application with GLFW_CURSOR_DISABLED

Started by January 29, 2022 10:17 PM
16 comments, last by thamas_bacsi 2 years, 6 months ago

I'm glad you found a solution.

I suggest that you report the bug to LXDE, if they aren't aware of it yet.

Hmm, I have to “reopen” this thread, because now I have the same behavior with XFCE as well.

So I start my app in windowed mode and I can alt+tab to switch to a different window in this case I get back my mouse pointer, however if while I am debugging my application, a break point is hit my pointer is “lost”, not just in the IDE, but even after I alt+tab I don't get it back.

However I discovered that if it is not an exception (crash) but the program is stopped because of a breakpoint then if I hit “continue” then as soon as glfwPollEvents() is called I get back my pointer.

Of course If the app stops because of an hw exception, segfault, etc then I can not simply iterate the main loop.

Maybe I will write a small example to share it with you to be able to demonstrate it.

Few additional notes:

  • I tried with LXDE, LXQT, XFCE, and Budgie with the same results
  • I tried to debug with my IDE (QtCreator) and from CLI with gdb, I received the same results
Advertisement

Below I created an example (mainly a copy paste 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); //GLFW_CURSOR_NORMAL); // 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
        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);
}

If I put a break point in the line

static int j = 0;

Then even after alt+tab I don't get back my pointer.

Any idea?

Could some please try to reproduce it on his / her linux machine?

Thanks.

Mod.

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

The same happens if I add breakpoint to line “std::cout << "10!" << std::endl; // <----- or here” instead. But again after hitting “ glfwPollEvents(); ” in the next iteration gives back the mouse pointer.

Your GLFW application and your debugger are separate applications I hope (that is, your debugger is not sharing or inheriting settings of the GLFW program?)

If not separate, then basically you have a fight within the same application (but apparently different windows?) for having or not having a mouse. Not sure that is supported at all, but that's the core question to answer then, I think. If the answer is yes, then the next question is how (probably).

If they are different applications (ie not sharing/inheriting settings) you have a fight between two applications at the desktop for the mouse. Likely your changes are better in this case at first sight, but not sure.

EDIT: So how is a third independent application, like a text-editor window behaving? Does it show the same symptoms? That may shed some light on what is happening perhaps.

Either way, you need to discuss this with some linux desktop experts. While you can do that here, I don't think there are many Linux desktop internals developers here.You may have much better luck elsewhere is my guess.

Hi Albert, thanks for your thoughts!

The behavior is the same for every 3rd application like browser, text-editor, etc.

My app and the debugger does not share settings I think (but to be honest I don't fully understand your question there).

You are right, maybe it is a more linux related question, maybe I should ask it in a glfw forum. (Earlier I asked it in stackoverflow, without any success.)

thamas_bacsi said:
You are right, maybe it is a more linux related question, maybe I should ask it in a glfw forum

GLFW has a scope of “application”.

It would seem weird to me if application A could break application B, no matter what application A is doing or not doing (except for edge cases like killing application B because A has root access or because A and B are tightly connected in some way).

If other completely unrelated applications have the same behavior as you say, it looks like a desktop-scope problem to me (ie between independent applications). I mean, the window manager of the desktop should be responsible for handling mouse/keyboard/video/etc such that each application gets what it wants would be my first guess. If that doesn't happen (like it does in your case), then either what you want isn't supported or the manager is broken. Given that it happens with different desktop managers, the latter becomes less likely of course.

EDIT: So, rather than GLFW, I'd look for the cause in LXDE, LXQT, XFCE, and Budgie, etc. Did you try finding other similar cases? I wouldn't be surprised if the problem is not specific to GLFW. I also wouldn't be surprised if the problem is known in GDB forums. They may even have a work-around for it.

-----

As a different direction (besides remote debugging, although it looks like you'd need 2 physical computers connected with each other to get that running), did you consider the impact of not disabling the mouse while debugging? Maybe you need to rewrite some code or add some new functions, but that may be simpler than trying to get to the bottom of the above problem. Window managing has stopped being simple a long time ago.

Advertisement

@Alberth

“did you consider the impact of not disabling the mouse while debugging?”

Yes, this is what I am doing now to be able to debug, however in my windowed app this means I can not turn (e.g) left that much (when the mouse leaves the window), so this is not the best solution but this way I can get at least debugging.

Note. Now I can confirm that this issue has nothing to do with GLFW. I created an SDL app (copied from https://lazyfoo.net/tutorials/SDL/03_event_driven_programming/index.php)​ removed the image thing and added mouse capture in it (SDL_SetRelativeMouseMode(SDL_TRUE);) and now I have the same issue with it.

#include <SDL.h>
#include <stdio.h>

//Screen dimension constants
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;

//Starts up SDL and creates window
bool init();

//Loads media
bool loadMedia();

//Frees media and shuts down SDL
void close();

//The window we'll be rendering to
SDL_Window* gWindow = NULL;

//The surface contained by the window
SDL_Surface* gScreenSurface = NULL;

//The image we will load and show on the screen
SDL_Surface* gXOut = NULL;

bool init()
{
   //Initialization flag
   bool success = true;

   //Initialize SDL
   if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
   {
      printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() );
      success = false;
   }
   else
   {
      //Create window
      gWindow = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN );
      if( gWindow == NULL )
      {
         printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() );
         success = false;
      }
      else
      {
         //Get window surface
         gScreenSurface = SDL_GetWindowSurface( gWindow );
      }
   }

   return success;
}

void close()
{ 
   //Destroy window
   SDL_DestroyWindow( gWindow );
   gWindow = NULL;

   //Quit SDL subsystems
   SDL_Quit();
}

int main()
{
   //Start up SDL and create window
   if( !init() )
   {
      printf( "Failed to initialize!\n" );
   }
   else
   {
      SDL_SetRelativeMouseMode(SDL_TRUE);
      //Main loop flag
      bool quit = false;

      //Event handler
      SDL_Event e;

      //While application is running
      while( !quit )
      {
         //Handle events on queue
         while( SDL_PollEvent( &e ) != 0 )
         {
            //User requests quit
            if( e.type == SDL_QUIT )
            {
               quit = true;
            }
         }

         //Update the surface
         SDL_UpdateWindowSurface( gWindow );
      }
   }

   //Free resources and close SDL
   close();

   return 0;

So you were right, this issue must be linux, window handling, etc specific.

(I also installed KDE Desktop Environment, same behavior with that too.)

Thanks for your help!

This topic is closed to new replies.

Advertisement