summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2016-03-15 12:34:26 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2016-03-15 12:41:21 -0400
commit9a11e3a64d485f2e9ae2bb2dd6409eb1c87f99d0 (patch)
tree34a6bccac86400f74d58f7f4c9eb12e05771b50f
parenta8f242f80a980698f82d6ac6692e46e5373893c6 (diff)
change API for CairoWidget::focus_handler
This functor/closure is responsible for stealing focus from any existing text entry (or whatever else may have focus) when clicking on a CairoWidget or derived class. The old implementation just gave focus back to the editor canvas. The new version walks up the widget packing heirarchy to find a focusable parent (from the CairoWidget for which it is invoked). If no focusable parent is found, it cancels keyboard focus in the toplevel window containing the CairoWidget
-rw-r--r--gtk2_ardour/ardour_button.cc2
-rw-r--r--gtk2_ardour/big_clock_window.cc3
-rw-r--r--gtk2_ardour/editor.cc2
-rw-r--r--gtk2_ardour/editor.h2
-rw-r--r--gtk2_ardour/editor_actions.cc35
-rw-r--r--gtk2_ardour/editor_mouse.cc2
-rw-r--r--gtk2_ardour/public_editor.h2
-rw-r--r--libs/gtkmm2ext/cairo_widget.cc6
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/cairo_widget.h4
9 files changed, 44 insertions, 14 deletions
diff --git a/gtk2_ardour/ardour_button.cc b/gtk2_ardour/ardour_button.cc
index a4f346a040..2d020595ab 100644
--- a/gtk2_ardour/ardour_button.cc
+++ b/gtk2_ardour/ardour_button.cc
@@ -724,7 +724,7 @@ ArdourButton::set_led_left (bool yn)
bool
ArdourButton::on_button_press_event (GdkEventButton *ev)
{
- focus_handler ();
+ focus_handler (this);
if (ev->button == 1 && (_elements & Indicator) && _led_rect && _distinct_led_click) {
if (ev->x >= _led_rect->x && ev->x < _led_rect->x + _led_rect->width &&
diff --git a/gtk2_ardour/big_clock_window.cc b/gtk2_ardour/big_clock_window.cc
index e442c5455b..56fe34feac 100644
--- a/gtk2_ardour/big_clock_window.cc
+++ b/gtk2_ardour/big_clock_window.cc
@@ -55,8 +55,7 @@ void
BigClockWindow::on_unmap ()
{
ArdourWindow::on_unmap ();
-
- PublicEditor::instance().reset_focus ();
+ PublicEditor::instance().reset_focus (&clock);
}
bool
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc
index a118d1d642..1df263496b 100644
--- a/gtk2_ardour/editor.cc
+++ b/gtk2_ardour/editor.cc
@@ -1178,7 +1178,7 @@ Editor::generic_event_handler (GdkEvent* ev)
/* leaving window, so reset focus, thus ending any and
all text entry operations.
*/
- reset_focus();
+ reset_focus (&contents());
break;
}
break;
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index 1d11dd282d..5778a3cbbb 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -1274,7 +1274,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void naturalize_region ();
- void reset_focus ();
+ void reset_focus (Gtk::Widget*);
void split_region ();
diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc
index 008a4d75dc..280bc3f9cb 100644
--- a/gtk2_ardour/editor_actions.cc
+++ b/gtk2_ardour/editor_actions.cc
@@ -1739,9 +1739,40 @@ Editor::parameter_changed (std::string p)
}
void
-Editor::reset_focus ()
+Editor::reset_focus (Gtk::Widget* w)
{
- _track_canvas->grab_focus();
+ /* this resets focus to the first focusable parent of the given widget,
+ * or, if there is no focusable parent, cancels focus in the toplevel
+ * window that the given widget is packed into (if there is one).
+ */
+
+ if (!w) {
+ return;
+ }
+
+ Gtk::Widget* top = w->get_toplevel();
+
+ if (!top || !top->is_toplevel()) {
+ return;
+ }
+
+ w = w->get_parent ();
+
+ while (w) {
+ if (w->get_can_focus ()) {
+ Window* win = dynamic_cast<Window*> (top);
+ win->set_focus (*w);
+ return;
+ }
+ w = w->get_parent ();
+ }
+
+ /* no focusable parent found, cancel focus in top level window.
+ C++ API cannot be used for this. Thanks, references.
+ */
+
+ gtk_window_set_focus (GTK_WINDOW(top->gobj()), 0);
+
}
void
diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc
index 48d838a1db..a1a7b793b6 100644
--- a/gtk2_ardour/editor_mouse.cc
+++ b/gtk2_ardour/editor_mouse.cc
@@ -2456,7 +2456,7 @@ Editor::escape ()
selection->clear ();
}
- reset_focus ();
+ reset_focus (&contents());
}
/** Update _join_object_range_state which indicate whether we are over the top
diff --git a/gtk2_ardour/public_editor.h b/gtk2_ardour/public_editor.h
index df6bba3a06..45fbb9ece9 100644
--- a/gtk2_ardour/public_editor.h
+++ b/gtk2_ardour/public_editor.h
@@ -319,7 +319,7 @@ class PublicEditor : public Gtkmm2ext::Tabbable {
Glib::RefPtr<Gtk::ActionGroup> editor_menu_actions;
Glib::RefPtr<Gtk::ActionGroup> _region_actions;
- virtual void reset_focus () = 0;
+ virtual void reset_focus (Gtk::Widget*) = 0;
virtual bool canvas_scroll_event (GdkEventScroll* event, bool from_canvas) = 0;
virtual bool canvas_control_point_event (GdkEvent* event, ArdourCanvas::Item*, ControlPoint*) = 0;
diff --git a/libs/gtkmm2ext/cairo_widget.cc b/libs/gtkmm2ext/cairo_widget.cc
index 78fb042f59..fe93f1eb7c 100644
--- a/libs/gtkmm2ext/cairo_widget.cc
+++ b/libs/gtkmm2ext/cairo_widget.cc
@@ -30,7 +30,7 @@ static const char* has_cairo_widget_background_info = "has_cairo_widget_backgrou
bool CairoWidget::_flat_buttons = false;
bool CairoWidget::_widget_prelight = true;
-sigc::slot<void> CairoWidget::focus_handler;
+sigc::slot<void,Gtk::Widget*> CairoWidget::focus_handler;
void CairoWidget::set_source_rgb_a( cairo_t* cr, Gdk::Color col, float a) //ToDo: this one and the Canvas version should be in a shared file (?)
{
@@ -60,7 +60,7 @@ CairoWidget::~CairoWidget ()
bool
CairoWidget::on_button_press_event (GdkEventButton*)
{
- focus_handler();
+ focus_handler (this);
return false;
}
@@ -393,7 +393,7 @@ CairoWidget::set_widget_prelight (bool yn)
}
void
-CairoWidget::set_focus_handler (sigc::slot<void> s)
+CairoWidget::set_focus_handler (sigc::slot<void,Gtk::Widget*> s)
{
focus_handler = s;
}
diff --git a/libs/gtkmm2ext/gtkmm2ext/cairo_widget.h b/libs/gtkmm2ext/gtkmm2ext/cairo_widget.h
index 2a483840f9..2588adcdcc 100644
--- a/libs/gtkmm2ext/gtkmm2ext/cairo_widget.h
+++ b/libs/gtkmm2ext/gtkmm2ext/cairo_widget.h
@@ -93,7 +93,7 @@ public:
they wish to invoke any existing focus handler from their own
button press handler, they can just use: focus_handler();
*/
- static void set_focus_handler (sigc::slot<void>);
+ static void set_focus_handler (sigc::slot<void,Gtk::Widget*>);
protected:
/** Render the widget to the given Cairo context */
@@ -118,7 +118,7 @@ protected:
static bool _widget_prelight;
bool _grabbed;
- static sigc::slot<void> focus_handler;
+ static sigc::slot<void,Gtk::Widget*> focus_handler;
private:
Cairo::RefPtr<Cairo::Surface> image_surface;