RAHHH
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
# Copyright (c) Twisted Matrix Laboratories.
|
||||
# See LICENSE for details.
|
||||
|
||||
"""
|
||||
This module provides support for Twisted to interact with the glib
|
||||
mainloop via GObject Introspection.
|
||||
|
||||
In order to use this support, simply do the following::
|
||||
|
||||
from twisted.internet import gireactor
|
||||
gireactor.install()
|
||||
|
||||
If you wish to use a GApplication, register it with the reactor::
|
||||
|
||||
from twisted.internet import reactor
|
||||
reactor.registerGApplication(app)
|
||||
|
||||
Then use twisted.internet APIs as usual.
|
||||
|
||||
On Python 3, pygobject v3.4 or later is required.
|
||||
"""
|
||||
|
||||
|
||||
from typing import Union
|
||||
|
||||
from gi.repository import GLib
|
||||
|
||||
from twisted.internet import _glibbase
|
||||
from twisted.internet.error import ReactorAlreadyRunning
|
||||
from twisted.python import runtime
|
||||
|
||||
if getattr(GLib, "threads_init", None) is not None:
|
||||
GLib.threads_init()
|
||||
|
||||
|
||||
class GIReactor(_glibbase.GlibReactorBase):
|
||||
"""
|
||||
GObject-introspection event loop reactor.
|
||||
|
||||
@ivar _gapplication: A C{Gio.Application} instance that was registered
|
||||
with C{registerGApplication}.
|
||||
"""
|
||||
|
||||
# By default no Application is registered:
|
||||
_gapplication = None
|
||||
|
||||
def __init__(self, useGtk=False):
|
||||
_glibbase.GlibReactorBase.__init__(self, GLib, None)
|
||||
|
||||
def registerGApplication(self, app):
|
||||
"""
|
||||
Register a C{Gio.Application} or C{Gtk.Application}, whose main loop
|
||||
will be used instead of the default one.
|
||||
|
||||
We will C{hold} the application so it doesn't exit on its own. In
|
||||
versions of C{python-gi} 3.2 and later, we exit the event loop using
|
||||
the C{app.quit} method which overrides any holds. Older versions are
|
||||
not supported.
|
||||
"""
|
||||
if self._gapplication is not None:
|
||||
raise RuntimeError("Can't register more than one application instance.")
|
||||
if self._started:
|
||||
raise ReactorAlreadyRunning(
|
||||
"Can't register application after reactor was started."
|
||||
)
|
||||
if not hasattr(app, "quit"):
|
||||
raise RuntimeError(
|
||||
"Application registration is not supported in"
|
||||
" versions of PyGObject prior to 3.2."
|
||||
)
|
||||
self._gapplication = app
|
||||
|
||||
def run():
|
||||
app.hold()
|
||||
app.run(None)
|
||||
|
||||
self._run = run
|
||||
|
||||
self._crash = app.quit
|
||||
|
||||
|
||||
class PortableGIReactor(_glibbase.GlibReactorBase):
|
||||
"""
|
||||
Portable GObject Introspection event loop reactor.
|
||||
"""
|
||||
|
||||
def __init__(self, useGtk=False):
|
||||
super().__init__(GLib, None, useGtk=useGtk)
|
||||
|
||||
def registerGApplication(self, app):
|
||||
"""
|
||||
Register a C{Gio.Application} or C{Gtk.Application}, whose main loop
|
||||
will be used instead of the default one.
|
||||
"""
|
||||
raise NotImplementedError("GApplication is not currently supported on Windows.")
|
||||
|
||||
def simulate(self) -> None:
|
||||
"""
|
||||
For compatibility only. Do nothing.
|
||||
"""
|
||||
|
||||
|
||||
def install(useGtk: bool = False) -> Union[GIReactor, PortableGIReactor]:
|
||||
"""
|
||||
Configure the twisted mainloop to be run inside the glib mainloop.
|
||||
|
||||
@param useGtk: A hint that the Gtk GUI will or will not be used. Currently
|
||||
does not modify any behavior.
|
||||
"""
|
||||
reactor: Union[GIReactor, PortableGIReactor]
|
||||
if runtime.platform.getType() == "posix":
|
||||
reactor = GIReactor(useGtk=useGtk)
|
||||
else:
|
||||
reactor = PortableGIReactor(useGtk=useGtk)
|
||||
|
||||
from twisted.internet.main import installReactor
|
||||
|
||||
installReactor(reactor)
|
||||
return reactor
|
||||
|
||||
|
||||
__all__ = ["install"]
|
||||
Reference in New Issue
Block a user