github beeware/toga v0.5.4
0.5.4

10 hours ago

Features

  • It is now possible to draw bitmap images on a Canvas. (#995)
  • The DetailedList widget on Windows has been massively improved, and now matches the visual appearance on other platforms. (#2110, #4319)
  • Widget implementations are now contributed by entry points, allowing lazy loading on a per-widget basis. (#2687)
  • Toga's WinForms backend can now be used on ARM64 machines with a native ARM64 Python interpreter. (#2782)
  • The GTK4 backend now integrates with libadwaita for ActivityIndicator, Window, and App. (#3069)
  • Toga Positron now has a bootstrap for FastAPI-based websites. (#3327)
  • The WebView widget now supports an on_navigation_starting handler to prevent user-defined URLs from being loaded (#3442)
  • The Qt backend now has implementations for all widgets, plus support for dialogs, fonts and status icons. (#3914)
  • The currently active backend can now be retrieved at runtime using toga.backend. (#3923)
  • Android apps now support the use of webbrowser.open(). (#3932)
  • The on_webview_load handler is now supported on Android (#4036)
  • Apps built with Toga no longer requires the "Requires Full Screen" key in the app template, allowing support for multitasking on iPadOS. (#4043)
  • The columns of Table and Tree widgets can now be specified using Column objects that provide a richer interface for configuring data access. (#4091)
  • The header row of a Table and Tree widget can now be hidden. (#4091)
  • The rgb and hsl color representation classes now declare slots, reducing memory usage. (#4136)
  • The Canvas widget can now draw rounded rectangles. (#4161)
  • The Table widget on WinForms can now display icons in all columns. Previously, icons were only supported in the first column. (#4164)
  • ListSource and TreeSource now allow mapping-based data to be used without explicitly providing accessors. (#4221)
  • The web backend now uses WebAwesome instead of Shoelace to provide web components. (#4227)
  • The Switch widget is now supported in the Textual backend. (#4230)
  • The Tree widget is now supported in the Windows backend. (#4235, #4360)
  • macOS and iOS apps can now use any font that has been registered with the operating system. (#4307)
  • The Canvas widget now has save and restore methods, and supports setting the drawing context attributes fill_style, stroke_style, line_width, and line_dash. (#4332)
  • The Toga repository now has an AGENTS.md file and Spec Kit constitution to provide assistance for Generative AI tools. (#4344)

Bugfixes

  • The Canvas widget on Android, Qt and WinForms now matches the behavior of the HTML Canvas when a transform is applied while preparing a path. (#2206)
  • Calling stroke() or fill() in a Canvas context no longer clears the current path. (#2207)
  • SplitContainers in a non-primary tab of OptionContainer will now correctly apply its split on Cocoa. (#2288)
  • The key event handling code now supports non-US keyboards better on macOS. More keys are supported on Qt. (#2428)
  • Memory leaks for all remaining widgets have been resolved on all leaking platforms. (#2849)
  • Apps no longer crash if an icon file exists but is cannot be loaded. Toga now logs a warning and falls back to a default icon. (#3565)
  • When creating an Image from a file path, it's now guaranteed that the file won't remain open after construction. (#3730)
  • On Android, DetailedList now uses theme-resolved text colors (Primary/Secondary) instead of hard-coded black, fixing unreadable text in dark mode. (#3751)
  • Calling scroll_to_bottom() on a MultilineTextInput that is already at the bottom of the scroll area no longer causes a "bounce" in the scroll position. (#3872)
  • Double-clicking on the header or an empty row a macOS Table no longer triggers the activation of the last item, raising an error if there is no data. (#3905)
  • The text color of TextInput on macOS in dark mode has been fixed. (#3919)
  • When adding or removing tabs from an OptionContainer, or when setting the content of a SplitContainer, the window and app properties of the content, and the App and Window's widget registry, are now correctly updated. (#3929)
  • Nested OptionContainers will now show label text correctly on iOS 26+. (#3949)
  • On iOS, the height of the top status bar will now be accounted for properly when the device is rotated. (#3957)
  • Apps now log an error instead of crashing if the system locale value is set to an unknown or invalid value. (#3984)
  • Label, Box, and ImageView widgets will now display with a transparent background on the Qt backend. (#3997)
  • NumberInput values on macOS no longer visually disappear when the widget loses focus. (#3998)
  • Cocoa and GTK OptionContainer widgets now rehints properly to accommodate for all of its content sizes at all times, in addition to the decorations around them. (#4010)
  • OptionContainer and ScrollContainer widgets inside an OptionContainer will no longer error on layout on Cocoa. (#4010)
  • Setting an item in a ListSource now gives a "change" instead of an "insert" notification. (#4029)
  • Data source listeners are now fully disconnected when data changes in DetailedList, Selection, Table and Tree widgets. (#4030)
  • On Cocoa, ineffective scrolls in an inner ScrollContainer will now be automatically passed on to the outer ScrollContainer. (#4034)
  • Cocoa ScrollContainer widgets will now handle elastic effects in small contents properly in a fashion similar to native apps. (#4034)
  • There are now different Listener protocols for ValueSource, ListSource, and TreeSource. (#4035)
  • Any AttributeError generated by data source Row and Node objects now reference the correct attribute name. (#4037)
  • GTK4's DateInput now consistently emits signals on programmatic change, even when only the year component is altered. (#4040)
  • MainWindow objects on iOS will no longer have their content overlap slightly with the navigation bar. (#4043)
  • The ListListener and TreeListener protocols no longer incompatibly override the insert, remove and clear methods of ListSource and TreeSource, permitting mutable sources which are also listeners. (#4046)
  • WinForms buttons with icons will now reliably scale to 32x32px icon size, regardless of the size of the original icon image. (#4051)
  • Screen.as_image now properly accounts for HiDPI scaling on Winforms. (#4051)
  • Large static content can now be loaded into WebView widgets on Windows, Android and Qt. (#4062)
  • The initial layout of a MainWindow before resize will now be based on the correct size of the container. (#4069)
  • Window state transitions to MAXIMIZED from PRESENTATION or FULLSCREEN will now work reliably with the Qt backend. (#4069)
  • The list of accessors for creating rows in Table and Tree widgets is now set at widget creation time, preventing inconsistent data conversion if columns are changed. (#4071)
  • Qt windows will now properly close when a close is requested on the application. (#4078)
  • File reference handling in the Android event loop has been corrected. (#4083)
  • On Cocoa, when not setting a background color, DateInput, TimeInput, and MultilineTextInput now paints the proper background. (#4099)
  • On Cocoa, setting the background color from non-transparent colors to transparent now works correctly on the Selection and MultilineTextInput widgets. (#4099)
  • Previously, it was documented that setting the colors for Selection would not work on Cocoa; however, the background color worked partially, coloring an entire rectangular widget instead of the widget itself. The color handling is now entirely removed for Selection. (#4099)
  • There are no longer any zero division errors when drawing an ellipse in a Canvas on macOS, iOS or GTK backends. (#4161)
  • The Android implementation of Canvas now has the same default corner-mitering threshold as the HTML canvas specification. (#4162)
  • The mouse wheel scrolling behavior of MultilineTextInput has been improved. (#4222)
  • Entering presentation mode with multiple windows now correctly puts all windows into presentation mode, not just the last one. (#4233)
  • In Light Mode on macOS, when a DetailedList is not focused but has a selection, the text now draws dark instead of light to preserve contrast. (#4264)
  • To better match native styling, the focus border on macOS DetailedList has been removed. (#4270)
  • Right-aligned, multi-line strings that contain an empty line are now correctly sized on macOS. (#4315)
  • Canvas now consistently handles line-dash patterns of an odd or zero length. (#4334)
  • App-level dialogs on macOS 26 are now reliably responsive to clicks for dismissal. (#4346)
  • Some runtime errors caused by Window event handlers firing as part of the window initialization process have now been silenced. (#4347)
  • Toga's lazy-loading mechanism now uses an explicit file encoding. (#4365)

Backward Incompatible Changes

  • The get_platform_factory() function and backend factory modules are deprecated. Widget authors should use toga.get_factory() instead, and writers of new backends should use entry points to declare the implemented objects. The new factory objects are not modules but instead are lazy namespace objects. (#2687)

  • The parsing function travertino.colors.color() (also accessible as toga.colors.color()) is deprecated. The Travertino method has been renamed travertino.colors.Color.parse(). There should be no need to use this method in Toga, as all APIs that accept colors will automatically parse of raw color representations from strings. (#3946)

  • Source objects now look for methods with names of the form source_{notification}, rather than just {notification} when the notify method is called. If you have a custom listener class with methods like change, insert, remove or clear, you should re-name them to have a source_ prefix: source_change, source_insert and so on. (#4046)

  • When nesting stroke contexts or fill contexts for Canvas drawing operations, leaving an argument (e.g. color) blank on an inner context now respects any value set on the outer context, instead of resetting it to the default. (#4057)

  • The Canvas widget has undergone some significant internal changes.

    • Drawing methods can now be called directly on a Canvas. Calling them on states is now deprecated.
    • The "camel case" context manager drawing methods (ClosedPath, Fill, and Stroke) are deprecated. They are now unified with their standalone counterparts (close_path, fill, and stroke, respectively). For example, the fill method (lowercase) can be used as a normal method or as with canvas.fill():.
    • List-like methods on states are deprecated. Manipulate their drawing_actions lists directly, and manually call redraw() on the Canvas.
    • Calling redraw() on states is deprecated. Call Canvas.redraw() instead.
    • States no longer hold a reference to their Canvas; their canvas attribute is deprecated. (This is largely an internal detail, and unlikely to affect user code.)
    • The class toga.widgets.canvas.Context has been renamed from Context to State.
    • Context's Context() method has also been renamed to state().
    • The context property of Canvas has been renamed to root_state.
    • toga.widgets.canvas.DrawingObject has been renamed from DrawingObject to DrawingAction. This is an internal class, and is unlikely to be used directly.

    The previous names and APIs should still work, but will raise a DeprecationWarning if used. See the [upgrading guide][canvas-0-5-4-upgrade] for more details on how to update Canvas usage. (#4082, #4159)

  • Instances of the WriteText and DrawImage objects representing Canvas actions now report None when queried for their attributes that haven't been set, instead of supplying the default. (#4089)

  • Using headings as a keyword argument when creating Table and Tree objects is deprecated. Any headings argument should be replaced with columns. The use of headings=None to hide the header row has been deprecated; use show_headings=False instead. (#4091)

  • Specifying accessors when creating Table and Tree widgets is deprecated. Use of accessor arguments on insert_column() and append_column() methods has also been deprecated. Use accessor arguments on column objects or data sources instead. (#4091)

  • The behavior of the Canvas widget when a drawing was scaled by a factor of 0 in either axis was unspecified and varied across backends and HTML Canvas implementations. The Canvas widget now follows a consistent, reasonable behavior when this happens which should produce similar results on all backends. On some backends, to avoid errors or other drawing problems, a very small scale factor is used instead of 0 when asked to scale by 0. (#4110)

  • The specification for Tree/Table column data has historically documented that an icon in a column is specified with a 2-tuple. However, on some platforms, the implementation has allowed n-tuples and/or other collection types. This has now been constrained - a 2-tuple is the only way to specify an icon for column data; and using a tuple of any length other than 2 will raise an error. (#4135)

Documentation

  • Documentation has been added for colors. (#3568)
  • The "Success Stories" page has been reformatted into a structured table with consistent fields for platform support, screenshots, descriptions, and BeeWare components. (#3596)
  • The API reference documentation has been restructured. (#3941)
  • A new contribution guide has been added. (#3969)
  • Data source topic guide now includes a discussion of how and when to connect and disconnect Listeners from Sources. (#4030)
  • The API design guide now references the BeeWare code style guide. (#4231)
  • The FAQ has been updated with entries about file access. (#4239)
  • Known limitations on the usage of OptionContainer as nested content on mobile platforms are now documented. (#4297)
  • The Canvas documentation has been revamped, with the existing content splitting into two pages (general reference and advanced usage), plus the addition of a migration guide for the new API changes. (#4362)

Misc

Don't miss a new toga release

NewReleases is sending notifications on new releases.