Skip to content

fix(map.lic): v2.1.1 gtk crash fix#2280

Open
mrhoribu wants to merge 3 commits intomasterfrom
fix/map.lic-v2.1.1
Open

fix(map.lic): v2.1.1 gtk crash fix#2280
mrhoribu wants to merge 3 commits intomasterfrom
fix/map.lic-v2.1.1

Conversation

@mrhoribu
Copy link
Contributor

@coderabbitai summary

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 21, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8ee1ba00-8d55-4b2b-a7f3-6613baa54d0f

📥 Commits

Reviewing files that changed from the base of the PR and between 511be4d and eadd73e.

📒 Files selected for processing (1)
  • scripts/map.lic
🚧 Files skipped from review as they are similar to previous changes (1)
  • scripts/map.lic

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes

    • Prevented lingering GUI objects and handler leaks; dynamic menus no longer retain old items.
    • Strengthened window shutdown to reliably destroy UI elements and menus before exit, and made cleanup wait for queued GUI teardown.
    • Fixed crashes related to viewport centering and improved submenu/menu item lifetime handling.
  • Chores

    • Version bumped from 2.1.0 to 2.1.1.

Walkthrough

Updated scripts/map.lic to v2.1.1: added GC anchors for GTK wrappers and dynamic menus, changed dynamic-menu handling, refactored ElanthiaMap::Window#destroy to queue and wait for ordered cleanup (note pins, markers, menus, layout, window), replaced an inline timeout with an ivar-stored Proc, and fixed several GC/crash ordering issues.

Changes

Cohort / File(s) Summary
Map script
scripts/map.lic
Bumped version to v2.1.1; added GC anchor ivars @_prevent_gc and @_dynamic_menu_gc; anchor menu items and timeout Proc; clear dynamic anchors before submenu rebuilds; refactored ElanthiaMap::Window#destroy to queue ordered cleanup (explicitly destroy @note_pin_widgets first, markers, menus, layout children, then destroy @gtk_window inside the queued block), wait for queued cleanup to complete with a bounded polling loop, set @gtk_window = nil, and clear GC anchors; broke chained Gdk::Screen calls to avoid GC crashes.

Sequence Diagram

sequenceDiagram
    participant Script as Main Script
    participant Window as ElanthiaMap::Window
    participant Queue as Gtk.queue
    participant Cleanup as Cleanup Block
    participant GTK as GTK Engine
    participant GC as Ruby GC

    Script->>Window: call destroy
    Window->>Window: set completed = false, enqueue cleanup
    Window->>Queue: queue Cleanup block
    Note right of Window: poll/sleep until completed or timeout
    Queue->>Cleanup: run queued cleanup
    Cleanup->>Cleanup: destroy note pins -> markers -> menus -> layout children
    Cleanup->>GTK: destroy `@gtk_window`, disconnect handlers
    Cleanup->>Window: set completed = true, clear GC anchors
    Window->>Script: return after polling sees completed
    Script->>GC: Procs/handlers become eligible for collection
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive The description contains only a placeholder '@coderabbitai summary' with no meaningful content related to the changeset. Replace the placeholder with an actual description explaining the GTK crash fixes, GC anchor improvements, and cleanup control flow changes.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately reflects the main change: addressing GTK crash fixes in map.lic version 2.1.1, which is the primary focus of the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/map.lic-v2.1.1

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
scripts/map.lic (1)

1579-1605: ⚠️ Potential issue | 🟠 Major

Unanchored scale submenu items when global mode is enabled.

When global_scale_enabled is true at line 1584, the scale submenu rebuild is skipped. However, line 1581 clears @_dynamic_menu_gc unconditionally for all menus, releasing the old scale submenu items before that conditional check. These items—which contain Procs with signal handlers—remain in the GTK widget tree but lose their Ruby anchor, leaving them vulnerable to garbage collection during normal operation while GTK still references them. Either use a fresh anchor array and keep the previous one alive until replaced submenus are destroyed, or rebuild the scale submenu regardless of the global_scale_enabled setting.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/map.lic` around lines 1579 - 1605, Clearing the global anchor array
`@_dynamic_menu_gc` before you decide whether to rebuild the scale submenu
unanchors Procs for `@menu_scale` when `@settings`[:global_scale_enabled] is true;
either preserve the old anchors until the submenu is explicitly destroyed or
always rebuild the scale submenu. Fix by changing the order in the refresh
logic: either (A) move `@_dynamic_menu_gc.clear` into each menu-specific branch so
you only clear anchors for menus you rebuild (references: `@_dynamic_menu_gc`,
`@menu_scale`, `@menu_tags`, `@menu_locations`, build_scale_submenu), or (B) allocate
a fresh anchor array (old_anchor = `@_dynamic_menu_gc`; `@_dynamic_menu_gc` = [])
and only discard old_anchor after you have destroyed/replaced the corresponding
submenu widgets so the Procs remain anchored while GTK still holds them.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@scripts/map.lic`:
- Around line 602-670: The destroy logic currently relies only on the
`@_timeout_proc` ivar and never cancels scheduled GLib timeouts, so earlier
timeouts can leak C-side references; modify the code that schedules callbacks
(where GLib::Timeout.add(50, &@_timeout_proc) is called) to capture and store
the returned source id in a dedicated ivar (e.g. `@_timeout_source_id` or
similar), and in the destroy method (the block that runs before clearing
`@_prevent_gc` and `@_dynamic_menu_gc`) call
GLib::Timeout.remove(`@_timeout_source_id`) for any existing source id (and
clear/reset both `@_timeout_source_id` and `@_timeout_proc`) before releasing GC
anchors to ensure pending timeouts are canceled.

---

Outside diff comments:
In `@scripts/map.lic`:
- Around line 1579-1605: Clearing the global anchor array `@_dynamic_menu_gc`
before you decide whether to rebuild the scale submenu unanchors Procs for
`@menu_scale` when `@settings`[:global_scale_enabled] is true; either preserve the
old anchors until the submenu is explicitly destroyed or always rebuild the
scale submenu. Fix by changing the order in the refresh logic: either (A) move
`@_dynamic_menu_gc.clear` into each menu-specific branch so you only clear anchors
for menus you rebuild (references: `@_dynamic_menu_gc`, `@menu_scale`, `@menu_tags`,
`@menu_locations`, build_scale_submenu), or (B) allocate a fresh anchor array
(old_anchor = `@_dynamic_menu_gc`; `@_dynamic_menu_gc` = []) and only discard
old_anchor after you have destroyed/replaced the corresponding submenu widgets
so the Procs remain anchored while GTK still holds them.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bbb83393-036c-4c26-a5b7-ecf69b3023b5

📥 Commits

Reviewing files that changed from the base of the PR and between 86379e4 and 511be4d.

📒 Files selected for processing (1)
  • scripts/map.lic

@mrhoribu
Copy link
Contributor Author

@coderabbitai review again

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 25, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 25, 2026

@mrhoribu Sure! Triggering a review of the PR now.

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant