Skip to content

Instantly share code, notes, and snippets.

@eip
Created November 16, 2025 15:51
Show Gist options
  • Select an option

  • Save eip/af158db2f1584aa377ddf6fdab42d778 to your computer and use it in GitHub Desktop.

Select an option

Save eip/af158db2f1584aa377ddf6fdab42d778 to your computer and use it in GitHub Desktop.
Keep your Mac awake by jiggling the mouse
#!/usr/bin/env osascript -l JavaScript
ObjC.import("Cocoa");
ObjC.import("CoreGraphics");
function screenSize() {
const w = $.NSScreen.mainScreen.frame.size.width;
const h = $.NSScreen.mainScreen.frame.size.height;
return { w, h };
}
function mousePos() {
const event = $.CGEventCreate(null);
const pos = $.CGEventGetLocation(event);
return { x: parseInt(pos.x), y: parseInt(pos.y) };
}
function mouseMove(pos) {
const event = $.CGEventCreateMouseEvent(null, $.kCGEventMouseMoved, $.CGPointMake(pos.x, pos.y), null);
$.CGEventPost($.kCGHIDEventTap, event);
}
function newPos(val, distance, max) {
const jitter = Math.round(Math.random() * distance);
let result = Math.random() < 0.5 ? val - jitter : val + jitter;
if (val - jitter < 0) result = val + jitter;
else if (val + jitter >= max) result = val - jitter;
return result;
}
function print(str) {
$.NSFileHandle.fileHandleWithStandardOutput.writeData($.NSString.alloc.initWithUTF8String(str).dataUsingEncoding($.NSUTF8StringEncoding));
}
function timeFmt(date) {
const hh = date.getHours();
const mm = date.getMinutes();
return `${hh}:${mm.toString().padStart(2, "0")}`;
}
function run(argv) {
let distance, interval, hours, minutes;
if (argv.length === 3) {
distance = Number(argv[0]);
interval = Number(argv[1]);
[hours, minutes] = argv[2].split(":").map(Number);
}
if (isNaN(distance) || isNaN(interval) || isNaN(hours) || isNaN(minutes)) {
print("Usage: engaging.js <distance pixels> <interval seconds> <until HH:MM>\n");
return;
}
if (interval < 1 || interval > 300) {
print("Interval must be between 1 and 300 seconds.\n");
return;
}
if (distance < 1 || distance > 200) {
print("Distance must be between 1 and 200 pixels.\n");
return;
}
if (hours < 0 || hours > 23 || minutes < 0 || minutes > 59) {
print("Time must be in HH:MM format (24-hour clock).\n");
return;
}
const until = new Date();
until.setHours(hours, minutes, 0, 0);
const now = new Date();
if (now > until && now - until > 12 * 60 * 60 * 1000) {
until.setDate(until.getDate() + 1);
}
if (new Date() >= until) {
print(`The specified time ${timeFmt(until)} has already passed today.\n`);
return;
}
print(`Jiggling mouse by ${distance} pixels every ${interval} sec until ${timeFmt(until)}...\n`);
let prev_pos = { x: -1, y: -1 };
const ss = screenSize();
while (new Date() < until) {
const pos = mousePos();
if (pos.x != prev_pos.x || pos.y != prev_pos.y) {
prev_pos = pos;
delay(interval);
continue;
}
mouseMove({ x: newPos(pos.x, distance, ss.w), y: newPos(pos.y, distance, ss.h) });
print(".");
delay(0.5);
mouseMove(pos);
delay(interval - 0.5);
}
print("\nFinished.\n");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment