diff --git a/Telegram/SourceFiles/core/application.cpp b/Telegram/SourceFiles/core/application.cpp index dd83a0ab2..f12c5509a 100644 --- a/Telegram/SourceFiles/core/application.cpp +++ b/Telegram/SourceFiles/core/application.cpp @@ -860,7 +860,9 @@ void Application::updateNonIdle() { } crl::time Application::lastNonIdleTime() const { - return std::max(Platform::LastUserInputTime(), _lastNonIdleTime); + return std::max( + Platform::LastUserInputTime().value_or(0), + _lastNonIdleTime); } rpl::producer Application::passcodeLockChanges() const { diff --git a/Telegram/SourceFiles/platform/linux/specific_linux.cpp b/Telegram/SourceFiles/platform/linux/specific_linux.cpp index 2342e2a61..dba4a7357 100644 --- a/Telegram/SourceFiles/platform/linux/specific_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/specific_linux.cpp @@ -193,10 +193,6 @@ void psDeleteDir(const QString &dir) { _removeDirectory(dir); } -bool psIdleSupported() { - return false; -} - void psActivateProcess(uint64 pid) { // objc_activateProgram(); } @@ -435,10 +431,6 @@ bool OpenSystemSettings(SystemSettingsType type) { return true; } -crl::time LastUserInputTime() { - return 0LL; -} - namespace ThirdParty { void start() { diff --git a/Telegram/SourceFiles/platform/linux/specific_linux.h b/Telegram/SourceFiles/platform/linux/specific_linux.h index 646a15384..cd68306f2 100644 --- a/Telegram/SourceFiles/platform/linux/specific_linux.h +++ b/Telegram/SourceFiles/platform/linux/specific_linux.h @@ -33,7 +33,9 @@ inline void ReInitOnTopPanel(QWidget *panel) { QString CurrentExecutablePath(int argc, char *argv[]); -crl::time LastUserInputTime(); +inline std::optional LastUserInputTime() { + return std::nullopt; +} } // namespace Platform @@ -51,8 +53,6 @@ void psWriteDump(); void psDeleteDir(const QString &dir); -bool psIdleSupported(); - QStringList psInitLogs(); void psClearInitLogs(); diff --git a/Telegram/SourceFiles/platform/mac/specific_mac.h b/Telegram/SourceFiles/platform/mac/specific_mac.h index 6e080886c..c87d1054c 100644 --- a/Telegram/SourceFiles/platform/mac/specific_mac.h +++ b/Telegram/SourceFiles/platform/mac/specific_mac.h @@ -19,8 +19,6 @@ inline bool TranslucentWindowsSupported(QPoint globalPosition) { QString CurrentExecutablePath(int argc, char *argv[]); -crl::time LastUserInputTime(); - void RemoveQuarantine(const QString &path); namespace ThirdParty { @@ -52,8 +50,6 @@ void psWriteDump(); void psDeleteDir(const QString &dir); -bool psIdleSupported(); - QStringList psInitLogs(); void psClearInitLogs(); diff --git a/Telegram/SourceFiles/platform/mac/specific_mac.mm b/Telegram/SourceFiles/platform/mac/specific_mac.mm index 4a2f21289..b6a89e16e 100644 --- a/Telegram/SourceFiles/platform/mac/specific_mac.mm +++ b/Telegram/SourceFiles/platform/mac/specific_mac.mm @@ -90,10 +90,6 @@ void psDeleteDir(const QString &dir) { objc_deleteDir(dir); } -bool psIdleSupported() { - return objc_idleSupported(); -} - QStringList psInitLogs() { return _initLogs; } @@ -255,9 +251,58 @@ bool OpenSystemSettings(SystemSettingsType type) { return true; } -crl::time LastUserInputTime() { - auto idleTime = 0LL; - return objc_idleTime(idleTime) ? (crl::now() - crl::time(idleTime)) : 0LL; +// Taken from https://github.com/trueinteractions/tint/issues/53. +std::optional LastUserInputTime() { + CFMutableDictionaryRef properties = 0; + CFTypeRef obj; + mach_port_t masterPort; + io_iterator_t iter; + io_registry_entry_t curObj; + + IOMasterPort(MACH_PORT_NULL, &masterPort); + + /* Get IOHIDSystem */ + IOServiceGetMatchingServices(masterPort, IOServiceMatching("IOHIDSystem"), &iter); + if (iter == 0) { + return std::nullopt; + } else { + curObj = IOIteratorNext(iter); + } + if (IORegistryEntryCreateCFProperties(curObj, &properties, kCFAllocatorDefault, 0) == KERN_SUCCESS && properties != NULL) { + obj = CFDictionaryGetValue(properties, CFSTR("HIDIdleTime")); + CFRetain(obj); + } else { + return std::nullopt; + } + + uint64 err = ~0L, idleTime = err; + if (obj) { + CFTypeID type = CFGetTypeID(obj); + + if (type == CFDataGetTypeID()) { + CFDataGetBytes((CFDataRef) obj, CFRangeMake(0, sizeof(idleTime)), (UInt8*)&idleTime); + } else if (type == CFNumberGetTypeID()) { + CFNumberGetValue((CFNumberRef)obj, kCFNumberSInt64Type, &idleTime); + } else { + // error + } + + CFRelease(obj); + + if (idleTime != err) { + idleTime /= 1000000; // return as ms + } + } else { + // error + } + + CFRelease((CFTypeRef)properties); + IOObjectRelease(curObj); + IOObjectRelease(iter); + if (idleTime == err) { + return std::nullopt; + } + return (crl::now() - static_cast(idleTime)); } } // namespace Platform diff --git a/Telegram/SourceFiles/platform/mac/specific_mac_p.h b/Telegram/SourceFiles/platform/mac/specific_mac_p.h index 4b2ed364d..a149447b7 100644 --- a/Telegram/SourceFiles/platform/mac/specific_mac_p.h +++ b/Telegram/SourceFiles/platform/mac/specific_mac_p.h @@ -16,8 +16,6 @@ void objc_bringToBack(WId winId); void objc_debugShowAlert(const QString &str); void objc_outputDebugString(const QString &str); -bool objc_idleSupported(); -bool objc_idleTime(crl::time &idleTime); void objc_start(); void objc_ignoreApplicationActivationRightNow(); diff --git a/Telegram/SourceFiles/platform/mac/specific_mac_p.mm b/Telegram/SourceFiles/platform/mac/specific_mac_p.mm index 8eae41830..5d21d2629 100644 --- a/Telegram/SourceFiles/platform/mac/specific_mac_p.mm +++ b/Telegram/SourceFiles/platform/mac/specific_mac_p.mm @@ -343,64 +343,6 @@ void objc_outputDebugString(const QString &str) { } } -bool objc_idleSupported() { - auto idleTime = 0LL; - return objc_idleTime(idleTime); -} - -bool objc_idleTime(crl::time &idleTime) { // taken from https://github.com/trueinteractions/tint/issues/53 - CFMutableDictionaryRef properties = 0; - CFTypeRef obj; - mach_port_t masterPort; - io_iterator_t iter; - io_registry_entry_t curObj; - - IOMasterPort(MACH_PORT_NULL, &masterPort); - - /* Get IOHIDSystem */ - IOServiceGetMatchingServices(masterPort, IOServiceMatching("IOHIDSystem"), &iter); - if (iter == 0) { - return false; - } else { - curObj = IOIteratorNext(iter); - } - if (IORegistryEntryCreateCFProperties(curObj, &properties, kCFAllocatorDefault, 0) == KERN_SUCCESS && properties != NULL) { - obj = CFDictionaryGetValue(properties, CFSTR("HIDIdleTime")); - CFRetain(obj); - } else { - return false; - } - - uint64 err = ~0L, result = err; - if (obj) { - CFTypeID type = CFGetTypeID(obj); - - if (type == CFDataGetTypeID()) { - CFDataGetBytes((CFDataRef) obj, CFRangeMake(0, sizeof(result)), (UInt8*)&result); - } else if (type == CFNumberGetTypeID()) { - CFNumberGetValue((CFNumberRef)obj, kCFNumberSInt64Type, &result); - } else { - // error - } - - CFRelease(obj); - - if (result != err) { - result /= 1000000; // return as ms - } - } else { - // error - } - - CFRelease((CFTypeRef)properties); - IOObjectRelease(curObj); - IOObjectRelease(iter); - if (result == err) return false; - - idleTime = static_cast(result); - return true; -} - void objc_start() { _sharedDelegate = [[ApplicationDelegate alloc] init]; [[NSApplication sharedApplication] setDelegate:_sharedDelegate]; diff --git a/Telegram/SourceFiles/platform/platform_specific.h b/Telegram/SourceFiles/platform/platform_specific.h index 848ff2194..919065a02 100644 --- a/Telegram/SourceFiles/platform/platform_specific.h +++ b/Telegram/SourceFiles/platform/platform_specific.h @@ -40,8 +40,13 @@ void RequestPermission(PermissionType type, Fn resultCal void OpenSystemSettingsForPermission(PermissionType type); bool OpenSystemSettings(SystemSettingsType type); -QString SystemLanguage(); -QString SystemCountry(); +[[nodiscard]] QString SystemLanguage(); +[[nodiscard]] QString SystemCountry(); + +[[nodiscard]] std::optional LastUserInputTime(); +[[nodiscard]] inline bool LastUserInputTimeSupported() { + return LastUserInputTime().has_value(); +} namespace ThirdParty { diff --git a/Telegram/SourceFiles/platform/win/specific_win.cpp b/Telegram/SourceFiles/platform/win/specific_win.cpp index 5526fb09a..ea8071405 100644 --- a/Telegram/SourceFiles/platform/win/specific_win.cpp +++ b/Telegram/SourceFiles/platform/win/specific_win.cpp @@ -128,12 +128,6 @@ namespace { } } -bool psIdleSupported() { - LASTINPUTINFO lii; - lii.cbSize = sizeof(LASTINPUTINFO); - return GetLastInputInfo(&lii); -} - QStringList psInitLogs() { return _initLogs; } @@ -333,10 +327,12 @@ QString CurrentExecutablePath(int argc, char *argv[]) { return QString(); } -crl::time LastUserInputTime() { - LASTINPUTINFO lii; +std::optional LastUserInputTime() { + auto lii = LASTINPUTINFO{ 0 }; lii.cbSize = sizeof(LASTINPUTINFO); - return GetLastInputInfo(&lii) ? (crl::now() + lii.dwTime - GetTickCount()) : 0LL; + return GetLastInputInfo(&lii) + ? std::make_optional(crl::now() + lii.dwTime - GetTickCount()) + : std::nullopt; } namespace { diff --git a/Telegram/SourceFiles/platform/win/specific_win.h b/Telegram/SourceFiles/platform/win/specific_win.h index 169b0f5e4..fe28a368f 100644 --- a/Telegram/SourceFiles/platform/win/specific_win.h +++ b/Telegram/SourceFiles/platform/win/specific_win.h @@ -36,8 +36,6 @@ inline void ReInitOnTopPanel(QWidget *panel) { QString CurrentExecutablePath(int argc, char *argv[]); -crl::time LastUserInputTime(); - namespace ThirdParty { inline void start() { @@ -59,8 +57,6 @@ void psWriteDump(); void psDeleteDir(const QString &dir); -bool psIdleSupported(); - QStringList psInitLogs(); void psClearInitLogs(); diff --git a/Telegram/SourceFiles/settings/settings_privacy_security.cpp b/Telegram/SourceFiles/settings/settings_privacy_security.cpp index 855584317..9a84960c2 100644 --- a/Telegram/SourceFiles/settings/settings_privacy_security.cpp +++ b/Telegram/SourceFiles/settings/settings_privacy_security.cpp @@ -205,7 +205,7 @@ void SetupLocalPasscode(not_null container) { Ui::show(Box(true)); }); - const auto label = psIdleSupported() + const auto label = Platform::LastUserInputTimeSupported() ? lng_passcode_autolock_away : lng_passcode_autolock_inactive; auto value = PasscodeChanges( diff --git a/Telegram/SourceFiles/window/notifications_manager_default.cpp b/Telegram/SourceFiles/window/notifications_manager_default.cpp index 0e9f659b5..95d4b2a15 100644 --- a/Telegram/SourceFiles/window/notifications_manager_default.cpp +++ b/Telegram/SourceFiles/window/notifications_manager_default.cpp @@ -586,7 +586,10 @@ void Notification::prepareActionsCache() { bool Notification::checkLastInput(bool hasReplyingNotifications) { if (!_waitingForInput) return true; - if (Core::App().lastNonIdleTime() > _started) { + const auto waitForUserInput = Platform::LastUserInputTimeSupported() + ? (Core::App().lastNonIdleTime() <= _started) + : false; + if (!waitForUserInput) { _waitingForInput = false; if (!hasReplyingNotifications) { _hideTimer.start(st::notifyWaitLongHide);