File: xembed.py

package info (click to toggle)
linuxcnc 1%3A2.9.4-2
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 282,780 kB
  • sloc: python: 201,110; ansic: 106,370; cpp: 99,219; tcl: 16,054; xml: 10,617; sh: 10,258; makefile: 1,251; javascript: 138; sql: 72; asm: 15
file content (143 lines) | stat: -rw-r--r-- 4,695 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#!/usr/bin/env python3
import sys, time
import os
import subprocess

from PyQt5.QtCore import QEvent, pyqtProperty
from PyQt5.QtGui import QWindow, QResizeEvent, QMoveEvent
from PyQt5.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 = pyqtProperty(str, get_command, set_command, reset_command)

if __name__ == '__main__':
    from PyQt5.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_())