1313// - ulSize - The height of the cursor within this buffer
1414Cursor::Cursor (const ULONG ulSize, TextBuffer& parentBuffer) noexcept :
1515 _parentBuffer{ parentBuffer },
16- _fHasMoved (false ),
17- _fIsVisible(true ),
18- _fIsOn(true ),
19- _fIsDouble(false ),
20- _fBlinkingAllowed(true ),
21- _fDelay(false ),
22- _fIsConversionArea(false ),
23- _fDelayedEolWrap(false ),
24- _fDeferCursorRedraw(false ),
25- _fHaveDeferredCursorRedraw(false ),
26- _ulSize(ulSize),
27- _cursorType(CursorType::Legacy)
16+ _ulSize (ulSize)
2817{
2918}
3019
@@ -35,203 +24,145 @@ til::point Cursor::GetPosition() const noexcept
3524 return _cPosition;
3625}
3726
38- bool Cursor::HasMoved () const noexcept
27+ uint64_t Cursor::GetLastMutationId () const noexcept
3928{
40- return _fHasMoved ;
29+ return _mutationId ;
4130}
4231
4332bool Cursor::IsVisible () const noexcept
4433{
45- return _fIsVisible ;
34+ return _isVisible ;
4635}
4736
48- bool Cursor::IsOn () const noexcept
37+ bool Cursor::IsBlinking () const noexcept
4938{
50- return _fIsOn;
51- }
52-
53- bool Cursor::IsBlinkingAllowed () const noexcept
54- {
55- return _fBlinkingAllowed;
39+ return _isBlinking;
5640}
5741
5842bool Cursor::IsDouble () const noexcept
5943{
6044 return _fIsDouble;
6145}
6246
63- bool Cursor::IsConversionArea () const noexcept
64- {
65- return _fIsConversionArea;
66- }
67-
68- bool Cursor::GetDelay () const noexcept
69- {
70- return _fDelay;
71- }
72-
7347ULONG Cursor::GetSize () const noexcept
7448{
7549 return _ulSize;
7650}
7751
78- void Cursor::SetHasMoved (const bool fHasMoved ) noexcept
79- {
80- _fHasMoved = fHasMoved ;
81- }
82-
83- void Cursor::SetIsVisible (const bool fIsVisible ) noexcept
84- {
85- _fIsVisible = fIsVisible ;
86- _RedrawCursor ();
87- }
88-
89- void Cursor::SetIsOn (const bool fIsOn ) noexcept
52+ void Cursor::SetIsVisible (bool enable)
9053{
91- _fIsOn = fIsOn ;
92- _RedrawCursorAlways ();
54+ if (_isVisible != enable)
55+ {
56+ _isVisible = enable;
57+ _redrawIfVisible ();
58+ }
9359}
9460
95- void Cursor::SetBlinkingAllowed ( const bool fBlinkingAllowed ) noexcept
61+ void Cursor::SetIsBlinking ( bool enable)
9662{
97- _fBlinkingAllowed = fBlinkingAllowed ;
98- // GH#2642 - From what we've gathered from other terminals, when blinking is
99- // disabled, the cursor should remain On always, and have the visibility
100- // controlled by the IsVisible property. So when you do a printf "\e[?12l"
101- // to disable blinking, the cursor stays stuck On. At this point, only the
102- // cursor visibility property controls whether the user can see it or not.
103- // (Yes, the cursor can be On and NOT Visible)
104- _fIsOn = true ;
105- _RedrawCursorAlways ();
63+ if (_isBlinking != enable)
64+ {
65+ _isBlinking = enable;
66+ _redrawIfVisible ();
67+ }
10668}
10769
10870void Cursor::SetIsDouble (const bool fIsDouble ) noexcept
10971{
110- _fIsDouble = fIsDouble ;
111- _RedrawCursor ();
112- }
113-
114- void Cursor::SetIsConversionArea (const bool fIsConversionArea ) noexcept
115- {
116- // Functionally the same as "Hide cursor"
117- // Never called with TRUE, it's only used in the creation of a
118- // ConversionAreaInfo, and never changed after that.
119- _fIsConversionArea = fIsConversionArea ;
120- _RedrawCursorAlways ();
121- }
122-
123- void Cursor::SetDelay (const bool fDelay ) noexcept
124- {
125- _fDelay = fDelay ;
72+ if (_fIsDouble != fIsDouble )
73+ {
74+ _fIsDouble = fIsDouble ;
75+ _redrawIfVisible ();
76+ }
12677}
12778
12879void Cursor::SetSize (const ULONG ulSize) noexcept
12980{
130- _ulSize = ulSize;
131- _RedrawCursor ();
81+ if (_ulSize != ulSize)
82+ {
83+ _ulSize = ulSize;
84+ _redrawIfVisible ();
85+ }
13286}
13387
13488void Cursor::SetStyle (const ULONG ulSize, const CursorType type) noexcept
13589{
136- _ulSize = ulSize;
137- _cursorType = type;
138-
139- _RedrawCursor ();
140- }
141-
142- // Routine Description:
143- // - Sends a redraw message to the renderer only if the cursor is currently on.
144- // - NOTE: For use with most methods in this class.
145- // Arguments:
146- // - <none>
147- // Return Value:
148- // - <none>
149- void Cursor::_RedrawCursor () noexcept
150- {
151- // Only trigger the redraw if we're on.
152- // Don't draw the cursor if this was triggered from a conversion area.
153- // (Conversion areas have cursors to mark the insertion point internally, but the user's actual cursor is the one on the primary screen buffer.)
154- if (IsOn () && !IsConversionArea ())
90+ if (_ulSize != ulSize || _cursorType != type)
15591 {
156- if (_fDeferCursorRedraw)
157- {
158- _fHaveDeferredCursorRedraw = true ;
159- }
160- else
161- {
162- _RedrawCursorAlways ();
163- }
92+ _ulSize = ulSize;
93+ _cursorType = type;
94+ _redrawIfVisible ();
16495 }
16596}
16697
167- // Routine Description:
168- // - Sends a redraw message to the renderer no matter what.
169- // - NOTE: For use with the method that turns the cursor on and off to force a refresh
170- // and clear the ON cursor from the screen. Not for use with other methods.
171- // They should use the other method so refreshes are suppressed while the cursor is off.
172- // Arguments:
173- // - <none>
174- // Return Value:
175- // - <none>
176- void Cursor::_RedrawCursorAlways () noexcept
177- {
178- _parentBuffer.NotifyPaintFrame ();
179- }
180-
18198void Cursor::SetPosition (const til::point cPosition) noexcept
18299{
183- _RedrawCursor ();
184- _cPosition = cPosition;
185- _RedrawCursor ();
186- ResetDelayEOLWrap ();
100+ if (_cPosition != cPosition)
101+ {
102+ _cPosition = cPosition;
103+ ResetDelayEOLWrap ();
104+ _redrawIfVisible ();
105+ }
187106}
188107
189108void Cursor::SetXPosition (const til::CoordType NewX) noexcept
190109{
191- _RedrawCursor ();
192- _cPosition.x = NewX;
193- _RedrawCursor ();
194- ResetDelayEOLWrap ();
110+ if (_cPosition.x != NewX)
111+ {
112+ _cPosition.x = NewX;
113+ ResetDelayEOLWrap ();
114+ _redrawIfVisible ();
115+ }
195116}
196117
197118void Cursor::SetYPosition (const til::CoordType NewY) noexcept
198119{
199- _RedrawCursor ();
200- _cPosition.y = NewY;
201- _RedrawCursor ();
202- ResetDelayEOLWrap ();
120+ if (_cPosition.y != NewY)
121+ {
122+ _cPosition.y = NewY;
123+ ResetDelayEOLWrap ();
124+ _redrawIfVisible ();
125+ }
203126}
204127
205128void Cursor::IncrementXPosition (const til::CoordType DeltaX) noexcept
206129{
207- _RedrawCursor ();
208- _cPosition.x += DeltaX;
209- _RedrawCursor ();
210- ResetDelayEOLWrap ();
130+ if (DeltaX != 0 )
131+ {
132+ _cPosition.x = _cPosition.x + DeltaX;
133+ ResetDelayEOLWrap ();
134+ _redrawIfVisible ();
135+ }
211136}
212137
213138void Cursor::IncrementYPosition (const til::CoordType DeltaY) noexcept
214139{
215- _RedrawCursor ();
216- _cPosition.y += DeltaY;
217- _RedrawCursor ();
218- ResetDelayEOLWrap ();
140+ if (DeltaY != 0 )
141+ {
142+ _cPosition.y = _cPosition.y + DeltaY;
143+ ResetDelayEOLWrap ();
144+ _redrawIfVisible ();
145+ }
219146}
220147
221148void Cursor::DecrementXPosition (const til::CoordType DeltaX) noexcept
222149{
223- _RedrawCursor ();
224- _cPosition.x -= DeltaX;
225- _RedrawCursor ();
226- ResetDelayEOLWrap ();
150+ if (DeltaX != 0 )
151+ {
152+ _cPosition.x = _cPosition.x - DeltaX;
153+ ResetDelayEOLWrap ();
154+ _redrawIfVisible ();
155+ }
227156}
228157
229158void Cursor::DecrementYPosition (const til::CoordType DeltaY) noexcept
230159{
231- _RedrawCursor ();
232- _cPosition.y -= DeltaY;
233- _RedrawCursor ();
234- ResetDelayEOLWrap ();
160+ if (DeltaY != 0 )
161+ {
162+ _cPosition.y = _cPosition.y - DeltaY;
163+ ResetDelayEOLWrap ();
164+ _redrawIfVisible ();
165+ }
235166}
236167
237168// /////////////////////////////////////////////////////////////////////////////
@@ -244,79 +175,53 @@ void Cursor::DecrementYPosition(const til::CoordType DeltaY) noexcept
244175// - OtherCursor - The cursor to copy properties from
245176// Return Value:
246177// - <none>
247- void Cursor::CopyProperties (const Cursor& OtherCursor ) noexcept
178+ void Cursor::CopyProperties (const Cursor& other ) noexcept
248179{
249- // We shouldn't copy the position as it will be already rearranged by the resize operation.
250- // _cPosition = pOtherCursor->_cPosition;
251-
252- _fHasMoved = OtherCursor._fHasMoved ;
253- _fIsVisible = OtherCursor._fIsVisible ;
254- _fIsOn = OtherCursor._fIsOn ;
255- _fIsDouble = OtherCursor._fIsDouble ;
256- _fBlinkingAllowed = OtherCursor._fBlinkingAllowed ;
257- _fDelay = OtherCursor._fDelay ;
258- _fIsConversionArea = OtherCursor._fIsConversionArea ;
259-
260- // A resize operation should invalidate the delayed end of line status, so do not copy.
261- // _fDelayedEolWrap = OtherCursor._fDelayedEolWrap;
262- // _coordDelayedAt = OtherCursor._coordDelayedAt;
263-
264- _fDeferCursorRedraw = OtherCursor._fDeferCursorRedraw ;
265- _fHaveDeferredCursorRedraw = OtherCursor._fHaveDeferredCursorRedraw ;
266-
267- // Size will be handled separately in the resize operation.
268- // _ulSize = OtherCursor._ulSize;
269- _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 ;
270187}
271188
272189void Cursor::DelayEOLWrap () noexcept
273190{
274191 _coordDelayedAt = _cPosition;
275- _fDelayedEolWrap = true ;
276192}
277193
278194void Cursor::ResetDelayEOLWrap () noexcept
279195{
280- _coordDelayedAt = {};
281- _fDelayedEolWrap = false ;
196+ _coordDelayedAt.reset ();
282197}
283198
284- til::point Cursor::GetDelayedAtPosition () const noexcept
199+ const std::optional< til::point>& Cursor::GetDelayEOLWrap () const noexcept
285200{
286201 return _coordDelayedAt;
287202}
288203
289- bool Cursor::IsDelayedEOLWrap () const noexcept
204+ CursorType Cursor::GetType () const noexcept
290205{
291- return _fDelayedEolWrap;
292- }
293-
294- void Cursor::StartDeferDrawing () noexcept
295- {
296- _fDeferCursorRedraw = true ;
206+ return _cursorType;
297207}
298208
299- bool Cursor::IsDeferDrawing ( ) noexcept
209+ void Cursor::SetType ( const CursorType type ) noexcept
300210{
301- return _fDeferCursorRedraw ;
211+ _cursorType = type ;
302212}
303213
304- void Cursor::EndDeferDrawing () noexcept
214+ void Cursor::_redrawIfVisible () noexcept
305215{
306- if (_fHaveDeferredCursorRedraw)
216+ _mutationId++;
217+ if (IsVisible ())
307218 {
308- _RedrawCursorAlways ();
219+ _parentBuffer. NotifyPaintFrame ();
309220 }
310-
311- _fDeferCursorRedraw = FALSE ;
312- }
313-
314- const CursorType Cursor::GetType () const noexcept
315- {
316- return _cursorType;
317221}
318222
319- void Cursor::SetType ( const CursorType type ) noexcept
223+ void Cursor::_redraw ( ) noexcept
320224{
321- _cursorType = type;
225+ _mutationId++;
226+ _parentBuffer.NotifyPaintFrame ();
322227}
0 commit comments