From ea7de4e60414c676945223dd25c5afd8f4f7b4f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Manuel=20Ferrer=20Ortiz?= Date: Sat, 5 Oct 2024 23:33:21 +0200 Subject: [PATCH] Allow jumping between words on the input line when the focus is on it, with key combinations 'Command + Left' and 'Command + Right', instead of collapsing or expanding the channel list for the current server. The later bindings were taking precedence even when the focus was on the input line (the BTextView to type IRC messages the user wants to send). With the changes on this commit, when the focus is on the input line, these key combinations correctly move to the start of the current word or the previous word, or to the end of the current word or the next word. And when the focus is anywhere else, the behavior before this commit is replicated. And the combinations 'Command + Shift + Left' and 'Command + Shift + Right' were also done to work correctly, moving the selection on the input line between words. As the operation of expanding the channel list is harmless to the user (it will keep showing the server messages), and the collapse operation opens the server messages screen; changes the focus to the input line and moves its cursor to its end, 'Command + Right' will also expand the channel list if the cursor is at the end of the input line. This way the operation of collapsing the channel list can be intuitively undone by pressing 'Command + Right' right afterwards. The opposite WAS NOT implemented, i.e. collapsing the channel list with 'Command + Left' when the cursor is at the start of the input line, because the collapsing operation hides the current channel messages (it's not harmless to the user's workflow). --- src/ClientAgentInputFilter.cpp | 50 ++++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/src/ClientAgentInputFilter.cpp b/src/ClientAgentInputFilter.cpp index f48a030..02ae5fb 100644 --- a/src/ClientAgentInputFilter.cpp +++ b/src/ClientAgentInputFilter.cpp @@ -223,6 +223,9 @@ filter_result ClientAgentInputFilter::HandleKeys(BMessage* msg) if ((keymodifiers & B_OPTION_KEY) == 0 && (keymodifiers & B_COMMAND_KEY) != 0 && (keymodifiers & B_CONTROL_KEY) == 0 && (keymodifiers & B_SHIFT_KEY) != 0) { + /////////////////////// + /// Shift + Command /// + /////////////////////// switch (keyStroke[0]) { case '0': case B_INSERT: @@ -231,16 +234,29 @@ filter_result ClientAgentInputFilter::HandleKeys(BMessage* msg) result = B_SKIP_MESSAGE; break; + case B_LEFT_ARROW: + case B_RIGHT_ARROW: + { + BTextView* focusedTextView = dynamic_cast(vision_app->pClientWin()->CurrentFocus()); + if (focusedTextView) // while selecting text, move to start of word or previous word, or to end of word or next word + result = B_DISPATCH_MESSAGE; // Let the text view handle the message + else { // baxter muscle memory + result = B_SKIP_MESSAGE; + if (keyStroke[0] == B_LEFT_ARROW) + winList->ContextSelectUp(); + else + winList->ContextSelectDown(); + } + } break; + case B_UP_ARROW: - case B_LEFT_ARROW: // baxter muscle memory - case ',': // bowser muscle memory + case ',': // bowser muscle memory winList->ContextSelectUp(); result = B_SKIP_MESSAGE; break; - case B_DOWN_ARROW: // - case B_RIGHT_ARROW: // baxter muscle memory - case '.': // bowser muscle memory + case B_DOWN_ARROW: + case '.': // bowser muscle memory winList->ContextSelectDown(); result = B_SKIP_MESSAGE; break; @@ -283,14 +299,30 @@ filter_result ClientAgentInputFilter::HandleKeys(BMessage* msg) case B_LEFT_ARROW: // collapse current server (if expanded) { - winList->CollapseCurrentServer(); - result = B_SKIP_MESSAGE; + BView* focusedView = vision_app->pClientWin()->CurrentFocus(); + if (dynamic_cast(focusedView) == NULL) { // The focused view is not a BTextView + winList->CollapseCurrentServer(); + result = B_SKIP_MESSAGE; + } else + result = B_DISPATCH_MESSAGE; // Let the text view handle the message } break; case B_RIGHT_ARROW: // expand current server (if collapsed) { - winList->ExpandCurrentServer(); - result = B_SKIP_MESSAGE; + BTextView* focusedTextView = dynamic_cast(vision_app->pClientWin()->CurrentFocus()); + bool insertionAtEnd; // Whether the insertion point of the focused BTextView is at the end of its text + if (focusedTextView) { + int32 selectionStart, selectionEnd; + focusedTextView->GetSelection(&selectionStart, &selectionEnd); + insertionAtEnd = (selectionStart == selectionEnd) && (selectionEnd == focusedTextView->TextLength()); + } + if (focusedTextView == NULL // The focused view is not a BTextView + || insertionAtEnd) { + winList->ExpandCurrentServer(); + result = B_SKIP_MESSAGE; + } + else + result = B_DISPATCH_MESSAGE; // Let the text view handle the message } break; case '/': // bowser muscle memory