|
|
@@ -68,9 +68,9 @@ public:
|
|
|
rebuild_layout();
|
|
|
}
|
|
|
|
|
|
- // Request redraw on most events
|
|
|
- if (drawing_area_) {
|
|
|
- drawing_area_->queue_draw();
|
|
|
+ // Request redraw on most events - recursively find all drawing areas
|
|
|
+ if (content_widget_) {
|
|
|
+ queue_redraw_all_windows(content_widget_);
|
|
|
}
|
|
|
|
|
|
// Handle mode switching events
|
|
|
@@ -117,6 +117,22 @@ public:
|
|
|
core_ = core;
|
|
|
}
|
|
|
|
|
|
+ // Helper to recursively find and redraw all drawing areas
|
|
|
+ void queue_redraw_all_windows(Gtk::Widget* widget) {
|
|
|
+ if (!widget) return;
|
|
|
+
|
|
|
+ if (auto drawing_area = dynamic_cast<Gtk::DrawingArea*>(widget)) {
|
|
|
+ drawing_area->queue_draw();
|
|
|
+ } else if (auto paned = dynamic_cast<Gtk::Paned*>(widget)) {
|
|
|
+ if (auto start_child = paned->get_start_child()) {
|
|
|
+ queue_redraw_all_windows(start_child);
|
|
|
+ }
|
|
|
+ if (auto end_child = paned->get_end_child()) {
|
|
|
+ queue_redraw_all_windows(end_child);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
private:
|
|
|
EditorCore* core_;
|
|
|
Glib::RefPtr<Gtk::Application> app_;
|
|
|
@@ -336,6 +352,9 @@ protected:
|
|
|
if (content_widget_) {
|
|
|
window_->unset_child();
|
|
|
}
|
|
|
+
|
|
|
+ // Clear the drawing area reference since we're rebuilding
|
|
|
+ drawing_area_ = nullptr;
|
|
|
|
|
|
// Create new layout based on the tree
|
|
|
content_widget_ = create_widget_for_layout_node(root_layout);
|
|
|
@@ -353,9 +372,11 @@ protected:
|
|
|
auto drawing_area = Gtk::make_managed<Gtk::DrawingArea>();
|
|
|
|
|
|
// Set up drawing for this specific window
|
|
|
- drawing_area->set_draw_func([this, node](const Cairo::RefPtr<Cairo::Context>& cr, int width, int height) {
|
|
|
- if (node && node->window) {
|
|
|
- draw_window(cr, width, height, node->window);
|
|
|
+ // Use a weak reference to the window to avoid crashes if the layout is rebuilt
|
|
|
+ std::weak_ptr<Window> weak_window = node->window;
|
|
|
+ drawing_area->set_draw_func([this, weak_window](const Cairo::RefPtr<Cairo::Context>& cr, int width, int height) {
|
|
|
+ if (auto window = weak_window.lock()) {
|
|
|
+ draw_window(cr, width, height, window);
|
|
|
}
|
|
|
});
|
|
|
|
|
|
@@ -363,18 +384,22 @@ protected:
|
|
|
|
|
|
// Add input handling
|
|
|
auto controller = Gtk::EventControllerKey::create();
|
|
|
- controller->signal_key_pressed().connect([this, node](guint keyval, guint keycode, Gdk::ModifierType state) -> bool {
|
|
|
+ // 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 (node && node->window && 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 != node->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() == node->window) {
|
|
|
- break;
|
|
|
+ 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;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -385,16 +410,19 @@ protected:
|
|
|
|
|
|
// Add focus handling to set active window
|
|
|
auto focus_controller = Gtk::EventControllerFocus::create();
|
|
|
- focus_controller->signal_enter().connect([this, node]() {
|
|
|
- if (node && node->window && 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 != node->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() == node->window) {
|
|
|
- break;
|
|
|
+ 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;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -444,9 +472,8 @@ protected:
|
|
|
cr->set_source_rgb(bg.r / 255.0, bg.g / 255.0, bg.b / 255.0);
|
|
|
cr->paint();
|
|
|
|
|
|
- // Create Pango layout - need to get context from a drawing area
|
|
|
- // For now, use the first drawing area's context
|
|
|
- auto layout = Pango::Layout::create(drawing_area_->get_pango_context());
|
|
|
+ // Create Pango layout - create context directly from Cairo
|
|
|
+ auto layout = Pango::Layout::create(cr);
|
|
|
|
|
|
// Font configuration
|
|
|
Pango::FontDescription font_desc("Monospace 12");
|