# glViewport not working with maximized window

**URL:** <https://discourse.glfw.org/t/glviewport-not-working-with-maximized-window/2271>\
**Category:** support\
**Created:** [January 5, 2023, 2:04pm UTC](https://discourse.glfw.org/t/glviewport-not-working-with-maximized-window/2271 "2023-01-05T14:04:19Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![wbt](https://avatars.discourse-cdn.com/v4/letter/w/da6949/32.png) [@wbt](https://discourse.glfw.org/u/wbt)\
**Post date:** [January 5, 2023, 2:04pm UTC](https://discourse.glfw.org/t/glviewport-not-working-with-maximized-window/2271/1 "2023-01-05T14:04:20Z")

</div>

For my application, I want to maintain a square viewport when the window gets resized. I have defined a windowSizeCallback function to redefine the viewport each time the window is resized; see attached example. This works fine when the window is resized when I drag the corner, but it doesn’t work when the window is maximized, even though the callback function _does_ get called when the window is maximized. What am I doing wrong? Or is this a bug in GLFW? I think it might be GLFW, because a similar GLUT program _does_ work as expected. Thanks in advance for any reply!

GLFW version: 3.3.8 Cocoa NSGL EGL OSMesa dynamic  
MacOS 10.14.6  
GLFW Python bindings version 2.5.5  
Python 3.10

```auto
import glfw
from OpenGL.GL import *

# Make sure we always have a square viewport
def window_size_callback(window, x, y):
    if x > y:
        glViewport(0, 0, y, y)
    else:
        glViewport(0, y - x, x, x)

print(f"GLFW version: {glfw.get_version_string().decode()}")

# Initialize the GLFW library
if not glfw.init():
    exit()

# Create a windowed mode window and its OpenGL context
window = glfw.create_window(200, 200, "Test Viewport", None, None)
if not window:
    glfw.terminate()
    exit()

# Make the window's context current
glfw.make_context_current(window)

# Set the callback function for resizing the window
glfw.set_window_size_callback(window, window_size_callback)

while not glfw.window_should_close(window):
    glClear(GL_COLOR_BUFFER_BIT)
    glBegin(GL_LINES)
    glVertex(-1, -1)
    glVertex(1, 1)
    glVertex(-1, 1)
    glVertex(1, -1)
    glEnd()

    # Swap front and back buffers
    glfw.swap_buffers(window)

    # Wait for events
    glfw.wait_events()

glfw.terminate()

```

---

<div class="post-metadata">

**Author:** ![ws909](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.glfw.org/ws909/32/714_2.png) [@ws909](https://discourse.glfw.org/u/ws909)\
**Post date:** [January 7, 2023, 11:22pm UTC](https://discourse.glfw.org/t/glviewport-not-working-with-maximized-window/2271/2 "2023-01-07T23:22:15Z")

</div>

The window/screen coordinates on MacOS are not in pixels. You need to use `glfwGetFramebufferSize`. You can set a callback for the frame buffer size changed events too.

---

<div class="post-metadata">

**Author:** ![wbt](https://avatars.discourse-cdn.com/v4/letter/w/da6949/32.png) [@wbt](https://discourse.glfw.org/u/wbt)\
**Post date:** [January 8, 2023, 9:26am UTC](https://discourse.glfw.org/t/glviewport-not-working-with-maximized-window/2271/3 "2023-01-08T09:26:20Z")

</div>

Hi ws909,

Thanks for your reply. I am not sure I understand what you mean, though. Both `glfwGetWindowSize` and `glfwGetFramebufferSize` report the same numbers as the arguments supplied to the window size callback function. Using the framebuffer size callback instead of the window size callback has the same effect. As said above, the example code works fine when dragging the window corner, but fails when the window is maximized, even though the callback function _does_ get called. Can you check whether you see the same behaviour on your setup? Thanks!

Best regards,

Wouter

---

<div class="post-metadata">

**Author:** ![ws909](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.glfw.org/ws909/32/714_2.png) [@ws909](https://discourse.glfw.org/u/ws909)\
**Post date:** [January 13, 2023, 9:17pm UTC](https://discourse.glfw.org/t/glviewport-not-working-with-maximized-window/2271/4 "2023-01-13T21:17:04Z")

</div>

@wbt

> [@wbt](#):
>
> Both `glfwGetWindowSize` and `glfwGetFramebufferSize` report the same numbers as the arguments supplied to the window size callback function

That might be, but `glViewport` and other OpenGL functions that don’t use normalized coordinates operate on frame buffer coordinates, which are guaranteed to be different from window or screen coordinates, on certain platforms. MacOS is one of these. This is the case on my current MacBook (let’s exclude that bug I reported a year or two ago which none of us have found a fix for yet), but if I remember correctly, an older MBA with a 1440x900 screen that I had, used a 1:1 scaling, resulting in similar sizes for the frame buffer and window size.

Short answer: you’re doing it incorrectly, and you need to change to `glfwSetFramebufferCallback` and `glfwGetFramebufferSize`.

Not that this fixes the problem you’re describing, though.

I converted your code to C, and ran it on the latest master. I can confirm that this issue happens when the window is put into fullscreen (green full screen mode button in the title bar), and persists when the window exits this fullscreen mode. It does however not happen when the window is maximized (fill desktop work area (double click on title bar)).

Please report this as a bug [on Github](https://github.com/glfw/glfw/issues/new) if you have an account there. See [reporting a bug](https://github.com/glfw/glfw/blob/master/docs/CONTRIBUTING.md#reporting-a-bug).

C code:

```auto
#define GLAD_GL_IMPLEMENTATION
#include <glad/gl.h>
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>

#include <stdio.h>
#include <stdlib.h>

// Make sure we always have a square viewport
void windowSizeCallback(GLFWwindow* window, int x, int y) {
    if (x > y) {
        glViewport(0, 0, y, y);
    } else {
        glViewport(0, y - x, x, x);
    }
}

int main(int argc, char** argv) {
    // Initialize the GLFW library
    if (!glfwInit()) {
        exit(-1);
    }
    
    // Create a windowed mode window and its OpenGL context
    GLFWwindow* window = glfwCreateWindow(200, 200, "Test Viewport", NULL, NULL);
    if (!window) {
        glfwTerminate();
        exit(-1);
    }

    // Use the frame buffer size callback instead of the window size callback
    glfwSetFramebufferSizeCallback(window, windowSizeCallback);
    
    glfwMakeContextCurrent(window);
    gladLoadGL(glfwGetProcAddress);

    while (!glfwWindowShouldClose(window)) {
        glClear(GL_COLOR_BUFFER_BIT);
        glBegin(GL_LINES);
        glVertex2i(-1, -1);
        glVertex2i(1, 1);
        glVertex2i(-1, 1);
        glVertex2i(1, -1);
        glEnd();
        glfwSwapBuffers(window);

        glfwWaitEvents();
    }
    
    glfwTerminate();
}

```

---

<div class="post-metadata">

**Author:** ![ws909](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.glfw.org/ws909/32/714_2.png) [@ws909](https://discourse.glfw.org/u/ws909)\
**Post date:** [January 13, 2023, 9:46pm UTC](https://discourse.glfw.org/t/glviewport-not-working-with-maximized-window/2271/5 "2023-01-13T21:46:57Z")

</div>

The bug has nothing to do with `glViewport`. It is caused by GLFW reporting an incorrect frame buffer size. Pretty much a result of the same that spawned multiple other similar bug reports. Logging the frame buffer size when in fullscreen in this program, reports `3600x2252` on my `3024x1964` screen.

---

<div class="post-metadata">

**Author:** ![wbt](https://avatars.discourse-cdn.com/v4/letter/w/da6949/32.png) [@wbt](https://discourse.glfw.org/u/wbt)\
**Post date:** [January 15, 2023, 1:24pm UTC](https://discourse.glfw.org/t/glviewport-not-working-with-maximized-window/2271/6 "2023-01-15T13:24:14Z")

</div>

Thanks for the confirmation. I will report a bug on GitHub. Could you just check one more thing for me: if you change the callback function to use a fixed viewport, e.g.:

```auto
glViewport(0, 0, 200, 200);

```

and you maximize the window, does the viewport fill the entire screen (i.e. the cross is stretched horizontally)? That’s what I’m seeing, which seems to indicate that not only is the framebuffer size reported incorrectly, but the call to `glViewport` also fails. Not sure if this is related to GLFW, but as said before, a similar GLUT program does work correctly.

I also converted my app to use the framebuffer callback as indeed the window size and frame buffer size differ on the Mac Retina screens (not on regular screens though).

Thanks again,

Wouter

---

<div class="post-metadata">

**Author:** ![ws909](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.glfw.org/ws909/32/714_2.png) [@ws909](https://discourse.glfw.org/u/ws909)\
**Post date:** [January 15, 2023, 2:12pm UTC](https://discourse.glfw.org/t/glviewport-not-working-with-maximized-window/2271/7 "2023-01-15T14:12:31Z")

</div>

Yes, but this actually has nothing to do with OpenGL either. It’s simply because the callback is never fired when you move into fullscreen. The frame buffer size callback is neither fired. The viewport is reset every time the frame buffer size changes. When the window is put into fullscreen, the size changes, but the callbacks are not called, so you’re not overriding the now reset viewport. So this is also a bug.

---

<div class="post-metadata">

**Author:** ![wbt](https://avatars.discourse-cdn.com/v4/letter/w/da6949/32.png) [@wbt](https://discourse.glfw.org/u/wbt)\
**Post date:** [January 15, 2023, 3:43pm UTC](https://discourse.glfw.org/t/glviewport-not-working-with-maximized-window/2271/8 "2023-01-15T15:43:41Z")

</div>

As far as I can see by logging to the terminal, the `FramebufferSizeCallback` _is_ fired when the window is put into full screen, either when it is done by the user (green button) or programmatically (by means of `glfwSetWindowMonitor`). But after the callback is completed, in the _next_ iteration of the main drawing loop, the viewport is reset again to the screen size, as can be seen from the example below (in C).

So, even though the event of going to full screen has already been handled, the system decides on its own to change the viewport in the next iteration. Can you confirm this strange behaviour?

```auto
// compile:
// cc -o test_glfw -lglfw -framework OpenGL -DGL_SILENCE_DEPRECATION test_glfw.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <GLFW/glfw3.h>
#include <OpenGL/GL.h>

// Make sure we always have a square viewport
void framebufferSizeCallback(GLFWwindow* window, int x, int y) {
    printf("Framebuffer size: %d x %d\n", x, y);
    if (x > y) {
        glViewport(0, 0, y, y);
    } else {
        glViewport(0, y - x, x, x);
    }
}

// Exit when a key is pressed
void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) {
    glfwTerminate();
    exit(0);
}

int main(int argc, char** argv) {
    // Initialize the GLFW library
    if (!glfwInit()) {
        exit(-1);
    }
    
    // Create a windowed mode window and its OpenGL context
    GLFWwindow* window = glfwCreateWindow(200, 200, "Test Viewport", NULL, NULL);
    if (!window) {
        glfwTerminate();
        exit(-1);
    }

    // Make the window's context current
    glfwMakeContextCurrent(window);

    // Synchronize buffer swap interval with refresh rate
    glfwSwapInterval(1);

    // Set the callback function for resizing the window
    glfwSetFramebufferSizeCallback(window, framebufferSizeCallback);

    // Set the callback function for keypresses
    glfwSetKeyCallback(window, keyCallback);

    // Make the window full-screen
    GLFWmonitor *monitor = glfwGetPrimaryMonitor();
    const GLFWvidmode *mode = glfwGetVideoMode(monitor);
    glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate);
    
    while (!glfwWindowShouldClose(window)) {
        glClear(GL_COLOR_BUFFER_BIT);
        glBegin(GL_LINES);
        glVertex2i(-1, -1);
        glVertex2i(1, 1);
        glVertex2i(-1, 1);
        glVertex2i(1, -1);
        glEnd();
        glfwSwapBuffers(window);

        glfwPollEvents();

        // Check if viewport has changed
        static GLint previousViewport[4];
        GLint viewport[4];
        glGetIntegerv(GL_VIEWPORT, viewport);
        if (memcmp(previousViewport, viewport, sizeof(viewport))) {
            printf("Viewport set to (%d, %d, %d, %d)\n", viewport[0], viewport[1], viewport[2], viewport[3]);
            memcpy(previousViewport, viewport, sizeof(viewport));
        }
    }
    
    glfwTerminate();
    return 0;
}

```

---

<div class="post-metadata">

**Author:** ![wbt](https://avatars.discourse-cdn.com/v4/letter/w/da6949/32.png) [@wbt](https://discourse.glfw.org/u/wbt)\
**Post date:** [January 15, 2023, 4:48pm UTC](https://discourse.glfw.org/t/glviewport-not-working-with-maximized-window/2271/9 "2023-01-15T16:48:56Z")

</div>

Bug report made [here](https://github.com/glfw/glfw/issues/2251).

---

<div class="post-metadata">

**Author:** ![ws909](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.glfw.org/ws909/32/714_2.png) [@ws909](https://discourse.glfw.org/u/ws909)\
**Post date:** [January 16, 2023, 11:38am UTC](https://discourse.glfw.org/t/glviewport-not-working-with-maximized-window/2271/10 "2023-01-16T11:38:04Z")

</div>

You’re right about your observations. I must’ve remembered something wrong from yesterday’s testing.

Repeatedly setting the viewport in the loop works, though.

> [@wbt](#):
>
> But after the callback is completed, in the _next_ iteration of the main drawing loop, the viewport is reset again to the screen size, as can be seen from the example below (in C).
> 
> So, even though the event of going to full screen has already been handled, the system decides on its own to change the viewport in the next iteration. Can you confirm this strange behaviour?

This issue is probably caused by the native frame buffer being resized after the callback is fired. I’ll look into GLFW’s source code for that. `glfwGetWindowSize` and `glfwGetFramebufferSize` return the same values as given to the callbacks.
