Skip to content

Commit 8390d60

Browse files
committed
Move all blink handling into Renderer
1 parent af39dbd commit 8390d60

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+786
-1204
lines changed

.github/actions/spelling/expect/expect.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1765,6 +1765,7 @@ UINTs
17651765
uld
17661766
uldash
17671767
uldb
1768+
ULONGLONG
17681769
ulwave
17691770
Unadvise
17701771
unattend

src/buffer/out/cursor.cpp

Lines changed: 96 additions & 179 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,7 @@
1313
// - ulSize - The height of the cursor within this buffer
1414
Cursor::Cursor(const ULONG ulSize, TextBuffer& parentBuffer) noexcept :
1515
_parentBuffer{ parentBuffer },
16-
_fIsVisible(true),
17-
_fIsOn(true),
18-
_fIsDouble(false),
19-
_fBlinkingAllowed(true),
20-
_fDelay(false),
21-
_fIsConversionArea(false),
22-
_fDelayedEolWrap(false),
23-
_fDeferCursorRedraw(false),
24-
_fHaveDeferredCursorRedraw(false),
25-
_ulSize(ulSize),
26-
_cursorType(CursorType::Legacy)
16+
_ulSize(ulSize)
2717
{
2818
}
2919

@@ -34,193 +24,145 @@ til::point Cursor::GetPosition() const noexcept
3424
return _cPosition;
3525
}
3626

37-
bool Cursor::IsVisible() const noexcept
27+
uint64_t Cursor::GetLastMutationId() const noexcept
3828
{
39-
return _fIsVisible;
29+
return _mutationId;
4030
}
4131

42-
bool Cursor::IsOn() const noexcept
32+
bool Cursor::IsVisible() const noexcept
4333
{
44-
return _fIsOn;
34+
return _isVisible;
4535
}
4636

47-
bool Cursor::IsBlinkingAllowed() const noexcept
37+
bool Cursor::IsBlinking() const noexcept
4838
{
49-
return _fBlinkingAllowed;
39+
return _isBlinking;
5040
}
5141

5242
bool Cursor::IsDouble() const noexcept
5343
{
5444
return _fIsDouble;
5545
}
5646

57-
bool Cursor::IsConversionArea() const noexcept
58-
{
59-
return _fIsConversionArea;
60-
}
61-
62-
bool Cursor::GetDelay() const noexcept
63-
{
64-
return _fDelay;
65-
}
66-
6747
ULONG Cursor::GetSize() const noexcept
6848
{
6949
return _ulSize;
7050
}
7151

72-
void Cursor::SetIsVisible(const bool fIsVisible) noexcept
52+
void Cursor::SetIsVisible(bool enable)
7353
{
74-
_fIsVisible = fIsVisible;
75-
_RedrawCursor();
76-
}
77-
78-
void Cursor::SetIsOn(const bool fIsOn) noexcept
79-
{
80-
_fIsOn = fIsOn;
81-
_RedrawCursorAlways();
54+
if (_isVisible != enable)
55+
{
56+
_isVisible = enable;
57+
_redrawIfVisible();
58+
}
8259
}
8360

84-
void Cursor::SetBlinkingAllowed(const bool fBlinkingAllowed) noexcept
61+
void Cursor::SetIsBlinking(bool enable)
8562
{
86-
_fBlinkingAllowed = fBlinkingAllowed;
87-
// GH#2642 - From what we've gathered from other terminals, when blinking is
88-
// disabled, the cursor should remain On always, and have the visibility
89-
// controlled by the IsVisible property. So when you do a printf "\e[?12l"
90-
// to disable blinking, the cursor stays stuck On. At this point, only the
91-
// cursor visibility property controls whether the user can see it or not.
92-
// (Yes, the cursor can be On and NOT Visible)
93-
_fIsOn = true;
94-
_RedrawCursorAlways();
63+
if (_isBlinking != enable)
64+
{
65+
_isBlinking = enable;
66+
_redrawIfVisible();
67+
}
9568
}
9669

9770
void Cursor::SetIsDouble(const bool fIsDouble) noexcept
9871
{
99-
_fIsDouble = fIsDouble;
100-
_RedrawCursor();
101-
}
102-
103-
void Cursor::SetIsConversionArea(const bool fIsConversionArea) noexcept
104-
{
105-
// Functionally the same as "Hide cursor"
106-
// Never called with TRUE, it's only used in the creation of a
107-
// ConversionAreaInfo, and never changed after that.
108-
_fIsConversionArea = fIsConversionArea;
109-
_RedrawCursorAlways();
110-
}
111-
112-
void Cursor::SetDelay(const bool fDelay) noexcept
113-
{
114-
_fDelay = fDelay;
72+
if (_fIsDouble != fIsDouble)
73+
{
74+
_fIsDouble = fIsDouble;
75+
_redrawIfVisible();
76+
}
11577
}
11678

11779
void Cursor::SetSize(const ULONG ulSize) noexcept
11880
{
119-
_ulSize = ulSize;
120-
_RedrawCursor();
81+
if (_ulSize != ulSize)
82+
{
83+
_ulSize = ulSize;
84+
_redrawIfVisible();
85+
}
12186
}
12287

12388
void Cursor::SetStyle(const ULONG ulSize, const CursorType type) noexcept
12489
{
125-
_ulSize = ulSize;
126-
_cursorType = type;
127-
128-
_RedrawCursor();
129-
}
130-
131-
// Routine Description:
132-
// - Sends a redraw message to the renderer only if the cursor is currently on.
133-
// - NOTE: For use with most methods in this class.
134-
// Arguments:
135-
// - <none>
136-
// Return Value:
137-
// - <none>
138-
void Cursor::_RedrawCursor() noexcept
139-
{
140-
// Only trigger the redraw if we're on.
141-
// Don't draw the cursor if this was triggered from a conversion area.
142-
// (Conversion areas have cursors to mark the insertion point internally, but the user's actual cursor is the one on the primary screen buffer.)
143-
if (IsOn() && !IsConversionArea())
90+
if (_ulSize != ulSize || _cursorType != type)
14491
{
145-
if (_fDeferCursorRedraw)
146-
{
147-
_fHaveDeferredCursorRedraw = true;
148-
}
149-
else
150-
{
151-
_RedrawCursorAlways();
152-
}
92+
_ulSize = ulSize;
93+
_cursorType = type;
94+
_redrawIfVisible();
15395
}
15496
}
15597

156-
// Routine Description:
157-
// - Sends a redraw message to the renderer no matter what.
158-
// - NOTE: For use with the method that turns the cursor on and off to force a refresh
159-
// and clear the ON cursor from the screen. Not for use with other methods.
160-
// They should use the other method so refreshes are suppressed while the cursor is off.
161-
// Arguments:
162-
// - <none>
163-
// Return Value:
164-
// - <none>
165-
void Cursor::_RedrawCursorAlways() noexcept
166-
{
167-
_parentBuffer.NotifyPaintFrame();
168-
}
169-
17098
void Cursor::SetPosition(const til::point cPosition) noexcept
17199
{
172-
_RedrawCursor();
173-
_cPosition = cPosition;
174-
_RedrawCursor();
175-
ResetDelayEOLWrap();
100+
if (_cPosition != cPosition)
101+
{
102+
_cPosition = cPosition;
103+
ResetDelayEOLWrap();
104+
_redrawIfVisible();
105+
}
176106
}
177107

178108
void Cursor::SetXPosition(const til::CoordType NewX) noexcept
179109
{
180-
_RedrawCursor();
181-
_cPosition.x = NewX;
182-
_RedrawCursor();
183-
ResetDelayEOLWrap();
110+
if (_cPosition.x != NewX)
111+
{
112+
_cPosition.x = NewX;
113+
ResetDelayEOLWrap();
114+
_redrawIfVisible();
115+
}
184116
}
185117

186118
void Cursor::SetYPosition(const til::CoordType NewY) noexcept
187119
{
188-
_RedrawCursor();
189-
_cPosition.y = NewY;
190-
_RedrawCursor();
191-
ResetDelayEOLWrap();
120+
if (_cPosition.y != NewY)
121+
{
122+
_cPosition.y = NewY;
123+
ResetDelayEOLWrap();
124+
_redrawIfVisible();
125+
}
192126
}
193127

194128
void Cursor::IncrementXPosition(const til::CoordType DeltaX) noexcept
195129
{
196-
_RedrawCursor();
197-
_cPosition.x += DeltaX;
198-
_RedrawCursor();
199-
ResetDelayEOLWrap();
130+
if (DeltaX != 0)
131+
{
132+
_cPosition.x = _cPosition.x + DeltaX;
133+
ResetDelayEOLWrap();
134+
_redrawIfVisible();
135+
}
200136
}
201137

202138
void Cursor::IncrementYPosition(const til::CoordType DeltaY) noexcept
203139
{
204-
_RedrawCursor();
205-
_cPosition.y += DeltaY;
206-
_RedrawCursor();
207-
ResetDelayEOLWrap();
140+
if (DeltaY != 0)
141+
{
142+
_cPosition.y = _cPosition.y + DeltaY;
143+
ResetDelayEOLWrap();
144+
_redrawIfVisible();
145+
}
208146
}
209147

210148
void Cursor::DecrementXPosition(const til::CoordType DeltaX) noexcept
211149
{
212-
_RedrawCursor();
213-
_cPosition.x -= DeltaX;
214-
_RedrawCursor();
215-
ResetDelayEOLWrap();
150+
if (DeltaX != 0)
151+
{
152+
_cPosition.x = _cPosition.x - DeltaX;
153+
ResetDelayEOLWrap();
154+
_redrawIfVisible();
155+
}
216156
}
217157

218158
void Cursor::DecrementYPosition(const til::CoordType DeltaY) noexcept
219159
{
220-
_RedrawCursor();
221-
_cPosition.y -= DeltaY;
222-
_RedrawCursor();
223-
ResetDelayEOLWrap();
160+
if (DeltaY != 0)
161+
{
162+
_cPosition.y = _cPosition.y - DeltaY;
163+
ResetDelayEOLWrap();
164+
_redrawIfVisible();
165+
}
224166
}
225167

226168
///////////////////////////////////////////////////////////////////////////////
@@ -233,78 +175,53 @@ void Cursor::DecrementYPosition(const til::CoordType DeltaY) noexcept
233175
// - OtherCursor - The cursor to copy properties from
234176
// Return Value:
235177
// - <none>
236-
void Cursor::CopyProperties(const Cursor& OtherCursor) noexcept
178+
void Cursor::CopyProperties(const Cursor& other) noexcept
237179
{
238-
// We shouldn't copy the position as it will be already rearranged by the resize operation.
239-
//_cPosition = pOtherCursor->_cPosition;
240-
241-
_fIsVisible = OtherCursor._fIsVisible;
242-
_fIsOn = OtherCursor._fIsOn;
243-
_fIsDouble = OtherCursor._fIsDouble;
244-
_fBlinkingAllowed = OtherCursor._fBlinkingAllowed;
245-
_fDelay = OtherCursor._fDelay;
246-
_fIsConversionArea = OtherCursor._fIsConversionArea;
247-
248-
// A resize operation should invalidate the delayed end of line status, so do not copy.
249-
//_fDelayedEolWrap = OtherCursor._fDelayedEolWrap;
250-
//_coordDelayedAt = OtherCursor._coordDelayedAt;
251-
252-
_fDeferCursorRedraw = OtherCursor._fDeferCursorRedraw;
253-
_fHaveDeferredCursorRedraw = OtherCursor._fHaveDeferredCursorRedraw;
254-
255-
// Size will be handled separately in the resize operation.
256-
//_ulSize = OtherCursor._ulSize;
257-
_cursorType = OtherCursor._cursorType;
180+
_cPosition = other._cPosition;
181+
_coordDelayedAt = other._coordDelayedAt;
182+
_ulSize = other._ulSize;
183+
_cursorType = other._cursorType;
184+
_isVisible = other._isVisible;
185+
_isBlinking = other._isBlinking;
186+
_fIsDouble = other._fIsDouble;
258187
}
259188

260189
void Cursor::DelayEOLWrap() noexcept
261190
{
262191
_coordDelayedAt = _cPosition;
263-
_fDelayedEolWrap = true;
264192
}
265193

266194
void Cursor::ResetDelayEOLWrap() noexcept
267195
{
268-
_coordDelayedAt = {};
269-
_fDelayedEolWrap = false;
196+
_coordDelayedAt.reset();
270197
}
271198

272-
til::point Cursor::GetDelayedAtPosition() const noexcept
199+
const std::optional<til::point>& Cursor::GetDelayEOLWrap() const noexcept
273200
{
274201
return _coordDelayedAt;
275202
}
276203

277-
bool Cursor::IsDelayedEOLWrap() const noexcept
204+
CursorType Cursor::GetType() const noexcept
278205
{
279-
return _fDelayedEolWrap;
280-
}
281-
282-
void Cursor::StartDeferDrawing() noexcept
283-
{
284-
_fDeferCursorRedraw = true;
206+
return _cursorType;
285207
}
286208

287-
bool Cursor::IsDeferDrawing() noexcept
209+
void Cursor::SetType(const CursorType type) noexcept
288210
{
289-
return _fDeferCursorRedraw;
211+
_cursorType = type;
290212
}
291213

292-
void Cursor::EndDeferDrawing() noexcept
214+
void Cursor::_redrawIfVisible() noexcept
293215
{
294-
if (_fHaveDeferredCursorRedraw)
216+
_mutationId++;
217+
if (IsVisible())
295218
{
296-
_RedrawCursorAlways();
219+
_parentBuffer.NotifyPaintFrame();
297220
}
298-
299-
_fDeferCursorRedraw = FALSE;
300221
}
301222

302-
const CursorType Cursor::GetType() const noexcept
223+
void Cursor::_redraw() noexcept
303224
{
304-
return _cursorType;
305-
}
306-
307-
void Cursor::SetType(const CursorType type) noexcept
308-
{
309-
_cursorType = type;
225+
_mutationId++;
226+
_parentBuffer.NotifyPaintFrame();
310227
}

0 commit comments

Comments
 (0)