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

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

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

Интересует реализация на глобальном уровне, то есть чтобы работало даже тогда, когда приложение свернуто или в трее или окно приложения не в фокусе. Предполагается слежка за клавиатурой и мышью. Внутри виджета это сделать можно путем переопределения mouseMoveEvent и keyPressEvent. Но на глобальном уровне не представляю как.
  • Вопрос задан
  • 4070 просмотров
Пригласить эксперта
Ответы на вопрос 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, потом немного доработано. Более общего решения не существует, только реализации под конкретную платформу
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Похожие вопросы