We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Saving game settings causes a traceback
```
Traceback (most recent call last):
  File "/mnt/extrastorage/lutris/lutris/gui/lutriswindow.py", line 666, in on_game_updated
    self.view.set_selected_game(game.id)
  File "/mnt/extrastorage/lutris/lutris/gui/views/list.py", line 123, in set_selected_game
    row = self.get_row_by_id(game_id, filtered=True)
AttributeError: 'GameListView' object has no attribute 'get_row_by_id'
```

`GameListView` does not seem to provide that method. 

After the traceback occurs, Lutris will try to update the default wine prefix (`~/.wine`) rather than the correct one and must be restarted.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `lutris/gui/views/list.py`
Content:
```
1 # pylint: disable=no-member
2 from gi.repository import Gtk, Pango
3 from lutris import settings
4 from lutris.gui.views.base import GameView
5 from lutris.gui.views import (
6     COL_NAME,
7     COL_ICON,
8     COL_YEAR,
9     COL_RUNNER_HUMAN_NAME,
10     COL_PLATFORM,
11     COL_LASTPLAYED,
12     COL_LASTPLAYED_TEXT,
13     COL_INSTALLED_AT,
14     COL_INSTALLED_AT_TEXT,
15     COL_PLAYTIME_TEXT,
16     COLUMN_NAMES
17 )
18 
19 
20 class GameListView(Gtk.TreeView, GameView):
21     """Show the main list of games."""
22 
23     __gsignals__ = GameView.__gsignals__
24 
25     def __init__(self, store):
26         self.game_store = store
27         self.model = self.game_store.modelsort
28         super().__init__(self.model)
29         self.set_rules_hint(True)
30 
31         # Icon column
32         image_cell = Gtk.CellRendererPixbuf()
33         column = Gtk.TreeViewColumn("", image_cell, pixbuf=COL_ICON)
34         column.set_reorderable(True)
35         column.set_sort_indicator(False)
36         self.append_column(column)
37 
38         # Text columns
39         default_text_cell = self.set_text_cell()
40         name_cell = self.set_text_cell()
41         name_cell.set_padding(5, 0)
42 
43         self.set_column(name_cell, "Name", COL_NAME, 200)
44         self.set_column(default_text_cell, "Year", COL_YEAR, 60)
45         self.set_column(default_text_cell, "Runner", COL_RUNNER_HUMAN_NAME, 120)
46         self.set_column(default_text_cell, "Platform", COL_PLATFORM, 120)
47         self.set_column(default_text_cell, "Last Played", COL_LASTPLAYED_TEXT, 120)
48         self.set_sort_with_column(COL_LASTPLAYED_TEXT, COL_LASTPLAYED)
49         self.set_column(default_text_cell, "Installed At", COL_INSTALLED_AT_TEXT, 120)
50         self.set_sort_with_column(COL_INSTALLED_AT_TEXT, COL_INSTALLED_AT)
51         self.set_column(default_text_cell, "Play Time", COL_PLAYTIME_TEXT, 100)
52 
53         self.get_selection().set_mode(Gtk.SelectionMode.SINGLE)
54 
55         self.connect_signals()
56         self.connect("row-activated", self.on_row_activated)
57         self.get_selection().connect("changed", self.on_cursor_changed)
58 
59     @staticmethod
60     def set_text_cell():
61         text_cell = Gtk.CellRendererText()
62         text_cell.set_padding(10, 0)
63         text_cell.set_property("ellipsize", Pango.EllipsizeMode.END)
64         return text_cell
65 
66     def set_column(self, cell, header, column_id, default_width, sort_id=None):
67         column = Gtk.TreeViewColumn(header, cell, markup=column_id)
68         column.set_sort_indicator(True)
69         column.set_sort_column_id(column_id if sort_id is None else sort_id)
70         self.set_column_sort(column_id if sort_id is None else sort_id)
71         column.set_resizable(True)
72         column.set_reorderable(True)
73         width = settings.read_setting(
74             "%s_column_width" % COLUMN_NAMES[column_id], "list view"
75         )
76         column.set_fixed_width(int(width) if width else default_width)
77         self.append_column(column)
78         column.connect("notify::width", self.on_column_width_changed)
79         return column
80 
81     def set_column_sort(self, col):
82         """Sort a column and fallback to sorting by name and runner."""
83 
84         def sort_func(model, row1, row2, user_data):
85             v1 = model.get_value(row1, col)
86             v2 = model.get_value(row2, col)
87             diff = -1 if v1 < v2 else 0 if v1 == v2 else 1
88             if diff is 0:
89                 v1 = model.get_value(row1, COL_NAME)
90                 v2 = model.get_value(row2, COL_NAME)
91                 diff = -1 if v1 < v2 else 0 if v1 == v2 else 1
92             if diff is 0:
93                 v1 = model.get_value(row1, COL_RUNNER_HUMAN_NAME)
94                 v2 = model.get_value(row2, COL_RUNNER_HUMAN_NAME)
95                 diff = -1 if v1 < v2 else 0 if v1 == v2 else 1
96             return diff
97 
98         self.model.set_sort_func(col, sort_func)
99 
100     def set_sort_with_column(self, col, sort_col):
101         """Set to sort a column by using another column"""
102 
103         def sort_func(model, row1, row2, _user_data):
104             value1 = model.get_value(row1, sort_col)
105             value2 = model.get_value(row2, sort_col)
106             return -1 if value1 < value2 else 0 if value1 == value2 else 1
107 
108         self.model.set_sort_func(col, sort_func)
109 
110     def get_selected_item(self):
111         """Return the currently selected game's id."""
112         selection = self.get_selection()
113         if not selection:
114             return None
115         model, select_iter = selection.get_selected()
116         if select_iter:
117             return select_iter
118 
119     def select(self):
120         self.set_cursor(self.current_path[0])
121 
122     def set_selected_game(self, game_id):
123         row = self.get_row_by_id(game_id, filtered=True)
124         if row:
125             self.set_cursor(row.path)
126 
127     def on_row_activated(self, widget, line=None, column=None):
128         """Handles double clicks"""
129         selected_item = self.get_selected_item()
130         if selected_item:
131             selected_game = self.get_selected_game(selected_item)
132         else:
133             selected_game = None
134         self.emit("game-activated", selected_game)
135 
136     def on_cursor_changed(self, widget, line=None, column=None):
137         selected_item = self.get_selected_item()
138         if selected_item:
139             self.selected_game = self.get_selected_game(selected_item)
140         else:
141             self.selected_game = None
142         self.emit("game-selected", self.selected_game)
143 
144     @staticmethod
145     def on_column_width_changed(col, *args):
146         col_name = col.get_title()
147         if col_name:
148             settings.write_setting(
149                 col_name.replace(" ", "") + "_column_width",
150                 col.get_fixed_width(),
151                 "list view",
152             )
153
```
--- 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/lutris/gui/views/list.py b/lutris/gui/views/list.py
--- a/lutris/gui/views/list.py
+++ b/lutris/gui/views/list.py
@@ -120,7 +120,7 @@
         self.set_cursor(self.current_path[0])
 
     def set_selected_game(self, game_id):
-        row = self.get_row_by_id(game_id, filtered=True)
+        row = self.game_store.get_row_by_id(game_id, filtered=True)
         if row:
             self.set_cursor(row.path)

{"golden_diff": "diff --git a/lutris/gui/views/list.py b/lutris/gui/views/list.py\n--- a/lutris/gui/views/list.py\n+++ b/lutris/gui/views/list.py\n@@ -120,7 +120,7 @@\n         self.set_cursor(self.current_path[0])\n \n     def set_selected_game(self, game_id):\n-        row = self.get_row_by_id(game_id, filtered=True)\n+        row = self.game_store.get_row_by_id(game_id, filtered=True)\n         if row:\n             self.set_cursor(row.path)\n", "issue": "Saving game settings causes a traceback\n```\r\nTraceback (most recent call last):\r\n  File \"/mnt/extrastorage/lutris/lutris/gui/lutriswindow.py\", line 666, in on_game_updated\r\n    self.view.set_selected_game(game.id)\r\n  File \"/mnt/extrastorage/lutris/lutris/gui/views/list.py\", line 123, in set_selected_game\r\n    row = self.get_row_by_id(game_id, filtered=True)\r\nAttributeError: 'GameListView' object has no attribute 'get_row_by_id'\r\n```\r\n\r\n`GameListView` does not seem to provide that method. \r\n\r\nAfter the traceback occurs, Lutris will try to update the default wine prefix (`~/.wine`) rather than the correct one and must be restarted.\n", "before_files": [{"content": "# pylint: disable=no-member\nfrom gi.repository import Gtk, Pango\nfrom lutris import settings\nfrom lutris.gui.views.base import GameView\nfrom lutris.gui.views import (\n    COL_NAME,\n    COL_ICON,\n    COL_YEAR,\n    COL_RUNNER_HUMAN_NAME,\n    COL_PLATFORM,\n    COL_LASTPLAYED,\n    COL_LASTPLAYED_TEXT,\n    COL_INSTALLED_AT,\n    COL_INSTALLED_AT_TEXT,\n    COL_PLAYTIME_TEXT,\n    COLUMN_NAMES\n)\n\n\nclass GameListView(Gtk.TreeView, GameView):\n    \"\"\"Show the main list of games.\"\"\"\n\n    __gsignals__ = GameView.__gsignals__\n\n    def __init__(self, store):\n        self.game_store = store\n        self.model = self.game_store.modelsort\n        super().__init__(self.model)\n        self.set_rules_hint(True)\n\n        # Icon column\n        image_cell = Gtk.CellRendererPixbuf()\n        column = Gtk.TreeViewColumn(\"\", image_cell, pixbuf=COL_ICON)\n        column.set_reorderable(True)\n        column.set_sort_indicator(False)\n        self.append_column(column)\n\n        # Text columns\n        default_text_cell = self.set_text_cell()\n        name_cell = self.set_text_cell()\n        name_cell.set_padding(5, 0)\n\n        self.set_column(name_cell, \"Name\", COL_NAME, 200)\n        self.set_column(default_text_cell, \"Year\", COL_YEAR, 60)\n        self.set_column(default_text_cell, \"Runner\", COL_RUNNER_HUMAN_NAME, 120)\n        self.set_column(default_text_cell, \"Platform\", COL_PLATFORM, 120)\n        self.set_column(default_text_cell, \"Last Played\", COL_LASTPLAYED_TEXT, 120)\n        self.set_sort_with_column(COL_LASTPLAYED_TEXT, COL_LASTPLAYED)\n        self.set_column(default_text_cell, \"Installed At\", COL_INSTALLED_AT_TEXT, 120)\n        self.set_sort_with_column(COL_INSTALLED_AT_TEXT, COL_INSTALLED_AT)\n        self.set_column(default_text_cell, \"Play Time\", COL_PLAYTIME_TEXT, 100)\n\n        self.get_selection().set_mode(Gtk.SelectionMode.SINGLE)\n\n        self.connect_signals()\n        self.connect(\"row-activated\", self.on_row_activated)\n        self.get_selection().connect(\"changed\", self.on_cursor_changed)\n\n    @staticmethod\n    def set_text_cell():\n        text_cell = Gtk.CellRendererText()\n        text_cell.set_padding(10, 0)\n        text_cell.set_property(\"ellipsize\", Pango.EllipsizeMode.END)\n        return text_cell\n\n    def set_column(self, cell, header, column_id, default_width, sort_id=None):\n        column = Gtk.TreeViewColumn(header, cell, markup=column_id)\n        column.set_sort_indicator(True)\n        column.set_sort_column_id(column_id if sort_id is None else sort_id)\n        self.set_column_sort(column_id if sort_id is None else sort_id)\n        column.set_resizable(True)\n        column.set_reorderable(True)\n        width = settings.read_setting(\n            \"%s_column_width\" % COLUMN_NAMES[column_id], \"list view\"\n        )\n        column.set_fixed_width(int(width) if width else default_width)\n        self.append_column(column)\n        column.connect(\"notify::width\", self.on_column_width_changed)\n        return column\n\n    def set_column_sort(self, col):\n        \"\"\"Sort a column and fallback to sorting by name and runner.\"\"\"\n\n        def sort_func(model, row1, row2, user_data):\n            v1 = model.get_value(row1, col)\n            v2 = model.get_value(row2, col)\n            diff = -1 if v1 < v2 else 0 if v1 == v2 else 1\n            if diff is 0:\n                v1 = model.get_value(row1, COL_NAME)\n                v2 = model.get_value(row2, COL_NAME)\n                diff = -1 if v1 < v2 else 0 if v1 == v2 else 1\n            if diff is 0:\n                v1 = model.get_value(row1, COL_RUNNER_HUMAN_NAME)\n                v2 = model.get_value(row2, COL_RUNNER_HUMAN_NAME)\n                diff = -1 if v1 < v2 else 0 if v1 == v2 else 1\n            return diff\n\n        self.model.set_sort_func(col, sort_func)\n\n    def set_sort_with_column(self, col, sort_col):\n        \"\"\"Set to sort a column by using another column\"\"\"\n\n        def sort_func(model, row1, row2, _user_data):\n            value1 = model.get_value(row1, sort_col)\n            value2 = model.get_value(row2, sort_col)\n            return -1 if value1 < value2 else 0 if value1 == value2 else 1\n\n        self.model.set_sort_func(col, sort_func)\n\n    def get_selected_item(self):\n        \"\"\"Return the currently selected game's id.\"\"\"\n        selection = self.get_selection()\n        if not selection:\n            return None\n        model, select_iter = selection.get_selected()\n        if select_iter:\n            return select_iter\n\n    def select(self):\n        self.set_cursor(self.current_path[0])\n\n    def set_selected_game(self, game_id):\n        row = self.get_row_by_id(game_id, filtered=True)\n        if row:\n            self.set_cursor(row.path)\n\n    def on_row_activated(self, widget, line=None, column=None):\n        \"\"\"Handles double clicks\"\"\"\n        selected_item = self.get_selected_item()\n        if selected_item:\n            selected_game = self.get_selected_game(selected_item)\n        else:\n            selected_game = None\n        self.emit(\"game-activated\", selected_game)\n\n    def on_cursor_changed(self, widget, line=None, column=None):\n        selected_item = self.get_selected_item()\n        if selected_item:\n            self.selected_game = self.get_selected_game(selected_item)\n        else:\n            self.selected_game = None\n        self.emit(\"game-selected\", self.selected_game)\n\n    @staticmethod\n    def on_column_width_changed(col, *args):\n        col_name = col.get_title()\n        if col_name:\n            settings.write_setting(\n                col_name.replace(\" \", \"\") + \"_column_width\",\n                col.get_fixed_width(),\n                \"list view\",\n            )\n", "path": "lutris/gui/views/list.py"}], "after_files": [{"content": "# pylint: disable=no-member\nfrom gi.repository import Gtk, Pango\nfrom lutris import settings\nfrom lutris.gui.views.base import GameView\nfrom lutris.gui.views import (\n    COL_NAME,\n    COL_ICON,\n    COL_YEAR,\n    COL_RUNNER_HUMAN_NAME,\n    COL_PLATFORM,\n    COL_LASTPLAYED,\n    COL_LASTPLAYED_TEXT,\n    COL_INSTALLED_AT,\n    COL_INSTALLED_AT_TEXT,\n    COL_PLAYTIME_TEXT,\n    COLUMN_NAMES\n)\n\n\nclass GameListView(Gtk.TreeView, GameView):\n    \"\"\"Show the main list of games.\"\"\"\n\n    __gsignals__ = GameView.__gsignals__\n\n    def __init__(self, store):\n        self.game_store = store\n        self.model = self.game_store.modelsort\n        super().__init__(self.model)\n        self.set_rules_hint(True)\n\n        # Icon column\n        image_cell = Gtk.CellRendererPixbuf()\n        column = Gtk.TreeViewColumn(\"\", image_cell, pixbuf=COL_ICON)\n        column.set_reorderable(True)\n        column.set_sort_indicator(False)\n        self.append_column(column)\n\n        # Text columns\n        default_text_cell = self.set_text_cell()\n        name_cell = self.set_text_cell()\n        name_cell.set_padding(5, 0)\n\n        self.set_column(name_cell, \"Name\", COL_NAME, 200)\n        self.set_column(default_text_cell, \"Year\", COL_YEAR, 60)\n        self.set_column(default_text_cell, \"Runner\", COL_RUNNER_HUMAN_NAME, 120)\n        self.set_column(default_text_cell, \"Platform\", COL_PLATFORM, 120)\n        self.set_column(default_text_cell, \"Last Played\", COL_LASTPLAYED_TEXT, 120)\n        self.set_sort_with_column(COL_LASTPLAYED_TEXT, COL_LASTPLAYED)\n        self.set_column(default_text_cell, \"Installed At\", COL_INSTALLED_AT_TEXT, 120)\n        self.set_sort_with_column(COL_INSTALLED_AT_TEXT, COL_INSTALLED_AT)\n        self.set_column(default_text_cell, \"Play Time\", COL_PLAYTIME_TEXT, 100)\n\n        self.get_selection().set_mode(Gtk.SelectionMode.SINGLE)\n\n        self.connect_signals()\n        self.connect(\"row-activated\", self.on_row_activated)\n        self.get_selection().connect(\"changed\", self.on_cursor_changed)\n\n    @staticmethod\n    def set_text_cell():\n        text_cell = Gtk.CellRendererText()\n        text_cell.set_padding(10, 0)\n        text_cell.set_property(\"ellipsize\", Pango.EllipsizeMode.END)\n        return text_cell\n\n    def set_column(self, cell, header, column_id, default_width, sort_id=None):\n        column = Gtk.TreeViewColumn(header, cell, markup=column_id)\n        column.set_sort_indicator(True)\n        column.set_sort_column_id(column_id if sort_id is None else sort_id)\n        self.set_column_sort(column_id if sort_id is None else sort_id)\n        column.set_resizable(True)\n        column.set_reorderable(True)\n        width = settings.read_setting(\n            \"%s_column_width\" % COLUMN_NAMES[column_id], \"list view\"\n        )\n        column.set_fixed_width(int(width) if width else default_width)\n        self.append_column(column)\n        column.connect(\"notify::width\", self.on_column_width_changed)\n        return column\n\n    def set_column_sort(self, col):\n        \"\"\"Sort a column and fallback to sorting by name and runner.\"\"\"\n\n        def sort_func(model, row1, row2, user_data):\n            v1 = model.get_value(row1, col)\n            v2 = model.get_value(row2, col)\n            diff = -1 if v1 < v2 else 0 if v1 == v2 else 1\n            if diff is 0:\n                v1 = model.get_value(row1, COL_NAME)\n                v2 = model.get_value(row2, COL_NAME)\n                diff = -1 if v1 < v2 else 0 if v1 == v2 else 1\n            if diff is 0:\n                v1 = model.get_value(row1, COL_RUNNER_HUMAN_NAME)\n                v2 = model.get_value(row2, COL_RUNNER_HUMAN_NAME)\n                diff = -1 if v1 < v2 else 0 if v1 == v2 else 1\n            return diff\n\n        self.model.set_sort_func(col, sort_func)\n\n    def set_sort_with_column(self, col, sort_col):\n        \"\"\"Set to sort a column by using another column\"\"\"\n\n        def sort_func(model, row1, row2, _user_data):\n            value1 = model.get_value(row1, sort_col)\n            value2 = model.get_value(row2, sort_col)\n            return -1 if value1 < value2 else 0 if value1 == value2 else 1\n\n        self.model.set_sort_func(col, sort_func)\n\n    def get_selected_item(self):\n        \"\"\"Return the currently selected game's id.\"\"\"\n        selection = self.get_selection()\n        if not selection:\n            return None\n        model, select_iter = selection.get_selected()\n        if select_iter:\n            return select_iter\n\n    def select(self):\n        self.set_cursor(self.current_path[0])\n\n    def set_selected_game(self, game_id):\n        row = self.game_store.get_row_by_id(game_id, filtered=True)\n        if row:\n            self.set_cursor(row.path)\n\n    def on_row_activated(self, widget, line=None, column=None):\n        \"\"\"Handles double clicks\"\"\"\n        selected_item = self.get_selected_item()\n        if selected_item:\n            selected_game = self.get_selected_game(selected_item)\n        else:\n            selected_game = None\n        self.emit(\"game-activated\", selected_game)\n\n    def on_cursor_changed(self, widget, line=None, column=None):\n        selected_item = self.get_selected_item()\n        if selected_item:\n            self.selected_game = self.get_selected_game(selected_item)\n        else:\n            self.selected_game = None\n        self.emit(\"game-selected\", self.selected_game)\n\n    @staticmethod\n    def on_column_width_changed(col, *args):\n        col_name = col.get_title()\n        if col_name:\n            settings.write_setting(\n                col_name.replace(\" \", \"\") + \"_column_width\",\n                col.get_fixed_width(),\n                \"list view\",\n            )\n", "path": "lutris/gui/views/list.py"}]}