Compare commits
2 Commits
5da22eed8e
...
ece744aafe
Author | SHA1 | Date |
---|---|---|
yutent | ece744aafe | |
yutent | b398551deb |
|
@ -3,7 +3,8 @@
|
||||||
# @date 2023/08/08 14:07:26
|
# @date 2023/08/08 14:07:26
|
||||||
|
|
||||||
|
|
||||||
import gi, os, sys, json, shutil, hashlib, random
|
import gi, os, sys, json
|
||||||
|
import webbrowser, shutil, hashlib, random
|
||||||
|
|
||||||
gi.require_version('Gtk', '3.0')
|
gi.require_version('Gtk', '3.0')
|
||||||
gi.require_version("WebKit2", "4.1")
|
gi.require_version("WebKit2", "4.1")
|
||||||
|
@ -288,6 +289,25 @@ class WebEngine(WebKit2.WebView):
|
||||||
|
|
||||||
return (_error, output)
|
return (_error, output)
|
||||||
|
|
||||||
|
def _shell_handler(self, params = {}):
|
||||||
|
_error = None
|
||||||
|
output = None
|
||||||
|
path = params.get('path')
|
||||||
|
|
||||||
|
match(params.get('action')):
|
||||||
|
case 'openExternal':
|
||||||
|
webbrowser.open(params.get('url'))
|
||||||
|
|
||||||
|
case 'showItemInFolder':
|
||||||
|
os.system(f"xdg-open '{path}'")
|
||||||
|
|
||||||
|
case 'openPath':
|
||||||
|
os.system(f"xdg-open '{path}'")
|
||||||
|
|
||||||
|
case 'trashItem':
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _fs_handler(self, params = {}):
|
def _fs_handler(self, params = {}):
|
||||||
_error = None
|
_error = None
|
||||||
|
|
|
@ -3,488 +3,509 @@
|
||||||
* @author yutent<yutent.io@gmail.com>
|
* @author yutent<yutent.io@gmail.com>
|
||||||
* @date 2023/07/21 17:38:11
|
* @date 2023/07/21 17:38:11
|
||||||
*/
|
*/
|
||||||
|
!(function () {
|
||||||
|
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'
|
||||||
|
}
|
||||||
|
const KEYS_MAP = {
|
||||||
|
shift: '<Shift>',
|
||||||
|
ctrl: '<Ctrl>',
|
||||||
|
alt: '<Alt>',
|
||||||
|
super: '<Super>'
|
||||||
|
}
|
||||||
|
|
||||||
const MIME_TYPES = {
|
const NO_CALLBACK = false
|
||||||
html: 'text/html',
|
const CALL_ONCE = true
|
||||||
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'
|
|
||||||
}
|
|
||||||
const KEYS_MAP = {
|
|
||||||
shift: '<Shift>',
|
|
||||||
ctrl: '<Ctrl>',
|
|
||||||
alt: '<Alt>',
|
|
||||||
super: '<Super>'
|
|
||||||
}
|
|
||||||
|
|
||||||
const NO_CALLBACK = false
|
const __events__ = Symbol('events')
|
||||||
const CALL_ONCE = true
|
|
||||||
|
|
||||||
function defer() {
|
function defer() {
|
||||||
let obj = {}
|
let obj = {}
|
||||||
obj.promise = new Promise((resolve, reject) => {
|
obj.promise = new Promise((resolve, reject) => {
|
||||||
obj.resolve = resolve
|
obj.resolve = resolve
|
||||||
obj.reject = reject
|
obj.reject = reject
|
||||||
})
|
})
|
||||||
return obj
|
return obj
|
||||||
}
|
}
|
||||||
|
|
||||||
function rand(prefix = 'cb_') {
|
function rand(prefix = 'cb_') {
|
||||||
return prefix + Math.random().toString().slice(2)
|
return prefix + Math.random().toString().slice(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
function handler(event, data = {}, need = CALL_ONCE) {
|
function handler(event, data = {}, need = CALL_ONCE) {
|
||||||
let _ = defer()
|
let _ = defer()
|
||||||
let callback
|
let callback
|
||||||
|
|
||||||
if (need === NO_CALLBACK) {
|
if (need === NO_CALLBACK) {
|
||||||
_.resolve(true)
|
_.resolve(true)
|
||||||
} else {
|
} else {
|
||||||
callback = rand()
|
callback = rand()
|
||||||
native.$once(callback, (err, res) => {
|
native.$once(callback, (err, res) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
_.reject(err)
|
_.reject(err)
|
||||||
} else {
|
} else {
|
||||||
_.resolve(res)
|
_.resolve(res)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
window.webkit.messageHandlers.app.postMessage({
|
||||||
|
event,
|
||||||
|
data,
|
||||||
|
callback
|
||||||
|
})
|
||||||
|
return _.promise
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
function readonly(obj, key, value) {
|
||||||
|
Object.defineProperty(obj, key, {
|
||||||
|
get() {
|
||||||
|
return value
|
||||||
|
},
|
||||||
|
enumerable: false
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
window.webkit.messageHandlers.app.postMessage({
|
function _extend(origin, options = {}) {
|
||||||
event,
|
for (let k in options) {
|
||||||
data,
|
readonly(origin, k, options[k])
|
||||||
callback
|
}
|
||||||
})
|
}
|
||||||
return _.promise
|
|
||||||
}
|
|
||||||
|
|
||||||
function base64(str = '') {
|
class NativeImage {
|
||||||
return btoa(str).replace(/[+=\/]/g, '')
|
#origin
|
||||||
}
|
|
||||||
|
|
||||||
function _postMessage(data = {}, uuid = null) {
|
constructor(obj) {
|
||||||
let ev = new Event('message')
|
this.#origin = obj
|
||||||
Object.assign(ev, {
|
this.width = obj.width
|
||||||
data,
|
this.height = obj.height
|
||||||
source: {
|
this.type = MIME_TYPES[obj.filepath.split('.').pop()]
|
||||||
postMessage(msg) {
|
}
|
||||||
native.children.postMessage(msg, uuid)
|
|
||||||
|
toJSON() {
|
||||||
|
return this.#origin
|
||||||
|
}
|
||||||
|
|
||||||
|
export(type, base64) {
|
||||||
|
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]
|
||||||
}
|
}
|
||||||
}
|
|
||||||
})
|
|
||||||
window.dispatchEvent(ev)
|
|
||||||
}
|
|
||||||
|
|
||||||
function readonly(obj, key, value) {
|
ctx.putImageData(imgData, 0, 0)
|
||||||
Object.defineProperty(obj, key, {
|
|
||||||
get() {
|
|
||||||
return value
|
|
||||||
},
|
|
||||||
enumerable: false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
class NativeImage {
|
if (base64) {
|
||||||
#origin
|
return canvas.toDataURL(type || this.type, 1)
|
||||||
|
|
||||||
constructor(obj) {
|
|
||||||
this.#origin = obj
|
|
||||||
this.width = obj.width
|
|
||||||
this.height = obj.height
|
|
||||||
this.type = MIME_TYPES[obj.filepath.split('.').pop()]
|
|
||||||
}
|
|
||||||
|
|
||||||
toJSON() {
|
|
||||||
return this.#origin
|
|
||||||
}
|
|
||||||
|
|
||||||
export(type, base64) {
|
|
||||||
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)
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class EventEmitter {
|
|
||||||
//
|
|
||||||
__events__ = Object.create(null)
|
|
||||||
|
|
||||||
$on(name, fn) {
|
|
||||||
if (this.__events__[name]) {
|
|
||||||
this.__events__[name].push(fn)
|
|
||||||
} else {
|
|
||||||
this.__events__[name] = [fn]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$once(name, fn) {
|
|
||||||
fn.__once__ = true
|
|
||||||
this.$on(name, fn)
|
|
||||||
}
|
|
||||||
|
|
||||||
$off(name, fn) {
|
|
||||||
if (this.__events__[name]) {
|
|
||||||
if (fn) {
|
|
||||||
this.__events__[name] = this.__events__[name].filter(it => it !== fn)
|
|
||||||
} else {
|
} else {
|
||||||
this.__events__[name] = []
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$emit(name, ...args) {
|
class Native {
|
||||||
if (this.__events__[name]) {
|
//
|
||||||
for (let fn of this.__events__[name]) {
|
[__events__] = Object.create(null)
|
||||||
try {
|
|
||||||
fn.apply(this, args)
|
$on(name, fn) {
|
||||||
if (fn.__once__) {
|
if (this[__events__][name]) {
|
||||||
this.$off(name, fn)
|
this[__events__][name].push(fn)
|
||||||
}
|
} else {
|
||||||
} catch (e) {
|
this[__events__][name] = [fn]
|
||||||
console.error(e)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$once(name, fn) {
|
||||||
|
fn.__once__ = true
|
||||||
|
this.$on(name, fn)
|
||||||
|
}
|
||||||
|
|
||||||
|
$off(name, fn) {
|
||||||
|
if (this[__events__][name]) {
|
||||||
|
if (fn) {
|
||||||
|
this[__events__][name] = this[__events__][name].filter(
|
||||||
|
it => it !== fn
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
this[__events__][name] = []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
$destroy() {
|
$emit(name, ...args) {
|
||||||
this.__events__ = Object.create(null)
|
if (this[__events__][name]) {
|
||||||
}
|
for (let fn of this[__events__][name]) {
|
||||||
}
|
try {
|
||||||
|
fn.apply(this, args)
|
||||||
readonly(window, 'native', new EventEmitter())
|
if (fn.__once__) {
|
||||||
|
this.$off(name, fn)
|
||||||
native.$on('opener_message', (data, uuid) => _postMessage(data, uuid))
|
}
|
||||||
|
} catch (e) {
|
||||||
Object.assign(native, {
|
console.error(e)
|
||||||
env: '{{env}}',
|
}
|
||||||
app: {
|
}
|
||||||
name: '{{app_name}}',
|
|
||||||
version: '{{app_version}}',
|
|
||||||
quit() {
|
|
||||||
return handler('app', { action: 'quit' }, NO_CALLBACK)
|
|
||||||
},
|
|
||||||
relaunch() {
|
|
||||||
return handler('app', { action: 'relaunch' }, NO_CALLBACK)
|
|
||||||
},
|
|
||||||
getLocale() {
|
|
||||||
return native.env.LANG
|
|
||||||
}
|
|
||||||
},
|
|
||||||
fs: {
|
|
||||||
access(filepath, mode = 'r') {
|
|
||||||
return handler('fs', { action: 'access', mode, filepath })
|
|
||||||
},
|
|
||||||
|
|
||||||
read(filepath, mode = 'r') {
|
|
||||||
return handler('fs', { action: 'read', mode, filepath }).then(r =>
|
|
||||||
mode.includes('b') ? new Uint8Array(r) : r
|
|
||||||
)
|
|
||||||
},
|
|
||||||
write(filepath, content = '', mode = 'w') {
|
|
||||||
return handler('fs', {
|
|
||||||
action: 'write',
|
|
||||||
mode,
|
|
||||||
filepath,
|
|
||||||
content
|
|
||||||
})
|
|
||||||
},
|
|
||||||
append(filepath, content = '', mode = 'a+') {
|
|
||||||
return handler('fs', {
|
|
||||||
action: 'write',
|
|
||||||
mode,
|
|
||||||
filepath,
|
|
||||||
content
|
|
||||||
})
|
|
||||||
},
|
|
||||||
exists(filepath) {
|
|
||||||
return handler('fs', { action: 'exists', filepath })
|
|
||||||
},
|
|
||||||
list(filepath) {
|
|
||||||
return handler('fs', { action: 'list', filepath })
|
|
||||||
},
|
|
||||||
isfile(filepath) {
|
|
||||||
return handler('fs', { action: 'isfile', filepath })
|
|
||||||
},
|
|
||||||
isdir(filepath) {
|
|
||||||
return handler('fs', { action: 'isdir', filepath })
|
|
||||||
},
|
|
||||||
remove(filepath) {
|
|
||||||
return handler('fs', { action: 'remove', filepath })
|
|
||||||
},
|
|
||||||
rename(filepath, target) {
|
|
||||||
return handler('fs', { action: 'rename', filepath, target })
|
|
||||||
},
|
|
||||||
copy(filepath, target) {
|
|
||||||
return handler('fs', { action: 'copy', filepath, target })
|
|
||||||
},
|
|
||||||
mkdir(filepath) {
|
|
||||||
return handler('fs', { action: 'mkdir', 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 }, NO_CALLBACK)
|
|
||||||
},
|
|
||||||
readImage() {
|
|
||||||
return handler('clipboard', { action: 'wait_for_image' }).then(r =>
|
|
||||||
r ? new NativeImage(r) : r
|
|
||||||
)
|
|
||||||
},
|
|
||||||
writeImage(value) {
|
|
||||||
// 暂不知原因, postMessage传给Gtk后, JSON.stringify()并未读取toJSON的结果
|
|
||||||
if (typeof value === 'object') {
|
|
||||||
value = value.toJSON()
|
|
||||||
}
|
|
||||||
return handler('clipboard', { action: 'set_image', value }, NO_CALLBACK)
|
|
||||||
},
|
|
||||||
clear() {
|
|
||||||
return handler('clipboard', { action: 'clear' }, NO_CALLBACK)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
screen: {
|
|
||||||
getAllDisplays() {
|
|
||||||
return handler('monitor', { action: 'get-all' })
|
|
||||||
},
|
|
||||||
getPrimaryDisplay() {
|
|
||||||
return handler('monitor', { action: 'get-primary' })
|
|
||||||
}
|
|
||||||
},
|
|
||||||
globalShortcut: {
|
|
||||||
get enabled() {
|
|
||||||
return handler('keybinder', { action: 'supported' })
|
|
||||||
},
|
|
||||||
register(keyMap, callback) {
|
|
||||||
let shortcut_callback = base64(keyMap)
|
|
||||||
native.$off(shortcut_callback)
|
|
||||||
native.$on(shortcut_callback, callback)
|
|
||||||
return handler('keybinder', {
|
|
||||||
action: 'register',
|
|
||||||
value: keyMap,
|
|
||||||
shortcut_callback
|
|
||||||
})
|
|
||||||
},
|
|
||||||
unregister(keyMap) {
|
|
||||||
let shortcut_callback = base64(keyMap)
|
|
||||||
native.$off(shortcut_callback)
|
|
||||||
return handler('keybinder', { action: 'unregister', value: keyMap })
|
|
||||||
},
|
|
||||||
unregisterAll(keyMaps) {
|
|
||||||
for (let it of keyMaps) {
|
|
||||||
this.unregister(it)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
tray: {
|
|
||||||
create() {
|
|
||||||
//
|
|
||||||
},
|
|
||||||
remove() {
|
|
||||||
//
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
$destroy() {
|
||||||
* 设置普通状态的tray图标, 只需要传名称, 自动会去当前主题下去找
|
this[__events__] = Object.create(null)
|
||||||
*/
|
|
||||||
set_icon(name) {
|
|
||||||
return handler('tray', { action: 'set_icon', value: name })
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置警示图标, 同上
|
|
||||||
*/
|
|
||||||
set_attention_icon(name) {
|
|
||||||
return handler('tray', { action: 'set_attention_icon', value: name })
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
set_title(title) {
|
|
||||||
return handler('tray', { action: 'set_title', value: title })
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改tray图标状态
|
|
||||||
* @param status <Number> 0: 隐藏, 1: 显示, 2: 重要(对应上面的attention_icon)
|
|
||||||
*/
|
|
||||||
set_status(status) {
|
|
||||||
return handler('tray', { action: 'set_status', value: status })
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
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 })
|
|
||||||
},
|
|
||||||
|
|
||||||
close() {
|
readonly(window, 'native', new Native())
|
||||||
return handler('window', { action: 'close' })
|
|
||||||
},
|
|
||||||
|
|
||||||
isVisible() {
|
native.$on('opener_message', (data, uuid) => _postMessage(data, uuid))
|
||||||
return handler('window', { action: 'is_visible' })
|
|
||||||
|
_extend(native, {
|
||||||
|
env: '{{env}}',
|
||||||
|
app: {
|
||||||
|
name: '{{app_name}}',
|
||||||
|
version: '{{app_version}}',
|
||||||
|
quit() {
|
||||||
|
return handler('app', { action: 'quit' }, NO_CALLBACK)
|
||||||
|
},
|
||||||
|
relaunch() {
|
||||||
|
return handler('app', { action: 'relaunch' }, NO_CALLBACK)
|
||||||
|
},
|
||||||
|
getLocale() {
|
||||||
|
return native.env.LANG
|
||||||
|
}
|
||||||
},
|
},
|
||||||
toggleVisible() {
|
shell: {
|
||||||
handler('window', { action: 'toggle_visible' }, NO_CALLBACK)
|
openExternal(url) {},
|
||||||
|
showItemInFolder(path) {},
|
||||||
|
openPath(path) {},
|
||||||
|
trashItem(path) {}
|
||||||
},
|
},
|
||||||
hide() {
|
fs: {
|
||||||
handler('window', { action: 'hide' }, NO_CALLBACK)
|
access(filepath, mode = 'r') {
|
||||||
|
return handler('fs', { action: 'access', mode, filepath })
|
||||||
|
},
|
||||||
|
|
||||||
|
read(filepath, mode = 'r') {
|
||||||
|
return handler('fs', { action: 'read', mode, filepath }).then(r =>
|
||||||
|
mode.includes('b') ? new Uint8Array(r) : r
|
||||||
|
)
|
||||||
|
},
|
||||||
|
write(filepath, content = '', mode = 'w') {
|
||||||
|
return handler('fs', {
|
||||||
|
action: 'write',
|
||||||
|
mode,
|
||||||
|
filepath,
|
||||||
|
content
|
||||||
|
})
|
||||||
|
},
|
||||||
|
append(filepath, content = '', mode = 'a+') {
|
||||||
|
return handler('fs', {
|
||||||
|
action: 'write',
|
||||||
|
mode,
|
||||||
|
filepath,
|
||||||
|
content
|
||||||
|
})
|
||||||
|
},
|
||||||
|
exists(filepath) {
|
||||||
|
return handler('fs', { action: 'exists', filepath })
|
||||||
|
},
|
||||||
|
list(filepath) {
|
||||||
|
return handler('fs', { action: 'list', filepath })
|
||||||
|
},
|
||||||
|
isfile(filepath) {
|
||||||
|
return handler('fs', { action: 'isfile', filepath })
|
||||||
|
},
|
||||||
|
isdir(filepath) {
|
||||||
|
return handler('fs', { action: 'isdir', filepath })
|
||||||
|
},
|
||||||
|
remove(filepath) {
|
||||||
|
return handler('fs', { action: 'remove', filepath })
|
||||||
|
},
|
||||||
|
rename(filepath, target) {
|
||||||
|
return handler('fs', { action: 'rename', filepath, target })
|
||||||
|
},
|
||||||
|
copy(filepath, target) {
|
||||||
|
return handler('fs', { action: 'copy', filepath, target })
|
||||||
|
},
|
||||||
|
mkdir(filepath) {
|
||||||
|
return handler('fs', { action: 'mkdir', filepath })
|
||||||
|
}
|
||||||
},
|
},
|
||||||
show() {
|
image(filepath) {
|
||||||
handler('window', { action: 'show' }, NO_CALLBACK)
|
return handler('image', { value: filepath }).then(r => new NativeImage(r))
|
||||||
},
|
},
|
||||||
fullscreen() {
|
clipboard: {
|
||||||
handler('window', { action: 'fullscreen' }, NO_CALLBACK)
|
readText() {
|
||||||
|
return handler('clipboard', { action: 'wait_for_text' })
|
||||||
|
},
|
||||||
|
writeText(value) {
|
||||||
|
return handler('clipboard', { action: 'set_text', value }, NO_CALLBACK)
|
||||||
|
},
|
||||||
|
readImage() {
|
||||||
|
return handler('clipboard', { action: 'wait_for_image' }).then(r =>
|
||||||
|
r ? new NativeImage(r) : r
|
||||||
|
)
|
||||||
|
},
|
||||||
|
writeImage(value) {
|
||||||
|
// 暂不知原因, postMessage传给Gtk后, JSON.stringify()并未读取toJSON的结果
|
||||||
|
if (typeof value === 'object') {
|
||||||
|
value = value.toJSON()
|
||||||
|
}
|
||||||
|
return handler('clipboard', { action: 'set_image', value }, NO_CALLBACK)
|
||||||
|
},
|
||||||
|
clear() {
|
||||||
|
return handler('clipboard', { action: 'clear' }, NO_CALLBACK)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
unfullscreen() {
|
screen: {
|
||||||
handler('window', { action: 'unfullscreen' }, NO_CALLBACK)
|
getAllDisplays() {
|
||||||
|
return handler('monitor', { action: 'get-all' })
|
||||||
|
},
|
||||||
|
getPrimaryDisplay() {
|
||||||
|
return handler('monitor', { action: 'get-primary' })
|
||||||
|
}
|
||||||
},
|
},
|
||||||
maximize() {
|
globalShortcut: {
|
||||||
handler('window', { action: 'maximize' }, NO_CALLBACK)
|
get enabled() {
|
||||||
|
return handler('keybinder', { action: 'supported' })
|
||||||
|
},
|
||||||
|
register(keyMap, callback) {
|
||||||
|
let shortcut_callback = base64(keyMap)
|
||||||
|
native.$off(shortcut_callback)
|
||||||
|
native.$on(shortcut_callback, callback)
|
||||||
|
return handler('keybinder', {
|
||||||
|
action: 'register',
|
||||||
|
value: keyMap,
|
||||||
|
shortcut_callback
|
||||||
|
})
|
||||||
|
},
|
||||||
|
unregister(keyMap) {
|
||||||
|
let shortcut_callback = base64(keyMap)
|
||||||
|
native.$off(shortcut_callback)
|
||||||
|
return handler('keybinder', { action: 'unregister', value: keyMap })
|
||||||
|
},
|
||||||
|
unregisterAll(keyMaps) {
|
||||||
|
for (let it of keyMaps) {
|
||||||
|
this.unregister(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
unmaximize() {
|
tray: {
|
||||||
handler('window', { action: 'unmaximize' }, NO_CALLBACK)
|
create() {
|
||||||
|
//
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
//
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置普通状态的tray图标, 只需要传名称, 自动会去当前主题下去找
|
||||||
|
*/
|
||||||
|
set_icon(name) {
|
||||||
|
return handler('tray', { action: 'set_icon', value: name })
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置警示图标, 同上
|
||||||
|
*/
|
||||||
|
set_attention_icon(name) {
|
||||||
|
return handler('tray', { action: 'set_attention_icon', value: name })
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
set_title(title) {
|
||||||
|
return handler('tray', { action: 'set_title', value: title })
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改tray图标状态
|
||||||
|
* @param status <Number> 0: 隐藏, 1: 显示, 2: 重要(对应上面的attention_icon)
|
||||||
|
*/
|
||||||
|
set_status(status) {
|
||||||
|
return handler('tray', { action: 'set_status', value: status })
|
||||||
|
}
|
||||||
},
|
},
|
||||||
setTitle(title = '') {
|
opener: {
|
||||||
handler('window', { action: 'set_title', value: title }, NO_CALLBACK)
|
postMessage(data = {}) {
|
||||||
|
return handler('opener', { action: 'postmessage', data }, NO_CALLBACK)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
resize(width = 0, height = 0) {
|
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 })
|
||||||
|
},
|
||||||
|
|
||||||
|
close() {
|
||||||
|
return handler('window', { action: 'close' })
|
||||||
|
},
|
||||||
|
|
||||||
|
isVisible() {
|
||||||
|
return handler('window', { action: 'is_visible' })
|
||||||
|
},
|
||||||
|
toggleVisible() {
|
||||||
|
handler('window', { action: 'toggle_visible' }, NO_CALLBACK)
|
||||||
|
},
|
||||||
|
hide() {
|
||||||
|
handler('window', { action: 'hide' }, NO_CALLBACK)
|
||||||
|
},
|
||||||
|
show() {
|
||||||
|
handler('window', { action: 'show' }, NO_CALLBACK)
|
||||||
|
},
|
||||||
|
fullscreen() {
|
||||||
|
handler('window', { action: 'fullscreen' }, NO_CALLBACK)
|
||||||
|
},
|
||||||
|
unfullscreen() {
|
||||||
|
handler('window', { action: 'unfullscreen' }, NO_CALLBACK)
|
||||||
|
},
|
||||||
|
maximize() {
|
||||||
|
handler('window', { action: 'maximize' }, NO_CALLBACK)
|
||||||
|
},
|
||||||
|
unmaximize() {
|
||||||
|
handler('window', { action: 'unmaximize' }, NO_CALLBACK)
|
||||||
|
},
|
||||||
|
setTitle(title = '') {
|
||||||
|
handler('window', { action: 'set_title', value: title }, NO_CALLBACK)
|
||||||
|
},
|
||||||
|
resize(width = 0, height = 0) {
|
||||||
|
handler(
|
||||||
|
'window',
|
||||||
|
{ action: 'resize', value: { width, height } },
|
||||||
|
NO_CALLBACK
|
||||||
|
)
|
||||||
|
},
|
||||||
|
move(x = 0, y = 0) {
|
||||||
|
handler('window', { action: 'move', value: { x, y } }, NO_CALLBACK)
|
||||||
|
},
|
||||||
|
setOpacity(opacity = 1) {
|
||||||
|
handler(
|
||||||
|
'window',
|
||||||
|
{ action: 'set_opacity', value: opacity },
|
||||||
|
NO_CALLBACK
|
||||||
|
)
|
||||||
|
},
|
||||||
|
alwayOnTop(setting = true) {
|
||||||
|
handler(
|
||||||
|
'window',
|
||||||
|
{ action: 'set_keep_above', value: setting },
|
||||||
|
NO_CALLBACK
|
||||||
|
)
|
||||||
|
},
|
||||||
|
alwayOnBotttom(setting = true) {
|
||||||
|
handler(
|
||||||
|
'window',
|
||||||
|
{ action: 'set_keep_below', value: setting },
|
||||||
|
NO_CALLBACK
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
notify({ title, summary, icon, progress = 0, urgency = 0, callback }) {
|
||||||
|
let eventName
|
||||||
|
if (callback) {
|
||||||
|
eventName = rand()
|
||||||
|
native.$once(eventName, callback)
|
||||||
|
}
|
||||||
handler(
|
handler(
|
||||||
'window',
|
'notify',
|
||||||
{ action: 'resize', value: { width, height } },
|
{ title, summary, icon, progress, urgency, callback: eventName },
|
||||||
NO_CALLBACK
|
NO_CALLBACK
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
move(x = 0, y = 0) {
|
|
||||||
handler('window', { action: 'move', value: { x, y } }, NO_CALLBACK)
|
|
||||||
},
|
|
||||||
setOpacity(opacity = 1) {
|
|
||||||
handler('window', { action: 'set_opacity', value: opacity }, NO_CALLBACK)
|
|
||||||
},
|
|
||||||
alwayOnTop(setting = true) {
|
|
||||||
handler(
|
|
||||||
'window',
|
|
||||||
{ action: 'set_keep_above', value: setting },
|
|
||||||
NO_CALLBACK
|
|
||||||
)
|
|
||||||
},
|
|
||||||
alwayOnBotttom(setting = true) {
|
|
||||||
handler(
|
|
||||||
'window',
|
|
||||||
{ action: 'set_keep_below', value: setting },
|
|
||||||
NO_CALLBACK
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
notify({ title, summary, icon, progress = 0, urgency = 0, callback }) {
|
|
||||||
let eventName
|
|
||||||
if (callback) {
|
|
||||||
eventName = rand()
|
|
||||||
native.$once(eventName, callback)
|
|
||||||
}
|
|
||||||
handler(
|
|
||||||
'notify',
|
|
||||||
{ title, summary, icon, progress, urgency, callback: eventName },
|
|
||||||
NO_CALLBACK
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
md5(value = '') {
|
md5(value = '') {
|
||||||
return handler('md5', { value })
|
return handler('md5', { value })
|
||||||
},
|
|
||||||
|
|
||||||
proxy: {
|
|
||||||
disable() {
|
|
||||||
return handler('proxy', { action: 'disable' }, NO_CALLBACK)
|
|
||||||
},
|
},
|
||||||
system() {
|
|
||||||
return handler('proxy', { action: 'system' }, NO_CALLBACK)
|
|
||||||
},
|
|
||||||
custom(url = '', ignore = null) {
|
|
||||||
return handler('proxy', { action: 'enable', url, ignore }, NO_CALLBACK)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
handler
|
proxy: {
|
||||||
})
|
disable() {
|
||||||
|
return handler('proxy', { action: 'disable' }, NO_CALLBACK)
|
||||||
|
},
|
||||||
|
system() {
|
||||||
|
return handler('proxy', { action: 'system' }, NO_CALLBACK)
|
||||||
|
},
|
||||||
|
custom(url = '', ignore = null) {
|
||||||
|
return handler('proxy', { action: 'enable', url, ignore }, NO_CALLBACK)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handler
|
||||||
|
})
|
||||||
|
})()
|
||||||
|
|
Loading…
Reference in New Issue