Added workaround for apparent Xinerama bug when warping the pointer.
This should allow synergy to be used on a system using Xinerama to create a single logical screen from multiple physical screens.
This commit is contained in:
parent
019994548c
commit
6a108ed2d5
|
@ -57,6 +57,8 @@ AC_PATH_XTRA
|
||||||
save_CPPFLAGS="$CPPFLAGS"
|
save_CPPFLAGS="$CPPFLAGS"
|
||||||
CPPFLAGS="$X_CFLAGS $CPPFLAGS"
|
CPPFLAGS="$X_CFLAGS $CPPFLAGS"
|
||||||
AC_CHECK_HEADERS([X11/extensions/XTest.h])
|
AC_CHECK_HEADERS([X11/extensions/XTest.h])
|
||||||
|
|
||||||
|
AC_CHECK_LIB(Xinerama, XineramaQueryExtension, AC_CHECK_HEADERS([X11/extensions/Xinerama.h]) [X_LIBS="$X_LIBS -lXinerama"], , [$X_LIBS -lXext -lX11 $X_EXTRA_LIBS])
|
||||||
CPPFLAGS="$save_CPPFLAGS"
|
CPPFLAGS="$save_CPPFLAGS"
|
||||||
|
|
||||||
dnl checks for types
|
dnl checks for types
|
||||||
|
|
|
@ -30,6 +30,12 @@
|
||||||
#else
|
#else
|
||||||
# include <X11/X.h>
|
# include <X11/X.h>
|
||||||
# include <X11/Xutil.h>
|
# include <X11/Xutil.h>
|
||||||
|
# if HAVE_X11_EXTENSIONS_XINERAMA_H
|
||||||
|
// Xinerama.h may lack extern "C" for inclusion by C++
|
||||||
|
extern "C" {
|
||||||
|
# include <X11/extensions/Xinerama.h>
|
||||||
|
}
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#if UNIX_LIKE
|
#if UNIX_LIKE
|
||||||
# if HAVE_POLL
|
# if HAVE_POLL
|
||||||
|
@ -119,6 +125,7 @@ CXWindowsScreen::CXWindowsScreen(IScreenReceiver* receiver,
|
||||||
m_window(None),
|
m_window(None),
|
||||||
m_x(0), m_y(0),
|
m_x(0), m_y(0),
|
||||||
m_w(0), m_h(0),
|
m_w(0), m_h(0),
|
||||||
|
m_xCenter(0), m_yCenter(0),
|
||||||
m_screensaver(NULL),
|
m_screensaver(NULL),
|
||||||
m_screensaverNotify(false),
|
m_screensaverNotify(false),
|
||||||
m_atomScreensaver(None),
|
m_atomScreensaver(None),
|
||||||
|
@ -561,8 +568,8 @@ CXWindowsScreen::getCursorPos(SInt32& x, SInt32& y) const
|
||||||
y = my;
|
y = my;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
x = m_x + (m_w >> 1);
|
x = m_xCenter;
|
||||||
y = m_y + (m_h >> 1);
|
y = m_yCenter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -570,20 +577,54 @@ void
|
||||||
CXWindowsScreen::getCursorCenter(SInt32& x, SInt32& y) const
|
CXWindowsScreen::getCursorCenter(SInt32& x, SInt32& y) const
|
||||||
{
|
{
|
||||||
CLock lock(&m_mutex);
|
CLock lock(&m_mutex);
|
||||||
assert(m_display != NULL);
|
|
||||||
|
|
||||||
x = m_x + (m_w >> 1);
|
x = m_xCenter;
|
||||||
y = m_y + (m_h >> 1);
|
y = m_yCenter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CXWindowsScreen::updateScreenShape()
|
CXWindowsScreen::updateScreenShape()
|
||||||
{
|
{
|
||||||
|
// get shape of default screen
|
||||||
m_x = 0;
|
m_x = 0;
|
||||||
m_y = 0;
|
m_y = 0;
|
||||||
m_w = WidthOfScreen(DefaultScreenOfDisplay(m_display));
|
m_w = WidthOfScreen(DefaultScreenOfDisplay(m_display));
|
||||||
m_h = HeightOfScreen(DefaultScreenOfDisplay(m_display));
|
m_h = HeightOfScreen(DefaultScreenOfDisplay(m_display));
|
||||||
LOG((CLOG_INFO "screen shape: %d,%d %dx%d", m_x, m_y, m_w, m_h));
|
LOG((CLOG_INFO "screen shape: %d,%d %dx%d", m_x, m_y, m_w, m_h));
|
||||||
|
|
||||||
|
// get center of default screen
|
||||||
|
m_xCenter = m_x + (m_w >> 1);
|
||||||
|
m_yCenter = m_y + (m_h >> 1);
|
||||||
|
|
||||||
|
#if HAVE_X11_EXTENSIONS_XINERAMA_H
|
||||||
|
// get center of first Xinerama screen. Xinerama appears to have
|
||||||
|
// a bug when XWarpPointer() is used in combination with
|
||||||
|
// XGrabPointer(). in that case, the warp is successful but the
|
||||||
|
// next pointer motion warps the pointer again, apparently to
|
||||||
|
// constrain it to some unknown region, possibly the region from
|
||||||
|
// 0,0 to Wm,Hm where Wm (Hm) is the minimum width (height) over
|
||||||
|
// all physical screens. this warp only seems to happen if the
|
||||||
|
// pointer wasn't in that region before the XWarpPointer(). the
|
||||||
|
// second (unexpected) warp causes synergy to think the pointer
|
||||||
|
// has been moved when it hasn't. to work around the problem,
|
||||||
|
// we warp the pointer to the center of the first physical
|
||||||
|
// screen instead of the logical screen.
|
||||||
|
int eventBase, errorBase;
|
||||||
|
if (XineramaQueryExtension(m_display, &eventBase, &errorBase)) {
|
||||||
|
if (XineramaIsActive(m_display)) {
|
||||||
|
int numScreens;
|
||||||
|
XineramaScreenInfo* screens;
|
||||||
|
screens = XineramaQueryScreens(m_display, &numScreens);
|
||||||
|
if (screens != NULL) {
|
||||||
|
if (numScreens > 1) {
|
||||||
|
m_xCenter = screens[0].x_org + (screens[0].width >> 1);
|
||||||
|
m_yCenter = screens[0].y_org + (screens[0].height >> 1);
|
||||||
|
}
|
||||||
|
XFree(screens);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -271,6 +271,7 @@ private:
|
||||||
|
|
||||||
SInt32 m_x, m_y;
|
SInt32 m_x, m_y;
|
||||||
SInt32 m_w, m_h;
|
SInt32 m_w, m_h;
|
||||||
|
SInt32 m_xCenter, m_yCenter;
|
||||||
|
|
||||||
// clipboards
|
// clipboards
|
||||||
CXWindowsClipboard* m_clipboard[kClipboardEnd];
|
CXWindowsClipboard* m_clipboard[kClipboardEnd];
|
||||||
|
|
Loading…
Reference in New Issue