[rkward] /: Fix several window activation quirks in "Focus follows mouse" mode
Thomas Friedrichsmeier
thomas.friedrichsmeier at ruhr-uni-bochum.de
Fri Jan 1 12:35:30 UTC 2016
Git commit 0ac80a868158f3e7150adef751917fbf05cfb187 by Thomas Friedrichsmeier.
Committed on 01/01/2016 at 12:35.
Pushed by tfry into branch 'master'.
Fix several window activation quirks in "Focus follows mouse" mode
M +1 -0 ChangeLog
M +35 -3 rkward/windows/rkmdiwindow.cpp
M +1 -1 rkward/windows/rkmdiwindow.h
http://commits.kde.org/rkward/0ac80a868158f3e7150adef751917fbf05cfb187
diff --git a/ChangeLog b/ChangeLog
index 11930a0..6ca254a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,4 @@
+- Fix several window activation quirks in "Focus follows mouse" mode
- File selectors in "Import XYZ" plugins now filter for standard file extensions, by default
- Show a warning screen when invoking plugins from the command line (or from clicking an rkward://-link in an external application)
diff --git a/rkward/windows/rkmdiwindow.cpp b/rkward/windows/rkmdiwindow.cpp
index 0535cf7..5c51270 100644
--- a/rkward/windows/rkmdiwindow.cpp
+++ b/rkward/windows/rkmdiwindow.cpp
@@ -261,10 +261,37 @@ void RKMDIWindow::windowActivationChange (bool) {
if (active || (!isAttached ())) update ();
}
-void RKMDIWindow::slotActivate () {
+void RKMDIWindow::slotActivateForFocusFollowsMouse () {
RK_TRACE (APP);
+ if (!underMouse ()) return;
+
+ // we can't do without activateWindow(), below. Unfortunately, this has the side effect of raising the window (in some cases). This is not always what we want, e.g. if a
+ // plot window is stacked above this window. (And since this is activation by mouse hover, this window is already visible, by definition!)
+ // So we try a heuristic (imperfect) to find, if there are any other windows stacked above this one, in order to re-raise them above this.
+ QWidgetList toplevels = qApp->topLevelWidgets ();
+ QWidgetList overlappers;
+ QWidget *window = topLevelWidget ();
+ QRect rect = window->frameGeometry ();
+ for (int i = toplevels.size () - 1; i >= 0; --i) {
+ QWidget *tl = toplevels[i];
+ if (!tl->isWindow ()) continue;
+ if (tl == window) continue;
+ if (tl->isHidden ()) continue;
+
+ QRect tlrect = tl->geometry ();
+ QRect intersected = tlrect.intersected (rect);
+ if (!intersected.isEmpty ()) {
+ QWidget *above = qApp->topLevelAt ((intersected.left () +intersected.right ()) / 2, (intersected.top () +intersected.bottom ()) / 2);
+ if (above && (above != window) && (above->isWindow ()) && (!above->isHidden ()) && (overlappers.indexOf (above) < 0)) overlappers.append (above);
+ }
+ }
+
activate (true);
+
+ for (int i = 0; i < overlappers.size (); ++i) {
+ overlappers[i]->raise ();
+ }
}
void RKMDIWindow::enterEvent (QEvent *event) {
@@ -275,9 +302,14 @@ void RKMDIWindow::enterEvent (QEvent *event) {
if (!QApplication::activePopupWidget ()) {
// see http://sourceforge.net/p/rkward/bugs/90/
// enter events may be delivered while a popup-menu (in a different window) is executing. If we activate in this case, the popup-menu might get deleted
- // while still handling events. Similar problems seem to occur, when the popup menu has just finished (by the user selecting an action) and this results
+ // while still handling events.
+ //
+ // Similar problems seem to occur, when the popup menu has just finished (by the user selecting an action) and this results
// in the mouse entering this widget. To prevent crashes in this second case, we delay the activation until the next iteration of the event loop.
- QTimer::singleShot (0, this, SLOT (slotActivate()));
+ //
+ // Finally, in some cases (such as when a new script window was created), we need a short delay, as we may be catching an enter event on a window that is in the same place,
+ // where the newly created window goes. This would cause activation to switch back, immediately.
+ QTimer::singleShot (50, this, SLOT (slotActivateForFocusFollowsMouse()));
}
}
}
diff --git a/rkward/windows/rkmdiwindow.h b/rkward/windows/rkmdiwindow.h
index 54c7154..913f485 100644
--- a/rkward/windows/rkmdiwindow.h
+++ b/rkward/windows/rkmdiwindow.h
@@ -134,7 +134,7 @@ friend class RKWorkplace;
/** type of this window */
int type;
private slots:
- void slotActivate ();
+ void slotActivateForFocusFollowsMouse ();
private:
friend class RKToolWindowBar;
/** state of this window (attached / detached). This is usually set from the RKWorkplace */
More information about the rkward-tracker
mailing list