Compare commits

..

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

3 changed files with 50 additions and 115 deletions

View File

@ -9,7 +9,7 @@ toggle window visibility and create quick notes from anywhere in your operating
### Window management ### Window management
| Option | Description | Default | | Option | Description | Default |
| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| ------------------------------ | | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ |
| Launch on startup | Open Obsidian automatically whenever you log into your computer. | Disabled | | Launch on startup | Open Obsidian automatically whenever you log into your computer. | Disabled |
| Hide on launch | Minimises Obsidian automatically whenever the app is launched. If the "Run in background" option is enabled, windows will be hidden to the system tray/menubar instead of minimised to the taskbar/dock. | Disabled | | Hide on launch | Minimises Obsidian automatically whenever the app is launched. If the "Run in background" option is enabled, windows will be hidden to the system tray/menubar instead of minimised to the taskbar/dock. | Disabled |
| Run in background | Hide the app and continue to run it in the background instead of quitting it when pressing the window close button or toggle focus hotkey. | Disabled | | Run in background | Hide the app and continue to run it in the background instead of quitting it when pressing the window close button or toggle focus hotkey. | Disabled |
@ -17,7 +17,7 @@ toggle window visibility and create quick notes from anywhere in your operating
| Create tray icon | Add an icon to your system tray/menubar to bring hidden Obsidian windows back into focus on click or force a full quit/relaunch of the app through the right-click menu. | Enabled | | Create tray icon | Add an icon to your system tray/menubar to bring hidden Obsidian windows back into focus on click or force a full quit/relaunch of the app through the right-click menu. | Enabled |
| Tray icon image | Set the image used by the tray/menubar icon. Recommended size: 16x16 | ![](obsidian.png) | | Tray icon image | Set the image used by the tray/menubar icon. Recommended size: 16x16 | ![](obsidian.png) |
| Tray icon tooltip | Set a title to identify the tray/menubar icon by. The `{{vault}}` placeholder will be replaced by the vault name. | `{{vault}} \| Obsidian` | | Tray icon tooltip | Set a title to identify the tray/menubar icon by. The `{{vault}}` placeholder will be replaced by the vault name. | `{{vault}} \| Obsidian` |
| Toggle window focus hotkey | This hotkey is registered globally and will be detected even if Obsidian does not have keyboard focus. Format: [Electron accelerator](https://www.electronjs.org/docs/latest/tutorial/keyboard-shortcuts#accelerators) | <kbd>CmdOrCtrl+Shift+Tab</kbd> | | Toggle window focus hotkey | This hotkey is registered globally and will be detected even if Obsidian does not have keyboard focus. Format: [Electron accelerator](https://www.electronjs.org/docs/latest/api/accelerator) | <kbd>CmdOrCtrl+Shift+Tab</kbd> |
The `Relaunch Obsidian` and `Close Vault` actions can be triggered from the tray/menubar context menu, The `Relaunch Obsidian` and `Close Vault` actions can be triggered from the tray/menubar context menu,
or with the in-app command palette (search for "Tray: Relaunch Obsidian" or "Tray: Close Vault"). or with the in-app command palette (search for "Tray: Relaunch Obsidian" or "Tray: Close Vault").
@ -26,14 +26,14 @@ Hotkeys can be assigned to the commands via Obsidian's built-in hotkey manager.
### Quick notes ### Quick notes
| Option | Description | Default | | Option | Description | Default |
| ---------------------- | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| ---------------------------- | | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- |
| Quick note location | New quick notes will be placed in this folder. | | | Quick note location | New quick notes will be placed in this folder. | |
| Quick note date format | New quick notes will use a filename of this pattern. Format: [Moment.js format string](https://momentjs.com/docs/#/displaying/format/) | `YYYY-MM-DD` | | Quick note date format | New quick notes will use a filename of this pattern. Format: [Moment.js format string](https://momentjs.com/docs/#/displaying/format/) | `YYYY-MM-DD` |
| Quick note hotkey | This hotkey is registered globally and will be detected even if Obsidian does not have keyboard focus. Format: [Electron accelerator](https://www.electronjs.org/docs/latest/tutorial/keyboard-shortcuts#accelerators) | <kbd>CmdOrCtrl+Shift+Q</kbd> | | Quick note hotkey | This hotkey is registered globally and will be detected even if Obsidian does not have keyboard focus. Format: [Electron accelerator](https://www.electronjs.org/docs/latest/api/accelerator) | <kbd>CmdOrCtrl+Shift+Q</kbd> |
## 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.

129
main.js
View File

@ -1,5 +1,5 @@
/** /**
* obsidian-tray v0.3.5 * obsidian-tray v0.3.3
* (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
*/ */
@ -24,7 +24,7 @@ const LOG_PREFIX = "obsidian-tray",
ACCELERATOR_FORMAT = ` ACCELERATOR_FORMAT = `
This hotkey is registered globally and will be detected even if Obsidian does This hotkey is registered globally and will be detected even if Obsidian does
not have keyboard focus. Format: not have keyboard focus. Format:
<a href="https://www.electronjs.org/docs/latest/tutorial/keyboard-shortcuts#accelerators" target="_blank" rel="noopener"> <a href="https://www.electronjs.org/docs/latest/api/accelerator" target="_blank" rel="noopener">
Electron accelerator</a> Electron accelerator</a>
`, `,
MOMENT_FORMAT = ` MOMENT_FORMAT = `
@ -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

@ -4,7 +4,7 @@
"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": "Run Obsidian from the system tray for customisable window management & global quick notes",
"version": "0.3.5", "version": "0.3.3",
"isDesktopOnly": true, "isDesktopOnly": true,
"minAppVersion": "1.0.0" "minAppVersion": "1.0.0"
} }