We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Add Canvas Dashed Line Support for Gtk+
Hey PyCon AU 2018 sprinters, and other new contributors - here is a great way to contribute for someone who runs Linux:

Recently @bryall implemented dashed line support for Canvas in the Cocoa backend in #578. It would be great to implement support for dashed lines in Gtk+ as well.

--- 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/gtk/toga_gtk/widgets/canvas.py`
Content:
```
1 import gi
2 
3 gi.require_version("Gtk", "3.0")
4 from gi.repository import Gtk
5 
6 try:
7     import cairo
8 except ImportError:
9     cairo = None
10 try:
11     gi.require_version("Pango", "1.0")
12     from gi.repository import Pango
13 
14     SCALE = Pango.SCALE
15 except ImportError:
16     SCALE = 1024
17 
18 from .base import Widget
19 from ..color import native_color
20 
21 
22 class Canvas(Widget):
23     def create(self):
24         if cairo is None:
25             raise RuntimeError(
26                 "'import cairo' failed; may need to install python-gi-cairo."
27             )
28 
29         self.native = Gtk.DrawingArea()
30         self.native.interface = self.interface
31         self.native.connect("draw", self.gtk_draw_callback)
32 
33     def gtk_draw_callback(self, canvas, gtk_context):
34         """Creates a draw callback
35 
36         Gtk+ uses a drawing callback to draw on a DrawingArea. Assignment of the
37         callback function creates a Gtk+ canvas and Gtk+ context automatically
38         using the canvas and gtk_context function arguments. This method calls
39         the draw method on the interface Canvas to draw the objects.
40 
41         """
42         self.interface._draw(self, draw_context=gtk_context)
43 
44     def redraw(self):
45         pass
46 
47     # Basic paths
48 
49     def new_path(self, draw_context, *args, **kwargs):
50         draw_context.new_path()
51 
52     def closed_path(self, x, y, draw_context, *args, **kwargs):
53         draw_context.close_path()
54 
55     def move_to(self, x, y, draw_context, *args, **kwargs):
56         draw_context.move_to(x, y)
57 
58     def line_to(self, x, y, draw_context, *args, **kwargs):
59         draw_context.line_to(x, y)
60 
61     # Basic shapes
62 
63     def bezier_curve_to(
64         self, cp1x, cp1y, cp2x, cp2y, x, y, draw_context, *args, **kwargs
65     ):
66         draw_context.curve_to(cp1x, cp1y, cp2x, cp2y, x, y)
67 
68     def quadratic_curve_to(self, cpx, cpy, x, y, draw_context, *args, **kwargs):
69         draw_context.curve_to(cpx, cpy, cpx, cpy, x, y)
70 
71     def arc(
72         self,
73         x,
74         y,
75         radius,
76         startangle,
77         endangle,
78         anticlockwise,
79         draw_context,
80         *args,
81         **kwargs
82     ):
83         if anticlockwise:
84             draw_context.arc_negative(x, y, radius, startangle, endangle)
85         else:
86             draw_context.arc(x, y, radius, startangle, endangle)
87 
88     def ellipse(
89         self,
90         x,
91         y,
92         radiusx,
93         radiusy,
94         rotation,
95         startangle,
96         endangle,
97         anticlockwise,
98         draw_context,
99         *args,
100         **kwargs
101     ):
102         draw_context.save()
103         draw_context.translate(x, y)
104         if radiusx >= radiusy:
105             draw_context.scale(1, radiusy / radiusx)
106             self.arc(0, 0, radiusx, startangle, endangle, anticlockwise, draw_context)
107         else:
108             draw_context.scale(radiusx / radiusy, 1)
109             self.arc(0, 0, radiusy, startangle, endangle, anticlockwise, draw_context)
110         draw_context.rotate(rotation)
111         draw_context.identity_matrix()
112         draw_context.restore()
113 
114     def rect(self, x, y, width, height, draw_context, *args, **kwargs):
115         draw_context.rectangle(x, y, width, height)
116 
117     # Drawing Paths
118 
119     def apply_color(self, color, draw_context, *args, **kwargs):
120         if color is not None:
121             draw_context.set_source_rgba(*native_color(color))
122         else:
123             # set color to black
124             draw_context.set_source_rgba(0, 0, 0, 1.0)
125 
126     def fill(self, color, fill_rule, preserve, draw_context, *args, **kwargs):
127         self.apply_color(color, draw_context)
128         if fill_rule is "evenodd":
129             draw_context.set_fill_rule(cairo.FILL_RULE_EVEN_ODD)
130         else:
131             draw_context.set_fill_rule(cairo.FILL_RULE_WINDING)
132         if preserve:
133             draw_context.fill_preserve()
134         else:
135             draw_context.fill()
136 
137     def stroke(self, color, line_width, draw_context, *args, **kwargs):
138         self.apply_color(color, draw_context)
139         draw_context.set_line_width(line_width)
140         draw_context.stroke()
141 
142     # Transformations
143 
144     def rotate(self, radians, draw_context, *args, **kwargs):
145         draw_context.rotate(radians)
146 
147     def scale(self, sx, sy, draw_context, *args, **kwargs):
148         draw_context.scale(sx, sy)
149 
150     def translate(self, tx, ty, draw_context, *args, **kwargs):
151         draw_context.translate(tx, ty)
152 
153     def reset_transform(self, draw_context, *args, **kwargs):
154         draw_context.identity_matrix()
155 
156     # Text
157 
158     def write_text(self, text, x, y, font, draw_context, *args, **kwargs):
159         # Set font family and size
160         if font:
161             write_font = font
162         elif self.native.font:
163             write_font = self.native.font
164             write_font.family = self.native.font.get_family()
165             write_font.size = self.native.font.get_size() / SCALE
166         draw_context.select_font_face(write_font.family)
167         draw_context.set_font_size(write_font.size)
168 
169         # Support writing multiline text
170         for line in text.splitlines():
171             width, height = write_font.measure(line)
172             draw_context.move_to(x, y)
173             draw_context.text_path(line)
174             y += height
175 
176     def measure_text(self, text, font, draw_context, *args, **kwargs):
177         # Set font family and size
178         if font:
179             draw_context.select_font_face(font.family)
180             draw_context.set_font_size(font.size)
181         elif self.native.font:
182             draw_context.select_font_face(self.native.font.get_family())
183             draw_context.set_font_size(self.native.font.get_size() / SCALE)
184 
185         x_bearing, y_bearing, width, height, x_advance, y_advance = draw_context.text_extents(
186             text
187         )
188         return width, height
189 
190     # Rehint
191 
192     def rehint(self):
193         # print("REHINT", self, self.native.get_preferred_width(), self.native.get_preferred_height())
194         width = self.native.get_preferred_width()
195         height = self.native.get_preferred_height()
196
```
--- 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/gtk/toga_gtk/widgets/canvas.py b/src/gtk/toga_gtk/widgets/canvas.py
--- a/src/gtk/toga_gtk/widgets/canvas.py
+++ b/src/gtk/toga_gtk/widgets/canvas.py
@@ -134,10 +134,13 @@
         else:
             draw_context.fill()
 
-    def stroke(self, color, line_width, draw_context, *args, **kwargs):
+    def stroke(self, color, line_width, line_dash, draw_context, *args, **kwargs):
         self.apply_color(color, draw_context)
         draw_context.set_line_width(line_width)
+        if line_dash is not None:
+            draw_context.set_dash(line_dash)
         draw_context.stroke()
+        draw_context.set_dash([])
 
     # Transformations

{"golden_diff": "diff --git a/src/gtk/toga_gtk/widgets/canvas.py b/src/gtk/toga_gtk/widgets/canvas.py\n--- a/src/gtk/toga_gtk/widgets/canvas.py\n+++ b/src/gtk/toga_gtk/widgets/canvas.py\n@@ -134,10 +134,13 @@\n         else:\n             draw_context.fill()\n \n-    def stroke(self, color, line_width, draw_context, *args, **kwargs):\n+    def stroke(self, color, line_width, line_dash, draw_context, *args, **kwargs):\n         self.apply_color(color, draw_context)\n         draw_context.set_line_width(line_width)\n+        if line_dash is not None:\n+            draw_context.set_dash(line_dash)\n         draw_context.stroke()\n+        draw_context.set_dash([])\n \n     # Transformations\n", "issue": "Add Canvas Dashed Line Support for Gtk+\nHey PyCon AU 2018 sprinters, and other new contributors - here is a great way to contribute for someone who runs Linux:\r\n\r\nRecently @bryall implemented dashed line support for Canvas in the Cocoa backend in #578. It would be great to implement support for dashed lines in Gtk+ as well.\n", "before_files": [{"content": "import gi\n\ngi.require_version(\"Gtk\", \"3.0\")\nfrom gi.repository import Gtk\n\ntry:\n    import cairo\nexcept ImportError:\n    cairo = None\ntry:\n    gi.require_version(\"Pango\", \"1.0\")\n    from gi.repository import Pango\n\n    SCALE = Pango.SCALE\nexcept ImportError:\n    SCALE = 1024\n\nfrom .base import Widget\nfrom ..color import native_color\n\n\nclass Canvas(Widget):\n    def create(self):\n        if cairo is None:\n            raise RuntimeError(\n                \"'import cairo' failed; may need to install python-gi-cairo.\"\n            )\n\n        self.native = Gtk.DrawingArea()\n        self.native.interface = self.interface\n        self.native.connect(\"draw\", self.gtk_draw_callback)\n\n    def gtk_draw_callback(self, canvas, gtk_context):\n        \"\"\"Creates a draw callback\n\n        Gtk+ uses a drawing callback to draw on a DrawingArea. Assignment of the\n        callback function creates a Gtk+ canvas and Gtk+ context automatically\n        using the canvas and gtk_context function arguments. This method calls\n        the draw method on the interface Canvas to draw the objects.\n\n        \"\"\"\n        self.interface._draw(self, draw_context=gtk_context)\n\n    def redraw(self):\n        pass\n\n    # Basic paths\n\n    def new_path(self, draw_context, *args, **kwargs):\n        draw_context.new_path()\n\n    def closed_path(self, x, y, draw_context, *args, **kwargs):\n        draw_context.close_path()\n\n    def move_to(self, x, y, draw_context, *args, **kwargs):\n        draw_context.move_to(x, y)\n\n    def line_to(self, x, y, draw_context, *args, **kwargs):\n        draw_context.line_to(x, y)\n\n    # Basic shapes\n\n    def bezier_curve_to(\n        self, cp1x, cp1y, cp2x, cp2y, x, y, draw_context, *args, **kwargs\n    ):\n        draw_context.curve_to(cp1x, cp1y, cp2x, cp2y, x, y)\n\n    def quadratic_curve_to(self, cpx, cpy, x, y, draw_context, *args, **kwargs):\n        draw_context.curve_to(cpx, cpy, cpx, cpy, x, y)\n\n    def arc(\n        self,\n        x,\n        y,\n        radius,\n        startangle,\n        endangle,\n        anticlockwise,\n        draw_context,\n        *args,\n        **kwargs\n    ):\n        if anticlockwise:\n            draw_context.arc_negative(x, y, radius, startangle, endangle)\n        else:\n            draw_context.arc(x, y, radius, startangle, endangle)\n\n    def ellipse(\n        self,\n        x,\n        y,\n        radiusx,\n        radiusy,\n        rotation,\n        startangle,\n        endangle,\n        anticlockwise,\n        draw_context,\n        *args,\n        **kwargs\n    ):\n        draw_context.save()\n        draw_context.translate(x, y)\n        if radiusx >= radiusy:\n            draw_context.scale(1, radiusy / radiusx)\n            self.arc(0, 0, radiusx, startangle, endangle, anticlockwise, draw_context)\n        else:\n            draw_context.scale(radiusx / radiusy, 1)\n            self.arc(0, 0, radiusy, startangle, endangle, anticlockwise, draw_context)\n        draw_context.rotate(rotation)\n        draw_context.identity_matrix()\n        draw_context.restore()\n\n    def rect(self, x, y, width, height, draw_context, *args, **kwargs):\n        draw_context.rectangle(x, y, width, height)\n\n    # Drawing Paths\n\n    def apply_color(self, color, draw_context, *args, **kwargs):\n        if color is not None:\n            draw_context.set_source_rgba(*native_color(color))\n        else:\n            # set color to black\n            draw_context.set_source_rgba(0, 0, 0, 1.0)\n\n    def fill(self, color, fill_rule, preserve, draw_context, *args, **kwargs):\n        self.apply_color(color, draw_context)\n        if fill_rule is \"evenodd\":\n            draw_context.set_fill_rule(cairo.FILL_RULE_EVEN_ODD)\n        else:\n            draw_context.set_fill_rule(cairo.FILL_RULE_WINDING)\n        if preserve:\n            draw_context.fill_preserve()\n        else:\n            draw_context.fill()\n\n    def stroke(self, color, line_width, draw_context, *args, **kwargs):\n        self.apply_color(color, draw_context)\n        draw_context.set_line_width(line_width)\n        draw_context.stroke()\n\n    # Transformations\n\n    def rotate(self, radians, draw_context, *args, **kwargs):\n        draw_context.rotate(radians)\n\n    def scale(self, sx, sy, draw_context, *args, **kwargs):\n        draw_context.scale(sx, sy)\n\n    def translate(self, tx, ty, draw_context, *args, **kwargs):\n        draw_context.translate(tx, ty)\n\n    def reset_transform(self, draw_context, *args, **kwargs):\n        draw_context.identity_matrix()\n\n    # Text\n\n    def write_text(self, text, x, y, font, draw_context, *args, **kwargs):\n        # Set font family and size\n        if font:\n            write_font = font\n        elif self.native.font:\n            write_font = self.native.font\n            write_font.family = self.native.font.get_family()\n            write_font.size = self.native.font.get_size() / SCALE\n        draw_context.select_font_face(write_font.family)\n        draw_context.set_font_size(write_font.size)\n\n        # Support writing multiline text\n        for line in text.splitlines():\n            width, height = write_font.measure(line)\n            draw_context.move_to(x, y)\n            draw_context.text_path(line)\n            y += height\n\n    def measure_text(self, text, font, draw_context, *args, **kwargs):\n        # Set font family and size\n        if font:\n            draw_context.select_font_face(font.family)\n            draw_context.set_font_size(font.size)\n        elif self.native.font:\n            draw_context.select_font_face(self.native.font.get_family())\n            draw_context.set_font_size(self.native.font.get_size() / SCALE)\n\n        x_bearing, y_bearing, width, height, x_advance, y_advance = draw_context.text_extents(\n            text\n        )\n        return width, height\n\n    # Rehint\n\n    def rehint(self):\n        # print(\"REHINT\", self, self.native.get_preferred_width(), self.native.get_preferred_height())\n        width = self.native.get_preferred_width()\n        height = self.native.get_preferred_height()\n", "path": "src/gtk/toga_gtk/widgets/canvas.py"}], "after_files": [{"content": "import gi\n\ngi.require_version(\"Gtk\", \"3.0\")\nfrom gi.repository import Gtk\n\ntry:\n    import cairo\nexcept ImportError:\n    cairo = None\ntry:\n    gi.require_version(\"Pango\", \"1.0\")\n    from gi.repository import Pango\n\n    SCALE = Pango.SCALE\nexcept ImportError:\n    SCALE = 1024\n\nfrom .base import Widget\nfrom ..color import native_color\n\n\nclass Canvas(Widget):\n    def create(self):\n        if cairo is None:\n            raise RuntimeError(\n                \"'import cairo' failed; may need to install python-gi-cairo.\"\n            )\n\n        self.native = Gtk.DrawingArea()\n        self.native.interface = self.interface\n        self.native.connect(\"draw\", self.gtk_draw_callback)\n\n    def gtk_draw_callback(self, canvas, gtk_context):\n        \"\"\"Creates a draw callback\n\n        Gtk+ uses a drawing callback to draw on a DrawingArea. Assignment of the\n        callback function creates a Gtk+ canvas and Gtk+ context automatically\n        using the canvas and gtk_context function arguments. This method calls\n        the draw method on the interface Canvas to draw the objects.\n\n        \"\"\"\n        self.interface._draw(self, draw_context=gtk_context)\n\n    def redraw(self):\n        pass\n\n    # Basic paths\n\n    def new_path(self, draw_context, *args, **kwargs):\n        draw_context.new_path()\n\n    def closed_path(self, x, y, draw_context, *args, **kwargs):\n        draw_context.close_path()\n\n    def move_to(self, x, y, draw_context, *args, **kwargs):\n        draw_context.move_to(x, y)\n\n    def line_to(self, x, y, draw_context, *args, **kwargs):\n        draw_context.line_to(x, y)\n\n    # Basic shapes\n\n    def bezier_curve_to(\n        self, cp1x, cp1y, cp2x, cp2y, x, y, draw_context, *args, **kwargs\n    ):\n        draw_context.curve_to(cp1x, cp1y, cp2x, cp2y, x, y)\n\n    def quadratic_curve_to(self, cpx, cpy, x, y, draw_context, *args, **kwargs):\n        draw_context.curve_to(cpx, cpy, cpx, cpy, x, y)\n\n    def arc(\n        self,\n        x,\n        y,\n        radius,\n        startangle,\n        endangle,\n        anticlockwise,\n        draw_context,\n        *args,\n        **kwargs\n    ):\n        if anticlockwise:\n            draw_context.arc_negative(x, y, radius, startangle, endangle)\n        else:\n            draw_context.arc(x, y, radius, startangle, endangle)\n\n    def ellipse(\n        self,\n        x,\n        y,\n        radiusx,\n        radiusy,\n        rotation,\n        startangle,\n        endangle,\n        anticlockwise,\n        draw_context,\n        *args,\n        **kwargs\n    ):\n        draw_context.save()\n        draw_context.translate(x, y)\n        if radiusx >= radiusy:\n            draw_context.scale(1, radiusy / radiusx)\n            self.arc(0, 0, radiusx, startangle, endangle, anticlockwise, draw_context)\n        else:\n            draw_context.scale(radiusx / radiusy, 1)\n            self.arc(0, 0, radiusy, startangle, endangle, anticlockwise, draw_context)\n        draw_context.rotate(rotation)\n        draw_context.identity_matrix()\n        draw_context.restore()\n\n    def rect(self, x, y, width, height, draw_context, *args, **kwargs):\n        draw_context.rectangle(x, y, width, height)\n\n    # Drawing Paths\n\n    def apply_color(self, color, draw_context, *args, **kwargs):\n        if color is not None:\n            draw_context.set_source_rgba(*native_color(color))\n        else:\n            # set color to black\n            draw_context.set_source_rgba(0, 0, 0, 1.0)\n\n    def fill(self, color, fill_rule, preserve, draw_context, *args, **kwargs):\n        self.apply_color(color, draw_context)\n        if fill_rule is \"evenodd\":\n            draw_context.set_fill_rule(cairo.FILL_RULE_EVEN_ODD)\n        else:\n            draw_context.set_fill_rule(cairo.FILL_RULE_WINDING)\n        if preserve:\n            draw_context.fill_preserve()\n        else:\n            draw_context.fill()\n\n    def stroke(self, color, line_width, line_dash, draw_context, *args, **kwargs):\n        self.apply_color(color, draw_context)\n        draw_context.set_line_width(line_width)\n        if line_dash is not None:\n            draw_context.set_dash(line_dash)\n        draw_context.stroke()\n        draw_context.set_dash([])\n\n    # Transformations\n\n    def rotate(self, radians, draw_context, *args, **kwargs):\n        draw_context.rotate(radians)\n\n    def scale(self, sx, sy, draw_context, *args, **kwargs):\n        draw_context.scale(sx, sy)\n\n    def translate(self, tx, ty, draw_context, *args, **kwargs):\n        draw_context.translate(tx, ty)\n\n    def reset_transform(self, draw_context, *args, **kwargs):\n        draw_context.identity_matrix()\n\n    # Text\n\n    def write_text(self, text, x, y, font, draw_context, *args, **kwargs):\n        # Set font family and size\n        if font:\n            write_font = font\n        elif self.native.font:\n            write_font = self.native.font\n            write_font.family = self.native.font.get_family()\n            write_font.size = self.native.font.get_size() / SCALE\n        draw_context.select_font_face(write_font.family)\n        draw_context.set_font_size(write_font.size)\n\n        # Support writing multiline text\n        for line in text.splitlines():\n            width, height = write_font.measure(line)\n            draw_context.move_to(x, y)\n            draw_context.text_path(line)\n            y += height\n\n    def measure_text(self, text, font, draw_context, *args, **kwargs):\n        # Set font family and size\n        if font:\n            draw_context.select_font_face(font.family)\n            draw_context.set_font_size(font.size)\n        elif self.native.font:\n            draw_context.select_font_face(self.native.font.get_family())\n            draw_context.set_font_size(self.native.font.get_size() / SCALE)\n\n        x_bearing, y_bearing, width, height, x_advance, y_advance = draw_context.text_extents(\n            text\n        )\n        return width, height\n\n    # Rehint\n\n    def rehint(self):\n        # print(\"REHINT\", self, self.native.get_preferred_width(), self.native.get_preferred_height())\n        width = self.native.get_preferred_width()\n        height = self.native.get_preferred_height()\n", "path": "src/gtk/toga_gtk/widgets/canvas.py"}]}