Don't eagerly set wxKeyEvent position fields.

This results in a noticeable delay when using wxGTK via a remote X11
connection for every key event as a round trip to server is needed to get the
mouse pointer position every time a key is pressed or released.

Only provide the position on demand. And explain that it's actually not very
useful as it's simply the same as the current mouse position.

Closes #14361.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@72207 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2012-07-24 20:45:52 +00:00
parent 7ce6da52a1
commit 2f7baaeccf
10 changed files with 78 additions and 49 deletions

View File

@ -1699,10 +1699,10 @@ public:
{ return wxPoint(m_x, m_y); }
// Get X position
wxCoord GetX() const { return m_x; }
wxCoord GetX() const;
// Get Y position
wxCoord GetY() const { return m_y; }
wxCoord GetY() const;
// Can be called from wxEVT_CHAR_HOOK handler to allow generation of normal
// key events even though the event had been handled (by default they would
@ -1766,6 +1766,7 @@ private:
{
m_x = evt.m_x;
m_y = evt.m_y;
m_hasPosition = evt.m_hasPosition;
m_keyCode = evt.m_keyCode;
@ -1776,11 +1777,19 @@ private:
#endif
}
// Initialize m_x and m_y using the current mouse cursor position if
// necessary.
void InitPositionIfNecessary() const;
// If this flag is true, the normal key events should still be generated
// even if wxEVT_CHAR_HOOK had been handled. By default it is false as
// handling wxEVT_CHAR_HOOK suppresses all the subsequent events.
bool m_allowNext;
// If true, m_x and m_y were already initialized. If false, try to get them
// when they're requested.
bool m_hasPosition;
DECLARE_DYNAMIC_CLASS(wxKeyEvent)
};

View File

@ -109,10 +109,10 @@ public:
// For embedded use. By default does nothing.
virtual void MacHandleUnhandledEvent( WXEVENTREF ev );
bool MacSendKeyDownEvent( wxWindow* focus , long keyval , long modifiers , long when , short wherex , short wherey , wxChar uniChar ) ;
bool MacSendKeyUpEvent( wxWindow* focus , long keyval , long modifiers , long when , short wherex , short wherey , wxChar uniChar ) ;
bool MacSendCharEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey , wxChar uniChar ) ;
void MacCreateKeyEvent( wxKeyEvent& event, wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey , wxChar uniChar ) ;
bool MacSendKeyDownEvent( wxWindow* focus , long keyval , long modifiers , long when , wxChar uniChar ) ;
bool MacSendKeyUpEvent( wxWindow* focus , long keyval , long modifiers , long when , wxChar uniChar ) ;
bool MacSendCharEvent( wxWindow* focus , long keymessage , long modifiers , long when , wxChar uniChar ) ;
void MacCreateKeyEvent( wxKeyEvent& event, wxWindow* focus , long keymessage , long modifiers , long when , wxChar uniChar ) ;
#if wxOSX_USE_CARBON
// we only have applescript on these
virtual short MacHandleAEODoc(const WXAPPLEEVENTREF event , WXAPPLEEVENTREF reply) ;

View File

@ -1444,6 +1444,9 @@ public:
//@{
/**
Obtains the position (in client coordinates) at which the key was pressed.
Notice that this position is simply the current mouse pointer position
and has no special relationship to the key event itself.
*/
wxPoint GetPosition() const;
void GetPosition(long* x, long* y) const;
@ -1502,11 +1505,15 @@ public:
/**
Returns the X position (in client coordinates) of the event.
@see GetPosition()
*/
wxCoord GetX() const;
/**
Returns the Y position (in client coordinates) of the event.
@see GetPosition()
*/
wxCoord GetY() const;

View File

@ -162,7 +162,7 @@ MyFrame::MyFrame(const wxString& title)
wxTE_READONLY);
headerText->SetValue(
" event key KeyCode mod UnicodeKey "
" RawKeyCode RawKeyFlags");
" RawKeyCode RawKeyFlags Position");
m_logText = new wxTextCtrl(this, wxID_ANY, "",
@ -404,7 +404,7 @@ wxString GetKeyName(const wxKeyEvent &event)
void MyFrame::LogEvent(const wxString& name, wxKeyEvent& event)
{
wxString msg;
// event key_name KeyCode modifiers Unicode raw_code raw_flags
// event key_name KeyCode modifiers Unicode raw_code raw_flags pos
msg.Printf("%7s %15s %5d %c%c%c%c"
#if wxUSE_UNICODE
"%5d (U+%04x)"
@ -416,6 +416,7 @@ void MyFrame::LogEvent(const wxString& name, wxKeyEvent& event)
#else
" not-set not-set"
#endif
" (%5d,%5d)"
"\n",
name,
GetKeyName(event),
@ -432,6 +433,8 @@ void MyFrame::LogEvent(const wxString& name, wxKeyEvent& event)
, (unsigned long) event.GetRawKeyCode()
, (unsigned long) event.GetRawKeyFlags()
#endif
, event.GetX()
, event.GetY()
);
m_logText->AppendText(msg);

View File

@ -736,6 +736,10 @@ wxKeyEvent::wxKeyEvent(wxEventType type)
m_uniChar = WXK_NONE;
#endif
m_x =
m_y = wxDefaultCoord;
m_hasPosition = false;
InitPropagation();
}
@ -759,6 +763,42 @@ wxKeyEvent::wxKeyEvent(wxEventType eventType, const wxKeyEvent& evt)
InitPropagation();
}
void wxKeyEvent::InitPositionIfNecessary() const
{
if ( m_hasPosition )
return;
// We're const because we're called from const Get[XY]() methods but we
// need to update the "cached" values.
wxKeyEvent& self = const_cast<wxKeyEvent&>(*this);
self.m_hasPosition = true;
// The only position we can possibly associate with the keyboard event on
// the platforms where it doesn't carry it already is the mouse position.
wxGetMousePosition(&self.m_x, &self.m_y);
// If this event is associated with a window, the position should be in its
// client coordinates, but otherwise leave it in screen coordinates as what
// else can we use?
wxWindow* const win = wxDynamicCast(GetEventObject(), wxWindow);
if ( win )
win->ScreenToClient(&self.m_x, &self.m_y);
}
wxCoord wxKeyEvent::GetX() const
{
InitPositionIfNecessary();
return m_x;
}
wxCoord wxKeyEvent::GetY() const
{
InitPositionIfNecessary();
return m_y;
}
bool wxKeyEvent::IsKeyInCategory(int category) const
{
switch ( GetKeyCode() )

View File

@ -711,8 +711,6 @@ static void wxFillOtherKeyEventFields(wxKeyEvent& event,
event.m_rawCode = (wxUint32) gdk_event->keyval;
event.m_rawFlags = gdk_event->hardware_keycode;
wxGetMousePosition(&event.m_x, &event.m_y);
win->ScreenToClient(&event.m_x, &event.m_y);
event.SetEventObject( win );
}

View File

@ -5682,21 +5682,6 @@ MSWInitAnyKeyEvent(wxKeyEvent& event,
#ifndef __WXWINCE__
event.SetTimestamp(::GetMessageTime());
#endif
// Event coordinates must be in window client coordinates system which
// doesn't make sense if there is no window.
//
// We could use screen coordinates for such events but this would make the
// logic of the event handlers more complicated: you'd need to test for the
// event object and interpret the coordinates differently according to
// whether it's NULL or not so unless somebody really asks for this let's
// just avoid the issue.
if ( win )
{
const wxPoint mousePos = win->ScreenToClient(wxGetMousePosition());
event.m_x = mousePos.x;
event.m_y = mousePos.y;
}
}
} // anonymous namespace

View File

@ -1400,34 +1400,34 @@ wxMouseState wxGetMouseState()
// TODO : once the new key/char handling is tested, move all the code to wxWindow
bool wxApp::MacSendKeyDownEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey , wxChar uniChar )
bool wxApp::MacSendKeyDownEvent( wxWindow* focus , long keymessage , long modifiers , long when , wxChar uniChar )
{
if ( !focus )
return false ;
wxKeyEvent event(wxEVT_KEY_DOWN) ;
MacCreateKeyEvent( event, focus , keymessage , modifiers , when , wherex , wherey , uniChar ) ;
MacCreateKeyEvent( event, focus , keymessage , modifiers , when , uniChar ) ;
return focus->OSXHandleKeyEvent(event);
}
bool wxApp::MacSendKeyUpEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey , wxChar uniChar )
bool wxApp::MacSendKeyUpEvent( wxWindow* focus , long keymessage , long modifiers , long when , wxChar uniChar )
{
if ( !focus )
return false ;
wxKeyEvent event( wxEVT_KEY_UP ) ;
MacCreateKeyEvent( event, focus , keymessage , modifiers , when , wherex , wherey , uniChar ) ;
MacCreateKeyEvent( event, focus , keymessage , modifiers , when , uniChar ) ;
return focus->OSXHandleKeyEvent(event) ;
}
bool wxApp::MacSendCharEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey , wxChar uniChar )
bool wxApp::MacSendCharEvent( wxWindow* focus , long keymessage , long modifiers , long when , wxChar uniChar )
{
if ( !focus )
return false ;
wxKeyEvent event(wxEVT_CHAR) ;
MacCreateKeyEvent( event, focus , keymessage , modifiers , when , wherex , wherey , uniChar ) ;
MacCreateKeyEvent( event, focus , keymessage , modifiers , when , uniChar ) ;
bool handled = false ;
@ -1508,7 +1508,7 @@ bool wxApp::MacSendCharEvent( wxWindow* focus , long keymessage , long modifiers
}
// This method handles common code for SendKeyDown, SendKeyUp, and SendChar events.
void wxApp::MacCreateKeyEvent( wxKeyEvent& event, wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey , wxChar uniChar )
void wxApp::MacCreateKeyEvent( wxKeyEvent& event, wxWindow* focus , long keymessage , long modifiers , long when , wxChar uniChar )
{
#if wxOSX_USE_COCOA_OR_CARBON
@ -1590,8 +1590,6 @@ void wxApp::MacCreateKeyEvent( wxKeyEvent& event, wxWindow* focus , long keymess
event.m_rawCode = keymessage;
event.m_rawFlags = modifiers;
event.m_x = wherex;
event.m_y = wherey;
event.SetTimestamp(when);
event.SetEventObject(focus);
#else
@ -1600,8 +1598,6 @@ void wxApp::MacCreateKeyEvent( wxKeyEvent& event, wxWindow* focus , long keymess
wxUnusedVar(keymessage);
wxUnusedVar(modifiers);
wxUnusedVar(when);
wxUnusedVar(wherex);
wxUnusedVar(wherey);
wxUnusedVar(uniChar);
#endif
}

View File

@ -306,7 +306,6 @@ static pascal OSStatus KeyboardEventHandler( EventHandlerCallRef handler , Event
UInt32 keyCode ;
UInt32 modifiers ;
Point point ;
UInt32 when = EventTimeToTicks( GetEventTime( event ) ) ;
#if wxUSE_UNICODE
@ -334,7 +333,6 @@ static pascal OSStatus KeyboardEventHandler( EventHandlerCallRef handler , Event
GetEventParameter( event, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &charCode );
GetEventParameter( event, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode );
GetEventParameter( event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers );
GetEventParameter( event, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &point );
UInt32 message = (keyCode << 8) + charCode;
switch ( GetEventKind( event ) )
@ -346,7 +344,7 @@ static pascal OSStatus KeyboardEventHandler( EventHandlerCallRef handler , Event
WXEVENTHANDLERCALLREF formerHandler = wxTheApp->MacGetCurrentEventHandlerCallRef() ;
wxTheApp->MacSetCurrentEvent( event , handler ) ;
if ( /* focus && */ wxTheApp->MacSendKeyDownEvent(
focus , message , modifiers , when , point.h , point.v , uniChar[0] ) )
focus , message , modifiers , when , uniChar[0] ) )
{
result = noErr ;
}
@ -356,7 +354,7 @@ static pascal OSStatus KeyboardEventHandler( EventHandlerCallRef handler , Event
case kEventRawKeyUp :
if ( /* focus && */ wxTheApp->MacSendKeyUpEvent(
focus , message , modifiers , when , point.h , point.v , uniChar[0] ) )
focus , message , modifiers , when , uniChar[0] ) )
{
result = noErr ;
}
@ -370,8 +368,6 @@ static pascal OSStatus KeyboardEventHandler( EventHandlerCallRef handler , Event
event.m_rawControlDown = modifiers & controlKey;
event.m_altDown = modifiers & optionKey;
event.m_controlDown = event.m_metaDown = modifiers & cmdKey;
event.m_x = point.h;
event.m_y = point.v;
#if wxUSE_UNICODE
event.m_uniChar = uniChar[0] ;

View File

@ -103,7 +103,6 @@ static pascal OSStatus wxWebKitKeyEventHandler(EventHandlerCallRef handler,
UInt32 keyCode ;
UInt32 modifiers ;
Point point ;
UInt32 when = EventTimeToTicks( GetEventTime( event ) ) ;
#if wxUSE_UNICODE
@ -140,8 +139,6 @@ static pascal OSStatus wxWebKitKeyEventHandler(EventHandlerCallRef handler,
sizeof(UInt32), NULL, &keyCode );
GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL,
sizeof(UInt32), NULL, &modifiers );
GetEventParameter(event, kEventParamMouseLocation, typeQDPoint, NULL,
sizeof(Point), NULL, &point );
UInt32 message = (keyCode << 8) + charCode;
switch ( GetEventKind( event ) )
@ -155,7 +152,7 @@ static pascal OSStatus wxWebKitKeyEventHandler(EventHandlerCallRef handler,
wxTheApp->MacSetCurrentEvent( event , handler ) ;
if ( /* focus && */ wxTheApp->MacSendKeyDownEvent(
focus, message, modifiers, when, point.h, point.v, uniChar[0]))
focus, message, modifiers, when, uniChar[0]))
{
result = noErr ;
}
@ -165,7 +162,7 @@ static pascal OSStatus wxWebKitKeyEventHandler(EventHandlerCallRef handler,
case kEventRawKeyUp :
if ( /* focus && */ wxTheApp->MacSendKeyUpEvent(
focus , message , modifiers , when , point.h , point.v , uniChar[0] ) )
focus , message , modifiers , when , uniChar[0] ) )
{
result = noErr ;
}
@ -179,8 +176,6 @@ static pascal OSStatus wxWebKitKeyEventHandler(EventHandlerCallRef handler,
event.m_controlDown = modifiers & controlKey;
event.m_altDown = modifiers & optionKey;
event.m_metaDown = modifiers & cmdKey;
event.m_x = point.h;
event.m_y = point.v;
#if wxUSE_UNICODE
event.m_uniChar = uniChar[0] ;