使用python在多窗口之间做桥接

master
yutent 2023-09-08 15:06:42 +08:00
parent 1f2273150c
commit 80872e0678
4 changed files with 83 additions and 35 deletions

View File

@ -8,15 +8,19 @@ from gi.repository import GObject, Gtk, Gdk, WebKit2, GLib, Gio, GdkPixbuf
def create_same_window(origin, req):
WebEngine = type(origin)
w, h = origin.window.get_size()
win = Gtk.Window()
win.set_default_size(w, h)
web = WebKit2.WebView.new_with_related_view(origin)
web = WebEngine(win, origin)
web.set_zoom_level(origin.get_zoom_level())
web.set_settings(origin.get_settings())
web.load_request(req)
win.add(web)
win.show_all()
return web
@ -47,11 +51,8 @@ def create_custom_window(origin, options):
web = WebEngine(win)
# web = WebEngine(win, origin)
# web = WebKit2.WebView.new_with_related_view(origin)
# web = WebEngine.new_with(win, origin)
# web.window = win
web = WebEngine(win, origin)
web.set_root(origin.root, True)
web.set_zoom_level(origin.get_zoom_level())
web.set_settings(origin.get_settings())

View File

@ -13,6 +13,7 @@ from gi.repository import WebKit2
class Inject:
def __init__(self, webview, env = {}):
self.webview = webview
self.manager = webview.get_user_content_manager()
script_data = open(self.abspath('./inject.js'), 'r').read()

View File

@ -75,12 +75,14 @@ class WebEngine(WebKit2.WebView):
root = None
window = None
opener = None
custom_bridge = None
def __init__(self, win):
def __init__(self, win, opener = None):
WebKit2.WebView.__init__(self)
self.opener = opener
self.window = win
if win.get_title() is None:
@ -106,6 +108,8 @@ class WebEngine(WebKit2.WebView):
self.connect('create', self.create_new_window)
# 允许前端 widnow.close() 关闭窗口
self.connect('close', lambda w: win.close())
@ -182,7 +186,7 @@ class WebEngine(WebKit2.WebView):
# 退出app
case 'quit':
self.window.close()
# self.emit('quit')
self.emit('quit')
# 读取图片, 返回图片像素数据
case 'image':
@ -212,6 +216,16 @@ class WebEngine(WebKit2.WebView):
elif params['action'] == 'remove':
pass
case 'opener':
callback = 'opener_message'
output = params.get('data')
scripts = 'native.$emit("opener_message", ' + json.dumps(output) + ')'
if self.opener is None:
self.evaluate_javascript(scripts, -1)
else:
self.opener.evaluate_javascript(scripts, -1)
return
case 'window':
_error, output = self._window_setting(params)
@ -399,6 +413,9 @@ class WebEngine(WebKit2.WebView):
case 'create':
self.new_window_by_custom(params.get('options'))
case 'close':
self.window.close()
case 'fullscreen':
self.window.fullscreen()

View File

@ -45,6 +45,9 @@ const KEYS_MAP = {
super: '<Super>'
}
const NO_CALLBACK = false
const CALL_ONCE = true
function defer() {
let obj = {}
obj.promise = new Promise((resolve, reject) => {
@ -58,22 +61,23 @@ function rand(prefix = 'cb_') {
return prefix + Math.random().toString().slice(2)
}
function handler(event, data = {}, once = true) {
function handler(event, data = {}, need = CALL_ONCE) {
let _ = defer()
let callback
if (typeof once === 'boolean') {
if (need === NO_CALLBACK) {
_.resolve(true)
} else {
callback = rand()
native[once ? '$once' : '$on'](callback, (err, res) => {
native.$once(callback, (err, res) => {
if (err) {
_.reject(err)
} else {
_.resolve(res)
}
})
} else {
_.resolve(true)
}
window.webkit.messageHandlers.app.postMessage({
event,
data,
@ -188,11 +192,13 @@ class EventEmitter {
window.native = new EventEmitter()
native.$on('opener_message', data => window.postMessage(data))
Object.assign(native, {
env: '{{env}}',
quit() {
return handler('quit', {}, null)
return handler('quit', {}, NO_CALLBACK)
},
fs: {
access(filepath, mode = 'r') {
@ -250,7 +256,7 @@ Object.assign(native, {
return handler('clipboard', { action: 'wait_for_text' })
},
writeText(value) {
return handler('clipboard', { action: 'set_text', value }, null)
return handler('clipboard', { action: 'set_text', value }, NO_CALLBACK)
},
readImage() {
return handler('clipboard', { action: 'wait_for_image' }).then(r =>
@ -262,10 +268,10 @@ Object.assign(native, {
if (typeof value === 'object') {
value = value.toJSON()
}
return handler('clipboard', { action: 'set_image', value }, null)
return handler('clipboard', { action: 'set_image', value }, NO_CALLBACK)
},
clear() {
return handler('clipboard', { action: 'clear' })
return handler('clipboard', { action: 'clear' }, NO_CALLBACK)
}
},
screen: {
@ -338,51 +344,74 @@ Object.assign(native, {
return handler('tray', { action: 'set_status', value: status })
}
},
opener: {
//
postMessage(data = {}) {
return handler('opener', { action: 'postmessage', data }, NO_CALLBACK)
}
},
window: {
create(options = {}) {
return handler('window', { action: 'create', options })
},
close() {
return handler('window', { action: 'close' })
},
isVisible() {
return handler('window', { action: 'is_visible' })
},
toggleVisible() {
handler('window', { action: 'toggle_visible' }, null)
handler('window', { action: 'toggle_visible' }, NO_CALLBACK)
},
hide() {
handler('window', { action: 'hide' }, null)
handler('window', { action: 'hide' }, NO_CALLBACK)
},
show() {
handler('window', { action: 'show' }, null)
handler('window', { action: 'show' }, NO_CALLBACK)
},
fullscreen() {
handler('window', { action: 'fullscreen' }, null)
handler('window', { action: 'fullscreen' }, NO_CALLBACK)
},
unfullscreen() {
handler('window', { action: 'unfullscreen' }, null)
handler('window', { action: 'unfullscreen' }, NO_CALLBACK)
},
maximize() {
handler('window', { action: 'maximize' }, null)
handler('window', { action: 'maximize' }, NO_CALLBACK)
},
unmaximize() {
handler('window', { action: 'unmaximize' }, null)
handler('window', { action: 'unmaximize' }, NO_CALLBACK)
},
setTitle(title = '') {
handler('window', { action: 'set_title', value: title }, null)
handler('window', { action: 'set_title', value: title }, NO_CALLBACK)
},
resize(width = 0, height = 0) {
handler('window', { action: 'resize', value: { width, height } }, null)
handler(
'window',
{ action: 'resize', value: { width, height } },
NO_CALLBACK
)
},
move(x = 0, y = 0) {
handler('window', { action: 'move', value: { x, y } }, null)
handler('window', { action: 'move', value: { x, y } }, NO_CALLBACK)
},
setOpacity(opacity = 1) {
handler('window', { action: 'set_opacity', value: opacity }, null)
handler('window', { action: 'set_opacity', value: opacity }, NO_CALLBACK)
},
alwayOnTop(setting = true) {
handler('window', { action: 'set_keep_above', value: setting }, null)
handler(
'window',
{ action: 'set_keep_above', value: setting },
NO_CALLBACK
)
},
alwayOnBotttom(setting = true) {
handler('window', { action: 'set_keep_below', value: setting }, null)
handler(
'window',
{ action: 'set_keep_below', value: setting },
NO_CALLBACK
)
}
},
notify({ title, summary, icon, progress = 0, urgency = 0, callback }) {
@ -394,7 +423,7 @@ Object.assign(native, {
handler(
'notify',
{ title, summary, icon, progress, urgency, callback: eventName },
null
NO_CALLBACK
)
},
@ -404,13 +433,13 @@ Object.assign(native, {
proxy: {
disable() {
return handler('proxy', { action: 'disable' })
return handler('proxy', { action: 'disable' }, NO_CALLBACK)
},
system() {
return handler('proxy', { action: 'system' })
return handler('proxy', { action: 'system' }, NO_CALLBACK)
},
custom(url = '', ignore = null) {
return handler('proxy', { action: 'enable', url, ignore })
return handler('proxy', { action: 'enable', url, ignore }, NO_CALLBACK)
}
},