View Issue Details

IDProjectCategoryView StatusLast Update
0017636ScribusGeneralpublic2026-08-22 07:09
Reporterqirat Assigned To 
PrioritynormalSeverityminorReproducibilityalways
Status newResolutionopen 
PlatformLinuxOSFedoraOS Version42 Workstation
Product Version1.7.1.svn 
Summary0017636: Drag-selected and copied content from multiple pages is dictated by a wrongly highlighted page
DescriptionSo, when zooming out, drag-selecting and copying content from multiple pages, the page that is highlighted/selected during this dictates how the content would be pasted, even if the page has no content on it to be selected int he first place. It is like the page itself is copied during this as if it was content.

Please follow the steps below and you will find that pasting this content acts weird.
Steps To Reproduce1. Create a new doc with at least 5 pages (Right page was 1st page for me)
2. Leave pages 1 and 2 blank and draw a shape on the 3rd
3. Now zoom out and drag-select so that the drag goes over page 1 and page 2 a bit before grabbing the shape on page 3.
4. Ctrl+C to copy all selected content
5. Click on page 5 to make sure it is selected (red border around it)
6. Ctrl+V what you copied
7. The shape is pasted on page 7 (or in black space if page 7 is not there)
Additional InformationIn the Matrix chat group, @ale said he was able to reproduce the issue.

Also, please check the screen recording if something does not make sense in writing. (sorry for the low quality but it would serve its purpose)
Tags#patch_to_be_reviewed, #please_test, copy, copy page, paste
Attached Files
PatchNo

Activities

qirat

2026-08-10 11:33

reporter   ~0054193

This patch fixed it for me. And an other related bug is also fixed in the same patch (I hope that is ok).
fix-page-selection-and-indicator_v1.5_r27769.patch (7,780 bytes)   
Index: scribus/canvasmode_normal.cpp
===================================================================
--- scribus/canvasmode_normal.cpp	(revision 27769)
+++ scribus/canvasmode_normal.cpp	(working copy)
@@ -915,6 +915,13 @@
 			m_view->updatesOn(false);
 			shiftSel = SeleItem(m);
 			m_view->updatesOn(true);
+			// SeleItem() may request a redraw (setForcedRedraw + update()) so the
+			// active-page indicator follows a click onto a different page. That
+			// request can be silently dropped while view updates are suppressed
+			// above, leaving the indicator on the previous page. Re-issue it now
+			// that updates are back on.
+			m_canvas->setForcedRedraw(true);
+			m_canvas->update();
 			m_doc->m_Selection->delaySignalsOff();
 		}
 		if (((m_doc->m_Selection->isEmpty()) || (!shiftSel)) && (m->modifiers() == Qt::ShiftModifier))
@@ -1176,25 +1183,7 @@
 		QRectF canvasSele = QRectF(m_mousePressPoint.x(), m_mousePressPoint.y(), dx, dy).normalized();
 		QRectF localSele  = m_canvas->canvasToLocalF(canvasSele).normalized();
 		if (!m_doc->masterPageMode())
-		{
-			uint docPagesCount = m_doc->Pages->count();
-			uint docCurrPageNo = m_doc->currentPageNumber();
-			for (uint i = 0; i < docPagesCount; ++i)
-			{
-				ScPage*  page = m_doc->Pages->at(i);
-				QRectF pageRect(page->xOffset(), page->yOffset(), page->width(), page->height());
-				if (pageRect.intersects(canvasSele))
-				{
-					if (docCurrPageNo != i)
-					{
-						m_doc->setCurrentPage(m_doc->Pages->at(i));
-						m_view->m_ScMW->slotSetCurrentPage(i);
-					}
-					break;
-				}
-			}
 			m_view->setRulerPos(m_view->contentsX(), m_view->contentsY());
-		}
 		int docItemCount = m_doc->Items->count();
 		if (docItemCount != 0)
 		{
@@ -1235,6 +1224,43 @@
 				m_view->getGroupRectScreen(&x, &y, &w, &h);
 			}
 		}
+		// Resolve the current page from the resulting selection's own bounding
+		// box, not from the raw drag rectangle: a drag can touch an empty page
+		// (e.g. the facing blank page of a spread) before it reaches the page
+		// the selected content is actually on. Copy relies on doc->currentPage()
+		// being the content's page (see WriteObjects() in
+		// scribus171format_save.cpp), so getting this wrong here sends pasted
+		// items to the wrong page. Fall back to the old drag-rect based lookup
+		// only when nothing ended up selected.
+		if (!m_doc->masterPageMode())
+		{
+			int targetPageNo = -1;
+			if (!m_doc->m_Selection->isEmpty())
+			{
+				double gx, gy, gw, gh;
+				m_doc->m_Selection->getGroupRect(&gx, &gy, &gw, &gh);
+				targetPageNo = m_doc->OnPage(gx + gw / 2.0, gy + gh / 2.0);
+			}
+			if (targetPageNo == -1)
+			{
+				uint docPagesCount = m_doc->Pages->count();
+				for (uint i = 0; i < docPagesCount; ++i)
+				{
+					ScPage* page = m_doc->Pages->at(i);
+					QRectF pageRect(page->xOffset(), page->yOffset(), page->width(), page->height());
+					if (pageRect.intersects(canvasSele))
+					{
+						targetPageNo = static_cast<int>(i);
+						break;
+					}
+				}
+			}
+			if ((targetPageNo != -1) && (m_doc->currentPageNumber() != targetPageNo))
+			{
+				m_doc->setCurrentPage(m_doc->Pages->at(targetPageNo));
+				m_view->m_ScMW->slotSetCurrentPage(targetPageNo);
+			}
+		}
 		m_view->HaveSelRect = false;
 		m_shiftSelItems = false;
 //		m_view->redrawMarker->hide();
@@ -1707,6 +1733,15 @@
 				m_doc->setCurrentPage(m_doc->Pages->at(pgNum));
 				m_view->m_ScMW->slotSetCurrentPage(pgNum);
 				pageChanged = true;
+				// The redraw request further below (`if (currItem) { if (pageChanged)
+				// {...} }`) only fires when an item is found under the cursor. A click
+				// on empty space on a different page - e.g. clicking away to deselect
+				// - never reaches that branch, so the active-page indicator never got
+				// refreshed there. Request the redraw here too, right where the page
+				// actually changes, so it happens regardless of what currItem turns
+				// out to be.
+				m_canvas->setForcedRedraw(true);
+				m_canvas->update();
 			}
 		}
 		m_view->setRulerPos(m_view->contentsX(), m_view->contentsY());
Index: scribus/canvas.cpp
===================================================================
--- scribus/canvas.cpp	(revision 27769)
+++ scribus/canvas.cpp	(working copy)
@@ -880,6 +880,16 @@
 			t1 = t.elapsed();
 			t.start();
 #endif
+				// Unlike RENDER_NORMAL above, this case used to blit m_buffer
+				// unconditionally without checking m_viewMode.forceRedraw, so a
+				// pending forced redraw could be silently dropped whenever the
+				// render mode had already switched to RENDER_BUFFERED by the time
+				// this paintEvent() ran. Honour the flag here too, so a forced
+				// redraw always triggers a real buffer rebuild before blitting.
+				if ((m_viewMode.forceRedraw || m_viewMode.operTextSelecting) && (!bufferFilled))
+				{
+					fillBuffer(&m_buffer, m_bufferRect.topLeft(), p->rect());
+				}
 				int xV = p->rect().x() - m_bufferRect.x();
 				int yV = p->rect().y() - m_bufferRect.y();
 				int wV = p->rect().width();
Index: scribus/plugins/fileloader/scribus171format/scribus171format_save.cpp
===================================================================
--- scribus/plugins/fileloader/scribus171format/scribus171format_save.cpp	(revision 27769)
+++ scribus/plugins/fileloader/scribus171format/scribus171format_save.cpp	(working copy)
@@ -2054,6 +2054,21 @@
 			docu.writeAttribute("InID", item->inlineCharID);
 		if (master == ItemSelectionElements)
 		{
+			// Intentionally doc->currentPage() - the same page for every item in
+			// the selection, not each item's own page (doc->OnPage(item)). The
+			// normal in-app paste path (ScriXmlDoc::readElem() with loc=true, i.e.
+			// Ctrl+V) ignores the group offset and reconstructs each item as
+			// targetPage.offset + this value, so it needs to be an offset from one
+			// shared reference page for the whole selection: an item that is
+			// actually a page over from that reference then overflows past a
+			// single page's bounds, which is what carries it onto the matching
+			// page on the far side of the paste target and preserves multi-page
+			// spacing. A per-item page would give each item its own frame instead
+			// and collapse a multi-page selection onto one page on paste.
+			// doc->currentPage() itself is kept correct for a drag-selection by
+			// CanvasMode_Normal::mousePressEvent() in canvasmode_normal.cpp, which
+			// resolves it from the completed selection's bounding box rather than
+			// the first page the drag rectangle touches.
 			docu.writeAttribute("XPosition", item->xPos() - doc->currentPage()->xOffset());
 			docu.writeAttribute("YPosition", item->yPos() - doc->currentPage()->yOffset());
 		}
Index: scribus/scribusXml.cpp
===================================================================
--- scribus/scribusXml.cpp	(revision 27769)
+++ scribus/scribusXml.cpp	(working copy)
@@ -215,6 +215,15 @@
 		embedded->DrawObj(painter, QRectF());
 		painter->restore();
 	}
+	// This group-level offset is only consulted on the loc=false read path
+	// (e.g. dragging from the Scrapbook/shape palette); the normal in-app
+	// paste path (loc=true, Ctrl+C/Ctrl+V) ignores it and relies solely on
+	// each item's own offset from doc->currentPage(), written in
+	// Scribus171Format::WriteObjects() - see the comment there. For loc=false
+	// to stay consistent with that, this lookup needs to resolve to the same
+	// page doc->currentPage() has at copy time, which CanvasMode_Normal::
+	// mousePressEvent() (canvasmode_normal.cpp) guarantees for a drag
+	// selection.
 	int pg = doc->OnPage(xp + wp / 2.0, yp + hp / 2.0);
 	if (pg > -1)
 	{

qirat

2026-08-10 11:36

reporter   ~0054194

This how AI explains the issues, and their fixes (attached file).

Pls do [PATCH] and "Yes" in the mean time, if it will take time for you to take a look at it.
fix-page-selection-and-indicator_v1.5_r27769.md (3,873 bytes)   
# Cross-page selection & active-page indicator fixes (r27769)

Patch: `fix-page-selection-and-indicator_v1.5_r27769.patch`
Files touched: `canvasmode_normal.cpp`, `canvas.cpp`, `scribus171format_save.cpp`, `scribusXml.cpp`

---

## 1. Cross-page rubber-band selection copies relative to the wrong page

**Symptom:** Drag-select an item, copy, paste — pasted item lands offset by a page gap instead of at the paste target.

**Where:** `CanvasMode_Normal::mousePressEvent()` in `canvasmode_normal.cpp`.

**Root cause:** The current-page lookup ran *before* the item-selection loop, using whichever page the raw drag rectangle touched first. A drag can cross an empty/facing page before reaching the page the selected content is actually on, so `doc->currentPage()` ended up wrong at the moment `Copy` read it.

**Fix:** Moved the current-page resolution to *after* selection completes, and resolve it from the selection's own bounding-box center (`doc->OnPage(selectionCenter)`) instead of the drag rectangle. Falls back to the old drag-rect lookup only if nothing got selected.

---

## 2. Regression: multi-page selections collapsed onto one page on paste

This surfaced while fixing #1 — an earlier version of the fix additionally changed `WriteObjects()` (`scribus171format_save.cpp`) to anchor each copied item to *its own* page (`doc->OnPage(item)`) instead of `doc->currentPage()`. That looked like the natural companion fix, but broke multi-page selections.

**Why:** The standard in-app paste path (`ScriXmlDoc::readElem(..., loc=true)`, i.e. Ctrl+V) ignores the saved *group* offset entirely and reconstructs each item as `targetPage.offset + item.savedOffset`. That only works if every item's saved offset is expressed relative to **one shared reference page** for the whole selection — an item that's genuinely a page over from that reference then overflows past a single page's bounds, which is exactly what carries it onto the matching page on the far side of the paste target. Giving each item *its own* reference page breaks that: all items collapse onto whatever the single target page is.

**Fix:** Left `WriteObjects()` and the paired group-offset calculation in `ScriXmlDoc::writeElem()` (`scribusXml.cpp`) exactly as originally written — both keyed off one shared page (`doc->currentPage()` / `doc->OnPage(bbox center)`). The only actual defect was #1 (that shared page being resolved wrong); once that's fixed, this code was already correct. Added comments at both spots warning against reintroducing a per-item page reference here.

---

## 3. Active-page border doesn't refresh on a single click

**Symptom:** Clicking to select/deselect on another page updates document state correctly, but the red current-page border stays on the old page until an unrelated repaint (second click, zoom) forces a refresh.

**Where:** `Canvas::paintEvent()` in `canvas.cpp`; `SeleItem()` and `mousePressEvent()` in `canvasmode_normal.cpp`.

**Root cause (two parts):**
- `paintEvent()`'s `RENDER_BUFFERED` branch blitted the cached buffer unconditionally, never checking `forceRedraw` (unlike `RENDER_NORMAL`, which does). Since the render mode flips to `RENDER_BUFFERED` before a queued repaint actually runs, any pending redraw request was silently dropped.
- `SeleItem()` only requested a redraw when an item was found under the cursor, so deselecting by clicking empty space on a different page never requested one at all.

**Fix:**
- `RENDER_BUFFERED` now rebuilds the buffer when `forceRedraw` is set, same as `RENDER_NORMAL`.
- Redraw request moved to fire as soon as the page actually changes in `SeleItem()`, regardless of what's under the cursor.
- Re-issued the redraw request in `mousePressEvent()` after `updatesOn(true)`, since a request made while updates are suppressed can otherwise be lost.

Independent of #1/#2 — no functional overlap.

ale

2026-08-20 15:08

manager   ~0054252

So the problem seems to be that starting a selection from outside, automatically sets the first page "touched" by the selection as the current page.

Then, when copying the object which is on a different page, further on, the item gets an offset from the now selected page.

(And the offset is used when pasting.)

While the patch indeed gives the correct behavior, I cannot (yet) judge if it indeed fixes the wrong behavior or it just avoids the symptoms.

qirat

2026-08-20 15:53

reporter   ~0054253

Here is the complete explanation of the patch by AI.

ale

2026-08-20 19:37

manager   ~0054256

I would dare to affirm that the only part of the patch that is relevant to this ticket is in the patch attached to this note.

I did not check if the change is correct, but the result seem to be correct, with only this part of your v.1.5 patch applied.
The beginning of the comment seems to be somehow correct but I have a hard time understanding what is the meaning of the next part of it.

The other changes in your patch might or not be correct. Hard to say.
But they don't seem to be relevant to this ticket.
fix-page-selection-and-indicator_minimal.patch (3,029 bytes)   
diff --git a/scribus/canvasmode_normal.cpp b/scribus/canvasmode_normal.cpp
index c66730126..08e27db3e 100644
--- a/scribus/canvasmode_normal.cpp
+++ b/scribus/canvasmode_normal.cpp
@@ -868,7 +868,7 @@ void CanvasMode_Normal::mousePressEvent(QMouseEvent *m)
 		{
 			if (!m_lineMoveGesture)
 				m_lineMoveGesture = new LineMove(this);
-			
+
 			m_lineMoveGesture->mousePressEvent(m);
 			if (m_lineMoveGesture->haveLineItem())
 			{
@@ -1176,25 +1176,7 @@ void CanvasMode_Normal::mouseReleaseEvent(QMouseEvent *m)
 		QRectF canvasSele = QRectF(m_mousePressPoint.x(), m_mousePressPoint.y(), dx, dy).normalized();
 		QRectF localSele  = m_canvas->canvasToLocalF(canvasSele).normalized();
 		if (!m_doc->masterPageMode())
-		{
-			uint docPagesCount = m_doc->Pages->count();
-			uint docCurrPageNo = m_doc->currentPageNumber();
-			for (uint i = 0; i < docPagesCount; ++i)
-			{
-				ScPage*  page = m_doc->Pages->at(i);
-				QRectF pageRect(page->xOffset(), page->yOffset(), page->width(), page->height());
-				if (pageRect.intersects(canvasSele))
-				{
-					if (docCurrPageNo != i)
-					{
-						m_doc->setCurrentPage(m_doc->Pages->at(i));
-						m_view->m_ScMW->slotSetCurrentPage(i);
-					}
-					break;
-				}
-			}
 			m_view->setRulerPos(m_view->contentsX(), m_view->contentsY());
-		}
 		int docItemCount = m_doc->Items->count();
 		if (docItemCount != 0)
 		{
@@ -1235,6 +1217,43 @@ void CanvasMode_Normal::mouseReleaseEvent(QMouseEvent *m)
 				m_view->getGroupRectScreen(&x, &y, &w, &h);
 			}
 		}
+		// Resolve the current page from the resulting selection's own bounding
+		// box, not from the raw drag rectangle: a drag can touch an empty page
+		// (e.g. the facing blank page of a spread) before it reaches the page
+		// the selected content is actually on. Copy relies on doc->currentPage()
+		// being the content's page (see WriteObjects() in
+		// scribus171format_save.cpp), so getting this wrong here sends pasted
+		// items to the wrong page. Fall back to the old drag-rect based lookup
+		// only when nothing ended up selected.
+		if (!m_doc->masterPageMode())
+		{
+			int targetPageNo = -1;
+			if (!m_doc->m_Selection->isEmpty())
+			{
+				double gx, gy, gw, gh;
+				m_doc->m_Selection->getGroupRect(&gx, &gy, &gw, &gh);
+				targetPageNo = m_doc->OnPage(gx + gw / 2.0, gy + gh / 2.0);
+			}
+			if (targetPageNo == -1)
+			{
+				uint docPagesCount = m_doc->Pages->count();
+				for (uint i = 0; i < docPagesCount; ++i)
+				{
+					ScPage* page = m_doc->Pages->at(i);
+					QRectF pageRect(page->xOffset(), page->yOffset(), page->width(), page->height());
+					if (pageRect.intersects(canvasSele))
+					{
+						targetPageNo = static_cast<int>(i);
+						break;
+					}
+				}
+			}
+			if ((targetPageNo != -1) && (m_doc->currentPageNumber() != targetPageNo))
+			{
+				m_doc->setCurrentPage(m_doc->Pages->at(targetPageNo));
+				m_view->m_ScMW->slotSetCurrentPage(targetPageNo);
+			}
+		}
 		m_view->HaveSelRect = false;
 		m_shiftSelItems = false;
 //		m_view->redrawMarker->hide();

qirat

2026-08-21 02:14

reporter   ~0054258

Actually, it fixed another bug too (the code you removed I guess). The .md file in 0017636:0054194 explains this in section 0000003.

Well, you know the first bug so I will not repeat it.

--- Bug 0000002 ---
1. you just pasted an item, or have just moved it for that matter
2. you click another page, it is not highlighted with red border immediately, and needs another action for it.

It is correctly selected (no doubt) but the view is not refreshed until another action (a scroll, a zoom etc).

qirat

2026-08-21 02:15

reporter   ~0054259

Well, "...section 3" and "Bug 2" above.

qirat

2026-08-21 06:40

reporter   ~0054260

Also, worth mentioning that the number 2 regression that .md talks about is just some regression that was caught during my testing (it should not have been included there).

So, go for the number 1 and 3 only in that .md, OR check out this revised one here.
fix-page-selection-and-indicator_v1.6-revised.md (2,300 bytes)   
Cross-page selection & active-page indicator fixes (r27769)

Patch: `fix-page-selection-and-indicator_v1.5_r27769.patch`
Files touched: `canvasmode_normal.cpp`, `canvas.cpp`, `scribus171format_save.cpp`, `scribusXml.cpp`

---

#1. Cross-page rubber-band selection copies relative to the wrong page

Symptom: Drag-select an item, copy, paste — pasted item lands offset by a page gap instead of at the paste target.

Where: `CanvasMode_Normal::mousePressEvent()` in `canvasmode_normal.cpp`.

Root cause: The current-page lookup ran before the item-selection loop, using whichever page the raw drag rectangle touched first. A drag can cross an empty/facing page before reaching the page the selected content is actually on, so `doc->currentPage()` ended up wrong at the moment `Copy` read it.

Fix: Moved the current-page resolution to after selection completes, and resolve it from the selection's own bounding-box center (`doc->OnPage(selectionCenter)`) instead of the drag rectangle. Falls back to the old drag-rect lookup only if nothing got selected.

---

#2. Active-page border doesn't refresh on a single click

Symptom: Clicking to select/deselect on another page updates document state correctly, but the red current-page border stays on the old page until an unrelated repaint (second click, zoom) forces a refresh.

Where: `Canvas::paintEvent()` in `canvas.cpp`; `SeleItem()` and `mousePressEvent()` in `canvasmode_normal.cpp`.

Root cause (two parts):
- `paintEvent()`'s `RENDER_BUFFERED` branch blitted the cached buffer unconditionally, never checking `forceRedraw` (unlike `RENDER_NORMAL`, which does). Since the render mode flips to `RENDER_BUFFERED` before a queued repaint actually runs, any pending redraw request was silently dropped.
- `SeleItem()` only requested a redraw when an item was found under the cursor, so deselecting by clicking empty space on a different page never requested one at all.

Fix:
- `RENDER_BUFFERED` now rebuilds the buffer when `forceRedraw` is set, same as `RENDER_NORMAL`.
- Redraw request moved to fire as soon as the page actually changes in `SeleItem()`, regardless of what's under the cursor.
- Re-issued the redraw request in `mousePressEvent()` after `updatesOn(true)`, since a request made while updates are suppressed can otherwise be lost.

ale

2026-08-21 19:00

manager   ~0054276

I would suggest to separate the part fixing a different bug and open a ticket with the matching patch in that new ticket.

qirat

2026-08-22 06:20

reporter   ~0054280

Done. Here is the split for this one.

The report also explains why this split is has a little more code/comments in there compared to your. You know better anyway.
fix-page-highlight-v1.0.patch (5,388 bytes)   
Index: scribus/canvasmode_normal.cpp
===================================================================
--- scribus/canvasmode_normal.cpp	(revision 27773)
+++ scribus/canvasmode_normal.cpp	(working copy)
@@ -1176,25 +1176,7 @@
 		QRectF canvasSele = QRectF(m_mousePressPoint.x(), m_mousePressPoint.y(), dx, dy).normalized();
 		QRectF localSele  = m_canvas->canvasToLocalF(canvasSele).normalized();
 		if (!m_doc->masterPageMode())
-		{
-			uint docPagesCount = m_doc->Pages->count();
-			uint docCurrPageNo = m_doc->currentPageNumber();
-			for (uint i = 0; i < docPagesCount; ++i)
-			{
-				ScPage*  page = m_doc->Pages->at(i);
-				QRectF pageRect(page->xOffset(), page->yOffset(), page->width(), page->height());
-				if (pageRect.intersects(canvasSele))
-				{
-					if (docCurrPageNo != i)
-					{
-						m_doc->setCurrentPage(m_doc->Pages->at(i));
-						m_view->m_ScMW->slotSetCurrentPage(i);
-					}
-					break;
-				}
-			}
 			m_view->setRulerPos(m_view->contentsX(), m_view->contentsY());
-		}
 		int docItemCount = m_doc->Items->count();
 		if (docItemCount != 0)
 		{
@@ -1235,6 +1217,43 @@
 				m_view->getGroupRectScreen(&x, &y, &w, &h);
 			}
 		}
+		// Resolve the current page from the resulting selection's own bounding
+		// box, not from the raw drag rectangle: a drag can touch an empty page
+		// (e.g. the facing blank page of a spread) before it reaches the page
+		// the selected content is actually on. Copy relies on doc->currentPage()
+		// being the content's page (see WriteObjects() in
+		// scribus171format_save.cpp), so getting this wrong here sends pasted
+		// items to the wrong page. Fall back to the old drag-rect based lookup
+		// only when nothing ended up selected.
+		if (!m_doc->masterPageMode())
+		{
+			int targetPageNo = -1;
+			if (!m_doc->m_Selection->isEmpty())
+			{
+				double gx, gy, gw, gh;
+				m_doc->m_Selection->getGroupRect(&gx, &gy, &gw, &gh);
+				targetPageNo = m_doc->OnPage(gx + gw / 2.0, gy + gh / 2.0);
+			}
+			if (targetPageNo == -1)
+			{
+				uint docPagesCount = m_doc->Pages->count();
+				for (uint i = 0; i < docPagesCount; ++i)
+				{
+					ScPage* page = m_doc->Pages->at(i);
+					QRectF pageRect(page->xOffset(), page->yOffset(), page->width(), page->height());
+					if (pageRect.intersects(canvasSele))
+					{
+						targetPageNo = static_cast<int>(i);
+						break;
+					}
+				}
+			}
+			if ((targetPageNo != -1) && (m_doc->currentPageNumber() != targetPageNo))
+			{
+				m_doc->setCurrentPage(m_doc->Pages->at(targetPageNo));
+				m_view->m_ScMW->slotSetCurrentPage(targetPageNo);
+			}
+		}
 		m_view->HaveSelRect = false;
 		m_shiftSelItems = false;
 //		m_view->redrawMarker->hide();
Index: scribus/plugins/fileloader/scribus171format/scribus171format_save.cpp
===================================================================
--- scribus/plugins/fileloader/scribus171format/scribus171format_save.cpp	(revision 27773)
+++ scribus/plugins/fileloader/scribus171format/scribus171format_save.cpp	(working copy)
@@ -2054,6 +2054,21 @@
 			docu.writeAttribute("InID", item->inlineCharID);
 		if (master == ItemSelectionElements)
 		{
+			// Intentionally doc->currentPage() - the same page for every item in
+			// the selection, not each item's own page (doc->OnPage(item)). The
+			// normal in-app paste path (ScriXmlDoc::readElem() with loc=true, i.e.
+			// Ctrl+V) ignores the group offset and reconstructs each item as
+			// targetPage.offset + this value, so it needs to be an offset from one
+			// shared reference page for the whole selection: an item that is
+			// actually a page over from that reference then overflows past a
+			// single page's bounds, which is what carries it onto the matching
+			// page on the far side of the paste target and preserves multi-page
+			// spacing. A per-item page would give each item its own frame instead
+			// and collapse a multi-page selection onto one page on paste.
+			// doc->currentPage() itself is kept correct for a drag-selection by
+			// CanvasMode_Normal::mousePressEvent() in canvasmode_normal.cpp, which
+			// resolves it from the completed selection's bounding box rather than
+			// the first page the drag rectangle touches.
 			docu.writeAttribute("XPosition", item->xPos() - doc->currentPage()->xOffset());
 			docu.writeAttribute("YPosition", item->yPos() - doc->currentPage()->yOffset());
 		}
Index: scribus/scribusXml.cpp
===================================================================
--- scribus/scribusXml.cpp	(revision 27773)
+++ scribus/scribusXml.cpp	(working copy)
@@ -215,6 +215,15 @@
 		embedded->DrawObj(painter, QRectF());
 		painter->restore();
 	}
+	// This group-level offset is only consulted on the loc=false read path
+	// (e.g. dragging from the Scrapbook/shape palette); the normal in-app
+	// paste path (loc=true, Ctrl+C/Ctrl+V) ignores it and relies solely on
+	// each item's own offset from doc->currentPage(), written in
+	// Scribus171Format::WriteObjects() - see the comment there. For loc=false
+	// to stay consistent with that, this lookup needs to resolve to the same
+	// page doc->currentPage() has at copy time, which CanvasMode_Normal::
+	// mousePressEvent() (canvasmode_normal.cpp) guarantees for a drag
+	// selection.
 	int pg = doc->OnPage(xp + wp / 2.0, yp + hp / 2.0);
 	if (pg > -1)
 	{
fix-page-highlight-v1.0.patch (5,388 bytes)   

Issue History

Date Modified Username Field Change
2025-10-01 04:09 qirat New Issue
2025-10-01 04:09 qirat Tag Attached: copy
2025-10-01 04:09 qirat Tag Attached: copy page
2025-10-01 04:09 qirat Tag Attached: paste
2025-10-01 04:09 qirat File Added: Screencast From 2025-09-21 19-16-28 (trimmed).mp4
2025-10-01 17:16 ale Summary Drag-selected and copied content from pages is dictated by a wrongly highlighted page => Drag-selected and copied content from multiple pages is dictated by a wrongly highlighted page
2026-08-10 11:33 qirat Note Added: 0054193
2026-08-10 11:33 qirat File Added: fix-page-selection-and-indicator_v1.5_r27769.patch
2026-08-10 11:36 qirat Note Added: 0054194
2026-08-10 11:36 qirat File Added: fix-page-selection-and-indicator_v1.5_r27769.md
2026-08-20 15:08 ale Note Added: 0054252
2026-08-20 15:53 qirat Note Added: 0054253
2026-08-20 15:53 qirat File Added: fix-page-selection-and-indicator-report-brief.pdf
2026-08-20 19:37 ale Note Added: 0054256
2026-08-20 19:37 ale File Added: fix-page-selection-and-indicator_minimal.patch
2026-08-21 02:14 qirat Note Added: 0054258
2026-08-21 02:15 qirat Note Added: 0054259
2026-08-21 06:40 qirat Note Added: 0054260
2026-08-21 06:40 qirat File Added: fix-page-selection-and-indicator_v1.6-revised.md
2026-08-21 19:00 ale Note Added: 0054276
2026-08-22 06:20 qirat Note Added: 0054280
2026-08-22 06:20 qirat File Added: fix-page-highlight-report.pdf
2026-08-22 06:20 qirat File Added: fix-page-highlight-v1.0.patch
2026-08-22 06:21 qirat Tag Attached: #please_test
2026-08-22 07:09 ale Tag Attached: #patchtobereviewed
2026-08-27 08:05 ale Tag Renamed #patchtobereviewed => #patch_to_be_reviewed