Add Windows 11 Native Four Column Snap Layout mod - #5436
Conversation
Adds an extra native Windows 11 Snap Layout with four equal vertical columns
|
Thanks for the pull request! This repository uses a two-stage review: an AI review that you run yourself, followed by a human review. To get started, comment See the pull request review process for the full details. |
|
/ai-review |
Rename SnapLayout hook array to satisfy PR validation
Submission reviewNote: This review was done by Claude. Due to the amount of submissions, doing a fully manual review for each pull request is no longer feasible. Thank you for understanding. Remember: The AI reviewer can be wrong - it may misread code, flag correct code as broken, or suggest changes that make things worse. Treat its findings as suggestions to verify, not instructions to follow blindly. You're responsible for the code you submit, so if a finding doesn't hold up, say so instead of changing working code to satisfy it. Please address the following issues. The items in the collapsed sections are optional, so it's your call whether to address them. Nice, self-contained approach — cloning a native layout through the DLL's own vector helper (instead of memcpy-ing a struct with a 1. Hard-coded LoadLibraryExW(
L"C:\\WINDOWS\\SystemApps\\MicrosoftWindows.Client.Core_cw5n1h2txyewy\\SnapLayout.dll",
...The Windows directory is not always More importantly, force-loading a XAML component DLL into every HMODULE kernelBase = GetModuleHandleW(L"kernelbase.dll");
auto pLoadLibraryExW =
(decltype(&LoadLibraryExW))GetProcAddress(kernelBase, "LoadLibraryExW");
WindhawkUtils::SetFunctionHook(pLoadLibraryExW, LoadLibraryExW_Hook,
&LoadLibraryExW_Original);That also lets you drop 2. Hard-coded layout indices + if (count != kNativeLayoutCount || sourceIndex >= count) { return false; }
...
CloneAndAppendFourColumn(returnBuffer, 3) // snap bar
CloneAndAppendFourColumn(returnBuffer, 4) // flyoutWindows does not always offer the same six layouts in the same order — the set varies with the display's effective width and orientation (portrait/narrow displays get a reduced/different set), and it changes between builds. On any of those configurations You already have the predicate you need. Search for the source layout instead of hard-coding its position: bool CloneAndAppendFourColumn(RawVector* vec) {
if (!vec || !EmplaceLayout_Original) {
return false;
}
const SIZE_T count = GetVectorCount(vec, kSnapLayoutSize);
for (SIZE_T i = 0; i < count; i++) {
BYTE* source =
reinterpret_cast<BYTE*>(vec->first) + i * kSnapLayoutSize;
if (!IsExpectedSourceLayout(source)) {
continue;
}
void* newLayout = EmplaceLayout_Original(vec, source);
return newLayout && PatchToFourColumns(newLayout);
}
Wh_Log(L"No 2x2 four-zone source layout among %zu layouts", count);
return false;
}This makes the mod work across the full range of layout sets and builds, and it removes the snap-bar-vs-flyout index branching in 3. // This pass-through hook exists so Windhawk resolves the private vector helper
// and exposes a callable original/trampoline pointer.
void* __cdecl EmplaceLayout_Hook(void* vectorThis, const void* sourceLayout) {
return EmplaceLayout_Original(vectorThis, sourceLayout);
}
{
{LR"(private: struct SnapLayout & __cdecl std::vector<struct SnapLayout,class std::allocator<struct SnapLayout> >::_Emplace_one_at_back<struct SnapLayout const &>(struct SnapLayout const &))"},
&EmplaceLayout_Original,
nullptr, // Resolve only, no hook.
},and delete 4. The picker-height adjustment is latched and pinned to one magic number. if (hr == 0 && value && g_flyoutCustomAdded && *value == kNativePickerHeight) {
*value += kExtraPickerHeight;
}Two problems:
5. README has no screenshot. This is a purely visual mod — please add a screenshot or GIF of the Win+Z flyout with the four-column layout to the README. Only Optional improvements
Minor polish — none of this affects users, so it's your call.
Functionality notes
Non-critical observations and ideas about the feature behavior itself.
Next steps:
See the review process for details. |
Fix SnapLayout hook naming for PR validation
Fix SnapLayout hook naming for PR validation
Use x86-64 architecture metadata
Address AI review feedback and add readme screenshot
|
/ai-review |
Submission reviewNote: This review was done by Claude. Due to the amount of submissions, doing a fully manual review for each pull request is no longer feasible. Thank you for understanding. Remember: The AI reviewer can be wrong - it may misread code, flag correct code as broken, or suggest changes that make things worse. Treat its findings as suggestions to verify, not instructions to follow blindly. You're responsible for the code you submit, so if a finding doesn't hold up, say so instead of changing working code to satisfy it. Please address the following issues. The items in the collapsed sections are optional, so it's your call whether to address them. Overall this is careful work for a mod poking at undocumented structures: the source layout is validated before use, the clone is created with Picker height: the fixed Please verify the picker at 125% and 150% scaling and with the 6-layout picker. A version that sidesteps both the unit question and the layout count is to scale proportionally instead of adding a constant — record the layout count before/after in // In Layouts_Hook, before/after the CloneAndAppendFourColumn call:
g_flyoutLayoutsBefore = count; // layouts returned by Windows
g_flyoutLayoutsAfter = count + 1;
// In PickerHeight_Hook:
const int rowsBefore = (g_flyoutLayoutsBefore + kItemsPerRow - 1) / kItemsPerRow;
const int rowsAfter = (g_flyoutLayoutsAfter + kItemsPerRow - 1) / kItemsPerRow;
if (hr == 0 && value && rowsBefore > 0 && rowsAfter > rowsBefore) {
*value = MulDiv(*value, rowsAfter, rowsBefore);
}(That slightly over-adds the outer padding, but it's scale-independent and degrades gracefully.) Related: the adjustment also assumes Optional improvements
Minor polish — none of this affects users, so it's your call.
Functionality notes
Non-critical observations and ideas about the feature behavior itself.
Next steps:
See the review process for details. |
AI review improvements - Make picker height scaling-aware and refine review fixes
|
/ready-for-reviewer |
|
@Hoffelhas |
|
/ai-review |
Submission reviewNote: This review was done by Claude. Due to the amount of submissions, doing a fully manual review for each pull request is no longer feasible. Thank you for understanding. Remember: The AI reviewer can be wrong - it may misread code, flag correct code as broken, or suggest changes that make things worse. Treat its findings as suggestions to verify, not instructions to follow blindly. You're responsible for the code you submit, so if a finding doesn't hold up, say so instead of changing working code to satisfy it. Please address the following issues. The items in the collapsed sections are optional, so it's your call whether to address them. Nice, self-contained mod — no existing mod in the catalog touches 1. Symbol resolution is retried on every
if (!WindhawkUtils::HookSymbols(module, snapLayoutDllHooks,
ARRAYSIZE(snapLayoutDllHooks))) {
Wh_Log(L"Failed to resolve one or more SnapLayout.dll symbols");
g_snapLayoutHookClaimed = false; // <-- allows unlimited retries
return false;
}and Fix: treat a failed resolution as permanent — simply don't release the claim (or track it in a separate if (!WindhawkUtils::HookSymbols(module, snapLayoutDllHooks,
ARRAYSIZE(snapLayoutDllHooks))) {
Wh_Log(L"Failed to resolve one or more SnapLayout.dll symbols");
return false; // keep the claim: never retry for this module
}For reference, taskbar-icon-size.wh.cpp#L3097 claims the flag with 2. Consider making the layout configurable instead of hardcoding "four columns" Everything that makes this mod four-column-specific is two constants in Note that the zone count is bounded by Optional improvements
Minor polish — none of this affects users, so it's your call.
Functionality notes
Non-critical observations and ideas about the feature behavior itself.
Next steps:
See the review process for details. |
AI review - Prevent repeated SnapLayout symbol resolution after failure
|
/ai-review |
|
This pull request has already had 3 AI reviews in the last 24 hours, which is the limit, so no review was posted this time. Comment |
|
Hi @m417z, I want to go for ready-for-reviewer, but I need to do ai-review first. Would it please be possible to do that now instead of waiting? |
Submission reviewNote: This review was done by Claude. Due to the amount of submissions, doing a fully manual review for each pull request is no longer feasible. Thank you for understanding. Remember: The AI reviewer can be wrong - it may misread code, flag correct code as broken, or suggest changes that make things worse. Treat its findings as suggestions to verify, not instructions to follow blindly. You're responsible for the code you submit, so if a finding doesn't hold up, say so instead of changing working code to satisfy it. Please address the following issues. The items in the collapsed sections are optional, so it's your call whether to address them. The retry fix from the previous round is correct: the claim is now permanent, so a build where the private symbols don't resolve can no longer turn into repeated The "four columns" vs. "N columns" decision should be made before merge, because Everything that makes this mod four-column-specific is two constants in
A generalization that avoids the zone-allocation problem the previous review raised: instead of looking specifically for a 2×2 quadrant layout, search for a native layout that already has exactly N zones and rewrite it to N columns × 1 row. Depending on the build and monitor, Windows ships layouts with 2 and 3 zones alongside the 4-zone quadrant one, so N = 2..4 may need no new zone allocation at all — If it turns out that no native source layout with the right zone count exists on the builds you can test, or that the zone-vector growth symbol isn't available, that's a fine answer — please just say so in a pull request comment so the human reviewer sees the reasoning instead of an unaddressed finding. Optional improvements
Minor polish — none of this affects users, so it's your call. The first four were in the previous review and are repeated here so everything is in one place.
Functionality notes
Non-critical observations about the feature behavior itself. These are unchanged from the previous review — repeated in condensed form so the human reviewer has the full picture; several are things only you can confirm on a real machine.
Next steps:
See the review process for details. |
|
/ready-for-reviewer Regarding the suggestion to generalize the mod to N columns: I’d prefer to keep this submission intentionally focused on the missing four-column layout. Windows already provides native two- and three-column layouts, while supporting more than four columns or adding other formats would require additional reverse-engineering. Generalizing the implementation now would expand the scope and complexity of the mod without a demonstrated user need. If there is meaningful demand for arbitrary/custom column counts in the future, I think that would be better handled as a separate generalized mod. |
Windows 11 Native Four Column Snap Layout
Add an extra native Windows 11 Snap Layout with four equal vertical columns. This is especially useful on ultrawide monitors, where four equal vertical zones make better use of the available horizontal screen space.
What it does
existing Windows layouts.
when dragging a window to the top of the screen.
Groups continue to work normally.
Developed and tested on Windows 11 build 26200.9445 on x86-64.
Mod authorship
This mod was created by: