Changed how key state is tracked on X11. Now updating key state

on every key press and release so we don't have to updateKeys()
in isLockedToScreen().  However, if any key appears to be down
we still call updateKeys() to double check that it's really down.
If not we note the spurious lock and don't lock to the screen.
This commit is contained in:
crs
2004-03-14 17:55:53 +00:00
parent 6f19fcfe39
commit 20ba10bfa8
11 changed files with 382 additions and 310 deletions

View File

@@ -184,8 +184,8 @@ CXWindowsScreen::CXWindowsScreen(bool isPrimary) :
// install event handlers
EVENTQUEUE->adoptHandler(CEvent::kSystem, IEventQueue::getSystemTarget(),
new TMethodEventJob<CXWindowsScreen>(this,
&CXWindowsScreen::handleSystemEvent));
new TMethodEventJob<IPlatformScreen>(this,
&IPlatformScreen::handleSystemEvent));
// install the platform event queue
EVENTQUEUE->adoptBuffer(new CXWindowsEventQueueBuffer(m_display, m_window));
@@ -244,6 +244,9 @@ CXWindowsScreen::enable()
// warp the mouse to the cursor center
fakeMouseMove(m_xCenter, m_yCenter);
}
else {
m_keyState->updateKeys();
}
}
void
@@ -544,6 +547,21 @@ CXWindowsScreen::isAnyMouseButtonDown() const
return false;
}
KeyModifierMask
CXWindowsScreen::getActiveModifiers() const
{
// query the pointer to get the modifier state
Window root, window;
int xRoot, yRoot, xWindow, yWindow;
unsigned int state;
if (XQueryPointer(m_display, m_root, &root, &window,
&xRoot, &yRoot, &xWindow, &yWindow, &state)) {
return m_keyMapper.mapModifier(state);
}
return 0;
}
void
CXWindowsScreen::getCursorCenter(SInt32& x, SInt32& y) const
{
@@ -841,12 +859,49 @@ CXWindowsScreen::sendClipboardEvent(CEvent::Type type, ClipboardID id)
sendEvent(type, info);
}
Bool
CXWindowsScreen::findKeyEvent(Display*, XEvent* xevent, XPointer arg)
{
CKeyEventFilter* filter = reinterpret_cast<CKeyEventFilter*>(arg);
return (xevent->type == filter->m_event &&
xevent->xkey.window == filter->m_window &&
xevent->xkey.time == filter->m_time &&
xevent->xkey.keycode == filter->m_keycode) ? True : False;
}
void
CXWindowsScreen::handleSystemEvent(const CEvent& event, void*)
{
XEvent* xevent = reinterpret_cast<XEvent*>(event.getData());
assert(xevent != NULL);
// update key state
bool isRepeat = false;
if (m_isPrimary) {
if (xevent->type == KeyRelease) {
// check if this is a key repeat by getting the next
// KeyPress event that has the same key and time as
// this release event, if any. first prepare the
// filter info.
CKeyEventFilter filter;
filter.m_event = KeyPress;
filter.m_window = xevent->xkey.window;
filter.m_time = xevent->xkey.time;
filter.m_keycode = xevent->xkey.keycode;
XEvent xevent2;
isRepeat = (XCheckIfEvent(m_display, &xevent2,
&CXWindowsScreen::findKeyEvent,
(XPointer)&filter) == True);
}
if (xevent->type == KeyPress || xevent->type == KeyRelease) {
if (!isRepeat) {
m_keyState->setKeyDown(xevent->xkey.keycode,
xevent->type == KeyPress);
}
}
}
// let input methods try to handle event first
if (m_ic != NULL) {
// XFilterEvent() may eat the event and generate a new KeyPress
@@ -977,7 +1032,7 @@ CXWindowsScreen::handleSystemEvent(const CEvent& event, void*)
case KeyRelease:
if (m_isPrimary) {
onKeyRelease(xevent->xkey);
onKeyRelease(xevent->xkey, isRepeat);
}
return;
@@ -1037,41 +1092,12 @@ CXWindowsScreen::onKeyPress(XKeyEvent& xkey)
}
}
Bool
CXWindowsScreen::findKeyEvent(Display*, XEvent* xevent, XPointer arg)
{
CKeyEventFilter* filter = reinterpret_cast<CKeyEventFilter*>(arg);
return (xevent->type == filter->m_event &&
xevent->xkey.window == filter->m_window &&
xevent->xkey.time == filter->m_time &&
xevent->xkey.keycode == filter->m_keycode) ? True : False;
}
void
CXWindowsScreen::onKeyRelease(XKeyEvent& xkey)
CXWindowsScreen::onKeyRelease(XKeyEvent& xkey, bool isRepeat)
{
const KeyModifierMask mask = m_keyMapper.mapModifier(xkey.state);
KeyID key = mapKeyFromX(&xkey);
if (key != kKeyNone) {
// check if this is a key repeat by getting the next
// KeyPress event that has the same key and time as
// this release event, if any. first prepare the
// filter info.
CKeyEventFilter filter;
filter.m_event = KeyPress;
filter.m_window = xkey.window;
filter.m_time = xkey.time;
filter.m_keycode = xkey.keycode;
// now check for event
bool hasPress;
{
XEvent xevent2;
hasPress = (XCheckIfEvent(m_display, &xevent2,
&CXWindowsScreen::findKeyEvent,
(XPointer)&filter) == True);
}
// check for ctrl+alt+del emulation
if ((key == kKeyPause || key == kKeyBreak) &&
(mask & (KeyModifierControl | KeyModifierAlt)) ==
@@ -1079,11 +1105,11 @@ CXWindowsScreen::onKeyRelease(XKeyEvent& xkey)
// pretend it's ctrl+alt+del and ignore autorepeat
LOG((CLOG_DEBUG "emulate ctrl+alt+del"));
key = kKeyDelete;
hasPress = false;
isRepeat = false;
}
KeyButton keycode = static_cast<KeyButton>(xkey.keycode);
if (!hasPress) {
if (!isRepeat) {
// no press event follows so it's a plain release
LOG((CLOG_DEBUG1 "event: KeyRelease code=%d, state=0x%04x", keycode, xkey.state));
KeyModifierMask keyMask = m_keyState->getMaskForKey(keycode);