Partial local input detection for Linux

This commit is contained in:
Andrew Nelless 2017-05-19 20:16:30 +01:00
parent 0ac42d4d05
commit 41721e9eac
1 changed files with 42 additions and 33 deletions

View File

@ -102,7 +102,7 @@ XWindowsScreen::XWindowsScreen(
m_display(NULL),
m_root(None),
m_window(None),
m_isOnScreen(m_isPrimary),
m_isOnScreen(true),
m_x(0), m_y(0),
m_w(0), m_h(0),
m_xCenter(0), m_yCenter(0),
@ -159,7 +159,6 @@ XWindowsScreen::XWindowsScreen(
}
// primary/secondary screen only initialization
if (m_isPrimary) {
#ifdef HAVE_XI2
m_xi2detected = detectXI2();
if (m_xi2detected) {
@ -173,8 +172,7 @@ XWindowsScreen::XWindowsScreen(
// prepare to use input methods
openIM();
}
else {
if (!m_isPrimary) {
// become impervious to server grabs
XTestGrabControl(m_display, True);
}
@ -241,7 +239,7 @@ XWindowsScreen::enable()
XMapRaised(m_display, m_window);
// warp the mouse to the cursor center
fakeMouseMove(m_xCenter, m_yCenter);
warpCursor(m_xCenter, m_yCenter);
}
}
@ -359,12 +357,7 @@ XWindowsScreen::leave()
// now warp the mouse. we warp after showing the window so we're
// guaranteed to get the mouse leave event and to prevent the
// keyboard focus from changing under point-to-focus policies.
if (m_isPrimary) {
warpCursor(m_xCenter, m_yCenter);
}
else {
fakeMouseMove(m_xCenter, m_yCenter);
}
warpCursor(m_xCenter, m_yCenter);
// set input context focus to our window
if (m_ic != NULL) {
@ -835,7 +828,7 @@ XWindowsScreen::fakeMouseMove(SInt32 x, SInt32 y)
{
if (m_xinerama && m_xtestIsXineramaUnaware) {
XWarpPointer(m_display, None, m_root, 0, 0, 0, 0, x, y);
}
}
else {
XTestFakeMotionEvent(m_display, DefaultScreen(m_display),
x, y, CurrentTime);
@ -1043,7 +1036,10 @@ XWindowsScreen::openWindow() const
// moved. we'll reposition the window as necessary so its
// position here doesn't matter. it only needs to be 1x1 because
// it only needs to contain the cursor's hotspot.
attr.event_mask = LeaveWindowMask | ButtonPressMask;
attr.event_mask = PointerMotionMask |
ButtonPressMask | ButtonReleaseMask |
KeyPressMask | KeyReleaseMask |
KeymapStateMask;
x = 0;
y = 0;
w = 1;
@ -1252,27 +1248,31 @@ XWindowsScreen::handleSystemEvent(const Event& event, void*)
cookie->type == GenericEvent &&
cookie->extension == xi_opcode) {
if (cookie->evtype == XI_RawMotion) {
// Get current pointer's position
Window root, child;
XMotionEvent xmotion;
xmotion.type = MotionNotify;
xmotion.send_event = False; // Raw motion
xmotion.display = m_display;
xmotion.window = m_window;
/* xmotion's time, state and is_hint are not used */
unsigned int msk;
xmotion.same_screen = XQueryPointer(
m_display, m_root, &xmotion.root, &xmotion.subwindow,
&xmotion.x_root,
&xmotion.y_root,
&xmotion.x,
&xmotion.y,
&msk);
if (m_isPrimary) {
// Get current pointer's position
Window root, child;
XMotionEvent xmotion;
xmotion.type = MotionNotify;
xmotion.send_event = False; // Raw motion
xmotion.display = m_display;
xmotion.window = m_window;
/* xmotion's time, state and is_hint are not used */
unsigned int msk;
xmotion.same_screen = XQueryPointer(
m_display, m_root, &xmotion.root, &xmotion.subwindow,
&xmotion.x_root,
&xmotion.y_root,
&xmotion.x,
&xmotion.y,
&msk);
onMouseMove(xmotion);
XFreeEventData(m_display, cookie);
return;
} else if (!m_isOnScreen) {
LOG ((CLOG_INFO "local input detected"));
}
XFreeEventData(m_display, cookie);
return;
}
XFreeEventData(m_display, cookie);
XFreeEventData(m_display, cookie);
}
}
#endif
@ -1358,31 +1358,40 @@ XWindowsScreen::handleSystemEvent(const Event& event, void*)
case KeyPress:
if (m_isPrimary) {
onKeyPress(xevent->xkey);
} else {
LOG ((CLOG_INFO "local input detected"));
}
return;
case KeyRelease:
if (m_isPrimary) {
onKeyRelease(xevent->xkey, isRepeat);
} else {
LOG ((CLOG_INFO "local input detected"));
}
return;
case ButtonPress:
LOG ((CLOG_DEBUG "Yay, you clicked something!"));
if (m_isPrimary) {
onMousePress(xevent->xbutton);
} else {
LOG ((CLOG_INFO "local input detected"));
}
return;
case ButtonRelease:
if (m_isPrimary) {
onMouseRelease(xevent->xbutton);
} else {
LOG ((CLOG_INFO "local input detected"));
}
return;
case MotionNotify:
if (m_isPrimary) {
onMouseMove(xevent->xmotion);
} else if (!m_isOnScreen && (xevent->xmotion.send_event == False)) {
LOG ((CLOG_INFO "local input detected"));
}
return;