Volker
September 10, 2026, 4:35am
1
Hi Andreas,
the new Window Switcher in combination with the "Mouse Hovers Dock App Icon" is great.
Currently I am trying to achieve the following behavior:
A left-click on a non focused App in the Dock brings up the last opened window of this App
A left-click on a focused App is doing nothing
A left-lick on a non running App or App without windows is opening a window (standard macOS behavior)
I managed to get (1) working with the "Activate Hovered Item in Window Switcher" action in combination with "Trigger while mouse over Dock" and BTTWindowSwitcherActive = 1
To achieve (3) I want to check if a hovered App in the Dock has already running windows and if not I want to just pass through the left-click to mimic standard macOS behavior.
Can you think of any way to achieve this? I also played around a bit with the "Dock App click" action, but it seems not to fit for my usecase.
Thank you and best regards,
Volker
Do you mean clicking an inactive app should bring forward only its most recently used window, leaving its other windows where they are, while clicking an app with no windows should behave normally?
Nedks
September 10, 2026, 12:02pm
3
Irrelevant to the question being asked, sorry, but how did you get the Mouse Hovers Dock App Icon to work with little window showing. It is not working for me.
you can configure that via the "Mouse Hovers Dock Icon" trigger.
Volker
September 10, 2026, 4:12pm
5
If "inactive" means that the app has opened windows but none of them are frontmost - then yes that's what I try to achieve.
I've already achieved the first part, but struggle to find out which apps do not have a running window so that I can configure the second part.
Nedks
September 11, 2026, 9:29am
6
Hmmm, I have this set, but it doesn't seem to have any effect.
make sure BTT has screen recording permissions in system settings => security & privacy
Nedks
September 11, 2026, 9:38am
8
It was. What seemed to fix it was having a keyboard for shortcut for window snitcher and activating it and then this automation worked. Thanks!
Volker
September 11, 2026, 12:28pm
9
I solved this topic with the following JS -written by AI.
(async () => {
const done = (value) => {
returnToBTT(value);
return value;
};
const readDetails = async () => {
try { return await get_string_variable({ variable_name: "hovered_element_details" }); } catch (_) {}
try { return await get_string_variable("hovered_element_details"); } catch (_) {}
return "";
};
const details = (await readDetails()) || "";
if (!details) return done(false);
const detailValue = (key) => {
const normalize = (v) => String(v || "").replaceAll(" ", "").toLowerCase();
const wanted = new Set([normalize(key), normalize("AX" + key)]);
for (const line of String(details).split(String.fromCharCode(10))) {
const sep = line.indexOf(":");
if (sep === -1) continue;
const lineKey = normalize(line.slice(0, sep).replace(String.fromCharCode(13), ""));
if (!wanted.has(lineKey)) continue;
const raw = line.slice(sep + 1).trim();
return raw.startsWith('"') && raw.endsWith('"') ? raw.slice(1, -1) : raw;
}
return "";
};
const role = detailValue("RoleDescription");
const subrole = detailValue("Subrole");
const isAppDockItem =
/application dock item/i.test(role) || /AXApplicationDockItem/i.test(subrole);
if (!isAppDockItem) return done(false);
const isRunning = detailValue("IsApplicationRunning") === "1";
if (!isRunning) return done(true);
const firstValue = (...keys) => {
for (const key of keys) { const v = detailValue(key); if (v) return v; }
return "";
};
const bundleId = firstValue("BundleIdentifier", "BundleID", "ApplicationBundleIdentifier", "Bundle Identifier");
const appName = firstValue("Title", "Description", "AppName", "ApplicationName");
if (!bundleId && !appName) return done(false);
const appleString = (v) => {
let out = "";
for (const c of String(v || "")) {
const code = c.charCodeAt(0);
if (code === 92) out += "\\\\";
else if (code === 34) out += '\\"';
else if (code === 10 || code === 13) out += " ";
else out += c;
}
return '"' + out + '"';
};
const appleScript = [
"set targetBundleId to " + appleString(bundleId),
"set targetAppName to " + appleString(appName),
'tell application "System Events"',
" set foundProcess to missing value",
' if targetBundleId is not "" then',
" try",
" set procs to application processes whose bundle identifier is targetBundleId",
" if (count of procs) > 0 then set foundProcess to item 1 of procs",
" end try",
" end if",
' if foundProcess is missing value and targetAppName is not "" then',
" try",
" if exists application process targetAppName then set foundProcess to application process targetAppName",
" end try",
" end if",
' if foundProcess is missing value then return "true"',
" if (count of windows of foundProcess) is 0 then return \"true\"",
' return "false"',
"end tell",
].join("\n");
try {
const result = (await runAppleScript(appleScript)) || "false";
return done(result.trim() === "true");
} catch (_) {
return done(false);
}
})();