Cannot create 24Hz output reliably (OpenGL)

I’m having issues creating a full-screen 24Hz output in Windows 10.
I’ve tried several versions, up to 3.3.4 and they all pretty much do the same thing.

The monitor is already 24Hz in Windows, but when I create the context, it switches to 60Hz.
Sometimes it works (= creates a 24Hz output) and keeps working for a while until it doesn’t. It seems like a reboot is the only way to make it work again.

This is how I create the context:

// .: Set window hints
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);						// OpenGL >= 4.3
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_FALSE);				// To make MacOS happy; should not be needed
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);		// We don't want the old OpenGL
glfwWindowHint(GLFW_DOUBLEBUFFER, GLFW_TRUE);

auto mode = glfwGetVideoMode(glfwMonitor_);

const int mrate = mode->refreshRate;	// Current monitor rate (before window creation)

GLFWwindow *window = NULL;
fullscreen_ = (mode->width == width_ && mode->height == height_);

if (fullscreen_)
{
	glfwWindowHint(GLFW_AUTO_ICONIFY, GL_FALSE);
	glfwWindowHint(GLFW_CENTER_CURSOR, GL_FALSE);
	glfwWindowHint(GLFW_RED_BITS, mode->redBits);
	glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits);
	glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits);
	glfwWindowHint(GLFW_ALPHA_BITS, mode->blueBits);
	
	if (rate_ > 0)
		glfwWindowHint(GLFW_REFRESH_RATE, rate_);
	else
		glfwWindowHint(GLFW_REFRESH_RATE, mrate);

	window = glfwCreateWindow(width_, height_, name_.c_str(), glfwMonitor_, NULL);

	// Workaround for GLFW overriding the current monitor refresh rate (if not natively supported)
	if (mrate == rate_ && glfwGetVideoMode(glfwMonitor_)->refreshRate != rate_)
	{
		glfwSetWindowMonitor(window, glfwMonitor_, 0, 0, mode->width, mode->height, rate_);
	}

	int width = 0, height = 0;

	auto tic = std::chrono::steady_clock::now();

	std::chrono::steady_clock::time_point timeEnd = std::chrono::steady_clock::now();

	while (width == 0 || height == 0
		&& std::chrono::duration_cast<std::chrono::seconds>(std::chrono::steady_clock::now() - tic).count() < 10)
	{
		glfwSetWindowMonitor(window, glfwMonitor_, 0, 0, mode->width, mode->height, 60);
		glfwWaitEvents();
		glfwSetWindowMonitor(window, glfwMonitor_, 0, 0, mode->width, mode->height, rate_);
		glfwWaitEvents();
		glfwGetFramebufferSize(window, &width, &height);
	}

	if (width == 0 || height == 0)
	{
		myerror("Could not create a framebuffer!");
		return 1;
	}
}
else
{
	glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
	glfwWindowHint(GLFW_VISIBLE, GL_TRUE);
	glfwWindowHint(GLFW_DECORATED, GL_TRUE);

	window = glfwCreateWindow(width_, height_, name_.c_str(), NULL, NULL);
}

if (window == NULL)
{
	myerror("Could not create GLFW Window!");
	return 1;
}

The rate_ member argument is optional. If it is set (>0), we use that value to create the context, otherwise we use the current monitor refresh rate.

When my monitor is set to 24Hz in Windows, the first call to “auto mode = glfwGetVideoMode(glfwMonitor_);” correctly shows the rate is 24. However, when I create the window, the mode switches to 60Hz, even when I tell it to stay at 24 via the glfwWindowHint().

I added a workaround to set the refresh rate after the full-screen window is created, but it doesn’t seem to work.

Sometimes I get a framebuffer of size 0x0, instead of 1920x1080.

I added a second work-around that toggles between 60Hz and the desired refresh rate and tries for 10 seconds until time expires or I get a non-0 framebuffer. That doesn’t work reliably either.

Any idea why that happens?