Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Miscellaneous bug fixes for Mark Mode #13358

Merged
merged 13 commits into from
Jul 1, 2022
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/cascadia/profiles.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@
"switchToTab",
"tabSearch",
"toggleAlwaysOnTop",
"toggleBlockSelection",
"toggleFocusMode",
"selectAll",
"setFocusMode",
Expand Down
23 changes: 14 additions & 9 deletions src/cascadia/TerminalControl/ControlCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
vkey != VK_SNAPSHOT &&
keyDown)
{
if (_terminal->IsInMarkMode() && modifiers.IsCtrlPressed() && vkey == 'A')
const auto isInMarkMode = static_cast<Control::SelectionInteractionMode>(_terminal->SelectionMode()) == Control::SelectionInteractionMode::Mark;
carlos-zamora marked this conversation as resolved.
Show resolved Hide resolved
if (isInMarkMode && modifiers.IsCtrlPressed() && vkey == 'A')
{
auto lock = _terminal->LockForWriting();
_terminal->SelectAll();
Expand Down Expand Up @@ -950,8 +951,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
const auto end{ _terminal->SelectionEndForRendering() };
info.EndPos = { end.X, end.Y };

info.MovingEnd = _terminal->MovingEnd();
info.MovingCursor = _terminal->MovingCursor();
info.Endpoint = static_cast<SelectionEndpointTarget>(_terminal->SelectionEndpointTarget());

const auto bufferSize{ _terminal->GetTextBuffer().GetSize() };
info.StartAtLeftBoundary = _terminal->GetSelectionAnchor().x == bufferSize.Left();
Expand Down Expand Up @@ -998,13 +998,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// Method Description:
// - Given a copy-able selection, get the selected text from the buffer and send it to the
// Windows Clipboard (CascadiaWin32:main.cpp).
// - CopyOnSelect does NOT clear the selection
// Arguments:
// - singleLine: collapse all of the text to one line
// - formats: which formats to copy (defined by action's CopyFormatting arg). nullptr
// if we should defer which formats are copied to the global setting
// - clearSelection: if true, clear the selection. Used for CopyOnSelect.
bool ControlCore::CopySelectionToClipboard(bool singleLine,
const Windows::Foundation::IReference<CopyFormat>& formats)
const Windows::Foundation::IReference<CopyFormat>& formats,
bool clearSelection)
carlos-zamora marked this conversation as resolved.
Show resolved Hide resolved
{
// no selection --> nothing to copy
if (!_terminal->IsSelectionActive())
Expand Down Expand Up @@ -1044,7 +1045,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
bgColor) :
"";

if (!_settings->CopyOnSelect())
if (clearSelection)
{
_terminal->ClearSelection();
_updateSelection();
Expand Down Expand Up @@ -1088,9 +1089,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_updateSelection();
}

bool ControlCore::IsInMarkMode() const
Control::SelectionInteractionMode ControlCore::SelectionMode() const
{
return _terminal->IsInMarkMode();
return static_cast<Control::SelectionInteractionMode>(_terminal->SelectionMode());
}

// Method Description:
Expand Down Expand Up @@ -1625,7 +1626,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_terminal->MultiClickSelection(terminalPosition, mode);
selectionNeedsToBeCopied = true;
}
_updateSelection();
_renderer->TriggerSelection();
carlos-zamora marked this conversation as resolved.
Show resolved Hide resolved

// this is used for mouse selection,
// so hide the markers
_UpdateSelectionMarkersHandlers(*this, winrt::make<implementation::UpdateSelectionMarkersEventArgs>(true));
}

void ControlCore::_updateSelection()
Expand Down
4 changes: 2 additions & 2 deletions src/cascadia/TerminalControl/ControlCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation

void SendInput(const winrt::hstring& wstr);
void PasteText(const winrt::hstring& hstr);
bool CopySelectionToClipboard(bool singleLine, const Windows::Foundation::IReference<CopyFormat>& formats);
bool CopySelectionToClipboard(bool singleLine, const Windows::Foundation::IReference<CopyFormat>& formats, bool clearSelection = true);
void SelectAll();
bool ToggleBlockSelection();
void ToggleMarkMode();
bool IsInMarkMode() const;
Control::SelectionInteractionMode SelectionMode() const;

void GotFocus();
void LostFocus();
Expand Down
19 changes: 16 additions & 3 deletions src/cascadia/TerminalControl/ControlCore.idl
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,25 @@ namespace Microsoft.Terminal.Control
All
};

enum SelectionInteractionMode
{
Mouse,
Keyboard,
Mark
};

[flags]
enum SelectionEndpointTarget
{
Start = 0x1,
End = 0x2
};

struct SelectionData
{
Microsoft.Terminal.Core.Point StartPos;
Microsoft.Terminal.Core.Point EndPos;
Boolean MovingEnd;
Boolean MovingCursor;
SelectionEndpointTarget Endpoint;
Boolean StartAtLeftBoundary;
Boolean EndAtRightBoundary;
};
Expand Down Expand Up @@ -78,7 +91,6 @@ namespace Microsoft.Terminal.Control
Boolean ToggleBlockSelection();
void ToggleMarkMode();
void ClearBuffer(ClearBufferType clearType);
Boolean IsInMarkMode();

void SetHoveredCell(Microsoft.Terminal.Core.Point terminalPosition);
void ClearHoveredCell();
Expand All @@ -101,6 +113,7 @@ namespace Microsoft.Terminal.Control
Boolean HasSelection { get; };
IVector<String> SelectedText(Boolean trimTrailingWhitespace);
SelectionData SelectionInfo { get; };
SelectionInteractionMode SelectionMode();

String HoveredUriText { get; };
Windows.Foundation.IReference<Microsoft.Terminal.Core.Point> HoveredCell { get; };
Expand Down
30 changes: 23 additions & 7 deletions src/cascadia/TerminalControl/ControlInteractivity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,13 +142,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// Method Description:
// - Given a copy-able selection, get the selected text from the buffer and send it to the
// Windows Clipboard (CascadiaWin32:main.cpp).
// - CopyOnSelect does NOT clear the selection
// Arguments:
// - singleLine: collapse all of the text to one line
// - formats: which formats to copy (defined by action's CopyFormatting arg). nullptr
// if we should defer which formats are copied to the global setting
// - clearSelection: if true, clear the selection after copying it. Used for CopyOnSelect.
bool ControlInteractivity::CopySelectionToClipboard(bool singleLine,
const Windows::Foundation::IReference<CopyFormat>& formats)
const Windows::Foundation::IReference<CopyFormat>& formats,
bool clearSelection)
{
if (_core)
{
Expand All @@ -164,7 +165,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// Mark the current selection as copied
_selectionNeedsToBeCopied = false;

return _core->CopySelectionToClipboard(singleLine, formats);
return _core->CopySelectionToClipboard(singleLine, formats, clearSelection);
}

return false;
Expand Down Expand Up @@ -257,15 +258,27 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
else if (WI_IsFlagSet(buttonState, MouseButtonState::IsRightButtonDown))
{
// CopyOnSelect right click always pastes
if (_core->CopyOnSelect() || !_core->HasSelection())
if (_core->CopyOnSelect())
{
// CopyOnSelect:
// 1. keyboard selection? --> copy the new content first
// 2. right click always pastes!
if (_core->SelectionMode() > SelectionInteractionMode::Keyboard)
{
CopySelectionToClipboard(shiftEnabled, nullptr);
}
RequestPasteTextFromClipboard();
}
else
else if (_core->HasSelection())
{
// copy selected text
CopySelectionToClipboard(shiftEnabled, nullptr);
}
else
{
// no selection --> paste
RequestPasteTextFromClipboard();
}
carlos-zamora marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand Down Expand Up @@ -383,7 +396,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
isLeftMouseRelease &&
_selectionNeedsToBeCopied)
{
CopySelectionToClipboard(false, nullptr);
// IMPORTANT!
// Set clearSelection to false here!
// Otherwise, the selection will be cleared immediately after you make it.
CopySelectionToClipboard(false, nullptr, /*clearSelection*/ false);
}

_singleClickTouchdownPos = std::nullopt;
Expand Down
3 changes: 2 additions & 1 deletion src/cascadia/TerminalControl/ControlInteractivity.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
#pragma endregion

bool CopySelectionToClipboard(bool singleLine,
const Windows::Foundation::IReference<CopyFormat>& formats);
const Windows::Foundation::IReference<CopyFormat>& formats,
bool clearSelection = true);
void RequestPasteTextFromClipboard();
void SetEndSelectionPoint(const Core::Point pixelPosition);
bool ManglePathsForWsl();
Expand Down
15 changes: 8 additions & 7 deletions src/cascadia/TerminalControl/TermControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1188,7 +1188,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
{
// Manually show the cursor when a key is pressed. Restarting
// the timer prevents flickering.
_core.CursorOn(!_core.IsInMarkMode());
_core.CursorOn(_core.SelectionMode() != SelectionInteractionMode::Mark);
_cursorTimer->Start();
}

Expand Down Expand Up @@ -1659,7 +1659,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
if (_cursorTimer)
{
// When the terminal focuses, show the cursor immediately
_core.CursorOn(!_core.IsInMarkMode());
_core.CursorOn(_core.SelectionMode() != SelectionInteractionMode::Mark);
_cursorTimer->Start();
}

Expand Down Expand Up @@ -2830,9 +2830,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation

// show/update selection markers
// figure out which endpoint to move, get it and the relevant icon (hide the other icon)
const auto selectionAnchor{ markerData.MovingEnd ? markerData.EndPos : markerData.StartPos };
const auto& marker{ markerData.MovingEnd ? SelectionEndMarker() : SelectionStartMarker() };
const auto& otherMarker{ markerData.MovingEnd ? SelectionStartMarker() : SelectionEndMarker() };
const auto movingEnd{ WI_IsFlagSet(markerData.Endpoint, SelectionEndpointTarget::End) };
const auto selectionAnchor{ movingEnd ? markerData.EndPos : markerData.StartPos };
const auto& marker{ movingEnd ? SelectionEndMarker() : SelectionStartMarker() };
const auto& otherMarker{ movingEnd ? SelectionStartMarker() : SelectionEndMarker() };
if (selectionAnchor.Y < 0 || selectionAnchor.Y >= _core.ViewHeight())
{
// if the endpoint is outside of the viewport,
Expand All @@ -2841,7 +2842,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
otherMarker.Visibility(Visibility::Collapsed);
co_return;
}
else if (markerData.MovingCursor)
else if (WI_AreAllFlagsSet(markerData.Endpoint, SelectionEndpointTarget::Start | SelectionEndpointTarget::End))
{
// display both markers
displayMarker(true);
Expand All @@ -2851,7 +2852,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
{
// display one marker,
// but hide the other
displayMarker(markerData.MovingEnd);
displayMarker(movingEnd);
otherMarker.Visibility(Visibility::Collapsed);
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/cascadia/TerminalCore/Terminal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,9 @@ Terminal::Terminal() :
_snapOnInput{ true },
_altGrAliasing{ true },
_blockSelection{ false },
_markMode{ false },
_selectionMode{ 0 },
carlos-zamora marked this conversation as resolved.
Show resolved Hide resolved
_selection{ std::nullopt },
_selectionEndpoint{ static_cast<SelectionEndpoint>(0) },
_taskbarState{ 0 },
_taskbarProgress{ 0 },
_trimBlockSelection{ false },
Expand Down Expand Up @@ -1369,7 +1370,7 @@ void Terminal::SetCursorOn(const bool isOn)
bool Terminal::IsCursorBlinkingAllowed() const noexcept
{
const auto& cursor = _activeBuffer().GetCursor();
return !_markMode && cursor.IsBlinkingAllowed();
return _selectionMode != SelectionInteractionMode::Mark && cursor.IsBlinkingAllowed();
}

// Method Description:
Expand Down
22 changes: 18 additions & 4 deletions src/cascadia/TerminalCore/Terminal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,13 @@ class Microsoft::Terminal::Core::Terminal final :

#pragma region TextSelection
// These methods are defined in TerminalSelection.cpp
enum class SelectionInteractionMode
{
Mouse,
Keyboard,
Mark
};

enum class SelectionDirection
{
Left,
Expand All @@ -249,21 +256,27 @@ class Microsoft::Terminal::Core::Terminal final :
Viewport,
Buffer
};

enum class SelectionEndpoint
{
Start = 0x1,
End = 0x2
};

void MultiClickSelection(const til::point viewportPos, SelectionExpansion expansionMode);
void SetSelectionAnchor(const til::point position);
void SetSelectionEnd(const til::point position, std::optional<SelectionExpansion> newExpansionMode = std::nullopt);
void SetBlockSelection(const bool isEnabled) noexcept;
void UpdateSelection(SelectionDirection direction, SelectionExpansion mode, ControlKeyStates mods);
void SelectAll();
bool IsInMarkMode() const;
SelectionInteractionMode SelectionMode() const noexcept;
void ToggleMarkMode();

using UpdateSelectionParams = std::optional<std::pair<SelectionDirection, SelectionExpansion>>;
UpdateSelectionParams ConvertKeyEventToUpdateSelectionParams(const ControlKeyStates mods, const WORD vkey) const;
bool MovingEnd() const noexcept;
bool MovingCursor() const noexcept;
til::point SelectionStartForRendering() const;
til::point SelectionEndForRendering() const;
const SelectionEndpoint SelectionEndpointTarget() const noexcept;

const TextBuffer::TextAndColor RetrieveSelectedTextFromBuffer(bool trimTrailingWhitespace);
#pragma endregion
Expand Down Expand Up @@ -333,7 +346,8 @@ class Microsoft::Terminal::Core::Terminal final :
bool _blockSelection;
std::wstring _wordDelimiters;
SelectionExpansion _multiClickSelectionMode;
bool _markMode;
SelectionInteractionMode _selectionMode;
SelectionEndpoint _selectionEndpoint;
#pragma endregion

std::unique_ptr<TextBuffer> _mainBuffer;
Expand Down
Loading