diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp
index 78541e880..2f6ab6829 100644
--- a/src/citra_qt/bootmanager.cpp
+++ b/src/citra_qt/bootmanager.cpp
@@ -199,6 +199,8 @@ GRenderWindow::GRenderWindow(QWidget* parent_, EmuThread* emu_thread)
     setLayout(layout);
     InputCommon::Init();
 
+    this->setMouseTracking(true);
+
     GMainWindow* parent = GetMainWindow();
     connect(this, &GRenderWindow::FirstFrameDisplayed, parent, &GMainWindow::OnLoadComplete);
 }
@@ -295,6 +297,7 @@ void GRenderWindow::mousePressEvent(QMouseEvent* event) {
     } else if (event->button() == Qt::RightButton) {
         InputCommon::GetMotionEmu()->BeginTilt(pos.x(), pos.y());
     }
+    QWidget::mouseMoveEvent(event);
 }
 
 void GRenderWindow::mouseMoveEvent(QMouseEvent* event) {
@@ -305,6 +308,7 @@ void GRenderWindow::mouseMoveEvent(QMouseEvent* event) {
     const auto [x, y] = ScaleTouch(pos);
     this->TouchMoved(x, y);
     InputCommon::GetMotionEmu()->Tilt(pos.x(), pos.y());
+    QWidget::mouseMoveEvent(event);
 }
 
 void GRenderWindow::mouseReleaseEvent(QMouseEvent* event) {
diff --git a/src/citra_qt/configuration/config.cpp b/src/citra_qt/configuration/config.cpp
index 2901022da..9830f9000 100644
--- a/src/citra_qt/configuration/config.cpp
+++ b/src/citra_qt/configuration/config.cpp
@@ -570,6 +570,8 @@ void Config::ReadUIValues() {
     UISettings::values.show_console = ReadSetting(QStringLiteral("showConsole"), false).toBool();
     UISettings::values.pause_when_in_background =
         ReadSetting(QStringLiteral("pauseWhenInBackground"), false).toBool();
+    UISettings::values.hide_mouse =
+        ReadSetting(QStringLiteral("hideInactiveMouse"), false).toBool();
 
     qt_config->endGroup();
 }
@@ -1028,6 +1030,7 @@ void Config::SaveUIValues() {
     WriteSetting(QStringLiteral("showConsole"), UISettings::values.show_console, false);
     WriteSetting(QStringLiteral("pauseWhenInBackground"),
                  UISettings::values.pause_when_in_background, false);
+    WriteSetting(QStringLiteral("hideInactiveMouse"), UISettings::values.hide_mouse, false);
 
     qt_config->endGroup();
 }
diff --git a/src/citra_qt/configuration/configure_general.cpp b/src/citra_qt/configuration/configure_general.cpp
index 47d559e3d..419331d13 100644
--- a/src/citra_qt/configuration/configure_general.cpp
+++ b/src/citra_qt/configuration/configure_general.cpp
@@ -27,6 +27,7 @@ ConfigureGeneral::~ConfigureGeneral() = default;
 void ConfigureGeneral::SetConfiguration() {
     ui->toggle_check_exit->setChecked(UISettings::values.confirm_before_closing);
     ui->toggle_background_pause->setChecked(UISettings::values.pause_when_in_background);
+    ui->toggle_hide_mouse->setChecked(UISettings::values.hide_mouse);
 
     ui->toggle_update_check->setChecked(UISettings::values.check_for_update_on_start);
     ui->toggle_auto_update->setChecked(UISettings::values.update_on_close);
@@ -55,6 +56,7 @@ void ConfigureGeneral::ResetDefaults() {
 void ConfigureGeneral::ApplyConfiguration() {
     UISettings::values.confirm_before_closing = ui->toggle_check_exit->isChecked();
     UISettings::values.pause_when_in_background = ui->toggle_background_pause->isChecked();
+    UISettings::values.hide_mouse = ui->toggle_hide_mouse->isChecked();
 
     UISettings::values.check_for_update_on_start = ui->toggle_update_check->isChecked();
     UISettings::values.update_on_close = ui->toggle_auto_update->isChecked();
diff --git a/src/citra_qt/configuration/configure_general.ui b/src/citra_qt/configuration/configure_general.ui
index 181455a64..6b2aa4416 100644
--- a/src/citra_qt/configuration/configure_general.ui
+++ b/src/citra_qt/configuration/configure_general.ui
@@ -36,6 +36,13 @@
           </property>
          </widget>
         </item>
+        <item>
+         <widget class="QCheckBox" name="toggle_hide_mouse">
+          <property name="text">
+           <string>Hide mouse on inactivity</string>
+          </property>
+         </widget>
+        </item>
        </layout>
       </widget>
      </item>
diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp
index fc7eb2522..f47e359a0 100644
--- a/src/citra_qt/main.cpp
+++ b/src/citra_qt/main.cpp
@@ -102,6 +102,8 @@ __declspec(dllexport) unsigned long NvOptimusEnablement = 0x00000001;
 }
 #endif
 
+constexpr int default_mouse_timeout = 2500;
+
 /**
  * "Callouts" are one-time instructional messages shown to the user. In the config settings, there
  * is a bitfield "callout_flags" options, used to track if a message has already been shown to the
@@ -194,6 +196,14 @@ GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) {
     // Show one-time "callout" messages to the user
     ShowTelemetryCallout();
 
+    // make sure menubar has the arrow cursor instead of inheriting from this
+    ui.menubar->setCursor(QCursor());
+    statusBar()->setCursor(QCursor());
+
+    mouse_hide_timer.setInterval(default_mouse_timeout);
+    connect(&mouse_hide_timer, &QTimer::timeout, this, &GMainWindow::HideMouseCursor);
+    connect(ui.menubar, &QMenuBar::hovered, this, &GMainWindow::ShowMouseCursor);
+
     if (UISettings::values.check_for_update_on_start) {
         CheckForUpdates();
     }
@@ -965,6 +975,13 @@ void GMainWindow::BootGame(const QString& filename) {
     }
     status_bar_update_timer.start(2000);
 
+    if (UISettings::values.hide_mouse) {
+        mouse_hide_timer.start();
+        setMouseTracking(true);
+        ui.centralwidget->setMouseTracking(true);
+        ui.menubar->setMouseTracking(true);
+    }
+
     // show and hide the render_window to create the context
     render_window->show();
     render_window->hide();
@@ -1063,6 +1080,10 @@ void GMainWindow::ShutdownGame() {
         game_list->show();
     game_list->setFilterFocus();
 
+    setMouseTracking(false);
+    ui.centralwidget->setMouseTracking(false);
+    ui.menubar->setMouseTracking(false);
+
     // Disable status bar updates
     status_bar_update_timer.stop();
     message_label->setVisible(false);
@@ -1578,6 +1599,16 @@ void GMainWindow::OnConfigure() {
         SyncMenuUISettings();
         game_list->RefreshGameDirectory();
         config->Save();
+        if (UISettings::values.hide_mouse && emulation_running) {
+            setMouseTracking(true);
+            ui.centralwidget->setMouseTracking(true);
+            ui.menubar->setMouseTracking(true);
+            mouse_hide_timer.start();
+        } else {
+            setMouseTracking(false);
+            ui.centralwidget->setMouseTracking(false);
+            ui.menubar->setMouseTracking(false);
+        }
     } else {
         Settings::values.input_profiles = old_input_profiles;
         Settings::LoadProfile(old_input_profile_index);
@@ -1894,6 +1925,30 @@ void GMainWindow::UpdateStatusBar() {
     emu_frametime_label->setVisible(true);
 }
 
+void GMainWindow::HideMouseCursor() {
+    if (emu_thread == nullptr || UISettings::values.hide_mouse == false) {
+        mouse_hide_timer.stop();
+        ShowMouseCursor();
+        return;
+    }
+    setCursor(QCursor(Qt::BlankCursor));
+}
+
+void GMainWindow::ShowMouseCursor() {
+    unsetCursor();
+    if (emu_thread != nullptr && UISettings::values.hide_mouse) {
+        mouse_hide_timer.start();
+    }
+}
+
+void GMainWindow::mouseMoveEvent(QMouseEvent* event) {
+    ShowMouseCursor();
+}
+
+void GMainWindow::mousePressEvent(QMouseEvent* event) {
+    ShowMouseCursor();
+}
+
 void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string details) {
     QString status_message;
 
diff --git a/src/citra_qt/main.h b/src/citra_qt/main.h
index 132fad821..4bdbd622f 100644
--- a/src/citra_qt/main.h
+++ b/src/citra_qt/main.h
@@ -220,6 +220,8 @@ private:
     void UpdateWindowTitle();
     void RetranslateStatusBar();
     void InstallCIA(QStringList filepaths);
+    void HideMouseCursor();
+    void ShowMouseCursor();
 
     Ui::MainWindow ui;
 
@@ -248,6 +250,7 @@ private:
     QString game_path;
 
     bool auto_paused = false;
+    QTimer mouse_hide_timer;
 
     // Movie
     bool movie_record_on_start = false;
@@ -291,6 +294,8 @@ protected:
     void dropEvent(QDropEvent* event) override;
     void dragEnterEvent(QDragEnterEvent* event) override;
     void dragMoveEvent(QDragMoveEvent* event) override;
+    void mouseMoveEvent(QMouseEvent* event) override;
+    void mousePressEvent(QMouseEvent* event) override;
 };
 
 Q_DECLARE_METATYPE(std::size_t);
diff --git a/src/citra_qt/uisettings.h b/src/citra_qt/uisettings.h
index 0736db6ff..a54bc3ee7 100644
--- a/src/citra_qt/uisettings.h
+++ b/src/citra_qt/uisettings.h
@@ -76,6 +76,7 @@ struct Values {
     bool confirm_before_closing;
     bool first_start;
     bool pause_when_in_background;
+    bool hide_mouse;
 
     bool updater_found;
     bool update_on_close;