From 018c18a1ed2e2d7833acadc0724b504b67fb8404 Mon Sep 17 00:00:00 2001 From: yutent Date: Mon, 31 Jul 2023 16:19:19 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4=E7=9B=AE=E5=BD=95=E7=BB=93?= =?UTF-8?q?=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .httpserver | 4 ---- inject.js | 27 +++++++++++++++++---- main.py | 32 +++++++++++++++++++++---- notes/mimetypes.py | 34 +++++++++++++++++++++++++++ notes/protocal.py | 38 ++++++++++++++++++++++++++++++ app.js => webview/app.js | 40 +++++++++++++++++++++----------- index.html => webview/index.html | 11 +++++---- 7 files changed, 155 insertions(+), 31 deletions(-) delete mode 100644 .httpserver create mode 100644 notes/mimetypes.py create mode 100644 notes/protocal.py rename app.js => webview/app.js (75%) rename index.html => webview/index.html (51%) diff --git a/.httpserver b/.httpserver deleted file mode 100644 index b118066..0000000 --- a/.httpserver +++ /dev/null @@ -1,4 +0,0 @@ -{ - "enabled": true, - "port": 10086 -} diff --git a/inject.js b/inject.js index e5479a5..b47d05b 100644 --- a/inject.js +++ b/inject.js @@ -89,11 +89,11 @@ class NativeImage { this.type = MIME_TYPES[obj.filepath.split('.').pop()] } - toPixbuf() { + toJSON() { return this.#origin } - export(type) { + export(type, base64) { let _ = defer() let canvas = document.createElement('canvas') canvas.width = this.width @@ -110,9 +110,25 @@ class NativeImage { } ctx.putImageData(imgData, 0, 0) - canvas.toBlob(_.resolve, type || this.type, 1) - return _.promise + if (base64) { + return canvas.toDataURL(type || this.type, 1) + } else { + canvas.toBlob(_.resolve, type || this.type, 1) + return _.promise + } + } + + toPNG() { + return this.export('image/png') + } + + toJPEG() { + return this.export('image/jpeg') + } + + toDataURL(type) { + return this.export(type, true) } } @@ -188,8 +204,9 @@ Object.assign(native, { ) }, writeImage(value) { + // 暂不知原因, postMessage传给Gtk后, JSON.stringify()并未读取toJSON的结果 if (typeof value === 'object') { - value = value.toPixbuf() + value = value.toJSON() } return handler('clipboard', { action: 'set_image', value }, null) }, diff --git a/main.py b/main.py index c81f86a..5a14429 100755 --- a/main.py +++ b/main.py @@ -7,10 +7,11 @@ gi.require_version("Gtk", "3.0") gi.require_version("WebKit2", "4.1") gi.require_version("Keybinder", "3.0") -from gi.repository import Gtk, Gdk, WebKit2, GLib, Keybinder +from gi.repository import Gtk, Gdk, WebKit2, GLib, Gio, Keybinder from gi.repository.GdkPixbuf import Pixbuf from notes.utils import * +from notes.mimetypes import get_mimetype # 优先尝试使用指示器, 没有再使用 Gtk.StatusIcon try: @@ -37,6 +38,7 @@ class WebKitWindow(Gtk.Window): settings.set_enable_offline_web_application_cache(True) settings.set_enable_developer_extras(True) + # settings.set_disable_web_security(True) @@ -65,8 +67,14 @@ class WebKitWindow(Gtk.Window): self.webview.set_settings(settings) + context = self.webview.get_context() + context.register_uri_scheme('app', self.resource_request_callback) + # self.webview.connect("resource-load-started", self.resource_request_callback) + + - self.webview.load_uri("http://127.0.0.1:10086/index.html") + # self.webview.load_uri("http://127.0.0.1:10086/index.html") + self.webview.load_uri("app:///index.html") # self.webview.load_uri("https://benchmark.wkit.fun") @@ -79,12 +87,28 @@ class WebKitWindow(Gtk.Window): self.add(self.webview) + def resource_request_callback(self, req): + + schema = req.get_scheme() + pathname = req.get_path() + ext = pathname.split('.')[-1] - + if schema == 'app': + data = open(self.file_path('./webview' + pathname)).read() + data = Gio.MemoryInputStream.new_from_data(data.encode()) + # res = WebKit2.URISchemeResponse.new(data, -1) + # res.set_content_type(get_mimetype(ext)) + # res.set_http_headers('text/html') + # res.set_status(200) + # req.finish_with_response(res) + req.finish(data, -1, get_mimetype(ext)) + return True + else: + return False def create_tray(self): - if not AppIndicator3 : + if AppIndicator3 : indicator = AppIndicator3.Indicator.new( "youtube", "youtube", diff --git a/notes/mimetypes.py b/notes/mimetypes.py new file mode 100644 index 0000000..caaaf28 --- /dev/null +++ b/notes/mimetypes.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 + + + +mime_types = { + 'html': 'text/html', + 'txt': 'text/plain', + 'css': 'text/css', + 'xml': 'text/xml', + 'gif': 'image/gif', + 'jpg': 'image/jpeg', + 'webp': 'image/webp', + 'tiff': 'image/tiff', + 'png': 'image/png', + 'svg': 'image/svg+xml', + 'ico': 'image/x-icon', + 'bmp': 'image/x-ms-bmp', + 'js': 'application/javascript', + 'json': 'application/json', + 'mp3': 'audio/mpeg', + 'ogg': 'audio/ogg', + 'm4a': 'audio/x-m4a', + 'mp4': 'video/mp4', + 'webm': 'video/webm', + 'ttf': 'font/font-ttf', + 'woff': 'font/font-woff', + 'woff2': 'font/font-woff2', + 'wast': 'application/wast', + 'wasm': 'application/wasm', + 'other': 'application/octet-stream' +} + +def get_mimetype(name): + return mime_types.get(name) or mime_types['html'] \ No newline at end of file diff --git a/notes/protocal.py b/notes/protocal.py new file mode 100644 index 0000000..8900b37 --- /dev/null +++ b/notes/protocal.py @@ -0,0 +1,38 @@ + +import os +from gi.repository import Gio +from .mimetypes import get_mimetype + +def file_path(filepath): + root = os.path.dirname(os.path.realpath(__file__)) + return os.path.join(root, filepath) + +def resource_request_callback(req): + + schema = req.get_scheme() + pathname = req.get_path() + ext = pathname.split('.')[-1] + + print('----------------------------------------') + print(req.get_uri(),schema, pathname, ext, get_mimetype(ext)) + print('----------------------------------------') + + if schema == 'app': + data = open(file_path('./webview' + pathname)).read() + data = Gio.MemoryInputStream.new_from_data(data.encode()) + + # ------- 更多功能的reponse ---------------- + # res = WebKit2.URISchemeResponse.new(data, -1) + # res.set_content_type(get_mimetype(ext)) + # res.set_http_headers('text/html') + # res.set_status(200) + # req.finish_with_response(res) + # ---------------------------------------- + + # 简单的response + req.finish(data, -1, get_mimetype(ext)) + + +def register_schenes(webview): + context = webview.get_context() + context.register_uri_scheme('app', resource_request_callback) \ No newline at end of file diff --git a/app.js b/webview/app.js similarity index 75% rename from app.js rename to webview/app.js index a557e25..9f38ed2 100644 --- a/app.js +++ b/webview/app.js @@ -66,14 +66,14 @@ class App extends Component { } async writeImage() { - // let img = await native.image('/code/gtk/webkit/debian.png') - // native.clipboard.writeImage(img) - native.clipboard.writeImage('/code/gtk/webkit/red.png') - // try { - // this.img = URL.createObjectURL(await img.export()) - // } catch (err) { - // alert(err) - // } + let img = await native.image('/code/gtk/webkit/debian.png') + native.clipboard.writeImage(img) + // native.clipboard.writeImage('/code/gtk/webkit/red.png') + try { + this.img = URL.createObjectURL(await img.export()) + } catch (err) { + alert(err) + } } quit() { @@ -96,14 +96,28 @@ class App extends Component { async pasteImg(ev) { let items = ev.clipboardData.items + // let items = ev.clipboardData.getData('image/png') + // let items = await navigator.clipboard.read() + // let img - let img = await window?.native?.clipboard?.readImage() + console.log(items) + return + // for (let item of items) { + // if (item.types.includes('image/png')) { + // img = await item.getType('image/png') + // console.log(img) + // this.img = URL.createObjectURL(img) + // return + // } + // } - console.log(img) + // let img = await window?.native?.clipboard?.readImage() - if (img) { - this.img = URL.createObjectURL(await img.export()) - } + // console.log(img) + + // if (img) { + // this.img = URL.createObjectURL(await img.export()) + // } for (let it of items) { let file = it.getAsFile() diff --git a/index.html b/webview/index.html similarity index 51% rename from index.html rename to webview/index.html index e975b38..05a6580 100644 --- a/index.html +++ b/webview/index.html @@ -8,11 +8,12 @@