diff --git a/Userland/Applications/TextEditor/MainWidget.cpp b/Userland/Applications/TextEditor/MainWidget.cpp index 75eb86dba0c..7cdf0c8879b 100644 --- a/Userland/Applications/TextEditor/MainWidget.cpp +++ b/Userland/Applications/TextEditor/MainWidget.cpp @@ -59,7 +59,10 @@ MainWidget::MainWidget() m_editor->on_change = [this] { update_preview(); - window()->set_modified(editor().document().is_modified()); + }; + + m_editor->on_modified_change = [this](bool modified) { + window()->set_modified(modified); }; m_page_view = *find_descendant_of_type_named("webview"); diff --git a/Userland/Libraries/LibGUI/TextEditor.cpp b/Userland/Libraries/LibGUI/TextEditor.cpp index bd9b9754e95..7e1582562dc 100644 --- a/Userland/Libraries/LibGUI/TextEditor.cpp +++ b/Userland/Libraries/LibGUI/TextEditor.cpp @@ -1638,6 +1638,11 @@ void TextEditor::document_did_update_undo_stack() { m_undo_action->set_enabled(can_undo()); m_redo_action->set_enabled(can_redo()); + + // FIXME: This is currently firing more often than it should. + // Ideally we'd only send this out when the undo stack modified state actually changes. + if (on_modified_change) + on_modified_change(document().is_modified()); } void TextEditor::document_did_set_text() diff --git a/Userland/Libraries/LibGUI/TextEditor.h b/Userland/Libraries/LibGUI/TextEditor.h index d99929718b0..7c6f4b89789 100644 --- a/Userland/Libraries/LibGUI/TextEditor.h +++ b/Userland/Libraries/LibGUI/TextEditor.h @@ -134,6 +134,7 @@ public: virtual void redo() { document().redo(); } Function on_change; + Function on_modified_change; Function on_mousedown; Function on_return_pressed; Function on_escape_pressed; diff --git a/Userland/Libraries/LibGUI/UndoStack.cpp b/Userland/Libraries/LibGUI/UndoStack.cpp index 8437582a633..dec25df49c5 100644 --- a/Userland/Libraries/LibGUI/UndoStack.cpp +++ b/Userland/Libraries/LibGUI/UndoStack.cpp @@ -19,7 +19,7 @@ UndoStack::~UndoStack() bool UndoStack::can_undo() const { - return m_stack_index > 0; + return m_stack_index > 0 || (m_stack.size() == 1 && m_stack[0].commands.size() > 0); } bool UndoStack::can_redo() const @@ -67,7 +67,7 @@ void UndoStack::pop() void UndoStack::push(NonnullOwnPtr&& command) { if (m_stack.is_empty()) - m_stack.append(make()); + finalize_current_combo(); // If the stack cursor is behind the top of the stack, nuke everything from here to the top. if (m_stack_index != m_stack.size() - 1) { @@ -101,6 +101,8 @@ void UndoStack::finalize_current_combo() void UndoStack::set_current_unmodified() { + finalize_current_combo(); + if (m_clean_index.has_value() && m_clean_index.value() == m_stack_index) return; m_clean_index = m_stack_index; @@ -111,7 +113,15 @@ void UndoStack::set_current_unmodified() bool UndoStack::is_current_modified() const { - return !(m_clean_index.has_value() && m_clean_index.value() == m_stack_index); + if (!m_clean_index.has_value()) + return true; + if (m_stack_index != m_clean_index.value()) + return true; + if (m_stack.is_empty()) + return false; + if (m_stack_index == m_stack.size() - 1 && !m_stack[m_stack_index].commands.is_empty()) + return true; + return false; } void UndoStack::clear()