Black area while resizing window

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
User avatar
dusoft
Party member
Posts: 734
Joined: Fri Nov 08, 2013 12:07 am
Location: Europe usually
Contact:

Re: Black area while resizing window

Post by dusoft »

dcuny wrote: Fri Jan 31, 2025 10:44 pm
BrotSagtMist wrote: Fri Jan 31, 2025 8:44 pm This is a you problem.
Works on all my test boxes, so whatever you see there, this is specific to your system and not löve.
It's not specific to my machine - I've run this on multiple Windows machines for years, and have always seen this behavior.

Here's a minimal program:

Code: Select all

function love.load()
   love.window.setMode( 100, 100, {resizable=true, borderless=false})
end

function love.draw()
  love.graphics.clear({0,1,0})
end
Running Love v11.5 on Windows 11, here's what I see when I resize the window:

Image
Your example works for me on Linux, i.e. green is shown all the way while resizing. Somebody with different Windows should test.
dcuny
Prole
Posts: 17
Joined: Wed Aug 04, 2021 1:19 am

Re: Black area while resizing window

Post by dcuny »

Your example works for me on Linux, i.e. green is shown all the way while resizing. Somebody with different Windows should test.
That's because it's an issue of how Windows handles events.

It turns out that this is a longstanding issue with SDL. Libraries (like Blender's GHOST) have had workarounds.

Someone responded to GitHub pointing me to a thread explaining that there's no easy fix.

But at the bottom of the thread, there's a link announcing a fix for Windows that's been implemented for SDL 2.30.
RNavega
Party member
Posts: 433
Joined: Sun Aug 16, 2020 1:28 pm

Re: Black area while resizing window

Post by RNavega »

I also noticed this resizing problem, but it's one of those low-priority things because it only happens for a very short time until the user releases the mouse and then it's gone.

This is the closest that I can / am willing to experiment (it's still got some flashing on the side of the window):

Code: Select all

-- Use FFI to force LÖVE window redraws upon window resizes.

io.stdout:setvbuf('no')


local ffi = require('ffi')


ffi.cdef([[
// SDL_Event types.

// https://github.com/torch/sdl2-ffi/blob/master/cdefs.lua#L1655
typedef struct SDL_CommonEvent
{
    uint32_t type;
    uint32_t timestamp;
} SDL_CommonEvent;
typedef struct SDL_WindowEvent
{
    uint32_t type;
    uint32_t timestamp;
    uint32_t windowID;
    uint8_t event;
    uint8_t padding1;
    uint8_t padding2;
    uint8_t padding3;
    int32_t data1;
    int32_t data2;
} SDL_WindowEvent;

// https://github.com/torch/sdl2-ffi/blob/master/cdefs.lua#L1880
// https://github.com/libsdl-org/SDL/blob/SDL2/include/SDL_events.h#L655
typedef union SDL_Event
{
    uint32_t type;
    SDL_CommonEvent common;
    SDL_WindowEvent window;
    // Ignored events:
    /*
    SDL_KeyboardEvent key;
    SDL_TextEditingEvent edit;
    SDL_TextInputEvent text;
    SDL_MouseMotionEvent motion;
    SDL_MouseButtonEvent button;
    SDL_MouseWheelEvent wheel;
    SDL_JoyAxisEvent jaxis;
    SDL_JoyBallEvent jball;
    SDL_JoyHatEvent jhat;
    SDL_JoyButtonEvent jbutton;
    SDL_JoyDeviceEvent jdevice;
    SDL_ControllerAxisEvent caxis;
    SDL_ControllerButtonEvent cbutton;
    SDL_ControllerDeviceEvent cdevice;
    SDL_QuitEvent quit;
    SDL_UserEvent user;
    SDL_SysWMEvent syswm;
    SDL_TouchFingerEvent tfinger;
    SDL_MultiGestureEvent mgesture;
    SDL_DollarGestureEvent dgesture;
    SDL_DropEvent drop;
    */
    uint8_t padding[56];
} SDL_Event;

typedef int (__cdecl * SDL_EventFilter) (void *userdata, SDL_Event * event);

void SDL_AddEventWatch(SDL_EventFilter filter, void *userdata);
void SDL_DelEventWatch(SDL_EventFilter filter, void *userdata);

// OpenGL bindings from malkia's UFO on Github:
// https://github.com/malkia/ufo/blob/master/ffi/OpenGL.lua
void glViewport(int x, int y, int width, int height);
]])

local SDL = (jit.os == "Windows") and ffi.load("SDL2") or ffi.C

-- OpenGL bindings taken from UFO (see the cdef above):
local libs = ffi_OpenGL_libs or {
   OSX     = { x86 = "OpenGL.framework/OpenGL", x64 = "OpenGL.framework/OpenGL" },
   Windows = { x86 = "OPENGL32.DLL",            x64 = "OPENGL32.DLL" },
   Linux   = { x86 = "libGL.so",                x64 = "libGL.so", arm = "libGL.so" },
   BSD     = { x86 = "libGL.so",                x64 = "libGL.so" },
   POSIX   = { x86 = "libGL.so",                x64 = "libGL.so" },
   Other   = { x86 = "libGL.so",                x64 = "libGL.so" },
}
local gl = ffi.load(libs[ffi.os][ffi.arch])


local listening_resize = false


function love.load()
    -- Initialize the resize listening, if necessary.
    love.mousefocus(love.window.hasMouseFocus())
end


local function myWatcher(userdata, event)
    -- Identify window events.
    -- SDL_EventType from:
    -- https://github.com/libsdl-org/SDL/blob/SDL2/include/SDL_events.h#L94
    -- SDL_WINDOWEVENT_RESIZED from:
    -- https://github.com/libsdl-org/SDL/blob/SDL2/include/SDL_video.h#L163
    if (event.type == 0x200 and event.window.event == 5) then
        -- LÖVE does some special DPI handling of these coordinates. I also don't know
        -- if one size is for the "client area" and the other is the "full native window".
        local old_width, old_height = love.graphics.getDimensions()
        local new_width, new_height = event.window.data1, event.window.data2
        gl.glViewport(0, 0, new_width, new_height)
        -- Based on the drawing steps From LÖVE 11.x love.run:
        -- https://github.com/love2d/love/blob/11.x/src/modules/love/callbacks.lua#L135
        if love.graphics.isActive() then
            love.graphics.origin()
            love.graphics.clear(1, 0, 0)

            -- Need to scale to compensate the difference in size.
            love.graphics.scale(old_width / new_width,
                                old_height / new_height)
            love.draw()
            love.graphics.present()
        end
    end
    -- Return value: 1 = let the event go through; 0 = remove it.
    -- https://wiki.libsdl.org/SDL2/SDL_EventFilter#return-value
    return 1
end


function love.draw()
    love.graphics.setColor(0.1, 0.3, 0.4)
    love.graphics.circle('fill', 0, 0, 400)
    love.graphics.circle('fill', 800, 600, 400)
    love.graphics.setColor(1.0, 1.0, 1.0)
    love.graphics.print('Testing 1, 2, 3, ABC', 10, 10)
end


function love.focus(f)
    print('window focus ' .. tostring(f))
end


function love.mousefocus(f)
    print('mousefocus ' .. tostring(f))
    if f then
        if listening_resize then
            SDL.SDL_DelEventWatch(myWatcher, nil)
        end
        listening_resize = false
    else
        if not listening_resize then
            SDL.SDL_AddEventWatch(myWatcher, nil)
            listening_resize = true
        end
    end
end


function love.mousemoved(x, y)
    print('mousemove', x, y)
end


function love.keypressed(key)
    if key == 'escape' then
        love.event.quit()
    end
end
dcuny
Prole
Posts: 17
Joined: Wed Aug 04, 2021 1:19 am

Re: Black area while resizing window

Post by dcuny »

RNavega wrote: Sat Feb 01, 2025 7:28 am This is the closest that I can / am willing to experiment (it's still got some flashing on the side of the window):
Thanks! :cool:

It's certainly not perfect, and it's got some interesting side effects of widgets that depend on having an accurate window size.

But it's a huge improvement over the black window sections. :awesome:
User avatar
slime
Solid Snayke
Posts: 3176
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: Black area while resizing window

Post by slime »

I don't recommend that code - it will break on various platforms in love 11, and won't work at all in love 12.
dcuny
Prole
Posts: 17
Joined: Wed Aug 04, 2021 1:19 am

Re: Black area while resizing window

Post by dcuny »

slime wrote: Sun Feb 02, 2025 2:11 pm I don't recommend that code - it will break on various platforms in love 11, and won't work at all in love 12.
OK, thanks!
RNavega
Party member
Posts: 433
Joined: Sun Aug 16, 2020 1:28 pm

Re: Black area while resizing window

Post by RNavega »

To be clear, I also don't recommend that code, it's for academic purposes only.

Thankfully, this SDL2 quirk is that type of thing to not be cared about by almost all players.
User avatar
slime
Solid Snayke
Posts: 3176
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: Black area while resizing window

Post by slime »

dcuny wrote: Fri Jan 31, 2025 9:16 pm
Does love.update run during resizing?
No.

As far as I can tell, no callback is executing during a resize.
This is changed now in love 12 so by default the main game loop is run during a resize or move of the window. :)
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Bing [Bot], Google [Bot] and 7 guests