diff --git a/Applications/Terminal/Terminal.cpp b/Applications/Terminal/Terminal.cpp index 9e85460265c..fe0b79a4878 100644 --- a/Applications/Terminal/Terminal.cpp +++ b/Applications/Terminal/Terminal.cpp @@ -21,6 +21,12 @@ Terminal::Terminal(int ptm_fd) : m_ptm_fd(ptm_fd) , m_notifier(ptm_fd, GNotifier::Read) { + m_cursor_blink_timer.set_interval(500); + m_cursor_blink_timer.on_timeout = [this] { + m_cursor_blink_state = !m_cursor_blink_state; + update_cursor(); + }; + set_font(Font::default_fixed_width_font()); m_notifier.on_ready_to_read = [this] (GNotifier& notifier) { byte buffer[BUFSIZ]; @@ -724,6 +730,12 @@ void Terminal::event(GEvent& event) { if (event.type() == GEvent::WindowBecameActive || event.type() == GEvent::WindowBecameInactive) { m_in_active_window = event.type() == GEvent::WindowBecameActive; + if (!m_in_active_window) { + m_cursor_blink_timer.stop(); + } else { + m_cursor_blink_state = true; + m_cursor_blink_timer.start(); + } invalidate_cursor(); update(); } @@ -794,7 +806,7 @@ void Terminal::paint_event(GPaintEvent&) painter.fill_rect(row_rect(row), lookup_color(line.attributes[0].background_color).with_alpha(255 * m_opacity)); } for (word column = 0; column < m_columns; ++column) { - bool should_reverse_fill_for_cursor = m_in_active_window && row == m_cursor_row && column == m_cursor_column; + bool should_reverse_fill_for_cursor = m_cursor_blink_state && m_in_active_window && row == m_cursor_row && column == m_cursor_column; auto& attribute = line.attributes[column]; char ch = line.characters[column]; auto character_rect = glyph_rect(row, column); @@ -864,3 +876,9 @@ void Terminal::apply_size_increments_to_window(GWindow& window) window.set_size_increment({ font().glyph_width('x'), m_line_height }); window.set_base_size({ m_inset * 2, m_inset * 2}); } + +void Terminal::update_cursor() +{ + invalidate_cursor(); + flush_dirty_lines(); +} diff --git a/Applications/Terminal/Terminal.h b/Applications/Terminal/Terminal.h index 5f31d3b2e4a..4f1bbd439fc 100644 --- a/Applications/Terminal/Terminal.h +++ b/Applications/Terminal/Terminal.h @@ -7,6 +7,7 @@ #include #include #include +#include class Font; @@ -65,6 +66,7 @@ private: word rows() const { return m_rows; } Rect glyph_rect(word row, word column); Rect row_rect(word row); + void update_cursor(); struct Attribute { Attribute() { reset(); } @@ -154,6 +156,9 @@ private: float m_opacity { 1 }; bool m_needs_background_fill { true }; + bool m_cursor_blink_state { true }; int m_glyph_width { 0 }; + + GTimer m_cursor_blink_timer; }; diff --git a/LibGUI/GTimer.cpp b/LibGUI/GTimer.cpp new file mode 100644 index 00000000000..9edd58bd7a3 --- /dev/null +++ b/LibGUI/GTimer.cpp @@ -0,0 +1,39 @@ +#include + +GTimer::GTimer(GObject* parent) + : GObject(parent) +{ +} + +GTimer::~GTimer() +{ +} + +void GTimer::start() +{ + start(m_interval); +} + +void GTimer::start(int interval) +{ + if (m_active) + return; + start_timer(interval); + m_active = true; +} + +void GTimer::stop() +{ + if (!m_active) + return; + stop_timer(); + m_active = false; +} + +void GTimer::timer_event(GTimerEvent&) +{ + if (m_single_shot) + stop(); + if (on_timeout) + on_timeout(); +} diff --git a/LibGUI/GTimer.h b/LibGUI/GTimer.h new file mode 100644 index 00000000000..604c5042dfb --- /dev/null +++ b/LibGUI/GTimer.h @@ -0,0 +1,32 @@ +#pragma once + +#include +#include + +class GTimer final : public GObject { +public: + explicit GTimer(GObject* parent = nullptr); + virtual ~GTimer() override; + + void start(); + void start(int interval); + void stop(); + + bool is_active() const { return m_active; } + int interval() const { return m_interval; } + void set_interval(int interval) { m_interval = interval; } + + bool is_single_shot() const { return m_single_shot; } + void set_single_shot(bool single_shot) { m_single_shot = single_shot; } + + Function on_timeout; + + virtual const char* class_name() const override { return "GTimer"; } + +private: + virtual void timer_event(GTimerEvent&) override; + + bool m_active { false }; + bool m_single_shot { false }; + int m_interval { 0 }; +}; diff --git a/LibGUI/Makefile b/LibGUI/Makefile index 218b344b393..9660229968b 100644 --- a/LibGUI/Makefile +++ b/LibGUI/Makefile @@ -57,6 +57,7 @@ LIBGUI_OBJS = \ GTreeView.o \ GFileSystemModel.o \ GSplitter.o \ + GTimer.o \ GWindow.o OBJS = $(SHAREDGRAPHICS_OBJS) $(LIBGUI_OBJS)