From 2f7baaeccf143a4606c463bd50b1bd995fd3d18a Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 24 Jul 2012 20:45:52 +0000 Subject: [PATCH] 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 --- include/wx/event.h | 13 +++++++++++-- include/wx/osx/app.h | 8 ++++---- interface/wx/event.h | 7 +++++++ samples/keyboard/keyboard.cpp | 7 +++++-- src/common/event.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ src/gtk/window.cpp | 2 -- src/msw/window.cpp | 15 --------------- src/osx/carbon/app.cpp | 18 +++++++----------- src/osx/carbon/nonownedwnd.cpp | 8 ++------ src/osx/webview_webkit.mm | 9 ++------- 10 files changed, 78 insertions(+), 49 deletions(-) diff --git a/include/wx/event.h b/include/wx/event.h index 283a0f5..62d3a57 100644 --- a/include/wx/event.h +++ b/include/wx/event.h @@ -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) }; diff --git a/include/wx/osx/app.h b/include/wx/osx/app.h index 011d0dd..5145328 100644 --- a/include/wx/osx/app.h +++ b/include/wx/osx/app.h @@ -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) ; diff --git a/interface/wx/event.h b/interface/wx/event.h index be9d0d5..d02d5a0 100644 --- a/interface/wx/event.h +++ b/interface/wx/event.h @@ -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; diff --git a/samples/keyboard/keyboard.cpp b/samples/keyboard/keyboard.cpp index d90b035..7b30978 100644 --- a/samples/keyboard/keyboard.cpp +++ b/samples/keyboard/keyboard.cpp @@ -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); diff --git a/src/common/event.cpp b/src/common/event.cpp index 59f6bc0..fa39ae9 100644 --- a/src/common/event.cpp +++ b/src/common/event.cpp @@ -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(*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() ) diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 0aec013..e8dc915 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -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 ); } diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 34e2e2b..6bb0616 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -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 diff --git a/src/osx/carbon/app.cpp b/src/osx/carbon/app.cpp index 4f14173..7f394e8 100644 --- a/src/osx/carbon/app.cpp +++ b/src/osx/carbon/app.cpp @@ -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 } diff --git a/src/osx/carbon/nonownedwnd.cpp b/src/osx/carbon/nonownedwnd.cpp index 3f63eb0..8c70d53 100644 --- a/src/osx/carbon/nonownedwnd.cpp +++ b/src/osx/carbon/nonownedwnd.cpp @@ -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] ; diff --git a/src/osx/webview_webkit.mm b/src/osx/webview_webkit.mm index fb8796e..0b31750 100644 --- a/src/osx/webview_webkit.mm +++ b/src/osx/webview_webkit.mm @@ -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] ; -- 2.7.4