Skip to content

Commit 9770182

Browse files
Allow XScreensaver syncing from client to server
Allows to deactivate the screensaver and postpone screensaver activation if local input is detected on a client. This fixes the screensavers getting out of sync if a client has a local input device such as a touchscreen
1 parent 7dd10ec commit 9770182

14 files changed

+184
-80
lines changed

src/lib/barrier/Screen.cpp

+3-5
Original file line numberDiff line numberDiff line change
@@ -178,11 +178,9 @@ Screen::grabClipboard(ClipboardID id)
178178
void
179179
Screen::screensaver(bool activate)
180180
{
181-
if (!m_isPrimary) {
182-
// activate/deactivation screen saver iff synchronization enabled
183-
if (m_screenSaverSync) {
184-
m_screen->screensaver(activate);
185-
}
181+
// activate/deactivation screen saver iff synchronization enabled
182+
if (m_screenSaverSync) {
183+
m_screen->screensaver(activate);
186184
}
187185
}
188186

src/lib/barrier/protocol_types.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
* barrier -- mouse and keyboard sharing utility
33
* Copyright (C) 2012-2016 Symless Ltd.
44
* Copyright (C) 2002 Chris Schoeneman
5-
*
5+
*
66
* This package is free software; you can redistribute it and/or
77
* modify it under the terms of the GNU General Public License
88
* found in the file LICENSE that should have accompanied this file.
9-
*
9+
*
1010
* This package is distributed in the hope that it will be useful,
1111
* but WITHOUT ANY WARRANTY; without even the implied warranty of
1212
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

src/lib/barrier/protocol_types.h

+13-3
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
// 1.5: adds file transfer and removes home brew crypto
3131
// 1.6: adds clipboard streaming
3232
// 1.7: adds focus/screen switch on local input
33+
// adds screensaver sync on client local input
3334
// NOTE: with new version, barrier minor version should increment
3435
static const SInt16 kProtocolMajorVersion = 1;
3536
static const SInt16 kProtocolMinorVersion = 7;
@@ -130,9 +131,16 @@ extern const char* kMsgCClose;
130131
// must return this number with some messages. $4 = modifier key
131132
// mask. this will have bits set for each toggle modifier key
132133
// that is activated on entry to the screen. the secondary screen
133-
// should adjust its toggle modifiers to reflect that state.
134+
// should adjust its toggle modifiers to reflect that state. $5 =
135+
// forScreensaver flag which denotes whether the screen is only
136+
// entered for screensaver management purposes or not and thus
137+
// whether the client can change its screensaver state or should
138+
// not change the screensaver state
134139
extern const char* kMsgCEnter;
135140

141+
// enter screen 1.0: same as above but without respecting the screensaver state
142+
extern const char* kMsgCEnter1_0;
143+
136144
// leave screen: primary -> secondary
137145
// leaving screen. the secondary screen should send clipboard
138146
// data in response to this message for those clipboards that
@@ -149,8 +157,10 @@ extern const char* kMsgCLeave;
149157
// most recent kMsgCEnter. the primary always sends 0.
150158
extern const char* kMsgCClipboard;
151159

152-
// screensaver change: primary -> secondary
153-
// screensaver on primary has started ($1 == 1) or closed ($1 == 0)
160+
// screensaver change: primary <-> secondary
161+
// screensaver has started ($1 == 1) or closed ($1 == 0).
162+
// sync screensavers by dispatching information to all clients via
163+
// the server
154164
extern const char* kMsgCScreenSaver;
155165

156166
// reset options: primary -> secondary

src/lib/client/Client.cpp

+32-4
Original file line numberDiff line numberDiff line change
@@ -237,10 +237,13 @@ Client::getCursorPos(SInt32& x, SInt32& y) const
237237
}
238238

239239
void
240-
Client::enter(SInt32 xAbs, SInt32 yAbs, UInt32, KeyModifierMask mask, bool)
240+
Client::enter(SInt32 xAbs, SInt32 yAbs, UInt32, KeyModifierMask mask, bool forScreensaver)
241241
{
242242
m_active = true;
243243
m_screen->mouseMove(xAbs, yAbs);
244+
if (!forScreensaver) {
245+
m_screen->screensaver(false);
246+
}
244247
m_screen->enter(mask);
245248

246249
if (m_sendFileThread != NULL) {
@@ -509,9 +512,17 @@ Client::setupScreen()
509512
new TMethodEventJob<Client>(this,
510513
&Client::handleClipboardGrabbed));
511514
m_events->adoptHandler(m_events->forIScreen().localInput(),
512-
getEventTarget(),
513-
new TMethodEventJob<Client>(this,
514-
&Client::handleLocalInputEvent));
515+
getEventTarget(),
516+
new TMethodEventJob<Client>(this,
517+
&Client::handleLocalInputEvent));
518+
m_events->adoptHandler(m_events->forIPrimaryScreen().screensaverActivated(),
519+
getEventTarget(),
520+
new TMethodEventJob<Client>(this,
521+
&Client::handleScreensaverActivatedEvent));
522+
m_events->adoptHandler(m_events->forIPrimaryScreen().screensaverDeactivated(),
523+
getEventTarget(),
524+
new TMethodEventJob<Client>(this,
525+
&Client::handleScreensaverDeactivatedEvent));
515526
}
516527

517528
void
@@ -570,6 +581,11 @@ Client::cleanupScreen()
570581
getEventTarget());
571582
m_events->removeHandler(m_events->forIScreen().localInput(),
572583
getEventTarget());
584+
m_events->removeHandler(m_events->forIPrimaryScreen().screensaverActivated(),
585+
getEventTarget());
586+
m_events->removeHandler(m_events->forIPrimaryScreen().screensaverDeactivated(),
587+
getEventTarget());
588+
573589
delete m_server;
574590
m_server = NULL;
575591
}
@@ -745,6 +761,18 @@ Client::handleResume(const Event&, void*)
745761
}
746762
}
747763

764+
void
765+
Client::handleScreensaverActivatedEvent(const Event&, void*) {
766+
LOG((CLOG_DEBUG "Client received screensaver activate"));
767+
m_server->sendScreensaver(true);
768+
}
769+
770+
void
771+
Client::handleScreensaverDeactivatedEvent(const Event&, void*) {
772+
LOG((CLOG_DEBUG "Client received screensaver deactivate"));
773+
m_server->sendScreensaver(false);
774+
}
775+
748776
void
749777
Client::handleFileChunkSending(const Event& event, void*)
750778
{

src/lib/client/Client.h

+2
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,8 @@ class Client : public IClient, public INode {
188188
void handleHello(const Event&, void*);
189189
void handleSuspend(const Event& event, void*);
190190
void handleResume(const Event& event, void*);
191+
void handleScreensaverActivatedEvent(const Event&, void*);
192+
void handleScreensaverDeactivatedEvent(const Event&, void*);
191193
void handleFileChunkSending(const Event&, void*);
192194
void handleFileRecieveCompleted(const Event&, void*);
193195
void handleStopRetry(const Event&, void*);

src/lib/client/ServerProxy.cpp

+12-5
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ ServerProxy::parseMessage(const UInt8* code)
275275
}
276276

277277
else if (memcmp(code, kMsgCScreenSaver, 4) == 0) {
278-
screensaver();
278+
rcvScreensaver();
279279
}
280280

281281
else if (memcmp(code, kMsgQInfo, 4) == 0) {
@@ -524,11 +524,12 @@ void
524524
ServerProxy::enter()
525525
{
526526
// parse
527+
SInt8 forScreensaver;
527528
SInt16 x, y;
528529
UInt16 mask;
529530
UInt32 seqNum;
530-
ProtocolUtil::readf(m_stream, kMsgCEnter + 4, &x, &y, &seqNum, &mask);
531-
LOG((CLOG_DEBUG1 "recv enter, %d,%d %d %04x", x, y, seqNum, mask));
531+
ProtocolUtil::readf(m_stream, kMsgCEnter + 4, &x, &y, &seqNum, &mask, &forScreensaver);
532+
LOG((CLOG_DEBUG1 "recv enter, %d,%d %d %04x, forScreensaver=%d", x, y, seqNum, mask, forScreensaver));
532533

533534
// discard old compressed mouse motion, if any
534535
m_compressMouse = false;
@@ -538,7 +539,7 @@ ServerProxy::enter()
538539
m_seqNum = seqNum;
539540

540541
// forward
541-
m_client->enter(x, y, seqNum, static_cast<KeyModifierMask>(mask), false);
542+
m_client->enter(x, y, seqNum, static_cast<KeyModifierMask>(mask), forScreensaver != 0);
542543
}
543544

544545
void
@@ -777,7 +778,7 @@ ServerProxy::mouseWheel()
777778
}
778779

779780
void
780-
ServerProxy::screensaver()
781+
ServerProxy::rcvScreensaver()
781782
{
782783
// parse
783784
SInt8 on;
@@ -788,6 +789,12 @@ ServerProxy::screensaver()
788789
m_client->screensaver(on != 0);
789790
}
790791

792+
void
793+
ServerProxy::sendScreensaver(bool activate) {
794+
// Notify server about screensaver state of client
795+
ProtocolUtil::writef(m_stream, kMsgCScreenSaver, activate ? 1 : 0);
796+
}
797+
791798
void
792799
ServerProxy::resetOptions()
793800
{

src/lib/client/ServerProxy.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ class ServerProxy {
6060
// sending dragging information to server
6161
void sendDragInfo(UInt32 fileCount, const char* info, size_t size);
6262

63+
// Send screensaver information to server
64+
void sendScreensaver(bool activate);
65+
6366
#ifdef TEST_ENV
6467
void handleDataForTest() { handleData(Event(), NULL); }
6568
#endif
@@ -99,7 +102,7 @@ class ServerProxy {
99102
void mouseMove();
100103
void mouseRelativeMove();
101104
void mouseWheel();
102-
void screensaver();
105+
void rcvScreensaver();
103106
void resetOptions();
104107
void setOptions();
105108
void queryInfo();

src/lib/platform/XWindowsScreen.cpp

+6-3
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,6 @@ XWindowsScreen::disable()
244244
void
245245
XWindowsScreen::enter()
246246
{
247-
screensaver(false);
248-
249247
// release input context focus
250248
if (m_ic != NULL) {
251249
m_impl->XUnsetICFocus(m_ic);
@@ -411,9 +409,11 @@ void
411409
XWindowsScreen::screensaver(bool activate)
412410
{
413411
if (activate) {
412+
m_screensaverNotificationTimer.reset();
414413
m_screensaver->activate();
415414
}
416415
else {
416+
m_screensaverNotificationTimer.reset();
417417
m_screensaver->deactivate();
418418
}
419419
}
@@ -2117,8 +2117,11 @@ XWindowsScreen::selectXIRawEventsSecondary()
21172117
mask.mask = (unsigned char*) calloc(mask.mask_len, sizeof(char));
21182118
LOGC((mask.mask == nullptr), (CLOG_ERR "Cannot listen on XI2 events due to memory error"));
21192119

2120-
// Detect mouse button press events on secondary screens (= clients)
2120+
// Detect mouse events (movement, button press) on secondary screens (= clients)
2121+
XISetMask(mask.mask, XI_RawMotion);
21212122
XISetMask(mask.mask, XI_RawButtonPress);
2123+
// Detect key press events on secondary screens (= clients)
2124+
XISetMask(mask.mask, XI_RawKeyPress);
21222125
// Detect touchscreen events on secondary screens (= clients)
21232126
XISetMask(mask.mask, XI_RawTouchBegin);
21242127
XISetMask(mask.mask, XI_RawTouchUpdate);

src/lib/platform/XWindowsScreen.h

+4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include "barrier/PlatformScreen.h"
2222
#include "barrier/KeyMap.h"
23+
#include "base/Stopwatch.h"
2324
#include "common/stdset.h"
2425
#include "common/stdvector.h"
2526
#include "XWindowsImpl.h"
@@ -231,6 +232,9 @@ class XWindowsScreen : public PlatformScreen {
231232
// screen saver stuff
232233
XWindowsScreenSaver* m_screensaver;
233234
bool m_screensaverNotify;
235+
// Timer for server notification to suppress screensaver if necessary
236+
Stopwatch m_screensaverNotificationTimer;
237+
const double NOTIFICATION_TIMEOUT = 10.0;
234238

235239
// logical to physical button mapping. m_buttons[i] gives the
236240
// physical button for logical button i+1.

src/lib/server/ClientProxy1_7.cpp

+24
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,15 @@ ClientProxy1_7::~ClientProxy1_7()
3939
{
4040
}
4141

42+
void
43+
ClientProxy1_7::enter(SInt32 xAbs, SInt32 yAbs,
44+
UInt32 seqNum, KeyModifierMask mask, bool forScreensaver)
45+
{
46+
LOG((CLOG_DEBUG1 "send enter to \"%s\", %d,%d %d %04x, forScreensaver=%d", getName().c_str(), xAbs, yAbs, seqNum, mask, forScreensaver ? 1 : 0));
47+
ProtocolUtil::writef(getStream(), kMsgCEnter,
48+
xAbs, yAbs, seqNum, mask, forScreensaver ? 1 : 0);
49+
}
50+
4251
bool
4352
ClientProxy1_7::parseMessage(const UInt8* code)
4453
{
@@ -51,9 +60,24 @@ ClientProxy1_7::parseMessage(const UInt8* code)
5160

5261
m_events->addEvent(Event(m_events->forIScreen().localInput(), getEventTarget(), info));
5362
}
63+
else if (memcmp(code, kMsgCScreenSaver, 4) == 0) {
64+
rcvScreensaver();
65+
}
5466
else {
5567
return ClientProxy1_6::parseMessage(code);
5668
}
5769

5870
return true;
5971
}
72+
73+
void
74+
ClientProxy1_7::rcvScreensaver()
75+
{
76+
SInt8 activate;
77+
ProtocolUtil::readf(getStream(), kMsgCScreenSaver + 4, &activate);
78+
if (activate != 0) {
79+
m_events->addEvent(Event(m_events->forIPrimaryScreen().screensaverActivated(), getEventTarget()));
80+
} else {
81+
m_events->addEvent(Event(m_events->forIPrimaryScreen().screensaverDeactivated(), getEventTarget()));
82+
}
83+
}

src/lib/server/ClientProxy1_7.h

+6-2
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,14 @@ class ClientProxy1_7 : public ClientProxy1_6 {
2828
ClientProxy1_7(const String& name, barrier::IStream* adoptedStream, Server* server, IEventQueue* events);
2929
~ClientProxy1_7();
3030

31+
virtual void enter(SInt32 xAbs, SInt32 yAbs,
32+
UInt32 seqNum, KeyModifierMask mask,
33+
bool forScreensaver);
34+
35+
protected:
3136
virtual bool parseMessage(const UInt8* code);
3237

33-
private:
34-
void handleClipboardSendingEvent(const Event&, void*);
38+
virtual void rcvScreensaver();
3539

3640
private:
3741
IEventQueue* m_events;

src/lib/server/PrimaryClient.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -139,10 +139,10 @@ PrimaryClient::disable()
139139

140140
void
141141
PrimaryClient::enter(SInt32 xAbs, SInt32 yAbs,
142-
UInt32 seqNum, KeyModifierMask mask, bool screensaver)
142+
UInt32 seqNum, KeyModifierMask mask, bool forScreensaver)
143143
{
144144
m_screen->setSequenceNumber(seqNum);
145-
if (!screensaver) {
145+
if (!forScreensaver) {
146146
m_screen->warpCursor(xAbs, yAbs);
147147
}
148148
m_screen->enter(mask);
@@ -244,9 +244,9 @@ PrimaryClient::mouseWheel(SInt32, SInt32)
244244
}
245245

246246
void
247-
PrimaryClient::screensaver(bool)
247+
PrimaryClient::screensaver(bool activate)
248248
{
249-
// ignore
249+
m_screen->screensaver(activate);
250250
}
251251

252252
void

0 commit comments

Comments
 (0)