144 lines
4.6 KiB
Python
144 lines
4.6 KiB
Python
#!/usr/bin/env python3
|
|
import sys, time
|
|
import os
|
|
import subprocess
|
|
|
|
from qtpy.QtCore import QEvent, Property
|
|
from qtpy.QtGui import QWindow, QResizeEvent, QMoveEvent
|
|
from qtpy.QtWidgets import QWidget
|
|
|
|
from qtvcp.widgets.widget_baseclass import _HalWidgetBase
|
|
try:
|
|
from qtvcp.lib import xembed
|
|
except:
|
|
pass
|
|
from qtvcp import logger
|
|
|
|
# Instantiate the libraries with global reference
|
|
# LOG is for running code logging
|
|
LOG = logger.getLogger(__name__)
|
|
|
|
# Force the log level for this module
|
|
# LOG.setLevel(logger.INFO) # One of DEBUG, INFO, WARNING, ERROR, CRITICAL
|
|
|
|
class XEmbeddable(QWidget, _HalWidgetBase):
|
|
def __init__(self, parent=None):
|
|
super(XEmbeddable, self).__init__(parent)
|
|
|
|
def _hal_init(self):
|
|
pass
|
|
|
|
def embed(self, command):
|
|
if '-x {XID}' in command:
|
|
# convert gladevcp to other type of embedding
|
|
command = command.replace('-x {XID}', ' --xid ')
|
|
self.embed_program(command)
|
|
elif '{XID}' in command:
|
|
self.let_program_embed(command)
|
|
else:
|
|
self.embed_program(command)
|
|
|
|
# foreign program embeds it's self in our window
|
|
def let_program_embed(self,command):
|
|
self.w = QWindow()
|
|
self.container = QWidget.createWindowContainer(self.w, self)
|
|
|
|
xid = int(self.w.winId())
|
|
cmd = command.replace('{XID}', str(xid))
|
|
self.launch(cmd)
|
|
self.show()
|
|
# there seems to be a race - sometimes the foreign window doesn't embed
|
|
time.sleep(.2)
|
|
|
|
# we embed foreign program into our window
|
|
def embed_program(self, command):
|
|
try:
|
|
self.external_id = self.launch_xid(command)
|
|
window = QWindow.fromWinId(self.external_id)
|
|
self.container = QWidget.createWindowContainer(window, self)
|
|
self.show()
|
|
# there seems to be a race - sometimes the foreign window doesn't embed
|
|
time.sleep(.2)
|
|
return True
|
|
except Exception as e:
|
|
LOG.warning('Exception:{}'.format(command))
|
|
LOG.warning('Exception:{}'.format( e))
|
|
raise Exception(e)
|
|
return False
|
|
|
|
def event(self, event):
|
|
if event.type() == QEvent.Resize:
|
|
w = QResizeEvent.size(event)
|
|
try:
|
|
self.container.resize(w.width(), w.height())
|
|
except:
|
|
pass
|
|
elif event.type() == QEvent.Move:
|
|
try:
|
|
self.container.move(QMoveEvent.pos(event))
|
|
except:
|
|
pass
|
|
return True
|
|
|
|
# launches program that embeds it's self into our window
|
|
# The foreign program never resizes as the window changes
|
|
def launch(self, cmd):
|
|
c = cmd.split()
|
|
self.ob = subprocess.Popen(c,stdin = subprocess.PIPE,
|
|
stdout = subprocess.PIPE)
|
|
|
|
# returns program's XID number so we can embed it into our window
|
|
# This works the best - the window resizes properly
|
|
# still not great qt4 worked so much better
|
|
def launch_xid(self,cmd):
|
|
c = cmd.split()
|
|
self.ob = subprocess.Popen(c,stdin = subprocess.PIPE,
|
|
stdout = subprocess.PIPE)
|
|
sid = self.ob.stdout.readline()
|
|
LOG.debug( 'XID: {}'.format(sid))
|
|
return int(sid)
|
|
|
|
def _hal_cleanup(self):
|
|
try:
|
|
self.ob.terminate()
|
|
except Exception as e:
|
|
print(e)
|
|
|
|
class XEmbed(XEmbeddable, _HalWidgetBase):
|
|
def __init__(self, parent=None):
|
|
super(XEmbed, self).__init__(parent)
|
|
self.command = None
|
|
|
|
def _hal_init(self):
|
|
# send embedded program our X window id so it can forward events to us.
|
|
wid = int(self.QTVCP_INSTANCE_.winId())
|
|
print('parent wind id', wid)
|
|
os.environ['QTVCP_FORWARD_EVENTS_TO'] = str(wid)
|
|
LOG.debug( 'Emed command: {}'.format(self.command))
|
|
result = self.embed(self.command)
|
|
if result:
|
|
return
|
|
self.x11mess = xembed.X11ClientMessage(self.external_id)
|
|
|
|
|
|
def send_x11_message(self,):
|
|
self.x11mess.send_client_message()
|
|
|
|
def set_command(self, data):
|
|
self.command = data
|
|
def get_command(self):
|
|
return self.command
|
|
def reset_command(self):
|
|
self.command = None
|
|
|
|
command_string = Property(str, get_command, set_command, reset_command)
|
|
|
|
if __name__ == '__main__':
|
|
from qtpy.QtWidgets import QApplication
|
|
app = QApplication(sys.argv)
|
|
ex = XEmbed()
|
|
ex.embed('halcmd loadusr gladevcp --xid ../../gladevcp/offsetpage.glade')
|
|
ex.show()
|
|
ex.setWindowTitle('embed')
|
|
sys.exit(app.exec())
|