We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Create desktop/application menu shortcut writes a bad .desktop file
File contents:

```
[Desktop Entry]
Type=Application
Name=%s
Icon=%s
Exec=lutris lutris:%s
Categories=Game
```

**How to reproduce**
Right click a game and select Create desktop shortcut.
Navigate to ~/Desktop
You see a file with name `gameslug-id.desktop` but it contains what's above. If you're in a file manager you see the game title instead of the filename, so it appears as `%s` there.

**Lutris debug output**

```
[system]:Executing which xdg-user-dir
```

Operating system: Arch Linux


--- 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/shortcuts.py`
Content:
```
1 """Desktop file creator."""
2 import os
3 import stat
4 import shutil
5 import subprocess
6 
7 from textwrap import dedent
8 from xdg import BaseDirectory
9 from gi.repository import GLib
10 
11 from lutris.util import system
12 from lutris.util.log import logger
13 from lutris.settings import CACHE_DIR
14 
15 
16 def get_xdg_basename(game_slug, game_id, legacy=False):
17     if legacy:
18         filename = "{}.desktop".format(game_slug)
19     else:
20         filename = "{}-{}.desktop".format(game_slug, game_id)
21     return filename
22 
23 
24 def create_launcher(game_slug, game_id, game_name, desktop=False, menu=False):
25     """Create a .desktop file."""
26     desktop_dir = (
27         GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DESKTOP)
28     )
29     launcher_content = dedent(
30         """
31         [Desktop Entry]
32         Type=Application
33         Name=%s
34         Icon=%s
35         Exec=lutris lutris:%s
36         Categories=Game
37         """.format(game_name, 'lutris_{}'.format(game_slug), game_id)
38     )
39 
40     launcher_filename = get_xdg_basename(game_slug, game_id, legacy=False)
41     tmp_launcher_path = os.path.join(CACHE_DIR, launcher_filename)
42     tmp_launcher = open(tmp_launcher_path,  "w")
43     tmp_launcher.write(launcher_content)
44     tmp_launcher.close()
45     os.chmod(tmp_launcher_path, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC |
46              stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP)
47 
48     if desktop:
49         shutil.copy(tmp_launcher_path,
50                     os.path.join(desktop_dir, launcher_filename))
51     if menu:
52         menu_path = os.path.join(GLib.get_user_data_dir(), 'applications')
53         shutil.copy(tmp_launcher_path,
54                     os.path.join(menu_path, launcher_filename))
55     os.remove(tmp_launcher_path)
56 
57 
58 def get_launcher_path(game_slug, game_id):
59     """Return the path of a XDG game launcher.
60     When legacy is set, it will return the old path with only the slug,
61     otherwise it will return the path with slug + id
62     """
63     xdg_executable = 'xdg-user-dir'
64     if not system.find_executable(xdg_executable):
65         logger.error("%s not found", xdg_executable)
66         return
67     desktop_dir = subprocess.Popen([xdg_executable, 'DESKTOP'],
68                                    stdout=subprocess.PIPE).communicate()[0]
69     desktop_dir = str(desktop_dir).strip()
70 
71     legacy_launcher_path = os.path.join(
72         desktop_dir, get_xdg_basename(game_slug, game_id, legacy=True)
73     )
74     # First check if legacy path exists, for backward compatibility
75     if system.path_exists(legacy_launcher_path):
76         return legacy_launcher_path
77     # Otherwise return new path, whether it exists or not
78     return os.path.join(
79         desktop_dir, get_xdg_basename(game_slug, game_id, legacy=False)
80     )
81 
82 
83 def get_menu_launcher_path(game_slug, game_id):
84     """Return the path to a XDG menu launcher, prioritizing legacy paths if
85     they exist
86     """
87     menu_dir = os.path.join(BaseDirectory.xdg_data_home, 'applications')
88     menu_path = os.path.join(
89         menu_dir, get_xdg_basename(game_slug, game_id, legacy=True)
90     )
91     if system.path_exists(menu_path):
92         return menu_path
93     return os.path.join(
94         menu_dir, get_xdg_basename(game_slug, game_id, legacy=False)
95     )
96 
97 
98 def desktop_launcher_exists(game_slug, game_id):
99     return system.path_exists(get_launcher_path(game_slug, game_id))
100 
101 
102 def menu_launcher_exists(game_slug, game_id):
103     return system.path_exists(get_menu_launcher_path(game_slug, game_id))
104 
105 
106 def remove_launcher(game_slug, game_id, desktop=False, menu=False):
107     """Remove existing .desktop file."""
108     if desktop:
109         launcher_path = get_launcher_path(game_slug, game_id)
110         if system.path_exists(launcher_path):
111             os.remove(launcher_path)
112 
113     if menu:
114         menu_path = get_menu_launcher_path(game_slug, game_id)
115         if system.path_exists(menu_path):
116             os.remove(menu_path)
117
```
--- 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/shortcuts.py b/lutris/shortcuts.py
--- a/lutris/shortcuts.py
+++ b/lutris/shortcuts.py
@@ -30,9 +30,9 @@
         """
         [Desktop Entry]
         Type=Application
-        Name=%s
-        Icon=%s
-        Exec=lutris lutris:%s
+        Name={}
+        Icon={}
+        Exec=lutris lutris:{}
         Categories=Game
         """.format(game_name, 'lutris_{}'.format(game_slug), game_id)
     )

{"golden_diff": "diff --git a/lutris/shortcuts.py b/lutris/shortcuts.py\n--- a/lutris/shortcuts.py\n+++ b/lutris/shortcuts.py\n@@ -30,9 +30,9 @@\n         \"\"\"\n         [Desktop Entry]\n         Type=Application\n-        Name=%s\n-        Icon=%s\n-        Exec=lutris lutris:%s\n+        Name={}\n+        Icon={}\n+        Exec=lutris lutris:{}\n         Categories=Game\n         \"\"\".format(game_name, 'lutris_{}'.format(game_slug), game_id)\n     )\n", "issue": "Create desktop/application menu shortcut writes a bad .desktop file\nFile contents:\n\n```\n[Desktop Entry]\nType=Application\nName=%s\nIcon=%s\nExec=lutris lutris:%s\nCategories=Game\n```\n\n**How to reproduce**\nRight click a game and select Create desktop shortcut.\nNavigate to ~/Desktop\nYou see a file with name `gameslug-id.desktop` but it contains what's above. If you're in a file manager you see the game title instead of the filename, so it appears as `%s` there.\n\n**Lutris debug output**\n\n```\n[system]:Executing which xdg-user-dir\n```\n\nOperating system: Arch Linux\n\n", "before_files": [{"content": "\"\"\"Desktop file creator.\"\"\"\nimport os\nimport stat\nimport shutil\nimport subprocess\n\nfrom textwrap import dedent\nfrom xdg import BaseDirectory\nfrom gi.repository import GLib\n\nfrom lutris.util import system\nfrom lutris.util.log import logger\nfrom lutris.settings import CACHE_DIR\n\n\ndef get_xdg_basename(game_slug, game_id, legacy=False):\n    if legacy:\n        filename = \"{}.desktop\".format(game_slug)\n    else:\n        filename = \"{}-{}.desktop\".format(game_slug, game_id)\n    return filename\n\n\ndef create_launcher(game_slug, game_id, game_name, desktop=False, menu=False):\n    \"\"\"Create a .desktop file.\"\"\"\n    desktop_dir = (\n        GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DESKTOP)\n    )\n    launcher_content = dedent(\n        \"\"\"\n        [Desktop Entry]\n        Type=Application\n        Name=%s\n        Icon=%s\n        Exec=lutris lutris:%s\n        Categories=Game\n        \"\"\".format(game_name, 'lutris_{}'.format(game_slug), game_id)\n    )\n\n    launcher_filename = get_xdg_basename(game_slug, game_id, legacy=False)\n    tmp_launcher_path = os.path.join(CACHE_DIR, launcher_filename)\n    tmp_launcher = open(tmp_launcher_path,  \"w\")\n    tmp_launcher.write(launcher_content)\n    tmp_launcher.close()\n    os.chmod(tmp_launcher_path, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC |\n             stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP)\n\n    if desktop:\n        shutil.copy(tmp_launcher_path,\n                    os.path.join(desktop_dir, launcher_filename))\n    if menu:\n        menu_path = os.path.join(GLib.get_user_data_dir(), 'applications')\n        shutil.copy(tmp_launcher_path,\n                    os.path.join(menu_path, launcher_filename))\n    os.remove(tmp_launcher_path)\n\n\ndef get_launcher_path(game_slug, game_id):\n    \"\"\"Return the path of a XDG game launcher.\n    When legacy is set, it will return the old path with only the slug,\n    otherwise it will return the path with slug + id\n    \"\"\"\n    xdg_executable = 'xdg-user-dir'\n    if not system.find_executable(xdg_executable):\n        logger.error(\"%s not found\", xdg_executable)\n        return\n    desktop_dir = subprocess.Popen([xdg_executable, 'DESKTOP'],\n                                   stdout=subprocess.PIPE).communicate()[0]\n    desktop_dir = str(desktop_dir).strip()\n\n    legacy_launcher_path = os.path.join(\n        desktop_dir, get_xdg_basename(game_slug, game_id, legacy=True)\n    )\n    # First check if legacy path exists, for backward compatibility\n    if system.path_exists(legacy_launcher_path):\n        return legacy_launcher_path\n    # Otherwise return new path, whether it exists or not\n    return os.path.join(\n        desktop_dir, get_xdg_basename(game_slug, game_id, legacy=False)\n    )\n\n\ndef get_menu_launcher_path(game_slug, game_id):\n    \"\"\"Return the path to a XDG menu launcher, prioritizing legacy paths if\n    they exist\n    \"\"\"\n    menu_dir = os.path.join(BaseDirectory.xdg_data_home, 'applications')\n    menu_path = os.path.join(\n        menu_dir, get_xdg_basename(game_slug, game_id, legacy=True)\n    )\n    if system.path_exists(menu_path):\n        return menu_path\n    return os.path.join(\n        menu_dir, get_xdg_basename(game_slug, game_id, legacy=False)\n    )\n\n\ndef desktop_launcher_exists(game_slug, game_id):\n    return system.path_exists(get_launcher_path(game_slug, game_id))\n\n\ndef menu_launcher_exists(game_slug, game_id):\n    return system.path_exists(get_menu_launcher_path(game_slug, game_id))\n\n\ndef remove_launcher(game_slug, game_id, desktop=False, menu=False):\n    \"\"\"Remove existing .desktop file.\"\"\"\n    if desktop:\n        launcher_path = get_launcher_path(game_slug, game_id)\n        if system.path_exists(launcher_path):\n            os.remove(launcher_path)\n\n    if menu:\n        menu_path = get_menu_launcher_path(game_slug, game_id)\n        if system.path_exists(menu_path):\n            os.remove(menu_path)\n", "path": "lutris/shortcuts.py"}], "after_files": [{"content": "\"\"\"Desktop file creator.\"\"\"\nimport os\nimport stat\nimport shutil\nimport subprocess\n\nfrom textwrap import dedent\nfrom xdg import BaseDirectory\nfrom gi.repository import GLib\n\nfrom lutris.util import system\nfrom lutris.util.log import logger\nfrom lutris.settings import CACHE_DIR\n\n\ndef get_xdg_basename(game_slug, game_id, legacy=False):\n    if legacy:\n        filename = \"{}.desktop\".format(game_slug)\n    else:\n        filename = \"{}-{}.desktop\".format(game_slug, game_id)\n    return filename\n\n\ndef create_launcher(game_slug, game_id, game_name, desktop=False, menu=False):\n    \"\"\"Create a .desktop file.\"\"\"\n    desktop_dir = (\n        GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DESKTOP)\n    )\n    launcher_content = dedent(\n        \"\"\"\n        [Desktop Entry]\n        Type=Application\n        Name={}\n        Icon={}\n        Exec=lutris lutris:{}\n        Categories=Game\n        \"\"\".format(game_name, 'lutris_{}'.format(game_slug), game_id)\n    )\n\n    launcher_filename = get_xdg_basename(game_slug, game_id, legacy=False)\n    tmp_launcher_path = os.path.join(CACHE_DIR, launcher_filename)\n    tmp_launcher = open(tmp_launcher_path,  \"w\")\n    tmp_launcher.write(launcher_content)\n    tmp_launcher.close()\n    os.chmod(tmp_launcher_path, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC |\n             stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP)\n\n    if desktop:\n        shutil.copy(tmp_launcher_path,\n                    os.path.join(desktop_dir, launcher_filename))\n    if menu:\n        menu_path = os.path.join(GLib.get_user_data_dir(), 'applications')\n        shutil.copy(tmp_launcher_path,\n                    os.path.join(menu_path, launcher_filename))\n    os.remove(tmp_launcher_path)\n\n\ndef get_launcher_path(game_slug, game_id):\n    \"\"\"Return the path of a XDG game launcher.\n    When legacy is set, it will return the old path with only the slug,\n    otherwise it will return the path with slug + id\n    \"\"\"\n    xdg_executable = 'xdg-user-dir'\n    if not system.find_executable(xdg_executable):\n        logger.error(\"%s not found\", xdg_executable)\n        return\n    desktop_dir = subprocess.Popen([xdg_executable, 'DESKTOP'],\n                                   stdout=subprocess.PIPE).communicate()[0]\n    desktop_dir = str(desktop_dir).strip()\n\n    legacy_launcher_path = os.path.join(\n        desktop_dir, get_xdg_basename(game_slug, game_id, legacy=True)\n    )\n    # First check if legacy path exists, for backward compatibility\n    if system.path_exists(legacy_launcher_path):\n        return legacy_launcher_path\n    # Otherwise return new path, whether it exists or not\n    return os.path.join(\n        desktop_dir, get_xdg_basename(game_slug, game_id, legacy=False)\n    )\n\n\ndef get_menu_launcher_path(game_slug, game_id):\n    \"\"\"Return the path to a XDG menu launcher, prioritizing legacy paths if\n    they exist\n    \"\"\"\n    menu_dir = os.path.join(BaseDirectory.xdg_data_home, 'applications')\n    menu_path = os.path.join(\n        menu_dir, get_xdg_basename(game_slug, game_id, legacy=True)\n    )\n    if system.path_exists(menu_path):\n        return menu_path\n    return os.path.join(\n        menu_dir, get_xdg_basename(game_slug, game_id, legacy=False)\n    )\n\n\ndef desktop_launcher_exists(game_slug, game_id):\n    return system.path_exists(get_launcher_path(game_slug, game_id))\n\n\ndef menu_launcher_exists(game_slug, game_id):\n    return system.path_exists(get_menu_launcher_path(game_slug, game_id))\n\n\ndef remove_launcher(game_slug, game_id, desktop=False, menu=False):\n    \"\"\"Remove existing .desktop file.\"\"\"\n    if desktop:\n        launcher_path = get_launcher_path(game_slug, game_id)\n        if system.path_exists(launcher_path):\n            os.remove(launcher_path)\n\n    if menu:\n        menu_path = get_menu_launcher_path(game_slug, game_id)\n        if system.path_exists(menu_path):\n            os.remove(menu_path)\n", "path": "lutris/shortcuts.py"}]}