Ubuntu Linux wxPython mediactrl fails under Wayland

Howdy All,

This issue has been tested under Ubuntu Linux 23.04 and 23.10. Python 3.11 and 3.12 and wx 4.2.1. Ubuntu is now running Wayland as default and this is the crux of my problem.

wx.mediactrl no longer seems to be working. The key issue is that it cannot bind to a window and I understand this is due to Wayland managing windows differently and mediactrl is trying to get a hook to a X window which doesn’t exist under Wayland.

The error message is here:
X Error of failed request: BadWindow (invalid Window parameter)
Major opcode of failed request: 2 (X_ChangeWindowAttributes)
Resource id in failed request: 0x22ae580
Serial number of failed request: 23
Current serial number in output stream: 26

Sample code to reproduce is here (Note you need to point to where your sample video is).

#!/usr/bin/env python3

import wx
import wx.media

----------------------------------------------------------------------------------------------------------------------

Window for displaying the full screen video player

class CheckAll(wx.Frame):
def init(self):
wx.Frame.init(self, wx.GetApp().TopWindow, -1, ‘’, size=wx.DisplaySize(), style=wx.NO_BORDER)

    self.Bind(wx.EVT_CLOSE, self.on_close)
    self.Bind(wx.EVT_CHAR_HOOK, self.on_keypress)

    self.panel = wx.Panel(self)
    self.panel.SetFocus()

    self.mc = wx.media.MediaCtrl(self.panel,
                            style=wx.SIMPLE_BORDER,
                            size=(-1, -1),
                            )
    self.Bind(wx.media.EVT_MEDIA_LOADED, self.on_media_loaded, self.mc)
    self.Bind(wx.media.EVT_MEDIA_FINISHED, self.on_media_stopped, self.mc)

    # --------------------------------------------------------------------------------------------------------------
    # Setup the sizer and add the buttons
    sizer = wx.BoxSizer(wx.VERTICAL)
    top_sizer = wx.BoxSizer(wx.HORIZONTAL)
    sizer.Add(self.mc, 1, wx.EXPAND)
    top_sizer.Add(sizer, 1, wx.ALL | wx.EXPAND)

    # --------------------------------------------------------------------------------------------------------------
    # Get the window to size automatically based upon sizer requirements
    # and show the sizer
    self.panel.SetSizerAndFit(top_sizer)
    top_sizer.Layout()

    # --------------------------------------------------------------------------------------------------------------
    # Display the window
    self.Centre()
    self.Show()
    self.ShowFullScreen(True, wx.FULLSCREEN_NOCAPTION)
    self.load_video()

# --------------------------------------------------------------------------------------------------------------
# This is the key press event handler
def on_keypress(self, event):
    self.on_close(-1)

# --------------------------------------------------------------------------------------------------------------
# Handle the close event and ensure the parent window is given back control
def on_close(self, _event):
    # Stop the currently playing video
    self.mc.Stop()
    self.Destroy()

# --------------------------------------------------------------------------------------------------------------
# Load the video pointed to by video_index
def load_video(self):
    file_to_load = r'../../mame/videos/pacman.mp4'
    self.mc.Load(file_to_load)

# --------------------------------------------------------------------------------------------------------------
# This is the media loaded event for wx MediaCtrl.  It starts the video playing.
def on_media_loaded(self, _event):
    self.mc.Play()  # Play the video

# --------------------------------------------------------------------------------------------------------------
# This is the media stopped event for wx MediaCtrl.  It points to the next video in the list and resumes playing.
def on_media_stopped(self, _event):
    self.load_video()

if name == ‘main’:
app = wx.App()
CheckAll()
app.MainLoop()

Unfortunately XWayland is very buggy and densest help. Things tend to be unstable and crash. If you Select X.Org as the desktop login rather than Wayland then it works fine but this is not a fix as more distributions now are moving to full-time Wayland support with some indicating they will drop X completely.

Does anyone know if anything is being worked on in this area for Wayland support? As a side note, python-vlc window bindings also don’t work under Wayland. Is there any in-window video player that does work?

I found the following PR in the wxWidgets GitHub repository which apparently got the wxMediaCtrl to work on Wayland.

I believe the PR was incorporated in wxWidgets 3.1.6.

However, wxPython 4.2.1 is built from wxWidgets 3.2.2.1 so perhaps something has broken Wayland support in the intervening period?

The only other report I could find of an error similar to what you are getting is in the following issue that was raised on the wxPython GitHub repo:

However that issue was found while running Debian under Windows Subsystem for Linux (WSL) on Windows 11 and I don’t know if that uses Wayland. In any case, no solution was discussed.

I’m not sure if that is the same issue that was patched previously. The symptoms seem to be different. This issue definitely looks like a problem with MediaCtrl wanting an X window id which it wont get from Wayland. I know python-vlc has this same issue.

Would appreciate if someone else could try to reproduce this just to make sure im not going crazy.

Can you please edit your reproducer code and put it into a code block? I can’t copy and paste it to try it.

In any event, I see the same error when running the wxPython MediaCtrl demo. I’m not entirely sure what’s going on. The wxWidgets support for Wayland in wxMediaCtrl landed a while ago - not sure why it doesn’t work in wxPython.

So it turns out that it depends on which version of the gstreamer backend wxWidgets is built against - if it is built against the gstplayer version, Wayland support works. If against the older gstreamer 1.0 version, Wayland support is still broken. So, if you rebuild with gstplayer, you should have better results.

ok well that is interesting. I’ll roll out a clean VM and test it. Will report back to confirm.

Appreciate the assistance on this one.

Hi swt2c, do you have specific details on the library to install? I cant find instructions for gstplayer.

Thanks.

On Ubuntu it should be libgstreamer-plugins-bad1.0-dev.

Thanks for that. Ok, so I can confirm that this does indeed allow wxMediaCtrl to work under Wayland but I do see some stability issues (GStreamer-GL-CRITICAL **: 18:07:06.827: Failed to flush Wayland connection). Probably with that library. Out of the scope of this discussion.

Should we be raising a bug report given that the standard gstreamer library is still not supported for Wayland under wxWidgets?

You can if you want, sure.