Skip to main content

Dipping Duck

So I was trying to read a document on my computer at work today, while making notes on a piece of paper. But every five minutes the screensaver would activate, causing me to stop writing, type my password, and find my place in the document again. Needless to say it was quite annoying.

Dilbert comic

Now you might be wondering why I don't just change the screensaver time-out or turn off the requirement for a password. Well even though I'm a local administrator, there is a domain-wide GPO that prevents me from doing so. (Yes I know I can edit the registry, but that setting doesn't survive a GP refresh.) I understand the reason for the policy, but five minutes seems a bit too short.

I wanted to fix this problem and keep my job at the same time. Alice's "dipping duck" inspired me to write a simple program to simulate mouse movement.

#include <windows.h>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
    HANDLE htmr = CreateWaitableTimer(NULL, TRUE, L"CheckIdle");
    LARGE_INTEGER lidt;
    LASTINPUTINFO lii;

    __int64 qwdt = -30 * 10000000; /* 30 seconds */
    lidt.LowPart = (DWORD)(qwdt & 0xFFFFFFFF);
    lidt.HighPart = (LONG)(qwdt >> 32);

    while (TRUE) {
        SetWaitableTimer(htmr, &lidt, 0, NULL, NULL, FALSE);
        WaitForSingleObject(htmr, INFINITE);

        RtlZeroMemory(&lii, sizeof(LASTINPUTINFO));
        lii.cbSize = sizeof(LASTINPUTINFO);
        BOOL ret = GetLastInputInfo(&lii);

        int threshold = 3 * 60; /* 3 minutes */
        int idletime = ret ?
            (GetTickCount() - lii.dwTime) / 1000 : 0;

        BOOL scrnsvr = FALSE;
        SystemParametersInfo(
            SPI_GETSCREENSAVERRUNNING, 0, &scrnsvr, 0);

        if (idletime > threshold && !scrnsvr) {
            MOUSEINPUT mi;
            RtlZeroMemory(&mi, sizeof(MOUSEINPUT));
            mi.dwFlags = MOUSEEVENTF_MOVE;
            mi.dx = 1;
            mi.dy = 1;

            INPUT in;
            in.type = INPUT_MOUSE;
            in.mi = mi;

            SendInput(1, &in, sizeof(in));
        }
    }

    return 0;
}

Every thirty seconds the program checks to see if the computer is idle. After three minutes of inactivity (and if the screensaver isn't running), it moves the mouse cursor one pixel down and to the right. If I lock the workstation or manually activate the screensaver, the program won't do anything. To compile this program, create a new empty C++ Win32 application project. Add a new cpp file, drop in the code above, and hit "Build Solution".

Now the screensaver won't be a nuisance when I'm trying to read. I just have to make sure to hit Win-L before I leave my desk!