mirror of
https://github.com/fanchenio/DawnLauncher.git
synced 2025-07-15 05:42:10 +08:00
Compare commits
No commits in common. "main" and "1.4.6" have entirely different histories.
@ -1,5 +1,9 @@
|
|||||||
# [简体中文](https://github.com/fanchenio/DawnLauncher) | English
|
# [简体中文](https://github.com/fanchenio/DawnLauncher) | English
|
||||||
|
|
||||||
|
# Update
|
||||||
|
|
||||||
|
After disappearing for more than three months, I refactored the `Dawn Launcher` code. Because I had no experience in developing `NodeJS` and `Electron` at the beginning, `Vue` was not well written, and the code was a bit sloppy, so I carried out Code refactoring, the new version uses `Electron26 + Vite + Vue3 + TS`, the UI framework uses `Naive`, regarding the native API, I switched from `C++` to `Rust`, and the database switched from `electron-store` With `SQLite3`, the language has also added `English`.
|
||||||
|
|
||||||
# Dawn Launcher
|
# Dawn Launcher
|
||||||
|
|
||||||
The `Windows` quick launch tool helps you organize your messy desktop, manage your desktop shortcuts by category, and keep your desktop clean and tidy.
|
The `Windows` quick launch tool helps you organize your messy desktop, manage your desktop shortcuts by category, and keep your desktop clean and tidy.
|
||||||
@ -8,7 +12,7 @@ Supports associated folders (real-time synchronization of folder contents), quic
|
|||||||
|
|
||||||
# Technology Stack
|
# Technology Stack
|
||||||
|
|
||||||
`Electron + Vite + Vue3 + TS + Rust`
|
`Electron + Vite + Vue3 + TS`
|
||||||
|
|
||||||
# Support Platform
|
# Support Platform
|
||||||
|
|
||||||
@ -27,6 +31,14 @@ Supports associated folders (real-time synchronization of folder contents), quic
|
|||||||
|
|
||||||
[dawnlauncher.com](https://dawnlauncher.com/)
|
[dawnlauncher.com](https://dawnlauncher.com/)
|
||||||
|
|
||||||
|
# Donate(Wechat)
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
# Donate(Alipay)
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
# UI
|
# UI
|
||||||
|
|
||||||

|

|
||||||
|
14
README.md
14
README.md
@ -1,5 +1,9 @@
|
|||||||
# 简体中文 | [English](https://github.com/fanchenio/DawnLauncher/blob/main/README-ENGLISH.md)
|
# 简体中文 | [English](https://github.com/fanchenio/DawnLauncher/blob/main/README-ENGLISH.md)
|
||||||
|
|
||||||
|
# 更新
|
||||||
|
|
||||||
|
消失了三个多月,我将`Dawn Launcher`代码进行重构,因为一开始没有开发`NodeJS`和`Electron`的经验,`Vue`也写的不好,代码写的有些潦草,所以进行了代码重构,新版使用了`Electron26 + Vite + Vue3 + TS`,UI 框架使用了`Naive`,关于原生 API 方面,我从`C++`切换到了 `Rust`,数据库从`electron-store`切换到了`SQLite3`,语言也新增了`英语`。
|
||||||
|
|
||||||
# Dawn Launcher
|
# Dawn Launcher
|
||||||
|
|
||||||
`Windows`快捷启动工具,帮助您整理杂乱无章的桌面,分门别类管理您的桌面快捷方式,让您的桌面保持干净整洁。
|
`Windows`快捷启动工具,帮助您整理杂乱无章的桌面,分门别类管理您的桌面快捷方式,让您的桌面保持干净整洁。
|
||||||
@ -8,7 +12,7 @@
|
|||||||
|
|
||||||
# 技术栈
|
# 技术栈
|
||||||
|
|
||||||
`Electron + Vite + Vue3 + TS + Rust`
|
`Electron + Vite + Vue3 + TS`
|
||||||
|
|
||||||
# 支持平台
|
# 支持平台
|
||||||
|
|
||||||
@ -31,6 +35,14 @@
|
|||||||
|
|
||||||
369652112
|
369652112
|
||||||
|
|
||||||
|
# 捐赠(微信)
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
# 捐赠(支付宝)
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
# 界面
|
# 界面
|
||||||
|
|
||||||

|

|
||||||
|
@ -77,12 +77,10 @@ let simplifiedChinese = {
|
|||||||
controlPanel: "控制面板",
|
controlPanel: "控制面板",
|
||||||
convertAbsolutePath: "转为绝对路径",
|
convertAbsolutePath: "转为绝对路径",
|
||||||
convertRelativePath: "转为相对路径",
|
convertRelativePath: "转为相对路径",
|
||||||
copy: "复制",
|
|
||||||
copyFullPath: "复制完整路径",
|
copyFullPath: "复制完整路径",
|
||||||
copyTo: "复制到",
|
copyTo: "复制到",
|
||||||
createShortcut: "创建快捷方式",
|
createShortcut: "创建快捷方式",
|
||||||
ctrlNumberKey: "Ctrl + 数字键",
|
ctrlNumberKey: "Ctrl + 数字键",
|
||||||
cut: "剪切",
|
|
||||||
default: "默认",
|
default: "默认",
|
||||||
defaultIcon: "默认图标",
|
defaultIcon: "默认图标",
|
||||||
delayDisplay: "延迟显示",
|
delayDisplay: "延迟显示",
|
||||||
@ -208,7 +206,6 @@ let simplifiedChinese = {
|
|||||||
parameters: "参数",
|
parameters: "参数",
|
||||||
password: "密码",
|
password: "密码",
|
||||||
pasteIcon: "粘贴图标",
|
pasteIcon: "粘贴图标",
|
||||||
paste: "粘贴",
|
|
||||||
path: "路径",
|
path: "路径",
|
||||||
powerOptions: "电源选项",
|
powerOptions: "电源选项",
|
||||||
powerShell: "PowerShell",
|
powerShell: "PowerShell",
|
||||||
@ -387,12 +384,10 @@ let traditionalChinese = {
|
|||||||
controlPanel: "控製面板",
|
controlPanel: "控製面板",
|
||||||
convertAbsolutePath: "轉為絕對路徑",
|
convertAbsolutePath: "轉為絕對路徑",
|
||||||
convertRelativePath: "轉為相對路徑",
|
convertRelativePath: "轉為相對路徑",
|
||||||
copy: "復製",
|
|
||||||
copyFullPath: "復製完整路徑",
|
copyFullPath: "復製完整路徑",
|
||||||
copyTo: "復製到",
|
copyTo: "復製到",
|
||||||
createShortcut: "創建快捷方式",
|
createShortcut: "創建快捷方式",
|
||||||
ctrlNumberKey: "Ctrl + 數字鍵",
|
ctrlNumberKey: "Ctrl + 數字鍵",
|
||||||
cut: "剪切",
|
|
||||||
default: "默認",
|
default: "默認",
|
||||||
defaultIcon: "默認圖標",
|
defaultIcon: "默認圖標",
|
||||||
delayDisplay: "延遲顯示",
|
delayDisplay: "延遲顯示",
|
||||||
@ -518,7 +513,6 @@ let traditionalChinese = {
|
|||||||
parameters: "參數",
|
parameters: "參數",
|
||||||
password: "密碼",
|
password: "密碼",
|
||||||
pasteIcon: "粘貼圖標",
|
pasteIcon: "粘貼圖標",
|
||||||
paste: "粘貼",
|
|
||||||
path: "路徑",
|
path: "路徑",
|
||||||
powerOptions: "電源選項",
|
powerOptions: "電源選項",
|
||||||
powerShell: "PowerShell",
|
powerShell: "PowerShell",
|
||||||
@ -705,12 +699,10 @@ let english = {
|
|||||||
controlPanel: "Control Panel",
|
controlPanel: "Control Panel",
|
||||||
convertAbsolutePath: "Convert to Absolute Path",
|
convertAbsolutePath: "Convert to Absolute Path",
|
||||||
convertRelativePath: "Convert to Relative Path",
|
convertRelativePath: "Convert to Relative Path",
|
||||||
copy: "Copy",
|
|
||||||
copyFullPath: "Copy Full Path",
|
copyFullPath: "Copy Full Path",
|
||||||
copyTo: "Copy to",
|
copyTo: "Copy to",
|
||||||
createShortcut: "Create Shortcut",
|
createShortcut: "Create Shortcut",
|
||||||
ctrlNumberKey: "Ctrl + Number Key",
|
ctrlNumberKey: "Ctrl + Number Key",
|
||||||
cut: "Cut",
|
|
||||||
default: "Default",
|
default: "Default",
|
||||||
defaultIcon: "Default Icon",
|
defaultIcon: "Default Icon",
|
||||||
delayDisplay: "Delay Display",
|
delayDisplay: "Delay Display",
|
||||||
@ -838,7 +830,6 @@ let english = {
|
|||||||
parameters: "Parameters",
|
parameters: "Parameters",
|
||||||
password: "Password",
|
password: "Password",
|
||||||
pasteIcon: "Paste Icon",
|
pasteIcon: "Paste Icon",
|
||||||
paste: "Paste",
|
|
||||||
path: "Path",
|
path: "Path",
|
||||||
powerOptions: "Power Options",
|
powerOptions: "Power Options",
|
||||||
powerShell: "PowerShell",
|
powerShell: "PowerShell",
|
||||||
|
@ -24,11 +24,7 @@ function createWindow() {
|
|||||||
fullscreenable: false,
|
fullscreenable: false,
|
||||||
focusable: true,
|
focusable: true,
|
||||||
show: false,
|
show: false,
|
||||||
transparent: global.setting.appearance.transparency < 1,
|
backgroundColor: getMainBackgorunColor(),
|
||||||
backgroundColor:
|
|
||||||
global.setting.appearance.transparency === 1
|
|
||||||
? getMainBackgorunColor()
|
|
||||||
: null,
|
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
spellcheck: false,
|
spellcheck: false,
|
||||||
preload: join(__dirname, "../preload/index.js"),
|
preload: join(__dirname, "../preload/index.js"),
|
||||||
|
@ -49,11 +49,7 @@ function createAddEditWindow(id: number | null, parentId: number | null) {
|
|||||||
fullscreenable: false,
|
fullscreenable: false,
|
||||||
focusable: true,
|
focusable: true,
|
||||||
show: false,
|
show: false,
|
||||||
transparent: global.setting.appearance.transparency < 1,
|
backgroundColor: getMainBackgorunColor(),
|
||||||
backgroundColor:
|
|
||||||
global.setting.appearance.transparency === 1
|
|
||||||
? getMainBackgorunColor()
|
|
||||||
: null,
|
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
spellcheck: false,
|
spellcheck: false,
|
||||||
preload: join(__dirname, "../preload/index.js"),
|
preload: join(__dirname, "../preload/index.js"),
|
||||||
@ -117,11 +113,7 @@ function createSetIconWindow(id: number) {
|
|||||||
fullscreenable: false,
|
fullscreenable: false,
|
||||||
focusable: true,
|
focusable: true,
|
||||||
show: false,
|
show: false,
|
||||||
transparent: global.setting.appearance.transparency < 1,
|
backgroundColor: getMainBackgorunColor(),
|
||||||
backgroundColor:
|
|
||||||
global.setting.appearance.transparency === 1
|
|
||||||
? getMainBackgorunColor()
|
|
||||||
: null,
|
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
spellcheck: false,
|
spellcheck: false,
|
||||||
preload: join(__dirname, "../preload/index.js"),
|
preload: join(__dirname, "../preload/index.js"),
|
||||||
@ -180,11 +172,7 @@ function createAssociateFolderWindow(id: number) {
|
|||||||
fullscreenable: false,
|
fullscreenable: false,
|
||||||
focusable: true,
|
focusable: true,
|
||||||
show: false,
|
show: false,
|
||||||
transparent: global.setting.appearance.transparency < 1,
|
backgroundColor: getMainBackgorunColor(),
|
||||||
backgroundColor:
|
|
||||||
global.setting.appearance.transparency === 1
|
|
||||||
? getMainBackgorunColor()
|
|
||||||
: null,
|
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
spellcheck: false,
|
spellcheck: false,
|
||||||
preload: join(__dirname, "../preload/index.js"),
|
preload: join(__dirname, "../preload/index.js"),
|
||||||
@ -248,11 +236,7 @@ function createAggregateWindow(id: number) {
|
|||||||
fullscreenable: false,
|
fullscreenable: false,
|
||||||
focusable: true,
|
focusable: true,
|
||||||
show: false,
|
show: false,
|
||||||
transparent: global.setting.appearance.transparency < 1,
|
backgroundColor: getMainBackgorunColor(),
|
||||||
backgroundColor:
|
|
||||||
global.setting.appearance.transparency === 1
|
|
||||||
? getMainBackgorunColor()
|
|
||||||
: null,
|
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
spellcheck: false,
|
spellcheck: false,
|
||||||
preload: join(__dirname, "../preload/index.js"),
|
preload: join(__dirname, "../preload/index.js"),
|
||||||
|
@ -561,13 +561,6 @@ function showOpenDialogSync(windowName: string, options: OpenDialogOptions) {
|
|||||||
return pathList;
|
return pathList;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 窗口是否存在
|
|
||||||
*/
|
|
||||||
function mainWindowExist() {
|
|
||||||
return global.mainWindow && !global.mainWindow.isDestroyed();
|
|
||||||
}
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
downloadImage,
|
downloadImage,
|
||||||
getURLInfo,
|
getURLInfo,
|
||||||
@ -587,5 +580,4 @@ export {
|
|||||||
showErrorMessageBox,
|
showErrorMessageBox,
|
||||||
showSaveDialogSync,
|
showSaveDialogSync,
|
||||||
showOpenDialogSync,
|
showOpenDialogSync,
|
||||||
mainWindowExist,
|
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { app, ipcMain, Menu, OpenDialogSyncOptions, shell } from "electron";
|
import { app, ipcMain, OpenDialogSyncOptions, shell } from "electron";
|
||||||
import { getFileIcon } from "../../commons/utils";
|
import { getFileIcon } from "../../commons/utils";
|
||||||
import mime from "mime";
|
import mime from "mime";
|
||||||
import { ShortcutInfo } from "../../../types/common";
|
import { ShortcutInfo } from "../../../types/common";
|
||||||
@ -164,24 +164,4 @@ export default function () {
|
|||||||
app.getPath("home")
|
app.getPath("home")
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
// 文本框菜单
|
|
||||||
ipcMain.on("textRightMenu", (event, args) => {
|
|
||||||
// 菜单
|
|
||||||
let menu = Menu.buildFromTemplate([
|
|
||||||
{
|
|
||||||
role: "cut",
|
|
||||||
label: global.language.cut,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
role: "copy",
|
|
||||||
label: global.language.copy,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
role: "paste",
|
|
||||||
label: global.language.paste,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
// 显示
|
|
||||||
menu.popup();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
@ -25,11 +25,7 @@ function createBackupRestoreDataWindow() {
|
|||||||
fullscreenable: false,
|
fullscreenable: false,
|
||||||
focusable: true,
|
focusable: true,
|
||||||
show: false,
|
show: false,
|
||||||
transparent: global.setting.appearance.transparency < 1,
|
backgroundColor: getMainBackgorunColor(),
|
||||||
backgroundColor:
|
|
||||||
global.setting.appearance.transparency === 1
|
|
||||||
? getMainBackgorunColor()
|
|
||||||
: null,
|
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
spellcheck: false,
|
spellcheck: false,
|
||||||
preload: join(__dirname, "../preload/index.js"),
|
preload: join(__dirname, "../preload/index.js"),
|
||||||
|
@ -8,10 +8,7 @@ import { initSystemItem } from "./item/commons/data";
|
|||||||
import commonIpcEvent from "./commons/ipcEvent";
|
import commonIpcEvent from "./commons/ipcEvent";
|
||||||
import itemIpcEvent from "./item/ipcEvent";
|
import itemIpcEvent from "./item/ipcEvent";
|
||||||
import settingIpcEvent from "./setting/ipcEvent";
|
import settingIpcEvent from "./setting/ipcEvent";
|
||||||
import {
|
import { init as settingDataInit } from "./setting/data";
|
||||||
init as settingDataInit,
|
|
||||||
update as updateSetting,
|
|
||||||
} from "./setting/data";
|
|
||||||
import { setShortcutKey } from "./setting";
|
import { setShortcutKey } from "./setting";
|
||||||
import searchIpcEvent from "./search/ipcEvent";
|
import searchIpcEvent from "./search/ipcEvent";
|
||||||
import { createMainWindow } from "./main";
|
import { createMainWindow } from "./main";
|
||||||
@ -40,13 +37,8 @@ process.env.VITE_PUBLIC = process.env.VITE_DEV_SERVER_URL
|
|||||||
// 解决透明窗口闪烁
|
// 解决透明窗口闪烁
|
||||||
app.commandLine.appendSwitch("wm-window-animations-disabled");
|
app.commandLine.appendSwitch("wm-window-animations-disabled");
|
||||||
|
|
||||||
// 初始化设置数据
|
// 解决创建窗口屏幕闪烁问题
|
||||||
settingDataInit();
|
app.disableHardwareAcceleration();
|
||||||
// 如果主窗口是非透明窗口的话,禁止GPU加速,解决白屏问题。
|
|
||||||
// 如果主窗口是透明窗口的话,将除主窗口外的窗口都改为透明度0.99,解决解决白屏问题。
|
|
||||||
if (global.setting.appearance.transparency === 1) {
|
|
||||||
app.disableHardwareAcceleration();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set application name for Windows 10+ notifications
|
// Set application name for Windows 10+ notifications
|
||||||
if (process.platform === "win32") app.setAppUserModelId(app.getName());
|
if (process.platform === "win32") app.setAppUserModelId(app.getName());
|
||||||
@ -70,18 +62,8 @@ app.whenReady().then(() => {
|
|||||||
}
|
}
|
||||||
// addon
|
// addon
|
||||||
global.addon = require("../../native/addon.node");
|
global.addon = require("../../native/addon.node");
|
||||||
if (global.first) {
|
// 初始化数据
|
||||||
// 首次添加,判断系统语言
|
settingDataInit();
|
||||||
if (app.getLocale().toLowerCase().indexOf("zh-") === 0) {
|
|
||||||
// 简体中文
|
|
||||||
global.setting.general.language = "SimplifiedChinese";
|
|
||||||
} else {
|
|
||||||
// 英文
|
|
||||||
global.setting.general.language = "English";
|
|
||||||
}
|
|
||||||
// 修改
|
|
||||||
updateSetting(global.setting);
|
|
||||||
}
|
|
||||||
// 获取语言
|
// 获取语言
|
||||||
global.language = getLanguage(global.setting.general.language);
|
global.language = getLanguage(global.setting.general.language);
|
||||||
// 禁用debugtron
|
// 禁用debugtron
|
||||||
|
@ -332,9 +332,9 @@ function batchDel(idList: Array<number>) {
|
|||||||
// 参数
|
// 参数
|
||||||
let params = itemList.map((item) => item.id).join(",");
|
let params = itemList.map((item) => item.id).join(",");
|
||||||
// SQL
|
// SQL
|
||||||
let sql = `DELETE FROM ${tableName} WHERE id in (${params})`;
|
let sql = `DELETE FROM ${tableName} WHERE id in (?)`;
|
||||||
// 运行
|
// 运行
|
||||||
let res = db.prepare(sql).run().changes > 0;
|
let res = db.prepare(sql).run(params).changes > 0;
|
||||||
if (res) {
|
if (res) {
|
||||||
// 提取分类ID
|
// 提取分类ID
|
||||||
let classificationIdList = new Set<number>();
|
let classificationIdList = new Set<number>();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { BrowserWindow, shell, app } from "electron";
|
import { BrowserWindow, shell, app } from "electron";
|
||||||
import { extname, join } from "node:path";
|
import { join } from "node:path";
|
||||||
import { parsePath, getURLParams, getFileIcon } from "../../commons/utils";
|
import { parsePath, getURLParams } from "../../commons/utils";
|
||||||
import { Item } from "../../../types/item";
|
import { Item } from "../../../types/item";
|
||||||
import {
|
import {
|
||||||
batchAdd,
|
batchAdd,
|
||||||
@ -15,10 +15,8 @@ import { writeFile, statSync, readFileSync, accessSync } from "node:fs";
|
|||||||
import mime from "mime";
|
import mime from "mime";
|
||||||
import {
|
import {
|
||||||
deleteExtname,
|
deleteExtname,
|
||||||
getFileName,
|
|
||||||
getItemName,
|
getItemName,
|
||||||
isAbsolutePath,
|
isAbsolutePath,
|
||||||
newItem,
|
|
||||||
} from "../../../commons/utils/common";
|
} from "../../../commons/utils/common";
|
||||||
import { iconExts } from "../../commons/utils";
|
import { iconExts } from "../../commons/utils";
|
||||||
import { addAssociateFolderWatcher } from "../classification";
|
import { addAssociateFolderWatcher } from "../classification";
|
||||||
@ -31,7 +29,6 @@ import {
|
|||||||
showSaveDialogSync,
|
showSaveDialogSync,
|
||||||
} from "../commons/index";
|
} from "../commons/index";
|
||||||
import { fork } from "../../commons/utilityProcessUtils";
|
import { fork } from "../../commons/utilityProcessUtils";
|
||||||
import { ShortcutInfo } from "../../../types/common";
|
|
||||||
|
|
||||||
// 窗口
|
// 窗口
|
||||||
let itemAddEditWindow: BrowserWindow | null = null;
|
let itemAddEditWindow: BrowserWindow | null = null;
|
||||||
@ -62,11 +59,7 @@ async function createAddEditWindow(
|
|||||||
fullscreenable: false,
|
fullscreenable: false,
|
||||||
focusable: true,
|
focusable: true,
|
||||||
show: false,
|
show: false,
|
||||||
transparent: global.setting.appearance.transparency < 1,
|
backgroundColor: getMainBackgorunColor(),
|
||||||
backgroundColor:
|
|
||||||
global.setting.appearance.transparency === 1
|
|
||||||
? getMainBackgorunColor()
|
|
||||||
: null,
|
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
spellcheck: false,
|
spellcheck: false,
|
||||||
preload: join(__dirname, "../preload/index.js"),
|
preload: join(__dirname, "../preload/index.js"),
|
||||||
@ -126,11 +119,7 @@ async function createNetworkIconWindow() {
|
|||||||
fullscreenable: false,
|
fullscreenable: false,
|
||||||
focusable: true,
|
focusable: true,
|
||||||
show: false,
|
show: false,
|
||||||
transparent: global.setting.appearance.transparency < 1,
|
backgroundColor: getMainBackgorunColor(),
|
||||||
backgroundColor:
|
|
||||||
global.setting.appearance.transparency === 1
|
|
||||||
? getMainBackgorunColor()
|
|
||||||
: null,
|
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
spellcheck: false,
|
spellcheck: false,
|
||||||
preload: join(__dirname, "../preload/index.js"),
|
preload: join(__dirname, "../preload/index.js"),
|
||||||
@ -181,11 +170,7 @@ async function createSVGIconWindow() {
|
|||||||
fullscreenable: false,
|
fullscreenable: false,
|
||||||
focusable: true,
|
focusable: true,
|
||||||
show: false,
|
show: false,
|
||||||
transparent: global.setting.appearance.transparency < 1,
|
backgroundColor: getMainBackgorunColor(),
|
||||||
backgroundColor:
|
|
||||||
global.setting.appearance.transparency === 1
|
|
||||||
? getMainBackgorunColor()
|
|
||||||
: null,
|
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
spellcheck: false,
|
spellcheck: false,
|
||||||
preload: join(__dirname, "../preload/index.js"),
|
preload: join(__dirname, "../preload/index.js"),
|
||||||
@ -263,17 +248,24 @@ function move(idList: Array<number>, toClassificationId: number) {
|
|||||||
* @param classificationId
|
* @param classificationId
|
||||||
* @param pathList
|
* @param pathList
|
||||||
*/
|
*/
|
||||||
async function drop(classificationId: number, pathList: Array<string>) {
|
function drop(classificationId: number, pathList: Array<string>) {
|
||||||
// 获取项目信息
|
fork(
|
||||||
let resultList = await getDropItemInfo(classificationId, pathList);
|
"getDropItemInfo",
|
||||||
// 添加项目
|
{
|
||||||
let itemList = batchAdd(classificationId, resultList);
|
classificationId,
|
||||||
// 发送消息到页面
|
pathList,
|
||||||
sendToWebContent("mainWindow", "onAddItem", {
|
},
|
||||||
itemList,
|
(resultList: Array<Item>) => {
|
||||||
clear: false,
|
// 添加项目
|
||||||
classificationId: null,
|
let itemList = batchAdd(classificationId, resultList);
|
||||||
});
|
// 发送消息到页面
|
||||||
|
sendToWebContent("mainWindow", "onAddItem", {
|
||||||
|
itemList,
|
||||||
|
clear: false,
|
||||||
|
classificationId: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -319,15 +311,10 @@ function updateOpenInfo(type: string, id: number) {
|
|||||||
*/
|
*/
|
||||||
function run(
|
function run(
|
||||||
type: string,
|
type: string,
|
||||||
operation: "open" | "runas" | "openFileLocation" | "explore",
|
operation: "open" | "runas" | "openFileLocation",
|
||||||
item: Item
|
item: Item
|
||||||
) {
|
) {
|
||||||
if (item.data) {
|
if (item.data) {
|
||||||
if (operation === "open" && item.data.runAsAdmin) {
|
|
||||||
operation = "runas";
|
|
||||||
} else if (operation === "open" && item.type === 1) {
|
|
||||||
operation = "explore";
|
|
||||||
}
|
|
||||||
// 更新打开信息
|
// 更新打开信息
|
||||||
updateOpenInfo(type, item.id);
|
updateOpenInfo(type, item.id);
|
||||||
// 判断类型
|
// 判断类型
|
||||||
@ -704,90 +691,6 @@ function deleteQuickSearchHistory(itemId: number) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 通过路径获取项目信息
|
|
||||||
* @param classificationId
|
|
||||||
* @param pathList
|
|
||||||
*/
|
|
||||||
async function getDropItemInfo(
|
|
||||||
classificationId: number,
|
|
||||||
pathList: Array<string>
|
|
||||||
) {
|
|
||||||
// 项目列表
|
|
||||||
let itemList: Array<Item> = [];
|
|
||||||
// 解析文件信息并添加项目
|
|
||||||
for (const path of pathList) {
|
|
||||||
try {
|
|
||||||
// item
|
|
||||||
let item = newItem({ classificationId });
|
|
||||||
// 目标
|
|
||||||
item.data.target = path;
|
|
||||||
// 名称
|
|
||||||
item.name = getFileName(item.data.target);
|
|
||||||
// 判断是否是快捷方式,如果是的话,需要获取真实路径
|
|
||||||
if (mime.getType(path) === "application/x-ms-shortcut") {
|
|
||||||
// 快捷方式
|
|
||||||
// 获取真实文件路径和参数
|
|
||||||
let shortcutInfo: ShortcutInfo | null =
|
|
||||||
global.addon.getShortcutFileInfo(path);
|
|
||||||
if (shortcutInfo) {
|
|
||||||
// 路径
|
|
||||||
if (shortcutInfo.target) {
|
|
||||||
item.data.target = shortcutInfo.target;
|
|
||||||
}
|
|
||||||
// 参数
|
|
||||||
if (shortcutInfo.arguments) {
|
|
||||||
item.data.params = shortcutInfo.arguments;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 获取图标
|
|
||||||
item.data.icon = await getFileIcon(item.data.target);
|
|
||||||
// 获取后缀,判断是否是url
|
|
||||||
let ext = extname(item.data.target);
|
|
||||||
if (ext && ext.toLowerCase() === ".url") {
|
|
||||||
// url
|
|
||||||
let url = parseUrlFileContent(readFileSync(item.data.target, "utf-8"));
|
|
||||||
if (url && url.trim() !== "") {
|
|
||||||
item.data.target = url;
|
|
||||||
item.type = 2;
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 文件类型
|
|
||||||
let stats = statSync(item.data.target);
|
|
||||||
item.type = stats.isFile() ? 0 : 1;
|
|
||||||
}
|
|
||||||
// 去掉后缀
|
|
||||||
if (item.type === 0 || item.type === 2) {
|
|
||||||
item.name = deleteExtname(item.name);
|
|
||||||
}
|
|
||||||
// push
|
|
||||||
itemList.push(item);
|
|
||||||
} catch (e) {}
|
|
||||||
}
|
|
||||||
return itemList;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 解析.url文件内容以获取URL
|
|
||||||
* @param content
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
function parseUrlFileContent(content: string) {
|
|
||||||
if (content) {
|
|
||||||
const lines = content.split("\n");
|
|
||||||
for (const line of lines) {
|
|
||||||
if (line.startsWith("URL=")) {
|
|
||||||
const url = line.substring(4).trim();
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
createAddEditWindow,
|
createAddEditWindow,
|
||||||
createNetworkIconWindow,
|
createNetworkIconWindow,
|
||||||
|
@ -203,7 +203,8 @@ export default function () {
|
|||||||
// "打开"菜单
|
// "打开"菜单
|
||||||
let openMenu = false;
|
let openMenu = false;
|
||||||
if (
|
if (
|
||||||
item.type === 0 ||
|
(item.type === 0 &&
|
||||||
|
global.addon.hasRunas(parsePath(item.data.target))) ||
|
||||||
item.type === 4 ||
|
item.type === 4 ||
|
||||||
(item.type === 3 && item.data.target === "cmd.exe")
|
(item.type === 3 && item.data.target === "cmd.exe")
|
||||||
) {
|
) {
|
||||||
|
@ -13,7 +13,6 @@ import cacheData from "../commons/cacheData";
|
|||||||
import {
|
import {
|
||||||
getMainBackgorunColor,
|
getMainBackgorunColor,
|
||||||
getWindowInScreen,
|
getWindowInScreen,
|
||||||
mainWindowExist,
|
|
||||||
sendToWebContent,
|
sendToWebContent,
|
||||||
} from "../commons";
|
} from "../commons";
|
||||||
import { release } from "node:os";
|
import { release } from "node:os";
|
||||||
@ -25,6 +24,8 @@ let mainWindow: BrowserWindow | null = null;
|
|||||||
* 主窗口
|
* 主窗口
|
||||||
*/
|
*/
|
||||||
function createMainWindow() {
|
function createMainWindow() {
|
||||||
|
// 预热
|
||||||
|
global.addon.hasRunas(process.execPath);
|
||||||
// 如果窗口存在先关闭窗口
|
// 如果窗口存在先关闭窗口
|
||||||
if (mainWindow && !mainWindow.isDestroyed() && mainWindow.isVisible()) {
|
if (mainWindow && !mainWindow.isDestroyed() && mainWindow.isVisible()) {
|
||||||
mainWindow.close();
|
mainWindow.close();
|
||||||
@ -66,6 +67,11 @@ function createMainWindow() {
|
|||||||
global.addon.removeWindowAnimation(
|
global.addon.removeWindowAnimation(
|
||||||
mainWindow.getNativeWindowHandle().readInt32LE(0)
|
mainWindow.getNativeWindowHandle().readInt32LE(0)
|
||||||
);
|
);
|
||||||
|
// 恢复上一次的位置
|
||||||
|
let bounds = cacheData.cacheStore.get("mainWindowBounds");
|
||||||
|
if (bounds) {
|
||||||
|
mainWindow.setBounds(bounds);
|
||||||
|
}
|
||||||
// 永远居中不可移动
|
// 永远居中不可移动
|
||||||
if (global.setting.general.alwaysCenter) {
|
if (global.setting.general.alwaysCenter) {
|
||||||
mainWindow.setMovable(false);
|
mainWindow.setMovable(false);
|
||||||
@ -76,39 +82,8 @@ function createMainWindow() {
|
|||||||
if (global.setting.general.alwaysTop) {
|
if (global.setting.general.alwaysTop) {
|
||||||
mainWindow.setAlwaysOnTop(true, "screen-saver");
|
mainWindow.setAlwaysOnTop(true, "screen-saver");
|
||||||
}
|
}
|
||||||
// 恢复上一次的位置
|
|
||||||
let bounds: any = cacheData.cacheStore.get("mainWindowBounds");
|
|
||||||
// 锁定尺寸
|
// 锁定尺寸
|
||||||
mainWindow.setResizable(!global.setting.general.lockSize);
|
mainWindow.setResizable(!global.setting.general.lockSize);
|
||||||
// 如果是锁定尺寸的话,使用锁定尺寸来设置窗口尺寸
|
|
||||||
if (global.setting.general.lockSize) {
|
|
||||||
let lockSizeBounds: any = cacheData.cacheStore.get(
|
|
||||||
"mainWindowLockSizeBounds"
|
|
||||||
);
|
|
||||||
if (lockSizeBounds) {
|
|
||||||
if (bounds) {
|
|
||||||
bounds.width = lockSizeBounds.width;
|
|
||||||
bounds.height = lockSizeBounds.height;
|
|
||||||
} else {
|
|
||||||
bounds = {
|
|
||||||
width: lockSizeBounds.width,
|
|
||||||
height: lockSizeBounds.height,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (bounds) {
|
|
||||||
cacheData.cacheStore.set("mainWindowLockSizeBounds", bounds);
|
|
||||||
} else {
|
|
||||||
cacheData.cacheStore.set(
|
|
||||||
"mainWindowLockSizeBounds",
|
|
||||||
mainWindow.getBounds()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (bounds) {
|
|
||||||
mainWindow.setBounds(bounds);
|
|
||||||
}
|
|
||||||
// 托盘
|
// 托盘
|
||||||
createTray(!global.setting.general.hideTray);
|
createTray(!global.setting.general.hideTray);
|
||||||
// 永远居中
|
// 永远居中
|
||||||
@ -181,10 +156,6 @@ function createMainWindow() {
|
|||||||
sendToWebContent("mainWindow", "onCollapseSubClassification", {});
|
sendToWebContent("mainWindow", "onCollapseSubClassification", {});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// 主窗口关闭事件
|
|
||||||
mainWindow.on("closed", () => {
|
|
||||||
app.quit();
|
|
||||||
});
|
|
||||||
// 创建鼠标hook
|
// 创建鼠标hook
|
||||||
let mousedownClassName = null;
|
let mousedownClassName = null;
|
||||||
addon.createMouseHook((...args: any[]) => {
|
addon.createMouseHook((...args: any[]) => {
|
||||||
@ -218,8 +189,6 @@ function createMainWindow() {
|
|||||||
// 中间单击
|
// 中间单击
|
||||||
showHideMouseWheelClick();
|
showHideMouseWheelClick();
|
||||||
}
|
}
|
||||||
// 失去焦点隐藏
|
|
||||||
onBlurHide();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// 禁用标题栏右键
|
// 禁用标题栏右键
|
||||||
@ -234,50 +203,6 @@ function createMainWindow() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 失去焦点隐藏
|
|
||||||
*/
|
|
||||||
function onBlurHide() {
|
|
||||||
if (
|
|
||||||
mainWindowExist() &&
|
|
||||||
global.mainWindow.isVisible() &&
|
|
||||||
global.setting.general.hideLoseFocus &&
|
|
||||||
!global.setting.general.alwaysTop &&
|
|
||||||
global.mainWindow.getChildWindows().length === 0 &&
|
|
||||||
!global.mainWindowShowDialog &&
|
|
||||||
!hasCursorPosWindow(global.mainWindow)
|
|
||||||
) {
|
|
||||||
// 隐藏窗口
|
|
||||||
hideMainWindow();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断鼠标是否在置顶的窗口范围内
|
|
||||||
*/
|
|
||||||
function hasCursorPosWindow(window: BrowserWindow) {
|
|
||||||
if (window && !window.isDestroyed() && window.isVisible()) {
|
|
||||||
// 获取鼠标位置
|
|
||||||
let point = screen.getCursorScreenPoint();
|
|
||||||
// 窗口位置信息
|
|
||||||
let bounds = window.getBounds();
|
|
||||||
// 判断鼠标是否在窗口以外
|
|
||||||
if (
|
|
||||||
point.x < bounds.x ||
|
|
||||||
point.x > bounds.x + bounds.width ||
|
|
||||||
point.y < bounds.y ||
|
|
||||||
point.y > bounds.y + bounds.height
|
|
||||||
) {
|
|
||||||
// 窗口以外
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
// 窗口以内
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 显示窗口之前
|
* 显示窗口之前
|
||||||
* @param blurHide
|
* @param blurHide
|
||||||
@ -303,9 +228,6 @@ function showMainWindowBefore(
|
|||||||
* @param autoHide
|
* @param autoHide
|
||||||
*/
|
*/
|
||||||
function showMainWindow(blurHide: boolean, autoHide = false) {
|
function showMainWindow(blurHide: boolean, autoHide = false) {
|
||||||
if (!mainWindowExist()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// flag
|
// flag
|
||||||
let flag = true;
|
let flag = true;
|
||||||
// 是否开启勿扰模式
|
// 是否开启勿扰模式
|
||||||
@ -320,12 +242,12 @@ function showMainWindow(blurHide: boolean, autoHide = false) {
|
|||||||
}
|
}
|
||||||
if (flag) {
|
if (flag) {
|
||||||
if (!global.setting.general.alwaysTop) {
|
if (!global.setting.general.alwaysTop) {
|
||||||
global.mainWindow.setAlwaysOnTop(true, "screen-saver");
|
mainWindow.setAlwaysOnTop(true, "screen-saver");
|
||||||
}
|
}
|
||||||
global.mainWindow.show();
|
global.mainWindow.show();
|
||||||
global.mainWindow.focus();
|
global.mainWindow.focus();
|
||||||
if (!global.setting.general.alwaysTop) {
|
if (!global.setting.general.alwaysTop) {
|
||||||
global.mainWindow.setAlwaysOnTop(false);
|
mainWindow.setAlwaysOnTop(false);
|
||||||
}
|
}
|
||||||
global.blurHide = blurHide;
|
global.blurHide = blurHide;
|
||||||
}
|
}
|
||||||
@ -335,7 +257,7 @@ function showMainWindow(blurHide: boolean, autoHide = false) {
|
|||||||
* 隐藏窗口
|
* 隐藏窗口
|
||||||
*/
|
*/
|
||||||
function hideMainWindow() {
|
function hideMainWindow() {
|
||||||
if (mainWindowExist() && global.mainWindow.isVisible()) {
|
if (global.mainWindow.isVisible()) {
|
||||||
global.mainWindow.hide();
|
global.mainWindow.hide();
|
||||||
global.blurHide = false;
|
global.blurHide = false;
|
||||||
}
|
}
|
||||||
@ -396,13 +318,10 @@ function createTray(show: boolean) {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
function edgeAdsorb(display: Display | null, workArea = false) {
|
function edgeAdsorb(display: Display | null, workArea = false) {
|
||||||
if (!mainWindowExist()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 如果勾选停靠在桌面边缘时自动隐藏,放行
|
// 如果勾选停靠在桌面边缘时自动隐藏,放行
|
||||||
if (
|
if (
|
||||||
!global.setting.general.edgeAdsorb &&
|
global.mainWindow.isDestroyed() ||
|
||||||
!global.setting.general.edgeAutoHide
|
(!global.setting.general.edgeAdsorb && !global.setting.general.edgeAutoHide)
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -410,7 +329,7 @@ function edgeAdsorb(display: Display | null, workArea = false) {
|
|||||||
// 清空方向
|
// 清空方向
|
||||||
global.mainWindowDirection = null;
|
global.mainWindowDirection = null;
|
||||||
// 屏幕
|
// 屏幕
|
||||||
let displays = display ? [display] : getWindowInScreen(global.mainWindow);
|
let displays = display ? [display] : getWindowInScreen(mainWindow);
|
||||||
if (displays.length > 1 || displays.length === 0) {
|
if (displays.length > 1 || displays.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -499,9 +418,6 @@ function edgeAdsorb(display: Display | null, workArea = false) {
|
|||||||
* 显示时跟随鼠标位置
|
* 显示时跟随鼠标位置
|
||||||
*/
|
*/
|
||||||
function showFollowMousePosition() {
|
function showFollowMousePosition() {
|
||||||
if (!mainWindowExist()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 当永远居中、固定位置勾选后不能使用显示时跟随鼠标位置
|
// 当永远居中、固定位置勾选后不能使用显示时跟随鼠标位置
|
||||||
if (
|
if (
|
||||||
!global.setting.general.alwaysCenter &&
|
!global.setting.general.alwaysCenter &&
|
||||||
@ -532,9 +448,6 @@ function showFollowMousePosition() {
|
|||||||
* 中间单击显示/隐藏窗口
|
* 中间单击显示/隐藏窗口
|
||||||
*/
|
*/
|
||||||
function showHideMouseWheelClick() {
|
function showHideMouseWheelClick() {
|
||||||
if (!mainWindowExist()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (global.setting.general.showHideMouseWheelClick) {
|
if (global.setting.general.showHideMouseWheelClick) {
|
||||||
if (global.mainWindow.isVisible()) {
|
if (global.mainWindow.isVisible()) {
|
||||||
hideMainWindow();
|
hideMainWindow();
|
||||||
@ -548,11 +461,8 @@ function showHideMouseWheelClick() {
|
|||||||
* 永远居中
|
* 永远居中
|
||||||
*/
|
*/
|
||||||
function alwaysCenter() {
|
function alwaysCenter() {
|
||||||
if (!mainWindowExist()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (global.setting.general.alwaysCenter) {
|
if (global.setting.general.alwaysCenter) {
|
||||||
global.mainWindow.center();
|
mainWindow.center();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -563,32 +473,26 @@ function alwaysCenter() {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
function autoHide(size: number, timer: boolean) {
|
function autoHide(size: number, timer: boolean) {
|
||||||
if (!mainWindowExist()) {
|
if (global.mainWindow.isDestroyed() || !global.setting.general.edgeAutoHide) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!global.setting.general.edgeAutoHide) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 当有子窗口时不自动隐藏
|
// 当有子窗口时不自动隐藏
|
||||||
if (
|
if (mainWindow.getChildWindows().length > 0 || global.mainWindowShowDialog) {
|
||||||
global.mainWindow.getChildWindows().length > 0 ||
|
|
||||||
global.mainWindowShowDialog
|
|
||||||
) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let x = screen.getCursorScreenPoint().x;
|
let x = screen.getCursorScreenPoint().x;
|
||||||
let y = screen.getCursorScreenPoint().y;
|
let y = screen.getCursorScreenPoint().y;
|
||||||
try {
|
try {
|
||||||
// 屏幕
|
// 屏幕
|
||||||
let displays = getWindowInScreen(global.mainWindow);
|
let displays = getWindowInScreen(mainWindow);
|
||||||
if (displays.length > 1 || displays.length === 0) {
|
if (displays.length > 1 || displays.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 屏幕区域
|
// 屏幕区域
|
||||||
let displayBounds = displays[0].bounds;
|
let displayBounds = displays[0].bounds;
|
||||||
// 窗口位置信息
|
// 窗口位置信息
|
||||||
let bounds = global.mainWindow.getBounds();
|
let bounds = mainWindow.getBounds();
|
||||||
if (global.mainWindow.isVisible()) {
|
if (mainWindow.isVisible()) {
|
||||||
let flag = false;
|
let flag = false;
|
||||||
if (bounds.x === displayBounds.x && bounds.y === displayBounds.y) {
|
if (bounds.x === displayBounds.x && bounds.y === displayBounds.y) {
|
||||||
// 左上角
|
// 左上角
|
||||||
@ -763,15 +667,12 @@ function doubleClickTaskbar(
|
|||||||
mousedownClassName: string | null,
|
mousedownClassName: string | null,
|
||||||
className: string | null
|
className: string | null
|
||||||
) {
|
) {
|
||||||
if (!mainWindowExist()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 必须开启设置
|
// 必须开启设置
|
||||||
if (!global.setting.general.showHideDoubleClickTaskbar) {
|
if (!global.setting.general.showHideDoubleClickTaskbar) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 获取屏幕
|
// 获取屏幕
|
||||||
let displays = getWindowInScreen(global.mainWindow);
|
let displays = getWindowInScreen(mainWindow);
|
||||||
if (
|
if (
|
||||||
displays.length > 1 ||
|
displays.length > 1 ||
|
||||||
displays.length === 0 ||
|
displays.length === 0 ||
|
||||||
@ -807,7 +708,7 @@ function doubleClickTaskbar(
|
|||||||
// 清空计数
|
// 清空计数
|
||||||
global.doubleClickTaskbarCounter = 0;
|
global.doubleClickTaskbarCounter = 0;
|
||||||
// 显示或隐藏
|
// 显示或隐藏
|
||||||
if (global.mainWindow.isVisible()) {
|
if (mainWindow.isVisible()) {
|
||||||
hideMainWindow();
|
hideMainWindow();
|
||||||
} else {
|
} else {
|
||||||
showMainWindowBefore(false);
|
showMainWindowBefore(false);
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
import { BrowserWindow, shell, screen } from "electron";
|
import { BrowserWindow, shell, screen } from "electron";
|
||||||
import { join } from "node:path";
|
import { join } from "node:path";
|
||||||
import {
|
import { getWindowInScreen, sendToWebContent } from "../commons";
|
||||||
getMainBackgorunColor,
|
|
||||||
getWindowInScreen,
|
|
||||||
sendToWebContent,
|
|
||||||
} from "../commons";
|
|
||||||
import cacheData from "../commons/cacheData";
|
import cacheData from "../commons/cacheData";
|
||||||
|
|
||||||
// 窗口
|
// 窗口
|
||||||
@ -28,11 +24,7 @@ function createQuickSearchWindow() {
|
|||||||
fullscreenable: false,
|
fullscreenable: false,
|
||||||
resizable: false,
|
resizable: false,
|
||||||
alwaysOnTop: true,
|
alwaysOnTop: true,
|
||||||
transparent: global.setting.appearance.transparency < 1,
|
backgroundColor: global.setting.appearance.theme.mainBackgroundColor,
|
||||||
backgroundColor:
|
|
||||||
global.setting.appearance.transparency === 1
|
|
||||||
? getMainBackgorunColor()
|
|
||||||
: null,
|
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
spellcheck: false,
|
spellcheck: false,
|
||||||
backgroundThrottling: false,
|
backgroundThrottling: false,
|
||||||
|
@ -51,6 +51,14 @@ function select() {
|
|||||||
* 添加
|
* 添加
|
||||||
*/
|
*/
|
||||||
function add(setting: Setting) {
|
function add(setting: Setting) {
|
||||||
|
// 首次添加,判断系统语言
|
||||||
|
if (app.getLocale().toLowerCase().indexOf("zh-") === 0) {
|
||||||
|
// 简体中文
|
||||||
|
setting.general.language = "SimplifiedChinese";
|
||||||
|
} else {
|
||||||
|
// 英文
|
||||||
|
setting.general.language = "English";
|
||||||
|
}
|
||||||
// SQL
|
// SQL
|
||||||
let sql = `INSERT INTO ${settingTableName}
|
let sql = `INSERT INTO ${settingTableName}
|
||||||
(id, setting)
|
(id, setting)
|
||||||
@ -59,8 +67,6 @@ function add(setting: Setting) {
|
|||||||
let id = db.prepare(sql).run(1, JSON.stringify(setting)).lastInsertRowid;
|
let id = db.prepare(sql).run(1, JSON.stringify(setting)).lastInsertRowid;
|
||||||
if (id) {
|
if (id) {
|
||||||
global.setting = setting;
|
global.setting = setting;
|
||||||
// 添加设置被视为首次打开软件
|
|
||||||
global.first = true;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -5,11 +5,7 @@ import { hideMainWindow, showMainWindowBefore } from "../main/index";
|
|||||||
import { list as selectClassificationList } from "../classification/data";
|
import { list as selectClassificationList } from "../classification/data";
|
||||||
import { list as selectItemList } from "../item/data";
|
import { list as selectItemList } from "../item/data";
|
||||||
import { run } from "../item";
|
import { run } from "../item";
|
||||||
import {
|
import { closeWindow, getMainBackgorunColor } from "../commons/index";
|
||||||
closeWindow,
|
|
||||||
getMainBackgorunColor,
|
|
||||||
mainWindowExist,
|
|
||||||
} from "../commons/index";
|
|
||||||
import {
|
import {
|
||||||
createQuickSearchWindow,
|
createQuickSearchWindow,
|
||||||
hideQuickSearchWindow,
|
hideQuickSearchWindow,
|
||||||
@ -38,11 +34,7 @@ function createSettingWindow() {
|
|||||||
fullscreenable: false,
|
fullscreenable: false,
|
||||||
skipTaskbar: true,
|
skipTaskbar: true,
|
||||||
show: false,
|
show: false,
|
||||||
transparent: global.setting.appearance.transparency < 1,
|
backgroundColor: getMainBackgorunColor(),
|
||||||
backgroundColor:
|
|
||||||
global.setting.appearance.transparency === 1
|
|
||||||
? getMainBackgorunColor()
|
|
||||||
: null,
|
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
spellcheck: false,
|
spellcheck: false,
|
||||||
preload: join(__dirname, "../preload/index.js"),
|
preload: join(__dirname, "../preload/index.js"),
|
||||||
@ -87,12 +79,10 @@ function setShortcutKey(setting: Setting = global.setting) {
|
|||||||
globalShortcut.register(
|
globalShortcut.register(
|
||||||
setting.general.showHideShortcutKey.replace("Win", "Super"),
|
setting.general.showHideShortcutKey.replace("Win", "Super"),
|
||||||
() => {
|
() => {
|
||||||
if (mainWindowExist()) {
|
if (global.mainWindow.isVisible()) {
|
||||||
if (global.mainWindow.isVisible()) {
|
hideMainWindow();
|
||||||
hideMainWindow();
|
} else {
|
||||||
} else {
|
showMainWindowBefore(true);
|
||||||
showMainWindowBefore(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -110,10 +100,8 @@ function setShortcutKey(setting: Setting = global.setting) {
|
|||||||
globalShortcut.register(
|
globalShortcut.register(
|
||||||
classification.shortcutKey.replace("Win", "Super"),
|
classification.shortcutKey.replace("Win", "Super"),
|
||||||
() => {
|
() => {
|
||||||
if (mainWindowExist()) {
|
// 分类
|
||||||
// 分类
|
showMainWindowBefore(true, false, classification.id);
|
||||||
showMainWindowBefore(true, false, classification.id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -131,20 +119,18 @@ function setShortcutKey(setting: Setting = global.setting) {
|
|||||||
globalShortcut.register(
|
globalShortcut.register(
|
||||||
item.shortcutKey.replace("Win", "Super"),
|
item.shortcutKey.replace("Win", "Super"),
|
||||||
() => {
|
() => {
|
||||||
if (mainWindowExist()) {
|
// flag
|
||||||
// flag
|
let flag = true;
|
||||||
let flag = true;
|
// 是否开启勿扰模式
|
||||||
// 是否开启勿扰模式
|
if (global.setting.general.notDisturb) {
|
||||||
if (global.setting.general.notDisturb) {
|
if (global.addon.isFullscreen()) {
|
||||||
if (global.addon.isFullscreen()) {
|
flag = false;
|
||||||
flag = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (flag) {
|
|
||||||
// 项目
|
|
||||||
run("main", "open", item);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (flag) {
|
||||||
|
// 项目
|
||||||
|
run("main", "open", item);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -16,7 +16,6 @@ import { statSync, mkdirSync, copyFileSync, readFileSync } from "node:fs";
|
|||||||
import mime from "mime";
|
import mime from "mime";
|
||||||
import { checkInvalid } from "../item";
|
import { checkInvalid } from "../item";
|
||||||
import { updateItemOpenNumberSortToDefualt } from "../classification";
|
import { updateItemOpenNumberSortToDefualt } from "../classification";
|
||||||
import cacheData from "../commons/cacheData";
|
|
||||||
|
|
||||||
export default function () {
|
export default function () {
|
||||||
// 创建设置窗口
|
// 创建设置窗口
|
||||||
@ -92,13 +91,6 @@ export default function () {
|
|||||||
// 锁定尺寸
|
// 锁定尺寸
|
||||||
ipcMain.on("setLockSize", (event, args) => {
|
ipcMain.on("setLockSize", (event, args) => {
|
||||||
global.mainWindow.setResizable(!args);
|
global.mainWindow.setResizable(!args);
|
||||||
if (args) {
|
|
||||||
// 存储主窗口尺寸
|
|
||||||
cacheData.cacheStore.set(
|
|
||||||
"mainWindowLockSizeBounds",
|
|
||||||
global.mainWindow.getBounds()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
// 固定位置
|
// 固定位置
|
||||||
ipcMain.on("setFixedPosition", (event, args) => {
|
ipcMain.on("setFixedPosition", (event, args) => {
|
||||||
|
@ -5,7 +5,7 @@ import {
|
|||||||
newItem,
|
newItem,
|
||||||
} from "../../commons/utils/common";
|
} from "../../commons/utils/common";
|
||||||
import { CommonItem, Item } from "../../types/item";
|
import { CommonItem, Item } from "../../types/item";
|
||||||
import { parse, join } from "node:path";
|
import { parse, join, extname } from "node:path";
|
||||||
import { readdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
|
import { readdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
|
||||||
import xml2js from "xml2js";
|
import xml2js from "xml2js";
|
||||||
import { newCommonItem, newCommonItemData } from "../../commons/utils/common";
|
import { newCommonItem, newCommonItemData } from "../../commons/utils/common";
|
||||||
@ -43,6 +43,11 @@ process.parentPort.once("message", async (event) => {
|
|||||||
res = await getStartMenuItemList(dataParam);
|
res = await getStartMenuItemList(dataParam);
|
||||||
} else if (params.name === "getAppxItemList") {
|
} else if (params.name === "getAppxItemList") {
|
||||||
res = await getAppxItemList();
|
res = await getAppxItemList();
|
||||||
|
} else if (params.name === "getDropItemInfo") {
|
||||||
|
res = await getDropItemInfo(
|
||||||
|
dataParam.classificationId,
|
||||||
|
dataParam.pathList
|
||||||
|
);
|
||||||
} else if (params.name === "refreshItemIcon") {
|
} else if (params.name === "refreshItemIcon") {
|
||||||
res = await refreshItemIcon(dataParam);
|
res = await refreshItemIcon(dataParam);
|
||||||
} else if (params.name === "getDirectoryItemList") {
|
} else if (params.name === "getDirectoryItemList") {
|
||||||
@ -553,6 +558,90 @@ function getPropertiesIcon(installLocation: string, result: any) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过路径获取项目信息
|
||||||
|
* @param classificationId
|
||||||
|
* @param pathList
|
||||||
|
*/
|
||||||
|
async function getDropItemInfo(
|
||||||
|
classificationId: number,
|
||||||
|
pathList: Array<string>
|
||||||
|
) {
|
||||||
|
// 项目列表
|
||||||
|
let itemList: Array<Item> = [];
|
||||||
|
// 解析文件信息并添加项目
|
||||||
|
for (const path of pathList) {
|
||||||
|
try {
|
||||||
|
// item
|
||||||
|
let item = newItem({ classificationId });
|
||||||
|
// 目标
|
||||||
|
item.data.target = path;
|
||||||
|
// 名称
|
||||||
|
item.name = getFileName(item.data.target);
|
||||||
|
// 判断是否是快捷方式,如果是的话,需要获取真实路径
|
||||||
|
if (mime.getType(path) === "application/x-ms-shortcut") {
|
||||||
|
// 快捷方式
|
||||||
|
// 获取真实文件路径和参数
|
||||||
|
let shortcutInfo: ShortcutInfo | null =
|
||||||
|
global.addon.getShortcutFileInfo(path);
|
||||||
|
if (shortcutInfo) {
|
||||||
|
// 路径
|
||||||
|
if (shortcutInfo.target) {
|
||||||
|
item.data.target = shortcutInfo.target;
|
||||||
|
}
|
||||||
|
// 参数
|
||||||
|
if (shortcutInfo.arguments) {
|
||||||
|
item.data.params = shortcutInfo.arguments;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 获取图标
|
||||||
|
item.data.icon = await getFileIcon(item.data.target);
|
||||||
|
// 获取后缀,判断是否是url
|
||||||
|
let ext = extname(item.data.target);
|
||||||
|
if (ext && ext.toLowerCase() === ".url") {
|
||||||
|
// url
|
||||||
|
let url = parseUrlFileContent(readFileSync(item.data.target, "utf-8"));
|
||||||
|
if (url && url.trim() !== "") {
|
||||||
|
item.data.target = url;
|
||||||
|
item.type = 2;
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 文件类型
|
||||||
|
let stats = statSync(item.data.target);
|
||||||
|
item.type = stats.isFile() ? 0 : 1;
|
||||||
|
}
|
||||||
|
// 去掉后缀
|
||||||
|
if (item.type === 0 || item.type === 2) {
|
||||||
|
item.name = deleteExtname(item.name);
|
||||||
|
}
|
||||||
|
// push
|
||||||
|
itemList.push(item);
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
return itemList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析.url文件内容以获取URL
|
||||||
|
* @param content
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function parseUrlFileContent(content: string) {
|
||||||
|
if (content) {
|
||||||
|
const lines = content.split("\n");
|
||||||
|
for (const line of lines) {
|
||||||
|
if (line.startsWith("URL=")) {
|
||||||
|
const url = line.substring(4).trim();
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 刷新项目图标
|
* 刷新项目图标
|
||||||
* @param itemList
|
* @param itemList
|
||||||
|
@ -114,10 +114,6 @@ contextBridge.exposeInMainWorld("api", {
|
|||||||
) => {
|
) => {
|
||||||
ipcRenderer.send("run", { operation, target, params, startLocation });
|
ipcRenderer.send("run", { operation, target, params, startLocation });
|
||||||
},
|
},
|
||||||
// 文本框菜单
|
|
||||||
textRightMenu: () => {
|
|
||||||
ipcRenderer.send("textRightMenu");
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
contextBridge.exposeInMainWorld("main", {
|
contextBridge.exposeInMainWorld("main", {
|
||||||
|
2
electron/types/global.d.ts
vendored
2
electron/types/global.d.ts
vendored
@ -5,8 +5,6 @@ import { Setting } from "../../types/setting";
|
|||||||
declare global {
|
declare global {
|
||||||
// addon
|
// addon
|
||||||
var addon: any;
|
var addon: any;
|
||||||
// 是否是首次打开软件
|
|
||||||
var first: boolean;
|
|
||||||
// 语言
|
// 语言
|
||||||
var language: any;
|
var language: any;
|
||||||
// 主窗口
|
// 主窗口
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "dawn-launcher",
|
"name": "dawn-launcher",
|
||||||
"productName": "Dawn Launcher",
|
"productName": "Dawn Launcher",
|
||||||
"version": "1.5.1",
|
"version": "1.4.6",
|
||||||
"main": "dist-electron/main/index.js",
|
"main": "dist-electron/main/index.js",
|
||||||
"description": "Windows 快捷启动工具,帮助您整理杂乱无章的桌面,分门别类管理您的桌面快捷方式,让您的桌面保持干净整洁。",
|
"description": "Windows 快捷启动工具,帮助您整理杂乱无章的桌面,分门别类管理您的桌面快捷方式,让您的桌面保持干净整洁。",
|
||||||
"author": "FanChenIO",
|
"author": "FanChenIO",
|
||||||
|
@ -201,3 +201,12 @@ fn shell_execute(operation: String, file: String, params: String, start_location
|
|||||||
fn system_item_execute(target: String, params: Option<String>) {
|
fn system_item_execute(target: String, params: Option<String>) {
|
||||||
windows::system_item_execute(&target, params.as_deref())
|
windows::system_item_execute(&target, params.as_deref())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断文件是否有以管理员身份运行权限
|
||||||
|
*/
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[napi]
|
||||||
|
fn has_runas(path: String) -> bool {
|
||||||
|
windows::has_runas(&path)
|
||||||
|
}
|
||||||
|
@ -42,14 +42,15 @@ use windows::{
|
|||||||
Shell::{
|
Shell::{
|
||||||
BHID_SFUIObject, IContextMenu, IShellItem, IShellItemImageFactory, IShellLinkW,
|
BHID_SFUIObject, IContextMenu, IShellItem, IShellItemImageFactory, IShellLinkW,
|
||||||
SHCreateItemFromParsingName, SHEmptyRecycleBinW, SHQueryUserNotificationState,
|
SHCreateItemFromParsingName, SHEmptyRecycleBinW, SHQueryUserNotificationState,
|
||||||
ShellLink, CMF_NORMAL, CMINVOKECOMMANDINFO, QUNS_ACCEPTS_NOTIFICATIONS, QUNS_APP,
|
ShellLink, CMF_NORMAL, CMINVOKECOMMANDINFO, GCS_VERBA, QUNS_ACCEPTS_NOTIFICATIONS,
|
||||||
QUNS_BUSY, QUNS_NOT_PRESENT, QUNS_PRESENTATION_MODE, QUNS_QUIET_TIME,
|
QUNS_APP, QUNS_BUSY, QUNS_NOT_PRESENT, QUNS_PRESENTATION_MODE, QUNS_QUIET_TIME,
|
||||||
QUNS_RUNNING_D3D_FULL_SCREEN, SHERB_NOSOUND, SIIGBF_ICONONLY, SLGP_UNCPRIORITY,
|
QUNS_RUNNING_D3D_FULL_SCREEN, SHERB_NOSOUND, SIIGBF_ICONONLY, SLGP_UNCPRIORITY,
|
||||||
},
|
},
|
||||||
WindowsAndMessaging::{
|
WindowsAndMessaging::{
|
||||||
CallNextHookEx, CreatePopupMenu, DestroyMenu, FindWindowW, GetClassNameW,
|
CallNextHookEx, CreatePopupMenu, DestroyMenu, FindWindowW, GetClassNameW,
|
||||||
GetCursorPos, GetForegroundWindow, GetSystemMetrics, GetWindowRect, SendMessageW,
|
GetCursorPos, GetForegroundWindow, GetMenuItemCount, GetMenuItemInfoA,
|
||||||
SetForegroundWindow, SetWindowsHookExW, TrackPopupMenu, WindowFromPoint, HHOOK,
|
GetSystemMetrics, GetWindowRect, SendMessageW, SetForegroundWindow,
|
||||||
|
SetWindowsHookExW, TrackPopupMenu, WindowFromPoint, HHOOK, MENUITEMINFOA, MIIM_ID,
|
||||||
MSLLHOOKSTRUCT, SC_MONITORPOWER, SM_CXSCREEN, SM_CYSCREEN, SW_NORMAL, TPM_NONOTIFY,
|
MSLLHOOKSTRUCT, SC_MONITORPOWER, SM_CXSCREEN, SM_CYSCREEN, SW_NORMAL, TPM_NONOTIFY,
|
||||||
TPM_RETURNCMD, WH_MOUSE_LL, WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MBUTTONDOWN,
|
TPM_RETURNCMD, WH_MOUSE_LL, WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MBUTTONDOWN,
|
||||||
WM_MBUTTONUP, WM_MOUSEHWHEEL, WM_MOUSEMOVE, WM_MOUSEWHEEL, WM_RBUTTONDOWN,
|
WM_MBUTTONUP, WM_MOUSEHWHEEL, WM_MOUSEMOVE, WM_MOUSEWHEEL, WM_RBUTTONDOWN,
|
||||||
@ -721,8 +722,6 @@ pub fn shell_execute(
|
|||||||
start_location: Option<String>,
|
start_location: Option<String>,
|
||||||
) {
|
) {
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
// 是否是打开文件夹
|
|
||||||
let is_dir = operation == "explore";
|
|
||||||
// dir
|
// dir
|
||||||
let dir = start_location.unwrap_or_else(|| {
|
let dir = start_location.unwrap_or_else(|| {
|
||||||
// 判断是否是文件夹
|
// 判断是否是文件夹
|
||||||
@ -735,10 +734,6 @@ pub fn shell_execute(
|
|||||||
path.parent().unwrap().display().to_string()
|
path.parent().unwrap().display().to_string()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// 文件夹
|
|
||||||
let dir_param = format!("\"{}\"", file.to_string());
|
|
||||||
let dir_param = HSTRING::from(dir_param.as_str());
|
|
||||||
let dir_param = PCWSTR(dir_param.as_ptr());
|
|
||||||
// HSTRING
|
// HSTRING
|
||||||
let operation = HSTRING::from(operation.as_str());
|
let operation = HSTRING::from(operation.as_str());
|
||||||
let file = HSTRING::from(file.as_str());
|
let file = HSTRING::from(file.as_str());
|
||||||
@ -750,18 +745,8 @@ pub fn shell_execute(
|
|||||||
let params = PCWSTR(params.as_ptr());
|
let params = PCWSTR(params.as_ptr());
|
||||||
let dir = PCWSTR(dir.as_ptr());
|
let dir = PCWSTR(dir.as_ptr());
|
||||||
unsafe {
|
unsafe {
|
||||||
if is_dir {
|
// execute
|
||||||
ShellExecuteW(
|
ShellExecuteW(None, operation, file, params, dir, SW_SHOWDEFAULT);
|
||||||
None,
|
|
||||||
w!("open"),
|
|
||||||
w!("explorer.exe"),
|
|
||||||
dir_param,
|
|
||||||
None,
|
|
||||||
SW_SHOWDEFAULT,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
ShellExecuteW(None, operation, file, params, dir, SW_SHOWDEFAULT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -804,3 +789,68 @@ pub fn system_item_execute(target: &str, params: Option<&str>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断文件是否有以管理员身份运行权限
|
||||||
|
*/
|
||||||
|
pub fn has_runas(path: &str) -> bool {
|
||||||
|
// IShellItem
|
||||||
|
let path = HSTRING::from(path);
|
||||||
|
if let Ok(shell_item) =
|
||||||
|
unsafe { SHCreateItemFromParsingName::<_, _, IShellItem>(PCWSTR(path.as_ptr()), None) }
|
||||||
|
{
|
||||||
|
// IContextMenu
|
||||||
|
if let Ok(context_menu) =
|
||||||
|
unsafe { shell_item.BindToHandler::<_, IContextMenu>(None, &BHID_SFUIObject) }
|
||||||
|
{
|
||||||
|
// Menu
|
||||||
|
if let Ok(menu) = unsafe { CreatePopupMenu() } {
|
||||||
|
// 写入菜单
|
||||||
|
if let Ok(()) =
|
||||||
|
unsafe { context_menu.QueryContextMenu(menu, 0, 1, 0x7FFF, CMF_NORMAL) }
|
||||||
|
{
|
||||||
|
// 获取菜单总数
|
||||||
|
let count = unsafe { GetMenuItemCount(menu) };
|
||||||
|
// 循环每一项菜单
|
||||||
|
for i in 0..count {
|
||||||
|
// 获取菜单信息
|
||||||
|
let mut menu_info = MENUITEMINFOA::default();
|
||||||
|
menu_info.cbSize = std::mem::size_of::<MENUITEMINFOA>() as u32;
|
||||||
|
menu_info.fMask = MIIM_ID;
|
||||||
|
if unsafe { GetMenuItemInfoA(menu, i as u32, true, &mut menu_info) }
|
||||||
|
.as_bool()
|
||||||
|
{
|
||||||
|
// idcmd
|
||||||
|
let idcmd = menu_info.wID as usize - 1;
|
||||||
|
// 菜单项比如在指定范围内
|
||||||
|
if idcmd >= 1 && idcmd <= 0x7FFF {
|
||||||
|
// 获取菜单命令信息
|
||||||
|
let mut verb = [0u8; 256];
|
||||||
|
let pstr = PSTR(verb.as_mut_ptr());
|
||||||
|
if let Ok(()) = unsafe {
|
||||||
|
context_menu.GetCommandString(
|
||||||
|
menu_info.wID as usize - 1,
|
||||||
|
GCS_VERBA,
|
||||||
|
None,
|
||||||
|
pstr,
|
||||||
|
verb.len() as u32,
|
||||||
|
)
|
||||||
|
} {
|
||||||
|
if let Ok(command) = unsafe { pstr.to_string() } {
|
||||||
|
if command.to_lowercase() == "runas" {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unsafe {
|
||||||
|
DestroyMenu(menu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
22
src/App.vue
22
src/App.vue
@ -305,24 +305,6 @@ function keydown(e: any) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 监听鼠标右键
|
|
||||||
function contextmenu(e: MouseEvent) {
|
|
||||||
let target = e.target as HTMLInputElement;
|
|
||||||
if (target) {
|
|
||||||
if (
|
|
||||||
(target.nodeName != null &&
|
|
||||||
target.nodeName.toLowerCase() == "input" &&
|
|
||||||
target.type != null &&
|
|
||||||
target.type.toLowerCase() == "text") ||
|
|
||||||
(target.nodeName != null && target.nodeName.toLowerCase() == "textarea")
|
|
||||||
) {
|
|
||||||
window.api.textRightMenu();
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 监听
|
// 监听
|
||||||
let onUpdateSettingUnListen: Function | null = null;
|
let onUpdateSettingUnListen: Function | null = null;
|
||||||
// mounted
|
// mounted
|
||||||
@ -331,8 +313,6 @@ onMounted(() => {
|
|||||||
createStyle();
|
createStyle();
|
||||||
// 监听键盘
|
// 监听键盘
|
||||||
window.addEventListener("keydown", keydown, true);
|
window.addEventListener("keydown", keydown, true);
|
||||||
// 监听右键
|
|
||||||
window.addEventListener("contextmenu", contextmenu, true);
|
|
||||||
// 监听更新项目
|
// 监听更新项目
|
||||||
onUpdateSettingUnListen = window.setting.onUpdate((data) => {
|
onUpdateSettingUnListen = window.setting.onUpdate((data) => {
|
||||||
store.setting = data;
|
store.setting = data;
|
||||||
@ -342,8 +322,6 @@ onMounted(() => {
|
|||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
// 监听键盘
|
// 监听键盘
|
||||||
window.removeEventListener("keydown", keydown, true);
|
window.removeEventListener("keydown", keydown, true);
|
||||||
// 监听右键
|
|
||||||
window.removeEventListener("contextmenu", contextmenu, true);
|
|
||||||
// 删除监听
|
// 删除监听
|
||||||
if (onUpdateSettingUnListen) {
|
if (onUpdateSettingUnListen) {
|
||||||
onUpdateSettingUnListen();
|
onUpdateSettingUnListen();
|
||||||
|
1
src/index.d.ts
vendored
1
src/index.d.ts
vendored
@ -37,7 +37,6 @@ declare global {
|
|||||||
params: string | null,
|
params: string | null,
|
||||||
startLocation: string | null
|
startLocation: string | null
|
||||||
) => void;
|
) => void;
|
||||||
textRightMenu: () => void;
|
|
||||||
};
|
};
|
||||||
main: {
|
main: {
|
||||||
showWindow: (blurHide: boolean, autoHide: boolean) => void;
|
showWindow: (blurHide: boolean, autoHide: boolean) => void;
|
||||||
|
@ -4,11 +4,6 @@
|
|||||||
:style="{
|
:style="{
|
||||||
backgroundColor: store.setting.appearance.theme.mainBackgroundColor,
|
backgroundColor: store.setting.appearance.theme.mainBackgroundColor,
|
||||||
color: store.setting.appearance.theme.mainFontColor,
|
color: store.setting.appearance.theme.mainFontColor,
|
||||||
borderRadius:
|
|
||||||
store.setting.appearance.transparency < 1 &&
|
|
||||||
store.setting.appearance.windowRounded
|
|
||||||
? '8px'
|
|
||||||
: undefined,
|
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div class="flex items-center px-2 app-region-drag">
|
<div class="flex items-center px-2 app-region-drag">
|
||||||
@ -34,7 +29,7 @@
|
|||||||
/>
|
/>
|
||||||
<p class="mt-4">Dawn Launcher {{ version }}</p>
|
<p class="mt-4">Dawn Launcher {{ version }}</p>
|
||||||
<p class="mt-2">
|
<p class="mt-2">
|
||||||
Copyright © 2022-2025 Dawn Launcher. All Rights Reserved
|
Copyright © 2022-2024 Dawn Launcher. All Rights Reserved
|
||||||
</p>
|
</p>
|
||||||
<p class="mt-2">
|
<p class="mt-2">
|
||||||
{{ store.language.officialWebsite }}{{ store.language.colon
|
{{ store.language.officialWebsite }}{{ store.language.colon
|
||||||
|
@ -4,11 +4,6 @@
|
|||||||
:style="{
|
:style="{
|
||||||
backgroundColor: store.setting.appearance.theme.mainBackgroundColor,
|
backgroundColor: store.setting.appearance.theme.mainBackgroundColor,
|
||||||
color: store.setting.appearance.theme.mainFontColor,
|
color: store.setting.appearance.theme.mainFontColor,
|
||||||
borderRadius:
|
|
||||||
store.setting.appearance.transparency < 1 &&
|
|
||||||
store.setting.appearance.windowRounded
|
|
||||||
? '8px'
|
|
||||||
: undefined,
|
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div class="flex items-center app-region-drag">
|
<div class="flex items-center app-region-drag">
|
||||||
|
@ -4,11 +4,6 @@
|
|||||||
:style="{
|
:style="{
|
||||||
backgroundColor: store.setting.appearance.theme.mainBackgroundColor,
|
backgroundColor: store.setting.appearance.theme.mainBackgroundColor,
|
||||||
color: store.setting.appearance.theme.mainFontColor,
|
color: store.setting.appearance.theme.mainFontColor,
|
||||||
borderRadius:
|
|
||||||
store.setting.appearance.transparency < 1 &&
|
|
||||||
store.setting.appearance.windowRounded
|
|
||||||
? '8px'
|
|
||||||
: undefined,
|
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div class="flex items-center app-region-drag">
|
<div class="flex items-center app-region-drag">
|
||||||
|
@ -4,11 +4,6 @@
|
|||||||
:style="{
|
:style="{
|
||||||
backgroundColor: store.setting.appearance.theme.mainBackgroundColor,
|
backgroundColor: store.setting.appearance.theme.mainBackgroundColor,
|
||||||
color: store.setting.appearance.theme.mainFontColor,
|
color: store.setting.appearance.theme.mainFontColor,
|
||||||
borderRadius:
|
|
||||||
store.setting.appearance.transparency < 1 &&
|
|
||||||
store.setting.appearance.windowRounded
|
|
||||||
? '8px'
|
|
||||||
: undefined,
|
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div class="flex items-center app-region-drag">
|
<div class="flex items-center app-region-drag">
|
||||||
|
@ -4,11 +4,6 @@
|
|||||||
:style="{
|
:style="{
|
||||||
backgroundColor: store.setting.appearance.theme.mainBackgroundColor,
|
backgroundColor: store.setting.appearance.theme.mainBackgroundColor,
|
||||||
color: store.setting.appearance.theme.mainFontColor,
|
color: store.setting.appearance.theme.mainFontColor,
|
||||||
borderRadius:
|
|
||||||
store.setting.appearance.transparency < 1 &&
|
|
||||||
store.setting.appearance.windowRounded
|
|
||||||
? '8px'
|
|
||||||
: undefined,
|
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div class="flex items-center px-2 app-region-drag">
|
<div class="flex items-center px-2 app-region-drag">
|
||||||
|
@ -4,11 +4,6 @@
|
|||||||
:style="{
|
:style="{
|
||||||
backgroundColor: store.setting.appearance.theme.mainBackgroundColor,
|
backgroundColor: store.setting.appearance.theme.mainBackgroundColor,
|
||||||
color: store.setting.appearance.theme.mainFontColor,
|
color: store.setting.appearance.theme.mainFontColor,
|
||||||
borderRadius:
|
|
||||||
store.setting.appearance.transparency < 1 &&
|
|
||||||
store.setting.appearance.windowRounded
|
|
||||||
? '8px'
|
|
||||||
: undefined,
|
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div class="flex items-center px-2 app-region-drag">
|
<div class="flex items-center px-2 app-region-drag">
|
||||||
|
@ -523,8 +523,6 @@ onMounted(() => {
|
|||||||
// 监听显示窗口之前
|
// 监听显示窗口之前
|
||||||
listens.push(
|
listens.push(
|
||||||
window.main.onShowWindowBefore((data) => {
|
window.main.onShowWindowBefore((data) => {
|
||||||
// 隐藏搜索
|
|
||||||
store.search = false;
|
|
||||||
if (classificationContentRef.value) {
|
if (classificationContentRef.value) {
|
||||||
// 如果分类ID不为空的话选择分类ID
|
// 如果分类ID不为空的话选择分类ID
|
||||||
let selectedClassificationId: number | null =
|
let selectedClassificationId: number | null =
|
||||||
|
@ -5,11 +5,6 @@
|
|||||||
backgroundColor: store.setting.appearance.theme.mainBackgroundColor,
|
backgroundColor: store.setting.appearance.theme.mainBackgroundColor,
|
||||||
color: store.setting.appearance.theme.mainFontColor,
|
color: store.setting.appearance.theme.mainFontColor,
|
||||||
height: height + 'px',
|
height: height + 'px',
|
||||||
borderRadius:
|
|
||||||
store.setting.appearance.transparency < 1 &&
|
|
||||||
store.setting.appearance.windowRounded
|
|
||||||
? '8px'
|
|
||||||
: undefined,
|
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div class="flex items-center px-2 app-region-drag">
|
<div class="flex items-center px-2 app-region-drag">
|
||||||
@ -329,7 +324,9 @@
|
|||||||
v-if="
|
v-if="
|
||||||
selectedMenuId === 0 &&
|
selectedMenuId === 0 &&
|
||||||
form.data.target &&
|
form.data.target &&
|
||||||
form.data.target.trim() !== ''
|
form.data.target.trim() !== '' &&
|
||||||
|
(getFileExtname(form.data.target) === 'exe' ||
|
||||||
|
getFileExtname(form.data.target) === 'bat')
|
||||||
"
|
"
|
||||||
v-model:checked="form.data.runAsAdmin"
|
v-model:checked="form.data.runAsAdmin"
|
||||||
:focusable="false"
|
:focusable="false"
|
||||||
@ -457,6 +454,7 @@ import {
|
|||||||
isAbsolutePath,
|
isAbsolutePath,
|
||||||
deleteExtname,
|
deleteExtname,
|
||||||
getFileName,
|
getFileName,
|
||||||
|
getFileExtname,
|
||||||
} from "../../../commons/utils/common";
|
} from "../../../commons/utils/common";
|
||||||
import SystemItemList from "./components/SystemItemList.vue";
|
import SystemItemList from "./components/SystemItemList.vue";
|
||||||
import StartMenuItemList from "./components/StartMenuItemList.vue";
|
import StartMenuItemList from "./components/StartMenuItemList.vue";
|
||||||
@ -653,6 +651,12 @@ async function confirm() {
|
|||||||
if (!success) {
|
if (!success) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// 后缀
|
||||||
|
let ext = getFileExtname(form.data.target);
|
||||||
|
// 如果选中按管理员运行,但是文件类型不是exe和bat就修改为false
|
||||||
|
if (form.data.runAsAdmin && (!ext || (ext !== "exe" && ext !== "bat"))) {
|
||||||
|
form.data.runAsAdmin = false;
|
||||||
|
}
|
||||||
if (!id) {
|
if (!id) {
|
||||||
// 添加
|
// 添加
|
||||||
await addItem();
|
await addItem();
|
||||||
|
@ -4,11 +4,6 @@
|
|||||||
:style="{
|
:style="{
|
||||||
backgroundColor: store.setting.appearance.theme.mainBackgroundColor,
|
backgroundColor: store.setting.appearance.theme.mainBackgroundColor,
|
||||||
color: store.setting.appearance.theme.mainFontColor,
|
color: store.setting.appearance.theme.mainFontColor,
|
||||||
borderRadius:
|
|
||||||
store.setting.appearance.transparency < 1 &&
|
|
||||||
store.setting.appearance.windowRounded
|
|
||||||
? '8px'
|
|
||||||
: undefined,
|
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div class="flex items-center px-2 app-region-drag">
|
<div class="flex items-center px-2 app-region-drag">
|
||||||
|
@ -4,11 +4,6 @@
|
|||||||
:style="{
|
:style="{
|
||||||
backgroundColor: store.setting.appearance.theme.mainBackgroundColor,
|
backgroundColor: store.setting.appearance.theme.mainBackgroundColor,
|
||||||
color: store.setting.appearance.theme.mainFontColor,
|
color: store.setting.appearance.theme.mainFontColor,
|
||||||
borderRadius:
|
|
||||||
store.setting.appearance.transparency < 1 &&
|
|
||||||
store.setting.appearance.windowRounded
|
|
||||||
? '8px'
|
|
||||||
: undefined,
|
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div class="flex items-center px-2 app-region-drag">
|
<div class="flex items-center px-2 app-region-drag">
|
||||||
|
@ -130,7 +130,6 @@ import {
|
|||||||
setItemWidth,
|
setItemWidth,
|
||||||
run,
|
run,
|
||||||
removeInvalidItem,
|
removeInvalidItem,
|
||||||
showItemList,
|
|
||||||
} from "../js";
|
} from "../js";
|
||||||
import ItemList from "./List.vue";
|
import ItemList from "./List.vue";
|
||||||
import { Item } from "../../../../types/item";
|
import { Item } from "../../../../types/item";
|
||||||
@ -316,21 +315,12 @@ function createItemSortable() {
|
|||||||
let fromClassificationId = parseInt(
|
let fromClassificationId = parseInt(
|
||||||
event.from.getAttribute("classification-id")!
|
event.from.getAttribute("classification-id")!
|
||||||
);
|
);
|
||||||
let fromClassification =
|
// 当前项目
|
||||||
getClassificationById(fromClassificationId);
|
const currentItem =
|
||||||
if (fromClassification) {
|
getItemListByClassificationId(fromClassificationId)[
|
||||||
let itemList =
|
event.oldIndex
|
||||||
getItemListByClassificationId(fromClassificationId);
|
];
|
||||||
if (itemList) {
|
fromIdList.push(currentItem.id);
|
||||||
let copyItemList = JSON.parse(JSON.stringify(itemList));
|
|
||||||
// 可能会存在自定义排序的情况,所以需要按照指定的排序方式获取项目
|
|
||||||
const currentItem = showItemList(
|
|
||||||
copyItemList,
|
|
||||||
fromClassification
|
|
||||||
)[event.oldIndex];
|
|
||||||
fromIdList.push(currentItem.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// 批量操作
|
// 批量操作
|
||||||
for (const value of store.itemBatchOperationDataArray) {
|
for (const value of store.itemBatchOperationDataArray) {
|
||||||
|
@ -240,9 +240,9 @@ function runItem(e: any, dbclick: boolean) {
|
|||||||
let item = getItemById(itemId);
|
let item = getItemById(itemId);
|
||||||
if (item && item.data) {
|
if (item && item.data) {
|
||||||
if (dbclick && store.setting.item.doubleClickOpen) {
|
if (dbclick && store.setting.item.doubleClickOpen) {
|
||||||
run("main", "open", item);
|
run("main", item.data.runAsAdmin ? "runas" : "open", item);
|
||||||
} else if (!dbclick && !store.setting.item.doubleClickOpen) {
|
} else if (!dbclick && !store.setting.item.doubleClickOpen) {
|
||||||
run("main", "open", item);
|
run("main", item.data.runAsAdmin ? "runas" : "open", item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,6 @@
|
|||||||
:style="{
|
:style="{
|
||||||
color: store.setting.appearance.theme.mainFontColor,
|
color: store.setting.appearance.theme.mainFontColor,
|
||||||
backgroundColor: store.setting.appearance.theme.mainBackgroundColor,
|
backgroundColor: store.setting.appearance.theme.mainBackgroundColor,
|
||||||
borderRadius:
|
|
||||||
store.setting.appearance.transparency < 1 &&
|
|
||||||
store.setting.appearance.windowRounded
|
|
||||||
? '8px'
|
|
||||||
: undefined,
|
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
@ -5,11 +5,6 @@
|
|||||||
backgroundColor: store.setting.appearance.theme.mainBackgroundColor,
|
backgroundColor: store.setting.appearance.theme.mainBackgroundColor,
|
||||||
color: store.setting.appearance.theme.mainFontColor,
|
color: store.setting.appearance.theme.mainFontColor,
|
||||||
height: height + 'px',
|
height: height + 'px',
|
||||||
borderRadius:
|
|
||||||
store.setting.appearance.transparency < 1 &&
|
|
||||||
store.setting.appearance.windowRounded
|
|
||||||
? '8px'
|
|
||||||
: undefined,
|
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div class="flex items-center px-2 app-region-drag">
|
<div class="flex items-center px-2 app-region-drag">
|
||||||
|
Loading…
Reference in New Issue
Block a user