gui/applets: startup and embedding working

This commit is contained in:
Sebastien Bourdeauducq 2016-01-08 13:04:36 +08:00
parent e106ee3f90
commit 597c2e4b17
2 changed files with 42 additions and 6 deletions

View File

@ -112,6 +112,7 @@ def main():
smgr.register(d_datasets) smgr.register(d_datasets)
appletmgr = applets.AppletManager(dock_area) appletmgr = applets.AppletManager(dock_area)
atexit_register_coroutine(appletmgr.stop)
smgr.register(appletmgr) smgr.register(appletmgr)
if os.name != "nt": if os.name != "nt":

View File

@ -1,4 +1,6 @@
import logging import logging
import asyncio
import shlex
from quamash import QtCore, QtGui, QtWidgets from quamash import QtCore, QtGui, QtWidgets
from pyqtgraph import dockarea from pyqtgraph import dockarea
@ -8,23 +10,50 @@ logger = logging.getLogger(__name__)
class AppletDock(dockarea.Dock): class AppletDock(dockarea.Dock):
def __init__(self, token, name): def __init__(self, token, name, command):
dockarea.Dock.__init__(self, "applet" + str(token), dockarea.Dock.__init__(self, "applet" + str(token),
label="Applet: " + name, label="Applet: " + name,
closable=True) closable=True)
self.setMinimumSize(QtCore.QSize(500, 400)) self.setMinimumSize(QtCore.QSize(500, 400))
self.token = token
self.applet_name = name
self.command = command
async def start(self):
command = self.command.format(embed_token=self.token)
logger.debug("starting command %s for %s", command, self.applet_name)
try:
self.process = await asyncio.create_subprocess_exec(
*shlex.split(command))
except FileNotFoundError:
logger.warning("Applet %s failed to start", self.applet_name)
else:
logger.warning("Applet %s exited", self.applet_name)
def capture(self, win_id): def capture(self, win_id):
logger.debug("capturing window 0x%x for %s", win_id, self.applet_name)
self.captured_window = QtGui.QWindow.fromWinId(win_id) self.captured_window = QtGui.QWindow.fromWinId(win_id)
self.captured_widget = QtWidgets.QWidget.createWindowContainer(captured_window) self.captured_widget = QtWidgets.QWidget.createWindowContainer(
self.addWidget(captured_widget) self.captured_window)
self.addWidget(self.captured_widget)
def terminate(self): async def terminate(self):
if hasattr(self, "captured_window"): if hasattr(self, "captured_window"):
self.captured_window.close() self.captured_window.close()
self.captured_widget.deleteLater() self.captured_widget.deleteLater()
del self.captured_window del self.captured_window
del self.captured_widget del self.captured_widget
if hasattr(self, "process"):
try:
await asyncio.wait_for(self.process.wait(), 2.0)
except:
logger.warning("Applet %s failed to exit, killing",
self.applet_name)
try:
self.process.kill()
except ProcessLookupError:
pass
await self.process.wait()
class AppletsDock(dockarea.Dock): class AppletsDock(dockarea.Dock):
@ -116,18 +145,24 @@ class AppletManager:
logger.warning("Ignored incorrect embed token %d for winid 0x%x", logger.warning("Ignored incorrect embed token %d for winid 0x%x",
token, win_id) token, win_id)
return return
self.applet_docks[token].capture(win_id)
def create(self, name, command): def create(self, name, command):
token = next(iter(set(range(len(self.applet_docks) + 1)) token = next(iter(set(range(len(self.applet_docks) + 1))
- self.applet_docks.keys())) - self.applet_docks.keys()))
dock = AppletDock(token, name) dock = AppletDock(token, name, command)
self.applet_docks[token] = dock self.applet_docks[token] = dock
self.dock_area.floatDock(dock) self.dock_area.floatDock(dock)
asyncio.ensure_future(dock.start())
return token return token
def delete(self, token): def delete(self, token):
del self.applet_docks[token] del self.applet_docks[token]
async def stop(self):
for dock in self.applet_docks.values():
await dock.terminate()
def save_state(self): def save_state(self):
return dict() return dict()