Selaa lähdekoodia

refactor(frontend): Phase 1 quick wins for frontend improvements

- Fix GTK cache validation to check styles (prevents stale cache on theme change)
- Improve GTK paned layout fallback (try parent size before hardcoded fallback)
- Extract ViewportBounds helper in TUI to eliminate duplicated viewport calculation
- Reduce code duplication in TUI init/resize/render

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Bernardo Magri 1 kuukausi sitten
vanhempi
sitoutus
1506385f46
3 muutettua tiedostoa jossa 49 lisäystä ja 29 poistoa
  1. 17 4
      src/gtk_editor.cpp
  2. 3 1
      src/gtk_renderer.cpp
  3. 29 24
      src/tui_editor.cpp

+ 17 - 4
src/gtk_editor.cpp

@@ -604,10 +604,23 @@ Gtk::Widget* GtkEditor::create_widget_for_layout_node(std::shared_ptr<LayoutNode
              int width = paned->get_width();
              int height = paned->get_height();
              int size = (paned->get_orientation() == Gtk::Orientation::HORIZONTAL) ? width : height;
-             
-             // Fallback if size not yet available
-             if (size <= 1) size = 1000; // Assume a reasonable default window size
-             
+
+             // If size not available yet, try to get from parent or use allocation
+             if (size <= 1) {
+                 auto parent = paned->get_parent();
+                 if (parent) {
+                     width = parent->get_width();
+                     height = parent->get_height();
+                     size = (paned->get_orientation() == Gtk::Orientation::HORIZONTAL) ? width : height;
+                 }
+             }
+
+             // Final fallback using a reasonable minimum window size
+             if (size <= 1) {
+                 size = 800;  // Reasonable default for most displays
+                 spdlog::debug("Paned fallback size used: {}", size);
+             }
+
              paned->set_position(static_cast<int>(size * node->ratio));
         });
         

+ 3 - 1
src/gtk_renderer.cpp

@@ -229,7 +229,9 @@ void GtkRenderer::draw_window(const Cairo::RefPtr<Cairo::Context>& cr, int width
             bool use_cache = false;
             if (!has_selection && window_cache.count(buffer_line_idx)) {
                  auto& entry = window_cache[buffer_line_idx];
-                 if (entry.text_content == visible_text) { // Simple validation
+                 // Validate both text content AND styles to ensure cache is still valid
+                 // (styles change on theme switch or syntax highlighting updates)
+                 if (entry.text_content == visible_text && entry.styles == styles) {
                      cr->set_source(entry.surface, text_x, text_y);
                      cr->paint();
                      use_cache = true;

+ 29 - 24
src/tui_editor.cpp

@@ -41,6 +41,24 @@ private:
     static constexpr std::chrono::milliseconds BLINK_INTERVAL = std::chrono::milliseconds(500);
     static constexpr std::chrono::milliseconds BLINK_STATIONARY_THRESHOLD = std::chrono::milliseconds(1000); // 1 second
     
+    // Viewport bounds calculation (avoids code duplication)
+    struct ViewportBounds {
+        int content_width;
+        int content_height;
+        int line_number_width;
+        int minibuffer_lines;
+    };
+
+    ViewportBounds calculate_viewport_bounds() const {
+        ViewportBounds bounds;
+        bounds.minibuffer_lines = 1;  // Always reserve 1 line for minibuffer/message
+        bounds.content_height = height_ - bounds.minibuffer_lines;
+        bool show_line_numbers = core_->config().get<bool>("show_line_numbers", true);
+        bounds.line_number_width = show_line_numbers ? core_->config().get<int>("line_number_width", 6) : 0;
+        bounds.content_width = width_ - bounds.line_number_width;
+        return bounds;
+    }
+
     // Private helper method declarations
     std::string resolve_key(int ch);
     bool handle_input(int ch);
@@ -49,7 +67,7 @@ private:
     void render_window(std::shared_ptr<Window> window, int x, int y, int width, int height);
     void render_window_modeline(std::shared_ptr<Window> window, int x, int y, int width, bool is_active);
     void render_message_line();
-    
+
     int get_attributes_for_face(const std::string& face_name);
 
     // Hardware cursor position tracking
@@ -82,13 +100,9 @@ void TuiEditor::init() {
         core_->theme_manager().active_theme()->initialize_ncurses_colors();
     }
     
-    // Set initial viewport size (leave room for minibuffer/message line)
-    int minibuffer_lines = 1; // Always reserve 1 line for minibuffer/message
-    int content_height = height_ - minibuffer_lines;
-    bool show_line_numbers = core_->config().get<bool>("show_line_numbers", true);
-    int line_number_width = show_line_numbers ? core_->config().get<int>("line_number_width", 6) : 0;
-    int content_width = width_ - line_number_width;
-    core_->set_viewport_size(content_width, content_height);
+    // Set initial viewport size
+    auto bounds = calculate_viewport_bounds();
+    core_->set_viewport_size(bounds.content_width, bounds.content_height);
     
     spdlog::debug("ncurses editor initialized: {}x{}", width_, height_);
 }
@@ -108,14 +122,10 @@ void TuiEditor::run() {
         if (new_height != height_ || new_width != width_) {
             height_ = new_height;
             width_ = new_width;
-            int minibuffer_lines = 1; // Always reserve 1 line for minibuffer/message
-            int content_height = height_ - minibuffer_lines;
-            bool show_line_numbers = core_->config().get<bool>("show_line_numbers", true);
-            int line_number_width = show_line_numbers ? core_->config().get<int>("line_number_width", 6) : 0;
-            int content_width = width_ - line_number_width;
-            core_->set_viewport_size(content_width, content_height);
+            auto bounds = calculate_viewport_bounds();
+            core_->set_viewport_size(bounds.content_width, bounds.content_height);
             spdlog::debug("Screen resized to: {}x{}", width_, height_);
-            spdlog::debug("Content area: {}x{}", content_width, content_height);
+            spdlog::debug("Content area: {}x{}", bounds.content_width, bounds.content_height);
             // Force cursor to be visible after resize, as it implies movement.
             last_cursor_move_time_ = std::chrono::steady_clock::now();
             cursor_visible_ = true;
@@ -330,16 +340,11 @@ void TuiEditor::render() {
     }
     clear();
     
-    // Calculate content area (leave room for message line and potentially a completion line)
-    int minibuffer_lines = 1; // Always reserve 1 line for minibuffer/message
-    // if (core_->minibuffer_manager().is_active() && !core_->minibuffer_manager().get_completion_candidates().empty()) {
-    //     minibuffer_lines++; // Reserve an extra line for completions
-    // }
-    int content_height = height_ - minibuffer_lines; 
-    int content_width = width_;
-    
+    // Calculate content area
+    auto bounds = calculate_viewport_bounds();
+
     // Render the layout tree recursively (now includes per-window modelines)
-    render_layout_node(core_->root_layout(), 0, 0, content_width, content_height);
+    render_layout_node(core_->root_layout(), 0, 0, width_, bounds.content_height);
     
     // Global message/command line (last line)
     render_message_line();