Reacting to window resize events

According to docs I’m supposed use SDL_SetVideoMode() again upon
receiving a SDL_VIDEORESIZE. Problem is that this creates another
SDL_VIDEORESIZE, causing an endless resizing loop in certain conditions.

To accomodate for that, I use a delay of 0.5 seconds after the last
SDL_VIDEORESIZE before attempting to SetVideoMode(). Is there any way
more elegant than this?

Besides, does SetVideoMode() destroy OpenGL context for certaing? I.e.
can I expect texture allocations and the like to be all free again?–
Andreas Bombe <@Andreas_Bombe> DSA key 0x04880A44

According to docs I’m supposed use SDL_SetVideoMode() again upon
receiving a SDL_VIDEORESIZE. Problem is that this creates another
SDL_VIDEORESIZE, causing an endless resizing loop in certain conditions.

To accomodate for that, I use a delay of 0.5 seconds after the last
SDL_VIDEORESIZE before attempting to SetVideoMode(). Is there any way
more elegant than this?

I’ve never seen this. What values for width and height do you get in the
resize event?

Besides, does SetVideoMode() destroy OpenGL context for certaing? I.e.
can I expect texture allocations and the like to be all free again?

You should free your GL resources before calling SDL_SetVideoMode() and
reallocate them afterwards. It’s not strictly necessary on Linux, but
doing so keeps things portable. (TODO: keep OpenGL context on Windows)

See ya,
-Sam Lantinga, Software Engineer, Blizzard Entertainment

I’ve experienced this, under certain conditions. If I create a
non-resizable window using OpenGL with SDL, then call
SDL_SetVideoMode() with a new width and height, I get a
SDL_VIDEORESIZE event with the width and height one greater
than what I passed to SDL_SetVideoMode().
In other words, if I do this:

SDL_Surface* surface =
SDL_SetVideoMode(640, 480, 16, SDL_OPENGL)

to initialize the display, then call:

surface = SDL_SetVideoMode(800, 600, 16, SDL_OPENGL);

I’ll will get a resize event where event->w == 801 and
event->h == 601.

This only happens under Linux (although the only platforms
I’ve used SDL on are Linux and Windows), and only when the
window is non-resizeable. I don’t know if setting
SDL_OPENGL is a factor, since I’ve never tried it w/o
openGL. It may be window-manager dependent as well -
I first saw this happen shortly after switching from
Gnome to Fluxbox. It may be that I never noticed or
tried it under Gnome, however.

Hope that helps!

Ashley

Sam Lantinga wrote:>>According to docs I’m supposed use SDL_SetVideoMode() again upon

receiving a SDL_VIDEORESIZE. Problem is that this creates another
SDL_VIDEORESIZE, causing an endless resizing loop in certain conditions.

To accomodate for that, I use a delay of 0.5 seconds after the last
SDL_VIDEORESIZE before attempting to SetVideoMode(). Is there any way
more elegant than this?

I’ve never seen this. What values for width and height do you get in the
resize event?

Besides, does SetVideoMode() destroy OpenGL context for certaing? I.e.
can I expect texture allocations and the like to be all free again?

You should free your GL resources before calling SDL_SetVideoMode() and
reallocate them afterwards. It’s not strictly necessary on Linux, but
doing so keeps things portable. (TODO: keep OpenGL context on Windows)

See ya,
-Sam Lantinga, Software Engineer, Blizzard Entertainment


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

According to docs I’m supposed use SDL_SetVideoMode() again upon
receiving a SDL_VIDEORESIZE. Problem is that this creates another
SDL_VIDEORESIZE, causing an endless resizing loop in certain conditions.

To accomodate for that, I use a delay of 0.5 seconds after the last
SDL_VIDEORESIZE before attempting to SetVideoMode(). Is there any way
more elegant than this?

I’ve never seen this. What values for width and height do you get in the
resize event?

I get the inbetween sizes that were created during resize.

Perhaps I should summarize clearly:

I use a window manager that actually resizes windows during the mouse
dragging instead of drawing a box to indicate new size (it’s sawfish
1.3, but I don’t think that’s of relevance - that is, unless it’s
uncommon to send resize events to application resize requests). This
can obviously create many resize events in very short time.

The SDL program (apart from my own I experienced it with others as well)
uses lots of CPU time and may queue up a few events.

So while resizing from, say, 500x500 to 1000x1000 I could have,
depending on the timing, events for 600x600, 800x800 and 1000x1000 in
the queue by the time I handle it. (The window has reached its final
size of 1000x1000 already.)

I handle 600x600, SetVideoMode() resizes the window back to that,
WM queues new resize event for 600x600, I handle 800x800, WM queues
resize event for 800x800, etc. ad infinitum.

Fast rendering and/or responsive programs won’t exhibit that behaviour.
The problem really is that the only method I can see to react to resize
events actively sets the window size, causing a feedback loop.

My solution is to delay SetVideoMode() until the window size has been
stable for a certain time. It’s not very nice, but it will have to do
if there is no other way.

Besides, does SetVideoMode() destroy OpenGL context for certaing? I.e.
can I expect texture allocations and the like to be all free again?

You should free your GL resources before calling SDL_SetVideoMode() and
reallocate them afterwards. It’s not strictly necessary on Linux, but
doing so keeps things portable. (TODO: keep OpenGL context on Windows)

Ok, thanks.On Sat, Jun 28, 2003 at 09:18:31PM -0700, Sam Lantinga wrote:


Andreas Bombe <@Andreas_Bombe> DSA key 0x04880A44

[…]

I use a window manager that actually resizes windows during the
mouse dragging instead of drawing a box to indicate new size (it’s
sawfish 1.3, but I don’t think that’s of relevance - that is,
unless it’s uncommon to send resize events to application resize
requests).

I think that’s pretty much part of the definition of that feature.
It’s not much point resizing windows that way unless the contents
track the changes.

[…]

My solution is to delay SetVideoMode() until the window size has
been stable for a certain time. It’s not very nice, but it will
have to do if there is no other way.

Well, it would effectively break “live resizing” in any window
managers that do it, which is a bug IMHO. So, something is definitely
wrong here. You should be able to tell which events come from the
outside world and which ones are triggered by your own actions, or
you should have the option of not getting the latter at all.

//David Olofson - Programmer, Composer, Open Source Advocate

.- The Return of Audiality! --------------------------------.
| Free/Open Source Audio Engine for use in Games or Studio. |
| RT and off-line synth. Scripting. Sample accurate timing. |
`-----------------------------------> http://audiality.org -’
http://olofson.nethttp://www.reologica.se —On Tuesday 01 July 2003 17.57, Andreas Bombe wrote:

[…]

I use a window manager that actually resizes windows during the
mouse dragging instead of drawing a box to indicate new size (it’s
sawfish 1.3, but I don’t think that’s of relevance - that is,
unless it’s uncommon to send resize events to application resize
requests).

I think that’s pretty much part of the definition of that feature.
It’s not much point resizing windows that way unless the contents
track the changes.

[…]

My solution is to delay SetVideoMode() until the window size has
been stable for a certain time. It’s not very nice, but it will
have to do if there is no other way.

Well, it would effectively break “live resizing” in any window
managers that do it, which is a bug IMHO. So, something is definitely
wrong here. You should be able to tell which events come from the
outside world and which ones are triggered by your own actions, or
you should have the option of not getting the latter at all.

If you use a while(poll) loop to handle events you can set a flag and
save state each time you get a resize event inside the loop, and then
only do the call to SetVideoMode() out side the loop. That is, you
receive any number of resize events in the loop, but only respond to the
last one you see. That keeps the multiple resize events from
overwhelming your program and makes sure you only do the SetVideoMode()
during a “lull” in the event stream.

Seems to work for me anyway.

	Bob PendletonOn Tue, 2003-07-01 at 11:17, David Olofson wrote:

On Tuesday 01 July 2003 17.57, Andreas Bombe wrote:

//David Olofson - Programmer, Composer, Open Source Advocate

.- The Return of Audiality! --------------------------------.
| Free/Open Source Audio Engine for use in Games or Studio. |
| RT and off-line synth. Scripting. Sample accurate timing. |
`-----------------------------------> http://audiality.org -’
http://olofson.nethttp://www.reologica.se


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

±----------------------------------+

One possibility is to organize your own queue and put (some) events from
SDL queue there instead of immediately processing them. Then process
events “in batches” in a tight or even timer-driven loop from your
secondary queue; before each processing you may do some magic by merging
adjacent (or even not always adjacent) events. I am not really familiar
with SDL queue yet, maybe you can do this with it directly, but for your
secondary queue you definitely can organize the direct access – and
this is the whole point of having this extra queue. This is how Java AWT
works with its EventQueue. Basically, it retrieves and merges all
regions scheduling for repainting that are in the queue by the time the
event processing thread – that’s how it tries to masquerade the JVM
slowness. To give resizing user a clue you can probably still draw the
outline on each SDL event.

Hope this will help,
Pavel>I get the inbetween sizes that were created during resize.

Perhaps I should summarize clearly:

I use a window manager that actually resizes windows during the mouse
dragging instead of drawing a box to indicate new size (it’s sawfish
1.3, but I don’t think that’s of relevance - that is, unless it’s
uncommon to send resize events to application resize requests). This
can obviously create many resize events in very short time.

The SDL program (apart from my own I experienced it with others as well)
uses lots of CPU time and may queue up a few events.

So while resizing from, say, 500x500 to 1000x1000 I could have,
depending on the timing, events for 600x600, 800x800 and 1000x1000 in
the queue by the time I handle it. (The window has reached its final
size of 1000x1000 already.)

I handle 600x600, SetVideoMode() resizes the window back to that,
WM queues new resize event for 600x600, I handle 800x800, WM queues
resize event for 800x800, etc. ad infinitum.

[…]

I use a window manager that actually resizes windows during the
mouse dragging instead of drawing a box to indicate new size (it’s
sawfish 1.3, but I don’t think that’s of relevance - that is,
unless it’s uncommon to send resize events to application resize
requests).

I think that’s pretty much part of the definition of that feature.
It’s not much point resizing windows that way unless the contents
track the changes.

I thought that resize events wouldn’t have to be sent if the program
itself requested that size but yes, I can see now that wouldn’t be
complete. The WM can deny or override the requested size after all, I
guess.

[…]

My solution is to delay SetVideoMode() until the window size has
been stable for a certain time. It’s not very nice, but it will
have to do if there is no other way.

Well, it would effectively break “live resizing” in any window
managers that do it, which is a bug IMHO. So, something is definitely
wrong here. You should be able to tell which events come from the
outside world and which ones are triggered by your own actions, or
you should have the option of not getting the latter at all.

Not getting the latter would depend on having an “adapt to this screen
environment” function that is seperate from the “create this screen
environment” SetVideoMode(). I don’t see anything like that in SDL, so
maybe it’s a good thing to put on a todo list for a future SDL version?On Tue, Jul 01, 2003 at 06:17:19PM +0200, David Olofson wrote:

On Tuesday 01 July 2003 17.57, Andreas Bombe wrote:


Andreas Bombe <@Andreas_Bombe> DSA key 0x04880A44

That makes it less likely, but it’s still skippy. It’s what I do now,
but without a delay after the last resize event, it still looks like
this:

346 frames, 114.95 s, 1.9 fps
resize event 672x641
resizing to 672x641
resize event 681x656
resizing to 681x656
resize event 687x668
resizing to 687x668
349 frames, 116.48 s, 2.0 fps
resize event 700x687
resizing to 700x687
resize event 705x692
resizing to 705x692
resize event 700x687
resizing to 700x687
352 frames, 118.18 s, 1.8 fps
resize event 705x692
resizing to 705x692
355 frames, 119.40 s, 2.5 fps

Nevermind the low fps, it’s just Mesa on this computer (which means that
the X server was hit by software rendering). The frame counters are
printed approximately every 1.5 seconds, I was slowly and continuously
enlarging the window with the mouse.On Tue, Jul 01, 2003 at 03:19:25PM -0500, Bob Pendleton wrote:

If you use a while(poll) loop to handle events you can set a flag and
save state each time you get a resize event inside the loop, and then
only do the call to SetVideoMode() out side the loop. That is, you
receive any number of resize events in the loop, but only respond to the
last one you see.


Andreas Bombe <@Andreas_Bombe> DSA key 0x04880A44

If you use a while(poll) loop to handle events you can set a flag and
save state each time you get a resize event inside the loop, and then
only do the call to SetVideoMode() out side the loop. That is, you
receive any number of resize events in the loop, but only respond to the
last one you see.

That makes it less likely, but it’s still skippy. It’s what I do now,
but without a delay after the last resize event, it still looks like
this:

It doesn’t look like this shows how many resize events are being
ignored?

Also, I assume you have the same problem on computers with hardware
acceleration? Everything will look skippy at 2 FPS :slight_smile:

	Bob PendletonOn Wed, 2003-07-02 at 08:42, Andreas Bombe wrote:

On Tue, Jul 01, 2003 at 03:19:25PM -0500, Bob Pendleton wrote:

346 frames, 114.95 s, 1.9 fps
resize event 672x641
resizing to 672x641
resize event 681x656
resizing to 681x656
resize event 687x668
resizing to 687x668
349 frames, 116.48 s, 2.0 fps
resize event 700x687
resizing to 700x687
resize event 705x692
resizing to 705x692
resize event 700x687
resizing to 700x687
352 frames, 118.18 s, 1.8 fps
resize event 705x692
resizing to 705x692
355 frames, 119.40 s, 2.5 fps

Nevermind the low fps, it’s just Mesa on this computer (which means that
the X server was hit by software rendering). The frame counters are
printed approximately every 1.5 seconds, I was slowly and continuously
enlarging the window with the mouse.

±----------------------------------+

The problem comes from the fact that you have very low FPS, which means
that when you have gone through all the queued resize events and make
the actual resizing setVideoMode() it takes so long that the resize
events in the mean time get way of the values you used to the previous
setVideoMode, which generated resize event ends up in the queue. One
thing when FPS is this low is to not draw the actual scene until you
get resize event that matches the size you have set it with
setVideoMode(). So you kind of wait until you get the final size and
after that you draw in normal fashion.

I think it would be good if one could differentiate the setVideoMode()
generated resize events from the WM generated ones, but I don’t know if
that event struct have some unused space to incorporate this flag.On Wednesday 02 July 2003 16:42, Andreas Bombe wrote:

On Tue, Jul 01, 2003 at 03:19:25PM -0500, Bob Pendleton wrote:

If you use a while(poll) loop to handle events you can set a flag
and save state each time you get a resize event inside the loop,
and then only do the call to SetVideoMode() out side the loop. That
is, you receive any number of resize events in the loop, but only
respond to the last one you see.

That makes it less likely, but it’s still skippy. It’s what I do
now, but without a delay after the last resize event, it still looks
like this:

346 frames, 114.95 s, 1.9 fps
resize event 672x641
resizing to 672x641
resize event 681x656
resizing to 681x656
resize event 687x668
resizing to 687x668
349 frames, 116.48 s, 2.0 fps
resize event 700x687
resizing to 700x687
resize event 705x692
resizing to 705x692
resize event 700x687
resizing to 700x687
352 frames, 118.18 s, 1.8 fps
resize event 705x692
resizing to 705x692
355 frames, 119.40 s, 2.5 fps

I think it would be good if one could differentiate the setVideoMode()
generated resize events from the WM generated ones, but I don’t know if
that event struct have some unused space to incorporate this flag.

The only way to tell would be to see if the actual resolution matched
the last resolution set via SDL_SetVideoMode(), which it already checks.

See ya,
-Sam Lantinga, Software Engineer, Blizzard Entertainment

This may sound crazy, but maybe set the video mode if the mouse button is up?

The problem comes from the fact that you have very low FPS,

80 frames, 1.64 s, 48.8 fps
191 frames, 3.13 s, 74.2 fps
resize event 627x425
resizing to 627x425
resize event 595x389
resizing to 595x389
resize event 583x376
resizing to 583x376
resize event 536x329
resizing to 536x329
resize event 583x376
resizing to 583x376
resize event 536x329
resizing to 536x329
resize event 492x297
resizing to 492x297
resize event 536x329
resizing to 536x329
258 frames, 4.64 s, 44.4 fps
resize event 492x297
resizing to 492x297

Now this was on hardware accelerated OpenGL.

I think it would be good if one could differentiate the setVideoMode()
generated resize events from the WM generated ones, but I don’t know if
that event struct have some unused space to incorporate this flag.

Too complicated and wouldn’t work. All resize events are WM generated,
AFAIK.

The real solution is a new function for making SDL adapt its screen
surface to the new dimensions without attempting to change the window
size. Everything else (like my solution to delay SetVideoMode() until
0.5 seconds after the last resize event) is just a work-around.

The way is to split SetVideoMode() into its two components “setting up
environment” and “setting up library internal resources” by turning the
latter into its own public function and make SetVideoMode() do the
former and call the new function to do the latter. Technically this is
just a new feature, no API breakage follows. Maybe I’ll look into the
source if I find the time.On Wed, Jul 02, 2003 at 08:08:07PM +0300, Sami N??t?nen wrote:


Andreas Bombe <@Andreas_Bombe> DSA key 0x04880A44