From 80872e06789222e48d24f1aecd0691808a73d376 Mon Sep 17 00:00:00 2001 From: yutent Date: Fri, 8 Sep 2023 15:06:42 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BD=BF=E7=94=A8python=E5=9C=A8=E5=A4=9A?= =?UTF-8?q?=E7=AA=97=E5=8F=A3=E4=B9=8B=E9=97=B4=E5=81=9A=E6=A1=A5=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../webengine/gtk3/_custom_window.py | 15 ++-- .../dist-packages/webengine/gtk3/_inject.py | 1 + .../webengine/gtk3/_webengine.py | 21 ++++- .../dist-packages/webengine/gtk3/inject.js | 81 +++++++++++++------ 4 files changed, 83 insertions(+), 35 deletions(-) diff --git a/usr/lib/python3/dist-packages/webengine/gtk3/_custom_window.py b/usr/lib/python3/dist-packages/webengine/gtk3/_custom_window.py index 1307253..f756573 100644 --- a/usr/lib/python3/dist-packages/webengine/gtk3/_custom_window.py +++ b/usr/lib/python3/dist-packages/webengine/gtk3/_custom_window.py @@ -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()) diff --git a/usr/lib/python3/dist-packages/webengine/gtk3/_inject.py b/usr/lib/python3/dist-packages/webengine/gtk3/_inject.py index 90f28f9..21c8368 100644 --- a/usr/lib/python3/dist-packages/webengine/gtk3/_inject.py +++ b/usr/lib/python3/dist-packages/webengine/gtk3/_inject.py @@ -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() diff --git a/usr/lib/python3/dist-packages/webengine/gtk3/_webengine.py b/usr/lib/python3/dist-packages/webengine/gtk3/_webengine.py index f684446..f6052d0 100644 --- a/usr/lib/python3/dist-packages/webengine/gtk3/_webengine.py +++ b/usr/lib/python3/dist-packages/webengine/gtk3/_webengine.py @@ -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() diff --git a/usr/lib/python3/dist-packages/webengine/gtk3/inject.js b/usr/lib/python3/dist-packages/webengine/gtk3/inject.js index ba535f7..0290976 100644 --- a/usr/lib/python3/dist-packages/webengine/gtk3/inject.js +++ b/usr/lib/python3/dist-packages/webengine/gtk3/inject.js @@ -45,6 +45,9 @@ const KEYS_MAP = { 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) } },