Feature: 为Linux系统适配桌面图标栏(Tray) (#603)

This commit is contained in:
刘沛源
2020-12-29 09:59:50 +08:00
committed by GitHub
parent 2129f86266
commit 0fe3ade5c3
3 changed files with 201 additions and 140 deletions
+195 -136
View File
@@ -19,38 +19,161 @@ import { handleCopyUrl } from '~/main/utils/common'
let contextMenu: Menu | null let contextMenu: Menu | null
let menu: Menu | null let menu: Menu | null
let tray: Tray | null let tray: Tray | null
export function createContextMenu () { export function createContextMenu() {
const picBeds = getPicBeds() const picBeds = getPicBeds()
const submenu = picBeds.filter(item => item.visible).map(item => { if (process.platform === "darwin" || process.platform === "win32") {
return { const submenu = picBeds.filter(item => item.visible).map(item => {
label: item.name, return {
type: 'radio', label: item.name,
checked: db.get('picBed.current') === item.type, type: 'radio',
click () { checked: db.get('picBed.current') === item.type,
picgo.saveConfig({ click() {
'picBed.current': item.type, picgo.saveConfig({
'picBed.uploader': item.type 'picBed.current': item.type,
}) 'picBed.uploader': item.type
if (windowManager.has(IWindowList.SETTING_WINDOW)) { })
windowManager.get(IWindowList.SETTING_WINDOW)!.webContents.send('syncPicBed') if (windowManager.has(IWindowList.SETTING_WINDOW)) {
windowManager.get(IWindowList.SETTING_WINDOW)!.webContents.send('syncPicBed')
}
} }
} }
} })
}) contextMenu = Menu.buildFromTemplate([
contextMenu = Menu.buildFromTemplate([ {
{ label: '关于',
label: '关于', click() {
click () { dialog.showMessageBox({
dialog.showMessageBox({ title: 'PicGo',
title: 'PicGo', message: 'PicGo',
message: 'PicGo', detail: `Version: ${pkg.version}\nAuthor: Molunerfinn\nGithub: https://github.com/Molunerfinn/PicGo`
detail: `Version: ${pkg.version}\nAuthor: Molunerfinn\nGithub: https://github.com/Molunerfinn/PicGo` })
}) }
},
{
label: '打开详细窗口',
click() {
const settingWindow = windowManager.get(IWindowList.SETTING_WINDOW)
settingWindow!.show()
settingWindow!.focus()
if (windowManager.has(IWindowList.MINI_WINDOW)) {
windowManager.get(IWindowList.MINI_WINDOW)!.hide()
}
}
},
{
label: '选择默认图床',
type: 'submenu',
// @ts-ignore
submenu
},
// @ts-ignore
{
label: '打开更新助手',
type: 'checkbox',
checked: db.get('settings.showUpdateTip'),
click() {
const value = db.get('settings.showUpdateTip')
db.set('settings.showUpdateTip', !value)
}
},
{
label: '重启应用',
click() {
app.relaunch()
app.exit(0)
}
},
// @ts-ignore
{
role: 'quit',
label: '退出'
} }
}, ])
{ }
label: '打开详细窗口', else if (process.platform === "linux") {
click () { // TODO 图床选择功能
// 由于在Linux难以像在Mac和Windows上那样在点击时构造ContextMenu
// 暂时取消这个选单,避免引起和设置中启用的图床不一致
// TODO 重启应用功能
// 目前的实现无法正常工作
contextMenu = Menu.buildFromTemplate([
{
label: '打开详细窗口',
click() {
const settingWindow = windowManager.get(IWindowList.SETTING_WINDOW)
settingWindow!.show()
settingWindow!.focus()
if (windowManager.has(IWindowList.MINI_WINDOW)) {
windowManager.get(IWindowList.MINI_WINDOW)!.hide()
}
}
},
// @ts-ignore
{
label: '打开更新助手',
type: 'checkbox',
checked: db.get('settings.showUpdateTip'),
click() {
const value = db.get('settings.showUpdateTip')
db.set('settings.showUpdateTip', !value)
}
},
{
label: '关于应用',
click() {
dialog.showMessageBox({
title: 'PicGo',
message: 'PicGo',
buttons: ['Ok'],
detail: `Version: ${pkg.version}\nAuthor: Molunerfinn\nGithub: https://github.com/Molunerfinn/PicGo`,
});
}
},
// @ts-ignore
{
role: 'quit',
label: '退出'
}
])
}
}
export function createTray() {
const menubarPic = process.platform === 'darwin' ? `${__static}/menubar.png` : `${__static}/menubar-nodarwin.png`
tray = new Tray(menubarPic)
// click事件在Mac和Windows上可以触发(在Ubuntu上无法触发,Unity不支持)
if (process.platform === "darwin" || process.platform === "win32") {
tray.on('right-click', () => {
if (windowManager.has(IWindowList.TRAY_WINDOW)) {
windowManager.get(IWindowList.TRAY_WINDOW)!.hide()
}
createContextMenu()
tray!.popUpContextMenu(contextMenu!)
})
tray.on('click', (event, bounds) => {
if (process.platform === 'darwin') {
toggleWindow(bounds)
setTimeout(() => {
let img = clipboard.readImage()
let obj: ImgInfo[] = []
if (!img.isEmpty()) {
// 从剪贴板来的图片默认转为png
// @ts-ignore
const imgUrl = 'data:image/png;base64,' + Buffer.from(img.toPNG(), 'binary').toString('base64')
obj.push({
width: img.getSize().width,
height: img.getSize().height,
imgUrl
})
}
windowManager.get(IWindowList.TRAY_WINDOW)!.webContents.send('clipboardFiles', obj)
}, 0)
} else {
if (windowManager.has(IWindowList.TRAY_WINDOW)) {
windowManager.get(IWindowList.TRAY_WINDOW)!.hide()
}
const settingWindow = windowManager.get(IWindowList.SETTING_WINDOW) const settingWindow = windowManager.get(IWindowList.SETTING_WINDOW)
settingWindow!.show() settingWindow!.show()
settingWindow!.focus() settingWindow!.focus()
@@ -58,119 +181,55 @@ export function createContextMenu () {
windowManager.get(IWindowList.MINI_WINDOW)!.hide() windowManager.get(IWindowList.MINI_WINDOW)!.hide()
} }
} }
}, })
{
label: '选择默认图床',
type: 'submenu',
// @ts-ignore
submenu
},
// @ts-ignore
{
label: '打开更新助手',
type: 'checkbox',
checked: db.get('settings.showUpdateTip'),
click () {
const value = db.get('settings.showUpdateTip')
db.set('settings.showUpdateTip', !value)
}
},
{
label: '重启应用',
click () {
app.relaunch()
app.exit(0)
}
},
// @ts-ignore
{
role: 'quit',
label: '退出'
}
])
}
export function createTray () { tray.on('drag-enter', () => {
const menubarPic = process.platform === 'darwin' ? `${__static}/menubar.png` : `${__static}/menubar-nodarwin.png` if (systemPreferences.isDarkMode()) {
tray = new Tray(menubarPic) tray!.setImage(`${__static}/upload-dark.png`)
tray.on('right-click', () => { } else {
if (windowManager.has(IWindowList.TRAY_WINDOW)) { tray!.setImage(`${__static}/upload.png`)
windowManager.get(IWindowList.TRAY_WINDOW)!.hide() }
} })
createContextMenu()
tray!.popUpContextMenu(contextMenu!) tray.on('drag-end', () => {
}) tray!.setImage(`${__static}/menubar.png`)
tray.on('click', (event, bounds) => { })
if (process.platform === 'darwin') {
toggleWindow(bounds) tray.on('drop-files', async (event: Event, files: string[]) => {
setTimeout(() => { const pasteStyle = db.get('settings.pasteStyle') || 'markdown'
let img = clipboard.readImage() const trayWindow = windowManager.get(IWindowList.TRAY_WINDOW)!
let obj: ImgInfo[] = [] const imgs = await uploader
if (!img.isEmpty()) { .setWebContents(trayWindow.webContents)
// 从剪贴板来的图片默认转为png .upload(files)
// @ts-ignore if (imgs !== false) {
const imgUrl = 'data:image/png;base64,' + Buffer.from(img.toPNG(), 'binary').toString('base64') const pasteText: string[] = []
obj.push({ for (let i = 0; i < imgs.length; i++) {
width: img.getSize().width, pasteText.push(pasteTemplate(pasteStyle, imgs[i]))
height: img.getSize().height, const notification = new Notification({
imgUrl title: '上传成功',
body: imgs[i].imgUrl!,
icon: files[i]
}) })
setTimeout(() => {
notification.show()
}, i * 100)
db.insert('uploaded', imgs[i])
} }
windowManager.get(IWindowList.TRAY_WINDOW)!.webContents.send('clipboardFiles', obj) handleCopyUrl(pasteText.join('\n'))
}, 0) trayWindow.webContents.send('dragFiles', imgs)
} else {
if (windowManager.has(IWindowList.TRAY_WINDOW)) {
windowManager.get(IWindowList.TRAY_WINDOW)!.hide()
} }
const settingWindow = windowManager.get(IWindowList.SETTING_WINDOW) })
settingWindow!.show() // toggleWindow()
settingWindow!.focus() }
if (windowManager.has(IWindowList.MINI_WINDOW)) { // click事件在Ubuntu上无法触发,Unity不支持(在Mac和Windows上可以触发)
windowManager.get(IWindowList.MINI_WINDOW)!.hide() // 需要使用 setContextMenu 设置菜单
} else if (process.platform === "linux") {
} createContextMenu()
}) tray!.setContextMenu(contextMenu)
}
tray.on('drag-enter', () => {
if (systemPreferences.isDarkMode()) {
tray!.setImage(`${__static}/upload-dark.png`)
} else {
tray!.setImage(`${__static}/upload.png`)
}
})
tray.on('drag-end', () => {
tray!.setImage(`${__static}/menubar.png`)
})
tray.on('drop-files', async (event: Event, files: string[]) => {
const pasteStyle = db.get('settings.pasteStyle') || 'markdown'
const trayWindow = windowManager.get(IWindowList.TRAY_WINDOW)!
const imgs = await uploader
.setWebContents(trayWindow.webContents)
.upload(files)
if (imgs !== false) {
const pasteText: string[] = []
for (let i = 0; i < imgs.length; i++) {
pasteText.push(pasteTemplate(pasteStyle, imgs[i]))
const notification = new Notification({
title: '上传成功',
body: imgs[i].imgUrl!,
icon: files[i]
})
setTimeout(() => {
notification.show()
}, i * 100)
db.insert('uploaded', imgs[i])
}
handleCopyUrl(pasteText.join('\n'))
trayWindow.webContents.send('dragFiles', imgs)
}
})
// toggleWindow()
} }
export function createMenu () { export function createMenu() {
if (process.env.NODE_ENV !== 'development') { if (process.env.NODE_ENV !== 'development') {
const template = [{ const template = [{
label: 'Edit', label: 'Edit',
@@ -185,7 +244,7 @@ export function createMenu () {
{ {
label: 'Quit', label: 'Quit',
accelerator: 'CmdOrCtrl+Q', accelerator: 'CmdOrCtrl+Q',
click () { click() {
app.quit() app.quit()
} }
} }
+1 -3
View File
@@ -56,9 +56,7 @@ class LifeCycle {
} }
windowManager.create(IWindowList.TRAY_WINDOW) windowManager.create(IWindowList.TRAY_WINDOW)
windowManager.create(IWindowList.SETTING_WINDOW) windowManager.create(IWindowList.SETTING_WINDOW)
if (process.platform === 'darwin' || process.platform === 'win32') { createTray()
createTray()
}
db.set('needReload', false) db.set('needReload', false)
updateChecker() updateChecker()
// 不需要阻塞 // 不需要阻塞
+5 -1
View File
@@ -271,7 +271,11 @@ export default class extends Vue {
} }
closeWindow () { closeWindow () {
const window = BrowserWindow.getFocusedWindow() const window = BrowserWindow.getFocusedWindow()
window!.close() if (process.platform === 'linux') {
window!.hide()
} else {
window!.close()
}
} }
buildMenu () { buildMenu () {
const _this = this const _this = this