23

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?

genpfault
  • 51,148
  • 11
  • 85
  • 139
bfkjohns
  • 353
  • 1
  • 2
  • 7
  • 2
    Try [`SDL_WINDOWEVENT_SIZE_CHANGED`](https://wiki.libsdl.org/SDL_WindowEventID) – Ivan Aksamentov - Drop Aug 30 '15 at 09:12
  • 4
    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! https://wiki.libsdl.org/SDL_WindowEventID – david van brink Dec 22 '15 at 18:48
  • 4
    It's actually impossible because of this bug: https://bugzilla.libsdl.org/show_bug.cgi?id=2077 – LB-- Feb 28 '16 at 16:22
  • There is `SDL_SetWindowsMessageHook` which will call supplied function on every Windows message, before `TranslateMessage`. – Xeverous Mar 24 '21 at 14:53

3 Answers3

17
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.

Qix - MONICA WAS MISTREATED
  • 14,451
  • 16
  • 82
  • 145
ZhuYaDong
  • 191
  • 1
  • 5
  • @pergy in this case, there are no much differences.. but i think it's because this will make a thread, always executed. i think – manudicri Jun 25 '18 at 10:23
  • 1
    @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! – jeremyong Nov 03 '18 at 14:33
0

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).

Elad Maimoni
  • 3,703
  • 3
  • 20
  • 37
-8

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.

Kevin Duarte
  • 424
  • 1
  • 4
  • 13