Sign in to follow this  

[SDL] Dragging Window Problem

This topic is 3201 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey fellas, Whenever I move/drag my SDL Window by clicking on the title bar, the SDL program basically pauses until I release my left mouse button, where it resumes as it should. However, this sort of messes up the Timer (SDL_GetTicks()) that I use in my update(Uint32 d_ticks) function in my game loop.. My question is: is there anyway to detect when the user is moving/dragging the window so that I can pause my Timer and resume after the user is done dragging? This will greatly fix alot of buggy situations. I hope that was clear enough.. Thanks! :)

Share this post


Link to post
Share on other sites
I've been struggling with this problem as well (albeit a different aspect of it).

As I understand it at least, the root of the problem is that Windows blocks the main thread while the window is being dragged or resized, so anything that you do in the main thread (updating, rendering, etc.) will be suspended until the dragging or resizing is completed.

In your case, is the problem that the first time step computed after the window is released is very large? If so, a simple and practical solution might be simply to clamp the time step to some reasonable maximum value.

Also, if I may ask, what graphics API are you using? And when you drag the window partway off of and then back onto the screen, what behavior do you observe? (For example, is the part of the window that went offscreen 'blanked out' until you release the mouse button?)

Share this post


Link to post
Share on other sites
Hey jyk, thanks for the quick response,

Ah, limiting the time step is a possible solution if nothing will work. Thanks for that tip! However, I am really hoping to be able to somehow pause the timer..

Also, to answer your question: the graphics API I am using is just SDL (SDL_image). When I dragged my window partway off and on again, the entire image is still preserved (just frozen in time), nothing is blacked-out.

Share this post


Link to post
Share on other sites
Quote:
Also, to answer your question: the graphics API I am using is just SDL (SDL_image). When I dragged my window partway off and on again, the entire image is still preserved (just frozen in time), nothing is blacked-out.
Ah, I see. Yes, the problem I described only seems to occur when using an external graphics API such as OpenGL or Direct3D (it doesn't seem to be an issue when using SDL's built-in software rendering functionality).

Share this post


Link to post
Share on other sites
Ah, anyhow, if there's any way to be able to detect when the user is dragging the window, please let me know! Perhaps some kind of SDL_event sort of like how resizing the screen pushes the event SDL_RESIZEWINDOW..

Share this post


Link to post
Share on other sites
Quote:
Ah, anyhow, if there's any way to be able to detect when the user is dragging the window, please let me know! Perhaps some kind of SDL_event sort of like how resizing the screen pushes the event SDL_RESIZEWINDOW..
I'm not sure off the top of my head if SDL dispatches any events that would give you an opportunity to do something *before* the user starts to drag the window (my guess is though that is doesn't).

Keep in mind though that your main thread will be blocked while the window is being dragged, so unless you find a way to do some work in a different thread, you're not going to be able to do anything during this time.

Now when you say 'pause the timer', do you mean to somehow 'pause' the passage of time as far as SDL_GetTicks() is concerned, so that it will effectively return the same value both immediately before and immediately after window dragging occurs?

If so, I don't know that that's possible. You could pause your *own* timer, but again, that would require somehow knowing in advance that a window resize or drag event was about to occur.

Another option would be to somehow make use of SDL's 'event filter' callback. Keep in mind though that this may be called from a thread other than the main thread.

The problem I'm trying to solve is more or less independent of what events SDL does or does not send when the window is dragged, so I haven't investigated that aspect of things very carefully. If I find out anything though, I'll certainly post back with more information.

Share this post


Link to post
Share on other sites
I don't know if this will help solve your problem, but here are my informal observations about what events are sent, and when.

When the mouse leaves the client area of the window, you get an 'active' event (this is clearly documented, so it's no mystery). However, you don't get an event when the user clicks on the title bar.

While the window is being dragged, 'video expose' events are sent to the event filter function (if you've installed one).

When the mouse button is released, you get a 'video expose' event, and when the mouse re-enters the client area, you get an 'active' event.

Again, between the time the user clicks on the title bar and the time the post-move 'video expose' event is sent, your main thread will be blocked.

This is based on informal observation (just from printing all received events to the console), but it seems to be consistent with what I've read in the SDL docs and elsewhere. Anyway, that should give you a pretty good idea of what you have to work with as far as SDL events go.

Share this post


Link to post
Share on other sites
Wow, you are awesome jyk, thanks alot for your help

After considering what you said, I tried the video expose method, but somehow didn't like it that the game would pause when I click anywhere outside of the window.

Then, I tried capping my timer, and it actually worked beautifully. All of my bugs that revolved around my ticks-number being too high when dragging my window were all squashed duly. Thanks alot!

Share this post


Link to post
Share on other sites
I have actually had this issue myself and the problem I had was that part of the game logic meant that the time spent moving the window was still time elapsed in the game so a "pause" wouldn't help me much.

I ended up with something like this for a main loop to fix it:

while(running)
{
const Uint32 max_delta = 32;
now_time = SDL_GetTicks();
delta = now_time - last_time;

while( delta > 0 )
{
Uint32 dtime = std::min<Uint32>(delta,max_delta);
ProcessGameStuffLikePhysics(dtime);
delta -= dtime;
}

DrawStuff();
last_time = now_time;
}


I get a little bit of lag on the screen for a second where things seem jumpy while things catch up depending on the move time but once it catches up it looks the same on 2 instances where one window moves and the other doesn't.

The biggest thing this overcame was with the physics and moving through objects. Long delays where a wraparound occurs in the counters screw things up but that is where a max delay can really help out to just reset the screen and give up trying to sync.

Hope that helps.

Share this post


Link to post
Share on other sites

This topic is 3201 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this