A follow-up to an old custom action: Reposition a Keyboard Maestro Palette.
Here is a Keyboard Maestro subroutine version, with a sample macro to test its use with the Global palette. (Any other palette can be specified by name):
Move a named KM palette (subroutine & example).kmmacros (8,5 Ko)
2 Likes
Updated the subroutine to allow for X position or Y position to be left blank.
(So that the move can be purely horizontal or purely vertical)
Move a Named Keyboard Maestro Palette.kmmacros (7.0 KB)
Expand disclosure triangle to view JS source
// return (() => {
"use strict";
const main = () => {
const
paletteName = kmvar.Palette_name.trim(),
X = kmvar.New_X_position || "",
Y = kmvar.New_Y_position || "";
return either(
alert(`Move palette named "${paletteName}"`)
)(
msg => msg
)(
0 < paletteName.length
? [X, Y].some(
s => 0 < s.trim().length && isNaN(s)
)
? Left(
[
"X and Y must both be numeric or blank.",
`( Saw X:${X} Y:${Y} )`
].join("\n\n\t")
)
: namedPaletteToXYLR(paletteName)(
[X, Y].map(Number)
)
: Left("Palette name not specified.")
);
};
// namedPaletteToXYLR :: String ->
// (Int, Int) -> Either String IO String
const namedPaletteToXYLR = paletteName =>
(xy) => {
const
se = Application("System Events"),
procs = se.applicationProcesses.where({
name: "Keyboard Maestro Engine"
});
return bindLR(
0 < procs.length
? Right(procs[0])
: Left("Keyboard Maestro Engine not running")
)(
namedWindowMovedLR(se)(paletteName)(xy)
);
};
// namedWindowMovedLR :: System Events -> String ->
// (Num, Num) -> KM Engine Process -> IO Either String String
const namedWindowMovedLR = se =>
paletteName => ([x, y]) =>
procKME => {
const
windowName = (
"global" === paletteName.toLocaleLowerCase()
? "Keyboard Maestro"
: paletteName
),
paletteWin = procKME.windows
.byName(windowName);
return paletteWin.exists()
? Right(
(() => {
const
xy = paletteWin.position(),
newXY = [x || xy[0], y || xy[1]];
return (
paletteWin.position = newXY,
se.perform(paletteWin.actions.AXRaise),
`Palette "${paletteName}" moved to ${newXY}.`
);
})()
)
: Left(
[
"Palette not found as spelled:",
`\t"${paletteName}"`
].join("\n")
);
};
// ----------------------- JXA -----------------------
// alert :: String => String -> IO String
const alert = title =>
s => {
const sa = Object.assign(
Application("System Events"), {
includeStandardAdditions: true
});
return (
sa.activate(),
sa.displayDialog(s, {
withTitle: title,
buttons: ["OK"],
defaultButton: "OK"
}),
s
);
};
// --------------------- GENERIC ---------------------
// Left :: a -> Either a b
const Left = x => ({
type: "Either",
Left: x
});
// Right :: b -> Either a b
const Right = x => ({
type: "Either",
Right: x
});
// bindLR (>>=) :: Either a ->
// (a -> Either b) -> Either b
const bindLR = m =>
mf => m.Left ? (
m
) : mf(m.Right);
// either :: (a -> c) -> (b -> c) -> Either a b -> c
const either = fl =>
// Application of the function fl to the
// contents of any Left value in e, or
// the application of fr to its Right value.
fr => e => e.Left ? (
fl(e.Left)
) : fr(e.Right);
return main();
// })();
1 Like