SYNERGY-856 - Force prevent sleep (#7047)
* [UB-856] - Set display as busy * SYNERGY-856 - Prevent sleep on Mac * SYNERGY-856 - Prevent sleep on Linux * SYNERGY-856 - Update changelog * SYNERGY-856 - Set user activity on for Mac to prevent sleep * SYNERGY-856 - Prevent screen sleep continuosly * SYNERGY-856 - Try implementing DBus in the server/client * SYNERGY-856 - Move inhibitor to arch instead of gui * SYNERGY-856 - Undo undesired changes * SYNERGY-856 - Undo remaining undersired changes * SYNERGY-856 - Compile on MacOS * SYNERGY-856 - Reduce if/else depth * SYNERGY-856 - Remove AppDelegate include * SYNERGY-856 - Update inhibitor code to have more verbose debug output * SYNERGY-856 - Make methods static * SYNERGY-856 - Remove unused declarations
This commit is contained in:
parent
e69ea6f627
commit
6b1761316a
8 changed files with 156 additions and 17 deletions
|
|
@ -11,6 +11,7 @@ Bug fixes:
|
||||||
- #7036 Fix tray icon not changing theme on Big Sur
|
- #7036 Fix tray icon not changing theme on Big Sur
|
||||||
- #7046 Fix MacOS 10.13 build
|
- #7046 Fix MacOS 10.13 build
|
||||||
- #7049 Scroll doesn't work in case of macOS is server
|
- #7049 Scroll doesn't work in case of macOS is server
|
||||||
|
- #7047 Fix prevent sleep option on Mac and Windows
|
||||||
|
|
||||||
Enhancements:
|
Enhancements:
|
||||||
- #6998 Remove functionality related to the screen saver synchronisation
|
- #6998 Remove functionality related to the screen saver synchronisation
|
||||||
|
|
@ -20,6 +21,7 @@ Enhancements:
|
||||||
- #7030 | #7041 | #7043 Add user notification for secure input on Mac
|
- #7030 | #7041 | #7043 Add user notification for secure input on Mac
|
||||||
- #7044 Apply natural scroll setting independently on each client
|
- #7044 Apply natural scroll setting independently on each client
|
||||||
- #7040 Support "Kana" and "Eisu" keys on Japanese Apple Pro Keyboard (JIS)
|
- #7040 Support "Kana" and "Eisu" keys on Japanese Apple Pro Keyboard (JIS)
|
||||||
|
- #7047 Add prevent sleep option support to Linux
|
||||||
===========
|
===========
|
||||||
|
|
||||||
v1.14.0-stable
|
v1.14.0-stable
|
||||||
|
|
|
||||||
|
|
@ -41,4 +41,10 @@ add_library(arch STATIC ${sources})
|
||||||
|
|
||||||
if (UNIX)
|
if (UNIX)
|
||||||
target_link_libraries(arch ${CMAKE_DL_LIBS} ${libs})
|
target_link_libraries(arch ${CMAKE_DL_LIBS} ${libs})
|
||||||
|
|
||||||
|
if (NOT APPLE)
|
||||||
|
find_package (Qt5 COMPONENTS DBus)
|
||||||
|
include_directories(${Qt5DBus_INCLUDE_DIRS})
|
||||||
|
target_link_libraries (arch Qt5::DBus)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,9 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#ifndef __APPLE__
|
||||||
|
#include <QtDBus>
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// ArchSystemUnix
|
// ArchSystemUnix
|
||||||
|
|
@ -100,3 +103,76 @@ ArchSystemUnix::runCommand(const std::string& cmd)
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef __APPLE__
|
||||||
|
bool
|
||||||
|
ArchSystemUnix::DBusInhibitScreenCall(InhibitScreenServices serviceID, bool state, std::string& error)
|
||||||
|
{
|
||||||
|
error = "";
|
||||||
|
static const std::array<QString, 2> services =
|
||||||
|
{
|
||||||
|
"org.freedesktop.ScreenSaver",
|
||||||
|
"org.gnome.SessionManager"
|
||||||
|
};
|
||||||
|
static const std::array<QString, 2> paths =
|
||||||
|
{
|
||||||
|
"/org/freedesktop/ScreenSaver",
|
||||||
|
"/org/gnome/SessionManager"
|
||||||
|
};
|
||||||
|
static std::array<uint, 2> cookies;
|
||||||
|
|
||||||
|
auto serviceNum = static_cast<uint8_t>(serviceID);
|
||||||
|
|
||||||
|
QDBusConnection bus = QDBusConnection::sessionBus();
|
||||||
|
if (!bus.isConnected())
|
||||||
|
{
|
||||||
|
error = "bus failed to connect";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDBusInterface screenSaverInterface(
|
||||||
|
services[serviceNum],
|
||||||
|
paths[serviceNum],
|
||||||
|
services[serviceNum],
|
||||||
|
bus);
|
||||||
|
|
||||||
|
if (!screenSaverInterface.isValid())
|
||||||
|
{
|
||||||
|
error = "screen saver interface failed to initialize";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDBusReply<uint> reply;
|
||||||
|
if(state)
|
||||||
|
{
|
||||||
|
if (cookies[serviceNum])
|
||||||
|
{
|
||||||
|
error = "coockies are not empty";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
reply = screenSaverInterface.call("Inhibit", "Synergy", "Sleep is manually prevented by the Synergy preferences");
|
||||||
|
if (reply.isValid())
|
||||||
|
cookies[serviceNum] = reply.value();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!cookies[serviceNum])
|
||||||
|
{
|
||||||
|
error = "coockies are empty";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
reply = screenSaverInterface.call("UnInhibit", cookies[serviceNum]);
|
||||||
|
cookies[serviceNum] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!reply.isValid())
|
||||||
|
{
|
||||||
|
QDBusError qerror = reply.error();
|
||||||
|
error = qerror.name().toStdString() + " : " + qerror.message().toStdString();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -36,4 +36,12 @@ public:
|
||||||
virtual std::string getLibsUsed(void) const;
|
virtual std::string getLibsUsed(void) const;
|
||||||
|
|
||||||
static std::string runCommand(const std::string& cmd);
|
static std::string runCommand(const std::string& cmd);
|
||||||
|
|
||||||
|
#ifndef __APPLE__
|
||||||
|
enum class InhibitScreenServices {
|
||||||
|
kScreenSaver,
|
||||||
|
kSessionManager
|
||||||
|
};
|
||||||
|
static bool DBusInhibitScreenCall(InhibitScreenServices serviceID, bool state, std::string& error);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -251,6 +251,7 @@ MSWindowsScreen::enable()
|
||||||
|
|
||||||
if (App::instance().argsBase().m_preventSleep) {
|
if (App::instance().argsBase().m_preventSleep) {
|
||||||
ArchMiscWindows::addBusyState(ArchMiscWindows::kSYSTEM);
|
ArchMiscWindows::addBusyState(ArchMiscWindows::kSYSTEM);
|
||||||
|
ArchMiscWindows::addBusyState(ArchMiscWindows::kDISPLAY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -270,6 +271,7 @@ MSWindowsScreen::disable()
|
||||||
else {
|
else {
|
||||||
// allow the system to enter power saving mode
|
// allow the system to enter power saving mode
|
||||||
ArchMiscWindows::removeBusyState(ArchMiscWindows::kSYSTEM);
|
ArchMiscWindows::removeBusyState(ArchMiscWindows::kSYSTEM);
|
||||||
|
ArchMiscWindows::removeBusyState(ArchMiscWindows::kDISPLAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
// tell key state
|
// tell key state
|
||||||
|
|
|
||||||
|
|
@ -756,8 +756,10 @@ OSXScreen::enable()
|
||||||
{
|
{
|
||||||
if(App::instance().argsBase().m_preventSleep) {
|
if(App::instance().argsBase().m_preventSleep) {
|
||||||
CFStringRef reasonForActivity = CFSTR("Synergy application");
|
CFStringRef reasonForActivity = CFSTR("Synergy application");
|
||||||
IOReturn result = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoIdleSleep,
|
|
||||||
kIOPMAssertionLevelOn, reasonForActivity, &m_sleepPreventionAssertionID);
|
IOReturn result = IOPMAssertionCreateWithName(kIOPMAssertPreventUserIdleDisplaySleep,
|
||||||
|
kIOPMAssertionLevelOn, reasonForActivity,
|
||||||
|
&m_sleepPreventionAssertionID);
|
||||||
if(result != kIOReturnSuccess) {
|
if(result != kIOReturnSuccess) {
|
||||||
m_sleepPreventionAssertionID = 0;
|
m_sleepPreventionAssertionID = 0;
|
||||||
LOG((CLOG_ERR "failed to disable system idle sleep"));
|
LOG((CLOG_ERR "failed to disable system idle sleep"));
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,8 @@
|
||||||
#include "synergy/Clipboard.h"
|
#include "synergy/Clipboard.h"
|
||||||
#include "synergy/KeyMap.h"
|
#include "synergy/KeyMap.h"
|
||||||
#include "synergy/XScreen.h"
|
#include "synergy/XScreen.h"
|
||||||
|
#include "synergy/ArgsBase.h"
|
||||||
|
#include "synergy/App.h"
|
||||||
#include "arch/XArch.h"
|
#include "arch/XArch.h"
|
||||||
#include "arch/Arch.h"
|
#include "arch/Arch.h"
|
||||||
#include "base/Log.h"
|
#include "base/Log.h"
|
||||||
|
|
@ -133,7 +135,7 @@ XWindowsScreen::XWindowsScreen(
|
||||||
if (!disableXInitThreads) {
|
if (!disableXInitThreads) {
|
||||||
// initializes Xlib support for concurrent threads.
|
// initializes Xlib support for concurrent threads.
|
||||||
if (XInitThreads() == 0)
|
if (XInitThreads() == 0)
|
||||||
throw XArch("XInitThreads() returned zero");
|
throw XArch("XInitThreads() returned zero");
|
||||||
} else {
|
} else {
|
||||||
LOG((CLOG_DEBUG "skipping XInitThreads()"));
|
LOG((CLOG_DEBUG "skipping XInitThreads()"));
|
||||||
}
|
}
|
||||||
|
|
@ -245,6 +247,12 @@ XWindowsScreen::enable()
|
||||||
// warp the mouse to the cursor center
|
// warp the mouse to the cursor center
|
||||||
fakeMouseMove(m_xCenter, m_yCenter);
|
fakeMouseMove(m_xCenter, m_yCenter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// disable sleep if the flag is set
|
||||||
|
if (App::instance().argsBase().m_preventSleep &&
|
||||||
|
!disableIdleSleep()) {
|
||||||
|
LOG((CLOG_INFO "Failed to prevent system from going to sleep"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -263,6 +271,12 @@ XWindowsScreen::disable()
|
||||||
if (!m_isPrimary && m_autoRepeat) {
|
if (!m_isPrimary && m_autoRepeat) {
|
||||||
//XAutoRepeatOn(m_display);
|
//XAutoRepeatOn(m_display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// enable sleep when the display is disabled
|
||||||
|
if (App::instance().argsBase().m_preventSleep &&
|
||||||
|
!enableIdleSleep()) {
|
||||||
|
LOG((CLOG_INFO "Failed to enable system idle sleep"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -289,8 +303,8 @@ XWindowsScreen::enter()
|
||||||
CARD16 powerlevel;
|
CARD16 powerlevel;
|
||||||
BOOL enabled;
|
BOOL enabled;
|
||||||
if (DPMSQueryExtension(m_display, &dummy, &dummy) &&
|
if (DPMSQueryExtension(m_display, &dummy, &dummy) &&
|
||||||
DPMSCapable(m_display) &&
|
DPMSCapable(m_display) &&
|
||||||
DPMSInfo(m_display, &powerlevel, &enabled))
|
DPMSInfo(m_display, &powerlevel, &enabled))
|
||||||
{
|
{
|
||||||
if (enabled && powerlevel != DPMSModeOn)
|
if (enabled && powerlevel != DPMSModeOn)
|
||||||
DPMSForceLevel(m_display, DPMSModeOn);
|
DPMSForceLevel(m_display, DPMSModeOn);
|
||||||
|
|
@ -1332,7 +1346,7 @@ XWindowsScreen::handleSystemEvent(const Event& event, void*)
|
||||||
XFreeEventData(m_display, cookie);
|
XFreeEventData(m_display, cookie);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
XFreeEventData(m_display, cookie);
|
XFreeEventData(m_display, cookie);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1539,9 +1553,9 @@ XWindowsScreen::onKeyPress(XKeyEvent& xkey)
|
||||||
false, false, key, mask, 1, keycode);
|
false, false, key, mask, 1, keycode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LOG((CLOG_DEBUG1 "can't map keycode to key id"));
|
LOG((CLOG_DEBUG1 "can't map keycode to key id"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1864,7 +1878,7 @@ XWindowsScreen::doSelectEvents(Window w) const
|
||||||
// select events of interest. do this before querying the tree so
|
// select events of interest. do this before querying the tree so
|
||||||
// we'll get notifications of children created after the XQueryTree()
|
// we'll get notifications of children created after the XQueryTree()
|
||||||
// so we won't miss them.
|
// so we won't miss them.
|
||||||
XSelectInput(m_display, w, mask);
|
XSelectInput(m_display, w, mask);
|
||||||
|
|
||||||
// recurse on child windows
|
// recurse on child windows
|
||||||
Window rw, pw, *cw;
|
Window rw, pw, *cw;
|
||||||
|
|
@ -2156,7 +2170,7 @@ XWindowsScreen::selectXIRawMotion()
|
||||||
mask.mask = (unsigned char*)calloc(mask.mask_len, sizeof(char));
|
mask.mask = (unsigned char*)calloc(mask.mask_len, sizeof(char));
|
||||||
mask.deviceid = XIAllMasterDevices;
|
mask.deviceid = XIAllMasterDevices;
|
||||||
memset(mask.mask, 0, 2);
|
memset(mask.mask, 0, 2);
|
||||||
XISetMask(mask.mask, XI_RawKeyRelease);
|
XISetMask(mask.mask, XI_RawKeyRelease);
|
||||||
XISetMask(mask.mask, XI_RawMotion);
|
XISetMask(mask.mask, XI_RawMotion);
|
||||||
XISelectEvents(m_display, DefaultRootWindow(m_display), &mask, 1);
|
XISelectEvents(m_display, DefaultRootWindow(m_display), &mask, 1);
|
||||||
free(mask.mask);
|
free(mask.mask);
|
||||||
|
|
@ -2186,3 +2200,26 @@ XWindowsScreen::updateScrollDirection()
|
||||||
scrollDirectionUpdateThread.detach();
|
scrollDirectionUpdateThread.detach();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool XWindowsScreen::sleepInhibitCall(bool state, ArchSystemUnix::InhibitScreenServices serviceID)
|
||||||
|
{
|
||||||
|
std::string error;
|
||||||
|
if(!ArchSystemUnix::DBusInhibitScreenCall(serviceID, state, error))
|
||||||
|
{
|
||||||
|
LOG((CLOG_DEBUG "DBus inhibit error %s", error.c_str()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XWindowsScreen::disableIdleSleep()
|
||||||
|
{
|
||||||
|
return sleepInhibitCall(true, ArchSystemUnix::InhibitScreenServices::kScreenSaver) ||
|
||||||
|
sleepInhibitCall(true, ArchSystemUnix::InhibitScreenServices::kSessionManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XWindowsScreen::enableIdleSleep()
|
||||||
|
{
|
||||||
|
return sleepInhibitCall(false, ArchSystemUnix::InhibitScreenServices::kScreenSaver) ||
|
||||||
|
sleepInhibitCall(false, ArchSystemUnix::InhibitScreenServices::kSessionManager);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "arch/Arch.h"
|
||||||
#include "synergy/PlatformScreen.h"
|
#include "synergy/PlatformScreen.h"
|
||||||
#include "synergy/KeyMap.h"
|
#include "synergy/KeyMap.h"
|
||||||
#include "common/stdset.h"
|
#include "common/stdset.h"
|
||||||
|
|
@ -117,6 +118,11 @@ private:
|
||||||
void onError();
|
void onError();
|
||||||
static int ioErrorHandler(Display*);
|
static int ioErrorHandler(Display*);
|
||||||
|
|
||||||
|
// sleep management
|
||||||
|
static bool sleepInhibitCall(bool state, ArchSystemUnix::InhibitScreenServices serviceID);
|
||||||
|
static bool disableIdleSleep();
|
||||||
|
static bool enableIdleSleep();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class KeyEventFilter {
|
class KeyEventFilter {
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue