|
|
@@ -420,18 +420,42 @@ protected:
|
|
|
}, false);
|
|
|
drawing_area->add_controller(controller);
|
|
|
|
|
|
- // Add click handling to set active window explicitly
|
|
|
+ // Add click handling to set active window explicitly and move cursor
|
|
|
// We use GestureClick instead of EventControllerFocus to avoid spurious focus changes
|
|
|
- // (e.g. caused by layout rebuilds or mouse hover anomalies)
|
|
|
auto click_controller = Gtk::GestureClick::create();
|
|
|
std::weak_ptr<Window> weak_window_click = node->window;
|
|
|
- click_controller->signal_pressed().connect([this, weak_window_click, drawing_area](int, double, double) {
|
|
|
+ click_controller->signal_pressed().connect([this, weak_window_click, drawing_area](int /*n_press*/, double x, double y) {
|
|
|
if (auto window = weak_window_click.lock()) {
|
|
|
+ // 1. Activate Window
|
|
|
if (core_ && core_->active_window() != window) {
|
|
|
core_->set_active_window(window);
|
|
|
}
|
|
|
// IMPORTANT: Grab keyboard focus for this widget
|
|
|
drawing_area->grab_focus();
|
|
|
+
|
|
|
+ // 2. Move Cursor
|
|
|
+ if (line_height_ > 0 && char_width_ > 0) {
|
|
|
+ int row = static_cast<int>((y - PADDING_TOP) / line_height_);
|
|
|
+ int col = static_cast<int>((x - PADDING_LEFT) / char_width_);
|
|
|
+
|
|
|
+ if (row < 0) row = 0;
|
|
|
+ if (col < 0) col = 0;
|
|
|
+
|
|
|
+ auto viewport = window->viewport();
|
|
|
+ size_t target_line = viewport.scroll_offset + row;
|
|
|
+ size_t target_col = viewport.horizontal_offset + col;
|
|
|
+
|
|
|
+ // Check boundaries
|
|
|
+ if (target_line < window->buffer().line_count()) {
|
|
|
+ window->set_cursor({target_line, target_col});
|
|
|
+ drawing_area->queue_draw();
|
|
|
+ } else {
|
|
|
+ // Clicked past end of buffer, move to end
|
|
|
+ size_t last_line = window->buffer().line_count() - 1;
|
|
|
+ window->set_cursor({last_line, window->buffer().line(last_line).length()});
|
|
|
+ drawing_area->queue_draw();
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
});
|
|
|
drawing_area->add_controller(click_controller);
|