Window focus handling fixes.

Many windows were not getting key events.
Use magic focus infrastructure (built for widgets) to deliver key events
via window focus in/out.
This commit is contained in:
nick_m 2015-04-02 02:41:49 +11:00
parent 9a4827374c
commit 35f69656e8
11 changed files with 91 additions and 52 deletions

View file

@ -64,31 +64,37 @@ ArdourDialog::~ArdourDialog ()
}
bool
ArdourDialog::on_key_press_event (GdkEventKey* ev)
ArdourDialog::on_focus_in_event (GdkEventFocus *ev)
{
if (!relay_key_press (ev, this)) {
return Gtk::Window::on_key_press_event(ev);
if (Keyboard::some_magic_widget_has_focus()) {
Keyboard::magic_widget_drop_focus ();
}
return true;
Keyboard::the_keyboard().focus_in_window (ev, this);
Keyboard::magic_widget_grab_focus ();
return Dialog::on_focus_in_event (ev);
}
bool
ArdourDialog::on_enter_notify_event (GdkEventCrossing *ev)
ArdourDialog::on_focus_out_event (GdkEventFocus *ev)
{
Keyboard::the_keyboard().enter_window (ev, this);
return Dialog::on_enter_notify_event (ev);
if (!get_modal()) {
Keyboard::magic_widget_drop_focus ();
Keyboard::the_keyboard().focus_out_window (ev, this);
}
bool
ArdourDialog::on_leave_notify_event (GdkEventCrossing *ev)
{
Keyboard::the_keyboard().leave_window (ev, this);
return Dialog::on_leave_notify_event (ev);
return Dialog::on_focus_out_event (ev);
}
void
ArdourDialog::on_unmap ()
{
if (Keyboard::some_magic_widget_has_focus()) {
Gtk::Window* win = static_cast<Gtk::Window*>(get_focus()->get_toplevel());
if (win == Keyboard::get_current_window()) {
Keyboard::magic_widget_drop_focus ();
}
}
Keyboard::the_keyboard().leave_window (0, this);
Dialog::on_unmap ();
}
@ -119,7 +125,7 @@ void
ArdourDialog::init ()
{
set_border_width (10);
add_events (Gdk::FOCUS_CHANGE_MASK);
set_type_hint (Gdk::WINDOW_TYPE_HINT_DIALOG);
Gtk::Window* parent = WM::Manager::instance().transient_parent();

View file

@ -42,10 +42,9 @@ class ArdourDialog : public Gtk::Dialog, public ARDOUR::SessionHandlePtr
ArdourDialog (Gtk::Window& parent, std::string title, bool modal = false, bool use_separator = false);
~ArdourDialog();
bool on_enter_notify_event (GdkEventCrossing*);
bool on_leave_notify_event (GdkEventCrossing*);
bool on_focus_in_event (GdkEventFocus*);
bool on_focus_out_event (GdkEventFocus*);
bool on_delete_event (GdkEventAny*);
bool on_key_press_event (GdkEventKey*);
void on_unmap ();
void on_show ();

View file

@ -2623,10 +2623,8 @@ ARDOUR_UI::edit_metadata ()
{
SessionMetadataEditor dialog;
dialog.set_session (_session);
Keyboard::magic_widget_grab_focus ();
dialog.grab_focus ();
dialog.run ();
Keyboard::magic_widget_drop_focus ();
}
void

View file

@ -58,26 +58,48 @@ ArdourWindow::~ArdourWindow ()
bool
ArdourWindow::on_key_press_event (GdkEventKey* ev)
{
return relay_key_press (ev, this);
if (get_modal()) {
return Gtk::Window::on_key_press_event (ev);
}
if (!relay_key_press (ev, this)) {
return Gtk::Window::on_key_press_event (ev);
}
return true;
}
bool
ArdourWindow::on_enter_notify_event (GdkEventCrossing *ev)
ArdourWindow::on_focus_in_event (GdkEventFocus *ev)
{
Keyboard::the_keyboard().enter_window (ev, this);
return Window::on_enter_notify_event (ev);
if (Keyboard::some_magic_widget_has_focus()) {
Keyboard::magic_widget_drop_focus ();
}
Keyboard::the_keyboard().focus_in_window (ev, this);
Keyboard::magic_widget_grab_focus ();
return Window::on_focus_in_event (ev);
}
bool
ArdourWindow::on_leave_notify_event (GdkEventCrossing *ev)
ArdourWindow::on_focus_out_event (GdkEventFocus *ev)
{
Keyboard::the_keyboard().leave_window (ev, this);
return Window::on_leave_notify_event (ev);
if (!get_modal()) {
Keyboard::magic_widget_drop_focus ();
Keyboard::the_keyboard().focus_out_window (ev, this);
}
return Window::on_focus_out_event (ev);
}
void
ArdourWindow::on_unmap ()
{
if (Keyboard::some_magic_widget_has_focus()) {
Gtk::Window* win = static_cast<Gtk::Window*>(get_focus()->get_toplevel());
if (win == Keyboard::get_current_window()) {
Keyboard::magic_widget_drop_focus ();
}
}
Keyboard::the_keyboard().leave_window (0, this);
Window::on_unmap ();
}
@ -92,6 +114,7 @@ void
ArdourWindow::init ()
{
set_border_width (10);
add_events (Gdk::FOCUS_CHANGE_MASK);
/* ArdourWindows are not dialogs (they have no "OK" or "Close" button) but
they should be considered part of the same "window level" as a dialog. This

View file

@ -44,8 +44,8 @@ class ArdourWindow : public Gtk::Window, public ARDOUR::SessionHandlePtr, public
ArdourWindow (Gtk::Window& parent, std::string title);
~ArdourWindow();
bool on_enter_notify_event (GdkEventCrossing*);
bool on_leave_notify_event (GdkEventCrossing*);
bool on_focus_in_event (GdkEventFocus*);
bool on_focus_out_event (GdkEventFocus*);
bool on_delete_event (GdkEventAny *);
bool on_key_press_event (GdkEventKey*);
void on_unmap ();

View file

@ -536,22 +536,6 @@ ExportVideoDialog::on_show ()
Dialog::on_show ();
}
bool
ExportVideoDialog::on_focus_in_event (GdkEventFocus *ev)
{
Dialog::on_focus_in_event (ev);
Gtkmm2ext::Keyboard::magic_widget_grab_focus ();
return true;
}
bool
ExportVideoDialog::on_focus_out_event (GdkEventFocus *ev)
{
Dialog::on_focus_out_event (ev);
Gtkmm2ext::Keyboard::magic_widget_drop_focus ();
return true;
}
void
ExportVideoDialog::abort_clicked ()
{

View file

@ -64,9 +64,6 @@ class ExportVideoDialog : public ArdourDialog , public PBD::ScopedConnectionList
void set_original_file_information ();
bool on_focus_in_event (GdkEventFocus*);
bool on_focus_out_event (GdkEventFocus*);
void open_outfn_dialog ();
void open_invid_dialog ();
void scale_checkbox_toggled ();

View file

@ -184,7 +184,7 @@ KeyEditor::on_key_press_event (GdkEventKey* ev)
if (!ev->is_modifier) {
last_keyval = ev->keyval;
}
return false;
return ArdourWindow::on_key_press_event (ev);
}
bool

View file

@ -357,7 +357,10 @@ PluginUIWindow::on_key_press_event (GdkEventKey* event)
if (_pluginui->non_gtk_gui()) {
_pluginui->forward_key_event (event);
} else {
return relay_key_press (event, this);
if (!relay_key_press (event, this)) {
return Window::on_key_press_event (event);
}
return true;
}
}
return true;
@ -376,7 +379,10 @@ PluginUIWindow::on_key_press_event (GdkEventKey* event)
*/
return relay_key_press (event, &PublicEditor::instance());
} else {
return relay_key_press (event, this);
if (!relay_key_press (event, this)) {
return Window::on_key_press_event (event);
}
return true;
}
} else {
return false;

View file

@ -106,6 +106,8 @@ class LIBGTKMM2EXT_API Keyboard : public sigc::trackable, PBD::Stateful
bool leave_window (GdkEventCrossing *ev, Gtk::Window*);
bool enter_window (GdkEventCrossing *ev, Gtk::Window*);
bool focus_in_window (GdkEventFocus *ev, Gtk::Window*);
bool focus_out_window (GdkEventFocus *ev, Gtk::Window*);
static bool modifier_state_contains (guint state, ModifierMask);
static bool modifier_state_equals (guint state, ModifierMask);
@ -146,6 +148,7 @@ class LIBGTKMM2EXT_API Keyboard : public sigc::trackable, PBD::Stateful
static bool some_magic_widget_has_focus ();
static void magic_widget_grab_focus ();
static void magic_widget_drop_focus ();
static Gtk::Window* get_current_window () { return current_window; };
static void close_current_dialog ();

View file

@ -384,6 +384,29 @@ Keyboard::leave_window (GdkEventCrossing *ev, Gtk::Window* /*win*/)
return false;
}
bool
Keyboard::focus_in_window (GdkEventFocus *, Gtk::Window* win)
{
current_window = win;
DEBUG_TRACE (DEBUG::Keyboard, string_compose ("Focusing in window, title = %1\n", win->get_title()));
return false;
}
bool
Keyboard::focus_out_window (GdkEventFocus * ev, Gtk::Window* win)
{
if (ev) {
state.clear ();
current_window = 0;
} else {
current_window = 0;
}
DEBUG_TRACE (DEBUG::Keyboard, string_compose ("Foucusing out window, title = %1\n", win->get_title()));
return false;
}
void
Keyboard::set_edit_button (guint but)
{