Skip to content

Commit 52af22d

Browse files
committed
Refactor WeakrefCallable to be a core handler
1 parent e8c8a04 commit 52af22d

22 files changed

+49
-43
lines changed

core/src/toga/handlers.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import sys
66
import traceback
77
import warnings
8+
import weakref
89
from abc import ABC
910
from collections.abc import Awaitable, Callable, Generator
1011
from typing import TYPE_CHECKING, Any, NoReturn, Protocol, TypeVar, Union
@@ -259,3 +260,25 @@ def __bool__(self, other: object) -> NoReturn:
259260

260261
class PermissionResult(AsyncResult):
261262
RESULT_TYPE = "permission"
263+
264+
265+
class WeakrefCallable:
266+
"""
267+
A wrapper for callable that holds a weak reference to it.
268+
269+
This can be useful in particular when setting winforms event handlers, to avoid
270+
cyclical reference cycles between Python and the .NET CLR that are detected neither
271+
by the Python garbage collector nor the C# garbage collector. It is also used
272+
for some of the GTK4 event controllers.
273+
"""
274+
275+
def __init__(self, function):
276+
try:
277+
self.ref = weakref.WeakMethod(function)
278+
except TypeError: # pragma: no cover
279+
self.ref = weakref.ref(function)
280+
281+
def __call__(self, *args, **kwargs):
282+
function = self.ref()
283+
if function: # pragma: no branch
284+
return function(*args, **kwargs)

winforms/src/toga_winforms/app.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@
1010
from System.Net import SecurityProtocolType, ServicePointManager
1111
from System.Windows.Threading import Dispatcher
1212

13+
from toga.handlers import WeakrefCallable
14+
1315
from .libs.proactor import WinformsProactorEventLoop
14-
from .libs.wrapper import WeakrefCallable
1516
from .screens import Screen as ScreenImpl
1617

1718

winforms/src/toga_winforms/dialogs.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@
99
)
1010
from System.Windows.Forms import DialogResult, MessageBoxButtons, MessageBoxIcon
1111

12+
from toga.handlers import WeakrefCallable
13+
1214
from .libs.user32 import DPI_AWARENESS_CONTEXT_UNAWARE, SetThreadDpiAwarenessContext
13-
from .libs.wrapper import WeakrefCallable
1415

1516

1617
class BaseDialog:

winforms/src/toga_winforms/libs/wrapper.py

Lines changed: 0 additions & 22 deletions
This file was deleted.

winforms/src/toga_winforms/statusicons.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22

33
import toga
44
from toga.command import Group, Separator
5-
6-
from .libs.wrapper import WeakrefCallable
5+
from toga.handlers import WeakrefCallable
76

87

98
class StatusIcon:

winforms/src/toga_winforms/widgets/button.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
from travertino.size import at_least
55

66
from toga.colors import TRANSPARENT
7+
from toga.handlers import WeakrefCallable
78

8-
from ..libs.wrapper import WeakrefCallable
99
from .base import Widget
1010

1111

winforms/src/toga_winforms/widgets/canvas.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@
2424

2525
from toga.colors import TRANSPARENT
2626
from toga.constants import Baseline, FillRule
27+
from toga.handlers import WeakrefCallable
2728
from toga.widgets.canvas import arc_to_bezier, sweepangle
2829
from toga_winforms.colors import native_color
2930

30-
from ..libs.wrapper import WeakrefCallable
3131
from .box import Box
3232

3333

winforms/src/toga_winforms/widgets/dateinput.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
import System.Windows.Forms as WinForms
55
from System import DateTime as WinDateTime
66

7-
from ..libs.wrapper import WeakrefCallable
7+
from toga.handlers import WeakrefCallable
8+
89
from .base import Widget
910

1011

winforms/src/toga_winforms/widgets/mapview.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@
88
from System.Threading.Tasks import Task, TaskScheduler
99

1010
import toga
11+
from toga.handlers import WeakrefCallable
1112
from toga.types import LatLng
1213
from toga_winforms.libs.extensions import (
1314
CoreWebView2CreationProperties,
1415
WebView2,
1516
WebView2RuntimeNotFoundException,
1617
)
1718

18-
from ..libs.wrapper import WeakrefCallable
1919
from .base import Widget
2020

2121
MAPVIEW_HTML_CONTENT = """<!DOCTYPE html>

winforms/src/toga_winforms/widgets/multilinetextinput.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
from System.Drawing import SystemColors
33
from travertino.size import at_least
44

5+
from toga.handlers import WeakrefCallable
56
from toga_winforms.colors import native_color
67
from toga_winforms.libs.fonts import HorizontalTextAlignment
78

8-
from ..libs.wrapper import WeakrefCallable
99
from .textinput import TextInput
1010

1111

winforms/src/toga_winforms/widgets/numberinput.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
import System.Windows.Forms as WinForms
55
from System import Convert, String
66

7+
from toga.handlers import WeakrefCallable
78
from toga.widgets.numberinput import _clean_decimal
89
from toga_winforms.libs.fonts import HorizontalTextAlignment
910

10-
from ..libs.wrapper import WeakrefCallable
1111
from .base import Widget
1212

1313

winforms/src/toga_winforms/widgets/optioncontainer.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
from System.Windows.Forms import TabControl, TabPage
22

3+
from toga.handlers import WeakrefCallable
4+
35
from ..container import Container
4-
from ..libs.wrapper import WeakrefCallable
56
from .base import Widget
67

78

winforms/src/toga_winforms/widgets/scrollcontainer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
from System.Windows.Forms import Panel, SystemInformation
55
from travertino.node import Node
66

7+
from toga.handlers import WeakrefCallable
78
from toga_winforms.container import Container
89

9-
from ..libs.wrapper import WeakrefCallable
1010
from .base import Widget
1111

1212
# On Windows, scroll bars usually appear only when the content is larger than the

winforms/src/toga_winforms/widgets/selection.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33

44
import System.Windows.Forms as WinForms
55

6-
from ..libs.wrapper import WeakrefCallable
6+
from toga.handlers import WeakrefCallable
7+
78
from .base import Widget
89

910

winforms/src/toga_winforms/widgets/slider.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
import System.Windows.Forms as WinForms
44

55
from toga.colors import TRANSPARENT
6+
from toga.handlers import WeakrefCallable
67
from toga.widgets.slider import IntSliderImpl
78

8-
from ..libs.wrapper import WeakrefCallable
99
from .base import Widget
1010

1111
# Implementation notes

winforms/src/toga_winforms/widgets/splitcontainer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
)
66

77
from toga.constants import Direction
8+
from toga.handlers import WeakrefCallable
89

910
from ..container import Container
10-
from ..libs.wrapper import WeakrefCallable
1111
from .base import Widget
1212

1313

winforms/src/toga_winforms/widgets/switch.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
from travertino.size import at_least
55

66
from toga.colors import TRANSPARENT
7+
from toga.handlers import WeakrefCallable
78

8-
from ..libs.wrapper import WeakrefCallable
99
from .base import Widget
1010

1111

winforms/src/toga_winforms/widgets/table.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
import System.Windows.Forms as WinForms
44

55
import toga
6+
from toga.handlers import WeakrefCallable
67

7-
from ..libs.wrapper import WeakrefCallable
88
from .base import Widget
99

1010

winforms/src/toga_winforms/widgets/textinput.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44

55
import System.Windows.Forms as WinForms
66

7+
from toga.handlers import WeakrefCallable
78
from toga_winforms.colors import native_color
89
from toga_winforms.libs.fonts import HorizontalTextAlignment
910

10-
from ..libs.wrapper import WeakrefCallable
1111
from .base import Widget
1212

1313

winforms/src/toga_winforms/widgets/timeinput.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
import System.Windows.Forms as WinForms
55
from System import DateTime as WinDateTime
66

7-
from ..libs.wrapper import WeakrefCallable
7+
from toga.handlers import WeakrefCallable
8+
89
from .base import Widget
910

1011

winforms/src/toga_winforms/widgets/webview.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from System.Threading.Tasks import Task, TaskScheduler
1414

1515
import toga
16+
from toga.handlers import WeakrefCallable
1617
from toga.widgets.webview import CookiesResult, JavaScriptResult
1718
from toga_winforms.libs.extensions import (
1819
CoreWebView2Cookie,
@@ -21,7 +22,6 @@
2122
WebView2RuntimeNotFoundException,
2223
)
2324

24-
from ..libs.wrapper import WeakrefCallable
2525
from .base import Widget
2626

2727

winforms/src/toga_winforms/window.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010
from toga import App
1111
from toga.command import Separator
1212
from toga.constants import WindowState
13+
from toga.handlers import WeakrefCallable
1314
from toga.types import Position, Size
1415

1516
from .container import Container
1617
from .fonts import DEFAULT_FONT
17-
from .libs.wrapper import WeakrefCallable
1818
from .screens import Screen as ScreenImpl
1919
from .widgets.base import Scalable
2020

0 commit comments

Comments
 (0)