diff --git a/src/client/components/autocomplete.vue b/src/client/components/autocomplete.vue
index a02d5afbb8..dc539911d9 100644
--- a/src/client/components/autocomplete.vue
+++ b/src/client/components/autocomplete.vue
@@ -93,11 +93,6 @@ export default defineComponent({
 			required: true,
 		},
 
-		complete: {
-			type: Function,
-			required: true,
-		},
-
 		close: {
 			type: Function,
 			required: true,
@@ -114,6 +109,8 @@ export default defineComponent({
 		},
 	},
 
+	emits: ['done', 'closed'],
+
 	data() {
 		return {
 			getStaticImageUrl,
@@ -200,6 +197,11 @@ export default defineComponent({
 	},
 
 	methods: {
+		complete(type, value) {
+			this.$emit('done', { type, value });
+			this.$emit('closed');
+		},
+
 		setPosition() {
 			if (this.x + this.$el.offsetWidth > window.innerWidth) {
 				this.$el.style.left = (window.innerWidth - this.$el.offsetWidth) + 'px';
diff --git a/src/client/os.ts b/src/client/os.ts
index 66d1cbef34..015456ac07 100644
--- a/src/client/os.ts
+++ b/src/client/os.ts
@@ -54,20 +54,15 @@ export function popup(component: Component, props: Record<string, any>, events =
 		markRaw(component);
 		const id = Math.random().toString(); // TODO: uuidとか使う
 		const showing = ref(true);
-		const close = (...args) => {
-			resolve(...args);
-			showing.value = false;
-		};
 		const modal = {
 			type: 'popup',
 			component,
 			props,
 			showing,
 			events,
-			done: close,
-			bgClick: () => close(),
 			closed: () => {
 				store.commit('removePopup', id);
+				resolve();
 			},
 			id,
 		};
@@ -75,7 +70,7 @@ export function popup(component: Component, props: Record<string, any>, events =
 
 		onCancel.shouldReject = false;
 		onCancel(() => {
-			close();
+			showing.value = false;
 		});
 	});
 }
diff --git a/src/client/root.vue b/src/client/root.vue
index 2879deb52b..98250df4d4 100644
--- a/src/client/root.vue
+++ b/src/client/root.vue
@@ -6,7 +6,7 @@
 	<component :is="modal.component" v-bind="modal.props" v-on="modal.events" @done="modal.done"/>
 </XModal>
 
-<component v-for="popup in $store.state.popups.filter(x => x.type === 'popup')" :key="popup.id" :is="popup.component" v-bind="popup.props" v-on="popup.events" @done="popup.done" @closed="popup.closed"/>
+<component v-for="popup in $store.state.popups.filter(x => x.type === 'popup')" :key="popup.id" :is="popup.component" v-bind="popup.props" :showing="popup.showing" v-on="popup.events" @closed="popup.closed"/>
 
 <div id="wait" v-if="$store.state.pendingApiRequestsCount > 0"></div>
 </template>
diff --git a/src/client/scripts/autocomplete.ts b/src/client/scripts/autocomplete.ts
index 5f0910c828..3a92ccf6fd 100644
--- a/src/client/scripts/autocomplete.ts
+++ b/src/client/scripts/autocomplete.ts
@@ -154,12 +154,15 @@ export class Autocomplete {
 
 			const promise = popup(MkAutocomplete, {
 				textarea: this.textarea,
-				complete: this.complete,
 				close: this.close,
 				type: type,
 				q: _q,
 				x: _x,
 				y: _y,
+			}, {
+				done: (res) => {
+					this.complete(res);
+				}
 			});
 
 			this.suggestion = {
@@ -188,7 +191,7 @@ export class Autocomplete {
 	/**
 	 * オートコンプリートする
 	 */
-	private complete(type, value) {
+	private complete({ type, value }) {
 		this.close();
 
 		const caret = this.textarea.selectionStart;