Features
- Toga's Textual backend now has an automated test harness. Coverage is not yet complete, but automated testing of Textual widgets is now possible. (#2663)
- On macOS, the logic in the app delegate's native lifecycle notification methods has been moved to
cocoa_-prefixed methods on thetoga_cocoaApp implementation class. Every native app lifecycle notification now has a corresponding method, most defaulting to a no-op, that can be overridden to add custom platform-specific behavior in the absence of a cross-platform lifecycle API. (#4478) - The binary DLLs needed to support WebView2 usage on Windows have been split into a standalone PyPI package (
dotnet-WebView2.WinForms). (#4582) - App paths now provide anchors for common user-space folders - the user's Desktop, Documents, Downloads and Pictures folders. (#4645)
- Support for Python 3.15 was added. (#4683)
Bugfixes
- Software keyboards from iOS
TextInputwidgets can now be dismissed by clicking on any other widget outside its bounds. (#1236) - Desktop backends now respect user and system environment configuration (XDG base directories on Linux;
%LOCALAPPDATA%on Windows) for application storage paths. (#2867) - On macOS, space is no longer allocated for separators in a toolbar, matching recent style changes in macOS. (#3786)
- On macOS Tahoe, toolbar icons are now correctly sized. (#3786)
- WinForms DPI resizing, including font, content, and window sizes, have been made significantly more reliable. (#4486)
- The WinForms event loop has become more resilient in the presence of long running repetitive tasks. (#4532)
- When a WinForms window with a divider undergoes a DPI change, the current length of the divider is no longer permanently imposed as a minimum. (#4566)
- WinForms now properly scales the contents of a Canvas in HiDPI. (#4583)
- The equality operator now works with the GTK implementation of Icon. (#4602)
- Boolean checks on an
AsyncResultnow raise the same helpful error as comparisons, instead of a confusingTypeError. (#4630) - The Dummy backend now correctly declares all dependencies it requires for operation, instead of relying on testing dependencies from Toga's core library. (#4675)
- On macOS,
app.paths.configis now aConfigfolder inside the app's~/Library/Application Supportfolder, rather than a folder in~/Library/Preferences. Apple's guidelines reserve the Preferences folder for the system preferences API; apps should not create files there themselves. (#4682) - The Static Positron bootstrap no longer fails to generate a new project when using Briefcase 0.4.5 or newer. (#4691)
- The iOS 27 SDK can now be used to run Toga applications with a switch from
ApplicationDelegatetoSceneDelegate. (#4695) - The Testbed app is now able to run on iOS 26. (#4720)
- Compatibility with Windows Server 2016 was restored. (#4735)
- On Android, the content of an
OptionContainerthat is added to a window that is already visible is no longer hidden behind the tab bar. (#4729) - On Qt, the content of an
OptionContainertab is now laid out when the tab is selected. (#4738) - On Qt, the width of a flexible
Selectionwidget is now applied correctly. (#4739)
Backward Incompatible Changes
- Python 3.10 is no longer supported. (#4683)
- The Cocoa, GTK, Qt, WinForms and Textual backends now use
platformdirsto determine the base location of app-specific paths. Path locations are unchanged on Windows and Linux; on macOS,app.paths.confighas moved from~/Library/Preferences/<app id>to~/Library/Application Support/<app id>/Config, andapp.paths.datahas moved from~/Library/Application Support/<app id>to aDatasub-folder of that location, so that app paths cannot collide. Toga does not move any existing files; an app that needs to preserve files stored at an old location must migrate them on first run.
Misc
- #3897, #4353, #4358, #4557, #4558, #4559, #4564, #4568, #4576, #4581, #4589, #4590, #4591, #4592, #4593, #4594, #4595, #4596, #4597, #4607, #4608, #4609, #4610, #4611, #4612, #4613, #4614, #4615, #4616, #4617, #4618, #4619, #4620, #4621, #4622, #4623, #4624, #4625, #4626, #4634, #4637, #4638, #4639, #4640, #4641, #4642, #4643, #4644, #4647, #4648, #4649, #4650, #4651, #4652, #4653, #4654, #4655, #4656, #4657, #4658, #4659, #4660, #4661, #4662, #4663, #4664, #4665, #4671, #4672, #4673, #4677, #4678, #4679, #4680, #4685, #4686, #4687, #4688, #4689, #4690, #4697, #4698, #4699, #4700, #4701, #4702, #4703, #4704, #4705, #4706, #4707, #4708, #4709, #4710, #4711, #4712, #4713, #4714, #4715, #4716, #4717, #4718, #4720, #4721, #4722, #4723, #4724, #4725, #4726, #4727, #4728, #4731, #4732, #4733, #4734