From edf5822ace25ff6283b05e587116e49e50b77464 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 2 Dec 2011 00:50:12 +0000 Subject: [PATCH] Implement EVT_CHAR_HOOK for wxOSX/Cocoa. Send wxEVT_CHAR_HOOK event from wxOSX/Cocoa code. Also test for wxEVT_CHAR_HOOK in the keyboard sample and show the effect of not skipping it. Closes #12431. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@69889 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 1 + interface/wx/event.h | 3 +- samples/keyboard/keyboard.cpp | 52 +++++++++++++++++++++++++++-------- src/osx/cocoa/window.mm | 12 ++++++++ 4 files changed, 54 insertions(+), 14 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index ac3273f5bf..605ad3055c 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -507,6 +507,7 @@ OSX: - wxGetOsVersion() now returns more sensible version numbers, e.g. 10 and 6 for OS X 10.6. - Added wxApp::MacOpenFiles and deprecated wxApp::MacOpenFile. +- Implement wxEVT_CHAR_HOOK event generation in wxOSX/Cocoa. GTK: diff --git a/interface/wx/event.h b/interface/wx/event.h index e61807c55d..d715fac7cd 100644 --- a/interface/wx/event.h +++ b/interface/wx/event.h @@ -1372,8 +1372,7 @@ enum wxKeyCategoryFlags generated. Notice that this event is not generated when the mouse is captured as it is considered that the window which has the capture should receive all the keyboard events too without allowing its parent - wxTopLevelWindow to interfere with their processing. Also please note - that currently this event is not generated by wxOSX/Cocoa port. + wxTopLevelWindow to interfere with their processing. @endEventTable @see wxKeyboardState diff --git a/samples/keyboard/keyboard.cpp b/samples/keyboard/keyboard.cpp index 25907b5a4c..c9e1ff9fcc 100644 --- a/samples/keyboard/keyboard.cpp +++ b/samples/keyboard/keyboard.cpp @@ -41,18 +41,32 @@ private: { m_logText->AppendText("Test accelerator \"Esc\" used.\n"); } void OnClear(wxCommandEvent& WXUNUSED(event)) { m_logText->Clear(); } - void OnSkip(wxCommandEvent& event) { m_skip = event.IsChecked(); } + void OnSkipDown(wxCommandEvent& event) { m_skipDown = event.IsChecked(); } + void OnSkipHook(wxCommandEvent& event) { m_skipHook = event.IsChecked(); } - void OnKeyDown(wxKeyEvent& event) { LogEvent("KeyDown", event); } + void OnKeyDown(wxKeyEvent& event) + { + LogEvent("KeyDown", event); + if ( m_skipDown ) + event.Skip(); + } void OnKeyUp(wxKeyEvent& event) { LogEvent("KeyUp", event); } void OnChar(wxKeyEvent& event) { LogEvent("Char", event); } + void OnCharHook(wxKeyEvent& event) + { + LogEvent("Hook", event); + if ( m_skipHook ) + event.Skip(); + } + void OnPaintInputWin(wxPaintEvent& event); void LogEvent(const wxString& name, wxKeyEvent& event); wxTextCtrl *m_logText; wxWindow *m_inputWin; - bool m_skip; + bool m_skipHook, + m_skipDown; }; @@ -87,7 +101,8 @@ IMPLEMENT_APP(MyApp) MyFrame::MyFrame(const wxString& title) : wxFrame(NULL, wxID_ANY, title), m_inputWin(NULL), - m_skip(true) + m_skipHook(true), + m_skipDown(true) { SetIcon(wxICON(sample)); @@ -96,7 +111,8 @@ MyFrame::MyFrame(const wxString& title) { QuitID = wxID_EXIT, ClearID = wxID_CLEAR, - SkipID = 100, + SkipHook = 100, + SkipDown, TestAccelA, TestAccelCtrlA, TestAccelEsc @@ -113,8 +129,14 @@ MyFrame::MyFrame(const wxString& title) menuFile->Append(TestAccelEsc, "Test accelerator &3\tEsc"); menuFile->AppendSeparator(); - menuFile->AppendCheckItem(SkipID, "Call event.&Skip()\tCtrl-S"); - menuFile->Check(SkipID, true); + menuFile->AppendCheckItem(SkipHook, "Skip CHAR_HOOK event", + "Not skipping this event disables both KEY_DOWN and CHAR events" + ); + menuFile->Check(SkipHook, true); + menuFile->AppendCheckItem(SkipDown, "Skip KEY_DOWN event", + "Not skipping this event disables CHAR event generation" + ); + menuFile->Check(SkipDown, true); menuFile->AppendSeparator(); menuFile->Append(QuitID, "E&xit\tAlt-X", "Quit this program"); @@ -175,8 +197,10 @@ MyFrame::MyFrame(const wxString& title) Connect(ClearID, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MyFrame::OnClear)); - Connect(SkipID, wxEVT_COMMAND_MENU_SELECTED, - wxCommandEventHandler(MyFrame::OnSkip)); + Connect(SkipHook, wxEVT_COMMAND_MENU_SELECTED, + wxCommandEventHandler(MyFrame::OnSkipHook)); + Connect(SkipDown, wxEVT_COMMAND_MENU_SELECTED, + wxCommandEventHandler(MyFrame::OnSkipDown)); Connect(TestAccelA, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MyFrame::OnTestAccelA)); @@ -198,6 +222,13 @@ MyFrame::MyFrame(const wxString& title) wxPaintEventHandler(MyFrame::OnPaintInputWin), NULL, this); + // notice that we don't connect OnCharHook() to the input window, unlike + // the usual key events this one is propagated upwards + Connect(wxEVT_CHAR_HOOK, wxKeyEventHandler(MyFrame::OnCharHook)); + + // status bar is useful for showing the menu items help strings + CreateStatusBar(); + // and show itself (the frames, unlike simple controls, are not shown when // created initially) Show(true); @@ -404,9 +435,6 @@ void MyFrame::LogEvent(const wxString& name, wxKeyEvent& event) ); m_logText->AppendText(msg); - - if ( m_skip ) - event.Skip(); } diff --git a/src/osx/cocoa/window.mm b/src/osx/cocoa/window.mm index 841b89426c..0bf1872401 100644 --- a/src/osx/cocoa/window.mm +++ b/src/osx/cocoa/window.mm @@ -2299,6 +2299,18 @@ bool wxWidgetCocoaImpl::DoHandleKeyEvent(NSEvent *event) { wxKeyEvent wxevent(wxEVT_KEY_DOWN); SetupKeyEvent( wxevent, event ); + + // Generate wxEVT_CHAR_HOOK before sending any other events but only when + // the key is pressed, not when it's released (the type of wxevent is + // changed by SetupKeyEvent() so it can be wxEVT_KEY_UP too by now). + if ( wxevent.GetEventType() == wxEVT_KEY_DOWN ) + { + wxKeyEvent eventHook(wxevent); + eventHook.SetEventType(wxEVT_CHAR_HOOK); + if ( wxGetTopLevelParent(GetWXPeer())->OSXHandleKeyEvent(eventHook) ) + return true; + } + bool result = GetWXPeer()->OSXHandleKeyEvent(wxevent); // this will fire higher level events, like insertText, to help -- 2.45.2