From 9801bb7839ae30cf448c40385610a72d758c2a73 Mon Sep 17 00:00:00 2001 From: Albrecht Schlosser Date: Sat, 27 Jun 2015 14:13:57 +0000 Subject: Prevent sending (FL_SHORTCUT) events to inactive widgets (STR #3216). git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@10774 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 --- src/Fl.cxx | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Fl.cxx b/src/Fl.cxx index 379c4ced8..c6879c72c 100644 --- a/src/Fl.cxx +++ b/src/Fl.cxx @@ -1133,6 +1133,37 @@ void fl_throw_focus(Fl_Widget *o) { //////////////////////////////////////////////////////////////// +// Find the first active_r() widget, starting at the widget wi and +// walking up the widget hierarchy to the top level window. +// +// In other words: find_active() returns an active group that contains +// the inactive widget and all inactive parent groups. +// +// This is used to send FL_SHORTCUT events to the Fl::belowmouse() widget +// in case the target widget itself is inactive_r(). In this case the event +// is sent to the first active_r() parent. +// +// This prevents sending events to inactive widgets that might get the +// input focus otherwise. The search is fast and light and avoids calling +// inactive_r() multiple times. +// See STR #3216. +// +// Returns: first active_r() widget "above" the widget wi or NULL if +// no widget is active. May return the top level window. + +static Fl_Widget *find_active(Fl_Widget *wi) { + Fl_Widget *found = 0; + for (; wi; wi = wi->parent()) { + if (wi->active()) { + if (!found) found = wi; + } + else found = 0; + } + return found; +} + +//////////////////////////////////////////////////////////////// + // Call to->handle(), but first replace the mouse x/y with the correct // values to account for nested windows. 'window' is the outermost // window the event was posted to by the system: @@ -1398,7 +1429,7 @@ int Fl::handle_(int e, Fl_Window* window) if (grab()) {wi = grab(); break;} // send it to grab window // Try it as shortcut, sending to mouse widget and all parents: - wi = belowmouse(); + wi = find_active(belowmouse()); // STR #3216 if (!wi) { wi = modal(); if (!wi) wi = window; -- cgit v1.2.3