From bbed29a86a4fb246a786c2746b00238c7fc8164c Mon Sep 17 00:00:00 2001 From: ModStart Date: Wed, 15 Jan 2025 15:36:31 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=EF=BC=9ALinux=20=E5=B9=B3?= =?UTF-8?q?=E5=8F=B0=E5=BA=94=E7=94=A8=E5=88=97=E8=A1=A8=E6=89=AB=E6=8F=8F?= =?UTF-8?q?=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 14 +++++ electron/lib/env.ts | 20 +++--- .../manager/system/plugin/app/linux/icon.ts | 29 +++++++++ .../manager/system/plugin/app/linux/index.ts | 63 +++++++++++++++++-- .../manager/system/plugin/app/linux/title.ts | 19 ++++++ .../manager/system/plugin/app/mac/icon.ts | 7 +-- .../manager/system/plugin/app/mac/title.ts | 1 - src/types/Manager.ts | 4 +- 8 files changed, 136 insertions(+), 21 deletions(-) create mode 100644 electron/mapi/manager/system/plugin/app/linux/icon.ts create mode 100644 electron/mapi/manager/system/plugin/app/linux/title.ts diff --git a/README.md b/README.md index e000566..456e487 100644 --- a/README.md +++ b/README.md @@ -139,6 +139,20 @@ npm run dev npm run build ``` +### Ubuntu 开发环境 + +```shell +sudo apt install -y make gcc g++ python3 +``` + +### Windows 开发环境 + +- 安装 `Visual Studio 2019`,并安装 `Desktop Development with C++` 相关组件 + +### MacOS 开发环境 + +- 安装 `Python3` + ## 加入交流群 diff --git a/electron/lib/env.ts b/electron/lib/env.ts index 9720e44..c74c2d0 100644 --- a/electron/lib/env.ts +++ b/electron/lib/env.ts @@ -1,6 +1,7 @@ import {resolve} from "node:path"; import os from "os"; import {execSync} from "child_process"; +import {Log} from "../mapi/log"; export const isPackaged = ['true'].includes(process.env.IS_PACKAGED) @@ -52,14 +53,17 @@ export const platformArch = (): 'x86' | 'arm64' | null => { let platformUUIDCache: string | null = null export const platformUUID = () => { if (null === platformUUIDCache) { - if (isWin) { - platformUUIDCache = execSync('wmic csproduct get UUID').toString().split('\n')[1].trim() - } else if (isMac) { - platformUUIDCache = execSync('system_profiler SPHardwareDataType | grep UUID').toString().split(': ')[1].trim() - } else if (isLinux) { - platformUUIDCache = execSync('cat /sys/class/dmi/id/product_uuid').toString().trim() - } else { - platformUUIDCache = '' + try { + if (isWin) { + platformUUIDCache = execSync('wmic csproduct get UUID').toString().split('\n')[1].trim() + } else if (isMac) { + platformUUIDCache = execSync('system_profiler SPHardwareDataType | grep UUID').toString().split(': ')[1].trim() + } else if (isLinux) { + platformUUIDCache = execSync('cat /var/lib/dbus/machine-id').toString().trim().toUpperCase() + } + } catch (e) { + Log.error('Env.platformUUID', e.message) + platformUUIDCache = '000000' } } return platformUUIDCache diff --git a/electron/mapi/manager/system/plugin/app/linux/icon.ts b/electron/mapi/manager/system/plugin/app/linux/icon.ts new file mode 100644 index 0000000..c9549d4 --- /dev/null +++ b/electron/mapi/manager/system/plugin/app/linux/icon.ts @@ -0,0 +1,29 @@ +import path from "node:path"; +import fs from "node:fs"; + +export const getIcon = async (desktopInfo: Record, pathname: string, name: string) => { + if (!desktopInfo.Icon) { + return null + } + const themes = [ + 'hicolor', + ]; + const sizes = ['scalable', '512x512', '256x256', '48x48', '32x32']; + const types = [ + 'apps', + ]; + const exts = ['.png', '.svg']; + for (const theme of themes) { + for (const size of sizes) { + for (const type of types) { + for (const ext of exts) { + let iconPath = path.join('/usr/share/icons', theme, size, type, desktopInfo.Icon + ext); + if (fs.existsSync(iconPath)) { + return 'file://' + iconPath; + } + } + } + } + } + return null +} diff --git a/electron/mapi/manager/system/plugin/app/linux/index.ts b/electron/mapi/manager/system/plugin/app/linux/index.ts index 766c836..af3650b 100644 --- a/electron/mapi/manager/system/plugin/app/linux/index.ts +++ b/electron/mapi/manager/system/plugin/app/linux/index.ts @@ -1,5 +1,9 @@ import {listFiles} from "../util"; import path from "path"; +import {ConfigLang} from "../../../../../../config/lang"; +import {getIcon} from "./icon"; +import {getAppTitle} from "./title"; +import fs from "node:fs"; export const ManagerAppLinux = { list: async () => { @@ -7,17 +11,68 @@ export const ManagerAppLinux = { } } +const appSet = new Set(); + const lists = async () => { + appSet.clear() const files = await listFiles([ "/usr/share/applications", "/var/lib/snapd/desktop/applications", `${process.env.HOME}/.local/share/applications`, ]) - for (const file of files) { - if (path.extname(file.pathname) !== ".desktop") { + const apps = [] + const locale = ConfigLang.getLocale() + for (const f of files) { + if (appSet.has(f.pathname)) { + // console.log('appSet.has', f.pathname) + continue + } + const extname = path.extname(f.pathname); + if (extname !== '.desktop') { + continue + } + const app = { + name: f.name.replace(/\.(desktop)$/, ''), + title: f.name, + pathname: f.pathname, + icon: null, + command: null, + } + const desktopInfo = await parseDesktopFile(app.pathname) + app.icon = await getIcon(desktopInfo, app.pathname, app.name) + app.title = await getAppTitle(desktopInfo, locale, app.pathname, app.name); + if (!app.icon) { + continue + } + if (!desktopInfo.Exec) { continue } - //TODO + let command = desktopInfo.Exec + .replace(/ %[A-Za-z]/g, "") + .replace(/"/g, "") + .trim(); + if (desktopInfo.Terminal === 'true') { + command = `gnome-terminal -x ${command}` + } + app.command = command + appSet.add(app.pathname) + apps.push(app) + } + return apps +} + +const parseDesktopFile = async (pathname: string): Promise> => { + const content = fs.readFileSync(pathname, 'utf-8'); + const desktop = {}; + for (const line of content.split('\n')) { + if (line.startsWith('[')) { + continue; + } + const [key, value] = line.split('='); + if (!key || !value) { + continue; + } + desktop[key] = value; } - return [] + return desktop } diff --git a/electron/mapi/manager/system/plugin/app/linux/title.ts b/electron/mapi/manager/system/plugin/app/linux/title.ts new file mode 100644 index 0000000..11597a7 --- /dev/null +++ b/electron/mapi/manager/system/plugin/app/linux/title.ts @@ -0,0 +1,19 @@ +const langDirMap = { + 'zh-CN': ['zh_CN'], +} + +export const getAppTitle = async (desktopInfo: Record, locale: string, pathname: string, name: string) => { + if (locale in langDirMap) { + for (const k of langDirMap[locale]) { + const infoKey = `Name[${k}]` + if (desktopInfo[infoKey]) { + return desktopInfo[infoKey] + } + } + } + if (desktopInfo.Name) { + return desktopInfo.Name + } + return name +} + diff --git a/electron/mapi/manager/system/plugin/app/mac/icon.ts b/electron/mapi/manager/system/plugin/app/mac/icon.ts index 03f0201..e465f40 100644 --- a/electron/mapi/manager/system/plugin/app/mac/icon.ts +++ b/electron/mapi/manager/system/plugin/app/mac/icon.ts @@ -19,12 +19,7 @@ const getIconFile = (appFileInput) => { const mat = plistContent.match(/CFBundleIconFile<\/key>\s*(.*?)<\/string>/) if (mat) { const CFBundleIconFile = mat[1] - const iconFile = path.join( - appFileInput, - 'Contents', - 'Resources', - CFBundleIconFile - ); + const iconFile = path.join(appFileInput, 'Contents', 'Resources', CFBundleIconFile); const iconFiles = [iconFile, iconFile + '.icns', iconFile + '.tiff'] const existedIcon = iconFiles.find((iconFile) => { return fs.existsSync(iconFile); diff --git a/electron/mapi/manager/system/plugin/app/mac/title.ts b/electron/mapi/manager/system/plugin/app/mac/title.ts index efe44b2..014d954 100644 --- a/electron/mapi/manager/system/plugin/app/mac/title.ts +++ b/electron/mapi/manager/system/plugin/app/mac/title.ts @@ -1,5 +1,4 @@ import {Files} from "../../../../../file/main"; -import fs from "node:fs"; import {IconvUtil} from "../../../../../../lib/util"; const langDirMap = { diff --git a/src/types/Manager.ts b/src/types/Manager.ts index b225d9d..6333302 100644 --- a/src/types/Manager.ts +++ b/src/types/Manager.ts @@ -183,8 +183,8 @@ export type ActionRecord = { // type = command command?: string // type = view - showFastPanel: boolean, - showMainPanel: boolean, + showFastPanel?: boolean, + showMainPanel?: boolean, }, type?: ActionTypeEnum,