Qt: как узнать время простоя системы?

Доброго времени суток.

Как это реализовать? То есть, если пользователь не активен в течении некоторого времени (ушел), то сделать какое то действие.

Интересует реализация на глобальном уровне, то есть чтобы работало даже тогда, когда приложение свернуто или в трее или окно приложения не в фокусе. Предполагается слежка за клавиатурой и мышью. Внутри виджета это сделать можно путем переопределения mouseMoveEvent и keyPressEvent. Но на глобальном уровне не представляю как.
  • Вопрос задан
  • 4056 просмотров
Пригласить эксперта
Ответы на вопрос 6
ixSci
@ixSci
Win:
LASTINPUTINFO LastInput = {}; LastInput.cbSize = sizeof(LastInput); ::GetLastInputInfo(&LastInput); uint IdleTime = (::GetTickCount() - LastInput.dwTime)/1000;
Lin:
int EventBase = 0; int ErrorBase = 0; uint IdleTime = 0; if (::XScreenSaverQueryExtension(m_pDisplay, &EventBase, &ErrorBase)) { XScreenSaverInfo* pInfo = ::XScreenSaverAllocInfo(); if (pInfo) { ::XScreenSaverQueryInfo(::XOpenDisplay(NULL), DefaultRootWindow(m_pDisplay), pInfo); IdleTime = static_cast<uint>(pInfo->idle)/1000; ::XFree(pInfo); } }
Mac:
CFTimeInterval Interval = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateHIDSystemState, kCGAnyInputEventType); return static_cast<uint>(Interval);

Пожалуйста.
Ответ написан
sdevalex
@sdevalex
Qt это не умеет, я раньше тоже искал. Читайте информацию по SetWindowsHookEx, если под Windows.
Ответ написан
Комментировать
foxmuldercp
@foxmuldercp
Системный администратор, программист, фотограф
есть программа keepassx, пожете попробовать в её исходниках посмотреть — там есть опция «блокировать базу паролей через n секунд неактивности»
Ответ написан
Комментировать
Ryadovoy
@Ryadovoy
Как вариант можно воспользоваться планировщиком задач, встроенным в операционную систему.
Под Windows можно создать задачу в планировщике, которая будет выполняться, когда система уходит в idle состояние, наверняка в Linux и Mac есть нечто подобное.

Можно конечно и в ручную, но тут не все так просто и нужен комплексный подход:
процессор, диск, сеть, пользовательский ввод, SetThreadExecutionState, полноэкранные, приложения и т.п.

К примеру если пользователь смотрит фильм, то это ведь не idle, и подход, предложенный пользователем ixSci, как минимум будет работать не верно. Также возможны ситуации, когда процессор простаивает, но при этом активно выполняются дисковые операции, либо идет активная работа с сетью.

Еще полезно понизить приоритет фоновой задачи.
Для Windows см. SetThreadPriority с флагом THREAD_MODE_BACKGROUND_BEGIN.

Также, если подходить основательно, то необходимо отслеживать выход из idle, и останавливать задачу.
Ответ написан
vitaly_KF
@vitaly_KF
Разработчик Qt/C++
Есть ещё класс QDesktopWidget, возможно он отслеживает все глобальные события, попробуйте.
Ответ написан
Комментировать
github.com/euroelessar/qutim/tree/master/core/src/corelayers/idledetector
Здесь имеется рабочий код для Windows/MacOS X/X11, протестировано, работает, апи на Qt :)
Изначально взято из Psi, потом немного доработано. Более общего решения не существует, только реализации под конкретную платформу
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы