|
commit 495b2395c14607c030a0270ed7341bf04be7fa56
Author: Matthias Melcher <github@matthiasm.com>
AuthorDate: Tue Nov 22 16:18:56 2022 +0100
Commit: GitHub <noreply@github.com>
CommitDate: Tue Nov 22 16:18:56 2022 +0100
Fix selection extension in Fl_Text_*, issue 196 (#550)
Selecting a text range programmatically would not sync
some variables with the actual selection. This also fixes
a crash bug in macOS when dragging text that was
selected by buffer()->select() only.
FL/Fl_Text_Display.H | 1 +
src/Fl_Text_Display.cxx | 46 +++++++++++++++++++++++++++++++++++++++++++---
src/Fl_Text_Editor.cxx | 6 +++++-
3 files changed, 49 insertions(+), 4 deletions(-)
diff --git FL/Fl_Text_Display.H FL/Fl_Text_Display.H
index 21f0d63..1d5b511 100644
--- FL/Fl_Text_Display.H
+++ FL/Fl_Text_Display.H
@@ -124,6 +124,7 @@ public:
WRAP_AT_BOUNDS /**< wrap text so that it fits into the widget width */
};
+ friend int fl_text_drag_prepare(int pos, int key, Fl_Text_Display* d);
friend void fl_text_drag_me(int pos, Fl_Text_Display* d);
typedef void (*Unfinished_Style_Cb)(int, void *);
diff --git src/Fl_Text_Display.cxx src/Fl_Text_Display.cxx
index bd81e0e..e6f30c1 100644
--- src/Fl_Text_Display.cxx
+++ src/Fl_Text_Display.cxx
@@ -3961,7 +3961,42 @@ void Fl_Text_Display::draw(void) {
fl_pop_clip();
}
-
+// GitHub Issue #196: internal selection and visible selection can run out of
+// sync, giving the user unexpected keyboard selection. The code block below
+// captures that and fixes it.
+// - set pos to the drag target postion or -1 if we don't know
+// - if pos is -1, and key is not -1, key can be set to indicate a direction
+// (e.g. FL_Left)
+// return 0 if nothing changed, return 1 if dragPos or mCursorPos were modified
+int fl_text_drag_prepare(int pos, int key, Fl_Text_Display* d) {
+ if (d->buffer()->selected()) {
+ int start, end;
+ d->buffer()->selection_position(&start, &end);
+ if ( (d->dragPos!=start || d->mCursorPos!=end) && (d->dragPos!=end || d->mCursorPos!=start) ) {
+ if (pos!=-1) {
+ if (pos<start) {
+ d->mCursorPos = start;
+ d->dragPos = end;
+ } else {
+ d->mCursorPos = end;
+ d->dragPos = start;
+ }
+ } else if (key!=-1) {
+ switch (key) {
+ case FL_Home: case FL_Left: case FL_Up: case FL_Page_Up:
+ d->dragPos = end; d->mCursorPos = start; break;
+ default:
+ d->dragPos = start; d->mCursorPos = end; break;
+ }
+ } else {
+ d->dragPos = start;
+ d->mCursorPos = end;
+ }
+ return 1;
+ }
+ }
+ return 0;
+}
// this processes drag events due to mouse for Fl_Text_Display and
// also drags due to cursor movement with shift held down for
@@ -4079,8 +4114,12 @@ int Fl_Text_Display::handle(int event) {
}
if (Fl_Group::handle(event)) return 1;
if (Fl::event_state()&FL_SHIFT) {
- if (!buffer()->primary_selection()->selected())
- dragPos = insert_position();
+ if (buffer()->primary_selection()->selected()) {
+ int pos = xy_to_position(Fl::event_x(), Fl::event_y(), CURSOR_POS);
+ fl_text_drag_prepare(pos, -1, this);
+ } else {
+ dragPos = insert_position();
+ }
return handle(FL_DRAG);
}
dragging = 1;
@@ -4114,6 +4153,7 @@ int Fl_Text_Display::handle(int event) {
if (dragType==DRAG_START_DND) {
if (!Fl::event_is_click() && Fl::dnd_text_ops()) {
const char* copy = buffer()->selection_text();
+ Fl::copy(copy, strlen(copy));
Fl::screen_driver()->dnd(1);
free((void*)copy);
}
diff --git src/Fl_Text_Editor.cxx src/Fl_Text_Editor.cxx
index a786ac4..1393500 100644
--- src/Fl_Text_Editor.cxx
+++ src/Fl_Text_Editor.cxx
@@ -284,6 +284,7 @@ int Fl_Text_Editor::kf_enter(int, Fl_Text_Editor* e) {
return 1;
}
+extern int fl_text_drag_prepare(int pos, int key, Fl_Text_Display* d);
extern void fl_text_drag_me(int pos, Fl_Text_Display* d);
/** Moves the text cursor in the direction indicated by key \p 'c' in editor \p 'e'.
Supported values for 'c' are currently:
@@ -339,6 +340,7 @@ int Fl_Text_Editor::kf_move(int c, Fl_Text_Editor* e) {
\see kf_move()
*/
int Fl_Text_Editor::kf_shift_move(int c, Fl_Text_Editor* e) {
+ fl_text_drag_prepare(-1, c, e);
kf_move(c, e);
fl_text_drag_me(e->insert_position(), e);
char *copy = e->buffer()->selection_text();
@@ -441,6 +443,7 @@ int Fl_Text_Editor::kf_meta_move(int c, Fl_Text_Editor* e) {
\see kf_meta_move().
*/
int Fl_Text_Editor::kf_m_s_move(int c, Fl_Text_Editor* e) {
+ fl_text_drag_prepare(-1, c, e);
kf_meta_move(c, e);
fl_text_drag_me(e->insert_position(), e);
return 1;
@@ -450,6 +453,7 @@ int Fl_Text_Editor::kf_m_s_move(int c, Fl_Text_Editor* e) {
\see kf_ctrl_move().
*/
int Fl_Text_Editor::kf_c_s_move(int c, Fl_Text_Editor* e) {
+ fl_text_drag_prepare(-1, c, e);
kf_ctrl_move(c, e);
fl_text_drag_me(e->insert_position(), e);
return 1;
@@ -709,7 +713,7 @@ int Fl_Text_Editor::handle(int event) {
dragType = DRAG_NONE;
if(buffer()->selected()) {
buffer()->unselect();
- }
+ }
int pos = xy_to_position(Fl::event_x(), Fl::event_y(), CURSOR_POS);
insert_position(pos);
Fl::paste(*this, 0);
[ Direct Link to Message ] | |