How to set the aspect ratio of a GLFW window with Python?

import sys
import os 
sys.path.append(os.getcwd())
#sys.setrecursionlimit(100000)
from OpenGL.GL import *
from glfw.GLFW import *
from glfw import _GLFWwindow as GLFWwindow

import glm 
import math
import platform

from includes.Camera import Camera



def init_glfw(): 
    global SCR_WIDTH 
    global SCR_HEIGHT 
    global wind

    SCR_WIDTH = 1920
    SCR_HEIGHT = 1080

    glfwInit()
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4)
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6)
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE)
    if (platform.system() == "Darwin"): 
        glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE)

    wind = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", None, None)

    if (wind == None):
        print("Failed to create GLFW window")
        glfwTerminate()
        return -1
    
    glfwMakeContextCurrent(wind)
    glfwSetFramebufferSizeCallback(wind, framebuffer_size_callback) 

   
    glEnable(GL_BLEND)
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glViewport(0, 0, SCR_WIDTH, SCR_HEIGHT)
    
    #glfwGetWindowSize(window, SCR_WIDTH, SCR_HEIGHT);
    glfwSetWindowAspectRatio(wind, SCR_WIDTH, SCR_HEIGHT);

    print('GLFW is initialized....')

def init_objects():
    global standalone_v
    global standalone_i
    global standalone_ssbo
    global camera 

    α = 800.
    O = glm.vec3(0.,0.,0.)
    camera = Camera(O,α)
    camera.projection = glm.ortho((-SCR_WIDTH/2),
                                  (SCR_WIDTH/2),
                                  (-SCR_HEIGHT/2),
                                  (SCR_HEIGHT/2),
                                  0.1,
                                  α*2) 
    α1 = 0.5




    print('debug')

def init_buffers():
    global VAO 
    global VBO 
    global EBO 
    global SSBO 

    global standalone_v 
    global standalone_i  
    global standalone_ssbo
 
    standalone_v = glm.array.zeros(0,glm.float32)
    standalone_i = glm.array.zeros(0,glm.uint32)
    standalone_ssbo = glm.array.zeros(0,glm.vec4)

    VAO = glGenVertexArrays(1)
    VBO = glGenBuffers(1)
    EBO = glGenBuffers(1)
    SSBO = glGenBuffers(1)

    glBindVertexArray(VAO)
    glBindBuffer(GL_ARRAY_BUFFER, VBO)
    glBufferData(GL_ARRAY_BUFFER, standalone_v.nbytes, standalone_v.ptr, GL_STATIC_DRAW)
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO)
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, standalone_i.nbytes, standalone_i.ptr, GL_STATIC_DRAW) 
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO )
    glBufferData(GL_SHADER_STORAGE_BUFFER, glm.sizeof(glm.vec4) * (len(standalone_ssbo)), standalone_ssbo.ptr, GL_STATIC_DRAW); 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 
                          8 * glm.sizeof(glm.float32), None)
    glEnableVertexAttribArray(0)
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 
                          8 * glm.sizeof(glm.float32), ctypes.c_void_p(3 * glm.sizeof(glm.float32)))
    glEnableVertexAttribArray(1)
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 
                          8 * glm.sizeof(glm.float32), ctypes.c_void_p(6 * glm.sizeof(glm.float32)))
    glEnableVertexAttribArray(2)  

def init_shaders():
    global shader_pointlist
    shader_pointlist = Shader('shaders/PointList.vs', 'shaders/PointList.fs')
    
    print('done initializing shaders....')


def processInput(window: GLFWwindow) -> None:
    if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS):
        glfwSetWindowShouldClose(window, True)


def framebuffer_size_callback(window: GLFWwindow, width: int, height: int) -> None:
    global SCR_WIDTH 
    global SCR_HEIGHT 
    global camera 


    SCR_WIDTH = width 
    SCR_HEIGHT = height 


    #projection = glm.mat4(1.0)
    #projection = glm.ortho((-SCR_WIDTH/2),(SCR_WIDTH/2),(-SCR_HEIGHT/2),(SCR_HEIGHT/2),0.1,1000) 

    glViewport(0, 0, width, height)
    #glfwSetWindowAspectRatio(window, int(SCR_WIDTH), int(SCR_HEIGHT))

def render():
    global wind
    while (not glfwWindowShouldClose(wind)):
        processInput(wind)
        glClearColor(0.2, 0.3, 0.3, 1.0)
        glClear(GL_COLOR_BUFFER_BIT) 
        glfwSwapBuffers(wind)
        glfwPollEvents()





def main() -> int:
    init_glfw()
    init_shaders()
    init_buffers()
    init_objects()
    render()
    glfwTerminate()
    return 0

main()

Calling glfwSetAspectRatio inside framebuffer_size_callback seems to lead to a recurssion error or a segmentation fault. Is there a way to set aspect ratio on a resize event? Does aspect ratio need to be refreshed or is there a way to on a resize event handled by framebuffer_size_callback?

So far if I use glfwSetAspectRatio inside framebuffer_size_callback I get:

RecursionError: maximum recursion depth exceeded while calling a Python object

on Ubuntu jammy…

You should not set the aspect ration within the callback, but instead do so once after window creation. The aspect ration is remembered by GLFW and does not need to be refreshed.

    /* Create a windowed mode window and its OpenGL context */
    /* Create with the same aspect ratio you intend to set, here 16/9 */
    window = glfwCreateWindow(1280, 720, "Hello World", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        return -1;
    }
    /* Set the aspect ratio once */
    glfwSetWindowAspectRatio( window, 16, 9 );