Custom HTML Prompt That Doesn't Need Focus to Click a Button?

I found a solution. And thank you KM (@peternlewis) for allowing me to do this kind of thing from a "browser window" (Custom HTML Prompt):

As I said, if the window isn't currently focused, the first click over the button just focuses the window. So I listen to the focus event.

From there, I call a KM macro using window.KeyboardMaestro.Trigger that checks to see if the left mouse button is down (it probably always is, but it doesn't hurt to check), and whether it's over the button.

If all of that is true, I use an Execute a JavaScript in Custom HTML Prompt to execute the function the button click would have called. (I could have also just called the button's click() method).

For anyone who might want a solution like this, here's some code:

const _titleBarHeight = 16;
const _checkMouseDownOverCancelButtonMacroUUID = "99F97187-DAEC-4C02-89F2-D3841EFE2695";

function KMDidShowWindow() {
	// Delay adding the event listener - we don't need the first "focus" event.
	setTimeout(() => {window.addEventListener("focus", onWindowFocused);}, 100);
}

function onWindowFocused() {
	// If the Cancel button is visible, then call our function,
	// but delay it so this "focus" event finishes processing.
	// NOTE: "isHidden()" is a custom prototype - just use your imagination.
	if (!document.getElementById("cancelButton").isHidden())
		setTimeout(executeCheckMouseDownOverCancelButton, 10);
}

function executeCheckMouseDownOverCancelButton() {
	// build the parameters we'll pass to the KM macro
	var params = {};
	var r = document.getElementById("cancelButton").getBoundingClientRect();
	params.CancelButtonLeft = Math.round(window.screenX + r.left);
	params.CancelButtonTop = Math.round(window.screenY + r.top + _titleBarHeight);
	params.CancelButtonRight = Math.round(params.CancelButtonLeft + r.width);
	params.CancelButtonBottom = Math.round(params.CancelButtonTop + r.height);
	
	var paramString = JSON.stringify(params, null, 2);
	console.log(`Calling "Check Mouse Down Over Cancel Button" using the param\n${paramString}`);
	window.KeyboardMaestro.Trigger(_checkMouseDownOverCancelButtonMacroUUID, paramString);
}

function cancelButtonClick() {
	// code not shown because it's outside the context of this topic
}

Here's the macro that gets called, edited to show only the relevant stuff:

Reference: MACRO: Floating Progress Bar (Custom HTML Prompt) v1.3

4 Likes