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_SET_FOCUS(AudioDisplay::OnFocus)
EVT_KILL_FOCUS(AudioDisplay::OnFocus)
EVT_KEY_DOWN(AudioDisplay::OnKeyDown)
EVT_CHAR_HOOK(AudioDisplay::OnKeyDown)
END_EVENT_TABLE()

View file

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

View file

@ -103,6 +103,7 @@ class BaseGrid : public wxWindow, public BaseSelectionController<AssDialogue> {
void OnContextMenu(wxContextMenuEvent &evt);
void OnHighlightVisibleChange(agi::OptionValue const& opt);
void OnKeyDown(wxKeyEvent &event);
void OnCharHook(wxKeyEvent &event);
void OnMouseEvent(wxMouseEvent &event);
void OnPaint(wxPaintEvent &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_ICONIZE, &DialogDetachedVideo::OnMinimize, this);
Bind(wxEVT_KEY_DOWN, &DialogDetachedVideo::OnKeyDown, this);
Bind(wxEVT_CHAR_HOOK, &DialogDetachedVideo::OnKeyDown, this);
}
DialogDetachedVideo::~DialogDetachedVideo() { }

View file

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

View file

@ -55,6 +55,7 @@ class DialogStyling : public wxDialog, public SelectionListener<AssDialogue> {
void OnActivate(wxActivateEvent &evt);
void OnKeyDown(wxKeyEvent &evt);
void OnCharHook(wxKeyEvent &evt);
void OnListClicked(wxCommandEvent &evt);
void OnListDoubleClicked(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->SetMarginWidth(1, 0);
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"));
translated_box->Add(translated_text, 1, wxEXPAND, 0);

View file

@ -574,7 +574,7 @@ BEGIN_EVENT_TABLE(FrameMain, wxFrame)
EVT_CLOSE(FrameMain::OnCloseWindow)
EVT_KEY_DOWN(FrameMain::OnKeyDown)
EVT_CHAR_HOOK(FrameMain::OnKeyDown)
EVT_MOUSEWHEEL(FrameMain::OnMouseWheel)
#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) {
evt.StopPropagation();
if (!hotkey::check(context, c, evt.GetKeyCode(), evt.GetUnicodeKey(), evt.GetModifiers())) {
evt.Skip();
return false;

View file

@ -508,12 +508,6 @@ int AegisubApp::OnRun() {
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
#ifdef __WXMAC__

View file

@ -112,10 +112,6 @@ class AegisubApp: public wxApp {
// our ticket to catch exceptions happening in event handlers.
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:
/// DOCME
AegisubLocale locale;

View file

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

View file

@ -121,7 +121,7 @@ VideoDisplay::VideoDisplay(
Bind(wxEVT_SIZE, &VideoDisplay::OnSizeEvent, this);
Bind(wxEVT_CONTEXT_MENU, &VideoDisplay::OnContextMenu, 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_LEFT_DCLICK, &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)
EVT_MOUSE_EVENTS(VideoSlider::OnMouse)
EVT_KEY_DOWN(VideoSlider::OnKeyDown)
EVT_CHAR_HOOK(VideoSlider::OnCharHook)
EVT_PAINT(VideoSlider::OnPaint)
EVT_SET_FOCUS(VideoSlider::OnFocus)
EVT_KILL_FOCUS(VideoSlider::OnFocus)
@ -148,10 +149,11 @@ void VideoSlider::OnMouse(wxMouseEvent &event) {
}
}
void VideoSlider::OnKeyDown(wxKeyEvent &event) {
if (hotkey::check("Video", c, event))
return;
void VideoSlider::OnCharHook(wxKeyEvent &event) {
hotkey::check("Video", c, event);
}
void VideoSlider::OnKeyDown(wxKeyEvent &event) {
// Forward up/down to grid as those aren't yet handled by commands
if (event.GetKeyCode() == WXK_UP || event.GetKeyCode() == WXK_DOWN) {
c->subsGrid->GetEventHandler()->ProcessEvent(event);

View file

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