diff --git a/src/components/Modals/AddModal.vue b/src/components/Modals/AddModal.vue
index 000b3171..50ea4b98 100644
--- a/src/components/Modals/AddModal.vue
+++ b/src/components/Modals/AddModal.vue
@@ -7,6 +7,7 @@
     :fullscreen="phoneLayout"
     persistent
     @keydown.enter.prevent="$refs.addTorrent.click"
+    @keydown.esc.prevent="close"
   >
     <div
       class="noselect"
@@ -241,10 +242,6 @@ export default {
   },
   mounted() {
     this.dTransition = 'scale-transition'
-    document.addEventListener('keydown', this.handleKeyboardShortcut)
-  },
-  beforeDestroy() {
-    document.removeEventListener('keydown', this.handleKeyboardShortcut)
   },
   methods: {
     async setSettings() {
@@ -324,11 +321,6 @@ export default {
     },
     close() {
       this.dialog = false
-    },
-    handleKeyboardShortcut(e) {
-      if (e.key === 'Escape') {
-        this.close()
-      }
     }
   }
 }
diff --git a/src/components/Modals/RenameModal.vue b/src/components/Modals/RenameModal.vue
index c2cb640c..e0ee7366 100644
--- a/src/components/Modals/RenameModal.vue
+++ b/src/components/Modals/RenameModal.vue
@@ -1,5 +1,5 @@
 <template>
-  <v-dialog v-model="dialog" scrollable max-width="750px" :content-class="phoneLayout ? 'rounded-0' : 'rounded-form'" :fullscreen="phoneLayout">
+  <v-dialog v-model="dialog" scrollable max-width="750px" :content-class="phoneLayout ? 'rounded-0' : 'rounded-form'" :fullscreen="phoneLayout" @keydown.enter.prevent="rename" @keydown.esc.prevent="close">
     <v-card>
       <v-card-title class="pa-0">
         <v-toolbar-title class="ma-4 primarytext--text">
@@ -55,15 +55,9 @@ export default defineComponent({
       return this.getTorrent(this.hash)
     }
   },
-  mounted() {
-    document.addEventListener('keydown', this.handleKeyboardShortcut)
-  },
   created() {
     this.name = this.torrent.name
   },
-  beforeDestroy() {
-    document.removeEventListener('keydown', this.handleKeyboardShortcut)
-  },
   methods: {
     urlDecode() {
       this.name = decodeURIComponent(this.name)
@@ -74,13 +68,6 @@ export default defineComponent({
     },
     close() {
       this.dialog = false
-    },
-    handleKeyboardShortcut(e: KeyboardEvent) {
-      if (e.key === 'Escape') {
-        this.close()
-      } else if (e.key === 'Enter') {
-        this.rename()
-      }
     }
   }
 })
diff --git a/src/components/Modals/Rss/FeedForm.vue b/src/components/Modals/Rss/FeedForm.vue
index 343e0835..f56fd9d7 100644
--- a/src/components/Modals/Rss/FeedForm.vue
+++ b/src/components/Modals/Rss/FeedForm.vue
@@ -1,5 +1,5 @@
 <template>
-  <v-dialog v-model="dialog" content-class="rounded-form" max-width="300px">
+  <v-dialog v-model="dialog" content-class="rounded-form" max-width="300px" @keydown.enter.prevent="hasInitialFeed ? edit : create" @keydown.esc.prevent="cancel">
     <v-card>
       <v-card-title class="pa-0">
         <v-toolbar-title class="ma-4 primarytext--text">
@@ -60,12 +60,6 @@ export default defineComponent({
       this.feed = { ...this.initialFeed }
     }
   },
-  mounted() {
-    document.addEventListener('keydown', this.handleKeyboardShortcut)
-  },
-  beforeDestroy() {
-    document.removeEventListener('keydown', this.handleKeyboardShortcut)
-  },
   methods: {
     async create() {
       await qbit.createFeed(this.feed)
@@ -79,14 +73,6 @@ export default defineComponent({
       await qbit.editFeed(this.initialFeed.name, this.feed.name)
       this.$toast.success(this.$t('toast.feedSaved'))
       this.cancel()
-    },
-    handleKeyboardShortcut(e: KeyboardEvent) {
-      if (e.key === 'Escape') {
-        this.cancel()
-      } else if (e.key === 'Enter') {
-        if (this.hasInitialFeed) this.edit()
-        else this.create()
-      }
     }
   }
 })
diff --git a/src/components/Modals/Rss/RuleForm.vue b/src/components/Modals/Rss/RuleForm.vue
index 75f4dd25..51884b24 100644
--- a/src/components/Modals/Rss/RuleForm.vue
+++ b/src/components/Modals/Rss/RuleForm.vue
@@ -1,5 +1,5 @@
 <template>
-  <v-dialog v-model="dialog" max-width="1000px">
+  <v-dialog v-model="dialog" max-width="1000px" @keydown.enter.prevent="setRule" @keydown.esc.prevent="close">
     <v-card flat :loading="loading">
       <v-container class="pa-0 project done">
         <v-card-title class="justify-center">
@@ -181,13 +181,8 @@ export default defineComponent({
     }
   },
   mounted() {
-    document.addEventListener('keydown', this.handleKeyboardShortcut)
-
     this.updateArticles()
   },
-  beforeDestroy() {
-    document.removeEventListener('keydown', this.handleKeyboardShortcut)
-  },
   methods: {
     async setRule() {
       if ((this.hasInitialRule || this.lastSavedName !== '') && this.lastSavedName !== this.rule.name) {
@@ -228,13 +223,6 @@ export default defineComponent({
     },
     close() {
       this.dialog = false
-    },
-    handleKeyboardShortcut(e: KeyboardEvent) {
-      if (e.key === 'Escape') {
-        this.close()
-      } else if (e.key === 'Enter') {
-        this.setRule()
-      }
     }
   }
 })
diff --git a/src/components/Modals/SearchPluginManager.vue b/src/components/Modals/SearchPluginManager.vue
index 5b03f59d..478fb889 100644
--- a/src/components/Modals/SearchPluginManager.vue
+++ b/src/components/Modals/SearchPluginManager.vue
@@ -1,5 +1,5 @@
 <template>
-  <v-dialog v-model="dialog" scrollable :width="dialogWidth" :fullscreen="phoneLayout">
+  <v-dialog v-model="dialog" scrollable :width="dialogWidth" :fullscreen="phoneLayout" @keydown.esc.prevent="close">
     <v-card>
       <v-card-title class="pa-0">
         <v-toolbar-title class="ma-4 primarytext--text">
@@ -98,15 +98,10 @@ export default defineComponent({
     ...mapState(['searchPlugins'])
   },
   mounted() {
-    document.addEventListener('keydown', this.handleKeyboardShortcut)
-
     this.loading = true
     this.updatePluginList()
     this.loading = false
   },
-  beforeDestroy() {
-    document.removeEventListener('keydown', this.handleKeyboardShortcut)
-  },
   methods: {
     async updatePluginList() {
       await this.$store.dispatch('FETCH_SEARCH_PLUGINS')
@@ -162,11 +157,6 @@ export default defineComponent({
     },
     closeInstallDialog() {
       this.installDialog = false
-    },
-    handleKeyboardShortcut(e: KeyboardEvent) {
-      if (e.key === 'Escape') {
-        this.close()
-      }
     }
   }
 })
diff --git a/src/views/RssArticles.vue b/src/views/RssArticles.vue
index fefb9cbf..1e671d88 100644
--- a/src/views/RssArticles.vue
+++ b/src/views/RssArticles.vue
@@ -1,5 +1,5 @@
 <template>
-  <div class="px-1 px-sm-5 background noselect">
+  <div class="px-1 px-sm-5 background noselect" @keydown.esc.prevent="close">
     <v-row no-gutters class="grey--text" align="center" justify="center">
       <v-col>
         <h1 style="font-size: 1.6em !important" class="subtitle-1 ml-2">
@@ -94,15 +94,9 @@ export default defineComponent({
       mdiClose
     }
   },
-  mounted() {
-    document.addEventListener('keydown', this.handleKeyboardShortcut)
-  },
   created() {
     this.$store.commit('FETCH_FEEDS')
   },
-  beforeDestroy() {
-    document.removeEventListener('keydown', this.handleKeyboardShortcut)
-  },
   computed: {
     ...mapState(['rss']),
     articles(): FeedArticle[] {
@@ -139,11 +133,6 @@ export default defineComponent({
         await qbit.markAsRead(article.feedName, article.id)
       }
       this.$store.commit('FETCH_FEEDS')
-    },
-    handleKeyboardShortcut(e: KeyboardEvent) {
-      if (e.key === 'Escape') {
-        this.close()
-      }
     }
   }
 })
diff --git a/src/views/Settings.vue b/src/views/Settings.vue
index e509ef10..b210c735 100644
--- a/src/views/Settings.vue
+++ b/src/views/Settings.vue
@@ -1,5 +1,5 @@
 <template>
-  <div class="px-1 px-sm-5 background noselect">
+  <div class="px-1 px-sm-5 background noselect" @keydown.esc.prevent="close">
     <v-row no-gutters class="grey--text" align="center" justify="center">
       <v-col>
         <h1 style="font-size: 1.6em !important" class="subtitle-1 ml-2">
@@ -125,10 +125,6 @@ export default defineComponent({
   },
   mounted() {
     this.$store.dispatch('FETCH_SETTINGS')
-    document.addEventListener('keydown', this.handleKeyboardShortcut)
-  },
-  beforeDestroy() {
-    document.removeEventListener('keydown', this.handleKeyboardShortcut)
   },
   watch: {
     tab() {
@@ -138,11 +134,6 @@ export default defineComponent({
   methods: {
     close() {
       this.$router.back()
-    },
-    handleKeyboardShortcut(e: KeyboardEvent) {
-      if (e.key === 'Escape') {
-        this.close()
-      }
     }
   }
 })
diff --git a/src/views/TorrentDetail.vue b/src/views/TorrentDetail.vue
index 796a3c4d..9a94d58c 100644
--- a/src/views/TorrentDetail.vue
+++ b/src/views/TorrentDetail.vue
@@ -1,5 +1,5 @@
 <template>
-  <div class="px-1 px-sm-5 background noselect">
+  <div class="px-1 px-sm-5 background noselect" @keydown.esc.prevent="close">
     <v-row no-gutters class="grey--text" align="center" justify="center">
       <v-col>
         <h1 style="font-size: 1.6em !important" class="subtitle-1 ml-2">
@@ -83,20 +83,13 @@ export default {
   },
   mounted() {
     this.$store.dispatch('INIT_INTERVALS')
-    document.addEventListener('keydown', this.handleKeyboardShortcut)
   },
   beforeDestroy() {
     this.$store.commit('REMOVE_INTERVALS')
-    document.removeEventListener('keydown', this.handleKeyboardShortcut)
   },
   methods: {
     close() {
       this.$router.back()
-    },
-    handleKeyboardShortcut(e) {
-      if (e.key === 'Escape') {
-        this.close()
-      }
     }
   }
 }