[education/rkward] /: Fix selection of pane (split views) when attaching window

Thomas Friedrichsmeier null at kde.org
Fri Aug 29 07:17:05 BST 2025


Git commit c0fd163bb90a7b186342bdd93c18aeb6a47edf6c by Thomas Friedrichsmeier.
Committed on 29/08/2025 at 06:16.
Pushed by tfry into branch 'master'.

Fix selection of pane (split views) when attaching window

M  +2    -1    ChangeLog
M  +5    -9    rkward/windows/rkworkplace.cpp
M  +2    -3    rkward/windows/rkworkplace.h
M  +10   -3    rkward/windows/rkworkplaceview.cpp

https://invent.kde.org/education/rkward/-/commit/c0fd163bb90a7b186342bdd93c18aeb6a47edf6c

diff --git a/ChangeLog b/ChangeLog
index 7cf45270a..3a30d2feb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,5 @@
-9527--- Version 0.8.2 - UNRELEASED
+--- Version 0.8.2 - UNRELEASED
+- Fixed: Attached windows would not always be placed in the most recently active pane (in a split view)
 - Fixed: Crash when switching from dialog to wizard interface in plugins providing a preview
 - Fixed: Crash using context menu while data editor is visible, under certain conditions
 - Added: Enhanced "R Console" preview mode, including produced plots
diff --git a/rkward/windows/rkworkplace.cpp b/rkward/windows/rkworkplace.cpp
index c8d8cf47c..bc23fb489 100644
--- a/rkward/windows/rkworkplace.cpp
+++ b/rkward/windows/rkworkplace.cpp
@@ -1186,7 +1186,7 @@ void RKMDIWindowHistory::prev(QAction *prev_action, QAction *next_action) {
 	getSwitcher(prev_action, next_action)->prev();
 }
 
-RKMDIWindow *RKMDIWindowHistory::previousDocumentWindow() {
+RKMDIWindow *RKMDIWindowHistory::previousDocumentWindow() const {
 	RK_TRACE(APP);
 
 	for (int i = recent_windows.count() - 1; i >= 0; --i) {
@@ -1214,7 +1214,10 @@ RKMDIWindowHistoryWidget *RKMDIWindowHistory::getSwitcher(QAction *prev_action,
 	if (switcher) return switcher;
 
 	switcher = new RKMDIWindowHistoryWidget();
-	connect(switcher, &QObject::destroyed, this, &RKMDIWindowHistory::switcherDestroyed);
+	connect(switcher, &QObject::destroyed, this, [this]() {
+		RK_ASSERT(switcher);
+		switcher = nullptr;
+	});
 	switcher->addAction(prev_action);
 	switcher->addAction(next_action);
 	switcher->update(recent_windows);
@@ -1232,13 +1235,6 @@ RKMDIWindowHistoryWidget *RKMDIWindowHistory::getSwitcher(QAction *prev_action,
 	return switcher;
 }
 
-void RKMDIWindowHistory::switcherDestroyed() {
-	RK_TRACE(APP);
-
-	RK_ASSERT(switcher);
-	switcher = nullptr;
-}
-
 void RKMDIWindowHistory::popLastWindow(RKMDIWindow *match) {
 	RK_TRACE(APP);
 
diff --git a/rkward/windows/rkworkplace.h b/rkward/windows/rkworkplace.h
index b254d5bd1..27ae1eda8 100644
--- a/rkward/windows/rkworkplace.h
+++ b/rkward/windows/rkworkplace.h
@@ -46,15 +46,14 @@ class RKMDIWindowHistory : public QObject {
 	void removeWindow(RKMDIWindow *window);
 	/** pops the last window from the list, if it matches the given pointer */
 	void popLastWindow(RKMDIWindow *match);
-	RKMDIWindow *previousDocumentWindow();
+	RKMDIWindow *previousDocumentWindow() const;
 	void next(QAction *prev_action, QAction *next_action);
 	void prev(QAction *prev_action, QAction *next_action);
+	const QList<RKMDIWindow *> recentWindows() const { return recent_windows; };
   public Q_SLOTS:
 	void windowActivated(RKMDIWindow *window);
   Q_SIGNALS:
 	void activeWindowChanged(RKMDIWindow *window);
-  private Q_SLOTS:
-	void switcherDestroyed();
 
   private:
 	void updateSwitcher();
diff --git a/rkward/windows/rkworkplaceview.cpp b/rkward/windows/rkworkplaceview.cpp
index 1deb4b0fe..d22267a23 100644
--- a/rkward/windows/rkworkplaceview.cpp
+++ b/rkward/windows/rkworkplaceview.cpp
@@ -221,9 +221,15 @@ RKWorkplaceViewPane *RKWorkplaceView::activePane() const {
 		if (panes[i]->isActive()) return panes[i];
 	}
 
-	// Esp. when switching between console and script window, consider the previous window active
-	RKWorkplaceViewPane *pane = findWindow(RKWorkplace::mainWorkplace()->getHistory()->previousDocumentWindow());
-	if (pane) return pane;
+	// find the previously active pane, if any
+	// Note: RKMDIWindowHistory::previousDocumentWindow() is not suitable, here, because it also considers non-attached windows
+	const auto wins = RKWorkplace::mainWorkplace()->getHistory()->recentWindows();
+	for (int i = wins.count() - 1; i >= 0; --i) {
+		if (!wins[i]->isToolWindow()) {
+			auto pane = findWindow(wins[i]);
+			if (pane) return pane;
+		}
+	}
 
 	// As a last resort, return top-left pane
 	RK_ASSERT(!panes.isEmpty());
@@ -397,6 +403,7 @@ void RKWorkplaceView::addWindow(RKMDIWindow *widget) {
 	if (icon.isNull()) icon = widget->topLevelWidget()->windowIcon();
 	if (icon.isNull()) RK_ASSERT(false);
 
+	RKWorkplace::mainWorkplace()->getHistory()->popLastWindow(widget);
 	RKWorkplaceViewPane *pane = activePane();
 	RK_ASSERT(pane);
 	id = pane->addTab(widget, icon, widget->shortCaption());


More information about the rkward-tracker mailing list