Used MouseKeys accessibility function to show the mouse cursor
on a secondary screen when there's no physical mouse attached to the system. Kinda flaky when a mouse is attached or detached but seems to work well enough when the device is not attached to start with and not attached while running synergy.
This commit is contained in:
parent
423dd3b718
commit
a1bd77f91a
|
@ -106,7 +106,9 @@ CMSWindowsScreen::CMSWindowsScreen(bool isPrimary,
|
||||||
m_setMode(NULL),
|
m_setMode(NULL),
|
||||||
m_keyState(NULL),
|
m_keyState(NULL),
|
||||||
m_suspend(suspend),
|
m_suspend(suspend),
|
||||||
m_resume(resume)
|
m_resume(resume),
|
||||||
|
m_hasMouse(GetSystemMetrics(SM_MOUSEPRESENT) != 0),
|
||||||
|
m_showingMouse(false)
|
||||||
{
|
{
|
||||||
assert(s_instance != NULL);
|
assert(s_instance != NULL);
|
||||||
assert(s_screen == NULL);
|
assert(s_screen == NULL);
|
||||||
|
@ -125,6 +127,7 @@ CMSWindowsScreen::CMSWindowsScreen(bool isPrimary,
|
||||||
updateScreenShape();
|
updateScreenShape();
|
||||||
m_class = createWindowClass();
|
m_class = createWindowClass();
|
||||||
m_window = createWindow(m_class, "Synergy");
|
m_window = createWindow(m_class, "Synergy");
|
||||||
|
forceShowCursor();
|
||||||
LOG((CLOG_DEBUG "screen shape: %d,%d %dx%d %s", m_x, m_y, m_w, m_h, m_multimon ? "(multi-monitor)" : ""));
|
LOG((CLOG_DEBUG "screen shape: %d,%d %dx%d %s", m_x, m_y, m_w, m_h, m_multimon ? "(multi-monitor)" : ""));
|
||||||
LOG((CLOG_DEBUG "window is 0x%08x", m_window));
|
LOG((CLOG_DEBUG "window is 0x%08x", m_window));
|
||||||
}
|
}
|
||||||
|
@ -240,6 +243,7 @@ CMSWindowsScreen::disable()
|
||||||
m_nextClipboardWindow = NULL;
|
m_nextClipboardWindow = NULL;
|
||||||
|
|
||||||
m_isOnScreen = m_isPrimary;
|
m_isOnScreen = m_isPrimary;
|
||||||
|
forceShowCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -259,6 +263,7 @@ CMSWindowsScreen::enter()
|
||||||
|
|
||||||
// now on screen
|
// now on screen
|
||||||
m_isOnScreen = true;
|
m_isOnScreen = true;
|
||||||
|
forceShowCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -292,6 +297,7 @@ CMSWindowsScreen::leave()
|
||||||
|
|
||||||
// now off screen
|
// now off screen
|
||||||
m_isOnScreen = false;
|
m_isOnScreen = false;
|
||||||
|
forceShowCursor();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -525,6 +531,36 @@ CMSWindowsScreen::updateKeys()
|
||||||
m_desks->updateKeys();
|
m_desks->updateKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CMSWindowsScreen::fakeKeyDown(KeyID id, KeyModifierMask mask,
|
||||||
|
KeyButton button)
|
||||||
|
{
|
||||||
|
CPlatformScreen::fakeKeyDown(id, mask, button);
|
||||||
|
updateForceShowCursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CMSWindowsScreen::fakeKeyRepeat(KeyID id, KeyModifierMask mask,
|
||||||
|
SInt32 count, KeyButton button)
|
||||||
|
{
|
||||||
|
CPlatformScreen::fakeKeyRepeat(id, mask, count, button);
|
||||||
|
updateForceShowCursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CMSWindowsScreen::fakeKeyUp(KeyButton button)
|
||||||
|
{
|
||||||
|
CPlatformScreen::fakeKeyUp(button);
|
||||||
|
updateForceShowCursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CMSWindowsScreen::fakeToggle(KeyModifierMask modifier)
|
||||||
|
{
|
||||||
|
CPlatformScreen::fakeToggle(modifier);
|
||||||
|
updateForceShowCursor();
|
||||||
|
}
|
||||||
|
|
||||||
HINSTANCE
|
HINSTANCE
|
||||||
CMSWindowsScreen::openHookLibrary(const char* name)
|
CMSWindowsScreen::openHookLibrary(const char* name)
|
||||||
{
|
{
|
||||||
|
@ -829,6 +865,16 @@ CMSWindowsScreen::onEvent(HWND, UINT msg,
|
||||||
}
|
}
|
||||||
*result = TRUE;
|
*result = TRUE;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
case WM_DEVICECHANGE:
|
||||||
|
forceShowCursor();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WM_SETTINGCHANGE:
|
||||||
|
if (wParam == SPI_SETMOUSEKEYS) {
|
||||||
|
forceShowCursor();
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -1377,6 +1423,60 @@ CMSWindowsScreen::updateKeysCB(void*)
|
||||||
updateButtons();
|
updateButtons();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CMSWindowsScreen::forceShowCursor()
|
||||||
|
{
|
||||||
|
// check for mouse
|
||||||
|
m_hasMouse = (GetSystemMetrics(SM_MOUSEPRESENT) != 0);
|
||||||
|
|
||||||
|
// decide if we should show the mouse
|
||||||
|
bool showMouse = (!m_hasMouse && !m_isPrimary && m_isOnScreen);
|
||||||
|
|
||||||
|
// show/hide the mouse
|
||||||
|
if (showMouse != m_showingMouse) {
|
||||||
|
if (showMouse) {
|
||||||
|
m_oldMouseKeys.cbSize = sizeof(m_oldMouseKeys);
|
||||||
|
m_gotOldMouseKeys =
|
||||||
|
(SystemParametersInfo(SPI_GETMOUSEKEYS,
|
||||||
|
m_oldMouseKeys.cbSize, &m_oldMouseKeys, 0) != 0);
|
||||||
|
if (m_gotOldMouseKeys) {
|
||||||
|
m_mouseKeys = m_oldMouseKeys;
|
||||||
|
m_showingMouse = true;
|
||||||
|
updateForceShowCursor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (m_gotOldMouseKeys) {
|
||||||
|
SystemParametersInfo(SPI_SETMOUSEKEYS,
|
||||||
|
m_oldMouseKeys.cbSize,
|
||||||
|
&m_oldMouseKeys, SPIF_SENDCHANGE);
|
||||||
|
m_showingMouse = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CMSWindowsScreen::updateForceShowCursor()
|
||||||
|
{
|
||||||
|
DWORD oldFlags = m_mouseKeys.dwFlags;
|
||||||
|
|
||||||
|
// turn on MouseKeys
|
||||||
|
m_mouseKeys.dwFlags = MKF_AVAILABLE | MKF_MOUSEKEYSON;
|
||||||
|
|
||||||
|
// make sure MouseKeys is active in whatever state the NumLock is
|
||||||
|
// not currently in.
|
||||||
|
if ((m_keyState->getActiveModifiers() & KeyModifierNumLock) != 0) {
|
||||||
|
m_mouseKeys.dwFlags |= MKF_REPLACENUMBERS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update MouseKeys
|
||||||
|
if (oldFlags != m_mouseKeys.dwFlags) {
|
||||||
|
SystemParametersInfo(SPI_SETMOUSEKEYS,
|
||||||
|
m_mouseKeys.cbSize, &m_mouseKeys, SPIF_SENDCHANGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LRESULT CALLBACK
|
LRESULT CALLBACK
|
||||||
CMSWindowsScreen::wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
CMSWindowsScreen::wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
|
|
|
@ -80,6 +80,12 @@ public:
|
||||||
|
|
||||||
// IKeyState overrides
|
// IKeyState overrides
|
||||||
virtual void updateKeys();
|
virtual void updateKeys();
|
||||||
|
virtual void fakeKeyDown(KeyID id, KeyModifierMask mask,
|
||||||
|
KeyButton button);
|
||||||
|
virtual void fakeKeyRepeat(KeyID id, KeyModifierMask mask,
|
||||||
|
SInt32 count, KeyButton button);
|
||||||
|
virtual void fakeKeyUp(KeyButton button);
|
||||||
|
virtual void fakeToggle(KeyModifierMask modifier);
|
||||||
|
|
||||||
// IPlatformScreen overrides
|
// IPlatformScreen overrides
|
||||||
virtual void enable();
|
virtual void enable();
|
||||||
|
@ -174,6 +180,16 @@ private:
|
||||||
// job to update the key state
|
// job to update the key state
|
||||||
void updateKeysCB(void*);
|
void updateKeysCB(void*);
|
||||||
|
|
||||||
|
// determine whether the mouse is hidden by the system and force
|
||||||
|
// it to be displayed if user has entered this secondary screen.
|
||||||
|
void forceShowCursor();
|
||||||
|
|
||||||
|
// forceShowCursor uses MouseKeys to show the cursor. since we
|
||||||
|
// don't actually want MouseKeys behavior we have to make sure
|
||||||
|
// it applies when NumLock is in whatever state it's not in now.
|
||||||
|
// this method does that.
|
||||||
|
void updateForceShowCursor();
|
||||||
|
|
||||||
// our window proc
|
// our window proc
|
||||||
static LRESULT CALLBACK wndProc(HWND, UINT, WPARAM, LPARAM);
|
static LRESULT CALLBACK wndProc(HWND, UINT, WPARAM, LPARAM);
|
||||||
|
|
||||||
|
@ -250,6 +266,23 @@ private:
|
||||||
IJob* m_suspend;
|
IJob* m_suspend;
|
||||||
IJob* m_resume;
|
IJob* m_resume;
|
||||||
|
|
||||||
|
// the system shows the mouse cursor when an internal display count
|
||||||
|
// is >= 0. this count is maintained per application but there's
|
||||||
|
// apparently a system wide count added to the application's count.
|
||||||
|
// this system count is 0 if there's a mouse attached to the system
|
||||||
|
// and -1 otherwise. the MouseKeys accessibility feature can modify
|
||||||
|
// this system count by making the system appear to have a mouse.
|
||||||
|
//
|
||||||
|
// m_hasMouse is true iff there's a mouse attached to the system or
|
||||||
|
// MouseKeys is simulating one. we track this so we can force the
|
||||||
|
// cursor to be displayed when the user has entered this screen.
|
||||||
|
// m_showingMouse is true when we're doing that.
|
||||||
|
bool m_hasMouse;
|
||||||
|
bool m_showingMouse;
|
||||||
|
bool m_gotOldMouseKeys;
|
||||||
|
MOUSEKEYS m_mouseKeys;
|
||||||
|
MOUSEKEYS m_oldMouseKeys;
|
||||||
|
|
||||||
static CMSWindowsScreen* s_screen;
|
static CMSWindowsScreen* s_screen;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue