Process hotkeys in wxEVT_CHAR_HOOK rather than wxEVT_KEY_DOWN

Char hook events propagate by default, removing the need for the event
filter to make key down events propagate, which was causing some funny
issues.

On Windows, the char hook handler runs before menu accelerators, fixing
a bug where Default context hotkeys would override more specific ones
when they appeared on a menu. Unfortunately, this is not the case on
GTK, so the dumb accelerator-disabling hack is still required.

Originally committed to SVN as r6724.
This commit is contained in:
Thomas Goyne 2012-04-27 19:07:49 +00:00
parent 40b1fbaa1b
commit 123f02f0fb
15 changed files with 83 additions and 73 deletions

View File

@ -781,7 +781,7 @@ BEGIN_EVENT_TABLE(AudioDisplay, wxWindow)
EVT_SIZE(AudioDisplay::OnSize) EVT_SIZE(AudioDisplay::OnSize)
EVT_SET_FOCUS(AudioDisplay::OnFocus) EVT_SET_FOCUS(AudioDisplay::OnFocus)
EVT_KILL_FOCUS(AudioDisplay::OnFocus) EVT_KILL_FOCUS(AudioDisplay::OnFocus)
EVT_KEY_DOWN(AudioDisplay::OnKeyDown) EVT_CHAR_HOOK(AudioDisplay::OnKeyDown)
END_EVENT_TABLE() END_EVENT_TABLE()

View File

@ -150,6 +150,7 @@ BEGIN_EVENT_TABLE(BaseGrid,wxWindow)
EVT_COMMAND_SCROLL(GRID_SCROLLBAR,BaseGrid::OnScroll) EVT_COMMAND_SCROLL(GRID_SCROLLBAR,BaseGrid::OnScroll)
EVT_MOUSE_EVENTS(BaseGrid::OnMouseEvent) EVT_MOUSE_EVENTS(BaseGrid::OnMouseEvent)
EVT_KEY_DOWN(BaseGrid::OnKeyDown) EVT_KEY_DOWN(BaseGrid::OnKeyDown)
EVT_CHAR_HOOK(BaseGrid::OnCharHook)
EVT_MENU_RANGE(MENU_SHOW_COL,MENU_SHOW_COL+15,BaseGrid::OnShowColMenu) EVT_MENU_RANGE(MENU_SHOW_COL,MENU_SHOW_COL+15,BaseGrid::OnShowColMenu)
END_EVENT_TABLE() END_EVENT_TABLE()
@ -972,10 +973,24 @@ bool BaseGrid::IsDisplayed(const AssDialogue *line) const {
context->videoController->FrameAtTime(line->End,agi::vfr::END) >= frame; context->videoController->FrameAtTime(line->End,agi::vfr::END) >= frame;
} }
void BaseGrid::OnKeyDown(wxKeyEvent &event) { void BaseGrid::OnCharHook(wxKeyEvent &event) {
if (hotkey::check("Subtitle Grid", context, event)) if (hotkey::check("Subtitle Grid", context, event))
return; return;
int key = event.GetKeyCode();
if (key == WXK_UP || key == WXK_DOWN ||
key == WXK_PAGEUP || key == WXK_PAGEDOWN ||
key == WXK_HOME || key == WXK_END)
{
event.Skip();
return;
}
hotkey::check("Audio", context, event);
}
void BaseGrid::OnKeyDown(wxKeyEvent &event) {
int w,h; int w,h;
GetClientSize(&w,&h); GetClientSize(&w,&h);
@ -1005,48 +1020,46 @@ void BaseGrid::OnKeyDown(wxKeyEvent &event) {
step = GetRows(); step = GetRows();
} }
// Moving if (!dir) {
if (dir) { event.Skip();
event.Skip(false); return;
}
int old_extend = extendRow;
int next = mid(0, GetDialogueIndex(active_line) + dir * step, GetRows() - 1); int old_extend = extendRow;
SetActiveLine(GetDialogue(next)); int next = mid(0, GetDialogueIndex(active_line) + dir * step, GetRows() - 1);
SetActiveLine(GetDialogue(next));
// Move selection
if (!ctrl && !shift && !alt) { // Move selection
SelectRow(next); if (!ctrl && !shift && !alt) {
return; SelectRow(next);
} return;
}
// Move active only
if (alt && !shift && !ctrl) { // Move active only
Refresh(false); if (alt && !shift && !ctrl) {
return; Refresh(false);
} return;
}
// Shift-selection
if (shift && !ctrl && !alt) { // Shift-selection
extendRow = old_extend; if (shift && !ctrl && !alt) {
// Set range extendRow = old_extend;
int begin = next; // Set range
int end = extendRow; int begin = next;
if (end < begin) int end = extendRow;
std::swap(begin, end); if (end < begin)
std::swap(begin, end);
// Select range
Selection newsel; // Select range
for (int i = begin; i <= end; i++) Selection newsel;
newsel.insert(GetDialogue(i)); for (int i = begin; i <= end; i++)
newsel.insert(GetDialogue(i));
SetSelectedSet(newsel);
SetSelectedSet(newsel);
MakeCellVisible(extendRow, 0, false);
return; MakeCellVisible(extendRow, 0, false);
} return;
} }
else
hotkey::check("Audio", context, event);
} }
void BaseGrid::SetByFrame(bool state) { void BaseGrid::SetByFrame(bool state) {

View File

@ -103,6 +103,7 @@ class BaseGrid : public wxWindow, public BaseSelectionController<AssDialogue> {
void OnContextMenu(wxContextMenuEvent &evt); void OnContextMenu(wxContextMenuEvent &evt);
void OnHighlightVisibleChange(agi::OptionValue const& opt); void OnHighlightVisibleChange(agi::OptionValue const& opt);
void OnKeyDown(wxKeyEvent &event); void OnKeyDown(wxKeyEvent &event);
void OnCharHook(wxKeyEvent &event);
void OnMouseEvent(wxMouseEvent &event); void OnMouseEvent(wxMouseEvent &event);
void OnPaint(wxPaintEvent &event); void OnPaint(wxPaintEvent &event);
void OnScroll(wxScrollEvent &event); void OnScroll(wxScrollEvent &event);

View File

@ -94,7 +94,7 @@ DialogDetachedVideo::DialogDetachedVideo(agi::Context *context)
Bind(wxEVT_CLOSE_WINDOW, &DialogDetachedVideo::OnClose, this); Bind(wxEVT_CLOSE_WINDOW, &DialogDetachedVideo::OnClose, this);
Bind(wxEVT_ICONIZE, &DialogDetachedVideo::OnMinimize, this); Bind(wxEVT_ICONIZE, &DialogDetachedVideo::OnMinimize, this);
Bind(wxEVT_KEY_DOWN, &DialogDetachedVideo::OnKeyDown, this); Bind(wxEVT_CHAR_HOOK, &DialogDetachedVideo::OnKeyDown, this);
} }
DialogDetachedVideo::~DialogDetachedVideo() { } DialogDetachedVideo::~DialogDetachedVideo() { }

View File

@ -143,7 +143,8 @@ DialogStyling::DialogStyling(agi::Context *context)
c->selectionController->AddSelectionListener(this); c->selectionController->AddSelectionListener(this);
Bind(wxEVT_ACTIVATE, &DialogStyling::OnActivate, this); Bind(wxEVT_ACTIVATE, &DialogStyling::OnActivate, this);
Bind(wxEVT_KEY_DOWN, &DialogStyling::OnKeyDown, this); Bind(wxEVT_CHAR_HOOK, &DialogStyling::OnCharHook, this);
style_name->Bind(wxEVT_CHAR_HOOK, &DialogStyling::OnCharHook, this);
style_name->Bind(wxEVT_KEY_DOWN, &DialogStyling::OnKeyDown, this); style_name->Bind(wxEVT_KEY_DOWN, &DialogStyling::OnKeyDown, this);
play_video->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &DialogStyling::OnPlayVideoButton, this); play_video->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &DialogStyling::OnPlayVideoButton, this);
play_audio->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &DialogStyling::OnPlayAudioButton, this); play_audio->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &DialogStyling::OnPlayAudioButton, this);
@ -245,15 +246,17 @@ void DialogStyling::OnPlayAudioButton(wxCommandEvent &) {
style_name->SetFocus(); style_name->SetFocus();
} }
void DialogStyling::OnCharHook(wxKeyEvent &evt) {
hotkey::check("Styling Assistant", c, evt);
}
void DialogStyling::OnKeyDown(wxKeyEvent &evt) { void DialogStyling::OnKeyDown(wxKeyEvent &evt) {
if (!hotkey::check("Styling Assistant", c, evt)) { // Move the beginning of the selection back one character so that backspace
// Move the beginning of the selection back one character so that backspace // actually does something
// actually does something if (evt.GetKeyCode() == WXK_BACK && !evt.GetModifiers()) {
if (evt.GetKeyCode() == WXK_BACK && !evt.GetModifiers()) { long from, to;
long from, to; style_name->GetSelection(&from, &to);
style_name->GetSelection(&from, &to); if (from > 0)
if (from > 0) style_name->SetSelection(from - 1, to);
style_name->SetSelection(from - 1, to);
}
} }
} }

View File

@ -55,6 +55,7 @@ class DialogStyling : public wxDialog, public SelectionListener<AssDialogue> {
void OnActivate(wxActivateEvent &evt); void OnActivate(wxActivateEvent &evt);
void OnKeyDown(wxKeyEvent &evt); void OnKeyDown(wxKeyEvent &evt);
void OnCharHook(wxKeyEvent &evt);
void OnListClicked(wxCommandEvent &evt); void OnListClicked(wxCommandEvent &evt);
void OnListDoubleClicked(wxCommandEvent &evt); void OnListDoubleClicked(wxCommandEvent &evt);
void OnPlayAudioButton(wxCommandEvent &evt); void OnPlayAudioButton(wxCommandEvent &evt);

View File

@ -99,7 +99,7 @@ DialogTranslation::DialogTranslation(agi::Context *c)
translated_text->SetWrapMode(wxSTC_WRAP_WORD); translated_text->SetWrapMode(wxSTC_WRAP_WORD);
translated_text->SetMarginWidth(1, 0); translated_text->SetMarginWidth(1, 0);
translated_text->SetFocus(); translated_text->SetFocus();
translated_text->Bind(wxEVT_KEY_DOWN, &DialogTranslation::OnKeyDown, this); translated_text->Bind(wxEVT_CHAR_HOOK, &DialogTranslation::OnKeyDown, this);
wxSizer *translated_box = new wxStaticBoxSizer(wxVERTICAL, this, _("Translation")); wxSizer *translated_box = new wxStaticBoxSizer(wxVERTICAL, this, _("Translation"));
translated_box->Add(translated_text, 1, wxEXPAND, 0); translated_box->Add(translated_text, 1, wxEXPAND, 0);

View File

@ -574,7 +574,7 @@ BEGIN_EVENT_TABLE(FrameMain, wxFrame)
EVT_CLOSE(FrameMain::OnCloseWindow) EVT_CLOSE(FrameMain::OnCloseWindow)
EVT_KEY_DOWN(FrameMain::OnKeyDown) EVT_CHAR_HOOK(FrameMain::OnKeyDown)
EVT_MOUSEWHEEL(FrameMain::OnMouseWheel) EVT_MOUSEWHEEL(FrameMain::OnMouseWheel)
#ifdef __WXMAC__ #ifdef __WXMAC__

View File

@ -134,7 +134,6 @@ bool check(std::string const& context, agi::Context *c, int key_code, wchar_t ke
} }
bool check(std::string const& context, agi::Context *c, wxKeyEvent &evt) { bool check(std::string const& context, agi::Context *c, wxKeyEvent &evt) {
evt.StopPropagation();
if (!hotkey::check(context, c, evt.GetKeyCode(), evt.GetUnicodeKey(), evt.GetModifiers())) { if (!hotkey::check(context, c, evt.GetKeyCode(), evt.GetUnicodeKey(), evt.GetModifiers())) {
evt.Skip(); evt.Skip();
return false; return false;

View File

@ -508,12 +508,6 @@ int AegisubApp::OnRun() {
return 1; return 1;
} }
int AegisubApp::FilterEvent(wxEvent& event) {
if (event.GetEventType() == wxEVT_KEY_DOWN)
event.ResumePropagation(wxEVENT_PROPAGATE_MAX);
return -1 /* wxEventFilter::Event_Skip */;
}
//////////////// ////////////////
// Apple events // Apple events
#ifdef __WXMAC__ #ifdef __WXMAC__

View File

@ -112,10 +112,6 @@ class AegisubApp: public wxApp {
// our ticket to catch exceptions happening in event handlers. // our ticket to catch exceptions happening in event handlers.
void HandleEvent(wxEvtHandler *handler, wxEventFunction func, wxEvent& event) const; void HandleEvent(wxEvtHandler *handler, wxEventFunction func, wxEvent& event) const;
/// Top-level event filter to enable propagation of key events, which we
/// need for our hotkeys to work correctly
int FilterEvent(wxEvent& event);
public: public:
/// DOCME /// DOCME
AegisubLocale locale; AegisubLocale locale;

View File

@ -206,8 +206,8 @@ SubsEditBox::SubsEditBox(wxWindow *parent, agi::Context *context)
// Text editor // Text editor
TextEdit = new SubsTextEditCtrl(this, wxSize(300,50), wxBORDER_SUNKEN, c); TextEdit = new SubsTextEditCtrl(this, wxSize(300,50), wxBORDER_SUNKEN, c);
TextEdit->Bind(wxEVT_KEY_DOWN, &SubsEditBox::OnKeyDown, this); TextEdit->Bind(wxEVT_CHAR_HOOK, &SubsEditBox::OnKeyDown, this);
Bind(wxEVT_KEY_DOWN, &SubsEditBox::OnKeyDown, this); Bind(wxEVT_CHAR_HOOK, &SubsEditBox::OnKeyDown, this);
BottomSizer = new wxBoxSizer(wxHORIZONTAL); BottomSizer = new wxBoxSizer(wxHORIZONTAL);
BottomSizer->Add(TextEdit,1,wxEXPAND,0); BottomSizer->Add(TextEdit,1,wxEXPAND,0);

View File

@ -121,7 +121,7 @@ VideoDisplay::VideoDisplay(
Bind(wxEVT_SIZE, &VideoDisplay::OnSizeEvent, this); Bind(wxEVT_SIZE, &VideoDisplay::OnSizeEvent, this);
Bind(wxEVT_CONTEXT_MENU, &VideoDisplay::OnContextMenu, this); Bind(wxEVT_CONTEXT_MENU, &VideoDisplay::OnContextMenu, this);
Bind(wxEVT_ENTER_WINDOW, &VideoDisplay::OnMouseEvent, this); Bind(wxEVT_ENTER_WINDOW, &VideoDisplay::OnMouseEvent, this);
Bind(wxEVT_KEY_DOWN, &VideoDisplay::OnKeyDown, this); Bind(wxEVT_CHAR_HOOK, &VideoDisplay::OnKeyDown, this);
Bind(wxEVT_LEAVE_WINDOW, &VideoDisplay::OnMouseLeave, this); Bind(wxEVT_LEAVE_WINDOW, &VideoDisplay::OnMouseLeave, this);
Bind(wxEVT_LEFT_DCLICK, &VideoDisplay::OnMouseEvent, this); Bind(wxEVT_LEFT_DCLICK, &VideoDisplay::OnMouseEvent, this);
Bind(wxEVT_LEFT_DOWN, &VideoDisplay::OnMouseEvent, this); Bind(wxEVT_LEFT_DOWN, &VideoDisplay::OnMouseEvent, this);

View File

@ -106,6 +106,7 @@ int VideoSlider::GetXAtValue(int value) {
BEGIN_EVENT_TABLE(VideoSlider, wxWindow) BEGIN_EVENT_TABLE(VideoSlider, wxWindow)
EVT_MOUSE_EVENTS(VideoSlider::OnMouse) EVT_MOUSE_EVENTS(VideoSlider::OnMouse)
EVT_KEY_DOWN(VideoSlider::OnKeyDown) EVT_KEY_DOWN(VideoSlider::OnKeyDown)
EVT_CHAR_HOOK(VideoSlider::OnCharHook)
EVT_PAINT(VideoSlider::OnPaint) EVT_PAINT(VideoSlider::OnPaint)
EVT_SET_FOCUS(VideoSlider::OnFocus) EVT_SET_FOCUS(VideoSlider::OnFocus)
EVT_KILL_FOCUS(VideoSlider::OnFocus) EVT_KILL_FOCUS(VideoSlider::OnFocus)
@ -148,10 +149,11 @@ void VideoSlider::OnMouse(wxMouseEvent &event) {
} }
} }
void VideoSlider::OnKeyDown(wxKeyEvent &event) { void VideoSlider::OnCharHook(wxKeyEvent &event) {
if (hotkey::check("Video", c, event)) hotkey::check("Video", c, event);
return; }
void VideoSlider::OnKeyDown(wxKeyEvent &event) {
// Forward up/down to grid as those aren't yet handled by commands // Forward up/down to grid as those aren't yet handled by commands
if (event.GetKeyCode() == WXK_UP || event.GetKeyCode() == WXK_DOWN) { if (event.GetKeyCode() == WXK_UP || event.GetKeyCode() == WXK_DOWN) {
c->subsGrid->GetEventHandler()->ProcessEvent(event); c->subsGrid->GetEventHandler()->ProcessEvent(event);

View File

@ -70,6 +70,7 @@ class VideoSlider: public wxWindow {
void OnMouse(wxMouseEvent &event); void OnMouse(wxMouseEvent &event);
void OnKeyDown(wxKeyEvent &event); void OnKeyDown(wxKeyEvent &event);
void OnCharHook(wxKeyEvent &event);
void OnPaint(wxPaintEvent &); void OnPaint(wxPaintEvent &);
void OnFocus(wxFocusEvent &); void OnFocus(wxFocusEvent &);