mirror of
https://github.com/debauchee/barrier.git
synced 2026-05-08 14:41:57 +08:00
Added support on X11 for a global option to delay switching screens
when the mouse reaches a jump zone.
This commit is contained in:
@@ -59,7 +59,9 @@ CServer::CServer(const CString& serverName) :
|
||||
m_seqNum(0),
|
||||
m_activeSaver(NULL),
|
||||
m_httpServer(NULL),
|
||||
m_httpAvailable(&m_mutex, s_httpMaxSimultaneousRequests)
|
||||
m_httpAvailable(&m_mutex, s_httpMaxSimultaneousRequests),
|
||||
m_switchWaitDelay(0.0),
|
||||
m_switchWaitScreen(NULL)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
@@ -220,13 +222,18 @@ CServer::setConfig(const CConfig& config)
|
||||
// process global options
|
||||
const CConfig::CScreenOptions* options = m_config.getOptions("");
|
||||
if (options != NULL && options->size() > 0) {
|
||||
/*
|
||||
for (CConfig::CScreenOptions::const_iterator index = options->begin();
|
||||
index != options->end(); ++index) {
|
||||
const OptionID id = index->first;
|
||||
const OptionValue value = index->second;
|
||||
if (id == kOptionScreenSwitchDelay) {
|
||||
m_switchWaitDelay = 1.0e-3 * static_cast<double>(value);
|
||||
if (m_switchWaitDelay < 0.0) {
|
||||
m_switchWaitDelay = 0.0;
|
||||
}
|
||||
clearSwitchWait();
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// tell primary screen about reconfiguration
|
||||
@@ -496,6 +503,36 @@ CServer::onScreensaver(bool activated)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CServer::onOneShotTimerExpired(UInt32 id)
|
||||
{
|
||||
CLock lock(&m_mutex);
|
||||
|
||||
// ignore old timer or if there's no jump screen anymore
|
||||
if (m_switchWaitScreen == NULL || id != m_switchWaitTimer) {
|
||||
clearSwitchWait();
|
||||
return;
|
||||
}
|
||||
|
||||
// ignore if mouse is locked to screen
|
||||
if (isLockedToScreenNoLock()) {
|
||||
clearSwitchWait();
|
||||
return;
|
||||
}
|
||||
|
||||
// switch screen
|
||||
switchScreen(m_switchWaitScreen, m_switchWaitX, m_switchWaitY, false);
|
||||
}
|
||||
|
||||
void
|
||||
CServer::clearSwitchWait()
|
||||
{
|
||||
if (m_switchWaitScreen != NULL) {
|
||||
LOG((CLOG_DEBUG1 "cancel switch wait"));
|
||||
m_switchWaitScreen = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CServer::onKeyDown(KeyID id, KeyModifierMask mask)
|
||||
{
|
||||
@@ -582,11 +619,6 @@ CServer::onMouseMovePrimaryNoLock(SInt32 x, SInt32 y)
|
||||
assert(m_primaryClient != NULL);
|
||||
assert(m_active == m_primaryClient);
|
||||
|
||||
// ignore if mouse is locked to screen
|
||||
if (isLockedToScreenNoLock()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// get screen shape
|
||||
SInt32 ax, ay, aw, ah;
|
||||
m_active->getShape(ax, ay, aw, ah);
|
||||
@@ -616,6 +648,7 @@ CServer::onMouseMovePrimaryNoLock(SInt32 x, SInt32 y)
|
||||
}
|
||||
else {
|
||||
// still on local screen
|
||||
clearSwitchWait();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -623,6 +656,27 @@ CServer::onMouseMovePrimaryNoLock(SInt32 x, SInt32 y)
|
||||
// then ignore the move.
|
||||
IClient* newScreen = getNeighbor(m_active, dir, x, y);
|
||||
if (newScreen == NULL) {
|
||||
clearSwitchWait();
|
||||
return false;
|
||||
}
|
||||
|
||||
// if waiting before a switch then prepare to switch later
|
||||
if (m_switchWaitDelay > 0.0) {
|
||||
if (m_switchWaitScreen == NULL || dir != m_switchWaitDir) {
|
||||
m_switchWaitDir = dir;
|
||||
m_switchWaitScreen = newScreen;
|
||||
m_switchWaitX = x;
|
||||
m_switchWaitY = y;
|
||||
m_switchWaitTimer = m_primaryClient->addOneShotTimer(
|
||||
m_switchWaitDelay);
|
||||
LOG((CLOG_DEBUG1 "waiting to switch"));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// ignore if mouse is locked to screen
|
||||
if (isLockedToScreenNoLock()) {
|
||||
LOG((CLOG_DEBUG1 "locked to screen"));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -667,72 +721,110 @@ CServer::onMouseMoveSecondaryNoLock(SInt32 dx, SInt32 dy)
|
||||
SInt32 ax, ay, aw, ah;
|
||||
m_active->getShape(ax, ay, aw, ah);
|
||||
|
||||
// find direction of neighbor
|
||||
EDirection dir;
|
||||
IClient* newScreen = NULL;
|
||||
if (m_x < ax) {
|
||||
dir = kLeft;
|
||||
}
|
||||
else if (m_x > ax + aw - 1) {
|
||||
dir = kRight;
|
||||
}
|
||||
else if (m_y < ay) {
|
||||
dir = kTop;
|
||||
}
|
||||
else if (m_y > ay + ah - 1) {
|
||||
dir = kBottom;
|
||||
}
|
||||
else {
|
||||
newScreen = m_active;
|
||||
|
||||
// keep compiler quiet about unset variable
|
||||
dir = kLeft;
|
||||
}
|
||||
|
||||
// switch screens if the mouse is outside the screen and not
|
||||
// locked to the screen
|
||||
IClient* newScreen = NULL;
|
||||
if (!isLockedToScreenNoLock()) {
|
||||
// find direction of neighbor
|
||||
EDirection dir;
|
||||
if (m_x < ax) {
|
||||
dir = kLeft;
|
||||
}
|
||||
else if (m_x > ax + aw - 1) {
|
||||
dir = kRight;
|
||||
}
|
||||
else if (m_y < ay) {
|
||||
dir = kTop;
|
||||
}
|
||||
else if (m_y > ay + ah - 1) {
|
||||
dir = kBottom;
|
||||
}
|
||||
else {
|
||||
newScreen = m_active;
|
||||
|
||||
// keep compiler quiet about unset variable
|
||||
dir = kLeft;
|
||||
}
|
||||
|
||||
// get neighbor if we should switch
|
||||
bool clamp = false;
|
||||
if (newScreen == NULL) {
|
||||
// get neighbor we should switch to
|
||||
newScreen = getNeighbor(m_active, dir, m_x, m_y);
|
||||
LOG((CLOG_DEBUG1 "leave \"%s\" on %s", m_active->getName().c_str(), CConfig::dirName(dir)));
|
||||
if (newScreen == NULL) {
|
||||
LOG((CLOG_DEBUG1 "leave \"%s\" on %s", m_active->getName().c_str(), CConfig::dirName(dir)));
|
||||
|
||||
// get new position or clamp to current screen
|
||||
newScreen = getNeighbor(m_active, dir, m_x, m_y);
|
||||
if (newScreen == NULL) {
|
||||
LOG((CLOG_DEBUG1 "no neighbor; clamping"));
|
||||
if (m_x < ax) {
|
||||
m_x = ax;
|
||||
}
|
||||
else if (m_x > ax + aw - 1) {
|
||||
m_x = ax + aw - 1;
|
||||
}
|
||||
if (m_y < ay) {
|
||||
m_y = ay;
|
||||
}
|
||||
else if (m_y > ay + ah - 1) {
|
||||
m_y = ay + ah - 1;
|
||||
}
|
||||
LOG((CLOG_DEBUG1 "no neighbor %s", CConfig::dirName(dir)));
|
||||
clamp = true;
|
||||
}
|
||||
else if (m_switchWaitDelay > 0.0) {
|
||||
// wait to switch; prepare to switch later
|
||||
if (m_switchWaitScreen == NULL || dir != m_switchWaitDir) {
|
||||
m_switchWaitDir = dir;
|
||||
m_switchWaitScreen = newScreen;
|
||||
m_switchWaitX = m_x;
|
||||
m_switchWaitY = m_y;
|
||||
m_switchWaitTimer = m_primaryClient->addOneShotTimer(
|
||||
m_switchWaitDelay);
|
||||
LOG((CLOG_DEBUG1 "waiting to switch"));
|
||||
}
|
||||
|
||||
// don't try to switch screen now
|
||||
m_x = xOld + dx;
|
||||
m_y = yOld + dy;
|
||||
clamp = true;
|
||||
}
|
||||
else if (isLockedToScreenNoLock()) {
|
||||
// clamp to edge when locked to screen
|
||||
LOG((CLOG_DEBUG1 "locked to screen"));
|
||||
clamp = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// clamp to edge when locked
|
||||
// on same screen. if waiting and mouse is not on the border
|
||||
// we're waiting on then stop waiting.
|
||||
if (m_switchWaitScreen != NULL) {
|
||||
bool clearWait;
|
||||
SInt32 zoneSize = m_primaryClient->getJumpZoneSize();
|
||||
switch (m_switchWaitDir) {
|
||||
case kLeft:
|
||||
clearWait = (m_x >= ax + zoneSize);
|
||||
break;
|
||||
|
||||
case kRight:
|
||||
clearWait = (m_x <= ax + aw - 1 - zoneSize);
|
||||
break;
|
||||
|
||||
case kTop:
|
||||
clearWait = (m_y >= ay + zoneSize);
|
||||
break;
|
||||
|
||||
case kBottom:
|
||||
clearWait = (m_y <= ay + ah - 1 + zoneSize);
|
||||
break;
|
||||
}
|
||||
if (clearWait) {
|
||||
clearSwitchWait();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// clamp mouse to edge
|
||||
if (clamp) {
|
||||
if (m_x < ax) {
|
||||
m_x = ax;
|
||||
LOG((CLOG_DEBUG1 "clamp to left of \"%s\"", m_active->getName().c_str()));
|
||||
LOG((CLOG_DEBUG2 "clamp to left of \"%s\"", m_active->getName().c_str()));
|
||||
}
|
||||
else if (m_x > ax + aw - 1) {
|
||||
m_x = ax + aw - 1;
|
||||
LOG((CLOG_DEBUG1 "clamp to right of \"%s\"", m_active->getName().c_str()));
|
||||
LOG((CLOG_DEBUG2 "clamp to right of \"%s\"", m_active->getName().c_str()));
|
||||
}
|
||||
if (m_y < ay) {
|
||||
m_y = ay;
|
||||
LOG((CLOG_DEBUG1 "clamp to top of \"%s\"", m_active->getName().c_str()));
|
||||
LOG((CLOG_DEBUG2 "clamp to top of \"%s\"", m_active->getName().c_str()));
|
||||
}
|
||||
else if (m_y > ay + ah - 1) {
|
||||
m_y = ay + ah - 1;
|
||||
LOG((CLOG_DEBUG1 "clamp to bottom of \"%s\"", m_active->getName().c_str()));
|
||||
LOG((CLOG_DEBUG2 "clamp to bottom of \"%s\"", m_active->getName().c_str()));
|
||||
}
|
||||
newScreen = NULL;
|
||||
}
|
||||
|
||||
// warp cursor if on same screen
|
||||
@@ -801,6 +893,9 @@ CServer::switchScreen(IClient* dst, SInt32 x, SInt32 y, bool forScreensaver)
|
||||
|
||||
LOG((CLOG_INFO "switch from \"%s\" to \"%s\" at %d,%d", m_active->getName().c_str(), dst->getName().c_str(), x, y));
|
||||
|
||||
// stop waiting to switch
|
||||
clearSwitchWait();
|
||||
|
||||
// record new position
|
||||
m_x = x;
|
||||
m_y = y;
|
||||
@@ -1099,6 +1194,11 @@ CServer::closeClients(const CConfig& config)
|
||||
// close that client
|
||||
assert(index2->second != m_primaryClient);
|
||||
index2->second->close();
|
||||
|
||||
// don't switch to it if we planned to
|
||||
if (index2->second == m_switchWaitScreen) {
|
||||
clearSwitchWait();
|
||||
}
|
||||
}
|
||||
else {
|
||||
++index;
|
||||
@@ -1789,6 +1889,9 @@ CServer::removeConnection(const CString& name)
|
||||
// record new position (center of primary screen)
|
||||
m_primaryClient->getCursorCenter(m_x, m_y);
|
||||
|
||||
// stop waiting to switch if we were
|
||||
clearSwitchWait();
|
||||
|
||||
// don't notify active screen since it probably already disconnected
|
||||
LOG((CLOG_INFO "jump from \"%s\" to \"%s\" at %d,%d", active->getName().c_str(), m_primaryClient->getName().c_str(), m_x, m_y));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user