pythonlinuxx11gtk4mpv

How to render MPV to GTK4 window on X11 with python?


How can mpv render to GTK4 window or widget? In GTK3 it was quite easy to get XID (and put it as argument to MPV) but in GTK4 It seem have to be done with GtkX11 and X11Surface https://docs.gtk.org/gdk4-x11/method.X11Surface.get_xid.html But I have not clue how to do that in python - can't get surface from window/widget.

#!/usr/bin/env python3
import gi
import mpv

gi.require_version('Gtk', '4.0')
gi.require_version('Gdk', '4.0')
gi.require_version('GdkX11', '4.0')
from gi.repository import Gtk, Gdk, GdkX11


class MainClass(Gtk.ApplicationWindow):

    def __init__(self, app):
        super(MainClass, self).__init__()
        self.set_application(app)
        self.set_default_size(600, 400)
        self.connect("destroy", self.on_destroy)

        widget = Gtk.Frame()
        self.set_child(widget)
        self.present()

        # Can't get XID from widget there
        self.mpv = mpv.MPV(wid=str(GdkX11.X11Surface.get_xid(widget)))
        self.mpv.play("test.webm")

    def on_destroy(self, widget, data=None):
        self.mpv.terminate()
        Gtk.main_quit()


def on_activate(app):
    application = MainClass(app)


if __name__ == '__main__':
    # This is necessary since like Qt, Gtk stomps over the locale settings needed by libmpv.
    # Like with Qt, this needs to happen after importing Gtk but before creating the first mpv.MPV instance.
    import locale
    locale.setlocale(locale.LC_NUMERIC, 'C')

    app = Gtk.Application()
    app.connect('activate', on_activate)
    app.run(None)
TypeError: argument self: Expected GdkX11.X11Surface, but got gi.repository.Gtk.Frame

Solution

  • I don't know if this is completely correct
    GdkX11.X11Surface.get_xid() takes a X11Surface as a parameter
    Try this:

    self.mpv = mpv.MPV(wid=str(GdkX11.X11Surface.get_xid(self.get_surface())))
    

    This worked for me