From 41721e9eac5532ce7c048a3b63851b3736c0244b Mon Sep 17 00:00:00 2001 From: Andrew Nelless Date: Fri, 19 May 2017 20:16:30 +0100 Subject: [PATCH] Partial local input detection for Linux --- src/lib/platform/XWindowsScreen.cpp | 75 ++++++++++++++++------------- 1 file changed, 42 insertions(+), 33 deletions(-) diff --git a/src/lib/platform/XWindowsScreen.cpp b/src/lib/platform/XWindowsScreen.cpp index b405498e..42742ad0 100644 --- a/src/lib/platform/XWindowsScreen.cpp +++ b/src/lib/platform/XWindowsScreen.cpp @@ -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;