Skip to content

Commit

Permalink
SYNERGY-856 - Force prevent sleep (#7047)
Browse files Browse the repository at this point in the history
* [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
  • Loading branch information
igor-sikachyna committed Jul 12, 2021
1 parent e69ea6f commit 6b17613
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 17 deletions.
2 changes: 2 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Bug fixes:
- #7036 Fix tray icon not changing theme on Big Sur
- #7046 Fix MacOS 10.13 build
- #7049 Scroll doesn't work in case of macOS is server
- #7047 Fix prevent sleep option on Mac and Windows

Enhancements:
- #6998 Remove functionality related to the screen saver synchronisation
Expand All @@ -20,6 +21,7 @@ Enhancements:
- #7030 | #7041 | #7043 Add user notification for secure input on Mac
- #7044 Apply natural scroll setting independently on each client
- #7040 Support "Kana" and "Eisu" keys on Japanese Apple Pro Keyboard (JIS)
- #7047 Add prevent sleep option support to Linux
===========

v1.14.0-stable
Expand Down
6 changes: 6 additions & 0 deletions src/lib/arch/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,10 @@ add_library(arch STATIC ${sources})

if (UNIX)
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()
76 changes: 76 additions & 0 deletions src/lib/arch/unix/ArchSystemUnix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
#include <array>
#include <memory>
#include <string>
#ifndef __APPLE__
#include <QtDBus>
#endif

//
// ArchSystemUnix
Expand Down Expand Up @@ -100,3 +103,76 @@ ArchSystemUnix::runCommand(const std::string& cmd)
}
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
12 changes: 10 additions & 2 deletions src/lib/arch/unix/ArchSystemUnix.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2004 Chris Schoeneman
*
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Expand Down Expand Up @@ -36,4 +36,12 @@ class ArchSystemUnix : public IArchSystem {
virtual std::string getLibsUsed(void) const;

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
};
2 changes: 2 additions & 0 deletions src/lib/platform/MSWindowsScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ MSWindowsScreen::enable()

if (App::instance().argsBase().m_preventSleep) {
ArchMiscWindows::addBusyState(ArchMiscWindows::kSYSTEM);
ArchMiscWindows::addBusyState(ArchMiscWindows::kDISPLAY);
}
}

Expand All @@ -270,6 +271,7 @@ MSWindowsScreen::disable()
else {
// allow the system to enter power saving mode
ArchMiscWindows::removeBusyState(ArchMiscWindows::kSYSTEM);
ArchMiscWindows::removeBusyState(ArchMiscWindows::kDISPLAY);
}

// tell key state
Expand Down
6 changes: 4 additions & 2 deletions src/lib/platform/OSXScreen.mm
Original file line number Diff line number Diff line change
Expand Up @@ -756,8 +756,10 @@
{
if(App::instance().argsBase().m_preventSleep) {
CFStringRef reasonForActivity = CFSTR("Synergy application");
IOReturn result = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoIdleSleep,
kIOPMAssertionLevelOn, reasonForActivity, &m_sleepPreventionAssertionID);

IOReturn result = IOPMAssertionCreateWithName(kIOPMAssertPreventUserIdleDisplaySleep,
kIOPMAssertionLevelOn, reasonForActivity,
&m_sleepPreventionAssertionID);
if(result != kIOReturnSuccess) {
m_sleepPreventionAssertionID = 0;
LOG((CLOG_ERR "failed to disable system idle sleep"));
Expand Down
63 changes: 50 additions & 13 deletions src/lib/platform/XWindowsScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2002 Chris Schoeneman
*
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Expand All @@ -26,6 +26,8 @@
#include "synergy/Clipboard.h"
#include "synergy/KeyMap.h"
#include "synergy/XScreen.h"
#include "synergy/ArgsBase.h"
#include "synergy/App.h"
#include "arch/XArch.h"
#include "arch/Arch.h"
#include "base/Log.h"
Expand Down Expand Up @@ -129,11 +131,11 @@ XWindowsScreen::XWindowsScreen(

if (mouseScrollDelta==0) m_mouseScrollDelta=120;
s_screen = this;

if (!disableXInitThreads) {
// initializes Xlib support for concurrent threads.
if (XInitThreads() == 0)
throw XArch("XInitThreads() returned zero");
throw XArch("XInitThreads() returned zero");
} else {
LOG((CLOG_DEBUG "skipping XInitThreads()"));
}
Expand Down Expand Up @@ -245,6 +247,12 @@ XWindowsScreen::enable()
// warp the mouse to the cursor center
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
Expand All @@ -263,6 +271,12 @@ XWindowsScreen::disable()
if (!m_isPrimary && m_autoRepeat) {
//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
Expand All @@ -289,21 +303,21 @@ XWindowsScreen::enter()
CARD16 powerlevel;
BOOL enabled;
if (DPMSQueryExtension(m_display, &dummy, &dummy) &&
DPMSCapable(m_display) &&
DPMSInfo(m_display, &powerlevel, &enabled))
DPMSCapable(m_display) &&
DPMSInfo(m_display, &powerlevel, &enabled))
{
if (enabled && powerlevel != DPMSModeOn)
DPMSForceLevel(m_display, DPMSModeOn);
}
#endif

// unmap the hider/grab window. this also ungrabs the mouse and
// keyboard if they're grabbed.
XUnmapWindow(m_display, m_window);

/* maybe call this if entering for the screensaver
// set keyboard focus to root window. the screensaver should then
// pick up key events for when the user enters a password to unlock.
// pick up key events for when the user enters a password to unlock.
XSetInputFocus(m_display, PointerRoot, PointerRoot, CurrentTime);
*/

Expand Down Expand Up @@ -1332,7 +1346,7 @@ XWindowsScreen::handleSystemEvent(const Event& event, void*)
XFreeEventData(m_display, cookie);
return;
}
XFreeEventData(m_display, cookie);
XFreeEventData(m_display, cookie);
}
}
#endif
Expand Down Expand Up @@ -1539,9 +1553,9 @@ XWindowsScreen::onKeyPress(XKeyEvent& xkey)
false, false, key, mask, 1, keycode);
}
}
else {
else {
LOG((CLOG_DEBUG1 "can't map keycode to key id"));
}
}
}

void
Expand Down Expand Up @@ -1864,7 +1878,7 @@ XWindowsScreen::doSelectEvents(Window w) const
// select events of interest. do this before querying the tree so
// we'll get notifications of children created after the XQueryTree()
// so we won't miss them.
XSelectInput(m_display, w, mask);
XSelectInput(m_display, w, mask);

// recurse on child windows
Window rw, pw, *cw;
Expand Down Expand Up @@ -2156,7 +2170,7 @@ XWindowsScreen::selectXIRawMotion()
mask.mask = (unsigned char*)calloc(mask.mask_len, sizeof(char));
mask.deviceid = XIAllMasterDevices;
memset(mask.mask, 0, 2);
XISetMask(mask.mask, XI_RawKeyRelease);
XISetMask(mask.mask, XI_RawKeyRelease);
XISetMask(mask.mask, XI_RawMotion);
XISelectEvents(m_display, DefaultRootWindow(m_display), &mask, 1);
free(mask.mask);
Expand Down Expand Up @@ -2186,3 +2200,26 @@ XWindowsScreen::updateScrollDirection()
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);
}
6 changes: 6 additions & 0 deletions src/lib/platform/XWindowsScreen.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#pragma once

#include "arch/Arch.h"
#include "synergy/PlatformScreen.h"
#include "synergy/KeyMap.h"
#include "common/stdset.h"
Expand Down Expand Up @@ -117,6 +118,11 @@ class XWindowsScreen : public PlatformScreen {
void onError();
static int ioErrorHandler(Display*);

// sleep management
static bool sleepInhibitCall(bool state, ArchSystemUnix::InhibitScreenServices serviceID);
static bool disableIdleSleep();
static bool enableIdleSleep();

private:
class KeyEventFilter {
public:
Expand Down

0 comments on commit 6b17613

Please sign in to comment.