This repository has been archived on 2023-09-06. You can view files and clone it, but cannot push or open issues/pull-requests.
yutent
/
py-gtk-notes
Archived
1
0
Fork 0

调整目录结构

master
yutent 2023-07-31 16:19:19 +08:00
parent a08e1750e6
commit 018c18a1ed
7 changed files with 155 additions and 31 deletions

View File

@ -1,4 +0,0 @@
{
"enabled": true,
"port": 10086
}

View File

@ -89,11 +89,11 @@ class NativeImage {
this.type = MIME_TYPES[obj.filepath.split('.').pop()] this.type = MIME_TYPES[obj.filepath.split('.').pop()]
} }
toPixbuf() { toJSON() {
return this.#origin return this.#origin
} }
export(type) { export(type, base64) {
let _ = defer() let _ = defer()
let canvas = document.createElement('canvas') let canvas = document.createElement('canvas')
canvas.width = this.width canvas.width = this.width
@ -110,10 +110,26 @@ class NativeImage {
} }
ctx.putImageData(imgData, 0, 0) ctx.putImageData(imgData, 0, 0)
canvas.toBlob(_.resolve, type || this.type, 1)
if (base64) {
return canvas.toDataURL(type || this.type, 1)
} else {
canvas.toBlob(_.resolve, type || this.type, 1)
return _.promise return _.promise
} }
}
toPNG() {
return this.export('image/png')
}
toJPEG() {
return this.export('image/jpeg')
}
toDataURL(type) {
return this.export(type, true)
}
} }
class EventEmitter { class EventEmitter {
@ -188,8 +204,9 @@ Object.assign(native, {
) )
}, },
writeImage(value) { writeImage(value) {
// 暂不知原因, postMessage传给Gtk后, JSON.stringify()并未读取toJSON的结果
if (typeof value === 'object') { if (typeof value === 'object') {
value = value.toPixbuf() value = value.toJSON()
} }
return handler('clipboard', { action: 'set_image', value }, null) return handler('clipboard', { action: 'set_image', value }, null)
}, },

30
main.py
View File

@ -7,10 +7,11 @@ gi.require_version("Gtk", "3.0")
gi.require_version("WebKit2", "4.1") gi.require_version("WebKit2", "4.1")
gi.require_version("Keybinder", "3.0") 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 gi.repository.GdkPixbuf import Pixbuf
from notes.utils import * from notes.utils import *
from notes.mimetypes import get_mimetype
# 优先尝试使用指示器, 没有再使用 Gtk.StatusIcon # 优先尝试使用指示器, 没有再使用 Gtk.StatusIcon
try: try:
@ -37,6 +38,7 @@ class WebKitWindow(Gtk.Window):
settings.set_enable_offline_web_application_cache(True) settings.set_enable_offline_web_application_cache(True)
settings.set_enable_developer_extras(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) 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") # self.webview.load_uri("https://benchmark.wkit.fun")
@ -79,12 +87,28 @@ class WebKitWindow(Gtk.Window):
self.add(self.webview) 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): def create_tray(self):
if not AppIndicator3 : if AppIndicator3 :
indicator = AppIndicator3.Indicator.new( indicator = AppIndicator3.Indicator.new(
"youtube", "youtube",
"youtube", "youtube",

34
notes/mimetypes.py Normal file
View File

@ -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']

38
notes/protocal.py Normal file
View File

@ -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)

View File

@ -66,14 +66,14 @@ class App extends Component {
} }
async writeImage() { async writeImage() {
// let img = await native.image('/code/gtk/webkit/debian.png') let img = await native.image('/code/gtk/webkit/debian.png')
// native.clipboard.writeImage(img) native.clipboard.writeImage(img)
native.clipboard.writeImage('/code/gtk/webkit/red.png') // native.clipboard.writeImage('/code/gtk/webkit/red.png')
// try { try {
// this.img = URL.createObjectURL(await img.export()) this.img = URL.createObjectURL(await img.export())
// } catch (err) { } catch (err) {
// alert(err) alert(err)
// } }
} }
quit() { quit() {
@ -96,14 +96,28 @@ class App extends Component {
async pasteImg(ev) { async pasteImg(ev) {
let items = ev.clipboardData.items 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) { // console.log(img)
this.img = URL.createObjectURL(await img.export())
} // if (img) {
// this.img = URL.createObjectURL(await img.export())
// }
for (let it of items) { for (let it of items) {
let file = it.getAsFile() let file = it.getAsFile()

View File

@ -8,11 +8,12 @@
<script type="importmap"> <script type="importmap">
{ {
"imports":{ "imports":{
"es.shim":"//jscdn.ink/es.shim/latest/index.js", "es.shim":"https://jscdn.ink/es.shim/latest/index.js",
"wkit":"//jscdn.ink/wkit/latest/index.js", "wkit":"https://jscdn.ink/wkit/latest/index.js",
"vue":"//jscdn.ink/vue/3.2.47/vue.esm-browser.prod.js", "vue":"https://jscdn.ink/vue/3.2.47/vue.esm-browser.prod.js",
"vue-router":"//jscdn.ink/@bytedo/vue-router/4.1.6/vue-router.js","fetch":"//jscdn.ink/@bytedo/fetch/latest/next.js", "vue-router":"https://jscdn.ink/@bytedo/vue-router/4.1.6/vue-router.js",
"crypto":"//jscdn.ink/crypto.web.js/latest/index.js" "fetch":"https://jscdn.ink/@bytedo/fetch/latest/next.js",
"crypto":"https://jscdn.ink/crypto.web.js/latest/index.js"
} }
} }
</script> </script>