Identifying the main window

First, search the help docs and this forum. Maybe your question has been answered! The debugging steps can help, too. Still stuck? Delete this line and proceed.

What I’m trying to do

I’m on Windows and I want a hotkey that will activate the main Obsidian window , so I’m looking for a way to distinguish it from the other windows.

I am technical but not a developer so I’m fumbling at the mercy of chatbot. Please save me.

With the bot’s guidance I’ve found that window.location.href is ‘app://obsidian.md/index.html’ for the main window and ‘about:blank’ for the secondary windows.

Chatbot says I can use that to have a custom plug inject text into the title of the main window and update it when the title changes because I’ve moved tabs.

Is this the best way to do this?

Things I have tried

Using window.location.href to ID the main window, chatbot suggested the code below can be put in a custom plugin to alter the window title.

app.workspace.on('active-leaf-change', () => {
 const prefix =
 window.location.href === 'app://obsidian.md/index.html'
 ? '[MAIN] '
 : '[POP] ';
 document.title = prefix + document.title.replace(/^\[(MAIN|POP)\]\s*/, '');
});

I tried the two Community plugins related to Window Title (and the older one that doesn’t load any more) but they don’t ID the main window.

If this could be easily added to one of those I’d be happy to submit the change, but my understanding of Electron and javascript are limited.

Thank you

As you’re a Windows user you can do this with AutoHotKey.

I use v2 of AHK and something like this will either give Obsidian focus or launch it if it’s not running

; Detect hidden windows
DetectHiddenWindows, On

; Do not close the script
#Persistent

; Force single instance of the script
#SingleInstance, Force

; Hotkey: Ctrl + Alt + o
^!o::
    ; Check if Obsidian is already running
    if WinExist("ahk_exe Obsidian.exe")
    {
        ; MsgBox, Obsidian window exists, activating...
        WinActivate
    }
    else
    {
        ; MsgBox, Obsidian window does not exist, launching...
        Run, %LocalAppData%\Programs\obsidian\Obsidian.exe
    }
return

As I use an app launcher I generally do it is like this. Using this example I can give focus to various different apps I’ve got loaded

ToggleWinMinimize(TheWindowTitle) {
SetTitleMatchMode(2)  ; Ensure partial matching works

if WinActive(TheWindowTitle) {
    WinMinimize(TheWindowTitle)
} else if WinExist(TheWindowTitle) {
    winid := WinGetID(TheWindowTitle)
    if winid {  ; Ensure the window ID is valid
        WinActivate(winid)  ; Activate the window
    }
}

}

; Ctrl + Alt and...
^!u::ToggleWinMinimize("UltraEdit")
^!o::ToggleWinMinimize("Obsidian")K
^!k::ToggleWinMinimize("KeePassXC")

The window.location.href check won’t work from a plugin. Plugin code runs in the main window’s JS context even when a popout has focus, so window.location.href is always app://obsidian.md/index.html and document.title is always the main window’s title. That helps you: drop the check and tag the main window every time.

The second issue is the event. Obsidian rewrites the title on more than active-leaf-change. With that listener I lost the prefix after renaming the open file and after opening a popout. Watching the <title> element holds it.

I tested this on Obsidian 1.13.7 with a popout open. The main window kept [MAIN] ... through file switches, renames and new popouts, and the popout titles stayed untouched.

Create a folder .obsidian/plugins/main-window-tag/ in your vault with two files.

manifest.json:

{
  "id": "main-window-tag",
  "name": "Main window tag",
  "version": "0.0.1",
  "minAppVersion": "1.5.0",
  "description": "Prefixes the main window title with [MAIN].",
  "author": "you",
  "isDesktopOnly": true
}

main.js:

const { Plugin } = require("obsidian");

module.exports = class MainWindowTag extends Plugin {
  onload() {
    const tag = "[MAIN] ";
    const apply = () => {
      if (!document.title.startsWith(tag)) document.title = tag + document.title;
    };
    apply();
    const observer = new MutationObserver(apply);
    observer.observe(document.querySelector("title"), { childList: true });
    this.register(() => {
      observer.disconnect();
      document.title = document.title.replace(tag, "");
    });
  }
};

Restart Obsidian and turn on “Main window tag” under Settings → Community plugins.

Then AutoHotkey can target the main window by title. For v2:

^!o:: {
    SetTitleMatchMode 1
    if WinExist("[MAIN] ahk_exe Obsidian.exe")
        WinActivate
}

SetTitleMatchMode 1 means “title starts with”. I’m on macOS, so I haven’t run the AHK part myself.