From 59291ede879e339ac40c3dec0a16ddfa8de486b7 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Tue, 16 Sep 2014 12:42:39 -0400 Subject: [PATCH] add a focus handling callback so that all button press events on CairoWidgets will cause a focus reset. Conflicts: libs/gtkmm2ext/cairo_widget.cc libs/gtkmm2ext/gtkmm2ext/cairo_widget.h --- libs/gtkmm2ext/cairo_widget.cc | 17 +++++++++++++++++ libs/gtkmm2ext/gtkmm2ext/cairo_widget.h | 21 +++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/libs/gtkmm2ext/cairo_widget.cc b/libs/gtkmm2ext/cairo_widget.cc index d600052bad..0b7fdad306 100644 --- a/libs/gtkmm2ext/cairo_widget.cc +++ b/libs/gtkmm2ext/cairo_widget.cc @@ -24,6 +24,10 @@ static const char* has_cairo_widget_background_info = "has_cairo_widget_background_info"; + +static void noop() { } +sigc::slot CairoWidget::focus_handler (sigc::ptr_fun (noop)); + CairoWidget::CairoWidget () : _active_state (Gtkmm2ext::Off) , _visual_state (Gtkmm2ext::NoVisualState) @@ -38,6 +42,13 @@ CairoWidget::~CairoWidget () { } +bool +CairoWidget::on_button_press_event (GdkEventButton*) +{ + focus_handler(); + return false; +} + bool CairoWidget::on_expose_event (GdkEventExpose *ev) { @@ -194,3 +205,9 @@ CairoWidget::provide_background_for_cairo_widget (Gtk::Widget& w, const Gdk::Col g_object_set_data (G_OBJECT(w.gobj()), has_cairo_widget_background_info, (void*) 0xfeedface); } + +void +CairoWidget::set_focus_handler (sigc::slot s) +{ + focus_handler = s; +} diff --git a/libs/gtkmm2ext/gtkmm2ext/cairo_widget.h b/libs/gtkmm2ext/gtkmm2ext/cairo_widget.h index 35e353054a..a82c12fd70 100644 --- a/libs/gtkmm2ext/gtkmm2ext/cairo_widget.h +++ b/libs/gtkmm2ext/gtkmm2ext/cairo_widget.h @@ -69,11 +69,30 @@ public: virtual void render (cairo_t *, cairo_rectangle_t*) = 0; + /* set_focus_handler() will cause all button-press events on any + CairoWidget to invoke this slot/functor/function/method/callback. + + We do this because in general, CairoWidgets do not grab + keyboard focus, but a button press on them should + clear focus from any active text entry. + + This is global to all CairoWidgets and derived types. + + However, derived types can override the behaviour by defining their + own on_button_press_event() handler which returns true under all + conditions (which will block this handler from being called). If + 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); + protected: /** Render the widget to the given Cairo context */ virtual bool on_expose_event (GdkEventExpose *); void on_size_allocate (Gtk::Allocation &); void on_state_changed (Gtk::StateType); + bool on_button_press_event (GdkEventButton*); + Gdk::Color get_parent_bg (); /* this is an additional virtual "on_..." method. Glibmm does not @@ -87,6 +106,8 @@ protected: bool _need_bg; GdkEventExpose* _current_event_expose; // Valid only when on_expose_event + static sigc::slot focus_handler; + private: Glib::SignalProxyProperty _name_proxy; };