applets: workaround for Qt window embedding initial size bug

This commit is contained in:
Sebastien Bourdeauducq 2016-02-11 16:19:34 +01:00
parent cd9467a8df
commit 92c0ede689
2 changed files with 23 additions and 9 deletions

View File

@ -36,6 +36,9 @@ class AppletIPCClient(AsyncioChildComm):
action) action)
self.close_cb() self.close_cb()
def fix_initial_size(self):
self.write_pyon({"action": "fix_initial_size"})
async def listen(self): async def listen(self):
data = None data = None
while True: while True:
@ -133,13 +136,15 @@ class SimpleApplet:
# 2. applet creates native window without showing it, and get its ID # 2. applet creates native window without showing it, and get its ID
# 3. applet sends the ID to host, host embeds the widget # 3. applet sends the ID to host, host embeds the widget
# 4. applet shows the widget # 4. applet shows the widget
# Doing embedding the other way around (using QWindow.setParent in the # 5. parent resizes the widget
# applet) breaks resizing.
if self.args.embed is not None: if self.args.embed is not None:
self.ipc.set_close_cb(self.main_widget.close) self.ipc.set_close_cb(self.main_widget.close)
win_id = int(self.main_widget.winId()) win_id = int(self.main_widget.winId())
self.loop.run_until_complete(self.ipc.embed(win_id)) self.loop.run_until_complete(self.ipc.embed(win_id))
self.main_widget.show() self.main_widget.show()
self.ipc.fix_initial_size()
else:
self.main_widget.show()
def sub_init(self, data): def sub_init(self, data):
self.data = data self.data = data

View File

@ -44,7 +44,7 @@ class AppletIPCServer(AsyncioParentComm):
return return
self.write_pyon({"action": "mod", "mod": mod}) self.write_pyon({"action": "mod", "mod": mod})
async def serve(self, embed_cb): async def serve(self, embed_cb, fix_initial_size_cb):
self.datasets_sub.notify_cbs.append(self._on_mod) self.datasets_sub.notify_cbs.append(self._on_mod)
try: try:
while True: while True:
@ -54,6 +54,8 @@ class AppletIPCServer(AsyncioParentComm):
if action == "embed": if action == "embed":
embed_cb(obj["win_id"]) embed_cb(obj["win_id"])
self.write_pyon({"action": "embed_done"}) self.write_pyon({"action": "embed_done"})
elif action == "fix_initial_size":
fix_initial_size_cb()
elif action == "subscribe": elif action == "subscribe":
self.datasets = obj["datasets"] self.datasets = obj["datasets"]
if self.datasets_sub.model is not None: if self.datasets_sub.model is not None:
@ -74,8 +76,9 @@ class AppletIPCServer(AsyncioParentComm):
finally: finally:
self.datasets_sub.notify_cbs.remove(self._on_mod) self.datasets_sub.notify_cbs.remove(self._on_mod)
def start(self, embed_cb): def start(self, embed_cb, fix_initial_size_cb):
self.server_task = asyncio.ensure_future(self.serve(embed_cb)) self.server_task = asyncio.ensure_future(
self.serve(embed_cb, fix_initial_size_cb))
async def stop(self): async def stop(self):
self.server_task.cancel() self.server_task.cancel()
@ -109,14 +112,20 @@ class AppletDock(dockarea.Dock):
except: except:
logger.warning("Applet %s failed to start", self.applet_name, logger.warning("Applet %s failed to start", self.applet_name,
exc_info=True) exc_info=True)
self.ipc.start(self.embed) self.ipc.start(self.embed, self.fix_initial_size)
def embed(self, win_id): def embed(self, win_id):
logger.debug("capturing window 0x%x for %s", win_id, self.applet_name) logger.debug("capturing window 0x%x for %s", win_id, self.applet_name)
embed_window = QtGui.QWindow.fromWinId(win_id) self.embed_window = QtGui.QWindow.fromWinId(win_id)
self.embed_widget = QtWidgets.QWidget.createWindowContainer(embed_window) self.embed_widget = QtWidgets.QWidget.createWindowContainer(
self.embed_window)
self.addWidget(self.embed_widget) self.addWidget(self.embed_widget)
# HACK: This function would not be needed if Qt window embedding
# worked correctly.
def fix_initial_size(self):
self.embed_window.resize(self.embed_widget.size())
async def terminate(self): async def terminate(self):
if hasattr(self, "ipc"): if hasattr(self, "ipc"):
await self.ipc.stop() await self.ipc.stop()