diff --git a/internal/window/chat.go b/internal/window/chat.go
index 0c422c52..b4294feb 100644
--- a/internal/window/chat.go
+++ b/internal/window/chat.go
@@ -42,7 +42,6 @@ type ChatPage struct {
 	rightTitle  *adw.Bin
 
 	tabView       *adw.TabView
-	quickswitcher *quickswitcher.Dialog
 
 	lastGuildState   *app.TypedSingleState[discord.GuildID]
 	lastChannelState *app.TypedState[discord.ChannelID]
@@ -93,9 +92,6 @@ func NewChatPage(ctx context.Context, w *Window) *ChatPage {
 		lastChannelState: lastChannelKey.Acquire(ctx),
 	}
 
-	p.quickswitcher = quickswitcher.NewDialog(ctx)
-	p.quickswitcher.SetHideOnClose(true) // so we can reopen it later
-
 	p.tabView = adw.NewTabView()
 	p.tabView.AddCSSClass("window-chatpage-tabview")
 	p.tabView.SetDefaultIcon(gio.NewThemedIcon("channel-symbolic"))
@@ -178,7 +174,7 @@ func NewChatPage(ctx context.Context, w *Window) *ChatPage {
 }
 
 // OpenQuickSwitcher opens the Quick Switcher dialog.
-func (p *ChatPage) OpenQuickSwitcher() { p.quickswitcher.Show() }
+func (p *ChatPage) OpenQuickSwitcher() { quickswitcher.ShowDialog(p.ctx) }
 
 // ResetView switches out of any channel view and into the placeholder view.
 // This method is used when the guild becomes unavailable.
diff --git a/internal/window/quickswitcher/dialog.go b/internal/window/quickswitcher/dialog.go
index 0a5b0107..3a176355 100644
--- a/internal/window/quickswitcher/dialog.go
+++ b/internal/window/quickswitcher/dialog.go
@@ -12,14 +12,14 @@ import (
 
 // Dialog is a Quick Switcher dialog.
 type Dialog struct {
-	*adw.ApplicationWindow
+	*adw.Dialog
 	QuickSwitcher *QuickSwitcher
 }
 
 // ShowDialog shows a new Quick Switcher dialog.
 func ShowDialog(ctx context.Context) {
 	d := NewDialog(ctx)
-	d.Show()
+	d.Present(app.GTKWindowFromContext(ctx))
 }
 
 var dialogCSS = cssutil.Applier("quickswitcher-dialog", "")
@@ -30,7 +30,6 @@ func NewDialog(ctx context.Context) *Dialog {
 	qs.Box.Remove(qs.search) // jank
 	qs.search.SetHExpand(true)
 
-	win := app.GTKWindowFromContext(ctx)
 	app := app.FromContext(ctx)
 
 	header := adw.NewHeaderBar()
@@ -42,26 +41,17 @@ func NewDialog(ctx context.Context) *Dialog {
 	toolbarView.SetContent(qs)
 
 	d := Dialog{QuickSwitcher: qs}
-	d.ApplicationWindow = adw.NewApplicationWindow(app.Application)
-	d.SetTransientFor(win)
-	d.SetDefaultSize(375, 275)
-	d.SetModal(true)
-	d.SetDestroyWithParent(true)
+	d.Dialog = adw.NewDialog()
+	d.SetContentWidth(375)
+	d.SetContentHeight(275)
 	d.SetTitle(app.SuffixedTitle("Quick Switcher"))
-	d.SetContent(toolbarView)
+	d.SetChild(toolbarView)
 	d.ConnectShow(func() {
 		qs.Clear()
 		qs.search.GrabFocus()
 	})
 	dialogCSS(d)
 
-	// SetDestroyWithParent doesn't work for some reason, so we have to manually
-	// destroy the QuickSwitcher on transient window destroy.
-	win.ConnectCloseRequest(func() bool {
-		d.Destroy()
-		return false
-	})
-
 	qs.ConnectChosen(func() {
 		d.Close()
 	})