Actions
Improvements #14330
openImprove initial layout and position of WDialog
Status:
New
Priority:
Normal
Assignee:
-
Target version:
-
Start date:
02/12/2026
Due date:
% Done:
0%
Estimated time:
Description
Affected: WT 4.12.2 and former versions (checked down to 4.11.4)
STR:
- run attached
main.cppwithreload-is-new-session = false - open http://127.0.0.1:8080
--> result:
WDialogis not restricted to the height of the viewport.- There are no scrollbars in order to access the whole dialog.
- The dialog does not use the available width in order to display more of the
WTableView.
STR:
- press
Escape - click button "Popup"
--> result:
- The dialog pops up at a different position (centered).
- The title bar is inaccessible.
STR:
- reload the browser tab
--> The dialog is positioned as on first show.
Improvements:
a. limit WDialog to viewport
b. use available width (and height)
c. popup the dialog at the same position
The workaround by setting min/max size of widgets is inflexible and too restrictive.
Files
Updated by Michael Seibt 3 days ago
For limiting to viewport (improvement "a."), a workaround like the one below is still needed with both Wt 4.13.1 and the current HEAD commit 5118c5e.
It works for 'show()' and both overloads of 'positionAt()'.
It also fixes that the WDialog is located behind the header cells of a WTableView on positionAt(tbl->itemWidget(...)) - regardless of its z-index.
void WDialog::ensureFullyVisible()
{
setMaximumSize(WLength{100, LengthUnit::ViewportWidth}, WLength{100, LengthUnit::ViewportHeight});
doJavaScript
( "(function() {"
"const dlg = " + jsRef() + ";"
"const resize = new ResizeObserver(entries => {"
"if (!dlg || !dlg.checkVisibility()) return;"
"for (const entry of entries) {" // The 'for (...)' can be omitted.
"const bounds = dlg.getBoundingClientRect();"
"const viewport = Wt.WT.windowSize();"
"const x = Math.max(0, Math.min(bounds.left, viewport.x - bounds.width ));"
"const y = Math.max(0, Math.min(bounds.top, viewport.y - bounds.height));"
//"console.log('dialog resized:', entry.contentRect.width, entry.contentRect.height, bounds, viewport, x, y, dlg.style.position);"
"dlg.style.position = 'fixed';"
"dlg.style.left = x + 'px';"
"dlg.style.top = y + 'px';"
"}"
"});"
"resize.observe(dlg);"
"})();"
);
}
Actions