瀏覽代碼

fix(gtk): resolve window split UI issues

1. **Modeline display**: Show modeline for all windows, not just main window
   - Reserve 1 line for modeline in split windows, 2 lines for main window (modeline + minibuffer)

2. **Window focus stability**: Fix focus jumping back to previous window
   - Remove window cycling from key handler, only use focus controller
   - Only change window focus when actually needed to prevent conflicts

3. **Split ratio calculation**: Fix vertical split width issues
   - Use actual widget allocation size instead of hardcoded 500px
   - Defer position setting until widget is realized and has proper size
   - Calculate position based on orientation (width for vertical, height for horizontal)

These changes provide a much more stable and predictable multi-window experience.

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

Co-Authored-By: Claude <noreply@anthropic.com>
Bernardo Magri 1 月之前
父節點
當前提交
33f225a750
共有 1 個文件被更改,包括 22 次插入33 次删除
  1. 22 33
      src/gtk_editor.cpp

+ 22 - 33
src/gtk_editor.cpp

@@ -387,23 +387,7 @@ protected:
             // Use weak reference to window for key handling
             std::weak_ptr<Window> weak_window_key = node->window;
             controller->signal_key_pressed().connect([this, weak_window_key](guint keyval, guint keycode, Gdk::ModifierType state) -> bool {
-                // Set this window as active when it receives input
-                if (auto window = weak_window_key.lock()) {
-                    if (core_) {
-                        // For now, find the right window by cycling through next_window until we find the matching one
-                        // This is a hack but works until we add proper window focusing API
-                        auto current = core_->active_window();
-                        if (current != window) {
-                            // Try to find the target window by calling next_window repeatedly
-                            for (int i = 0; i < 10; ++i) { // Prevent infinite loop
-                                core_->next_window();
-                                if (core_->active_window() == window) {
-                                    break;
-                                }
-                            }
-                        }
-                    }
-                }
+                // Focus is handled by focus controller, just process the key
                 return on_key_pressed(keyval, keycode, state);
             }, false);
             drawing_area->add_controller(controller);
@@ -413,16 +397,13 @@ protected:
             std::weak_ptr<Window> weak_window_focus = node->window;
             focus_controller->signal_enter().connect([this, weak_window_focus]() {
                 if (auto window = weak_window_focus.lock()) {
-                    if (core_) {
-                        // For now, find the right window by cycling through next_window until we find the matching one
-                        auto current = core_->active_window();
-                        if (current != window) {
-                            // Try to find the target window by calling next_window repeatedly
-                            for (int i = 0; i < 10; ++i) { // Prevent infinite loop
-                                core_->next_window();
-                                if (core_->active_window() == window) {
-                                    break;
-                                }
+                    if (core_ && core_->active_window() != window) {
+                        // Only change focus if this window is not already active
+                        // Try to find the target window by calling next_window repeatedly
+                        for (int i = 0; i < 10; ++i) { // Prevent infinite loop
+                            core_->next_window();
+                            if (core_->active_window() == window) {
+                                break;
                             }
                         }
                     }
@@ -452,8 +433,15 @@ protected:
             if (child1) paned->set_start_child(*child1);
             if (child2) paned->set_end_child(*child2);
             
-            // Set initial position based on ratio
-            paned->set_position(static_cast<int>(500 * node->ratio)); // Default size
+            // Set initial position based on ratio - defer until widget is realized
+            auto node_ratio = node->ratio;
+            auto node_type = node->type;
+            paned->signal_realize().connect([paned, node_ratio, node_type]() {
+                // Get the actual allocated size and apply the ratio
+                auto allocation = paned->get_allocation();
+                int size = (node_type == LayoutNode::Type::HorizontalSplit) ? allocation.get_height() : allocation.get_width();
+                paned->set_position(static_cast<int>(size * node_ratio));
+            });
             
             return paned;
         }
@@ -497,9 +485,9 @@ protected:
         int visible_lines = static_cast<int>(content_height_px / line_height_);
         int visible_cols = static_cast<int>(content_width_px / char_width_);
         
-        // Reserve space for modeline and minibuffer at bottom only for main window
+        // Reserve space for modeline (all windows) and minibuffer (main window only)  
         bool is_main_window = (window == core_->active_window());
-        int editor_lines = is_main_window ? std::max(0, visible_lines - 2) : visible_lines;
+        int editor_lines = is_main_window ? std::max(0, visible_lines - 2) : std::max(0, visible_lines - 1);
         window->set_viewport_size(visible_cols, editor_lines);
 
         // Get default foreground color from theme
@@ -566,9 +554,10 @@ protected:
             }
         }
 
-        // Only render modeline and minibuffer for the main window
+        // Render modeline for all windows, but minibuffer only for the main window
+        render_modeline_for_window(cr, width, height, layout, window);
+        
         if (is_main_window) {
-            render_modeline_for_window(cr, width, height, layout, window);
             render_minibuffer(cr, width, height, layout);
         }
     }