fix(glfw): report a zero framebuffer size so the no-drawable guard is reachable
This commit is contained in:
1 parent
0ac5d47fa6
commit
c8a97e4a1b
1 file changed
+24
-3
@@ -103,6 +103,12 @@ void Host::close() noexcept {
|
|||||||
glfwMakeContextCurrent(nullptr);
|
glfwMakeContextCurrent(nullptr);
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
have_pointer_ = false;
|
have_pointer_ = false;
|
||||||
|
// A closed host reports no size: a second run() must not see the previous
|
||||||
|
// window's framebuffer size before its first refresh_sizes().
|
||||||
|
fb_width_ = 0;
|
||||||
|
fb_height_ = 0;
|
||||||
|
fb_scale_x_ = 1.0f;
|
||||||
|
fb_scale_y_ = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Host::run(const RunConfig& cfg, const FrameFn& frame, Status* st) {
|
bool Host::run(const RunConfig& cfg, const FrameFn& frame, Status* st) {
|
||||||
@@ -172,7 +178,17 @@ bool Host::run(const RunConfig& cfg, const FrameFn& frame, Status* st) {
|
|||||||
|
|
||||||
if (fb_width_ == 0 || fb_height_ == 0) {
|
if (fb_width_ == 0 || fb_height_ == 0) {
|
||||||
// Minimised, or a size the compositor reports as zero: nothing to draw
|
// Minimised, or a size the compositor reports as zero: nothing to draw
|
||||||
// into. Idle briefly rather than spin, so an exit deadline still lands.
|
// into, and nothing to hand `begin_frame` -- a stale larger size would be
|
||||||
|
// a lie about the framebuffer. Idle on events rather than spin, and still
|
||||||
|
// honour the exit deadline here: a bounded run that never gets a drawable
|
||||||
|
// must end, not idle past the deadline it was given. There is no frame to
|
||||||
|
// dump in this state, so the screenshot is skipped.
|
||||||
|
if (exit_after_s > 0.0 && glfwGetTime() - start >= exit_after_s) {
|
||||||
|
std::fprintf(stderr,
|
||||||
|
"[glfw] exit deadline reached with no drawable (framebuffer 0x0);"
|
||||||
|
" nothing to dump\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
glfwWaitEventsTimeout(0.05);
|
glfwWaitEventsTimeout(0.05);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -224,8 +240,13 @@ void Host::refresh_sizes() noexcept {
|
|||||||
glfwGetWindowContentScale(window_, &sx, &sy);
|
glfwGetWindowContentScale(window_, &sx, &sy);
|
||||||
content_scale_x_ = sx;
|
content_scale_x_ = sx;
|
||||||
content_scale_y_ = sy;
|
content_scale_y_ = sy;
|
||||||
if (fw > 0) fb_width_ = static_cast<u32>(fw);
|
// Assigned unconditionally, zero included: an iconified window really does
|
||||||
if (fh > 0) fb_height_ = static_cast<u32>(fh);
|
// report a 0x0 framebuffer (Windows, and several Linux window managers), and
|
||||||
|
// the loop's no-drawable guard reads exactly this. Only ever writing a
|
||||||
|
// positive size would leave the guard unreachable and keep handing
|
||||||
|
// `begin_frame` a stale size for a framebuffer that is no longer that big.
|
||||||
|
fb_width_ = fw > 0 ? static_cast<u32>(fw) : 0u;
|
||||||
|
fb_height_ = fh > 0 ? static_cast<u32>(fh) : 0u;
|
||||||
if (ww > 0 && fw > 0) fb_scale_x_ = static_cast<f32>(fw) / static_cast<f32>(ww);
|
if (ww > 0 && fw > 0) fb_scale_x_ = static_cast<f32>(fw) / static_cast<f32>(ww);
|
||||||
if (wh > 0 && fh > 0) fb_scale_y_ = static_cast<f32>(fh) / static_cast<f32>(wh);
|
if (wh > 0 && fh > 0) fb_scale_y_ = static_cast<f32>(fh) / static_cast<f32>(wh);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user