From 47068f41971658a552c2495052028f3db8e68524 Mon Sep 17 00:00:00 2001
From: jackson <63016612+fairybow@users.noreply.github.com>
Date: Fri, 24 Feb 2023 11:06:52 -0500
Subject: [PATCH] Typewriter & center on scroll :tophat:
- Updated Readme
- Added UserData / MainWindow menu options for Cursor "center on scroll" and "Typewriter" positioning
- Rewrote how Splitter/SplitterHandle handle initialization
- Added Splitter::hasHover check
- Added the toggling methods for Cursor COS/Typewriter to PlainTextEdit/Editor
---
Fernanda/docs/Notes.md | 9 ++++++-
Fernanda/docs/To-do.md | 3 +++
Fernanda/source/Editor.cpp | 23 +++++++++++++-----
Fernanda/source/Editor.h | 8 +++++--
Fernanda/source/MainWindow.cpp | 14 ++++++++---
Fernanda/source/PlainTextEdit.cpp | 12 ++++++++--
Fernanda/source/PlainTextEdit.h | 7 ++++--
Fernanda/source/Splitter.cpp | 39 ++++++++++++++-----------------
Fernanda/source/Splitter.h | 3 ++-
Fernanda/source/SplitterHandle.h | 5 ++--
Fernanda/source/UserData.cpp | 6 +++++
Fernanda/source/UserData.h | 2 ++
Fernanda/source/Version.h | 4 ++--
README.md | 19 ++++++++-------
14 files changed, 101 insertions(+), 53 deletions(-)
diff --git a/Fernanda/docs/Notes.md b/Fernanda/docs/Notes.md
index 4b1e600..71f9060 100644
--- a/Fernanda/docs/Notes.md
+++ b/Fernanda/docs/Notes.md
@@ -13,4 +13,11 @@
-
\ No newline at end of file
+
+
+```
+auto view = viewport();
+auto height = view->height();
+auto y = (height / 2) - cursorRect().y();
+viewport()->setGeometry(view->x(), y, view->width(), height);
+```
diff --git a/Fernanda/docs/To-do.md b/Fernanda/docs/To-do.md
index d9d57ca..e42c0e2 100644
--- a/Fernanda/docs/To-do.md
+++ b/Fernanda/docs/To-do.md
@@ -82,6 +82,8 @@
- [x] ~~Probably should combine `elements()` and `elementsByAttribute()`~~
### Editor / PlainTextEdit / LineNumberArea
+- [ ] "Ribbon" mode
+- [ ] A toggleable for every relevant `QPlainTextEdit` toggleable (`centerOnScroll` for example)
- [ ] It is not clear to me that `updateLineNumberAreaWidth(int newBlockCount)` actually uses `newBlockCount` arg
- [ ] Save undo/redo stacks
- [ ] Editor spacing and kerning sliders
@@ -91,6 +93,7 @@
- [ ] Wrap for parentheses and other closables
- [ ] If a filter was just applied, backspace should function as undo
- [ ] Make thin cursor change color when there's a selection?
+- [x] ~~Typewriter mode~~
- [x] ~~Avoid passing entire document for cursor underpaint lol~~
- [x] ~~Toggle chonky cursor vs regular~~
- [x] ~~Style horizontal scrollbar~~
diff --git a/Fernanda/source/Editor.cpp b/Fernanda/source/Editor.cpp
index 4373fea..5452bb3 100644
--- a/Fernanda/source/Editor.cpp
+++ b/Fernanda/source/Editor.cpp
@@ -58,16 +58,25 @@ void Editor::devRemoveStyle()
void Editor::toggle(bool checked, Has has)
{
switch (has) {
- case Has::BlockCursor:
- hasBlockCursor = checked;
- plainTextEdit->cursorPositionChanged();
- UserData::saveConfig(UserData::IniGroup::Editor, UserData::IniValue::ToggleCursorBlock, checked);
- break;
case Has::CursorBlink:
hasCursorBlink = checked;
startBlinker();
UserData::saveConfig(UserData::IniGroup::Editor, UserData::IniValue::ToggleCursorBlink, checked);
break;
+ case Has::CursorBlock:
+ hasCursorBlock = checked;
+ plainTextEdit->cursorPositionChanged();
+ UserData::saveConfig(UserData::IniGroup::Editor, UserData::IniValue::ToggleCursorBlock, checked);
+ break;
+ case Has::CursorCenterOnScroll:
+ askToggleCenterOnScroll(checked);
+ UserData::saveConfig(UserData::IniGroup::Editor, UserData::IniValue::ToggleCursorCenterOnScroll, checked);
+ break;
+ case Has::CursorTypewriter:
+ hasCursorTypewriter = checked;
+ plainTextEdit->textChanged();
+ UserData::saveConfig(UserData::IniGroup::Editor, UserData::IniValue::ToggleCursorTypewriter, checked);
+ break;
case Has::ExtraScrolls:
askToggleExtraScrolls(checked);
UserData::saveConfig(UserData::IniGroup::Editor, UserData::IniValue::ToggleScrollsPrevNext, checked);
@@ -185,6 +194,7 @@ void Editor::close(bool isFinal)
void Editor::connections()
{
+ connect(this, &Editor::askToggleCenterOnScroll, plainTextEdit, &PlainTextEdit::toggleCenterOnScroll);
connect(this, &Editor::askToggleLineNumberArea, plainTextEdit, &PlainTextEdit::toggleLineNumberArea);
connect(this, &Editor::askToggleScrolls, plainTextEdit, &PlainTextEdit::toggleScrolls);
connect(this, &Editor::askToggleExtraScrolls, plainTextEdit, &PlainTextEdit::toggleExtraScrolls);
@@ -205,7 +215,8 @@ void Editor::connections()
connect(plainTextEdit, &PlainTextEdit::askHasLineHighlight, this, [&]() { return hasLineHighlight; });
connect(plainTextEdit, &PlainTextEdit::askHasKeyFilter, this, [&]() { return hasKeyFilter; });
connect(plainTextEdit, &PlainTextEdit::askHasCursorBlink, this, [&]() { return hasCursorBlink; });
- connect(plainTextEdit, &PlainTextEdit::askHasBlockCursor, this, [&]() { return hasBlockCursor; });
+ connect(plainTextEdit, &PlainTextEdit::askHasCursorBlock, this, [&]() { return hasCursorBlock; });
+ connect(plainTextEdit, &PlainTextEdit::askHasCursorTypewriter, this, [&]() { return hasCursorTypewriter; });
connect(plainTextEdit, &PlainTextEdit::askCursorVisible, this, [&]() { return cursorVisible; });
connect(plainTextEdit, &PlainTextEdit::cursorPositionChanged, this, [&]() { cursorPositionChanged(); });
connect(plainTextEdit, &PlainTextEdit::selectionChanged, this, [&]() { selectionChanged(); });
diff --git a/Fernanda/source/Editor.h b/Fernanda/source/Editor.h
index acfd912..7d2e7bb 100644
--- a/Fernanda/source/Editor.h
+++ b/Fernanda/source/Editor.h
@@ -37,8 +37,10 @@ class Editor : public QWidget
AcceptNew
};
enum class Has {
- BlockCursor,
CursorBlink,
+ CursorBlock,
+ CursorCenterOnScroll,
+ CursorTypewriter,
ExtraScrolls,
KeyFilter,
LineHighlight,
@@ -92,7 +94,8 @@ public slots:
bool hasLineHighlight = true;
bool hasKeyFilter = true;
bool hasCursorBlink = true;
- bool hasBlockCursor = true;
+ bool hasCursorBlock = true;
+ bool hasCursorTypewriter = false;
bool cursorVisible = true;
void connections();
@@ -109,6 +112,7 @@ public slots:
bool askHasProject();
QAction* askTheme();
QActionGroup* askThemes();
+ void askToggleCenterOnScroll(bool checked);
void askToggleExtraScrolls(bool checked);
void askToggleLineNumberArea(bool checked);
void askToggleScrolls(bool checked);
diff --git a/Fernanda/source/MainWindow.cpp b/Fernanda/source/MainWindow.cpp
index be2dff6..14d4696 100644
--- a/Fernanda/source/MainWindow.cpp
+++ b/Fernanda/source/MainWindow.cpp
@@ -382,6 +382,8 @@ void MainWindow::makeToggleMenu()
auto load_most_recent_toggle = new QAction(tr("&Load most recent project on open"), this);
auto cursor_blink_toggle = new QAction(tr("&Blink"), this);
auto cursor_block_toggle = new QAction(tr("&Block"), this);
+ auto cursor_center_on_scroll_toggle = new QAction(tr("&Center on scroll"), this);
+ auto cursor_typewriter_toggle = new QAction(tr("&Typewriter"), this);
auto current_line_highlight_toggle = new QAction(tr("&Current line highlight"), this);
auto editor_shadow_toggle = new QAction(tr("&Editor shadow"), this);
auto editor_theme_toggle = new QAction(tr("&Editor theme"), this);
@@ -393,7 +395,7 @@ void MainWindow::makeToggleMenu()
auto indicator_toggle = new QAction(tr("&Indicator"), this);
auto preview_toggle = new QAction(tr("&Preview"), this);
auto status_bar_toggle = new QAction(tr("&Status bar"), this);
- auto aot_toggle = new QAction(tr("&Always-on-top"), this);
+ auto aot_toggle = new QAction(tr("&Always on top"), this);
auto stay_awake_toggle = new QAction(tr("&Stay awake"), this);
auto timer_toggle = new QAction(tr("&Timer"), this);
auto window_theme_toggle = new QAction(tr("&Window theme"), this);
@@ -402,7 +404,9 @@ void MainWindow::makeToggleMenu()
UserData::saveConfig(UserData::IniGroup::Data, UserData::IniValue::ToggleLoadMostRecent, checked); // move to story?
});
connect(cursor_blink_toggle, &QAction::toggled, this, [&](bool checked) { editor->toggle(checked, Editor::Has::CursorBlink); });
- connect(cursor_block_toggle, &QAction::toggled, this, [&](bool checked) { editor->toggle(checked, Editor::Has::BlockCursor); });
+ connect(cursor_block_toggle, &QAction::toggled, this, [&](bool checked) { editor->toggle(checked, Editor::Has::CursorBlock); });
+ connect(cursor_center_on_scroll_toggle, &QAction::toggled, this, [&](bool checked) { editor->toggle(checked, Editor::Has::CursorCenterOnScroll); });
+ connect(cursor_typewriter_toggle, &QAction::toggled, this, [&](bool checked) { editor->toggle(checked, Editor::Has::CursorTypewriter); });
connect(current_line_highlight_toggle, &QAction::toggled, this, [&](bool checked) { editor->toggle(checked, Editor::Has::LineHighlight); });
connect(editor_shadow_toggle, &QAction::toggled, this, [&](bool checked) { editor->toggle(checked, Editor::Has::Shadow); });
connect(editor_theme_toggle, &QAction::toggled, this, [&](bool checked) { editor->toggle(checked, Editor::Has::Theme); });
@@ -436,6 +440,8 @@ void MainWindow::makeToggleMenu()
load_most_recent_toggle,
cursor_blink_toggle,
cursor_block_toggle,
+ cursor_center_on_scroll_toggle,
+ cursor_typewriter_toggle,
current_line_highlight_toggle,
editor_shadow_toggle,
editor_theme_toggle,
@@ -456,6 +462,8 @@ void MainWindow::makeToggleMenu()
loadMenuToggle(load_most_recent_toggle, UserData::IniGroup::Data, UserData::IniValue::ToggleLoadMostRecent, false);
loadMenuToggle(cursor_blink_toggle, UserData::IniGroup::Editor, UserData::IniValue::ToggleCursorBlink, true);
loadMenuToggle(cursor_block_toggle, UserData::IniGroup::Editor, UserData::IniValue::ToggleCursorBlock, true);
+ loadMenuToggle(cursor_center_on_scroll_toggle, UserData::IniGroup::Editor, UserData::IniValue::ToggleCursorCenterOnScroll, false);
+ loadMenuToggle(cursor_typewriter_toggle, UserData::IniGroup::Editor, UserData::IniValue::ToggleCursorTypewriter, false);
loadMenuToggle(current_line_highlight_toggle, UserData::IniGroup::Editor, UserData::IniValue::ToggleLineHighlight, true);
loadMenuToggle(editor_shadow_toggle, UserData::IniGroup::Editor, UserData::IniValue::ToggleEditorShadow, true);
loadMenuToggle(editor_theme_toggle, UserData::IniGroup::Editor, UserData::IniValue::ToggleEditorTheme, true);
@@ -475,7 +483,7 @@ void MainWindow::makeToggleMenu()
toggle->addAction(load_most_recent_toggle);
toggle->addSeparator();
auto cursor = toggle->addMenu(tr("&Cursor"));
- for (const auto& action : { cursor_blink_toggle, cursor_block_toggle })
+ for (const auto& action : { cursor_blink_toggle, cursor_block_toggle, cursor_center_on_scroll_toggle, cursor_typewriter_toggle })
cursor->addAction(action);
for (const auto& action : { current_line_highlight_toggle, editor_shadow_toggle, editor_theme_toggle, key_filter_toggle, line_number_area_toggle, scrolls_previous_next_toggle })
toggle->addAction(action);
diff --git a/Fernanda/source/PlainTextEdit.cpp b/Fernanda/source/PlainTextEdit.cpp
index ca0b025..ec6d025 100644
--- a/Fernanda/source/PlainTextEdit.cpp
+++ b/Fernanda/source/PlainTextEdit.cpp
@@ -184,7 +184,7 @@ void PlainTextEdit::paintEvent(QPaintEvent* event)
auto current_char = currentChar();
auto rect = reshapeCursor(current_char);
painter.fillRect(rect, recolorCursor());
- if (!current_char.isNull() && askHasBlockCursor())
+ if (!current_char.isNull() && askHasCursorBlock())
{
painter.setPen(recolorCursor(true));
painter.drawText(rect, current_char);
@@ -315,6 +315,8 @@ void PlainTextEdit::connections()
connect(this, &PlainTextEdit::blockCountChanged, this, &PlainTextEdit::updateLineNumberAreaWidth);
connect(this, &PlainTextEdit::updateRequest, this, &PlainTextEdit::updateLineNumberArea);
connect(this, &PlainTextEdit::cursorPositionChanged, this, &PlainTextEdit::highlightCurrentLine);
+ connect(this, &PlainTextEdit::cursorPositionChanged, this, &PlainTextEdit::typewriter);
+ connect(this, &PlainTextEdit::textChanged, this, &PlainTextEdit::typewriter);
connect(verticalScrollBar(), &QScrollBar::rangeChanged, this, &PlainTextEdit::scrollButtonEnabledHandler);
connect(verticalScrollBar(), &QScrollBar::valueChanged, this, &PlainTextEdit::scrollButtonEnabledHandler);
connect(verticalScrollBar(), &QScrollBar::valueChanged, this, [&]() { sendBlockNumber(firstVisibleBlock().blockNumber()); });
@@ -334,7 +336,7 @@ void PlainTextEdit::connections()
const QRect PlainTextEdit::reshapeCursor(QChar currentChar)
{
- if (askHasBlockCursor())
+ if (askHasCursorBlock())
{
QFontMetrics metrics(font());
currentChar.isNull()
@@ -386,4 +388,10 @@ void PlainTextEdit::updateLineNumberArea(const QRect& rect, int dy)
updateLineNumberAreaWidth(0);
}
+void PlainTextEdit::typewriter()
+{
+ if (!askHasCursorTypewriter()) return;
+ centerCursor();
+}
+
// PlainTextEdit.cpp, Fernanda
diff --git a/Fernanda/source/PlainTextEdit.h b/Fernanda/source/PlainTextEdit.h
index 2df63b8..cd434bb 100644
--- a/Fernanda/source/PlainTextEdit.h
+++ b/Fernanda/source/PlainTextEdit.h
@@ -72,6 +72,8 @@ public slots:
void toggleScrolls(bool checked);
void toggleExtraScrolls(bool checked);
+ void toggleCenterOnScroll(bool checked) { setCenterOnScroll(checked); }
+
protected:
void resizeEvent(QResizeEvent* event) override;
void paintEvent(QPaintEvent* event) override;
@@ -103,6 +105,7 @@ public slots:
private slots:
void scrollButtonEnabledHandler();
void updateLineNumberArea(const QRect& rect, int dy);
+ void typewriter();
void updateLineNumberAreaWidth(int newBlockCount) { setViewportMargins(lineNumberAreaWidth(), 0, 0, 0); }
@@ -111,8 +114,9 @@ private slots:
void askFontSliderZoom(Zoom direction);
void askGoNext();
void askGoPrevious();
- bool askHasBlockCursor();
bool askHasCursorBlink();
+ bool askHasCursorBlock();
+ bool askHasCursorTypewriter();
bool askHasKeyFilter();
bool askHasLineHighlight();
bool askHasProject();
@@ -122,7 +126,6 @@ private slots:
class LineNumberArea : public QWidget
{
-
public:
LineNumberArea(PlainTextEdit* parent) : QWidget(parent), parent(parent) {}
diff --git a/Fernanda/source/Splitter.cpp b/Fernanda/source/Splitter.cpp
index f8ef869..f8cb516 100644
--- a/Fernanda/source/Splitter.cpp
+++ b/Fernanda/source/Splitter.cpp
@@ -93,7 +93,6 @@ SplitterHandle* Splitter::createHandle()
{
auto handle = new SplitterHandle(orientation(), this);
connect(handle, &SplitterHandle::askHoverExpand, this, &Splitter::hoverExpand);
- connect(handle, &SplitterHandle::askIsInitialized, this, &Splitter::initialize);
connect(handle, &SplitterHandle::askStoreWidths, this, &Splitter::storeWidths);
connect(handle, &SplitterHandle::askToggleExpansion, this, &Splitter::toggleExpansion);
connect(handle, &SplitterHandle::askUnhoverAll, this, &Splitter::unhoverAll);
@@ -147,6 +146,16 @@ bool Splitter::eventFilter(QObject* watched, QEvent* event)
return false;
}
+void Splitter::initialize()
+{
+ for (auto& widget_info : widgets)
+ {
+ if (widget_info.width) continue;
+ widget_info.state = State::Collapsed;
+ isInitialized = true;
+ }
+}
+
void Splitter::checkStates(int position, int index)
{
for (auto& widget_info : widgets)
@@ -157,11 +166,11 @@ void Splitter::checkStates(int position, int index)
auto& widget_state = widget_info.state;
(handle_index < 2)
? (position != 0)
- ? widget_state = State::Expanded
- : widget_state = State::Collapsed
+ ? widget_state = State::Expanded
+ : widget_state = State::Collapsed
: (position != (askWindowSize().width() - handleWidth()))
- ? widget_state = State::Expanded
- : widget_state = State::Collapsed;
+ ? widget_state = State::Expanded
+ : widget_state = State::Collapsed;
}
}
@@ -175,24 +184,10 @@ void Splitter::hoverExpand(SplitterHandle* handlePtr)
}
}
-void Splitter::initialize()
-{
- if (isInitialized)
- {
- storeWidths();
- return;
- }
- for (auto& widget_info : widgets)
- {
- if (widget_info.width) continue;
- widget_info.state = State::Collapsed;
- }
- storeWidths();
- isInitialized = true;
-}
-
void Splitter::storeWidths()
{
+ if (!isInitialized)
+ initialize();
for (auto& widget_info : widgets)
{
if (!isExpanded(widget_info)) continue;
@@ -220,7 +215,7 @@ void Splitter::unhoverAll()
if (!isHoverExpanded(widget_info)) continue;
QTimer::singleShot(250, this, [&]()
{
- if (!widget(widget_info.index)->underMouse() && !handle(widget_info.handleIndex)->underMouse())
+ if (!hasHover(widget_info))
collapse(widget_info);
});
}
diff --git a/Fernanda/source/Splitter.h b/Fernanda/source/Splitter.h
index 3bef538..b2c1d11 100644
--- a/Fernanda/source/Splitter.h
+++ b/Fernanda/source/Splitter.h
@@ -66,18 +66,19 @@ class Splitter : public QSplitter
void expand(Info& widgetInfo, bool isHover = false);
void uncollapseAll();
bool eventFilter(QObject* watched, QEvent* event);
+ void initialize();
int toWindowX(int index, int size) { return (index < 2) ? size : askWindowSize().width() - size; }
bool match(SplitterHandle* handlePtr, Info& widgetInfo) const { return (handlePtr == handle(widgetInfo.handleIndex)); }
bool isCollapsed(Info& widgetInfo) const { return (widgetInfo.state == State::Collapsed); }
bool isExpanded(Info& widgetInfo) const { return (widgetInfo.state == State::Expanded); }
bool isHoverExpanded(Info& widgetInfo) const { return (widgetInfo.state == State::HoverExpanded); }
+ bool hasHover(Info& widgetInfo) const { return (widget(widgetInfo.index)->underMouse() || handle(widgetInfo.handleIndex)->underMouse()); }
private slots:
void checkStates(int position, int index);
void hoverExpand(SplitterHandle* handlePtr);
- void initialize();
void storeWidths();
void toggleExpansion(SplitterHandle* handlePtr);
void unhoverAll();
diff --git a/Fernanda/source/SplitterHandle.h b/Fernanda/source/SplitterHandle.h
index b8a7966..6922487 100644
--- a/Fernanda/source/SplitterHandle.h
+++ b/Fernanda/source/SplitterHandle.h
@@ -31,7 +31,7 @@ class SplitterHandle : public QSplitterHandle
expanding->setDuration(100);
expanding->setEasingCurve(QEasingCurve::OutQuad);
expanding->setStartValue(splitter()->handleWidth());
- expanding->setEndValue(splitter()->handleWidth() * 1.5);
+ expanding->setEndValue(splitter()->handleWidth() * 1.6);
connect(hoverTrigger, &QTimer::timeout, this, [&]()
{
askHoverExpand(this);
@@ -62,7 +62,7 @@ class SplitterHandle : public QSplitterHandle
result = true;
break;
case QEvent::MouseButtonRelease:
- askIsInitialized();
+ askStoreWidths();
result = true;
break;
case QEvent::MouseButtonDblClick:
@@ -78,7 +78,6 @@ class SplitterHandle : public QSplitterHandle
signals:
void askHoverExpand(SplitterHandle* handlePtr);
- void askIsInitialized();
void askStoreWidths();
void askToggleExpansion(SplitterHandle* handlePtr);
void askUnhoverAll();
diff --git a/Fernanda/source/UserData.cpp b/Fernanda/source/UserData.cpp
index ba7e936..8cee1d8 100644
--- a/Fernanda/source/UserData.cpp
+++ b/Fernanda/source/UserData.cpp
@@ -171,6 +171,12 @@ const QString UserData::valueName(IniValue valueType)
case IniValue::ToggleCursorBlock:
result = "toggle__cursor_block";
break;
+ case IniValue::ToggleCursorCenterOnScroll:
+ result = "toggle__cursor_center_on_scroll";
+ break;
+ case IniValue::ToggleCursorTypewriter:
+ result = "toggle__cursor_typewriter";
+ break;
case IniValue::ToggleEditorShadow:
result = "toggle__editor_shadow";
break;
diff --git a/Fernanda/source/UserData.h b/Fernanda/source/UserData.h
index e20d89d..434cb76 100644
--- a/Fernanda/source/UserData.h
+++ b/Fernanda/source/UserData.h
@@ -53,6 +53,8 @@ namespace UserData
ToggleColorBar,
ToggleCursorBlink,
ToggleCursorBlock,
+ ToggleCursorCenterOnScroll,
+ ToggleCursorTypewriter,
ToggleEditorShadow,
ToggleEditorTheme,
ToggleIndicator,
diff --git a/Fernanda/source/Version.h b/Fernanda/source/Version.h
index 029e5dc..5539055 100644
--- a/Fernanda/source/Version.h
+++ b/Fernanda/source/Version.h
@@ -13,8 +13,8 @@
#pragma once
-#define VER_FILEVERSION 0,24,4,53
-#define VER_FILEVERSION_STR "v0.24.4-beta53"
+#define VER_FILEVERSION 0,25,0,54
+#define VER_FILEVERSION_STR "v0.25.0-beta54"
#define VER_PRODUCTVERSION VER_FILEVERSION
#define VER_PRODUCTVERSION_STR VER_FILEVERSION_STR
#define VER_COMPANYNAME_STR "fairybow"
diff --git a/README.md b/README.md
index 5770a1a..36d48b0 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
-# Fernanda
+# Fernanda
@@ -8,18 +8,19 @@
-
-
+
+
-
-
-
+
+
+
-
-
+
## :tea: **Hello**
+
+
Fernanda is a plain text editor for drafting long-form fiction. (At least, that's the plan.)
@@ -172,7 +173,7 @@ Fernanda comes with several two-tone editor themes inspired by retro displays an
**Tools:**
-- :pushpin: **Always-on-top:**
+- :pushpin: **Always on top:**
- Pin Fernanda to the top of your window order (will interfere with popups!)
- :bubble_tea: **Stay awake:**
- Keep the screen awake without input (Windows only)