Skip to content

Add Vertical OmniButton mod#3859

Open
sb4ssman wants to merge 11 commits into
ramensoftware:mainfrom
sb4ssman:sb4ssman-vertical-omnibutton
Open

Add Vertical OmniButton mod#3859
sb4ssman wants to merge 11 commits into
ramensoftware:mainfrom
sb4ssman:sb4ssman-vertical-omnibutton

Conversation

@sb4ssman

@sb4ssman sb4ssman commented Apr 22, 2026

Copy link
Copy Markdown
Contributor

Adds the Vertical OmniButton mod — stacks the Windows 11 system tray OmniButton (wifi / volume / battery) vertically using Taskbar.View.dll symbol hooks and GetTaskbarXamlRoot.

What's in v1.2

Simplified and cleaned up from the initial submission:

  • No registry writes — the mod never touches TaskbarBatteryPercent. All three battery percentage modes (Off / Inline / Stacked) switch live with no explorer restart.
  • Off mode hides the percentage text via a XAML TranslateTransform offset rather than toggling a registry value. Users keep battery percentage enabled in Windows; Off mode simply nudges the text off-screen.
  • New settings offPercentX / offPercentY let users tune exactly how far off-screen the hidden text is pushed (useful for non-standard themes where it might bleed in).
  • Fixed a bug where Off mode was incorrectly flipping the battery inner StackPanel orientation, causing the battery glyph to render wrong. Now only the text element is offset.
  • Fixed the deferred (LayoutUpdated) code path to apply the battery slot position offset in Off mode.
  • Removed dead RestoreOmniButtonHeight function.
  • Consistent battery percentage language across embedded readme, YAML settings, and README.

Updated mod description and version for Windows 10 and 11 compatibility. Added Windows version enumeration and improved taskbar handling for both Windows versions.
Rearranges the Windows 11 system tray OmniButton (wifi/volume/battery) from horizontal to vertical stacking using the Windows XAML Diagnostics API.
Comment thread mods/vertical-omnibutton.wh.cpp Outdated
Comment thread mods/vertical-omnibutton.wh.cpp Outdated
sb4ssman and others added 5 commits April 27, 2026 08:42
- Remove clock layout feature (moved to style.yaml)
- Remove auxiliary settings (restartExplorer, enableVertical, debugLogging, dumpOmniTree, openBatterySettings)
- Simplify Wh_ModSettingsChanged to use CleanupXamlElements + re-traverse
- Add defaults note to Battery percentage description
- Update readme to remove stale setting references

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add // Taskbar.View.dll and // taskbar.dll comments above each
WindhawkUtils::SYMBOL_HOOK hooks[] declaration as required by
ramensoftware/windhawk-mods PR validation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
offWifiX/Y, offVolumeX/Y, offBatteryX/Y
inlineWifiX/Y, inlineVolumeX/Y, inlineBatteryX/Y, inlinePercentX/Y
stackedWifiX/Y, stackedVolumeX/Y, stackedBatteryX/Y, stackedPercentX/Y

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Background thread retries ApplyAllSettings up to 5 times (2s apart)
after mod init, covering the race where the XAML tree isn't ready
when explorer first loads the mod on startup.
- Remove registry writes entirely; mod never touches TaskbarBatteryPercent
- Off mode now hides % text via XAML offset instead of registry, so all
  three modes switch live with no explorer restart required
- Add per-mode offsets for the hidden % text in Off mode (offPercentX/Y)
- Fix Off mode: stop flipping inner StackPanel orientation (was breaking
  glyph rendering); only push the text element off-screen with a transform
- Remove dead RestoreOmniButtonHeight function
- Fix deferred (LayoutUpdated) path for Off mode battery slot offset
- Sync battery % language across embedded readme, YAML, and README

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@sb4ssman

Copy link
Copy Markdown
Contributor Author

This version should be much more agreeable.

@sb4ssman sb4ssman requested a review from m417z April 28, 2026 22:56
@m417z

m417z commented May 2, 2026

Copy link
Copy Markdown
Member

I see that the code is similar to #3932 which I reviewed. Please apply my comments here too, let me know when it's ready for review.

Addresses review comments:
- GetSystemTrayModuleHandle(): tries SystemTray.dll (Win11 26200+),
  falls back to Taskbar.View.dll (skipped at version >=2604), then ExplorerExtensions.dll
- GetTaskbarXamlRoot: add #elif _M_ARM64 / #else #error arms
- Add -lversion; use WindhawkUtils::Wh_SetFunctionHookT

Also adds buttonHorizontalPadding setting, stoppable retry thread,
and inline mode auto-sizing so hover highlight matches content exactly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@sb4ssman

sb4ssman commented May 8, 2026

Copy link
Copy Markdown
Contributor Author

Updated to v1.4 with the review comments applied (same changes as #3932):

  • GetSystemTrayModuleHandle() pattern: tries SystemTray.dll first (Win11 26200+), falls back to Taskbar.View.dll (skipped at version ≥2604), then ExplorerExtensions.dll
  • GetTaskbarXamlRoot: added #elif defined(_M_ARM64) and #else #error arms
  • Added -lversion to compilerOptions; switched to WindhawkUtils::Wh_SetFunctionHookT

Also included since the last review:

  • buttonHorizontalPadding setting to control OmniButton width
  • Stoppable retry thread (no dangling thread handle on uninit)
  • Inline mode: button auto-sizes instead of fixed width, so the hover highlight matches the battery glyph + % text exactly

// Use default offset.
#else
#error "Unsupported architecture"
#endif

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (WaitForSingleObject(stopEvent, 2000) != WAIT_TIMEOUT) break;
if (g_omniStackPanel || g_unloading) break;
Wh_Log(L"[AfterInit] Retry %d — XAML not yet applied", i + 1);
ApplyAllSettingsOnWindowThread();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mod already hooks IconView::IconView, so why is this thread needed?


static void FlipBatteryLayout(FrameworkElement const& batteryCP) {
if (!WalkBatteryTree(batteryCP, 0))
Wh_Log(L"[Battery4] No inner StackPanel found (% may not be in tree yet)");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use %% to escape the % sign.

with the Windows 11 Taskbar Styler out of the box — no special settings required.

For basic vertical stacking without battery percentage, paste [style.yaml](https://github.com/sb4ssman/Windhawk-Vertical-OmniButton/blob/main/style.yaml)
into Windows 11 Taskbar Styler → Settings → Advanced.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
into Windows 11 Taskbar Styler → Settings → Advanced.
into Windows 11 Taskbar Styler → Settings → Textual mode.


iconView.Loaded([](IInspectable const&, RoutedEventArgs const&) {
if (!g_unloading && !g_omniStackPanel)
ApplyAllSettings();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unsubscribe after handling, otherwise the callback might be called again when the mod is unloaded, causing a crash. There's an example below, but if you prefer something simpler, allocate memory for the revoke token, assign it from iconView.Loaded, pass the pointer to the lambda, and unsubscribe when it's called.

g_autoRevokerList.emplace_back();
auto autoRevokerIt = g_autoRevokerList.end();
--autoRevokerIt;
*autoRevokerIt = iconView.Loaded(
winrt::auto_revoke_t{},
[autoRevokerIt](winrt::Windows::Foundation::IInspectable const& sender,
RoutedEventArgs const& e) {
Wh_Log(L">");
g_autoRevokerList.erase(autoRevokerIt);

@sb4ssman

Copy link
Copy Markdown
Contributor Author

@m417z Vertical-omnibutton was the first pass at this; in the interim I built a more comprehensive replacement (omnibutton-customizer) that covers vertical as one configuration of a full grid layout, adds per-element nudging, item reordering, and fill-order control among other details. I'd like to close this PR and submit omnibutton-customizer instead as the single OmniButton mod. Do you have any concerns with that, may I just close it and submit?

@m417z

m417z commented Jun 21, 2026

Copy link
Copy Markdown
Member

No concerns, go ahead. Alternatively, you can update this PR, whatever you prefer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants