summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornick_m <mainsbridge@gmail.com>2015-04-02 02:41:49 +1100
committernick_m <mainsbridge@gmail.com>2015-04-02 02:41:49 +1100
commit35f69656e859cdd00ce28e29083788a91d3fbd5f (patch)
treeb53ca99b60eff69381ffc85a6011d56aea412535
parent9a4827374ca4e4c310d02adf65c727d92b56724c (diff)
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.
-rw-r--r--gtk2_ardour/ardour_dialog.cc34
-rw-r--r--gtk2_ardour/ardour_dialog.h5
-rw-r--r--gtk2_ardour/ardour_ui.cc2
-rw-r--r--gtk2_ardour/ardour_window.cc39
-rw-r--r--gtk2_ardour/ardour_window.h4
-rw-r--r--gtk2_ardour/export_video_dialog.cc16
-rw-r--r--gtk2_ardour/export_video_dialog.h3
-rw-r--r--gtk2_ardour/keyeditor.cc2
-rw-r--r--gtk2_ardour/plugin_ui.cc10
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/keyboard.h3
-rw-r--r--libs/gtkmm2ext/keyboard.cc23
11 files changed, 90 insertions, 51 deletions
diff --git a/gtk2_ardour/ardour_dialog.cc b/gtk2_ardour/ardour_dialog.cc
index 37327b2c91..423cab0a30 100644
--- a/gtk2_ardour/ardour_dialog.cc
+++ b/gtk2_ardour/ardour_dialog.cc
@@ -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;
-}
-bool
-ArdourDialog::on_enter_notify_event (GdkEventCrossing *ev)
-{
- Keyboard::the_keyboard().enter_window (ev, this);
- return Dialog::on_enter_notify_event (ev);
+ Keyboard::the_keyboard().focus_in_window (ev, this);
+ Keyboard::magic_widget_grab_focus ();
+ return Dialog::on_focus_in_event (ev);
}
bool
-ArdourDialog::on_leave_notify_event (GdkEventCrossing *ev)
+ArdourDialog::on_focus_out_event (GdkEventFocus *ev)
{
- Keyboard::the_keyboard().leave_window (ev, this);
- return Dialog::on_leave_notify_event (ev);
+ if (!get_modal()) {
+ Keyboard::magic_widget_drop_focus ();
+ Keyboard::the_keyboard().focus_out_window (ev, this);
+ }
+ 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();
diff --git a/gtk2_ardour/ardour_dialog.h b/gtk2_ardour/ardour_dialog.h
index d994c0a6d1..1224cbb00a 100644
--- a/gtk2_ardour/ardour_dialog.h
+++ b/gtk2_ardour/ardour_dialog.h
@@ -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 ();
diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc
index 5d1da0dfcd..4d38d71c85 100644
--- a/gtk2_ardour/ardour_ui.cc
+++ b/gtk2_ardour/ardour_ui.cc
@@ -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
diff --git a/gtk2_ardour/ardour_window.cc b/gtk2_ardour/ardour_window.cc
index 3bc80dfc46..fc3ec84b0e 100644
--- a/gtk2_ardour/ardour_window.cc
+++ b/gtk2_ardour/ardour_window.cc
@@ -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,8 +114,9 @@ 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
+ /* 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
works on X11 and Quartz, in that:
diff --git a/gtk2_ardour/ardour_window.h b/gtk2_ardour/ardour_window.h
index c90eb3c049..7ae9c3dbce 100644
--- a/gtk2_ardour/ardour_window.h
+++ b/gtk2_ardour/ardour_window.h
@@ -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 ();
diff --git a/gtk2_ardour/export_video_dialog.cc b/gtk2_ardour/export_video_dialog.cc
index 7e01f5b9ad..e8b823dc90 100644
--- a/gtk2_ardour/export_video_dialog.cc
+++ b/gtk2_ardour/export_video_dialog.cc
@@ -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 ()
{
diff --git a/gtk2_ardour/export_video_dialog.h b/gtk2_ardour/export_video_dialog.h
index ab6f3223e9..93fe7fb5c2 100644
--- a/gtk2_ardour/export_video_dialog.h
+++ b/gtk2_ardour/export_video_dialog.h
@@ -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 ();
diff --git a/gtk2_ardour/keyeditor.cc b/gtk2_ardour/keyeditor.cc
index f8b5f2da4e..28cd8b8508 100644
--- a/gtk2_ardour/keyeditor.cc
+++ b/gtk2_ardour/keyeditor.cc
@@ -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
diff --git a/gtk2_ardour/plugin_ui.cc b/gtk2_ardour/plugin_ui.cc
index ea9dfaec75..9f22d1b54c 100644
--- a/gtk2_ardour/plugin_ui.cc
+++ b/gtk2_ardour/plugin_ui.cc
@@ -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;
diff --git a/libs/gtkmm2ext/gtkmm2ext/keyboard.h b/libs/gtkmm2ext/gtkmm2ext/keyboard.h
index d756c6199e..328638373f 100644
--- a/libs/gtkmm2ext/gtkmm2ext/keyboard.h
+++ b/libs/gtkmm2ext/gtkmm2ext/keyboard.h
@@ -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 ();
diff --git a/libs/gtkmm2ext/keyboard.cc b/libs/gtkmm2ext/keyboard.cc
index 48fcae8482..420d42209b 100644
--- a/libs/gtkmm2ext/keyboard.cc
+++ b/libs/gtkmm2ext/keyboard.cc
@@ -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)
{