We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Toga scrollbar breaks with macOS Natural Scrolling preference
## Expected Behavior
Scrolling in Toga windows should be reflected in the scrollbar.

## Current Behavior
When debugging the Toga ``DetailedList`` example in ``toga/examples/detailedlist``, I noticed that the scrolling direction was reversed from the trackpad direction (since I have macOS natural scrolling enabled), however the scroll bar moved in the reverse direction.

## Steps to reproduce

On a computer running macOS with Natural Scrolling enabled (set this in `System Preferences > Trackpad > Scroll & Zoom`):
```
cd toga/examples/detailedlist && python -m detailedlist
```

(this example will crash. this is already documented in issue #549.)

## My Environment

``toga-cocoa, running on Python 3.7.3, on macOS Mojave 10.14.4 (18E226)``

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/cocoa/toga_cocoa/widgets/internal/refresh.py`
Content:
```
1 from toga_cocoa.libs import (
2     SEL,
3     NSClipView,
4     NSEvent,
5     NSEventPhaseEnded,
6     NSLayoutAttributeCenterX,
7     NSLayoutAttributeCenterY,
8     NSLayoutAttributeHeight,
9     NSLayoutAttributeNotAnAttribute,
10     NSLayoutAttributeTop,
11     NSLayoutAttributeWidth,
12     NSLayoutConstraint,
13     NSLayoutRelationEqual,
14     NSMakePoint,
15     NSMakeRect,
16     NSNotificationCenter,
17     NSPoint,
18     NSProgressIndicator,
19     NSProgressIndicatorSpinningStyle,
20     NSRect,
21     NSScrollElasticityAllowed,
22     NSScrollView,
23     NSView,
24     NSViewBoundsDidChangeNotification,
25     ObjCInstance,
26     core_graphics,
27     kCGScrollEventUnitLine,
28     objc_method,
29     send_super
30 )
31 
32 HEADER_HEIGHT = 45.0
33 
34 
35 class RefreshableClipView(NSClipView):
36     @objc_method
37     def constrainScrollPoint_(self, proposedNewOrigin: NSPoint) -> NSPoint:
38         constrained = send_super(
39             __class__, self, 'constrainScrollPoint:', proposedNewOrigin,
40             restype=NSPoint, argtypes=[NSPoint]
41         )
42 
43         if self.superview and self.superview.refreshTriggered:
44             return NSMakePoint(
45                 constrained.x,
46                 max(proposedNewOrigin.y, -self.superview.refreshView.frame.size.height)
47             )
48 
49         return constrained
50 
51     @objc_method
52     def isFlipped(self):
53         return True
54 
55     @objc_method
56     def documentRect(self) -> NSRect:
57         rect = send_super(__class__, self, 'documentRect', restype=NSRect, argtypes=[])
58 
59         if self.superview and self.superview.refreshTriggered:
60             return NSMakeRect(
61                 rect.origin.x, rect.origin.y - self.superview.refreshView.frame.size.height,
62                 rect.size.width, rect.size.height + self.superview.refreshView.frame.size.height
63             )
64         return rect
65 
66 
67 class RefreshableScrollView(NSScrollView):
68     # Create Header View
69     @objc_method
70     def viewDidMoveToWindow(self) -> None:
71         self.refreshTriggered = False
72         self.isRefreshing = False
73         self.refreshView = None
74         self.refreshIndicator = None
75         self.createRefreshView()
76 
77     @objc_method
78     def createContentView(self):
79         superClipView = ObjCInstance(send_super(__class__, self, 'contentView'))
80         if not isinstance(superClipView, RefreshableClipView):
81             # create new clipview
82             documentView = superClipView.documentView
83             clipView = RefreshableClipView.alloc().initWithFrame(superClipView.frame)
84 
85             clipView.documentView = documentView
86             clipView.copiesOnScroll = False
87             clipView.drawsBackground = False
88 
89             self.setContentView(clipView)
90             superClipView = ObjCInstance(send_super(__class__, self, 'contentView'))
91 
92         return superClipView
93 
94     @objc_method
95     def createRefreshView(self) -> None:
96         # delete old stuff if any
97         if self.refreshView:
98             self.refreshView.removeFromSuperview()
99             self.refreshView.release()
100             self.refreshView = None
101 
102         self.verticalScrollElasticity = NSScrollElasticityAllowed
103 
104         # create new content view
105         self.createContentView()
106 
107         self.contentView.postsFrameChangedNotifications = True
108         self.contentView.postsBoundsChangedNotifications = True
109 
110         NSNotificationCenter.defaultCenter.addObserver(
111             self,
112             selector=SEL('viewBoundsChanged:'),
113             name=NSViewBoundsDidChangeNotification,
114             object=self.contentView,
115         )
116 
117         # Create view to hold the refresh widgets refreshview
118         contentRect = self.contentView.documentView.frame
119         self.refreshView = NSView.alloc().init()
120         self.refreshView.translatesAutoresizingMaskIntoConstraints = False
121 
122         # Create spinner
123         self.refreshIndicator = NSProgressIndicator.alloc().init()
124         self.refreshIndicator.style = NSProgressIndicatorSpinningStyle
125         self.refreshIndicator.translatesAutoresizingMaskIntoConstraints = False
126         self.refreshIndicator.displayedWhenStopped = True
127         self.refreshIndicator.usesThreadedAnimation = True
128         self.refreshIndicator.indeterminate = True
129         self.refreshIndicator.bezeled = False
130         self.refreshIndicator.sizeToFit()
131 
132         # Center the spinner in the header
133         self.refreshIndicator.setFrame(
134             NSMakeRect(
135                 self.refreshView.bounds.size.width / 2 - self.refreshIndicator.frame.size.width / 2,
136                 self.refreshView.bounds.size.height / 2 - self.refreshIndicator.frame.size.height / 2,
137                 self.refreshIndicator.frame.size.width,
138                 self.refreshIndicator.frame.size.height
139             )
140         )
141 
142         # Put everything in place
143         self.refreshView.addSubview(self.refreshIndicator)
144         # self.refreshView.addSubview(self.refreshArrow)
145         self.contentView.addSubview(self.refreshView)
146 
147         # set layout constraints
148         indicatorHCenter = NSLayoutConstraint.constraintWithItem_attribute_relatedBy_toItem_attribute_multiplier_constant_(  # noqa: E501
149             self.refreshIndicator, NSLayoutAttributeCenterX,
150             NSLayoutRelationEqual,
151             self.refreshView, NSLayoutAttributeCenterX,
152             1.0, 0,
153         )
154         self.refreshView.addConstraint(indicatorHCenter)
155 
156         indicatorVCenter = NSLayoutConstraint.constraintWithItem_attribute_relatedBy_toItem_attribute_multiplier_constant_(  # noqa: E501
157             self.refreshIndicator, NSLayoutAttributeCenterY,
158             NSLayoutRelationEqual,
159             self.refreshView, NSLayoutAttributeCenterY,
160             1.0, 0,
161         )
162         self.refreshView.addConstraint(indicatorVCenter)
163 
164         refreshWidth = NSLayoutConstraint.constraintWithItem_attribute_relatedBy_toItem_attribute_multiplier_constant_(  # noqa: E501
165             self.refreshView, NSLayoutAttributeWidth,
166             NSLayoutRelationEqual,
167             self.contentView, NSLayoutAttributeWidth,
168             1.0, 0,
169         )
170         self.contentView.addConstraint(refreshWidth)
171 
172         refreshHeight = NSLayoutConstraint.constraintWithItem_attribute_relatedBy_toItem_attribute_multiplier_constant_(  # noqa: E501
173             self.refreshView, NSLayoutAttributeHeight,
174             NSLayoutRelationEqual,
175             None, NSLayoutAttributeNotAnAttribute,
176             1.0, HEADER_HEIGHT,
177         )
178         self.contentView.addConstraint(refreshHeight)
179 
180         refreshHeight = NSLayoutConstraint.constraintWithItem_attribute_relatedBy_toItem_attribute_multiplier_constant_(  # noqa: E501
181             self.refreshView, NSLayoutAttributeTop,
182             NSLayoutRelationEqual,
183             self.contentView, NSLayoutAttributeTop,
184             1.0, -HEADER_HEIGHT,
185         )
186         self.contentView.addConstraint(refreshHeight)
187 
188         # Scroll to top
189         self.contentView.scrollToPoint(NSMakePoint(contentRect.origin.x, 0))
190         self.reflectScrolledClipView(self.contentView)
191 
192     # Detecting scroll
193     @objc_method
194     def scrollWheel_(self, event) -> None:
195         if event.phase == NSEventPhaseEnded:
196             if self.refreshTriggered and not self.isRefreshing:
197                 self.reload()
198 
199         send_super(__class__, self, 'scrollWheel:', event)
200 
201     @objc_method
202     def viewBoundsChanged_(self, note) -> None:
203         if self.isRefreshing:
204             return
205 
206         if self.contentView.bounds.origin.y <= -self.refreshView.frame.size.height:
207             self.refreshTriggered = True
208 
209     # Reload
210     @objc_method
211     def reload(self) -> None:
212         """Start a reload, starting the reload spinner"""
213         self.isRefreshing = True
214         self.refreshIndicator.startAnimation(self)
215         self.interface.on_refresh(self.interface)
216 
217     @objc_method
218     def finishedLoading(self):
219         """Invoke to mark the end of a reload, stopping and hiding the reload spinner"""
220         self.isRefreshing = False
221         self.refreshTriggered = False
222         self.refreshIndicator.stopAnimation(self)
223         self.detailedlist.reloadData()
224 
225         # Force a scroll event to make the scroll hide the reload
226         cgEvent = core_graphics.CGEventCreateScrollWheelEvent(None, kCGScrollEventUnitLine, 2, 1, 0)
227         scrollEvent = NSEvent.eventWithCGEvent(cgEvent)
228         self.scrollWheel(scrollEvent)
229
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/cocoa/toga_cocoa/widgets/internal/refresh.py b/src/cocoa/toga_cocoa/widgets/internal/refresh.py
--- a/src/cocoa/toga_cocoa/widgets/internal/refresh.py
+++ b/src/cocoa/toga_cocoa/widgets/internal/refresh.py
@@ -48,10 +48,6 @@
 
         return constrained
 
-    @objc_method
-    def isFlipped(self):
-        return True
-
     @objc_method
     def documentRect(self) -> NSRect:
         rect = send_super(__class__, self, 'documentRect', restype=NSRect, argtypes=[])

{"golden_diff": "diff --git a/src/cocoa/toga_cocoa/widgets/internal/refresh.py b/src/cocoa/toga_cocoa/widgets/internal/refresh.py\n--- a/src/cocoa/toga_cocoa/widgets/internal/refresh.py\n+++ b/src/cocoa/toga_cocoa/widgets/internal/refresh.py\n@@ -48,10 +48,6 @@\n \n         return constrained\n \n-    @objc_method\n-    def isFlipped(self):\n-        return True\n-\n     @objc_method\n     def documentRect(self) -> NSRect:\n         rect = send_super(__class__, self, 'documentRect', restype=NSRect, argtypes=[])\n", "issue": "Toga scrollbar breaks with macOS Natural Scrolling preference\n## Expected Behavior\r\nScrolling in Toga windows should be reflected in the scrollbar.\r\n\r\n## Current Behavior\r\nWhen debugging the Toga ``DetailedList`` example in ``toga/examples/detailedlist``, I noticed that the scrolling direction was reversed from the trackpad direction (since I have macOS natural scrolling enabled), however the scroll bar moved in the reverse direction.\r\n\r\n## Steps to reproduce\r\n\r\nOn a computer running macOS with Natural Scrolling enabled (set this in `System Preferences > Trackpad > Scroll & Zoom`):\r\n```\r\ncd toga/examples/detailedlist && python -m detailedlist\r\n```\r\n\r\n(this example will crash. this is already documented in issue #549.)\r\n\r\n## My Environment\r\n\r\n``toga-cocoa, running on Python 3.7.3, on macOS Mojave 10.14.4 (18E226)``\n", "before_files": [{"content": "from toga_cocoa.libs import (\n    SEL,\n    NSClipView,\n    NSEvent,\n    NSEventPhaseEnded,\n    NSLayoutAttributeCenterX,\n    NSLayoutAttributeCenterY,\n    NSLayoutAttributeHeight,\n    NSLayoutAttributeNotAnAttribute,\n    NSLayoutAttributeTop,\n    NSLayoutAttributeWidth,\n    NSLayoutConstraint,\n    NSLayoutRelationEqual,\n    NSMakePoint,\n    NSMakeRect,\n    NSNotificationCenter,\n    NSPoint,\n    NSProgressIndicator,\n    NSProgressIndicatorSpinningStyle,\n    NSRect,\n    NSScrollElasticityAllowed,\n    NSScrollView,\n    NSView,\n    NSViewBoundsDidChangeNotification,\n    ObjCInstance,\n    core_graphics,\n    kCGScrollEventUnitLine,\n    objc_method,\n    send_super\n)\n\nHEADER_HEIGHT = 45.0\n\n\nclass RefreshableClipView(NSClipView):\n    @objc_method\n    def constrainScrollPoint_(self, proposedNewOrigin: NSPoint) -> NSPoint:\n        constrained = send_super(\n            __class__, self, 'constrainScrollPoint:', proposedNewOrigin,\n            restype=NSPoint, argtypes=[NSPoint]\n        )\n\n        if self.superview and self.superview.refreshTriggered:\n            return NSMakePoint(\n                constrained.x,\n                max(proposedNewOrigin.y, -self.superview.refreshView.frame.size.height)\n            )\n\n        return constrained\n\n    @objc_method\n    def isFlipped(self):\n        return True\n\n    @objc_method\n    def documentRect(self) -> NSRect:\n        rect = send_super(__class__, self, 'documentRect', restype=NSRect, argtypes=[])\n\n        if self.superview and self.superview.refreshTriggered:\n            return NSMakeRect(\n                rect.origin.x, rect.origin.y - self.superview.refreshView.frame.size.height,\n                rect.size.width, rect.size.height + self.superview.refreshView.frame.size.height\n            )\n        return rect\n\n\nclass RefreshableScrollView(NSScrollView):\n    # Create Header View\n    @objc_method\n    def viewDidMoveToWindow(self) -> None:\n        self.refreshTriggered = False\n        self.isRefreshing = False\n        self.refreshView = None\n        self.refreshIndicator = None\n        self.createRefreshView()\n\n    @objc_method\n    def createContentView(self):\n        superClipView = ObjCInstance(send_super(__class__, self, 'contentView'))\n        if not isinstance(superClipView, RefreshableClipView):\n            # create new clipview\n            documentView = superClipView.documentView\n            clipView = RefreshableClipView.alloc().initWithFrame(superClipView.frame)\n\n            clipView.documentView = documentView\n            clipView.copiesOnScroll = False\n            clipView.drawsBackground = False\n\n            self.setContentView(clipView)\n            superClipView = ObjCInstance(send_super(__class__, self, 'contentView'))\n\n        return superClipView\n\n    @objc_method\n    def createRefreshView(self) -> None:\n        # delete old stuff if any\n        if self.refreshView:\n            self.refreshView.removeFromSuperview()\n            self.refreshView.release()\n            self.refreshView = None\n\n        self.verticalScrollElasticity = NSScrollElasticityAllowed\n\n        # create new content view\n        self.createContentView()\n\n        self.contentView.postsFrameChangedNotifications = True\n        self.contentView.postsBoundsChangedNotifications = True\n\n        NSNotificationCenter.defaultCenter.addObserver(\n            self,\n            selector=SEL('viewBoundsChanged:'),\n            name=NSViewBoundsDidChangeNotification,\n            object=self.contentView,\n        )\n\n        # Create view to hold the refresh widgets refreshview\n        contentRect = self.contentView.documentView.frame\n        self.refreshView = NSView.alloc().init()\n        self.refreshView.translatesAutoresizingMaskIntoConstraints = False\n\n        # Create spinner\n        self.refreshIndicator = NSProgressIndicator.alloc().init()\n        self.refreshIndicator.style = NSProgressIndicatorSpinningStyle\n        self.refreshIndicator.translatesAutoresizingMaskIntoConstraints = False\n        self.refreshIndicator.displayedWhenStopped = True\n        self.refreshIndicator.usesThreadedAnimation = True\n        self.refreshIndicator.indeterminate = True\n        self.refreshIndicator.bezeled = False\n        self.refreshIndicator.sizeToFit()\n\n        # Center the spinner in the header\n        self.refreshIndicator.setFrame(\n            NSMakeRect(\n                self.refreshView.bounds.size.width / 2 - self.refreshIndicator.frame.size.width / 2,\n                self.refreshView.bounds.size.height / 2 - self.refreshIndicator.frame.size.height / 2,\n                self.refreshIndicator.frame.size.width,\n                self.refreshIndicator.frame.size.height\n            )\n        )\n\n        # Put everything in place\n        self.refreshView.addSubview(self.refreshIndicator)\n        # self.refreshView.addSubview(self.refreshArrow)\n        self.contentView.addSubview(self.refreshView)\n\n        # set layout constraints\n        indicatorHCenter = NSLayoutConstraint.constraintWithItem_attribute_relatedBy_toItem_attribute_multiplier_constant_(  # noqa: E501\n            self.refreshIndicator, NSLayoutAttributeCenterX,\n            NSLayoutRelationEqual,\n            self.refreshView, NSLayoutAttributeCenterX,\n            1.0, 0,\n        )\n        self.refreshView.addConstraint(indicatorHCenter)\n\n        indicatorVCenter = NSLayoutConstraint.constraintWithItem_attribute_relatedBy_toItem_attribute_multiplier_constant_(  # noqa: E501\n            self.refreshIndicator, NSLayoutAttributeCenterY,\n            NSLayoutRelationEqual,\n            self.refreshView, NSLayoutAttributeCenterY,\n            1.0, 0,\n        )\n        self.refreshView.addConstraint(indicatorVCenter)\n\n        refreshWidth = NSLayoutConstraint.constraintWithItem_attribute_relatedBy_toItem_attribute_multiplier_constant_(  # noqa: E501\n            self.refreshView, NSLayoutAttributeWidth,\n            NSLayoutRelationEqual,\n            self.contentView, NSLayoutAttributeWidth,\n            1.0, 0,\n        )\n        self.contentView.addConstraint(refreshWidth)\n\n        refreshHeight = NSLayoutConstraint.constraintWithItem_attribute_relatedBy_toItem_attribute_multiplier_constant_(  # noqa: E501\n            self.refreshView, NSLayoutAttributeHeight,\n            NSLayoutRelationEqual,\n            None, NSLayoutAttributeNotAnAttribute,\n            1.0, HEADER_HEIGHT,\n        )\n        self.contentView.addConstraint(refreshHeight)\n\n        refreshHeight = NSLayoutConstraint.constraintWithItem_attribute_relatedBy_toItem_attribute_multiplier_constant_(  # noqa: E501\n            self.refreshView, NSLayoutAttributeTop,\n            NSLayoutRelationEqual,\n            self.contentView, NSLayoutAttributeTop,\n            1.0, -HEADER_HEIGHT,\n        )\n        self.contentView.addConstraint(refreshHeight)\n\n        # Scroll to top\n        self.contentView.scrollToPoint(NSMakePoint(contentRect.origin.x, 0))\n        self.reflectScrolledClipView(self.contentView)\n\n    # Detecting scroll\n    @objc_method\n    def scrollWheel_(self, event) -> None:\n        if event.phase == NSEventPhaseEnded:\n            if self.refreshTriggered and not self.isRefreshing:\n                self.reload()\n\n        send_super(__class__, self, 'scrollWheel:', event)\n\n    @objc_method\n    def viewBoundsChanged_(self, note) -> None:\n        if self.isRefreshing:\n            return\n\n        if self.contentView.bounds.origin.y <= -self.refreshView.frame.size.height:\n            self.refreshTriggered = True\n\n    # Reload\n    @objc_method\n    def reload(self) -> None:\n        \"\"\"Start a reload, starting the reload spinner\"\"\"\n        self.isRefreshing = True\n        self.refreshIndicator.startAnimation(self)\n        self.interface.on_refresh(self.interface)\n\n    @objc_method\n    def finishedLoading(self):\n        \"\"\"Invoke to mark the end of a reload, stopping and hiding the reload spinner\"\"\"\n        self.isRefreshing = False\n        self.refreshTriggered = False\n        self.refreshIndicator.stopAnimation(self)\n        self.detailedlist.reloadData()\n\n        # Force a scroll event to make the scroll hide the reload\n        cgEvent = core_graphics.CGEventCreateScrollWheelEvent(None, kCGScrollEventUnitLine, 2, 1, 0)\n        scrollEvent = NSEvent.eventWithCGEvent(cgEvent)\n        self.scrollWheel(scrollEvent)\n", "path": "src/cocoa/toga_cocoa/widgets/internal/refresh.py"}], "after_files": [{"content": "from toga_cocoa.libs import (\n    SEL,\n    NSClipView,\n    NSEvent,\n    NSEventPhaseEnded,\n    NSLayoutAttributeCenterX,\n    NSLayoutAttributeCenterY,\n    NSLayoutAttributeHeight,\n    NSLayoutAttributeNotAnAttribute,\n    NSLayoutAttributeTop,\n    NSLayoutAttributeWidth,\n    NSLayoutConstraint,\n    NSLayoutRelationEqual,\n    NSMakePoint,\n    NSMakeRect,\n    NSNotificationCenter,\n    NSPoint,\n    NSProgressIndicator,\n    NSProgressIndicatorSpinningStyle,\n    NSRect,\n    NSScrollElasticityAllowed,\n    NSScrollView,\n    NSView,\n    NSViewBoundsDidChangeNotification,\n    ObjCInstance,\n    core_graphics,\n    kCGScrollEventUnitLine,\n    objc_method,\n    send_super\n)\n\nHEADER_HEIGHT = 45.0\n\n\nclass RefreshableClipView(NSClipView):\n    @objc_method\n    def constrainScrollPoint_(self, proposedNewOrigin: NSPoint) -> NSPoint:\n        constrained = send_super(\n            __class__, self, 'constrainScrollPoint:', proposedNewOrigin,\n            restype=NSPoint, argtypes=[NSPoint]\n        )\n\n        if self.superview and self.superview.refreshTriggered:\n            return NSMakePoint(\n                constrained.x,\n                max(proposedNewOrigin.y, -self.superview.refreshView.frame.size.height)\n            )\n\n        return constrained\n\n    @objc_method\n    def documentRect(self) -> NSRect:\n        rect = send_super(__class__, self, 'documentRect', restype=NSRect, argtypes=[])\n\n        if self.superview and self.superview.refreshTriggered:\n            return NSMakeRect(\n                rect.origin.x, rect.origin.y - self.superview.refreshView.frame.size.height,\n                rect.size.width, rect.size.height + self.superview.refreshView.frame.size.height\n            )\n        return rect\n\n\nclass RefreshableScrollView(NSScrollView):\n    # Create Header View\n    @objc_method\n    def viewDidMoveToWindow(self) -> None:\n        self.refreshTriggered = False\n        self.isRefreshing = False\n        self.refreshView = None\n        self.refreshIndicator = None\n        self.createRefreshView()\n\n    @objc_method\n    def createContentView(self):\n        superClipView = ObjCInstance(send_super(__class__, self, 'contentView'))\n        if not isinstance(superClipView, RefreshableClipView):\n            # create new clipview\n            documentView = superClipView.documentView\n            clipView = RefreshableClipView.alloc().initWithFrame(superClipView.frame)\n\n            clipView.documentView = documentView\n            clipView.copiesOnScroll = False\n            clipView.drawsBackground = False\n\n            self.setContentView(clipView)\n            superClipView = ObjCInstance(send_super(__class__, self, 'contentView'))\n\n        return superClipView\n\n    @objc_method\n    def createRefreshView(self) -> None:\n        # delete old stuff if any\n        if self.refreshView:\n            self.refreshView.removeFromSuperview()\n            self.refreshView.release()\n            self.refreshView = None\n\n        self.verticalScrollElasticity = NSScrollElasticityAllowed\n\n        # create new content view\n        self.createContentView()\n\n        self.contentView.postsFrameChangedNotifications = True\n        self.contentView.postsBoundsChangedNotifications = True\n\n        NSNotificationCenter.defaultCenter.addObserver(\n            self,\n            selector=SEL('viewBoundsChanged:'),\n            name=NSViewBoundsDidChangeNotification,\n            object=self.contentView,\n        )\n\n        # Create view to hold the refresh widgets refreshview\n        contentRect = self.contentView.documentView.frame\n        self.refreshView = NSView.alloc().init()\n        self.refreshView.translatesAutoresizingMaskIntoConstraints = False\n\n        # Create spinner\n        self.refreshIndicator = NSProgressIndicator.alloc().init()\n        self.refreshIndicator.style = NSProgressIndicatorSpinningStyle\n        self.refreshIndicator.translatesAutoresizingMaskIntoConstraints = False\n        self.refreshIndicator.displayedWhenStopped = True\n        self.refreshIndicator.usesThreadedAnimation = True\n        self.refreshIndicator.indeterminate = True\n        self.refreshIndicator.bezeled = False\n        self.refreshIndicator.sizeToFit()\n\n        # Center the spinner in the header\n        self.refreshIndicator.setFrame(\n            NSMakeRect(\n                self.refreshView.bounds.size.width / 2 - self.refreshIndicator.frame.size.width / 2,\n                self.refreshView.bounds.size.height / 2 - self.refreshIndicator.frame.size.height / 2,\n                self.refreshIndicator.frame.size.width,\n                self.refreshIndicator.frame.size.height\n            )\n        )\n\n        # Put everything in place\n        self.refreshView.addSubview(self.refreshIndicator)\n        # self.refreshView.addSubview(self.refreshArrow)\n        self.contentView.addSubview(self.refreshView)\n\n        # set layout constraints\n        indicatorHCenter = NSLayoutConstraint.constraintWithItem_attribute_relatedBy_toItem_attribute_multiplier_constant_(  # noqa: E501\n            self.refreshIndicator, NSLayoutAttributeCenterX,\n            NSLayoutRelationEqual,\n            self.refreshView, NSLayoutAttributeCenterX,\n            1.0, 0,\n        )\n        self.refreshView.addConstraint(indicatorHCenter)\n\n        indicatorVCenter = NSLayoutConstraint.constraintWithItem_attribute_relatedBy_toItem_attribute_multiplier_constant_(  # noqa: E501\n            self.refreshIndicator, NSLayoutAttributeCenterY,\n            NSLayoutRelationEqual,\n            self.refreshView, NSLayoutAttributeCenterY,\n            1.0, 0,\n        )\n        self.refreshView.addConstraint(indicatorVCenter)\n\n        refreshWidth = NSLayoutConstraint.constraintWithItem_attribute_relatedBy_toItem_attribute_multiplier_constant_(  # noqa: E501\n            self.refreshView, NSLayoutAttributeWidth,\n            NSLayoutRelationEqual,\n            self.contentView, NSLayoutAttributeWidth,\n            1.0, 0,\n        )\n        self.contentView.addConstraint(refreshWidth)\n\n        refreshHeight = NSLayoutConstraint.constraintWithItem_attribute_relatedBy_toItem_attribute_multiplier_constant_(  # noqa: E501\n            self.refreshView, NSLayoutAttributeHeight,\n            NSLayoutRelationEqual,\n            None, NSLayoutAttributeNotAnAttribute,\n            1.0, HEADER_HEIGHT,\n        )\n        self.contentView.addConstraint(refreshHeight)\n\n        refreshHeight = NSLayoutConstraint.constraintWithItem_attribute_relatedBy_toItem_attribute_multiplier_constant_(  # noqa: E501\n            self.refreshView, NSLayoutAttributeTop,\n            NSLayoutRelationEqual,\n            self.contentView, NSLayoutAttributeTop,\n            1.0, -HEADER_HEIGHT,\n        )\n        self.contentView.addConstraint(refreshHeight)\n\n        # Scroll to top\n        self.contentView.scrollToPoint(NSMakePoint(contentRect.origin.x, 0))\n        self.reflectScrolledClipView(self.contentView)\n\n    # Detecting scroll\n    @objc_method\n    def scrollWheel_(self, event) -> None:\n        if event.phase == NSEventPhaseEnded:\n            if self.refreshTriggered and not self.isRefreshing:\n                self.reload()\n\n        send_super(__class__, self, 'scrollWheel:', event)\n\n    @objc_method\n    def viewBoundsChanged_(self, note) -> None:\n        if self.isRefreshing:\n            return\n\n        if self.contentView.bounds.origin.y <= -self.refreshView.frame.size.height:\n            self.refreshTriggered = True\n\n    # Reload\n    @objc_method\n    def reload(self) -> None:\n        \"\"\"Start a reload, starting the reload spinner\"\"\"\n        self.isRefreshing = True\n        self.refreshIndicator.startAnimation(self)\n        self.interface.on_refresh(self.interface)\n\n    @objc_method\n    def finishedLoading(self):\n        \"\"\"Invoke to mark the end of a reload, stopping and hiding the reload spinner\"\"\"\n        self.isRefreshing = False\n        self.refreshTriggered = False\n        self.refreshIndicator.stopAnimation(self)\n        self.detailedlist.reloadData()\n\n        # Force a scroll event to make the scroll hide the reload\n        cgEvent = core_graphics.CGEventCreateScrollWheelEvent(None, kCGScrollEventUnitLine, 2, 1, 0)\n        scrollEvent = NSEvent.eventWithCGEvent(cgEvent)\n        self.scrollWheel(scrollEvent)\n", "path": "src/cocoa/toga_cocoa/widgets/internal/refresh.py"}]}