SDL_WINDOWEVENT SDL_WINDOWEVENT_SIZE_CHANGED SDL_WINDOWEVENT_RESIZED not responding

I have written a python script to create a resizeable sdl2 window. That works. However, I don’t seem to be able to get sdl2.SDL_WINDOWEVENT sdl2.SDL_WINDOWEVENT_SIZE_CHANGED sdl2.SDL_WINDOWEVENT_RESIZE to respond. Below is my script.

Please advice how I can print out the new window size each time the window size changes.

#!/bin/env python3

''' SDL2 Window. '''

__author__ = 'sunbearc22'

import sdl2
import sdl2.ext


class SetWindow:
    """ Class to create, destroy and manage sdl2 window."""
    
    def __init__(self, title="SDL2 Window", x=sdl2.SDL_WINDOWPOS_UNDEFINED,
                 y=sdl2.SDL_WINDOWPOS_UNDEFINED, w=400, h=400, flags=0):
        """Initialisation"""
        self.title = title
        self.x = x
        self.y = y
        self.w = w
        self.h = h
        self.flags = flags
        print('SDL2 Window parameters initialised')

        self._create()


    def _create(self):
        '''Create SDL2 Window'''

        if sdl2.SDL_Init( sdl2.SDL_INIT_VIDEO ) != 0:
            print('SDL2 library with video flag fail to initialise')
            exit()
        print('SDL2 library with video flag initialised.')

        self.window = sdl2.SDL_CreateWindow(
            self.title.encode('ascii'), self.x, self.y, self.w, self.h,
            self.flags)

        if not self.window: 
            print('Fail to create SDL2 window.')
            exit()
        print('Created SDL2 Window: {}.'.format(self.title))


    def getWindowSize(self):
        '''Get SDL2 Window width & height '''
        sdl2.SDL_GetWindowSize( self.window, w, h )
        print('sdlWindowsize = {}'.format( [w, h]))
        return w, h


    def destroy(self):
        '''Destroy and quit SDL2 window'''
        sdl2.SDL_DestroyWindow(self.window) # Close and destroy SDL2 window
        sdl2.SDL_Quit() # Clean up SDL2
        print('Destroyed SDL2 window and quited SDL2')


def main():
    vflags = sdl2.SDL_WINDOW_RESIZABLE
    window = SetWindow(title="Test Window - Resizable", w=800, h=200,
                       flags=vflags)
    # Main loop
    running = True
    print('SDL2 Main Loop: Executing.')

    while running:
        #Check for any events that piled up since the last check.
        events = sdl2.ext.get_events()
        for event in events:
            if event.type == sdl2.SDL_QUIT:
                print('SDL2 Main Loop: sdl2.SDL_QUIT.')
                running = False
                break
            if event.type == sdl2.SDL_WINDOWEVENT:
                if event.type == sdl2.SDL_WINDOWEVENT_SIZE_CHANGED:
                    print('SDL_WINDOWEVENT_SIZE_CHANGED')
                    print('window.data1, window.data2 = ',
                          event.window.data1, event.window.data2)
                    newWidth, newHeight = window.getWindowSize()
                    break

                if event.type == sdl2.SDL_WINDOWEVENT_RESIZED:
                    print('SDL_WINDOWEVENT_RESIZED')
                    print('window.data1, window.data2 = ',
                          event.window.data1, event.window.data2)
                    newWidth, newHeight = window.getWindowSize()
                    break
    if not running:
        window.destroy()


if __name__ == '__main__':
    main()

They should be if event.event == surely? You’ve already checked that event.type is SDL_WINDOWEVENT.

Could you elaborate? I did not understand your reply. Thanks.
This sdl example showed that SDL_WINDOWEVENT_SIZE_CHANGED and SDL_WINDOWEVENT_RESIZED is used within a SDL_WINDOWEVENT loop.

Incidentally, does my code works on your system or results in the same issues I mentioned?

Thanks rtrussel. I got what you mean. I should just write

if sdl2.SDL_WINDOWEVENT_SIZE_CHANGED:
if sdl2.SDL_WINDOWEVENT_RESIZED:

I also added definitions to w and h for my code to work. Had to also import ctype.

    def getWindowSize(self):
        '''Get SDL2 Window width & height '''
        w = ctypes.c_int() # Represents the C signed int datatype
        h = ctypes.c_int()

However, this part of my code

 print('window.data1, window.data2 = ',
      event.window.data1, event.window.data2)

still prints

window.data1, window.data2 = 0 0

Can you tell me what is the correct syntax?

What he means is that you are using event.type on the second line here again when according to the example it should be event->window.event

Edit: and something else in python obviously

symbol "-> " is valid for C but not python. Hence I used “.” to replace it.

Check out the definition and code example of the SDL_WindowEvent structure here.

I noticed that i can’t close the window now when i press X on the window bar. I have pasted my revised scripted below.
Appreciate your help to understand what is hindering the window from shutting down and how to print event->window.data1 in python. The example is in C and I don’t quite understand it.

#!/bin/env python3

''' SDL2 Window. '''

__author__ = 'sunbearc22'

import sdl2
import sdl2.ext
import ctypes


class SetWindow:
    """ Class to create, destroy and manage sdl2 window."""
    
    def __init__(self, title="SDL2 Window", x=sdl2.SDL_WINDOWPOS_UNDEFINED,
                 y=sdl2.SDL_WINDOWPOS_UNDEFINED, w=400, h=400, flags=0):
        """Initialisation"""
        self.title = title
        self.x = x
        self.y = y
        self.w = w
        self.h = h
        self.flags = flags
        print('SDL2 Window parameters initialised')

        self._create()


    def _create(self):
        '''Create SDL2 Window'''

        if sdl2.SDL_Init( sdl2.SDL_INIT_VIDEO ) != 0:
            print('SDL2 library with video flag fail to initialise')
            exit()
        print('SDL2 library with video flag initialised.')

        self.window = sdl2.SDL_CreateWindow(
            self.title.encode('ascii'), self.x, self.y, self.w, self.h,
            self.flags)

        if not self.window: 
            print('Fail to create SDL2 window.')
            exit()
        print('Created SDL2 Window: {}.'.format(self.title))


    def getWindowSize(self):
        '''Get SDL2 Window width & height '''
        w = ctypes.c_int() # Represents the C signed int datatype
        h = ctypes.c_int()
        sdl2.SDL_GetWindowSize( self.window, w, h )
        print('sdlWindowsize = {}'.format( [w, h]))
        return w, h


    def destroy(self):
        '''Destroy and quit SDL2 window'''
        sdl2.SDL_DestroyWindow(self.window) # Close and destroy SDL2 window
        sdl2.SDL_Quit() # Clean up SDL2
        print('Destroyed SDL2 window and quited SDL2')


def main():
    vflags = sdl2.SDL_WINDOW_RESIZABLE
    window = SetWindow(title="Test Window - Resizable", w=800, h=200,
                       flags=vflags)
    # Main loop
    running = True
    print('SDL2 Main Loop: Executing.')

    while running:
        #Check for any events that piled up since the last check.
        events = sdl2.ext.get_events()
        for event in events:

            if event.type == sdl2.SDL_QUIT:
                print('SDL2 Main Loop: sdl2.SDL_QUIT.')
                running = False
                break

            if event.type == sdl2.SDL_WINDOWEVENT:
                if sdl2.SDL_WINDOWEVENT_SIZE_CHANGED:
                    print('SDL_WINDOWEVENT_SIZE_CHANGED')
                    print('window.data1, window.data2 = ',
                          event.window.data1, event.window.data2)
                    newWidth, newHeight = window.getWindowSize()
                    break

                if sdl2.SDL_WINDOWEVENT_RESIZED:
                    print('SDL_WINDOWEVENT_RESIZED')
                    print('window.data1, window.data2 = ',
                          event.window.data1, event.window.data2)
                    newWidth, newHeight = window.getWindowSize()
                    break

    #if not running:
    #    window.destroy()
    window.destroy()


if __name__ == '__main__':
    main()

I’m not familiar with Python so I don’t fully understand your code, but you can check for the SDL_WINDOWEVENT_CLOSE event and do whatever is necessary to shutdown the program (set ‘running = False’ ?) there.

Thank you very much for you help. Many online sdl resources use gives examples relating to C and not python. Would still have been stuck if not for your pointer. I will look into the flag you have suggested and if am still stuck i will raise a separate issue.

I found out that the event.window.data1, event.window.data2 commands do work. When the window size changes, the new window width and height are returned. However, when the window size does not change and yet other window event do occur, e.g. the mouse pointer moves in or out of the window, they will return zero values. This is unlike SDL_GetWindowSize which returns the window size every time a window event is triggered.

Thanks again.

How do I close this issue or label it solved?

The page to which I linked previously documents the data1 and data2 members as “event dependent data”. You therefore need to drill down into the description of the individual event IDs here to discover what they contain. Only SDL_WINDOWEVENT_MOVED and SDL_WINDOWEVENT_RESIZED state that those members contain anything useful.

Unfortunately, however, the code example on the same page immediately contradicts this by showing the data1 and data2 members being read in a handler for the SDL_WINDOWEVENT_SIZE_CHANGED event, which does not claim to set them! I’m afraid this is only too typical of the poor quality of the SDL2 documentation.

I figured it out. There are 2 two approaches to building and managing a sdl2 window in pysdl2.

  1. There is sdl2 which is a pure 1:1 python wrapper to sdl2. It’s syntax closely resemble the SDL 2.0 Wiki syntax that we have been referring to in our discussion.
  2. Then, there is the sdl2.ext syntax. There are differences. I had to read the python script sdl2.ext.window.py that is located in /usr/local/lib/python3.5/dist-packages/sdl2/ext to realize the differences. Fortunately the script was heavy commented which made understanding the differences easier.

My script had issue terminating the window because it initiated and created a window using sdl2 but used sdl2.ext to initiate and monitor the window’s main event loop. I have revised my script to adopt only sdl2 syntax. You can run it on command line using “python3 filemame.py”, you need python3 installed, and will find the window works well resizing, reporting current window size and terminates cleanly.

My script can be amended to follow sdl2.ext syntax. Interested folks can read more on how to do it here .

My revised script is posted below. It creates and monitors a resizeable window, based on pysdl2's sdl syntax. I hope it (and the above explanations) can help others, who are interested in using pysdl2 to create a platform neutral window, speed up their learning.

#!/bin/env python3

''' SDL2 Window. '''

__author__ = 'sunbearc22'

import sys
import sdl2
import ctypes


class SetWindow:
    """ Class to create, destroy and manage sdl2 window."""
    
    def __init__(self, title="SDL2 Window", x=sdl2.SDL_WINDOWPOS_UNDEFINED,
                 y=sdl2.SDL_WINDOWPOS_UNDEFINED, w=400, h=400, flags=0):
        """Initialisation"""
        self.title = title
        self.x = x
        self.y = y
        self.w = w
        self.h = h
        self.flags = flags
        print('SDL2 Window parameters initialised')

        self._create()


    def _create(self):
        '''Create SDL2 Window'''

        if sdl2.SDL_Init( sdl2.SDL_INIT_VIDEO ) != 0:
            print('SDL2 library with video flag fail to initialise')
            exit()
        print('SDL2 library with video flag initialised.')

        self.window = sdl2.SDL_CreateWindow(
            self.title.encode('ascii'), self.x, self.y, self.w, self.h,
            self.flags)

        if not self.window: 
            print('Fail to create SDL2 window.')
            exit()
        print('Created SDL2 Window: {}.'.format(self.title))


    def getWindowSize(self):
        '''Get SDL2 Window width & height '''
        w = ctypes.c_int() # Represents the C signed int datatype
        h = ctypes.c_int()
        sdl2.SDL_GetWindowSize( self.window, w, h )
        print('sdlWindowsize = {}'.format( [w, h]))
        return w, h


    def destroy(self):
        '''Destroy and quit SDL2 window'''
        sdl2.SDL_DestroyWindow(self.window) # Close and destroy SDL2 window
        sdl2.SDL_Quit() # Clean up SDL2
        print('Destroyed SDL2 window and quited SDL2')


def main():
    vflags = sdl2.SDL_WINDOW_RESIZABLE | sdl2.SDL_WINDOW_SHOWN
    window = SetWindow(title="Test Window - Resizable", w=800, h=200,
                       flags=vflags)
    # Main loop
    running = True
    event = sdl2.SDL_Event()
    print('SDL2 Main Loop: Executing.')
    while running:

        # Poll for currently pending events.
        while sdl2.SDL_PollEvent(ctypes.byref(event)) != 0:        

            if event.type == sdl2.SDL_QUIT:
                print('SDL2 Main Loop: sdl2.SDL_QUIT.')
                running = False
                break

            if event.type == sdl2.SDL_WINDOWEVENT:
                if event.window.event == sdl2.SDL_WINDOWEVENT_SIZE_CHANGED:
                    print('SDL_WINDOWEVENT_SIZE_CHANGED: windowID {0}:'
                          ' [{1} {2}]'.format( event.window.windowID,
                                               event.window.data1,
                                               event.window.data2))
                    newWidth, newHeight = window.getWindowSize()
                    print('')
                    break

                
    window.destroy()
    return 0



if __name__ == '__main__':
    sys.exit(main())

Edit: @macusva explained that “if sdl2.SDL_WINDOWEVENT_SIZE_CHANGED:” is inappropriate. The correct syntax is “if event.window.event == sdl2.SDL_WINDOWEVENT_SIZE_CHANGED:”. This ensures that only window size change events is detected. It also ensures that event.window.data1 and data2 returns the new window width and height (I have removed outdated comments relating to this matter from this writeup). I have update my script with the correct syntax.