Multi-monitor working for up/down directions to/from macOS.
Very rough implementation. #1112
This commit is contained in:
parent
653e4badeb
commit
810bf79456
|
@ -0,0 +1,12 @@
|
||||||
|
#include <Carbon/Carbon.h>
|
||||||
|
/**
|
||||||
|
* Platform-independent display.
|
||||||
|
*/
|
||||||
|
class Display {
|
||||||
|
public:
|
||||||
|
UInt32 displayId;
|
||||||
|
SInt32 x;
|
||||||
|
SInt32 y;
|
||||||
|
SInt32 width;
|
||||||
|
SInt32 height;
|
||||||
|
};
|
|
@ -22,6 +22,7 @@
|
||||||
#include "base/Event.h"
|
#include "base/Event.h"
|
||||||
#include "base/EventTypes.h"
|
#include "base/EventTypes.h"
|
||||||
#include "common/IInterface.h"
|
#include "common/IInterface.h"
|
||||||
|
#include "Display.h"
|
||||||
|
|
||||||
class IClipboard;
|
class IClipboard;
|
||||||
|
|
||||||
|
@ -67,5 +68,7 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual void getCursorPos(SInt32& x, SInt32& y) const = 0;
|
virtual void getCursorPos(SInt32& x, SInt32& y) const = 0;
|
||||||
|
|
||||||
|
virtual std::vector<Display*> getDisplays() const = 0;
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
};
|
};
|
||||||
|
|
|
@ -562,4 +562,9 @@ Screen::leaveSecondary()
|
||||||
m_screen->fakeAllKeysUp();
|
m_screen->fakeAllKeysUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<Display*>
|
||||||
|
Screen::getDisplays() const {
|
||||||
|
return m_screen->getDisplays();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -301,6 +301,7 @@ public:
|
||||||
virtual void getShape(SInt32& x, SInt32& y,
|
virtual void getShape(SInt32& x, SInt32& y,
|
||||||
SInt32& width, SInt32& height) const;
|
SInt32& width, SInt32& height) const;
|
||||||
virtual void getCursorPos(SInt32& x, SInt32& y) const;
|
virtual void getCursorPos(SInt32& x, SInt32& y) const;
|
||||||
|
virtual std::vector<Display*> getDisplays() const;
|
||||||
|
|
||||||
IPlatformScreen* getPlatformScreen() { return m_screen; }
|
IPlatformScreen* getPlatformScreen() { return m_screen; }
|
||||||
|
|
||||||
|
|
|
@ -234,6 +234,12 @@ Client::getShape(SInt32& x, SInt32& y, SInt32& w, SInt32& h) const
|
||||||
m_screen->getShape(x, y, w, h);
|
m_screen->getShape(x, y, w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<Display*>
|
||||||
|
Client::getDisplays() const
|
||||||
|
{
|
||||||
|
// TODO(vjpr):
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Client::getCursorPos(SInt32& x, SInt32& y) const
|
Client::getCursorPos(SInt32& x, SInt32& y) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -139,6 +139,7 @@ public:
|
||||||
virtual void getShape(SInt32& x, SInt32& y,
|
virtual void getShape(SInt32& x, SInt32& y,
|
||||||
SInt32& width, SInt32& height) const;
|
SInt32& width, SInt32& height) const;
|
||||||
virtual void getCursorPos(SInt32& x, SInt32& y) const;
|
virtual void getCursorPos(SInt32& x, SInt32& y) const;
|
||||||
|
virtual std::vector<Display*> getDisplays() const;
|
||||||
|
|
||||||
// IClient overrides
|
// IClient overrides
|
||||||
virtual void enter(SInt32 xAbs, SInt32 yAbs,
|
virtual void enter(SInt32 xAbs, SInt32 yAbs,
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "base/EventTypes.h"
|
#include "base/EventTypes.h"
|
||||||
#include "common/stdmap.h"
|
#include "common/stdmap.h"
|
||||||
#include "common/stdvector.h"
|
#include "common/stdvector.h"
|
||||||
|
#import "barrier/Display.h"
|
||||||
|
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
#include <Carbon/Carbon.h>
|
#include <Carbon/Carbon.h>
|
||||||
|
@ -53,6 +54,9 @@ class Mutex;
|
||||||
//! Implementation of IPlatformScreen for OS X
|
//! Implementation of IPlatformScreen for OS X
|
||||||
class OSXScreen : public PlatformScreen {
|
class OSXScreen : public PlatformScreen {
|
||||||
public:
|
public:
|
||||||
|
// TODO(vjpr): make private.
|
||||||
|
std::vector<Display*> m_displays;
|
||||||
|
|
||||||
OSXScreen(IEventQueue* events, bool isPrimary, bool autoShowHideCursor=true);
|
OSXScreen(IEventQueue* events, bool isPrimary, bool autoShowHideCursor=true);
|
||||||
virtual ~OSXScreen();
|
virtual ~OSXScreen();
|
||||||
|
|
||||||
|
@ -64,6 +68,7 @@ public:
|
||||||
virtual void getShape(SInt32& x, SInt32& y,
|
virtual void getShape(SInt32& x, SInt32& y,
|
||||||
SInt32& width, SInt32& height) const;
|
SInt32& width, SInt32& height) const;
|
||||||
virtual void getCursorPos(SInt32& x, SInt32& y) const;
|
virtual void getCursorPos(SInt32& x, SInt32& y) const;
|
||||||
|
virtual std::vector<Display*> getDisplays() const;
|
||||||
|
|
||||||
// IPrimaryScreen overrides
|
// IPrimaryScreen overrides
|
||||||
virtual void reconfigure(UInt32 activeSides);
|
virtual void reconfigure(UInt32 activeSides);
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "base/Log.h"
|
#include "base/Log.h"
|
||||||
#include "base/IEventQueue.h"
|
#include "base/IEventQueue.h"
|
||||||
#include "base/TMethodEventJob.h"
|
#include "base/TMethodEventJob.h"
|
||||||
|
#import "barrier/Display.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <mach-o/dyld.h>
|
#include <mach-o/dyld.h>
|
||||||
|
@ -244,6 +245,11 @@ OSXScreen::getShape(SInt32& x, SInt32& y, SInt32& w, SInt32& h) const
|
||||||
h = m_h;
|
h = m_h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<Display*>
|
||||||
|
OSXScreen::getDisplays() const {
|
||||||
|
return m_displays;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
OSXScreen::getCursorPos(SInt32& x, SInt32& y) const
|
OSXScreen::getCursorPos(SInt32& x, SInt32& y) const
|
||||||
{
|
{
|
||||||
|
@ -270,6 +276,7 @@ OSXScreen::warpCursor(SInt32 x, SInt32 y)
|
||||||
CGPoint pos;
|
CGPoint pos;
|
||||||
pos.x = x;
|
pos.x = x;
|
||||||
pos.y = y;
|
pos.y = y;
|
||||||
|
// NOTE: If y is invalid, it sets it to 0.
|
||||||
CGWarpMouseCursorPosition(pos);
|
CGWarpMouseCursorPosition(pos);
|
||||||
|
|
||||||
// save new cursor position
|
// save new cursor position
|
||||||
|
@ -1546,6 +1553,21 @@ OSXScreen::updateScreenShape()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// save displays as generic displays.
|
||||||
|
for (CGDisplayCount i = 0; i < displayCount; ++i) {
|
||||||
|
CGRect bounds = CGDisplayBounds(displays[i]);
|
||||||
|
Display* display = new Display{
|
||||||
|
// TODO(vjpr): Display numbers are simply the enumeration order. This is not stable between reboots I don't think.
|
||||||
|
i,
|
||||||
|
// --
|
||||||
|
(SInt32)bounds.origin.x,
|
||||||
|
(SInt32)bounds.origin.y,
|
||||||
|
(SInt32)bounds.size.width,
|
||||||
|
(SInt32)bounds.size.height};
|
||||||
|
m_displays.push_back(display);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// get smallest rect enclosing all display rects
|
// get smallest rect enclosing all display rects
|
||||||
CGRect totalBounds = CGRectZero;
|
CGRect totalBounds = CGRectZero;
|
||||||
for (CGDisplayCount i = 0; i < displayCount; ++i) {
|
for (CGDisplayCount i = 0; i < displayCount; ++i) {
|
||||||
|
@ -1566,6 +1588,7 @@ OSXScreen::updateScreenShape()
|
||||||
m_yCenter = (rect.origin.y + rect.size.height) / 2;
|
m_yCenter = (rect.origin.y + rect.size.height) / 2;
|
||||||
|
|
||||||
delete[] displays;
|
delete[] displays;
|
||||||
|
|
||||||
// We want to notify the peer screen whether we are primary screen or not
|
// We want to notify the peer screen whether we are primary screen or not
|
||||||
sendEvent(m_events->forIScreen().shapeChanged());
|
sendEvent(m_events->forIScreen().shapeChanged());
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,7 @@ public:
|
||||||
virtual bool getClipboard(ClipboardID id, IClipboard*) const = 0;
|
virtual bool getClipboard(ClipboardID id, IClipboard*) const = 0;
|
||||||
virtual void getShape(SInt32& x, SInt32& y,
|
virtual void getShape(SInt32& x, SInt32& y,
|
||||||
SInt32& width, SInt32& height) const = 0;
|
SInt32& width, SInt32& height) const = 0;
|
||||||
|
virtual std::vector<Display*> getDisplays() const = 0;
|
||||||
virtual void getCursorPos(SInt32& x, SInt32& y) const = 0;
|
virtual void getCursorPos(SInt32& x, SInt32& y) const = 0;
|
||||||
|
|
||||||
// IClient overrides
|
// IClient overrides
|
||||||
|
|
|
@ -500,3 +500,12 @@ ClientProxy1_0::ClientClipboard::ClientClipboard() :
|
||||||
{
|
{
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<Display*>
|
||||||
|
ClientProxy1_0::getDisplays() const {
|
||||||
|
|
||||||
|
// TODO(vjpr):
|
||||||
|
std::vector<Display*> vec;
|
||||||
|
return vec;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ public:
|
||||||
virtual void getShape(SInt32& x, SInt32& y,
|
virtual void getShape(SInt32& x, SInt32& y,
|
||||||
SInt32& width, SInt32& height) const;
|
SInt32& width, SInt32& height) const;
|
||||||
virtual void getCursorPos(SInt32& x, SInt32& y) const;
|
virtual void getCursorPos(SInt32& x, SInt32& y) const;
|
||||||
|
virtual std::vector<Display*> getDisplays() const;
|
||||||
|
|
||||||
// IClient overrides
|
// IClient overrides
|
||||||
virtual void enter(SInt32 xAbs, SInt32 yAbs,
|
virtual void enter(SInt32 xAbs, SInt32 yAbs,
|
||||||
|
|
|
@ -99,3 +99,11 @@ ClientProxy1_6::recvClipboard()
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<Display*> getDisplays() {
|
||||||
|
|
||||||
|
// TODO(vjpr):
|
||||||
|
std::vector<Display*> vec;
|
||||||
|
return vec;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ public:
|
||||||
|
|
||||||
virtual void setClipboard(ClipboardID id, const IClipboard* clipboard);
|
virtual void setClipboard(ClipboardID id, const IClipboard* clipboard);
|
||||||
virtual bool recvClipboard();
|
virtual bool recvClipboard();
|
||||||
|
//virtual std::vector<Display*> getDisplays();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void handleClipboardSendingEvent(const Event&, void*);
|
void handleClipboardSendingEvent(const Event&, void*);
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "barrier/Screen.h"
|
#include "barrier/Screen.h"
|
||||||
#include "barrier/Clipboard.h"
|
#include "barrier/Clipboard.h"
|
||||||
#include "base/Log.h"
|
#include "base/Log.h"
|
||||||
|
#include "platform/OSXScreen.h"
|
||||||
|
|
||||||
//
|
//
|
||||||
// PrimaryClient
|
// PrimaryClient
|
||||||
|
@ -272,3 +273,14 @@ PrimaryClient::setOptions(const OptionsList& options)
|
||||||
{
|
{
|
||||||
m_screen->setOptions(options);
|
m_screen->setOptions(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<Display*>
|
||||||
|
PrimaryClient::getDisplays() const {
|
||||||
|
|
||||||
|
// TODO(vjpr): Only works for osx!
|
||||||
|
IPlatformScreen* screen = m_screen->getPlatformScreen();
|
||||||
|
OSXScreen* platformScreen = dynamic_cast<OSXScreen*>(screen);
|
||||||
|
std::vector<Display*> displays = platformScreen->m_displays;
|
||||||
|
return displays;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -122,6 +122,7 @@ public:
|
||||||
virtual void getShape(SInt32& x, SInt32& y,
|
virtual void getShape(SInt32& x, SInt32& y,
|
||||||
SInt32& width, SInt32& height) const;
|
SInt32& width, SInt32& height) const;
|
||||||
virtual void getCursorPos(SInt32& x, SInt32& y) const;
|
virtual void getCursorPos(SInt32& x, SInt32& y) const;
|
||||||
|
virtual std::vector<Display*> getDisplays() const;
|
||||||
|
|
||||||
// IClient overrides
|
// IClient overrides
|
||||||
virtual void enter(SInt32 xAbs, SInt32 yAbs,
|
virtual void enter(SInt32 xAbs, SInt32 yAbs,
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include "base/IEventQueue.h"
|
#include "base/IEventQueue.h"
|
||||||
#include "base/Log.h"
|
#include "base/Log.h"
|
||||||
#include "base/TMethodEventJob.h"
|
#include "base/TMethodEventJob.h"
|
||||||
|
#include "platform/OSXScreen.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
@ -456,7 +457,8 @@ Server::switchScreen(BaseClientProxy* dst,
|
||||||
{
|
{
|
||||||
SInt32 dx, dy, dw, dh;
|
SInt32 dx, dy, dw, dh;
|
||||||
dst->getShape(dx, dy, dw, dh);
|
dst->getShape(dx, dy, dw, dh);
|
||||||
assert(x >= dx && y >= dy && x < dx + dw && y < dy + dh);
|
// TODO(vjpr): This doesn't make sense anymore when we use current display bounds.
|
||||||
|
//assert(x >= dx && y >= dy && x < dx + dw && y < dy + dh);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
assert(m_active != NULL);
|
assert(m_active != NULL);
|
||||||
|
@ -640,9 +642,38 @@ Server::getNeighbor(BaseClientProxy* src,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(vjpr): For now its just bottom-most.
|
||||||
|
// For a given direction, find the display furthest in that direction.
|
||||||
|
Display* findDisplay(BaseClientProxy* dst, SInt32& x, SInt32& y) {
|
||||||
|
|
||||||
|
Display* found = NULL;
|
||||||
|
|
||||||
|
std::vector<Display*> displays = dst->getDisplays();
|
||||||
|
|
||||||
|
LOG((CLOG_DEBUG1 "findDisplay - mouse pos %d,%d", x, y));
|
||||||
|
|
||||||
|
// Get display that mouse is on.
|
||||||
|
for (Display* display : displays) {
|
||||||
|
//LOG((CLOG_DEBUG1 "check x %d <= %d <= %d true=%d", display->x, x, display->x + display->width, display->x <= x <= (display->x + display->width)));
|
||||||
|
if (display->x <= x && x <= (display->x + display->width)) {
|
||||||
|
//LOG((CLOG_DEBUG1 "check y %d <= %d <= %d", display->y, y, display->y + display->width));
|
||||||
|
if (found) {
|
||||||
|
if (display->y < found->y) {
|
||||||
|
found = display;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
found = display;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
BaseClientProxy*
|
BaseClientProxy*
|
||||||
Server::mapToNeighbor(BaseClientProxy* src,
|
Server::mapToNeighbor(BaseClientProxy* src,
|
||||||
EDirection srcSide, SInt32& x, SInt32& y) const
|
EDirection srcSide, SInt32& x, SInt32& y, Display* currentDisplay) const
|
||||||
{
|
{
|
||||||
// note -- must be locked on entry
|
// note -- must be locked on entry
|
||||||
|
|
||||||
|
@ -698,8 +729,18 @@ Server::mapToNeighbor(BaseClientProxy* src,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kTop:
|
case kTop:
|
||||||
y -= dy;
|
// vjpr
|
||||||
while (dst != NULL) {
|
// Initially:
|
||||||
|
// y = mouse cursor position relative to primary display top-left corner.
|
||||||
|
// dy = highest display's top-left corner relative to primary display top-left corner. That is, (0,0) in the "canonical screen space".
|
||||||
|
//y -= dy;
|
||||||
|
// vjpr: We need to get y relative to our screen instead.
|
||||||
|
if (currentDisplay) {
|
||||||
|
y = y - currentDisplay->y;
|
||||||
|
} else {
|
||||||
|
y -= dy;
|
||||||
|
}
|
||||||
|
while (dst != NULL) {
|
||||||
lastGoodScreen = dst;
|
lastGoodScreen = dst;
|
||||||
lastGoodScreen->getShape(dx, dy, dw, dh);
|
lastGoodScreen->getShape(dx, dy, dw, dh);
|
||||||
y += dh;
|
y += dh;
|
||||||
|
@ -713,21 +754,36 @@ Server::mapToNeighbor(BaseClientProxy* src,
|
||||||
y += dy;
|
y += dy;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kBottom:
|
case kBottom: {
|
||||||
y -= dy;
|
y -= dy;
|
||||||
while (dst != NULL) {
|
while (dst != NULL) {
|
||||||
y -= dh;
|
// vjpr
|
||||||
lastGoodScreen = dst;
|
// y = pixels we need to position cursor in dest screen.
|
||||||
lastGoodScreen->getShape(dx, dy, dw, dh);
|
y -= dh;
|
||||||
if (y < dh) {
|
lastGoodScreen = dst;
|
||||||
break;
|
lastGoodScreen->getShape(dx, dy, dw, dh);
|
||||||
}
|
if (y < dh) {
|
||||||
LOG((CLOG_DEBUG2 "skipping over screen %s", getName(dst).c_str()));
|
break;
|
||||||
dst = getNeighbor(lastGoodScreen, srcSide, x, y);
|
}
|
||||||
}
|
LOG((CLOG_DEBUG2 "skipping over screen %s", getName(dst).c_str()));
|
||||||
assert(lastGoodScreen != NULL);
|
dst = getNeighbor(lastGoodScreen, srcSide, x, y);
|
||||||
y += dy;
|
}
|
||||||
break;
|
assert(lastGoodScreen != NULL);
|
||||||
|
// vjpr: `dy` is the top-left of all merged display bounds.
|
||||||
|
// Instead, we want to look at `x`, find the top-most dest display, then offset `y` from this display's origin.
|
||||||
|
|
||||||
|
// y += dy;
|
||||||
|
|
||||||
|
// TODO(vjpr): Have to add ability to read displays from dest.
|
||||||
|
auto display = findDisplay(dst, x, y);
|
||||||
|
if (!display) {
|
||||||
|
// TODO(vjpr): Shouldn't happen.
|
||||||
|
y += dy;
|
||||||
|
}
|
||||||
|
y = y + display->y;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case kNoDirection:
|
case kNoDirection:
|
||||||
assert(0 && "bad direction");
|
assert(0 && "bad direction");
|
||||||
|
@ -1733,6 +1789,9 @@ Server::onMouseUp(ButtonID id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#import <CoreGraphics/CGGeometry.h>
|
||||||
|
#import <CoreGraphics/CGDirectDisplay.h>
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Server::onMouseMovePrimary(SInt32 x, SInt32 y)
|
Server::onMouseMovePrimary(SInt32 x, SInt32 y)
|
||||||
{
|
{
|
||||||
|
@ -1776,6 +1835,43 @@ Server::onMouseMovePrimary(SInt32 x, SInt32 y)
|
||||||
yc = ay + ah - 1;
|
yc = ay + ah - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --------------------
|
||||||
|
// TODO(vjpr):
|
||||||
|
|
||||||
|
// TODO(vjpr): This CG function call is too slow! Adds lag.
|
||||||
|
//uint32_t displayCount = 0;
|
||||||
|
//uint32_t displayID;
|
||||||
|
//CGGetDisplaysWithPoint(CGPointMake(x, y), 1, &displayID, &displayCount);
|
||||||
|
//LOG((CLOG_DEBUG4 "onMouseMovePrimary displayID %d", displayID));
|
||||||
|
// ---
|
||||||
|
|
||||||
|
Display* currentDisplay = NULL;
|
||||||
|
|
||||||
|
// TODO(vjpr): Assumes OSX is always primary screen. Maybe this will break things.
|
||||||
|
OSXScreen* screen = dynamic_cast<OSXScreen*>(m_screen->getPlatformScreen());
|
||||||
|
std::vector<Display*> displays = screen->m_displays;
|
||||||
|
|
||||||
|
//LOG((CLOG_DEBUG1 "mouse pos %d,%d", x, y));
|
||||||
|
|
||||||
|
// Get display that mouse is on.
|
||||||
|
for (Display* display : displays) {
|
||||||
|
//LOG((CLOG_DEBUG1 "check x %d <= %d <= %d true=%d", display->x, x, display->x + display->width, display->x <= x <= (display->x + display->width)));
|
||||||
|
if (display->x <= x && x <= (display->x + display->width)) {
|
||||||
|
//LOG((CLOG_DEBUG1 "check y %d <= %d <= %d", display->y, y, display->y + display->width));
|
||||||
|
if (display->y <= y && y <= (display->y + display->height)) {
|
||||||
|
//LOG((CLOG_DEBUG1 "match x=%d y=%d w=%d h=%d", display->x, display->y, display->width, display->height));
|
||||||
|
currentDisplay = display;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//LOG((CLOG_DEBUG1 "currentDisplay x=%d,y=%d,w=%d,h=%d", currentDisplay->x, currentDisplay->y, currentDisplay->width, currentDisplay->height));
|
||||||
|
|
||||||
|
ax = currentDisplay->x;
|
||||||
|
ay = currentDisplay->y;
|
||||||
|
|
||||||
|
// --------------------
|
||||||
|
|
||||||
// see if we should change screens
|
// see if we should change screens
|
||||||
// when the cursor is in a corner, there may be a screen either
|
// when the cursor is in a corner, there may be a screen either
|
||||||
// horizontally or vertically. check both directions.
|
// horizontally or vertically. check both directions.
|
||||||
|
@ -1783,19 +1879,36 @@ Server::onMouseMovePrimary(SInt32 x, SInt32 y)
|
||||||
SInt32 xh = x, yv = y;
|
SInt32 xh = x, yv = y;
|
||||||
if (x < ax + zoneSize) {
|
if (x < ax + zoneSize) {
|
||||||
xh -= zoneSize;
|
xh -= zoneSize;
|
||||||
dirh = kLeft;
|
//dirh = kLeft;
|
||||||
}
|
}
|
||||||
else if (x >= ax + aw - zoneSize) {
|
else if (x >= ax + aw - zoneSize) {
|
||||||
xh += zoneSize;
|
xh += zoneSize;
|
||||||
dirh = kRight;
|
//dirh = kRight;
|
||||||
}
|
}
|
||||||
if (y < ay + zoneSize) {
|
if (y < ay + zoneSize) {
|
||||||
yv -= zoneSize;
|
yv -= zoneSize;
|
||||||
dirv = kTop;
|
|
||||||
|
// Is another display above?
|
||||||
|
for (Display* display : displays) {
|
||||||
|
if (display->displayId == currentDisplay->displayId) continue; // Skip current monitor.
|
||||||
|
SInt32 x0 = display->x;
|
||||||
|
SInt32 y0 = display->y + display->height;
|
||||||
|
SInt32 x1 = display->x + display->width;
|
||||||
|
SInt32 y1 = display->y;
|
||||||
|
if (y0 - 1 == display->y) {
|
||||||
|
// This display is directly above. Don't switch screen.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (x0 < x && x > x1) {
|
||||||
|
// The cursor is within the x bounds.
|
||||||
|
dirv = kTop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (y >= ay + ah - zoneSize) {
|
else if (y >= ay + ah - zoneSize) {
|
||||||
yv += zoneSize;
|
yv += zoneSize;
|
||||||
dirv = kBottom;
|
//dirv = kBottom;
|
||||||
}
|
}
|
||||||
if (dirh == kNoDirection && dirv == kNoDirection) {
|
if (dirh == kNoDirection && dirv == kNoDirection) {
|
||||||
// still on local screen
|
// still on local screen
|
||||||
|
@ -1814,7 +1927,7 @@ Server::onMouseMovePrimary(SInt32 x, SInt32 y)
|
||||||
x = xs[i], y = ys[i];
|
x = xs[i], y = ys[i];
|
||||||
|
|
||||||
// get jump destination
|
// get jump destination
|
||||||
BaseClientProxy* newScreen = mapToNeighbor(m_active, dir, x, y);
|
BaseClientProxy* newScreen = mapToNeighbor(m_active, dir, x, y, currentDisplay);
|
||||||
|
|
||||||
// should we switch or not?
|
// should we switch or not?
|
||||||
if (isSwitchOkay(newScreen, dir, x, y, xc, yc)) {
|
if (isSwitchOkay(newScreen, dir, x, y, xc, yc)) {
|
||||||
|
@ -2005,7 +2118,7 @@ Server::onMouseMoveSecondary(SInt32 dx, SInt32 dy)
|
||||||
}
|
}
|
||||||
|
|
||||||
// try to switch screen. get the neighbor.
|
// try to switch screen. get the neighbor.
|
||||||
newScreen = mapToNeighbor(m_active, dir, m_x, m_y);
|
newScreen = mapToNeighbor(m_active, dir, m_x, m_y, NULL);
|
||||||
|
|
||||||
// see if we should switch
|
// see if we should switch
|
||||||
if (!isSwitchOkay(newScreen, dir, m_x, m_y, xc, yc)) {
|
if (!isSwitchOkay(newScreen, dir, m_x, m_y, xc, yc)) {
|
||||||
|
|
|
@ -232,7 +232,7 @@ private:
|
||||||
// cross multiple screens. if there is no suitable screen then
|
// cross multiple screens. if there is no suitable screen then
|
||||||
// return NULL and x,y are not modified.
|
// return NULL and x,y are not modified.
|
||||||
BaseClientProxy* mapToNeighbor(BaseClientProxy*, EDirection,
|
BaseClientProxy* mapToNeighbor(BaseClientProxy*, EDirection,
|
||||||
SInt32& x, SInt32& y) const;
|
SInt32& x, SInt32& y, Display*) const;
|
||||||
|
|
||||||
// adjusts x and y or neither to avoid ending up in a jump zone
|
// adjusts x and y or neither to avoid ending up in a jump zone
|
||||||
// after entering the client in the given direction.
|
// after entering the client in the given direction.
|
||||||
|
|
Loading…
Reference in New Issue