diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp
index 822ba1a349..fd0a130a3a 100644
--- a/src/yuzu/bootmanager.cpp
+++ b/src/yuzu/bootmanager.cpp
@@ -303,6 +303,7 @@ GRenderWindow::GRenderWindow(GMainWindow* parent, EmuThread* emu_thread_,
     connect(this, &GRenderWindow::ExecuteProgramSignal, parent, &GMainWindow::OnExecuteProgram,
             Qt::QueuedConnection);
     connect(this, &GRenderWindow::ExitSignal, parent, &GMainWindow::OnExit, Qt::QueuedConnection);
+    connect(this, &GRenderWindow::TasPlaybackStateChanged, parent, &GMainWindow::OnTasStateChanged);
 }
 
 void GRenderWindow::ExecuteProgram(std::size_t program_index) {
@@ -319,10 +320,18 @@ GRenderWindow::~GRenderWindow() {
 
 void GRenderWindow::OnFrameDisplayed() {
     input_subsystem->GetTas()->UpdateThread();
+    const TasInput::TasState new_tas_state = std::get<0>(input_subsystem->GetTas()->GetStatus());
+
     if (!first_frame) {
+        last_tas_state = new_tas_state;
         first_frame = true;
         emit FirstFrameDisplayed();
     }
+
+    if (new_tas_state != last_tas_state) {
+        last_tas_state = new_tas_state;
+        emit TasPlaybackStateChanged();
+    }
 }
 
 bool GRenderWindow::IsShown() const {
diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h
index 40fd4a9d64..061e3605f3 100644
--- a/src/yuzu/bootmanager.h
+++ b/src/yuzu/bootmanager.h
@@ -41,6 +41,10 @@ enum class LoadCallbackStage;
 class RendererBase;
 } // namespace VideoCore
 
+namespace TasInput {
+enum class TasState;
+}
+
 class EmuThread final : public QThread {
     Q_OBJECT
 
@@ -203,6 +207,7 @@ signals:
     void ExecuteProgramSignal(std::size_t program_index);
     void ExitSignal();
     void MouseActivity();
+    void TasPlaybackStateChanged();
 
 private:
     void TouchBeginEvent(const QTouchEvent* event);
@@ -236,6 +241,7 @@ private:
     QWidget* child_widget = nullptr;
 
     bool first_frame = false;
+    TasInput::TasState last_tas_state;
 
     std::array<std::size_t, 16> touch_ids{};
 
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index c4c76b094f..5058c3e4ee 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -965,6 +965,9 @@ void GMainWindow::InitializeHotkeys() {
     const QString toggle_status_bar = QStringLiteral("Toggle Status Bar");
     const QString fullscreen = QStringLiteral("Fullscreen");
     const QString capture_screenshot = QStringLiteral("Capture Screenshot");
+    const QString tas_start_stop = QStringLiteral("TAS Start/Stop");
+    const QString tas_record = QStringLiteral("TAS Record");
+    const QString tas_reset = QStringLiteral("TAS Reset");
 
     ui->action_Load_File->setShortcut(hotkey_registry.GetKeySequence(main_window, load_file));
     ui->action_Load_File->setShortcutContext(
@@ -1005,6 +1008,18 @@ void GMainWindow::InitializeHotkeys() {
     ui->action_Fullscreen->setShortcutContext(
         hotkey_registry.GetShortcutContext(main_window, fullscreen));
 
+    ui->action_TAS_Start->setShortcut(hotkey_registry.GetKeySequence(main_window, tas_start_stop));
+    ui->action_TAS_Start->setShortcutContext(
+        hotkey_registry.GetShortcutContext(main_window, tas_start_stop));
+
+    ui->action_TAS_Record->setShortcut(hotkey_registry.GetKeySequence(main_window, tas_record));
+    ui->action_TAS_Record->setShortcutContext(
+        hotkey_registry.GetShortcutContext(main_window, tas_record));
+
+    ui->action_TAS_Reset->setShortcut(hotkey_registry.GetKeySequence(main_window, tas_reset));
+    ui->action_TAS_Reset->setShortcutContext(
+        hotkey_registry.GetShortcutContext(main_window, tas_reset));
+
     connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Load File"), this),
             &QShortcut::activated, this, &GMainWindow::OnMenuLoadFile);
     connect(
@@ -1095,28 +1110,6 @@ void GMainWindow::InitializeHotkeys() {
                     render_window->setAttribute(Qt::WA_Hover, true);
                 }
             });
-    connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("TAS Start/Stop"), this),
-            &QShortcut::activated, this, [&] {
-                if (!emulation_running) {
-                    return;
-                }
-                input_subsystem->GetTas()->StartStop();
-            });
-    connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("TAS Reset"), this),
-            &QShortcut::activated, this, [&] { input_subsystem->GetTas()->Reset(); });
-    connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("TAS Record"), this),
-            &QShortcut::activated, this, [&] {
-                if (!emulation_running) {
-                    return;
-                }
-                bool is_recording = input_subsystem->GetTas()->Record();
-                if (!is_recording) {
-                    const auto res = QMessageBox::question(this, tr("TAS Recording"),
-                                                           tr("Overwrite file of player 1?"),
-                                                           QMessageBox::Yes | QMessageBox::No);
-                    input_subsystem->GetTas()->SaveRecording(res == QMessageBox::Yes);
-                }
-            });
 }
 
 void GMainWindow::SetDefaultUIGeometry() {
@@ -1236,11 +1229,11 @@ void GMainWindow::ConnectMenuEvents() {
     connect(ui->action_Restart, &QAction::triggered, this,
             [this] { BootGame(QString(game_path)); });
     connect(ui->action_Configure, &QAction::triggered, this, &GMainWindow::OnConfigure);
-    connect(ui->action_Configure_Tas, &QAction::triggered, this, &GMainWindow::OnConfigureTas);
     connect(ui->action_Configure_Current_Game, &QAction::triggered, this,
             &GMainWindow::OnConfigurePerGame);
 
     // View
+    connect(ui->action_Fullscreen, &QAction::triggered, this, &GMainWindow::ToggleFullscreen);
     connect(ui->action_Single_Window_Mode, &QAction::triggered, this,
             &GMainWindow::ToggleWindowMode);
     connect(ui->action_Display_Dock_Widget_Headers, &QAction::triggered, this,
@@ -1258,17 +1251,20 @@ void GMainWindow::ConnectMenuEvents() {
     ui->menu_Reset_Window_Size->addAction(ui->action_Reset_Window_Size_900);
     ui->menu_Reset_Window_Size->addAction(ui->action_Reset_Window_Size_1080);
 
-    // Fullscreen
-    connect(ui->action_Fullscreen, &QAction::triggered, this, &GMainWindow::ToggleFullscreen);
-
-    // Movie
+    // Tools
+    connect(ui->action_Rederive, &QAction::triggered, this,
+            std::bind(&GMainWindow::OnReinitializeKeys, this, ReinitializeKeyBehavior::Warning));
     connect(ui->action_Capture_Screenshot, &QAction::triggered, this,
             &GMainWindow::OnCaptureScreenshot);
 
+    // TAS
+    connect(ui->action_TAS_Start, &QAction::triggered, this, &GMainWindow::OnTasStartStop);
+    connect(ui->action_TAS_Record, &QAction::triggered, this, &GMainWindow::OnTasRecord);
+    connect(ui->action_TAS_Reset, &QAction::triggered, this, &GMainWindow::OnTasReset);
+    connect(ui->action_Configure_Tas, &QAction::triggered, this, &GMainWindow::OnConfigureTas);
+
     // Help
     connect(ui->action_Open_yuzu_Folder, &QAction::triggered, this, &GMainWindow::OnOpenYuzuFolder);
-    connect(ui->action_Rederive, &QAction::triggered, this,
-            std::bind(&GMainWindow::OnReinitializeKeys, this, ReinitializeKeyBehavior::Warning));
     connect(ui->action_About, &QAction::triggered, this, &GMainWindow::OnAbout);
 }
 
@@ -1582,6 +1578,7 @@ void GMainWindow::ShutdownGame() {
     game_list->SetFilterFocus();
     tas_label->clear();
     input_subsystem->GetTas()->Stop();
+    OnTasStateChanged();
 
     render_window->removeEventFilter(render_window);
     render_window->setAttribute(Qt::WA_Hover, false);
@@ -2509,6 +2506,7 @@ void GMainWindow::OnStartGame() {
     ui->action_Restart->setEnabled(true);
     ui->action_Configure_Current_Game->setEnabled(true);
     ui->action_Report_Compatibility->setEnabled(true);
+    OnTasStateChanged();
 
     discord_rpc->Update();
     ui->action_Load_Amiibo->setEnabled(true);
@@ -2821,6 +2819,32 @@ void GMainWindow::OnConfigureTas() {
     }
 }
 
+void GMainWindow::OnTasStartStop() {
+    if (!emulation_running) {
+        return;
+    }
+    input_subsystem->GetTas()->StartStop();
+    OnTasStateChanged();
+}
+
+void GMainWindow::OnTasRecord() {
+    if (!emulation_running) {
+        return;
+    }
+    const bool is_recording = input_subsystem->GetTas()->Record();
+    if (!is_recording) {
+        const auto res =
+            QMessageBox::question(this, tr("TAS Recording"), tr("Overwrite file of player 1?"),
+                                  QMessageBox::Yes | QMessageBox::No);
+        input_subsystem->GetTas()->SaveRecording(res == QMessageBox::Yes);
+    }
+    OnTasStateChanged();
+}
+
+void GMainWindow::OnTasReset() {
+    input_subsystem->GetTas()->Reset();
+}
+
 void GMainWindow::OnConfigurePerGame() {
     const u64 title_id = system->GetCurrentProcessProgramID();
     OpenPerGameConfiguration(title_id, game_path.toStdString());
@@ -3014,6 +3038,23 @@ QString GMainWindow::GetTasStateDescription() const {
     }
 }
 
+void GMainWindow::OnTasStateChanged() {
+    bool is_running = false;
+    bool is_recording = false;
+    if (emulation_running) {
+        const TasInput::TasState tas_status = std::get<0>(input_subsystem->GetTas()->GetStatus());
+        is_running = tas_status == TasInput::TasState::Running;
+        is_recording = tas_status == TasInput::TasState::Recording;
+    }
+
+    ui->action_TAS_Start->setText(is_running ? tr("&Stop Running") : tr("&Start"));
+    ui->action_TAS_Record->setText(is_recording ? tr("Stop R&ecording") : tr("R&ecord"));
+
+    ui->action_TAS_Start->setEnabled(emulation_running);
+    ui->action_TAS_Record->setEnabled(emulation_running);
+    ui->action_TAS_Reset->setEnabled(emulation_running);
+}
+
 void GMainWindow::UpdateStatusBar() {
     if (emu_thread == nullptr) {
         status_bar_update_timer.stop();
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index 24633ff2d8..556cbbaf72 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -177,6 +177,7 @@ public slots:
     void WebBrowserOpenWebPage(const std::string& main_url, const std::string& additional_args,
                                bool is_local);
     void OnAppFocusStateChanged(Qt::ApplicationState state);
+    void OnTasStateChanged();
 
 private:
     void RegisterMetaTypes();
@@ -268,6 +269,9 @@ private slots:
     void OnMenuRecentFile();
     void OnConfigure();
     void OnConfigureTas();
+    void OnTasStartStop();
+    void OnTasRecord();
+    void OnTasReset();
     void OnConfigurePerGame();
     void OnLoadAmiibo();
     void OnOpenYuzuFolder();
@@ -313,6 +317,7 @@ private:
     void OpenURL(const QUrl& url);
     void LoadTranslation();
     void OpenPerGameConfiguration(u64 title_id, const std::string& file_name);
+
     QString GetTasStateDescription() const;
 
     std::unique_ptr<Ui::MainWindow> ui;
diff --git a/src/yuzu/main.ui b/src/yuzu/main.ui
index a62e39a061..c58aa28667 100644
--- a/src/yuzu/main.ui
+++ b/src/yuzu/main.ui
@@ -79,39 +79,39 @@
      <string>&amp;View</string>
     </property>
     <widget class="QMenu" name="menu_Reset_Window_Size">
-      <property name="title">
-        <string>&amp;Reset Window Size</string>
-      </property>
+     <property name="title">
+      <string>&amp;Reset Window Size</string>
+     </property>
     </widget>
-    <action name="action_Reset_Window_Size_720">
-      <property name="text">
-        <string>Reset Window Size to &amp;720p</string>
-      </property>
-      <property name="iconText">
-        <string>Reset Window Size to 720p</string>
-      </property>
-    </action>
-    <action name="action_Reset_Window_Size_900">
-      <property name="text">
-        <string>Reset Window Size to &amp;900p</string>
-      </property>
-      <property name="iconText">
-        <string>Reset Window Size to 900p</string>
-      </property>
-    </action>
-    <action name="action_Reset_Window_Size_1080">
-      <property name="text">
-        <string>Reset Window Size to &amp;1080p</string>
-      </property>
-      <property name="iconText">
-        <string>Reset Window Size to 1080p</string>
-      </property>
-    </action>
     <widget class="QMenu" name="menu_View_Debugging">
      <property name="title">
       <string>&amp;Debugging</string>
      </property>
     </widget>
+    <action name="action_Reset_Window_Size_720">
+     <property name="text">
+      <string>Reset Window Size to &amp;720p</string>
+     </property>
+     <property name="iconText">
+      <string>Reset Window Size to 720p</string>
+     </property>
+    </action>
+    <action name="action_Reset_Window_Size_900">
+     <property name="text">
+      <string>Reset Window Size to &amp;900p</string>
+     </property>
+     <property name="iconText">
+      <string>Reset Window Size to 900p</string>
+     </property>
+    </action>
+    <action name="action_Reset_Window_Size_1080">
+     <property name="text">
+      <string>Reset Window Size to &amp;1080p</string>
+     </property>
+     <property name="iconText">
+      <string>Reset Window Size to 1080p</string>
+     </property>
+    </action>
     <addaction name="action_Fullscreen"/>
     <addaction name="action_Single_Window_Mode"/>
     <addaction name="action_Display_Dock_Widget_Headers"/>
@@ -125,10 +125,20 @@
     <property name="title">
      <string>&amp;Tools</string>
     </property>
+    <widget class="QMenu" name="menuTAS">
+     <property name="title">
+      <string>&amp;TAS</string>
+     </property>
+     <addaction name="action_TAS_Start"/>
+     <addaction name="action_TAS_Record"/>
+     <addaction name="action_TAS_Reset"/>
+     <addaction name="separator"/>
+     <addaction name="action_Configure_Tas"/>
+    </widget>
     <addaction name="action_Rederive"/>
     <addaction name="separator"/>
     <addaction name="action_Capture_Screenshot"/>
-    <addaction name="action_Configure_Tas"/>
+    <addaction name="menuTAS"/>
    </widget>
    <widget class="QMenu" name="menu_Help">
     <property name="title">
@@ -309,7 +319,7 @@
   </action>
   <action name="action_Configure_Tas">
    <property name="text">
-    <string>Configure &amp;TAS...</string>
+    <string>&amp;Configure TAS...</string>
    </property>
   </action>
   <action name="action_Configure_Current_Game">
@@ -320,6 +330,30 @@
     <string>Configure C&amp;urrent Game...</string>
    </property>
   </action>
+  <action name="action_TAS_Start">
+   <property name="enabled">
+    <bool>false</bool>
+   </property>
+   <property name="text">
+    <string>&amp;Start</string>
+   </property>
+  </action>
+  <action name="action_TAS_Reset">
+   <property name="enabled">
+    <bool>false</bool>
+   </property>
+   <property name="text">
+    <string>&amp;Reset</string>
+   </property>
+  </action>
+  <action name="action_TAS_Record">
+   <property name="enabled">
+    <bool>false</bool>
+   </property>
+   <property name="text">
+    <string>R&amp;ecord</string>
+   </property>
+  </action>
  </widget>
  <resources>
   <include location="yuzu.qrc"/>