Release Notes
A history of updates and improvements to Pyroom.
- Improved console input behavior by disabling automatic text corrections to make command entry more consistent across devices and keyboard locales.
- Added online sharing via server-stored payloads: share your project with an 8-character code or a short link (pyroom.app/s/…) that others can open directly in the playground.
- Redesigned Share modal with Offline (QR) and Online tabs — offline QR sharing remains fully functional without internet, online sharing supports payloads up to 20 KB.
- Added configurable expiration for online shares: choose from 1 hour to 1 year; shared projects are automatically deleted after expiry.
- Added 'Enter share code' menu item that opens a dedicated dialog for importing a project by its 8-character code.
- Short links (pyroom.app/s/…) automatically redirect to the playground and trigger an import confirmation dialog with project metadata.
- Fixed a Windows editor issue where typing a space could insert characters a few positions away from the visible caret in Monaco.
- Adjusted Monaco text rendering/input settings on Windows to improve cursor alignment and typing accuracy on fractional display scaling.
- Isolated Monaco's hidden input textarea from global form styles to prevent CSS side effects from impacting caret behavior.
- Expanded site navigation across English and Ukrainian pages, including mobile menu support and quick links for audiences and workflows.
- Improved UI interaction polish with refined button active states, interactive element transitions, and better Monaco text selection behavior on mobile devices.
- Added language suggestion support for Ukrainian users and improved discoverability with updated sitemap entries and robots.txt metadata cleanup.
- Fixed PyProxy memory leak: persistCallback() now tracks every .copy() created for buttons, checkbuttons, radiobuttons, bind(), and menu commands per widget; destroy() and reset() call .destroy() on all tracked copies.
- Extended Text widget index parsing: parseTextIndex() now handles 'end-1c', 'end+Nc', 'end-Nl' (line offset), 'insert' (cursor position), 'sel.first', 'sel.last', and compound indices like '1.0+2c'. textGet/textInsert/textDelete/textTagAdd/textTagRemove all pass live cursor and selection context.
- Functional Scrollbar: replaced decorative div with a styled track+thumb widget. The command option fires a Python callback with scroll fraction on drag. Added Scrollbar.set(first, last) to move the thumb when the linked widget scrolls.
- Replaced messagebox window.alert/window.confirm with a custom async DOM modal: styled overlay with title, icon, message text, and OK/Cancel buttons. All messagebox functions are now async def and return awaitable results. Keyboard shortcuts Enter/Escape work correctly.
- Fixed grid auto-sizing: grid() now updates grid-template-columns and grid-template-rows on the parent after each placement, automatically expanding 'auto' tracks to cover the new cell's column+span and row+span while respecting existing columnconfigure/rowconfigure weight settings.
- Fixed variable memory leak: gcVariableIfUnbound() deletes a variable's value from the variables map when the last binding (entry, text, scale, listbox, check, radio) and all traces are removed, preventing unbounded growth in long-running sessions.
- Added LabelFrame widget: titled border container rendered as a <fieldset>/<legend> pair, supporting child widget packing, bg/fg/font/relief options, and grid/pack layout.
- Added OptionMenu widget: standard tkinter dropdown that binds bidirectionally to a StringVar/Variable — selection changes update the variable and variable changes update the displayed option.
- Added ttk.Notebook widget with add(), select(), index(), and tabs() methods: supports multiple tab panels with a clickable tab bar and correct show/hide switching.
- Added ttk.Treeview widget with full insert/delete/heading/column/item/set/selection API rendered as an HTML table, supporting nested children, column widths, and row selection.
- Added columnconfigure() and rowconfigure() with weight parameter on Frame, Tk, and all widgets: weighted columns/rows expand using CSS fr units, minsize maps to minmax().
- Added after_idle() on Tk and all widgets: schedules a callback on the next idle cycle using requestIdleCallback (with setTimeout(0) fallback), matching standard Tkinter semantics.
- Added winfo_children(), winfo_exists(), and winfo_parent() for programmatic widget tree introspection — winfo_exists() returns False after destroy(), winfo_children() returns only direct children.
- Added configure() support for relief (sunken/raised/ridge/groove/solid/flat), bd/borderwidth, cursor (with Tkinter→CSS cursor name mapping), justify, anchor, and wraplength options on all widgets.
- Added state='readonly' for Entry and Text widgets: sets the HTML readOnly attribute (allows text selection and copy but prevents editing), distinct from state='disabled'.
- Added Text widget tag system: tag_add(), tag_config()/tag_configure(), tag_remove(), and tag_delete() — tags are rendered via a transparent overlay div that displays coloured/styled spans alongside the textarea.
- Added ttk.LabelFrame alias in the ttk submodule. Expanded Tkinter shim test suite from 159 to 225 tests covering all new widgets and APIs.
- Fixed canvas item coordinate storage: create_line, create_rectangle, create_oval, create_arc, create_polygon, and create_text now store coords on creation so canvas.coords(), canvas.move(), canvas.bbox(), and canvas.find_overlapping() return correct results.
- Fixed canvas.itemconfigure(): changes to fill, outline, width, and other visual options now take effect on the next redraw instead of being silently ignored.
- Fixed canvas tag system: tags set via the tags option at creation time are now stored and searchable. Added canvas.addtag_withtag(), canvas.addtag_all(), canvas.dtag(), canvas.gettags(), and find_withtag('all') support.
- Fixed pack(side=LEFT/RIGHT/TOP/BOTTOM): widgets packed with side= now correctly flow horizontally (LEFT/RIGHT) or vertically (TOP/BOTTOM) using flexbox direction on the parent container.
- Fixed event binding: <FocusIn>, <FocusOut>, <MouseWheel>, <Configure>, and <Button-3> now map to the correct DOM events instead of falling through to click. Event payload now includes widget, state (modifier bitmask), delta (scroll), button, char, x_root, y_root, and width/height fields.
- Expanded keysym mapping: F1–F12, Home, End, Delete, BackSpace, Escape, Tab, Return, PageUp, PageDown, Insert, space, and arrow keys now translate to correct Tkinter keysym strings. Specific key bindings like <Key-a> now filter correctly.
- Added variable.trace_add(), trace_remove(), trace_info(), and legacy aliases trace() and trace_variable() — the standard pattern for reactive UIs now works without polling.
- Expanded Tkinter shim test suite from 88 to 159 tests covering canvas coordinates, tag system, pack side, event mapping, full event payload, keysym translation, and variable traces.
- Expanded Tkinter variable bindings across widgets: Entry, Label, Text, Scale, Checkbutton, Radiobutton, and Listbox now sync correctly with StringVar/IntVar/DoubleVar/BooleanVar.
- Added Tkinter compatibility fixes for browser runtime: exported tk.Variable, normalized worker RPC arguments, and eliminated DataCloneError when passing variables/lists in widget options.
- Improved Tkinter API behavior: Text supports row.column indices and 'end', pack() options now apply (padding/fill/expand), and event handling is more precise for <Return> and <B1-Motion>.
- Added broader API coverage tests for Tkinter shim to lock behavior and prevent regressions across variable sync, events, layout options, and text/list operations.
- Removed deprecated manifest links from HTML files to clean up outdated PWA references.
- Added build information logging to console: version number, commit hash, and build timestamp for easier debugging.
- Improved service worker caching strategy with error handling and fallback logic for fully offline support.
- Added multi-source fallback loading for Pyodide and Monaco Editor with automatic failover (primary host → local cache → CDN backup).
- Added download button for preview output on mobile devices with improved layout for visual content like Matplotlib charts.
- Extended service worker caching to support asset subdomains, enabling full offline access to Pyodide and Monaco Editor resources.
- Added Python library management panel with one-click installation, refresh, and cache clearing for packages like NumPy, Matplotlib, and Pandas.
- Added bug report system on pyroom.app website with automatic GitHub issue creation for tracking user feedback and feature requests.
- Added email subscription feature on pyroom.app for release notifications, allowing users to stay updated on new versions.
- Added Refresh button (F5 shortcut) to quickly reload the page and reset the Python runtime session.
- Extended onboarding tutorial with step-by-step guidance for the Refresh action on desktop and mobile.
- Improved preview panel: now expands to fill available height on desktop, and fullscreen mode added for better content viewing.
- Separated release notes and onboarding into independent dialogs with individual view tracking.
- Expanded onboarding tutorial with device-specific steps, menu navigation guide, undo/redo instructions, and improved progression.
- Redesigned mobile interface with footer action bar, dedicated editor/results view toggle, and enhanced output panel behavior.
- Improved release notes display with chronological scrolling and version badges showing release type (major/minor).
- Added responsive font sizing for console input and output on mobile devices for better readability.
- Added 'Restore Defaults' button in settings to quickly reset all preferences to initial values.
- Improved light theme styling for action buttons and tutorial highlighting.
- Redesigned mobile layout with separate Editor and Results views for clearer workflow.
- Added mobile action controls for quick view switching and code execution.
- Fixed overflow handling and rendering issues on Apple devices and small screens.
- Added iframe embedding mode with configurable interface visibility and read-only options for code sharing.
- Extended code sharing with custom metadata support and improved link opening behavior.
- Updated About panel and release notes display for clearer product information.
- Added interactive onboarding tutorial with step-by-step highlighting of editor and runtime features.
- Replaced text header buttons with icon-based controls for menu, undo, redo, and run actions.
- Improved preview and console panel arrangement with consistent sizing on desktop and mobile.
- Added Auto theme mode that automatically follows your system light/dark preference.
- Improved Tkinter preview stability and runtime handling on mobile devices.
- Added in-app update notification for new versions with automatic service worker refresh.
- Extended offline support by caching app manifest and icon files.
- Added Progressive Web App support with manifest and service worker for installable app experience.
- Added code sharing capabilities and undo/redo controls in the editor.
- Improved layout stability on iOS and mobile devices, updated icon rendering.
- Added application settings with language selection (English/Ukrainian) and basic interface customization.
- Added import/export functionality for Python code files (.py).
- Added clickable error links in console output and improved build scripts.
- Initial release: browser-based Python playground with Monaco code editor and Pyodide runtime.
- Added Tkinter support layer for creating graphical interfaces directly in the browser.
- Established core architecture: code editor, console input/output, and visual preview panel.