Fix menu positioning on monitors with negative coordinates - #834

Open
MissinLinkk05551 wants to merge 1 commit into
moudey:mainfrom
MissinLinkk05551:fix-stacked-monitor-coordinates
Open

Fix menu positioning on monitors with negative coordinates#834
MissinLinkk05551 wants to merge 1 commit into
moudey:mainfrom
MissinLinkk05551:fix-stacked-monitor-coordinates

Conversation

@MissinLinkk05551

Copy link
Copy Markdown

Summary

Fixes context-menu and tooltip positioning on monitors that use negative virtual-screen coordinates, such as a secondary monitor positioned above or to the left of the primary monitor.

Problem

Some positioning calculations treated monitor coordinates as though every monitor started at (0, 0).

For example, a scrolling menu was vertically centered with:

wp->y = (ctx->_rcMonitor.height() - wnd->height) / 2;

That works only when the monitor begins at Y=0.

On a monitor positioned above the primary display, such as:

top = -900
bottom = 0

the calculation produces a positive Y coordinate, which can place the menu on the primary monitor instead of the monitor where it was invoked.

Tooltip boundary checks also treated any negative X or Y value as invalid, even though negative coordinates are valid within the Windows virtual desktop.

Changes

  • Include _rcMonitor.top when vertically centering scrolling menus.
  • Compare the menu bottom against _rcMonitor.bottom instead of monitor height.
  • Clamp tooltip X against _rcMonitor.left instead of global zero.
  • Clamp tooltip Y against _rcMonitor.top instead of global zero.

Testing

Tested on Windows 11 Pro 25H2 build 26200.8875 with two monitors at 100% scaling:

Primary: X=0, Y=0, 1366x768
Secondary: X=0, Y=-900, 1440x900

Before this change, with the secondary monitor stacked above the primary monitor, the context menu opened on the primary monitor.

After this change, the context menu opens on the correct monitor where it was invoked.

The project was built successfully using:

Release|x64

with zero build errors.

Related issues

Related to #774 and #692.

TCNOco added a commit to TCNOco/Shell that referenced this pull request Aug 16, 2026
moudey#834 (MissinLinkk05551) - menu and tooltip positioning on monitors with
negative virtual-screen coordinates. _rcMonitor holds true virtual-screen
coordinates, but the tooltip clamped its left and top against literal 0
while the right edge, two lines below, already clamped against
_rcMonitor.right; and the scrolling-popup path assigned Rect::height() -
a size - straight into WINDOWPOS::y, an absolute coordinate. A display
stacked above the primary has a negative top, which is what put menus on
the wrong monitor. Both are no-ops when the monitor's origin is (0,0),
so single-monitor setups are unaffected.
The PR's third hunk is not taken. It rewrites the condition of an
else-if whose body is entirely commented out, so it changes nothing,
and it would leave the adjacent inert branch using height() where this
one uses bottom - which reads like a surviving bug. Both are commented
where they are, with a note that they are inert.
moudey#831 (xiaobsh) - docs had sys.datetime's y and Y swapped. Confirmed
against string::TimeFormat: 'Y' is wYear % 100 and 'y' is %04u, so the
page had them backwards. While there, the same block gave the time
separator as '.' for sys.datetime, sys.datetime.short and
sys.datetime.time, where the format strings use ':'.
moudey#811 (ironsand) - the uninstall instructions named unst000.exe and
unstall.exe. Nothing in the repo has ever produced either; the
installer is a WiX MSI that registers an Add or Remove Programs entry.
The replacement names this fork's entry and install folder rather than
upstream's, which the PR's own wording would have kept wrong.
The winget and Chocolatey sections further down that page still
describe upstream's packages, which this fork does not publish. Left
alone deliberately - what to do about them is a distribution decision,
not a documentation fix.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for freeto 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.

1 participant

@MissinLinkk05551
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Fix menu positioning on monitors with negative coordinates - #834

Open
MissinLinkk05551 wants to merge 1 commit into
moudey:mainfrom
MissinLinkk05551:fix-stacked-monitor-coordinates
Open

Fix menu positioning on monitors with negative coordinates#834
MissinLinkk05551 wants to merge 1 commit into
moudey:mainfrom
MissinLinkk05551:fix-stacked-monitor-coordinates

Conversation

@MissinLinkk05551

Copy link
Copy Markdown

Summary

Fixes context-menu and tooltip positioning on monitors that use negative virtual-screen coordinates, such as a secondary monitor positioned above or to the left of the primary monitor.

Problem

Some positioning calculations treated monitor coordinates as though every monitor started at (0, 0).

For example, a scrolling menu was vertically centered with:

wp->y = (ctx->_rcMonitor.height() - wnd->height) / 2;

That works only when the monitor begins at Y=0.

On a monitor positioned above the primary display, such as:

top = -900
bottom = 0

the calculation produces a positive Y coordinate, which can place the menu on the primary monitor instead of the monitor where it was invoked.

Tooltip boundary checks also treated any negative X or Y value as invalid, even though negative coordinates are valid within the Windows virtual desktop.

Changes

  • Include _rcMonitor.top when vertically centering scrolling menus.
  • Compare the menu bottom against _rcMonitor.bottom instead of monitor height.
  • Clamp tooltip X against _rcMonitor.left instead of global zero.
  • Clamp tooltip Y against _rcMonitor.top instead of global zero.

Testing

Tested on Windows 11 Pro 25H2 build 26200.8875 with two monitors at 100% scaling:

Primary: X=0, Y=0, 1366x768
Secondary: X=0, Y=-900, 1440x900

Before this change, with the secondary monitor stacked above the primary monitor, the context menu opened on the primary monitor.

After this change, the context menu opens on the correct monitor where it was invoked.

The project was built successfully using:

Release|x64

with zero build errors.

Related issues

Related to #774 and #692.

TCNOco added a commit to TCNOco/Shell that referenced this pull request Aug 16, 2026
moudey#834 (MissinLinkk05551) - menu and tooltip positioning on monitors with
negative virtual-screen coordinates. _rcMonitor holds true virtual-screen
coordinates, but the tooltip clamped its left and top against literal 0
while the right edge, two lines below, already clamped against
_rcMonitor.right; and the scrolling-popup path assigned Rect::height() -
a size - straight into WINDOWPOS::y, an absolute coordinate. A display
stacked above the primary has a negative top, which is what put menus on
the wrong monitor. Both are no-ops when the monitor's origin is (0,0),
so single-monitor setups are unaffected.
The PR's third hunk is not taken. It rewrites the condition of an
else-if whose body is entirely commented out, so it changes nothing,
and it would leave the adjacent inert branch using height() where this
one uses bottom - which reads like a surviving bug. Both are commented
where they are, with a note that they are inert.
moudey#831 (xiaobsh) - docs had sys.datetime's y and Y swapped. Confirmed
against string::TimeFormat: 'Y' is wYear % 100 and 'y' is %04u, so the
page had them backwards. While there, the same block gave the time
separator as '.' for sys.datetime, sys.datetime.short and
sys.datetime.time, where the format strings use ':'.
moudey#811 (ironsand) - the uninstall instructions named unst000.exe and
unstall.exe. Nothing in the repo has ever produced either; the
installer is a WiX MSI that registers an Add or Remove Programs entry.
The replacement names this fork's entry and install folder rather than
upstream's, which the PR's own wording would have kept wrong.
The winget and Chocolatey sections further down that page still
describe upstream's packages, which this fork does not publish. Left
alone deliberately - what to do about them is a distribution decision,
not a documentation fix.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for freeto 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.

1 participant

@MissinLinkk05551
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Fix menu positioning on monitors with negative coordinates - #834

Open
MissinLinkk05551 wants to merge 1 commit into
moudey:mainfrom
MissinLinkk05551:fix-stacked-monitor-coordinates
Open

Fix menu positioning on monitors with negative coordinates#834
MissinLinkk05551 wants to merge 1 commit into
moudey:mainfrom
MissinLinkk05551:fix-stacked-monitor-coordinates

Conversation

@MissinLinkk05551

Copy link
Copy Markdown

Summary

Fixes context-menu and tooltip positioning on monitors that use negative virtual-screen coordinates, such as a secondary monitor positioned above or to the left of the primary monitor.

Problem

Some positioning calculations treated monitor coordinates as though every monitor started at (0, 0).

For example, a scrolling menu was vertically centered with:

wp->y = (ctx->_rcMonitor.height() - wnd->height) / 2;

That works only when the monitor begins at Y=0.

On a monitor positioned above the primary display, such as:

top = -900
bottom = 0

the calculation produces a positive Y coordinate, which can place the menu on the primary monitor instead of the monitor where it was invoked.

Tooltip boundary checks also treated any negative X or Y value as invalid, even though negative coordinates are valid within the Windows virtual desktop.

Changes

  • Include _rcMonitor.top when vertically centering scrolling menus.
  • Compare the menu bottom against _rcMonitor.bottom instead of monitor height.
  • Clamp tooltip X against _rcMonitor.left instead of global zero.
  • Clamp tooltip Y against _rcMonitor.top instead of global zero.

Testing

Tested on Windows 11 Pro 25H2 build 26200.8875 with two monitors at 100% scaling:

Primary: X=0, Y=0, 1366x768
Secondary: X=0, Y=-900, 1440x900

Before this change, with the secondary monitor stacked above the primary monitor, the context menu opened on the primary monitor.

After this change, the context menu opens on the correct monitor where it was invoked.

The project was built successfully using:

Release|x64

with zero build errors.

Related issues

Related to #774 and #692.

TCNOco added a commit to TCNOco/Shell that referenced this pull request Aug 16, 2026
moudey#834 (MissinLinkk05551) - menu and tooltip positioning on monitors with
negative virtual-screen coordinates. _rcMonitor holds true virtual-screen
coordinates, but the tooltip clamped its left and top against literal 0
while the right edge, two lines below, already clamped against
_rcMonitor.right; and the scrolling-popup path assigned Rect::height() -
a size - straight into WINDOWPOS::y, an absolute coordinate. A display
stacked above the primary has a negative top, which is what put menus on
the wrong monitor. Both are no-ops when the monitor's origin is (0,0),
so single-monitor setups are unaffected.
The PR's third hunk is not taken. It rewrites the condition of an
else-if whose body is entirely commented out, so it changes nothing,
and it would leave the adjacent inert branch using height() where this
one uses bottom - which reads like a surviving bug. Both are commented
where they are, with a note that they are inert.
moudey#831 (xiaobsh) - docs had sys.datetime's y and Y swapped. Confirmed
against string::TimeFormat: 'Y' is wYear % 100 and 'y' is %04u, so the
page had them backwards. While there, the same block gave the time
separator as '.' for sys.datetime, sys.datetime.short and
sys.datetime.time, where the format strings use ':'.
moudey#811 (ironsand) - the uninstall instructions named unst000.exe and
unstall.exe. Nothing in the repo has ever produced either; the
installer is a WiX MSI that registers an Add or Remove Programs entry.
The replacement names this fork's entry and install folder rather than
upstream's, which the PR's own wording would have kept wrong.
The winget and Chocolatey sections further down that page still
describe upstream's packages, which this fork does not publish. Left
alone deliberately - what to do about them is a distribution decision,
not a documentation fix.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for freeto 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.

1 participant

@MissinLinkk05551
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Fix menu positioning on monitors with negative coordinates - #834

Open
MissinLinkk05551 wants to merge 1 commit into
moudey:mainfrom
MissinLinkk05551:fix-stacked-monitor-coordinates
Open

Fix menu positioning on monitors with negative coordinates#834
MissinLinkk05551 wants to merge 1 commit into
moudey:mainfrom
MissinLinkk05551:fix-stacked-monitor-coordinates

Conversation

@MissinLinkk05551

Copy link
Copy Markdown

Summary

Fixes context-menu and tooltip positioning on monitors that use negative virtual-screen coordinates, such as a secondary monitor positioned above or to the left of the primary monitor.

Problem

Some positioning calculations treated monitor coordinates as though every monitor started at (0, 0).

For example, a scrolling menu was vertically centered with:

wp->y = (ctx->_rcMonitor.height() - wnd->height) / 2;

That works only when the monitor begins at Y=0.

On a monitor positioned above the primary display, such as:

top = -900
bottom = 0

the calculation produces a positive Y coordinate, which can place the menu on the primary monitor instead of the monitor where it was invoked.

Tooltip boundary checks also treated any negative X or Y value as invalid, even though negative coordinates are valid within the Windows virtual desktop.

Changes

  • Include _rcMonitor.top when vertically centering scrolling menus.
  • Compare the menu bottom against _rcMonitor.bottom instead of monitor height.
  • Clamp tooltip X against _rcMonitor.left instead of global zero.
  • Clamp tooltip Y against _rcMonitor.top instead of global zero.

Testing

Tested on Windows 11 Pro 25H2 build 26200.8875 with two monitors at 100% scaling:

Primary: X=0, Y=0, 1366x768
Secondary: X=0, Y=-900, 1440x900

Before this change, with the secondary monitor stacked above the primary monitor, the context menu opened on the primary monitor.

After this change, the context menu opens on the correct monitor where it was invoked.

The project was built successfully using:

Release|x64

with zero build errors.

Related issues

Related to #774 and #692.

TCNOco added a commit to TCNOco/Shell that referenced this pull request Aug 16, 2026
moudey#834 (MissinLinkk05551) - menu and tooltip positioning on monitors with
negative virtual-screen coordinates. _rcMonitor holds true virtual-screen
coordinates, but the tooltip clamped its left and top against literal 0
while the right edge, two lines below, already clamped against
_rcMonitor.right; and the scrolling-popup path assigned Rect::height() -
a size - straight into WINDOWPOS::y, an absolute coordinate. A display
stacked above the primary has a negative top, which is what put menus on
the wrong monitor. Both are no-ops when the monitor's origin is (0,0),
so single-monitor setups are unaffected.
The PR's third hunk is not taken. It rewrites the condition of an
else-if whose body is entirely commented out, so it changes nothing,
and it would leave the adjacent inert branch using height() where this
one uses bottom - which reads like a surviving bug. Both are commented
where they are, with a note that they are inert.
moudey#831 (xiaobsh) - docs had sys.datetime's y and Y swapped. Confirmed
against string::TimeFormat: 'Y' is wYear % 100 and 'y' is %04u, so the
page had them backwards. While there, the same block gave the time
separator as '.' for sys.datetime, sys.datetime.short and
sys.datetime.time, where the format strings use ':'.
moudey#811 (ironsand) - the uninstall instructions named unst000.exe and
unstall.exe. Nothing in the repo has ever produced either; the
installer is a WiX MSI that registers an Add or Remove Programs entry.
The replacement names this fork's entry and install folder rather than
upstream's, which the PR's own wording would have kept wrong.
The winget and Chocolatey sections further down that page still
describe upstream's packages, which this fork does not publish. Left
alone deliberately - what to do about them is a distribution decision,
not a documentation fix.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for freeto 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.

1 participant

@MissinLinkk05551
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Fix menu positioning on monitors with negative coordinates - #834

Open
MissinLinkk05551 wants to merge 1 commit into
moudey:mainfrom
MissinLinkk05551:fix-stacked-monitor-coordinates
Open

Fix menu positioning on monitors with negative coordinates#834
MissinLinkk05551 wants to merge 1 commit into
moudey:mainfrom
MissinLinkk05551:fix-stacked-monitor-coordinates

Conversation

@MissinLinkk05551

Copy link
Copy Markdown

Summary

Fixes context-menu and tooltip positioning on monitors that use negative virtual-screen coordinates, such as a secondary monitor positioned above or to the left of the primary monitor.

Problem

Some positioning calculations treated monitor coordinates as though every monitor started at (0, 0).

For example, a scrolling menu was vertically centered with:

wp->y = (ctx->_rcMonitor.height() - wnd->height) / 2;

That works only when the monitor begins at Y=0.

On a monitor positioned above the primary display, such as:

top = -900
bottom = 0

the calculation produces a positive Y coordinate, which can place the menu on the primary monitor instead of the monitor where it was invoked.

Tooltip boundary checks also treated any negative X or Y value as invalid, even though negative coordinates are valid within the Windows virtual desktop.

Changes

  • Include _rcMonitor.top when vertically centering scrolling menus.
  • Compare the menu bottom against _rcMonitor.bottom instead of monitor height.
  • Clamp tooltip X against _rcMonitor.left instead of global zero.
  • Clamp tooltip Y against _rcMonitor.top instead of global zero.

Testing

Tested on Windows 11 Pro 25H2 build 26200.8875 with two monitors at 100% scaling:

Primary: X=0, Y=0, 1366x768
Secondary: X=0, Y=-900, 1440x900

Before this change, with the secondary monitor stacked above the primary monitor, the context menu opened on the primary monitor.

After this change, the context menu opens on the correct monitor where it was invoked.

The project was built successfully using:

Release|x64

with zero build errors.

Related issues

Related to #774 and #692.

TCNOco added a commit to TCNOco/Shell that referenced this pull request Aug 16, 2026
moudey#834 (MissinLinkk05551) - menu and tooltip positioning on monitors with
negative virtual-screen coordinates. _rcMonitor holds true virtual-screen
coordinates, but the tooltip clamped its left and top against literal 0
while the right edge, two lines below, already clamped against
_rcMonitor.right; and the scrolling-popup path assigned Rect::height() -
a size - straight into WINDOWPOS::y, an absolute coordinate. A display
stacked above the primary has a negative top, which is what put menus on
the wrong monitor. Both are no-ops when the monitor's origin is (0,0),
so single-monitor setups are unaffected.
The PR's third hunk is not taken. It rewrites the condition of an
else-if whose body is entirely commented out, so it changes nothing,
and it would leave the adjacent inert branch using height() where this
one uses bottom - which reads like a surviving bug. Both are commented
where they are, with a note that they are inert.
moudey#831 (xiaobsh) - docs had sys.datetime's y and Y swapped. Confirmed
against string::TimeFormat: 'Y' is wYear % 100 and 'y' is %04u, so the
page had them backwards. While there, the same block gave the time
separator as '.' for sys.datetime, sys.datetime.short and
sys.datetime.time, where the format strings use ':'.
moudey#811 (ironsand) - the uninstall instructions named unst000.exe and
unstall.exe. Nothing in the repo has ever produced either; the
installer is a WiX MSI that registers an Add or Remove Programs entry.
The replacement names this fork's entry and install folder rather than
upstream's, which the PR's own wording would have kept wrong.
The winget and Chocolatey sections further down that page still
describe upstream's packages, which this fork does not publish. Left
alone deliberately - what to do about them is a distribution decision,
not a documentation fix.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for freeto 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.

1 participant

@MissinLinkk05551
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Fix menu positioning on monitors with negative coordinates - #834

Open
MissinLinkk05551 wants to merge 1 commit into
moudey:mainfrom
MissinLinkk05551:fix-stacked-monitor-coordinates
Open

Fix menu positioning on monitors with negative coordinates#834
MissinLinkk05551 wants to merge 1 commit into
moudey:mainfrom
MissinLinkk05551:fix-stacked-monitor-coordinates

Conversation

@MissinLinkk05551

Copy link
Copy Markdown

Summary

Fixes context-menu and tooltip positioning on monitors that use negative virtual-screen coordinates, such as a secondary monitor positioned above or to the left of the primary monitor.

Problem

Some positioning calculations treated monitor coordinates as though every monitor started at (0, 0).

For example, a scrolling menu was vertically centered with:

wp->y = (ctx->_rcMonitor.height() - wnd->height) / 2;

That works only when the monitor begins at Y=0.

On a monitor positioned above the primary display, such as:

top = -900
bottom = 0

the calculation produces a positive Y coordinate, which can place the menu on the primary monitor instead of the monitor where it was invoked.

Tooltip boundary checks also treated any negative X or Y value as invalid, even though negative coordinates are valid within the Windows virtual desktop.

Changes

  • Include _rcMonitor.top when vertically centering scrolling menus.
  • Compare the menu bottom against _rcMonitor.bottom instead of monitor height.
  • Clamp tooltip X against _rcMonitor.left instead of global zero.
  • Clamp tooltip Y against _rcMonitor.top instead of global zero.

Testing

Tested on Windows 11 Pro 25H2 build 26200.8875 with two monitors at 100% scaling:

Primary: X=0, Y=0, 1366x768
Secondary: X=0, Y=-900, 1440x900

Before this change, with the secondary monitor stacked above the primary monitor, the context menu opened on the primary monitor.

After this change, the context menu opens on the correct monitor where it was invoked.

The project was built successfully using:

Release|x64

with zero build errors.

Related issues

Related to #774 and #692.

TCNOco added a commit to TCNOco/Shell that referenced this pull request Aug 16, 2026
moudey#834 (MissinLinkk05551) - menu and tooltip positioning on monitors with
negative virtual-screen coordinates. _rcMonitor holds true virtual-screen
coordinates, but the tooltip clamped its left and top against literal 0
while the right edge, two lines below, already clamped against
_rcMonitor.right; and the scrolling-popup path assigned Rect::height() -
a size - straight into WINDOWPOS::y, an absolute coordinate. A display
stacked above the primary has a negative top, which is what put menus on
the wrong monitor. Both are no-ops when the monitor's origin is (0,0),
so single-monitor setups are unaffected.
The PR's third hunk is not taken. It rewrites the condition of an
else-if whose body is entirely commented out, so it changes nothing,
and it would leave the adjacent inert branch using height() where this
one uses bottom - which reads like a surviving bug. Both are commented
where they are, with a note that they are inert.
moudey#831 (xiaobsh) - docs had sys.datetime's y and Y swapped. Confirmed
against string::TimeFormat: 'Y' is wYear % 100 and 'y' is %04u, so the
page had them backwards. While there, the same block gave the time
separator as '.' for sys.datetime, sys.datetime.short and
sys.datetime.time, where the format strings use ':'.
moudey#811 (ironsand) - the uninstall instructions named unst000.exe and
unstall.exe. Nothing in the repo has ever produced either; the
installer is a WiX MSI that registers an Add or Remove Programs entry.
The replacement names this fork's entry and install folder rather than
upstream's, which the PR's own wording would have kept wrong.
The winget and Chocolatey sections further down that page still
describe upstream's packages, which this fork does not publish. Left
alone deliberately - what to do about them is a distribution decision,
not a documentation fix.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for freeto 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.

1 participant

@MissinLinkk05551
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Fix menu positioning on monitors with negative coordinates - #834

Open
MissinLinkk05551 wants to merge 1 commit into
moudey:mainfrom
MissinLinkk05551:fix-stacked-monitor-coordinates
Open

Fix menu positioning on monitors with negative coordinates#834
MissinLinkk05551 wants to merge 1 commit into
moudey:mainfrom
MissinLinkk05551:fix-stacked-monitor-coordinates

Conversation

@MissinLinkk05551

Copy link
Copy Markdown

Summary

Fixes context-menu and tooltip positioning on monitors that use negative virtual-screen coordinates, such as a secondary monitor positioned above or to the left of the primary monitor.

Problem

Some positioning calculations treated monitor coordinates as though every monitor started at (0, 0).

For example, a scrolling menu was vertically centered with:

wp->y = (ctx->_rcMonitor.height() - wnd->height) / 2;

That works only when the monitor begins at Y=0.

On a monitor positioned above the primary display, such as:

top = -900
bottom = 0

the calculation produces a positive Y coordinate, which can place the menu on the primary monitor instead of the monitor where it was invoked.

Tooltip boundary checks also treated any negative X or Y value as invalid, even though negative coordinates are valid within the Windows virtual desktop.

Changes

  • Include _rcMonitor.top when vertically centering scrolling menus.
  • Compare the menu bottom against _rcMonitor.bottom instead of monitor height.
  • Clamp tooltip X against _rcMonitor.left instead of global zero.
  • Clamp tooltip Y against _rcMonitor.top instead of global zero.

Testing

Tested on Windows 11 Pro 25H2 build 26200.8875 with two monitors at 100% scaling:

Primary: X=0, Y=0, 1366x768
Secondary: X=0, Y=-900, 1440x900

Before this change, with the secondary monitor stacked above the primary monitor, the context menu opened on the primary monitor.

After this change, the context menu opens on the correct monitor where it was invoked.

The project was built successfully using:

Release|x64

with zero build errors.

Related issues

Related to #774 and #692.

TCNOco added a commit to TCNOco/Shell that referenced this pull request Aug 16, 2026
moudey#834 (MissinLinkk05551) - menu and tooltip positioning on monitors with
negative virtual-screen coordinates. _rcMonitor holds true virtual-screen
coordinates, but the tooltip clamped its left and top against literal 0
while the right edge, two lines below, already clamped against
_rcMonitor.right; and the scrolling-popup path assigned Rect::height() -
a size - straight into WINDOWPOS::y, an absolute coordinate. A display
stacked above the primary has a negative top, which is what put menus on
the wrong monitor. Both are no-ops when the monitor's origin is (0,0),
so single-monitor setups are unaffected.
The PR's third hunk is not taken. It rewrites the condition of an
else-if whose body is entirely commented out, so it changes nothing,
and it would leave the adjacent inert branch using height() where this
one uses bottom - which reads like a surviving bug. Both are commented
where they are, with a note that they are inert.
moudey#831 (xiaobsh) - docs had sys.datetime's y and Y swapped. Confirmed
against string::TimeFormat: 'Y' is wYear % 100 and 'y' is %04u, so the
page had them backwards. While there, the same block gave the time
separator as '.' for sys.datetime, sys.datetime.short and
sys.datetime.time, where the format strings use ':'.
moudey#811 (ironsand) - the uninstall instructions named unst000.exe and
unstall.exe. Nothing in the repo has ever produced either; the
installer is a WiX MSI that registers an Add or Remove Programs entry.
The replacement names this fork's entry and install folder rather than
upstream's, which the PR's own wording would have kept wrong.
The winget and Chocolatey sections further down that page still
describe upstream's packages, which this fork does not publish. Left
alone deliberately - what to do about them is a distribution decision,
not a documentation fix.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for freeto 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.

1 participant

@MissinLinkk05551
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Fix menu positioning on monitors with negative coordinates - #834

Open
MissinLinkk05551 wants to merge 1 commit into
moudey:mainfrom
MissinLinkk05551:fix-stacked-monitor-coordinates
Open

Fix menu positioning on monitors with negative coordinates#834
MissinLinkk05551 wants to merge 1 commit into
moudey:mainfrom
MissinLinkk05551:fix-stacked-monitor-coordinates

Conversation

@MissinLinkk05551

Copy link
Copy Markdown

Summary

Fixes context-menu and tooltip positioning on monitors that use negative virtual-screen coordinates, such as a secondary monitor positioned above or to the left of the primary monitor.

Problem

Some positioning calculations treated monitor coordinates as though every monitor started at (0, 0).

For example, a scrolling menu was vertically centered with:

wp->y = (ctx->_rcMonitor.height() - wnd->height) / 2;

That works only when the monitor begins at Y=0.

On a monitor positioned above the primary display, such as:

top = -900
bottom = 0

the calculation produces a positive Y coordinate, which can place the menu on the primary monitor instead of the monitor where it was invoked.

Tooltip boundary checks also treated any negative X or Y value as invalid, even though negative coordinates are valid within the Windows virtual desktop.

Changes

  • Include _rcMonitor.top when vertically centering scrolling menus.
  • Compare the menu bottom against _rcMonitor.bottom instead of monitor height.
  • Clamp tooltip X against _rcMonitor.left instead of global zero.
  • Clamp tooltip Y against _rcMonitor.top instead of global zero.

Testing

Tested on Windows 11 Pro 25H2 build 26200.8875 with two monitors at 100% scaling:

Primary: X=0, Y=0, 1366x768
Secondary: X=0, Y=-900, 1440x900

Before this change, with the secondary monitor stacked above the primary monitor, the context menu opened on the primary monitor.

After this change, the context menu opens on the correct monitor where it was invoked.

The project was built successfully using:

Release|x64

with zero build errors.

Related issues

Related to #774 and #692.

TCNOco added a commit to TCNOco/Shell that referenced this pull request Aug 16, 2026
moudey#834 (MissinLinkk05551) - menu and tooltip positioning on monitors with
negative virtual-screen coordinates. _rcMonitor holds true virtual-screen
coordinates, but the tooltip clamped its left and top against literal 0
while the right edge, two lines below, already clamped against
_rcMonitor.right; and the scrolling-popup path assigned Rect::height() -
a size - straight into WINDOWPOS::y, an absolute coordinate. A display
stacked above the primary has a negative top, which is what put menus on
the wrong monitor. Both are no-ops when the monitor's origin is (0,0),
so single-monitor setups are unaffected.
The PR's third hunk is not taken. It rewrites the condition of an
else-if whose body is entirely commented out, so it changes nothing,
and it would leave the adjacent inert branch using height() where this
one uses bottom - which reads like a surviving bug. Both are commented
where they are, with a note that they are inert.
moudey#831 (xiaobsh) - docs had sys.datetime's y and Y swapped. Confirmed
against string::TimeFormat: 'Y' is wYear % 100 and 'y' is %04u, so the
page had them backwards. While there, the same block gave the time
separator as '.' for sys.datetime, sys.datetime.short and
sys.datetime.time, where the format strings use ':'.
moudey#811 (ironsand) - the uninstall instructions named unst000.exe and
unstall.exe. Nothing in the repo has ever produced either; the
installer is a WiX MSI that registers an Add or Remove Programs entry.
The replacement names this fork's entry and install folder rather than
upstream's, which the PR's own wording would have kept wrong.
The winget and Chocolatey sections further down that page still
describe upstream's packages, which this fork does not publish. Left
alone deliberately - what to do about them is a distribution decision,
not a documentation fix.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for freeto 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.

1 participant

@MissinLinkk05551