Compare commits

..

No commits in common. "main" and "0.3.2" have entirely different histories.
main ... 0.3.2

4 changed files with 37 additions and 102 deletions

View File

@ -1,8 +1,8 @@
<img alt="" src="tray.png" align="right" height="128px"> <img alt="" src="tray.png" align="right" height="128px">
**Tray** is an [Obsidian](https://obsidian.md/) plugin that can be used to launch the app **Tray** is an [Obsidian](https://obsidian.md/) plugin that can be used to launch the app
on system startup and run it in the background, adding global hotkeys and a tray menu to on system startup and run it in the background, adding global hotkeys and a tray menu that
toggle window visibility and create quick notes from anywhere in your operating system. toggle app window visibility and can create quick notes from anywhere in your operating system.
## Configuration ## Configuration
@ -33,7 +33,7 @@ Hotkeys can be assigned to the commands via Obsidian's built-in hotkey manager.
## Installation ## Installation
### Obsidian Marketplace ### Obsidian Marketplace (Coming Soon)
1. In Obsidian, navigate to **Settings****Community plugins**. 1. In Obsidian, navigate to **Settings****Community plugins**.
2. Press the **Browse** button beside the **Community plugins** option. 2. Press the **Browse** button beside the **Community plugins** option.

127
main.js
View File

@ -1,5 +1,5 @@
/** /**
* obsidian-tray v0.3.5 * obsidian-tray v0.3.2
* (c) 2023 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/) * (c) 2023 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (https://github.com/dragonwocky/obsidian-tray/) under the MIT license * (https://github.com/dragonwocky/obsidian-tray/) under the MIT license
*/ */
@ -38,59 +38,31 @@ const LOG_PREFIX = "obsidian-tray",
let tray, plugin; let tray, plugin;
const obsidian = require("obsidian"), const obsidian = require("obsidian"),
{ app, Tray, Menu } = require("electron").remote, { app, Tray, Menu, nativeImage } = require("electron").remote,
{ nativeImage, BrowserWindow } = require("electron").remote,
{ getCurrentWindow, globalShortcut } = require("electron").remote; { getCurrentWindow, globalShortcut } = require("electron").remote;
const vaultWindows = new Set(), const childWindows = new Set(),
maximizedWindows = new Set(), observeChildWindows = () => {
getWindows = () => [...vaultWindows], getCurrentWindow().webContents.on("did-create-window", (win) => {
observeWindows = () => { childWindows.add(win);
const onWindowCreation = (win) => { win.on("close", () => childWindows.delete(win));
vaultWindows.add(win);
win.setSkipTaskbar(plugin.settings.hideTaskbarIcon); win.setSkipTaskbar(plugin.settings.hideTaskbarIcon);
win.on("close", () => {
if (win !== getCurrentWindow()) vaultWindows.delete(win);
}); });
// preserve maximised windows after minimisation
if (win.isMaximized()) maximizedWindows.add(win);
win.on("maximize", () => maximizedWindows.add(win));
win.on("unmaximize", () => maximizedWindows.delete(win));
};
onWindowCreation(getCurrentWindow());
getCurrentWindow().webContents.on("did-create-window", onWindowCreation);
if (process.platform === "darwin") {
// on macos, the "hide taskbar icon" option is implemented
// via app.dock.hide(): thus, the app as a whole will be
// hidden from the dock, including windows from other vaults.
// when a vault is closed via the "close vault" button,
// the cleanup process will call app.dock.show() to restore
// access to any other open vaults w/out the tray enabled
// => thus, this listener is required to re-hide the dock
// if switching to another vault with the option enabled
getCurrentWindow().on("focus", () => {
if (plugin.settings.hideTaskbarIcon) hideTaskbarIcons();
});
}
}, },
getAllWindows = () => [...childWindows, getCurrentWindow()],
showWindows = () => { showWindows = () => {
log(LOG_SHOWING_WINDOWS); log(LOG_SHOWING_WINDOWS);
getWindows().forEach((win) => { getAllWindows().forEach((win) => win.show());
if (maximizedWindows.has(win)) {
win.maximize();
win.focus();
} else win.show();
});
}, },
hideWindows = () => { hideWindows = () => {
log(LOG_HIDING_WINDOWS); log(LOG_HIDING_WINDOWS);
getWindows().forEach((win) => [ getAllWindows().forEach((win) => [
win.isFocused() && win.blur(), win.isFocused() && win.blur(),
plugin.settings.runInBackground ? win.hide() : win.minimize(), plugin.settings.runInBackground ? win.hide() : win.minimize(),
]); ]);
}, },
toggleWindows = (checkForFocus = true) => { toggleWindows = (checkForFocus = true) => {
const openWindows = getWindows().some((win) => { const openWindows = getAllWindows().some((win) => {
return (!checkForFocus || win.isFocused()) && win.isVisible(); return (!checkForFocus || win.isFocused()) && win.isVisible();
}); });
if (openWindows) hideWindows(); if (openWindows) hideWindows();
@ -119,13 +91,10 @@ const onWindowClose = (event) => event.preventDefault(),
window.removeEventListener("beforeunload", onWindowUnload, true); window.removeEventListener("beforeunload", onWindowUnload, true);
}; };
const hideTaskbarIcons = () => { const setHideTaskbarIcon = () => {
getWindows().forEach((win) => win.setSkipTaskbar(true)); getAllWindows().forEach((win) => {
if (process.platform === "darwin") app.dock.hide(); win.setSkipTaskbar(plugin.settings.hideTaskbarIcon);
}, });
showTaskbarIcons = () => {
getWindows().forEach((win) => win.setSkipTaskbar(false));
if (process.platform === "darwin") app.dock.show();
}, },
setLaunchOnStartup = () => { setLaunchOnStartup = () => {
const { launchOnStartup, runInBackground, hideOnLaunch } = plugin.settings; const { launchOnStartup, runInBackground, hideOnLaunch } = plugin.settings;
@ -133,14 +102,6 @@ const hideTaskbarIcons = () => {
openAtLogin: launchOnStartup, openAtLogin: launchOnStartup,
openAsHidden: runInBackground && hideOnLaunch, openAsHidden: runInBackground && hideOnLaunch,
}); });
};
const cleanup = () => {
log(LOG_CLEANUP);
unregisterHotkeys();
showTaskbarIcons();
allowWindowClose();
destroyTray();
}, },
relaunchApp = () => { relaunchApp = () => {
app.relaunch(); app.relaunch();
@ -148,14 +109,10 @@ const cleanup = () => {
}, },
closeVault = () => { closeVault = () => {
log(LOG_CLEANUP); log(LOG_CLEANUP);
cleanup(); unregisterHotkeys();
const vaultWindows = getWindows(), allowWindowClose();
obsidianWindows = BrowserWindow.getAllWindows(); destroyTray();
if (obsidianWindows.length === vaultWindows.length) { getAllWindows().forEach((win) => win.destroy());
// quit app directly if only remaining windows are in the
// current vault - necessary for successful quit on macos
app.quit();
} else vaultWindows.forEach((win) => win.destroy());
}; };
const addQuickNote = () => { const addQuickNote = () => {
@ -164,18 +121,8 @@ const addQuickNote = () => {
date = obsidian.moment().format(pattern), date = obsidian.moment().format(pattern),
name = obsidian name = obsidian
.normalizePath(`${quickNoteLocation ?? ""}/${date}`) .normalizePath(`${quickNoteLocation ?? ""}/${date}`)
.replace(/\*|"|\\|<|>|:|\||\?/g, "-"), .replace(/\*|"|\\|<|>|:|\||\?/g, "-");
// manually create and open file instead of depending plugin.app.fileManager.createAndOpenMarkdownFile(name);
// on createAndOpenMarkdownFile to force file creation
// relative to the root instead of the active file
// (in case user has default location for new notes
// set to "same folder as current file")
leaf = plugin.app.workspace.getLeaf(),
root = plugin.app.fileManager.getNewFileParent(""),
openMode = { active: true, state: { mode: "source" } };
plugin.app.fileManager
.createNewMarkdownFile(root, name)
.then((file) => leaf.openFile(file, openMode));
showWindows(); showWindows();
}, },
replaceVaultName = (str) => { replaceVaultName = (str) => {
@ -218,13 +165,7 @@ const addQuickNote = () => {
tray = new Tray(obsidianIcon); tray = new Tray(obsidianIcon);
tray.setContextMenu(contextMenu); tray.setContextMenu(contextMenu);
tray.setToolTip(replaceVaultName(plugin.settings.trayIconTooltip)); tray.setToolTip(replaceVaultName(plugin.settings.trayIconTooltip));
tray.on("click", () => { tray.on("click", () => toggleWindows(false));
if (process.platform === "darwin") {
// macos does not register separate left/right click actions
// for menu items, icon should open menu w/out causing toggle
tray.popUpContextMenu();
} else toggleWindows(false);
});
}; };
const registerHotkeys = () => { const registerHotkeys = () => {
@ -276,8 +217,8 @@ const OPTIONS = [
default: false, default: false,
onChange() { onChange() {
setLaunchOnStartup(); setLaunchOnStartup();
if (plugin.settings.runInBackground) interceptWindowClose(); const runInBackground = plugin.settings.runInBackground;
else [allowWindowClose(), showWindows()]; if (!runInBackground) showWindows();
}, },
}, },
{ {
@ -288,10 +229,7 @@ const OPTIONS = [
`, `,
type: "toggle", type: "toggle",
default: false, default: false,
onChange() { onChange: setHideTaskbarIcon,
if (plugin.settings.hideTaskbarIcon) hideTaskbarIcons();
else showTaskbarIcons();
},
}, },
{ {
key: "createTrayIcon", key: "createTrayIcon",
@ -453,10 +391,10 @@ class TrayPlugin extends obsidian.Plugin {
plugin = this; plugin = this;
createTrayIcon(); createTrayIcon();
registerHotkeys(); registerHotkeys();
setHideTaskbarIcon();
setLaunchOnStartup(); setLaunchOnStartup();
observeWindows(); observeChildWindows();
if (settings.runInBackground) interceptWindowClose(); if (settings.runInBackground) interceptWindowClose();
if (settings.hideTaskbarIcon) hideTaskbarIcons();
if (settings.hideOnLaunch) { if (settings.hideOnLaunch) {
this.registerEvent(this.app.workspace.onLayoutReady(hideWindows)); this.registerEvent(this.app.workspace.onLayoutReady(hideWindows));
} }
@ -475,15 +413,12 @@ class TrayPlugin extends obsidian.Plugin {
}); });
} }
onunload() { onunload() {
cleanup(); log(LOG_CLEANUP);
unregisterHotkeys();
allowWindowClose();
destroyTray();
} }
getCurrentWindow = getCurrentWindow
getWindows = getWindows;
showWindows = showWindows;
hideWindows = hideWindows;
toggleWindows = toggleWindows;
async loadSettings() { async loadSettings() {
const DEFAULT_SETTINGS = OPTIONS.map((opt) => ({ [opt.key]: opt.default })); const DEFAULT_SETTINGS = OPTIONS.map((opt) => ({ [opt.key]: opt.default }));
this.settings = Object.assign(...DEFAULT_SETTINGS, await this.loadData()); this.settings = Object.assign(...DEFAULT_SETTINGS, await this.loadData());

View File

@ -3,8 +3,8 @@
"name": "Tray", "name": "Tray",
"author": "dragonwocky", "author": "dragonwocky",
"authorUrl": "https://dragonwocky.me/", "authorUrl": "https://dragonwocky.me/",
"description": "Run Obsidian from the system tray for customisable window management & global quick notes", "description": "Launch Obsidian on startup and run it in the background from the system tray.",
"version": "0.3.5", "version": "0.3.2",
"isDesktopOnly": true, "isDesktopOnly": true,
"minAppVersion": "1.0.0" "minAppVersion": "1.0.0"
} }

BIN
tray.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB