Expose a mechanism for hooking into platform-specific App lifecycle events
#4,478 opened on Jun 18, 2026
Repository metrics
- Stars
- (3,615 stars)
- PR merge metrics
- (Avg merge 1d 10h) (47 merged PRs in 30d)
Description
What is the problem or limitation you are having?
Discussions like #1623 and #2329 involve the design of a cross-platform API that can capture app lifecycle events like "start", "resume", "sleep", "destroy" or "back".
However, in the absence of a cross-platform solution, we should expose mechanisms that enable users to plug functionality into these lifecycle events. This is part of a general principle of making platform-specific overrides possible in the absence of a cross-platform solution.
Describe the solution you'd like
On iOS, Android and macOS, these are all captured by delegate classes at the App level, implementing any logic needed by Toga's own cross-platform APIs.
The logic in these delegate classes should be moved to the implementation class, and the delegate class should call the implementation layer with all arguments provided to the delegate. For example, the macOS AppDelegate has a applicationDidFinishLaunching_(self, notification) method; the logic in that method should be moved to a cocoa_applicationDidFinishLaunching(self, notification) method on the Cocoa App class.
In addition, every known interface provided by the delegate should be implemented, deferring to a no-op implementation on the App class. This would allow a user to define user implementations. For example, Cocoa doesn't currently define a applicationDidBecomeActive: handler; it should, deferring to an empty cocoa_applicationDidBecomeActive(self, notification) method on the Cocoa App class.
This would allow a user to define:
if sys.platform == "darwin":
from toga_cocoa.app import App as NativeApp
def myDidBecomeActive(self, notification):
# ... custom logic before base class implementation...
NativeApp.cocoa_applicationDidBecomeActive(self, notification)
# ... custom logic after base class implementation...
class MyApp(toga.App):
def startup(self):
...
if sys.platform == "darwin":
self._impl.cocoa_applicationDidBecomeActive = myDidBecomeActive
GTK and Windows use event handlers rather than delegate classes; we should install event handlers for each known app lifecycle event that don't already exist.
Describe alternatives you've considered
- Wait until we have cross-platform APIs. This impedes progress for those who need any solution now.
- Provide a mechanism for platform-native event handlers similar to cross-platform event handlers at the interface level. This is overkill for a feature that should be considered a short-term workaround until we're able to establish a cross-platform API.
Additional context
This could be implemented on a per-platform basis - it would be acceptable to merge a solution for Android without having a solution for iOS or macOS etc.
The new methods should be documented in the "platform specific APIs" section for each platform (e.g., this section in the Android docs).
A topic guide on platform-native extensions would be worth adding as part of this work.