diff --git a/app.js b/app.js
index 2bde6c8..a6254b7 100644
--- a/app.js
+++ b/app.js
@@ -7,22 +7,42 @@
import 'es.shim'
import { $, bind } from 'wkit'
-function test1() {
- try {
- window.webkit.messageHandlers.app.postMessage({
- data: { foo: 'Test 1' }
- })
- $('#output').innerHTML = '这是没有回调的 '
- } catch (err) {
- alert(err)
- }
+async function test1() {
+ let txt = await native.clipboard.readText()
+ $('input').value = txt
}
-function test2() {
- native.handler('blabla', { foo: 'bar' }).then(r => {
- $('#output').innerHTML = JSON.stringify(r)
- })
+async function test2() {
+ native.clipboard.writeText('这是一段写进剪切板的文本')
+ // native.handler('blabla', { foo: 'bar' }).then(r => {
+ // $('#output').innerHTML = JSON.stringify(r)
+ // })
}
bind($('.btn1'), 'click', test1)
bind($('.btn2'), 'click', test2)
+bind($('.btn3'), 'click', async function () {
+ // window.open('about:blank')
+ // let img = await native.clipboard.writeImage('/code/gtk/webkit/debian.png')
+ let img = await native.image('/code/gtk/webkit/debian.png')
+ native.clipboard.writeImage(img)
+ // native.clipboard.writeImage('/code/gtk/webkit/debian.png')
+ try {
+ $('img').src = URL.createObjectURL(await img.export())
+ } catch (err) {
+ alert(err)
+ }
+})
+bind($('.btn4'), 'click', async function () {
+ native.quit()
+ // native.clipboard.clear()
+})
+
+bind($('textarea'), 'paste', async function (ev) {
+ let items = ev.clipboardData.items
+ for (let it of items) {
+ let file = it.getAsFile()
+ $('img').src = URL.createObjectURL(file)
+ break
+ }
+})
diff --git a/debian.png b/debian.png
new file mode 100644
index 0000000..249de87
Binary files /dev/null and b/debian.png differ
diff --git a/demo.js b/demo.js
new file mode 100644
index 0000000..3b501dd
--- /dev/null
+++ b/demo.js
@@ -0,0 +1,5 @@
+import fs from 'iofs'
+
+let buf = fs.cat('./debian.png')
+console.log(buf)
+console.log([...buf], buf.byteLength)
diff --git a/index.html b/index.html
index 5312038..7b4e8b5 100644
--- a/index.html
+++ b/index.html
@@ -16,6 +16,9 @@
}
}
+
@@ -25,6 +28,14 @@
打开控制台
loading...
+
+
+
+
+
+
+
+
diff --git a/inject.js b/inject.js
index 0840957..a3e7149 100644
--- a/inject.js
+++ b/inject.js
@@ -3,6 +3,40 @@
* @author yutent
* @date 2023/07/21 17:38:11
*/
+const MIME_TYPES = {
+ html: 'text/html',
+ json: 'application/json',
+ js: 'application/javascript',
+ htm: 'text/html',
+ txt: 'text/plain',
+ css: 'text/css',
+ webp: 'image/webp',
+ jpg: 'image/jpg',
+ jpeg: 'image/jpeg',
+ png: 'image/png',
+ gif: 'image/gif',
+ svg: 'image/svg+xml',
+ ico: 'image/ico',
+ mp3: 'audio/mpeg',
+ ogg: 'audio/ogg',
+ m4a: 'audio/m4a',
+ amr: 'audio/amr',
+ mp4: 'video/mp4',
+ webm: 'video/webm',
+ wasm: 'application/wasm',
+ asm: 'application/asm',
+ zip: 'application/zip',
+ '7z': 'application/x-7z-compressed',
+ eot: 'application/vnd.ms-fontobject',
+ ttf: 'font/ttf',
+ otf: 'font/otf',
+ woff: 'font/woff',
+ woff2: 'font/woff2',
+ xls: 'application/vnd.ms-excel',
+ doc: 'application/msword',
+ xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+ docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
+}
function defer() {
let obj = {}
@@ -19,8 +53,14 @@ function rand(prefix = 'cb_') {
function handler(event, data = {}, once = true) {
let _ = defer()
- let callback = rand()
- native[once ? '$once' : '$on'](callback, _.resolve)
+ let callback
+
+ if (typeof once === 'boolean') {
+ callback = rand()
+ native[once ? '$once' : '$on'](callback, _.resolve)
+ } else {
+ _.resolve(true)
+ }
window.webkit.messageHandlers.app.postMessage({
event,
data,
@@ -29,6 +69,43 @@ function handler(event, data = {}, once = true) {
return _.promise
}
+class NativeImage {
+ #origin
+
+ constructor(obj) {
+ this.#origin = obj
+ this.width = obj.width
+ this.height = obj.height
+ this.type = MIME_TYPES[obj.filepath.split('.').pop()]
+ }
+
+ toPixbuf() {
+ return this.#origin
+ }
+
+ export(type) {
+ let _ = defer()
+ let canvas = document.createElement('canvas')
+ canvas.width = this.width
+ canvas.height = this.height
+ let ctx = canvas.getContext('2d')
+ let imgData = ctx.getImageData(0, 0, this.width, this.height)
+ let data = imgData.data
+
+ for (let i = 0; i < this.#origin.bytes.length; i += 4) {
+ imgData.data[i] = this.#origin.bytes[i]
+ imgData.data[i + 1] = this.#origin.bytes[i + 1]
+ imgData.data[i + 2] = this.#origin.bytes[i + 2]
+ imgData.data[i + 3] = this.#origin.bytes[i + 3]
+ }
+
+ ctx.putImageData(imgData, 0, 0)
+ canvas.toBlob(_.resolve, type || this.type, 1)
+
+ return _.promise
+ }
+}
+
class EventEmitter {
//
__events__ = Object.create(null)
@@ -79,8 +156,34 @@ class EventEmitter {
window.native = new EventEmitter()
Object.assign(native, {
+ quit() {
+ return handler('quit')
+ },
fs: {
read(filepath) {}
},
+ image(filepath) {
+ return handler('image', { value: filepath }).then(r => new NativeImage(r))
+ },
+ clipboard: {
+ readText() {
+ return handler('clipboard', { action: 'wait_for_text' })
+ },
+ writeText(value) {
+ return handler('clipboard', { action: 'set_text', value }, null)
+ },
+ readImage() {
+ return handler('clipboard', { action: 'wait_for_image' })
+ },
+ writeImage(value) {
+ if (typeof value === 'object') {
+ value = value.toPixbuf()
+ }
+ return handler('clipboard', { action: 'set_image', value }, null)
+ },
+ clear() {
+ return handler('clipboard', { action: 'clear' })
+ }
+ },
handler
})
diff --git a/main.py b/main.py
index dd51dda..b9183a1 100755
--- a/main.py
+++ b/main.py
@@ -2,10 +2,12 @@
import gi, json, os
+
gi.require_version("Gtk", "3.0")
gi.require_version("WebKit2", "4.1")
-from gi.repository import Gtk, WebKit2
+from gi.repository import Gtk, Gdk, WebKit2, GLib
+from gi.repository.GdkPixbuf import Pixbuf
class WebKitWindow(Gtk.Window):
@@ -46,6 +48,9 @@ class WebKitWindow(Gtk.Window):
# self.webview.load_uri("https://benchmark.wkit.fun")
+ self.clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
+
+
self.add(self.webview)
@@ -54,7 +59,6 @@ class WebKitWindow(Gtk.Window):
def create_tray(self):
indicator = Gtk.StatusIcon.new_from_icon_name('youtube')
-
indicator.connect('activate', self.toggle_visible)
return indicator
@@ -68,6 +72,8 @@ class WebKitWindow(Gtk.Window):
else:
self.present()
+
+
def file_path(self, filepath):
@@ -76,19 +82,86 @@ class WebKitWindow(Gtk.Window):
def on_script_message(self, webview, message):
- data = message.get_js_value()
- data = json.loads(data.to_json(0))
- print('这是py收到的值: ',data)
+
+ data = json.loads(message.get_js_value().to_json(0))
+
event = data.get('event')
callback = data.get('callback')
- res = {"foo": 123, "bar": (11,22,33)}
+ params = data.get('data')
+
match event:
case 'fs':
pass
+ case 'clipboard':
+ output = None
+
+ # 读文本
+ if params['action'] == 'wait_for_text':
+ output = self.clipboard.wait_for_text()
+
+ # 写文本
+ elif params['action'] == 'set_text':
+ self.clipboard.set_text(params['value'], -1)
+
+ # 写图片
+ elif params['action'] == 'set_image':
+ image = params['value']
+ # 前端传进来的值, 如果是路径的话, 直接读取
+ if type(image) == str:
+ image = Pixbuf.new_from_file(image)
+ else:
+ image = Pixbuf.new_from_data(
+ data = bytes(image['bytes']),
+ colorspace = image['colorspace'],
+ has_alpha = image['has_alpha'],
+ bits_per_sample = image['bits_per_sample'],
+ width = image['width'],
+ height = image['height'],
+ rowstride = image['rowstride']
+ )
+
+ self.clipboard.set_image(image)
+ self.clipboard.store()
+
+ # 清除剪切板
+ elif params['action'] == 'clear':
+ self.clipboard.clear()
+
+ # 回调给前端
+ if callback and output:
+ scripts = 'native.$emit("' + callback + '",' + json.dumps(output) + ')'
+ print(scripts)
+ self.webview.evaluate_javascript(scripts, -1)
+
+ # 退出app
+ case 'quit':
+ Gtk.main_quit()
+
+ # 读取图片, 返回图片像素数据
+ case 'image':
+ filename = params['value']
+ pixbuf = Pixbuf.new_from_file(filename)
+ image = {
+ "width": pixbuf.get_width(),
+ "height": pixbuf.get_height(),
+ "colorspace": pixbuf.get_colorspace(),
+ "has_alpha": pixbuf. get_has_alpha(),
+ "bits_per_sample": pixbuf.get_bits_per_sample(),
+ "rowstride": pixbuf.get_rowstride(),
+ "filepath": filename,
+ "bytes": list(pixbuf.get_pixels())
+ }
+
+
+ scripts = 'native.$emit("' + callback + '",' + json.dumps(image) + ')'
+
+ self.webview.evaluate_javascript(scripts, -1)
+
case _:
if callback :
+ res = {"foo": 123, "bar": (11,22,33)}
scripts = 'native.$emit("' + callback + '",' + json.dumps(res) + ')'
print(scripts)
self.webview.evaluate_javascript(scripts, -1)
@@ -115,6 +188,4 @@ win.show_all()
tray = win.create_tray()
-print(tray)
-
Gtk.main()
\ No newline at end of file
diff --git a/notes/clipboard.py b/notes/clipboard.py
new file mode 100644
index 0000000..c5808da
--- /dev/null
+++ b/notes/clipboard.py
@@ -0,0 +1,41 @@
+
+import gi
+
+gi.require_version("Gtk", "3.0")
+
+from gi.repository import Gtk, Gdk
+from gi.repository.GdkPixbuf import Pixbuf
+
+clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
+
+
+# 读剪切板中的文本
+output = clipboard.wait_for_text()
+
+# 写文本进剪切板
+clipboard.set_text('blabla', -1)
+
+
+
+# 从文件中读取
+filepath = 'xxx.png'
+image = Pixbuf.new_from_file(filepath)
+
+# 从其他地方拿到的图片像素对象
+image = Pixbuf.new_from_data(
+ data = bytes(image['bytes']),
+ colorspace = image['colorspace'],
+ has_alpha = image['has_alpha'],
+ bits_per_sample = image['bits_per_sample'],
+ width = image['width'],
+ height = image['height'],
+ rowstride = image['rowstride']
+)
+
+clipboard.set_image(image)
+clipboard.store()
+
+
+
+# 清除
+clipboard.clear()
\ No newline at end of file
diff --git a/notes/image.py b/notes/image.py
new file mode 100644
index 0000000..a63b25f
--- /dev/null
+++ b/notes/image.py
@@ -0,0 +1,40 @@
+import gi
+
+gi.require_version("Gtk", "3.0")
+
+from gi.repository import Gtk, Gdk
+from gi.repository.GdkPixbuf import Pixbuf
+
+# 读取图片, 返回图片像素数据
+filename = 'xxx.png'
+pixbuf = Pixbuf.new_from_file(filename)
+
+# 得到这个对象, 就是可以传给前端的,
+
+image = {
+ "width": pixbuf.get_width(),
+ "height": pixbuf.get_height(),
+ "colorspace": pixbuf.get_colorspace(),
+ "has_alpha": pixbuf. get_has_alpha(),
+ "bits_per_sample": pixbuf.get_bits_per_sample(),
+ "rowstride": pixbuf.get_rowstride(),
+ "filepath": filename,
+ "bytes": list(pixbuf.get_pixels())
+}
+
+# scripts = 'native.$emit("' + callback + '",' + json.dumps(image) + ')'
+
+# 倒扣到前端传回来的数据, 调用 Pixbuf.new_from_data 可转回 Pixbuf对象
+pixbuf = Pixbuf.new_from_data(
+ data = bytes(image['bytes']),
+ colorspace = image['colorspace'],
+ has_alpha = image['has_alpha'],
+ bits_per_sample = image['bits_per_sample'],
+ width = image['width'],
+ height = image['height'],
+ rowstride = image['rowstride']
+)
+
+
+
+