]> git.lyx.org Git - features.git/commitdiff
Always remove selection after cursor up/down
authorJean-Marc Lasgouttes <lasgouttes@lyx.org>
Tue, 29 Jun 2021 10:43:59 +0000 (12:43 +0200)
committerJean-Marc Lasgouttes <lasgouttes@lyx.org>
Wed, 30 Jun 2021 14:51:58 +0000 (16:51 +0200)
When the cursor cannot move on cursor up/down, at least the selection
should be cleared (when not selecting).

To detect this, the method Cursor::upDownInText has been modified to
return true when cursor is at top/bottom of inset, but there is some
room above/below.

Moreover, introduce the functions LFUN_FINISHED_UP/DOWN, which is
dispatched at upper cursor level as long as no local movement is
possible. This allows to handle differently the original char moving
action and its consequences.

Fixes part of bug #12310.

src/Cursor.cpp
src/Cursor.h
src/FuncCode.h
src/LyXAction.cpp
src/Text3.cpp

index ad46e8c50567e61af367f7b1c90e26133393086d..d2190e729fb44dc7364cc2c2526f2574e2d4e456 100644 (file)
@@ -2216,7 +2216,7 @@ bool Cursor::upDownInText(bool up, bool & updateNeeded)
                        if (updateNeeded)
                                forceBufferUpdate();
                }
-               return false;
+               return valid_destination;
        }
 
        // with and without selection are handled differently
index f5490479851b8322f7b095d0bf4ae6ce0c3d152b..4ef5bc9d6cbde7b7500398c4f092a134766417f0 100644 (file)
@@ -496,8 +496,9 @@ public:
        /// return true if fullscreen update is needed
        bool down();
        /// move up/down in a text inset, called for LFUN_UP/DOWN,
-       /// return true if successful, updateNeeded set to true if fullscreen
-       /// update is needed, otherwise it's not touched
+       /// return true if the cursor has moved or can move, updateNeeded
+       /// set to true if fullscreen update is needed, otherwise it's not
+       /// touched
        bool upDownInText(bool up, bool & updateNeeded);
        /// move up/down in math or any non text inset, call for LFUN_UP/DOWN
        /// return true if successful
index 391232b8461b2765223beeae9164452f46303c4a..20231eb1645fdf00d485edc414ef8761c064d41c 100644 (file)
@@ -500,6 +500,8 @@ enum FuncCode
        LFUN_SPELLING_ADD_LOCAL,        // jspitzm 20210306
        // 390
        LFUN_SPELLING_REMOVE_LOCAL,     // jspitzm 20210307
+       LFUN_FINISHED_DOWN,             // lasgouttes 20210629
+       LFUN_FINISHED_UP,               // lasgouttes 20210629
        LFUN_LASTACTION                 // end of the table
 };
 
index 8933e3d1e732107d415fae41acb4e483899718d0..254060e789f438b7d85cb94015c1f465f8dacfa0 100644 (file)
@@ -1668,6 +1668,22 @@ void LyXAction::init()
  */
                { LFUN_FINISHED_RIGHT, "", ReadOnly, Hidden },
 
+/*!
+ * \var lyx::FuncCode lyx::LFUN_FINISHED_UP
+ * \li Action: Moves the cursor out of the current slice, going up.
+ * \li Notion: See also #LFUN_FINISHED_DOWN.
+ * \endvar
+ */
+               { LFUN_FINISHED_UP, "", ReadOnly, Hidden },
+
+/*!
+ * \var lyx::FuncCode lyx::LFUN_FINISHED_DOWN
+ * \li Action: Moves the cursor out of the current slice, going down.
+ * \li Notion: See also #LFUN_FINISHED_DOWN.
+ * \endvar
+ */
+               { LFUN_FINISHED_DOWN, "", ReadOnly, Hidden },
+
 /*!
  * \var lyx::FuncCode lyx::LFUN_FLEX_INSERT
  * \li Action: Inserts CharStyle, Custom inset or XML short element.
index ffc5d758dfaac80af426c07403a0e73d4de0a843..fcccdd3d4878235180c849115c31a59092d19bfe 100644 (file)
@@ -892,14 +892,12 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
        case LFUN_UP:
        case LFUN_DOWN: {
                // stop/start the selection
-               bool select = cmd.action() == LFUN_DOWN_SELECT ||
-                       cmd.action() == LFUN_UP_SELECT;
-
+               bool const select = cmd.action() == LFUN_DOWN_SELECT
+                                       || cmd.action() == LFUN_UP_SELECT;
                // move cursor up/down
-               bool up = cmd.action() == LFUN_UP_SELECT || cmd.action() == LFUN_UP;
-               bool const atFirstOrLastRow = cur.atFirstOrLastRow(up);
+               bool const up = cmd.action() == LFUN_UP_SELECT || cmd.action() == LFUN_UP;
 
-               if (!atFirstOrLastRow) {
+               if (!cur.atFirstOrLastRow(up)) {
                        needsUpdate |= cur.selHandle(select);
                        cur.upDownInText(up, needsUpdate);
                        needsUpdate |= cur.beforeDispatchCursor().inMathed();
@@ -915,13 +913,35 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                                        cur.forceBufferUpdate();
                                break;
                        }
+                       needsUpdate |= cur.selHandle(select);
+                       bool const can_move = cur.upDownInText(up, needsUpdate);
+                       // if the cursor can be moved up or down at an upper level,
+                       // delegate the dispatch to next level. Otherwise, we are
+                       // done.
+                       if (can_move) {
+                               cmd = FuncRequest(up ? LFUN_FINISHED_UP : LFUN_FINISHED_DOWN);
+                               cur.undispatched();
+                       }
+               }
 
-                       // if the cursor cannot be moved up or down do not remove
-                       // the selection right now, but wait for the next dispatch.
-                       if (select)
-                               needsUpdate |= cur.selHandle(select);
+               break;
+       }
+
+       case LFUN_FINISHED_UP:
+       case LFUN_FINISHED_DOWN: {
+               // move cursor up/down
+               bool const up = cmd.action() == LFUN_FINISHED_UP;
+
+               if (!cur.atFirstOrLastRow(up)) {
                        cur.upDownInText(up, needsUpdate);
-                       cur.undispatched();
+                       needsUpdate |= cur.beforeDispatchCursor().inMathed();
+               } else {
+                       bool const can_move = cur.upDownInText(up, needsUpdate);
+                       // if the cursor can be moved up or down and we are not
+                       // moving cusor at top level, wait for the next dispatch.
+                       // Otherwise, we are done.
+                       if (can_move)
+                               cur.undispatched();
                }
 
                break;