1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
#:schema ./schemas/flow-rules.schema.json
# Default window classification rules for FlowWM.
#
# This file is embedded into flowd.exe at compile time (via `include_str!`) and
# provides sensible defaults for common Windows system windows that should NOT
# be tiled. It does NOT ship as a separate runtime file. Users can override
# any of these rules by adding their own rules in flow-rules.toml (which is
# checked first).
#
# Format: first match wins. Each rule has a "match" clause (AND logic) and
# an "action" (tile, float, or ignore).
#
# For match field documentation, see the MatchRule docstring in src/config/types.rs.
= "float"
# ── Windows Shell ────────────────────────────────────────────────────
# Windows taskbar — primary monitor.
[[]]
= { = "Shell_TrayWnd" }
= "ignore"
# Windows taskbar — secondary monitors. On multi-monitor setups explorer creates
# one taskbar window per additional monitor under a distinct class
# (`Shell_SecondaryTrayWnd`, NOT `Shell_TrayWnd`). It is a top-level, visible,
# titled, non-cloaked, ownerless shell surface, so it passes every pre-filter
# gate exactly like the primary taskbar above — without this rule the secondary
# taskbar registers as Floating and gets a border overlay drawn around it.
# Class-only match: same race-free rationale as the primary taskbar rule.
[[]]
= { = "Shell_SecondaryTrayWnd" }
= "ignore"
# WinUI / XAML Islands desktop content bridge — an invisible helper window
# (title "DesktopWindowXamlSource") created by WinUI 3 / XAML Islands hosts
# (Settings, Photos, the Run box, …). It passes flow's visibility/Alt+Tab/owner
# gates but is never a real app window the user would want tiled, so ignore it
# by class (race-free).
[[]]
= { = "Windows.UI.Composition.DesktopWindowContentBridge" }
= "ignore"
# Windows 11 Start Menu host. The actual start menu runs in
# StartMenuExperienceHost.exe (NOT ShellExperienceHost.exe below, which hosts
# the older shell surfaces). Its popup surface is a top-level
# `Xaml_WindowedPopupClass` window titled "PopupHost" that passes every gate,
# so without this rule it is classified Floating and gets a border drawn around
# the start menu.
[[]]
= { = "StartMenuExperienceHost.exe" }
= "ignore"
# XAML windowed-popups — the class used by the Start Menu popup, Action Center
# flyouts, jump lists, and other OS-level XAML popups. All are transient system
# surfaces, never app windows. Ignored by class (race-free) so any host gets
# covered regardless of its exe name.
[[]]
= { = "Xaml_WindowedPopupClass" }
= "ignore"
# Windows Search overlay — Windows 10 (`SearchUI.exe`).
[[]]
= { = "SearchUI.exe" }
= "ignore"
# Windows Search overlay — Windows 11 22H2+ (`SearchHost.exe`). Win11 split the
# search UI out of `SearchUI.exe` into `SearchHost.exe`, so the Win10 rule above
# no longer catches it. The surface is a top-level, titled, non-cloaked-while-
# open, ownerless popup that passes every gate, so without this rule it gets
# floated and bordered whenever the user opens Search.
[[]]
= { = "SearchHost.exe" }
= "ignore"
# Older shell-experience host (Action Center / Cortana surfaces). The modern
# Start Menu is hosted by StartMenuExperienceHost.exe, handled above.
[[]]
= { = "ShellExperienceHost.exe" }
= "ignore"
# Windows Action Center / Quick Settings / notification toasts
[[]]
= { = "ShellExperienceHost.exe", = "Windows.UI.Core.CoreWindow" }
= "ignore"
# ── System Dialogs ──────────────────────────────────────────────────
# Common Win32 dialog boxes (Open/Save As, Properties, etc.)
[[]]
= { = "#32770" }
= "ignore"
# ── Explorer ────────────────────────────────────────────────────────
# Windows Explorer file open/save dialogs
[[]]
= { = "explorer.exe", = "CabinetWClass" }
= "ignore"
# Explorer's internal content tab — the surface where files actually render
# when navigating. A child of CabinetWClass that passes flow's pre-filters;
# floating it draws the border overlay over the file list (blank-page bug).
[[]]
= { = "explorer.exe", = "ShellTabWindowClass" }
= "ignore"
# WinUI non-client input sink — invisible helper for pointer/pen routing,
# created by Explorer, Settings, Photos, and any WinUI 3 host. Never a real
# app window. (Same rationale as the DesktopWindowContentBridge rule above.)
[[]]
= { = "InputNonClientPointerSource" }
= "ignore"
# ── Task Manager ────────────────────────────────────────────────────
# Task Manager's main window — the real top-level surface the user interacts
# with. Float it so it stays where the user places it instead of entering the
# tiling layout. Scoped to its class so the auxiliary helper windows below do
# not also match this rule.
[[]]
= { = "Taskmgr.exe", = "TaskManagerWindow" }
= "float"
# Task Manager auxiliary helper windows. The WinUI Task Manager (Taskmgr.exe)
# creates several internal surfaces besides its main window: an acrylic
# backdrop ("Glass Window", class GlassWindow), a "Filter Control Glass
# Window", and a "TaskManagerMain" native HWND host (class NativeHWNDHost).
# Each passes flow's visibility/Alt+Tab/owner gates — they are top-level,
# titled, and owner-less — yet none is a window the user would want floated or
# tiled. Without these rules every helper registers as Floating and gets its
# own border overlay + a 180ms animation when Task Manager opens. Scoped to exe
# so a legitimate app reusing one of these classes is unaffected.
[[]]
= { = "Taskmgr.exe", = "GlassWindow" }
= "ignore"
[[]]
= { = "Taskmgr.exe", = "FilterControlGlassWindow" }
= "ignore"
[[]]
= { = "Taskmgr.exe", = "NativeHWNDHost" }
= "ignore"
# ── Accessibility ───────────────────────────────────────────────────
# On-Screen Keyboard
[[]]
= { = "OSKMainClass" }
= "ignore"
# Magnifier
[[]]
= { = "Magnify.exe" }
= "ignore"
# Narrator
[[]]
= { = "Narrator.exe" }
= "ignore"
# ── Custom Apps ───────────────────────────────────────────────────
[[]]
= { = "Surfshark.exe" }
= "float"
[[]]
= { = "Addictive Keys.exe" }
= "float"
[[]]
= { = "steamwebhelper.exe", = "Friends List" }
= "float"
# ── Powertoys ───────────────────────────────────────────────────
[[]]
= { = "Microsoft.CmdPal.UI.exe" }
= "float"
# ── Chromium-based apps (Chrome, Edge, VS Code, Electron, ...) ──────
# Chromium "Legacy Window" — an invisible helper (class
# `Chrome_RenderWidgetHostHWND`, title "Chrome Legacy Window") created by every
# Chromium-based host: Chrome, Edge, VS Code (Electron), Slack, Discord, etc.
#
# It passes the Win32 pre-filters (WS_VISIBLE, non-empty title, no owner, not
# DWM-cloaked) yet is never shown to the user, so it must be ignored.
#
# Why match by `class` instead of `exe` + `title`?
# - `exe` differs per host (chrome.exe vs Code.exe vs msedge.exe ...), so an
# exe-constrained rule only ever catches one app. The class name is identical
# across all of them, so a single rule covers every Chromium host.
# - The class is assigned at window creation, while the title may be set a few
# milliseconds later. Class matching is therefore race-free; title matching
# can miss a window classified at creation time before its title arrives.
#
# This also kills the layout/animation churn caused by the transient legacy
# windows that Chrome spawns and destroys whenever a tab is opened or closed —
# ignored windows never enter the tiling layout, so no recalculation fires.
[[]]
= { = "Chrome_RenderWidgetHostHWND" }
= "ignore"
# ── Chrome.exe ──────
# Chrome picture-in-picture overlay — keep it floating.
[[]]
= { = "chrome.exe", = "Picture in picture" }
= "float"
# Chrome auxiliary toolbar window. chrome.exe creates a top-level window titled
# "ToolbarWindow32" — the name of the predefined Win32 comctl32 toolbar control
# class. It passes every pre-filter gate (visible, titled, Alt+Tab visible, no
# owner, not minimized) yet is an invisible helper, not a browser surface, so
# without this rule it registers as Floating and gets a border overlay.
#
# Why scope to `exe`? `ToolbarWindow32` is a universal control class name: any
# legacy Win32 app using a standard comctl32 toolbar produces a window whose
# text/class is "ToolbarWindow32". Matching on the title alone would catch
# legitimate toolbar controls in other apps, so the rule is confined to
# chrome.exe to target only Chrome's helper and leave other apps untouched.
[[]]
= { = "chrome.exe", = "ToolbarWindow32" }
= "ignore"
# ── WindowsTerminal.exe ──────
# For Windows Terminal on git commit / Create Git Worktree
[[]]
= "float"
[]
= "WindowsTerminal.exe"
= "CASCADIA_HOSTING_WINDOW_CLASS"