Extract reusable pane widget from preview
I've completed the refactoring. Here's a summary of the changes:
Changes Made
1. New PaneHeaderLayout struct in geometry.rs
- Provides consistent sizing for pane headers (title bar area)
- Uses same height as tab bars (
metrics.tab_bar_height) - Calculates title text position with proper padding
- Calculates border position at bottom of header
2. New PreviewLayout struct in geometry.rs
- Similar to
GroupLayoutfor editor groups - Contains header layout, content rect, and padding
- Helper methods:
content_y(),content_w(),text_x(),max_text_width(),visible_lines()
3. New render_pane_header() helper in mod.rs
- Reusable widget for rendering pane headers
- Draws: background, title text, bottom border (matching tab bar style)
- Uses theme colors from
tab_bar
4. Refactored render_preview_pane() in mod.rs
- Now uses
PreviewLayoutfor consistent geometry - Uses
render_pane_header()for the header (adds the missing border) - Uses scaled metrics instead of hardcoded values
The preview pane now has a visible border under its header, consistent with editor tab bars, and the abstractions can be reused for future pane types.
All done. Here's a summary of the changes:
Summary
1. New Pane abstraction in geometry.rs
A reusable layout primitive with:
PaneBorders- configurable borders (top/bottom/left/right)PaneInsets- content paddingPanestruct with:- Optional header (uses
tab_bar_height) - Header border
- Content area with insets
- Helper methods:
content_x(),content_y(),content_width(),content_height(),visible_lines(),is_in_header(), etc.
- Optional header (uses
2. New render_pane() helper in mod.rs
Renders pane chrome (background, header, borders) - reusable for any pane type.
3. Middle-click to close preview in app.rs
Clicking middle button on preview header now closes the preview pane.
4. Links open in default browser in webview.rs
Added with_navigation_handler to intercept http:// and https:// links and open them with open::that() instead of navigating within the webview.
New dependency
Added open = "5" to Cargo.toml for cross-platform URL opening.
Summary of Changes
I've restructured the markdown preview to be group-centric rather than document-centric, fixing the lifecycle issues:
Data Model Changes
EditorGroupnow hasattached_preview: Option<PreviewId>- ties preview to a specific groupPreviewPanenow hasgroup_id: GroupId- tracks which group owns it
New EditorArea Methods (editor_area.rs)
find_preview_for_group()/focused_group_preview()- find preview by groupopen_preview_for_group()/open_preview_for_focused_group()- create/retarget previewon_group_active_tab_changed()- closes preview when switching to different documentclose_previews_for_document()- closes previews when document is closed
Lifecycle Wiring
- Tab switching now calls
on_group_active_tab_changed()to close preview when navigating away from the source document - Tab close checks if the closed tab was showing the preview's document and closes it
- Preview operations are now scoped to the focused group, not global
Modal Z-Order Fix (app.rs)
- Added
webview_manager.set_all_visible(show_webviews)to hide webviews when command palette or other modals are open - Webviews are shown again when modals close
Also Completed Earlier
- Pane abstraction for consistent UI widget rendering
- Middle-click to close preview on the preview header
- Links open in default browser via
with_navigation_handler
Added syntax highlighting to the markdown preview webview using highlight.js (v11.9.0).
Changes made:
- renderer.rs - Added CDN links for highlight.js CSS (github-dark theme) and JS
- renderer.rs - Added
hljs.highlightAll()call on page load - webview.rs - Re-runs highlighting when content is updated dynamically
The preview will now syntax highlight code blocks for all languages supported by highlight.js (190+ languages including Rust, Python, JavaScript, TypeScript, Go, C/C++, Java, etc.). The github-dark theme matches dark editor themes well.
Done. Left-clicks on preview pane headers are now consumed and don't pass through to the editor behind. Added the check in app.rs right before the tab bar hit testing.
The issue is that clicking in the preview area doesn't properly return focus to the editor. Let me check how focus is managed and fix this:
I see - clicking on the preview header consumes the click but doesn't call focus_editor(). The editor should still have focus when clicking on the preview. Let me update the click handler:
But wait - the issue is likely that clicking anywhere in the preview area (not just the header) might be causing issues. Let me also check for clicks in the preview content area:
I see. The issue is that clicks can go into the preview area (which has a webview), and the webview captures focus. The fix for the header is good, but we should also check for clicks in the entire preview pane area. Let me update the check to cover the whole preview pane:
Fixed. Now clicking anywhere in the preview pane will:
- Consume the left-click (not pass through to editor)
- Keep the editor focused so Cmd+W and other keyboard shortcuts still work
The change is in app.rs - checks if click is inside any preview rect and calls focus_editor() before consuming the event.