Getting Continuous Window Resize Event in SDL 2
Asked Answered
F

3

27

I use the following structure to get new width and height of the resized SDL window:

if (sdl_set->GetMainEvent()->type == SDL_WINDOWEVENT)
{
  if (sdl_set->GetMainEvent()->window.event == SDL_WINDOWEVENT_RESIZED)
  {
    ScreenWidth = sdl_set->GetMainEvent()->window.data1;
    ScreenHeight = sdl_set->GetMainEvent()->window.data2;
    cout << "Window Resized!" << endl;
  }
}

But with this structure I'm only able to get new data after the resizing is done that is when I finish dragging and release the mouse button.

How can I get the new data continuously, that is while I'm dragging the window?

Ferrochromium answered 30/8, 2015 at 9:2 Comment(4)
Try SDL_WINDOWEVENT_SIZE_CHANGEDPusher
SDL_WINDOWEVENT_SIZE_CHANGED is NOT documented as providing continuous resizing updates. And experimentally (on mac os x) it doesn't. I also would like to know how to get continuous resize events during the user gesture! wiki.libsdl.org/SDL_WindowEventIDPedicular
It's actually impossible because of this bug: bugzilla.libsdl.org/show_bug.cgi?id=2077Venola
There is SDL_SetWindowsMessageHook which will call supplied function on every Windows message, before TranslateMessage.Zinciferous
A
20
static int resizingEventWatcher(void* data, SDL_Event* event) {
  if (event->type == SDL_WINDOWEVENT &&
      event->window.event == SDL_WINDOWEVENT_RESIZED) {
    SDL_Window* win = SDL_GetWindowFromID(event->window.windowID);
    if (win == (SDL_Window*)data) {
      printf("resizing.....\n");
    }
  }
  return 0;
}

int main() {
    SDL_Window* win = ...
    ...
    SDL_AddEventWatch(resizingEventWatcher, win);
    ...
}

use SDL's EventWatch can resolve it.

Albeit answered 19/11, 2016 at 12:54 Comment(2)
@pergy in this case, there are no much differences.. but i think it's because this will make a thread, always executed. i thinkRecessional
@pergy Late response but happened to see this just now. The difference is that event watches are invoked by the thread emitting the event itself (which may be a system/OS thread). In this case, the event pump is blocked on the resizing action which doesn't return on the resize is finished. In the meantime, size change events are being queued, but they are being queued behind the current resizing operation. Adding an event watch to listen to these events effectively handles them on a different thread, giving you an opportunity to repaint. Careful with thread safety though!Cleanshaven
T
2

If you are using a single thread, setting up an event watcher using SDL_AddEventWatch is not enough. This is because SDL_PumpEvents (which is called directly or indirectly by sdl) will not return until resizing is done, effectively blocking your thread.

To workaround this, you can setup a callback in your event watcher:

    void Window::HandleWindowEvent(const SDL_WindowEvent e)
    {
        switch(e.event)
        {
        ...
        case SDL_WINDOWEVENT_MOVED:
            if (_lastWindowMetrics.left != e.data1 || _lastWindowMetrics.top != e.data2)
            {
                _lastWindowMetrics.left = e.data1;
                _lastWindowMetrics.top = e.data2;
                _windowEvents.emplace_back(_lastWindowMetrics);

                _refresh(); // user callback that may be used to repaint the window
            }
            break;
        case SDL_WINDOWEVENT_RESIZED:
        case SDL_WINDOWEVENT_SIZE_CHANGED:
            if (_lastWindowMetrics.width != e.data1 || _lastWindowMetrics.height != e.data2)
            {
                _lastWindowMetrics.width = e.data1;
                _lastWindowMetrics.height = e.data2;
                _windowEvents.emplace_back(_lastWindowMetrics);

                _refresh(); // user callback that may be used to repaint the window
            }
            break;
         ...
        }

    }

I use the watcher mechanism to handle all windows events and only use SDL_PumpEvents and not SDL_PollEvents.

This is quite similar to the mechanism offered by glfwSetWindowRefreshCallback (if you are used to glfw).

Toehold answered 22/7, 2023 at 11:17 Comment(0)
J
-11

If you are on windows, have you tried using the windows api?

I know its not a real fix but if you are not making a cross platform application, you should give it a shot.

Use HWND to find SDL's window and return the window size.

Juba answered 25/2, 2017 at 9:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.