John Dalesandro

Restless: Idle-Prevention Utility to Keep Windows PC Awake

Ever been frustrated when your computer goes to sleep or locks the screen just when you didn’t want it to? Maybe you’re running a long download, compiling code, watching a video without interaction, or testing software. Windows built-in idle timers are useful, but they can be too aggressive when you need the system to stay active.

This C++ program provides a flexible and configurable solution to prevent Windows from idling, sleeping, or locking.

Why You Might Need This Tool

Windows automatically triggers sleep, hibernation, or screen locks after a period of inactivity. This can be inconvenient in situations like:

Instead of changing global power settings, this tool simulates harmless activity to keep the PC awake, without interfering with your work.

What This Program Does

The program works in three main ways:

  1. Keyboard Simulation
  1. Mouse Micro-Jiggle
  1. Power Management Integration

Features and Safety Highlights

Quick-Start Guide

CommandDescription
restless.exeRun with default settings (5-min idle threshold, 1-sec check, keyboard input).
restless.exe --interval 600 --freq 2Trigger after 10 min of inactivity, check every 2 seconds.
restless.exe --mouseEnable mouse micro-jiggle simulation.
restless.exe --keyboardEnable keyboard input simulation.
restless.exe --bothEnable both keyboard and mouse simulation.
restless.exe --nodisplay --duration 3600Headless mode for 1 hour; logs to restless.log.
restless.exe --settingsPrint current settings at startup.
restless.exe --helpShow full usage instructions.

Example: Keeping Video Playback Awake

If you’re watching a presentation video that doesn’t involve mouse or keyboard activity, run:

restless.exe --mouse --interval 120 --freq 1

This prevents sleep if no input occurs for 2 minutes with idle checks happening every second.

Download

Download the ZIP file containing the latest Restless build which includes the executable (.exe).

Source Code

#include <windows.h>
#include <iostream>
#include <fstream>
#include <string>
#include <csignal>

using namespace std;

struct Config {
    unsigned int idleThresholdMs = 1000 * 60 * 5;
    unsigned int checkFrequencyMs = 1000;
    unsigned int maxDurationMs = 0;
    bool showSettings = false;
    bool hideConsole = false;
    bool useKeyboard = false;
    bool useMouse = false;
    bool showHelp = false;
    bool argIssue = false;
};

static Config gConfig;
static ofstream gLog;

void LogMessage(const string &msg) {
    if (gConfig.hideConsole && gLog.is_open()) {
        gLog << msg << endl;
    } else {
        cout << msg << endl;
    }
}

BOOL WINAPI ConsoleHandler(DWORD signal) {
    if (signal == CTRL_C_EVENT || signal == CTRL_BREAK_EVENT ||
        signal == CTRL_CLOSE_EVENT || signal == CTRL_LOGOFF_EVENT ||
        signal == CTRL_SHUTDOWN_EVENT)
    {
        LogMessage("[INFO] Exiting and restoring system state...");
        SetThreadExecutionState(ES_CONTINUOUS);
        if (gLog.is_open()) gLog.close();
        ExitProcess(0);
    }
    return TRUE;
}

void SimulateKeyboardInput() {
    INPUT input[2] = {};
    input[0].type = INPUT_KEYBOARD;
    input[0].ki.wVk = VK_SHIFT;
    input[1].type = INPUT_KEYBOARD;
    input[1].ki.wVk = VK_SHIFT;
    input[1].ki.dwFlags = KEYEVENTF_KEYUP;

    SendInput(2, input, sizeof(INPUT));
    LogMessage("[DEBUG] Simulated keyboard input");
}

void SimulateMouseJiggle() {
    POINT pos;
    if (GetCursorPos(&pos)) {
        INPUT input[2] = {};
        input[0].type = INPUT_MOUSE;
        input[0].mi.dx = 1;
        input[0].mi.dy = 1;
        input[0].mi.dwFlags = MOUSEEVENTF_MOVE;

        input[1].type = INPUT_MOUSE;
        input[1].mi.dx = -1;
        input[1].mi.dy = -1;
        input[1].mi.dwFlags = MOUSEEVENTF_MOVE;

        SendInput(2, input, sizeof(INPUT));
        LogMessage("[DEBUG] Simulated mouse jiggle");
    }
}

Config ParseArgs(int argc, char *argv[]) {
    Config cfg;
    for (int i = 1; i < argc; i++) {
        string arg = argv[i];
        if (arg == "--interval" && i + 1 < argc) {
            int val = atoi(argv[++i]);
            cfg.idleThresholdMs = (val > 0)
                ? val * 1000 : cfg.idleThresholdMs;
        } else if (arg == "--freq" && i + 1 < argc) {
            int val = atoi(argv[++i]);
            cfg.checkFrequencyMs = (val > 0)
                ? val * 1000 : cfg.checkFrequencyMs;
        } else if (arg == "--duration" && i + 1 < argc) {
            int val = atoi(argv[++i]);
            cfg.maxDurationMs = (val > 0) ? val * 1000 : 0;
        } else if (arg == "--settings") {
            cfg.showSettings = true;
        } else if (arg == "--nodisplay") {
            cfg.hideConsole = true;
        } else if (arg == "--keyboard") {
            cfg.useKeyboard = true;
        } else if (arg == "--mouse") {
            cfg.useMouse = true;
        } else if (arg == "--both") {
            cfg.useKeyboard = true;
            cfg.useMouse = true;
        } else if (arg == "--help") {
            cfg.showHelp = true;
        } else {
            cfg.argIssue = true;
        }
    }
    return cfg;
}

void ShowUsage() {
    cout << "Usage:\n";
    cout << "  restless.exe [options]\n\n";
    cout << "Options:\n";
    cout << "  --interval <seconds>   Idle threshold before activity "
            "[default: 300]\n";
    cout << "  --freq <seconds>       Check frequency [default: 1]\n";
    cout << "  --duration <seconds>   Exit after duration (0=infinite)\n";
    cout << "  --keyboard             Enable keyboard input\n";
    cout << "  --mouse                Enable mouse jiggle\n";
    cout << "  --both                 Enable both keyboard and mouse\n";
    cout << "  --settings             Show current settings\n";
    cout << "  --nodisplay            Hide console (logs to restless.log)\n";
    cout << "  --help                 Show this help message\n";
}

int main(int argc, char *argv[]) {
    gConfig = ParseArgs(argc, argv);

    if (gConfig.showHelp) {
        ShowUsage();
        return 0;
    }

    if (gConfig.argIssue) {
        ShowUsage();
        return 1;
    }

    if (gConfig.hideConsole) {
        if (!FreeConsole()) {
            cerr << "[WARN] Failed to hide console." << endl;
        }
        gLog.open("restless.log", ios::out | ios::app);
    }

    if (gConfig.showSettings) {
        LogMessage("Interval: " +
            to_string(gConfig.idleThresholdMs / 1000) + " sec");
        LogMessage("Frequency: " +
            to_string(gConfig.checkFrequencyMs / 1000) + " sec");

        string mode;
        if (gConfig.useKeyboard && gConfig.useMouse) {
            mode = "Keyboard + Mouse";
        } else if (gConfig.useKeyboard) {
            mode = "Keyboard only";
        } else if (gConfig.useMouse) {
            mode = "Mouse only";
        } else {
            mode = "None (no activity)";
        }
        LogMessage("Mode: " + mode);

        LogMessage("Max Duration: " +
            (gConfig.maxDurationMs
                ? to_string(gConfig.maxDurationMs / 1000) + " sec"
                : string("Infinite")));
    }

    SetConsoleCtrlHandler(ConsoleHandler, TRUE);
    SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED);

    LASTINPUTINFO lastInput = { sizeof(LASTINPUTINFO) };
    ULONGLONG startTime = GetTickCount64();

    while (true) {
        if (!GetLastInputInfo(&lastInput)) {
            LogMessage("[ERROR] Failed to get input info");
            break;
        }

        ULONGLONG idleTime = GetTickCount64() - lastInput.dwTime;
        ULONGLONG elapsedTime = GetTickCount64() - startTime;

        if (idleTime >= gConfig.idleThresholdMs) {
            if (gConfig.useKeyboard) SimulateKeyboardInput();
            if (gConfig.useMouse) SimulateMouseJiggle();
        }

        if (gConfig.maxDurationMs > 0 &&
            elapsedTime >= gConfig.maxDurationMs)
        {
            LogMessage("[INFO] Max duration reached. Exiting...");
            break;
        }

        Sleep(gConfig.checkFrequencyMs);
    }

    SetThreadExecutionState(ES_CONTINUOUS);
    if (gLog.is_open()) gLog.close();
    return 0;
}

How to Compile

  1. Save the C++ code as restless.cpp.
  2. Open Developer Command Prompt for Visual Studio.
  3. Compile with:
cl restless.cpp /EHsc

This produces restless.exe. Run it with your preferred options.

If you prefer MinGW, you can compile with g++ restless.cpp -o restless.exe.

Troubleshooting

Summary

This idle-prevention tool is both lightweight and configurable. It helps you maintain productivity and avoid interruptions caused by automatic sleep, lock screens, or screen savers.

Whether you’re a developer, tester, or simply tired of Windows putting your PC to sleep, this tool provides a simple and reliable solution especially when access to change the power or sleep settings is not available. With keyboard and mouse simulation, configurable thresholds, and graceful shutdown handling, your PC stays awake when you need it.