mirror of
https://github.com/SFML/SFML.git
synced 2025-01-19 07:45:13 +08:00
Implemented WaitEvent on Linux
git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/branches/sfml2@1248 4e206d99-4929-0410-ac5d-dfc041789085
This commit is contained in:
parent
a68ff5713b
commit
0d66fa1776
@ -282,53 +282,25 @@ WindowHandle WindowImplX11::GetHandle() const
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void WindowImplX11::ProcessEvents(bool block)
|
void WindowImplX11::ProcessEvents(bool block)
|
||||||
{
|
{
|
||||||
// This function implements a workaround to properly discard
|
if (block)
|
||||||
// repeated key events when necessary. The problem is that the
|
|
||||||
// system's key events policy doesn't match SFML's one: X server will generate
|
|
||||||
// both repeated KeyPress and KeyRelease events when maintaining a key down, while
|
|
||||||
// SFML only wants repeated KeyPress events. Thus, we have to:
|
|
||||||
// - Discard duplicated KeyRelease events when EnableKeyRepeat is true
|
|
||||||
// - Discard both duplicated KeyPress and KeyRelease events when EnableKeyRepeat is false
|
|
||||||
|
|
||||||
|
|
||||||
// Process any event in the queue matching our window
|
|
||||||
XEvent event;
|
|
||||||
while (XCheckIfEvent(myDisplay, &event, &CheckEvent, reinterpret_cast<XPointer>(myWindow)))
|
|
||||||
{
|
{
|
||||||
// Detect repeated key events
|
// Blocking -- wait and process events in the event queue until a valid event is found
|
||||||
if ((event.type == KeyPress) || (event.type == KeyRelease))
|
XEvent event;
|
||||||
|
do
|
||||||
{
|
{
|
||||||
if (event.xkey.keycode < 256)
|
XIfEvent(myDisplay, &event, &CheckEvent, reinterpret_cast<XPointer>(myWindow));
|
||||||
{
|
|
||||||
// To detect if it is a repeated key event, we check the current state of the key.
|
|
||||||
// - If the state is "down", KeyReleased events must obviously be discarded.
|
|
||||||
// - KeyPress events are a little bit harder to handle: they depend on the EnableKeyRepeat state,
|
|
||||||
// and we need to properly forward the first one.
|
|
||||||
char keys[32];
|
|
||||||
XQueryKeymap(myDisplay, keys);
|
|
||||||
if (keys[event.xkey.keycode >> 3] & (1 << (event.xkey.keycode % 8)))
|
|
||||||
{
|
|
||||||
// KeyRelease event + key down = repeated event --> discard
|
|
||||||
if (event.type == KeyRelease)
|
|
||||||
{
|
|
||||||
myLastKeyReleaseEvent = event;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// KeyPress event + key repeat disabled + matching KeyRelease event = repeated event --> discard
|
|
||||||
if ((event.type == KeyPress) && !myKeyRepeat &&
|
|
||||||
(myLastKeyReleaseEvent.xkey.keycode == event.xkey.keycode) &&
|
|
||||||
(myLastKeyReleaseEvent.xkey.time == event.xkey.time))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
while (!ProcessEvent(event));
|
||||||
// Process the event
|
}
|
||||||
ProcessEvent(event);
|
else
|
||||||
}
|
{
|
||||||
|
// Non-blocking -- process all events in the event queue
|
||||||
|
XEvent event;
|
||||||
|
while (XCheckIfEvent(myDisplay, &event, &CheckEvent, reinterpret_cast<XPointer>(myWindow)))
|
||||||
|
{
|
||||||
|
ProcessEvent(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -586,8 +558,48 @@ void WindowImplX11::CleanUp()
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void WindowImplX11::ProcessEvent(XEvent windowEvent)
|
bool WindowImplX11::ProcessEvent(XEvent windowEvent)
|
||||||
{
|
{
|
||||||
|
// This function implements a workaround to properly discard
|
||||||
|
// repeated key events when necessary. The problem is that the
|
||||||
|
// system's key events policy doesn't match SFML's one: X server will generate
|
||||||
|
// both repeated KeyPress and KeyRelease events when maintaining a key down, while
|
||||||
|
// SFML only wants repeated KeyPress events. Thus, we have to:
|
||||||
|
// - Discard duplicated KeyRelease events when EnableKeyRepeat is true
|
||||||
|
// - Discard both duplicated KeyPress and KeyRelease events when EnableKeyRepeat is false
|
||||||
|
|
||||||
|
// Detect repeated key events
|
||||||
|
if ((windowEvent.type == KeyPress) || (windowEvent.type == KeyRelease))
|
||||||
|
{
|
||||||
|
if (windowEvent.xkey.keycode < 256)
|
||||||
|
{
|
||||||
|
// To detect if it is a repeated key event, we check the current state of the key.
|
||||||
|
// - If the state is "down", KeyReleased events must obviously be discarded.
|
||||||
|
// - KeyPress events are a little bit harder to handle: they depend on the EnableKeyRepeat state,
|
||||||
|
// and we need to properly forward the first one.
|
||||||
|
char keys[32];
|
||||||
|
XQueryKeymap(myDisplay, keys);
|
||||||
|
if (keys[windowEvent.xkey.keycode >> 3] & (1 << (windowEvent.xkey.keycode % 8)))
|
||||||
|
{
|
||||||
|
// KeyRelease event + key down = repeated event --> discard
|
||||||
|
if (windowEvent.type == KeyRelease)
|
||||||
|
{
|
||||||
|
myLastKeyReleaseEvent = windowEvent;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// KeyPress event + key repeat disabled + matching KeyRelease event = repeated event --> discard
|
||||||
|
if ((windowEvent.type == KeyPress) && !myKeyRepeat &&
|
||||||
|
(myLastKeyReleaseEvent.xkey.keycode == windowEvent.xkey.keycode) &&
|
||||||
|
(myLastKeyReleaseEvent.xkey.time == windowEvent.xkey.time))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert the X11 event to a sf::Event
|
||||||
switch (windowEvent.type)
|
switch (windowEvent.type)
|
||||||
{
|
{
|
||||||
// Destroy event
|
// Destroy event
|
||||||
@ -814,6 +826,8 @@ void WindowImplX11::ProcessEvent(XEvent windowEvent)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -191,8 +191,10 @@ private :
|
|||||||
///
|
///
|
||||||
/// \param windowEvent Event which has been received
|
/// \param windowEvent Event which has been received
|
||||||
///
|
///
|
||||||
|
/// \return True if the event was processed, false if it was discarded
|
||||||
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void ProcessEvent(XEvent windowEvent);
|
bool ProcessEvent(XEvent windowEvent);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Convert a X11 keysym to SFML key code
|
/// \brief Convert a X11 keysym to SFML key code
|
||||||
|
Loading…
Reference in New Issue
Block a user