You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GLFW多窗口异常:窗口最小化/缩放后另一窗口无响应

问题分析与解决方案

你的代码存在两个核心问题导致窗口无响应:

  1. 重复调用glfwPollEvents():GLFW的事件队列是全局共享的,每次调用glfwPollEvents()会处理所有待处理事件。你在渲染每个窗口后都调用一次,会导致事件被重复处理,引发窗口状态同步异常。
  2. 未判断窗口可见性:当窗口被最小化时,依然执行渲染和缓冲区交换操作,这会干扰GLFW的窗口状态管理,甚至阻塞事件处理流程。

修复后的代码

#include <GLFW/glfw3.h>

int main() {
    // Initialize GLFW
    if (!glfwInit()) {
        return -1;
    }

    // Create the first window and its OpenGL context
    GLFWwindow* window1 = glfwCreateWindow(640, 480, "Window 1", NULL, NULL);
    if (!window1) {
        glfwTerminate();
        return -1;
    }

    // Create the second window and its OpenGL context
    GLFWwindow* window2 = glfwCreateWindow(640, 480, "Window 2", NULL, NULL);
    if (!window2) {
        glfwDestroyWindow(window1);
        glfwTerminate();
        return -1;
    }

    // Main loop
    while (!glfwWindowShouldClose(window1) || !glfwWindowShouldClose(window2)) {
        // 只调用一次glfwPollEvents()处理全局事件队列
        glfwPollEvents();

        // 处理第一个窗口
        if (!glfwWindowShouldClose(window1)) {
            // 仅当窗口可见时才渲染
            if (glfwGetWindowAttrib(window1, GLFW_VISIBLE)) {
                glfwMakeContextCurrent(window1);
                // 这里添加你的渲染逻辑
                glfwSwapBuffers(window1);
            }
        }

        // 处理第二个窗口
        if (!glfwWindowShouldClose(window2)) {
            if (glfwGetWindowAttrib(window2, GLFW_VISIBLE)) {
                glfwMakeContextCurrent(window2);
                // 这里添加你的渲染逻辑
                glfwSwapBuffers(window2);
            }
        }
    }

    // 销毁窗口并清理
    glfwDestroyWindow(window1);
    glfwDestroyWindow(window2);
    glfwTerminate();
    return 0;
}

关键修改说明

  • 单次事件处理:将glfwPollEvents()移到循环开头,确保所有窗口的事件都被统一处理一次,避免重复处理导致的状态混乱。
  • 可见性判断:用glfwGetWindowAttrib(window, GLFW_VISIBLE)检查窗口是否可见,最小化或隐藏的窗口跳过渲染流程,减少无效操作并避免状态冲突。
  • 独立窗口判断:循环条件改为只要有一个窗口未关闭就继续,每个窗口的关闭状态单独判断,避免一个窗口关闭导致另一个窗口直接退出。
  • 语法修复:补上原代码中glfwMakeContextCurrent(window1)后的分号,避免编译错误。

额外提示

如果需要处理窗口焦点变化,可以注册窗口焦点回调:

void focus_callback(GLFWwindow* window, int focused) {
    // 窗口获得/失去焦点时的逻辑
    if (focused) {
        // 窗口获得焦点后的操作
    } else {
        // 窗口失去焦点后的操作
    }
}

// 在创建窗口后注册回调
glfwSetWindowFocusCallback(window1, focus_callback);
glfwSetWindowFocusCallback(window2, focus_callback);

内容的提问来源于stack exchange,提问作者omar abu abdullah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 01:52:04