Implement xcb-based LastUserInputTime method

This commit is contained in:
Ilya Fedin 2020-07-10 16:51:30 +04:00 committed by John Preston
parent c3f5de30be
commit 59b521d666
5 changed files with 110 additions and 42 deletions

View File

@ -95,7 +95,7 @@ jobs:
libgtk2.0-dev libice-dev libsm-dev libicu-dev libdrm-dev dh-autoreconf \
autoconf automake build-essential libxml2-dev libass-dev libfreetype6-dev \
libgpac-dev libsdl1.2-dev libtheora-dev libtool libva-dev libvdpau-dev \
libvorbis-dev libxcb1-dev libxcb-image0-dev libxcb-shm0-dev \
libvorbis-dev libxcb1-dev libxcb-image0-dev libxcb-shm0-dev libxcb-screensaver0-dev \
libxcb-xfixes0-dev libxcb-keysyms1-dev libxcb-icccm4-dev libatspi2.0-dev \
libxcb-render-util0-dev libxcb-util0-dev libxcb-xkb-dev libxrender-dev \
libasound-dev libpulse-dev libxcb-sync0-dev libxcb-randr0-dev libegl1-mesa-dev \

View File

@ -127,6 +127,23 @@ PRIVATE
desktop-app::external_openal
)
if (LINUX)
if (DESKTOP_APP_USE_PACKAGED)
find_package(PkgConfig REQUIRED)
pkg_check_modules(XCB_SCREENSAVER REQUIRED IMPORTED_TARGET xcb-screensaver)
pkg_check_modules(XCB REQUIRED IMPORTED_TARGET xcb)
target_link_libraries(Telegram
PRIVATE
PkgConfig::XCB_SCREENSAVER
PkgConfig::XCB
)
else()
target_link_static_libraries(Telegram PRIVATE xcb-screensaver)
target_link_libraries(Telegram PRIVATE xcb)
endif()
endif()
if (LINUX AND NOT TDESKTOP_DISABLE_GTK_INTEGRATION)
find_package(PkgConfig REQUIRED)
target_compile_options(Telegram PRIVATE -Wno-register)

View File

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "platform/linux/specific_linux.h"
#include "platform/linux/linux_libs.h"
#include "base/platform/base_platform_info.h"
#include "lang/lang_keys.h"
#include "mainwidget.h"
#include "mainwindow.h"
@ -23,6 +24,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <QtCore/QStandardPaths>
#include <QtCore/QProcess>
#include <QtCore/QVersionNumber>
#include <qpa/qplatformnativeinterface.h>
#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION
#include <QtDBus/QDBusInterface>
@ -32,6 +34,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <QtDBus/QDBusError>
#endif // !TDESKTOP_DISABLE_DBUS_INTEGRATION
#include <xcb/xcb.h>
#include <xcb/screensaver.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <cstdlib>
@ -268,6 +273,83 @@ bool GenerateDesktopFile(
}
}
std::optional<crl::time> XCBLastUserInputTime() {
if (const auto native = QGuiApplication::platformNativeInterface()) {
const auto connection = reinterpret_cast<xcb_connection_t*>(
native->nativeResourceForIntegration(QByteArray("connection")));
if (!connection) {
return std::nullopt;
}
const auto screen = xcb_setup_roots_iterator(
xcb_get_setup(connection)).data;
if (!screen) {
return std::nullopt;
}
const auto cookie = xcb_screensaver_query_info(connection, screen->root);
auto info = xcb_screensaver_query_info_reply(connection, cookie, nullptr);
if (!info) {
return std::nullopt;
}
const auto idle = info->ms_since_user_input;
free(info);
return (crl::now() - static_cast<crl::time>(idle));
}
return std::nullopt;
}
#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION
std::optional<crl::time> DBusLastUserInputTime() {
static auto NotSupported = false;
if (NotSupported) {
return std::nullopt;
}
static const auto Message = QDBusMessage::createMethodCall(
qsl("org.freedesktop.ScreenSaver"),
qsl("/org/freedesktop/ScreenSaver"),
qsl("org.freedesktop.ScreenSaver"),
qsl("GetSessionIdleTime"));
const QDBusReply<uint> reply = QDBusConnection::sessionBus().call(
Message);
static const auto NotSupportedErrors = {
QDBusError::ServiceUnknown,
QDBusError::NotSupported,
};
static const auto NotSupportedErrorsToLog = {
QDBusError::Disconnected,
QDBusError::AccessDenied,
};
if (reply.isValid()) {
return (crl::now() - static_cast<crl::time>(reply.value()));
} else if (ranges::contains(NotSupportedErrors, reply.error().type())) {
NotSupported = true;
} else {
if (ranges::contains(NotSupportedErrorsToLog, reply.error().type())) {
NotSupported = true;
}
LOG(("Unable to get last user input time: %1: %2")
.arg(reply.error().name())
.arg(reply.error().message()));
}
return std::nullopt;
}
#endif // !TDESKTOP_DISABLE_DBUS_INTEGRATION
} // namespace
void SetApplicationIcon(const QIcon &icon) {
@ -576,47 +658,12 @@ QImage GetImageFromClipboard() {
}
std::optional<crl::time> LastUserInputTime() {
// TODO: a fallback pure-X11 implementation, this one covers only major DEs on X11 and Wayland
// an example: https://stackoverflow.com/q/9049087
if (!IsWayland()) {
return XCBLastUserInputTime();
}
#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION
static auto NotSupported = false;
if (NotSupported) {
return std::nullopt;
}
static const auto Message = QDBusMessage::createMethodCall(
qsl("org.freedesktop.ScreenSaver"),
qsl("/org/freedesktop/ScreenSaver"),
qsl("org.freedesktop.ScreenSaver"),
qsl("GetSessionIdleTime"));
const QDBusReply<uint> reply = QDBusConnection::sessionBus().call(
Message);
static const auto NotSupportedErrors = {
QDBusError::ServiceUnknown,
QDBusError::NotSupported,
};
static const auto NotSupportedErrorsToLog = {
QDBusError::Disconnected,
QDBusError::AccessDenied,
};
if (reply.isValid()) {
return (crl::now() - static_cast<crl::time>(reply.value()));
} else if (ranges::contains(NotSupportedErrors, reply.error().type())) {
NotSupported = true;
} else {
if (ranges::contains(NotSupportedErrorsToLog, reply.error().type())) {
NotSupported = true;
}
LOG(("Unable to get last user input time: %1: %2")
.arg(reply.error().name())
.arg(reply.error().message()));
}
return DBusLastUserInputTime();
#endif // !TDESKTOP_DISABLE_DBUS_INTEGRATION
return std::nullopt;

View File

@ -17,7 +17,7 @@ You will need GCC 8 installed. To install them and all the required dependencies
libgtk2.0-dev libice-dev libsm-dev libicu-dev libdrm-dev dh-autoreconf \
autoconf automake build-essential libxml2-dev libass-dev libfreetype6-dev \
libgpac-dev libsdl1.2-dev libtheora-dev libtool libva-dev libvdpau-dev \
libvorbis-dev libxcb1-dev libxcb-image0-dev libxcb-shm0-dev \
libvorbis-dev libxcb1-dev libxcb-image0-dev libxcb-shm0-dev libxcb-screensaver0-dev \
libxcb-xfixes0-dev libxcb-keysyms1-dev libxcb-icccm4-dev libatspi2.0-dev \
libxcb-render-util0-dev libxcb-util0-dev libxcb-xkb-dev libxrender-dev \
libasound-dev libpulse-dev libxcb-sync0-dev libxcb-randr0-dev libegl1-mesa-dev \

View File

@ -79,6 +79,8 @@ parts:
- libqt5waylandclient5-dev
- libqt5x11extras5-dev
- libssl-dev
- libxcb1-dev
- libxcb-screensaver0-dev
- zlib1g-dev
stage-packages:
- qt5-image-formats-plugins
@ -92,6 +94,8 @@ parts:
- libqt5waylandclient5
- libqt5x11extras5
- libssl1.1
- libxcb1
- libxcb-screensaver0
- zlib1g
cmake-parameters:
- -DCMAKE_BUILD_TYPE=Release