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:
parent
40b1fbaa1b
commit
123f02f0fb
15 changed files with 83 additions and 73 deletions
|
@ -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()
|
||||
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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() { }
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 &);
|
||||
|
||||
|
|
Loading…
Reference in a new issue