This example uses the functions GetCaretPos and GetCursorPos to call a subroutine when it appears the mouse and keyboard have been idle for set number of seconds. Note, in my testing at least, it appears the GetCaretPos function only reports the position of the caret inside your app, it doesn't change when the caret is outside.
Option Explicit

Private Type POINTAPI
    x As Long
    y As Long
End Type

Private Declare Function GetCaretPos Lib "user32" (lpPoint As _
   POINTAPI) As Long
Private Declare Function GetCursorPos Lib "user32" (lpPoint As _
   POINTAPI) As Long

Private Const IDLE_SECONDS = 600

Private Sub Timer1_Timer()

    Static ptLastCaret As POINTAPI
    Static ptLastCursor As POINTAPI
    Static bNotFirst As Boolean
    Static bTriggered As Boolean
    Static dateChangeTime As Date
    Dim ptCaret As POINTAPI
    Dim ptCursor As POINTAPI
    If Not bNotFirst Then
        bNotFirst = True
        GetCaretPos ptLastCaret
        GetCursorPos ptLastCursor
        dateChangeTime = Now
        Exit Sub
    End If
    GetCursorPos ptCursor
    GetCaretPos ptCaret
    Debug.Print ptCaret.x, ptCaret.y;
    If ptLastCursor.x = ptCursor.x And _
       ptLastCursor.y = ptCursor.y And _
       ptLastCaret.x = ptCaret.x And _
       ptLastCaret.y = ptCaret.y Then
        If Not bTriggered And _
           DateDiff("s", dateChangeTime, Now) > IDLE_SECONDS Then
            bTriggered = True
        End If
        ptLastCursor.x = ptCursor.x
        ptLastCursor.y = ptCursor.y
        ptLastCaret.x = ptCaret.x
        ptLastCaret.y = ptCaret.y
        dateChangeTime = Now
        bTriggered = False
    End If

End Sub

Private Sub IdleTrigger()

    'Do something intresting here.
End Sub
Sample Usage: