Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QT track when a user has been idle from the computer?

Tags:

qt

Im trying to figure out how to track when a user has been idle from the computer, meaning not only my application. The reason is that i want my application to be able to set the user as "Away" after a certain amount of time. Think like Skype which takes you away after X minutes.

Any ideas how to accomplish this?

Edit

What i've got so far to track the mouse:

    //Init
    mouseTimer = new QTimer();
    mouseLastPos = QCursor::pos();
    mouseIdleSeconds = 0;

    //Connect and Start
    connect(mouseTimer, SIGNAL(timeout()), this, SLOT(mouseTimerTick()));
    mouseTimer->start(1000);

void MainWindow::mouseTimerTick()
{
    QPoint point = QCursor::pos();
    if(point != mouseLastPos)
        mouseIdleSeconds = 0;
    else
        mouseIdleSeconds++;

    mouseLastPos = point;

    //Here you could determine whatever to do
    //with the total number of idle seconds.

    qDebug() << mouseIdleSeconds;
}

Any way to add keyboard to this also?

like image 788
Alosyius Avatar asked Feb 20 '14 07:02

Alosyius


2 Answers

There are platform-specific ways of getting idle user notifications. You should almost always use those, instead of rolling your own.

Suppose you insist on rolling your own code. On X11, OS X and Windows, applications simply don't receive any events that are targeted at other applications. Qt doesn't offer much help in monitoring such global events. You need hook into the relevant global events, and filter them. This is platform specific.

So, no matter what you do, you have to write some front-end API that exposes the functionality you're after, and write one or more platform-specific backends.

The preferred platform-specific idle time APIs are:

  • On Windows, GetLastInputInfo, see this answer.

  • On OS X, NSWorkspaceWillSleepNotification and NSWorkspaceDidWakeNotification, see this answer.

  • On X11, it is the screensaver API:

    /* gcc -o getIdleTime getIdleTime.c -lXss */
    #include <X11/extensions/scrnsaver.h>
    #include <stdio.h>
    
    int main(void) {
      Display *dpy = XOpenDisplay(NULL);
    
      if (!dpy) {
        return(1);
      }
    
      XScreenSaverInfo *info = XScreenSaverAllocInfo();
      XScreenSaverQueryInfo(dpy, DefaultRootWindow(dpy), info);
      printf("%u", info->idle);
    
      return(0);
    }
    
like image 108
Kuba hasn't forgotten Monica Avatar answered Oct 20 '22 05:10

Kuba hasn't forgotten Monica


Best bet would be to check for mouse and keyboard events.

If you override the eventFilter function and in that check for:

QEvent::MouseButtonPress
QEvent::MouseButtonRelease
QEvent::Wheel
QEvent::KeyPress
QEvent::KeyRelease

Create a QTimer, which will be reset on any of the events, and if not, just let the timer tick and fire a callback at whatever intervalls you wish.

Edit:
Please see comments and Kuba Ober's answer for more info.

like image 1
Jite Avatar answered Oct 20 '22 05:10

Jite