|
|
@@ -225,16 +225,49 @@ protected:
|
|
|
|
|
|
// Render Cursor - Emacs-style blinking block cursor with color inversion
|
|
|
if (cursor_visible_ && cursor.line >= static_cast<size_t>(start_line) && cursor.line < static_cast<size_t>(end_line)) {
|
|
|
- // Account for horizontal scrolling and padding
|
|
|
- double cursor_screen_x = PADDING_LEFT + (static_cast<int>(cursor.column) - horizontal_offset) * char_width_;
|
|
|
int screen_y = cursor.line - start_line;
|
|
|
double cursor_y = PADDING_TOP + screen_y * line_height_;
|
|
|
|
|
|
+ // Get the line text and calculate exact cursor position using Pango text measurement
|
|
|
+ size_t buffer_line_idx = cursor.line;
|
|
|
+ const auto& cursor_line_text = buffer.line(buffer_line_idx);
|
|
|
+
|
|
|
+ // Calculate the exact X position by measuring text up to cursor position
|
|
|
+ double cursor_screen_x = PADDING_LEFT;
|
|
|
+
|
|
|
+ // If we have horizontal scrolling, we need to account for the visible portion
|
|
|
+ if (horizontal_offset > 0 && cursor.column >= static_cast<size_t>(horizontal_offset)) {
|
|
|
+
|
|
|
+ // Measure text from horizontal_offset to cursor position
|
|
|
+ if (horizontal_offset < static_cast<int>(cursor_line_text.length())) {
|
|
|
+ std::string text_to_cursor = cursor_line_text.substr(
|
|
|
+ horizontal_offset,
|
|
|
+ cursor.column - horizontal_offset
|
|
|
+ );
|
|
|
+ if (!text_to_cursor.empty()) {
|
|
|
+ layout->set_text(text_to_cursor);
|
|
|
+ Pango::Rectangle text_rect;
|
|
|
+ layout->get_pixel_extents(text_rect, text_rect);
|
|
|
+ cursor_screen_x = PADDING_LEFT + text_rect.get_width();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else if (horizontal_offset == 0) {
|
|
|
+ // No horizontal scrolling - measure from start of line to cursor
|
|
|
+ if (cursor.column > 0 && cursor.column <= cursor_line_text.length()) {
|
|
|
+ std::string text_to_cursor = cursor_line_text.substr(0, cursor.column);
|
|
|
+ layout->set_text(text_to_cursor);
|
|
|
+ Pango::Rectangle text_rect;
|
|
|
+ layout->get_pixel_extents(text_rect, text_rect);
|
|
|
+ cursor_screen_x = PADDING_LEFT + text_rect.get_width();
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // Cursor is before the visible area (shouldn't happen with proper scrolling)
|
|
|
+ cursor_screen_x = -char_width_; // Hide cursor
|
|
|
+ }
|
|
|
+
|
|
|
// Only render cursor if it's visible horizontally
|
|
|
if (cursor_screen_x >= PADDING_LEFT && cursor_screen_x < (width - PADDING_RIGHT)) {
|
|
|
// Get the character under cursor for rendering with inverted colors
|
|
|
- size_t buffer_line_idx = cursor.line;
|
|
|
- const auto& cursor_line_text = buffer.line(buffer_line_idx);
|
|
|
char cursor_char = (cursor.column < cursor_line_text.length()) ? cursor_line_text[cursor.column] : ' ';
|
|
|
|
|
|
// Draw block cursor background (inverted background color)
|
|
|
@@ -244,7 +277,7 @@ protected:
|
|
|
cr->fill();
|
|
|
|
|
|
// Draw the character with inverted color (background color as foreground)
|
|
|
- if (cursor_char != '\0') {
|
|
|
+ if (cursor_char != '\0' && cursor_char != ' ') {
|
|
|
Color cursor_fg = theme ? theme->get_bg_color(ThemeElement::Background) : Color(0, 0, 0);
|
|
|
cr->set_source_rgb(cursor_fg.r / 255.0, cursor_fg.g / 255.0, cursor_fg.b / 255.0);
|
|
|
|