diff --git a/src/nano.c b/src/nano.c
index 5b1a160ef7f604cb9e8d9048345b0b6f7ac9b7f4..63ef707b11b2dfbddf92f180fb5a73faae644445 100644
--- a/src/nano.c
+++ b/src/nano.c
@@ -1775,7 +1775,7 @@ int do_mouse(void)
 	    go_forward_chunks(row_count, &openfile->current, &leftedge);
 
 	openfile->current_x = actual_x(openfile->current->data,
-					leftedge + mouse_col);
+				actual_last_column(leftedge, mouse_col));
 
 #ifndef NANO_TINY
 	/* Clicking where the cursor is toggles the mark, as does clicking
diff --git a/src/proto.h b/src/proto.h
index 4e66b8e3e2154a7d099814fcb1556df23ef1ca48..aabca6ab8efda5c6b03fc2386813d7cccb388e47 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -665,6 +665,7 @@ void edit_scroll(scroll_dir direction, int nrows);
 #ifndef NANO_TINY
 size_t get_softwrap_breakpoint(const char *text, size_t leftedge,
 				bool *end_of_line);
+size_t actual_last_column(size_t leftedge, size_t column);
 size_t get_chunk(filestruct *line, size_t column, size_t *leftedge);
 size_t get_chunk_row(filestruct *line, size_t column);
 size_t get_chunk_leftedge(filestruct *line, size_t column);
diff --git a/src/winio.c b/src/winio.c
index e1adccb1e8cd545c9d01f4e3eec1faaf73f2a531..c8e8cc77e52b1b30d852f7f48ff7be3230b4c2c7 100644
--- a/src/winio.c
+++ b/src/winio.c
@@ -3028,6 +3028,34 @@ size_t get_softwrap_breakpoint(const char *text, size_t leftedge,
     return (editwincols > 2) ? prev_column : column - 1;
 }
 
+/* When in softwrap mode, and the given column is on or after the breakpoint of
+ * a softwrapped chunk, shift it back to the last column before the breakpoint.
+ * The given column is relative to the given leftedge in current.  The returned
+ * column is relative to the start of the text. */
+size_t actual_last_column(size_t leftedge, size_t column)
+{
+#ifndef NANO_TINY
+    if (ISSET(SOFTWRAP)) {
+	size_t end_col;
+	bool last_chunk;
+
+	end_col = get_softwrap_breakpoint(openfile->current->data, leftedge,
+						&last_chunk) - leftedge;
+
+	/* If we're not on the last chunk, we're one column past the end of
+	 * the row.  Shifting back one column might put us in the middle of
+	  * a multi-column character, but actual_x() will fix that later. */
+	if (!last_chunk)
+	    end_col--;
+
+	if (column > end_col)
+	    column = end_col;
+    }
+#endif
+
+    return leftedge + column;
+}
+
 /* Get the row of the softwrapped chunk of the given line that column is on,
  * relative to the first row (zero-based), and return it.  If leftedge isn't
  * NULL, return the leftmost column of the chunk in it. */