Compare commits
No commits in common. "6f7141560a89dadd0545bb2adc8b9ed7294cf91a" and "c1f7e8e503560ce6e04d96e2ffd5b22fda88684e" have entirely different histories.
6f7141560a
...
c1f7e8e503
|
@ -1,10 +1,10 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import gi
|
||||
import gi, os, json, shutil, hashlib, time, threading
|
||||
|
||||
gi.require_version('Gtk', '3.0')
|
||||
gi.require_version("WebKit2", "4.1")
|
||||
from gi.repository import Gtk, WebKit2
|
||||
from gi.repository import GObject, Gtk, Gdk, WebKit2, GLib, Gio, GdkPixbuf
|
||||
|
||||
|
||||
def create_same_window(origin, req):
|
||||
|
@ -37,12 +37,6 @@ def create_custom_window(origin, options):
|
|||
win.set_wmclass(wmclass, 'WebEngine')
|
||||
win.set_title(options.get('title') or 'WebEngine')
|
||||
|
||||
if options.get('icon_path'):
|
||||
win.set_icon_from_file(options['icon_path'])
|
||||
|
||||
if options.get('icon'):
|
||||
win.set_icon_name(options['icon'])
|
||||
|
||||
if options.get('frame') == False:
|
||||
win.set_decorated(False)
|
||||
|
||||
|
@ -56,7 +50,9 @@ def create_custom_window(origin, options):
|
|||
win.set_resizable(False)
|
||||
|
||||
|
||||
web = WebEngine(win, origin, options.get('uuid'))
|
||||
|
||||
|
||||
web = WebEngine(win, origin)
|
||||
web.set_root(origin.root, True)
|
||||
web.set_zoom_level(origin.get_zoom_level())
|
||||
web.set_settings(origin.get_settings())
|
||||
|
|
|
@ -13,12 +13,13 @@ 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()
|
||||
frame = WebKit2.UserContentInjectedFrames.ALL_FRAMES
|
||||
time = WebKit2.UserScriptInjectionTime.END
|
||||
script_data = script_data.replace("'{{env}}'", json.dumps(env)).replace("{{uuid}}", webview.uuid)
|
||||
script_data = script_data.replace("'{{env}}'", json.dumps(env))
|
||||
script = WebKit2.UserScript(script_data, frame, time, None, None)
|
||||
|
||||
self.manager.add_script(script)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# @date 2023/08/08 14:07:26
|
||||
|
||||
|
||||
import gi, os, json, shutil, hashlib, random
|
||||
import gi, os, json, shutil, hashlib, time, threading
|
||||
|
||||
gi.require_version('Gtk', '3.0')
|
||||
gi.require_version("WebKit2", "4.1")
|
||||
|
@ -54,6 +54,18 @@ def noop():
|
|||
pass
|
||||
|
||||
|
||||
# 类型js的settimeout的修饰器
|
||||
def set_timeout(timeout = 0.5):
|
||||
def decorator(callback):
|
||||
def wrapper(*args):
|
||||
t = threading.Timer(timeout, callback, args=args)
|
||||
t.start()
|
||||
return t
|
||||
return wrapper
|
||||
|
||||
return decorator
|
||||
|
||||
|
||||
|
||||
class WebEngine(WebKit2.WebView):
|
||||
|
||||
|
@ -61,28 +73,18 @@ class WebEngine(WebKit2.WebView):
|
|||
'quit': (GObject.SignalFlags.RUN_FIRST, None, ())
|
||||
}
|
||||
|
||||
uuid = None
|
||||
root = None
|
||||
window = None
|
||||
opener = None
|
||||
children = set()
|
||||
custom_bridge = None
|
||||
|
||||
def __init__(self, win, opener = None, uuid = None):
|
||||
def __init__(self, win, opener = None):
|
||||
|
||||
WebKit2.WebView.__init__(self)
|
||||
|
||||
if uuid is None:
|
||||
self.uuid = random.randbytes(8).hex()
|
||||
else:
|
||||
self.uuid = uuid
|
||||
|
||||
self.opener = opener
|
||||
self.window = win
|
||||
|
||||
if opener is not None:
|
||||
opener.children.add(self)
|
||||
|
||||
if win.get_title() is None:
|
||||
win.set_title('WebEngine')
|
||||
|
||||
|
@ -107,22 +109,9 @@ class WebEngine(WebKit2.WebView):
|
|||
self.connect('create', self.create_new_window)
|
||||
|
||||
# 允许前端 widnow.close() 关闭窗口
|
||||
self.connect('close', self.close_window)
|
||||
win.connect("destroy", self.remove_from_opener) # 通过外部关闭窗口时从父级中移除
|
||||
self.connect('close', lambda w: win.close())
|
||||
|
||||
|
||||
def remove_from_opener(self, win = None):
|
||||
if self.opener is not None:
|
||||
try:
|
||||
self.opener.children.remove(self)
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
def close_window(self, wv = None):
|
||||
self.remove_from_opener()
|
||||
self.window.close()
|
||||
|
||||
|
||||
# 响应原生js的 window.open
|
||||
def create_new_window(self, webview, nav):
|
||||
|
@ -196,7 +185,7 @@ class WebEngine(WebKit2.WebView):
|
|||
|
||||
# 退出app
|
||||
case 'quit':
|
||||
self.close_window()
|
||||
self.window.close()
|
||||
self.emit('quit')
|
||||
|
||||
# 读取图片, 返回图片像素数据
|
||||
|
@ -230,31 +219,13 @@ class WebEngine(WebKit2.WebView):
|
|||
case 'opener':
|
||||
callback = 'opener_message'
|
||||
output = params.get('data')
|
||||
uuid = json.dumps(self.uuid if self.opener else None)
|
||||
scripts = f"native.$emit('opener_message', {json.dumps(output)}, {uuid})"
|
||||
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 'children':
|
||||
callback = 'opener_message'
|
||||
output = params.get('data')
|
||||
uuid = params.get('uuid')
|
||||
scripts = f"native.$emit('opener_message', {json.dumps(output)})"
|
||||
if len(self.children) == 0:
|
||||
self.evaluate_javascript(scripts, -1)
|
||||
else:
|
||||
if uuid is None:
|
||||
for child in self.children:
|
||||
child.evaluate_javascript(scripts, -1)
|
||||
else:
|
||||
for child in self.children:
|
||||
if child.uuid == uuid:
|
||||
child.evaluate_javascript(scripts, -1)
|
||||
return
|
||||
|
||||
case 'window':
|
||||
_error, output = self._window_setting(params)
|
||||
|
||||
|
@ -443,7 +414,7 @@ class WebEngine(WebKit2.WebView):
|
|||
self.new_window_by_custom(params.get('options'))
|
||||
|
||||
case 'close':
|
||||
self.close_window()
|
||||
self.window.close()
|
||||
|
||||
case 'fullscreen':
|
||||
self.window.fullscreen()
|
||||
|
|
|
@ -90,19 +90,6 @@ function base64(str = '') {
|
|||
return btoa(str).replace(/[+=\/]/g, '')
|
||||
}
|
||||
|
||||
function _postMessage(data = {}, uuid = null) {
|
||||
let ev = new Event('message')
|
||||
Object.assign(ev, {
|
||||
data,
|
||||
source: {
|
||||
postMessage(msg) {
|
||||
native.children.postMessage(msg, uuid)
|
||||
}
|
||||
}
|
||||
})
|
||||
window.dispatchEvent(ev)
|
||||
}
|
||||
|
||||
class NativeImage {
|
||||
#origin
|
||||
|
||||
|
@ -205,7 +192,7 @@ class EventEmitter {
|
|||
|
||||
window.native = new EventEmitter()
|
||||
|
||||
native.$on('opener_message', (data, uuid) => _postMessage(data, uuid))
|
||||
native.$on('opener_message', data => window.postMessage(data))
|
||||
|
||||
Object.assign(native, {
|
||||
env: '{{env}}',
|
||||
|
@ -358,21 +345,12 @@ Object.assign(native, {
|
|||
}
|
||||
},
|
||||
opener: {
|
||||
//
|
||||
postMessage(data = {}) {
|
||||
return handler('opener', { action: 'postmessage', data }, NO_CALLBACK)
|
||||
}
|
||||
},
|
||||
children: {
|
||||
postMessage(data = {}, uuid = null) {
|
||||
return handler(
|
||||
'children',
|
||||
{ action: 'postmessage', data, uuid },
|
||||
NO_CALLBACK
|
||||
)
|
||||
}
|
||||
},
|
||||
window: {
|
||||
uuid: '{{uuid}}',
|
||||
create(options = {}) {
|
||||
return handler('window', { action: 'create', options })
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue