New Features
- Updated bundled MuPDF to 1.28.5.
- WORK IN PROGRESS New optional AI chat panel (opt-in
WITH_LLM_SUPPORTbuild flag) for talking to a local/remote OpenAI-compatible LLM (e.g. Ollama) from a dock widget; configurable vialektra.opt.llm_view/[llm_view]inconfig.toml. Messages now render as messenger-style chat bubbles, Shift+Return sends, and a connection status indicator shows whether the configured endpoint is currently reachable. - Recognize Adobe Illustrator (
.ai) files — they're PDF-compatible and already opened fine, but now show up in the Open File dialog and are labelled "AI" (not generic "PDF") in File Properties. - New
[tabs].close_button_modeconfig (all/current/hidden) controlling when tab close buttons are shown; also exposed to Lua. - Document links (and keyboard link-hints) with a
file://URI now open the target as a local document in a new tab, if it's a format Lektra can open, instead of always handing it to the OS/browser. - Added support for opening HTML/XHTML, Markdown, and plain text files, plus DOCX/XLSX/PPTX.
- New
view:region_select_image(callback)Lua API — likeregion_select, but the callback receives the selected region as a base64-encoded PNG image instead of just the rect. - New
zoom_to_selectioncommand and "Zoom to Selection" region-selection context menu entry — select a region and zoom in to fill the viewport with it, without cropping the rest of the document out of view like Narrow to Region does. - New
llm_viewcommand to toggle the LLM chat panel. - New
file_open_no_historycommand — opens a file without adding it to the recent-files list. - New
files_recent_cleancommand — removes recent-files entries whose file no longer exists on disk. - New
trim_marginscommand — hides the blank margins around each page's content, detected as pages are shown. - You can now click-and-drag an embedded image straight out of a document (PDF) onto another app or a file manager, saving/pasting it as a real PNG — instead of only being able to copy a selected region.
- New caret mode (
caret_modecommand, defaultF7) — a keyboard-driven text cursor for character-by-character navigation, cf. Firefox/Okular "caret browsing". Left/Right/Up/Down (alsohjkl), Home/End, and Shift+movement (also vim-styleH/J/K/L) to extend a selection; the existing yank command now has a default binding (y) to copy it. - A file that fails to open now keeps its own tab instead of vanishing — the tab title shows in red and the tab itself shows a centered error message, instead of a blocking "file not found" dialog with no trace of the attempt afterward.
- File Properties for PDFs now shows digital signature info (signer, date, reason, location) when the document has signature fields — this reports what the signature claims, not whether it's cryptographically valid.
- File Properties for images now also shows DPI. For CBZ/CBT it now shows the image count and the list of image files inside the archive (previously just page count).
- Text reflow for EPUB/FB2/MOBI, via new
font_size_increase/font_size_decrease/font_size_resetcommands — re-paginates the document at a larger or smaller text size without changing the page dimensions or affectingzoom_in/zoom_out(which stay pure raster scaling). Opt-in only; pagination never changes on its own. No default keybinding. - Menu icons switched to
QStylesystem icons only, for a consistent look across all platforms (previously mixed with Freedesktop theme icons that only rendered well on some Linux setups). - Recent Files entries now show real per-file-type icons from the OS instead of one generic glyph.
- New accessibility feature: high-contrast tone stretch (
behavior.high_contrast, withhigh_contrast_black_point/high_contrast_white_point) — cleans up muddy scanned-page backgrounds and sharpens low-contrast text. lektra.opt.page.bg/.fgnow accept hex-colour strings, not just integers.- ~50 menu actions across the app now have icons; toggle them off with
[window].show_menu_icons. Auto Fitmoved into theView → Fitsubmenu.- New
bookmark_export/bookmark_importcommands, with merge-on-import so re-importing the same file is safe. lektra.optfully audited against the TOML config — every config key is now reachable and settable from Lua (previously about half were missing or silently broken due to internal sort-order/casting bugs).- New
[tabs].open_positionconfig (end/start/after_current) for where new tabs land. - New
[behavior].close_on_last_tabto quit when the last tab closes. - Presentation mode is now fully implemented (previously a stub).
- New smart fit-to-width/height (
fit_width_smart/fit_height_smart) that ignores blank page margins. file_open_window/open_file_new_windowcommand is now actually registered.default_config.tomlrewritten to match the real parser and defaults.- Tutorial PDF audited and corrected against the real commands/keybindings.
- Command palette can now sort entries by how often you've picked them (most-used first, smex-style), via
[command_palette].sort_by_frequency(default on). Usage history persists across restarts unlesspersist_frequencyis turned off. Both are also exposed to Lua. lektra.event.register/.once/.unregister/.count/.clearnow accept a plain string event name (lektra.event.register("OnPageChanged", fn)) instead of requiring the fulllektra.event.EventType.OnPageChangedpath — the old enum form still works. The stub's callback-argument typing was also switched to string-literal overloads, which editors resolve reliably (the previous enum-value overloads didn't).
Bug Fixes
- Fix command in CONTRIBUTING.md file
- Fix most Lua document/view events (
OnFileOpen,OnReady,OnFileClose,OnPageChanged,OnZoomChanged,OnLinkClicked,OnTextSelected,OnSearchStarted/Finished/Cancelled, and both context-menu-requested events) never reaching listeners registered globally vialektra.event.register/.once— they only ever reached listeners registered per-view viaview:register. A script likeinit.luathat hooksOnFileOpenbefore any document is open (so it has no view to call:registeron) silently never fired. - Wire up two previously-unimplemented Lua events,
OnTabAddedandOnViewChanged(fires on split-pane focus changes too, not just tab switches). - Fix
OnZoomChangednot firing for the zoom paths most people actually use — mouse wheel, pinch, and Zoom In/Out with the defaultzoom.anchor_to_mouse = trueall bypassed the code path that dispatched it; onlyzoom_set/zoom_resetfired it. - Fix
lektra.event.clearbeing documented but never actually implemented — calling it did nothing. - Fix EPUB outline entries not navigating anywhere on double-click.
- Fix a crash (perceived as a freeze) double- or triple-clicking to select a word/line in a DjVu file — word/line/paragraph selection didn't check file type before touching MuPDF-only state DjVu doesn't have, now bails out cleanly instead.
- Fix detaching a tab to another window sometimes also spawning a spurious new window/process with the same document, caused by an unreliable window-focus heuristic instead of using Qt's own drag-result signal.
- Fix the statusbar (page number, mode, portal/narrow badges, etc.) not updating — or updating to the wrong state — when a window's last tab is closed or detached.
- Fix images rendering as diagonal coloured stripes when
behavior.dont_invert_imageswas enabled. - Fix
[page].bg/.fgbeing ignored for DjVu files. - Fix duplicate default keybindings when a
[keybindings]block was present in the config. - Fix two memory-safety bugs in the Lua config bridge that could read/write past object bounds.
- Fix focus mode not remembering the pre-toggle menubar/statusbar/tabbar visibility.
- Fix "Open File in VSplit/HSplit" always opening the first file in a new tab instead of splitting.
- Fix optional runtime libraries (djvulibre, rsvg, cairo) not loading on Debian/Ubuntu without the matching
-devpackage installed. - Fix a crash opening a file via VSplit/HSplit.
- Fix DjVu silently accepting a failed/corrupt decode job instead of reporting an error.
- Fix heap corruption rendering DjVu pages with zero DPI or oversized dimensions.
- Fix several null-deref crashes in DjVu message handling and during document swap.
- Fix a crash destroying an animated image mid-playback.
- Fix a crash in preview navigation when the window closes mid-timer.
- Fix a null-deref on IPC connection handling.
- Fix an infinite rotation loop from a malformed cross-window tab drop.
- Fix DjVu files with non-ASCII paths failing to open on Windows.
- Fix "Open Containing Folder" doing nothing.
- Fix stale search results/popups reappearing after cancelling or re-searching.
- Fix multi-file CLI open running
--commandbefore any file had actually loaded. - Fix zoom visibly jumping/snapping in continuous, horizontal, and book layout modes (mouse wheel, touchpad pinch, and keyboard zoom) — it now stays smoothly anchored under the cursor, matching single-page mode.
- Fix internal link (TOC/page-jump) hover tooltips showing a raw internal destination string instead of something meaningful — they now show "Go to page N".
- Fix a race that could double-fire the open-finished handler on rapid consecutive opens.
- Fix File Properties freezing on a DjVu file with a broken annotation job.
- Fix
lektra.opt.<section> = {...}whole-table assignment silently discarding the real config instead of applying it — this affected everyoptsection, including nested ones likepicker.shadow. - Fix CBZ files failing to open — content-based file-type detection can't distinguish a CBZ from a plain zip, so it's now recognized by extension like MuPDF itself does.
- Fix a long-standing bug where a failed or password-protected open could silently go nowhere:
openAsync()disconnects and never reconnects the signals that report those outcomes back to the view, on every single open attempt (not just retries). - Fix the total page count shown in the statusbar not updating after changing font size in a reflowable document (EPUB/FB2/MOBI), even though the number of pages actually changes when text re-paginates.
- Fix a brief blank view (just scrollbars, no page) right after a document finishes opening — the loading spinner now stays up until the first page has actually rendered, instead of stopping as soon as the document's metadata finished parsing.
- Fix scrollbars briefly flashing in the wrong spot (top-left corner) instead of staying hidden when a file fails to open.
- Fix crash reports being useless on a normal (Release) build — no debug info was kept and the app's own functions weren't even resolvable by name. Crash reports now include a properly symbolized stack trace (function names + file/line) alongside the raw one.