diff --git a/docs/configuration/profiles.md b/docs/configuration/profiles.md
index 380a2aded0..220f314425 100644
--- a/docs/configuration/profiles.md
+++ b/docs/configuration/profiles.md
@@ -119,6 +119,19 @@ profiles:
maximized: false
```
+### `margins`
+
+Enforces a horizontal and vertical margin to respect on both sides of the terminal.
+This is particularily useful on operating systems (like MacOS) that draw the border frame into the main widgets space,
+or simply to create some artificial space to improve the user's focus.
+
+```yaml
+profiles:
+ profile_name:
+ margins:
+ horizontal: 5
+ vertical: 0
+```
### `bell`
diff --git a/metainfo.xml b/metainfo.xml
index e25b78ea89..def97a2ba7 100644
--- a/metainfo.xml
+++ b/metainfo.xml
@@ -111,6 +111,7 @@
Changes VT sequence `DECSCUSR` (`CSI ? 0 SP q` and `CSI ? SP q`) to reset to user-configured cursor style (#1377).
Remove `contour-latest` terminfo file. Please use `contour` terminfo instead.
Adds `Command` as modifier to input mappings on MacOS to work along with `Meta` for convenience reasons (#1379).
+ Adds config option `profiles.*.margins` to allow customizing the horizontal / vertical margins (#1384).
diff --git a/src/contour/Config.cpp b/src/contour/Config.cpp
index aa0788b698..b587793f59 100644
--- a/src/contour/Config.cpp
+++ b/src/contour/Config.cpp
@@ -1555,6 +1555,11 @@ namespace
else
logger()("Invalid Terminal ID \"{}\", specified", strValue);
+ tryLoadChildRelative(
+ usedKeys, profile, basePath, "margins.horizontal", terminalProfile.margins.horizontal, logger);
+ tryLoadChildRelative(
+ usedKeys, profile, basePath, "margins.vertical", terminalProfile.margins.vertical, logger);
+
tryLoadChildRelative(usedKeys,
profile,
basePath,
diff --git a/src/contour/Config.h b/src/contour/Config.h
index 3c3e4e1eaa..d1354e2bff 100644
--- a/src/contour/Config.h
+++ b/src/contour/Config.h
@@ -161,6 +161,15 @@ struct TerminalProfile
std::string wmClass;
+ // Horizontal and vertical margins in pixels.
+ //
+ // Important, DPI is not yet applied to these values.
+ struct WindowMargins
+ {
+ unsigned horizontal = 0;
+ unsigned vertical = 0;
+ } margins;
+
vtbackend::PageSize terminalSize = { vtbackend::LineCount(10), vtbackend::ColumnCount(40) };
vtbackend::VTType terminalId = vtbackend::VTType::VT525;
@@ -407,4 +416,16 @@ struct fmt::formatter
return fmt::format_to(ctx.out(), "{}", static_cast(value));
}
};
+
+template <>
+struct fmt::formatter: public fmt::formatter
+{
+ using WindowMargins = contour::config::TerminalProfile::WindowMargins;
+ auto format(WindowMargins margins, format_context& ctx) -> format_context::iterator
+ {
+ return formatter::format(fmt::format("{}x+{}y", margins.horizontal, margins.vertical),
+ ctx);
+ }
+};
+
// }}}
diff --git a/src/contour/TerminalSession.cpp b/src/contour/TerminalSession.cpp
index 1f6550e04a..06b5f66f88 100644
--- a/src/contour/TerminalSession.cpp
+++ b/src/contour/TerminalSession.cpp
@@ -696,10 +696,10 @@ void TerminalSession::requestWindowResize(LineCount lines, ColumnCount columns)
_display->post([this, lines, columns]() { _display->resizeWindow(lines, columns); });
}
-void TerminalSession::requestWindowResize(QJSValue w, QJSValue h)
+void TerminalSession::adaptToWidgetSize()
{
- requestWindowResize(Width::cast_from(w.toNumber() * contentScale()),
- Height::cast_from(h.toNumber() * contentScale()));
+ if (_display)
+ _display->post([this]() { _display->adaptToWidgetSize(); });
}
void TerminalSession::requestWindowResize(Width width, Height height)
@@ -1493,13 +1493,8 @@ void TerminalSession::configureDisplay()
_display->toggleFullScreen();
_terminal.setRefreshRate(_display->refreshRate());
- auto const pageSize = PageSize {
- LineCount(unbox(_display->pixelSize().height) / unbox(_display->cellSize().height)),
- ColumnCount(unbox(_display->pixelSize().width) / unbox(_display->cellSize().width)),
- };
- _display->setPageSize(pageSize);
_display->setFonts(_profile.fonts);
- // TODO: maybe update margin after this call?
+ adaptToWidgetSize();
_display->setHyperlinkDecoration(_profile.hyperlinkDecoration.normal, _profile.hyperlinkDecoration.hover);
diff --git a/src/contour/TerminalSession.h b/src/contour/TerminalSession.h
index 6a1050a0db..a1ce9289da 100644
--- a/src/contour/TerminalSession.h
+++ b/src/contour/TerminalSession.h
@@ -215,7 +215,7 @@ class TerminalSession: public QAbstractItemModel, public vtbackend::Terminal::Ev
Q_INVOKABLE void applyPendingFontChange(bool answer, bool remember);
Q_INVOKABLE void executePendingBufferCapture(bool answer, bool remember);
Q_INVOKABLE void executeShowHostWritableStatusLine(bool answer, bool remember);
- Q_INVOKABLE void requestWindowResize(QJSValue w, QJSValue h);
+ Q_INVOKABLE void adaptToWidgetSize();
void updateColorPreference(vtbackend::ColorPreference preference);
diff --git a/src/contour/contour.yml b/src/contour/contour.yml
index 843d115b68..85e2530eef 100644
--- a/src/contour/contour.yml
+++ b/src/contour/contour.yml
@@ -291,6 +291,16 @@ profiles:
columns: 80
lines: 25
+ # Window margins
+ #
+ # The margin values are applied on both sides and are given in pixels
+ # with DPI yet to be applied to these values.
+ margins:
+ # Horizontal (left/right) margins.
+ horizontal: 5
+ # Vertical (top/bottom) margins.
+ vertical: 5
+
history:
# Number of lines to preserve (-1 for infinite).
limit: 1000
diff --git a/src/contour/display/TerminalDisplay.cpp b/src/contour/display/TerminalDisplay.cpp
index 367ef2cdf9..ce0499fa30 100644
--- a/src/contour/display/TerminalDisplay.cpp
+++ b/src/contour/display/TerminalDisplay.cpp
@@ -330,9 +330,9 @@ void TerminalDisplay::sizeChanged()
auto const qtBaseDisplaySize =
vtbackend::ImageSize { Width::cast_from(width()), Height::cast_from(height()) };
- auto const newPixelSize = qtBaseDisplaySize * contentScale();
- displayLog()("Resizing view to {}x{} virtual ({} actual).", width(), height(), newPixelSize);
- applyResize(newPixelSize, *_session, *_renderer);
+ auto const actualPixelSize = qtBaseDisplaySize * contentScale();
+ displayLog()("Resizing view to {}x{} virtual ({} actual).", width(), height(), actualPixelSize);
+ applyResize(actualPixelSize, *_session, *_renderer);
}
void TerminalDisplay::handleWindowChanged(QQuickWindow* newWindow)
@@ -444,7 +444,8 @@ void TerminalDisplay::applyFontDPI()
if (!_renderTarget)
return;
- auto const newPixelSize = vtbackend::ImageSize { Width::cast_from(width()), Height::cast_from(height()) };
+ auto const newPixelSize =
+ vtbackend::ImageSize { Width::cast_from(width()), Height::cast_from(height()) } * contentScale();
// Apply resize on same window metrics propagates proper recalculations and repaint.
applyResize(newPixelSize, *_session, *_renderer);
@@ -615,9 +616,9 @@ void TerminalDisplay::createRenderer()
{
auto const qtBaseDisplaySize =
ImageSize { vtbackend::Width::cast_from(width()), vtbackend::Height::cast_from(height()) };
- _renderer->setMargin(computeMargin(gridMetrics().cellSize, pageSize(), qtBaseDisplaySize));
- // resize widget (same pixels, but adjusted terminal rows/columns and margin)
+
auto const actualDisplaySize = qtBaseDisplaySize * contentScale();
+
applyResize(actualDisplaySize, *_session, *_renderer);
}
// }}}
@@ -940,34 +941,48 @@ double TerminalDisplay::contentScale() const
return window()->devicePixelRatio();
}
+/// Computes the required size of the widget to fit the given terminal size.
+///
+/// @param terminalSize the terminal size in rows and columns
+/// @param cellSize the size of a single cell in pixels (with content scale already applied)
+constexpr ImageSize computeRequiredSize(config::TerminalProfile::WindowMargins margins,
+ ImageSize cellSize,
+ PageSize totalPageSize) noexcept
+{
+ // We multiply by 2 because the margins are applied to both sides of the terminal.
+ auto const marginSize = ImageSize { vtbackend::Width::cast_from(margins.horizontal * 2),
+ vtbackend::Height::cast_from(margins.vertical * 2) };
+
+ return (cellSize * totalPageSize + marginSize);
+}
+
void TerminalDisplay::updateImplicitSize()
{
assert(_renderer);
assert(_session);
assert(window());
- // implicit width/height
- auto const dpr = contentScale();
- auto const implicitViewSize = _renderer->cellSize() * _session->terminal().totalPageSize() * (1.0 / dpr);
- setImplicitWidth(unbox(implicitViewSize.width));
- setImplicitHeight(unbox(implicitViewSize.height));
+ auto const requiredSize = computeRequiredSize(_session->profile().margins,
+ _renderer->cellSize() * (1.0 / contentScale()),
+ _session->terminal().totalPageSize());
+
+ fmt::print("updateImplicitSize: {}, margin {}\n", requiredSize, _session->profile().margins);
+
+ setImplicitWidth(unbox(requiredSize.width));
+ setImplicitHeight(unbox(requiredSize.height));
}
void TerminalDisplay::updateMinimumSize()
{
+ Require(window());
Require(_renderer);
assert(_session);
- Require(window());
-
- // minimum size
- auto constexpr MinimumGridSize = PageSize { LineCount(5), ColumnCount(10) };
- auto const minSize =
- ImageSize { Width::cast_from(unbox(gridMetrics().cellSize.width) * *MinimumGridSize.columns),
- Height::cast_from(unbox(gridMetrics().cellSize.width) * *MinimumGridSize.lines) };
- auto const scaledMinSize = minSize / contentScale();
+ auto constexpr MinimumTotalPageSize = PageSize { LineCount(5), ColumnCount(10) };
+ auto const minimumSize = computeRequiredSize(
+ _session->profile().margins, _renderer->cellSize() * (1.0 / contentScale()), MinimumTotalPageSize);
- window()->setMinimumSize(QSize(scaledMinSize.width.as(), scaledMinSize.height.as()));
+ window()->setMinimumSize(QSize(unbox(minimumSize.width), unbox(minimumSize.height)));
}
// }}}
@@ -1136,6 +1151,18 @@ void TerminalDisplay::notify(std::string_view /*_title*/, std::string_view /*_bo
// TODO: showNotification callback to Controller?
}
+void TerminalDisplay::adaptToWidgetSize()
+{
+ // Resize widget (same pixels, but adjusted terminal rows/columns and margin)
+ Require(_renderer != nullptr);
+ Require(_session != nullptr);
+
+ auto const qtBaseDisplaySize =
+ ImageSize { vtbackend::Width::cast_from(width()), vtbackend::Height::cast_from(height()) };
+ auto const actualDisplaySize = qtBaseDisplaySize * contentScale();
+ applyResize(actualDisplaySize, *_session, *_renderer);
+}
+
void TerminalDisplay::resizeWindow(vtbackend::Width newWidth, vtbackend::Height newHeight)
{
Require(_session != nullptr);
@@ -1146,26 +1173,7 @@ void TerminalDisplay::resizeWindow(vtbackend::Width newWidth, vtbackend::Height
return;
}
- auto const pixelsAvailable =
- vtbackend::ImageSize { vtbackend::Width::cast_from(*newWidth ? *newWidth : (unsigned) width()),
- vtbackend::Height::cast_from(*newHeight ? *newHeight : (unsigned) height()) };
-
- auto const newPageSize =
- PageSize { .lines = vtbackend::LineCount(unbox(pixelsAvailable.height)
- / unbox(gridMetrics().cellSize.height)),
- .columns = vtbackend::ColumnCount(unbox(pixelsAvailable.width)
- / unbox(gridMetrics().cellSize.width)) };
-
- auto const newPixelsUsed = vtbackend::ImageSize {
- vtbackend::Width::cast_from(unbox(newPageSize.columns) * unbox(gridMetrics().cellSize.width)),
- vtbackend::Height::cast_from(unbox(newPageSize.lines) * unbox(gridMetrics().cellSize.height))
- };
-
- // setSizePolicy(QSizePolicy::Policy::Fixed, QSizePolicy::Policy::Fixed);
- const_cast(profile()).terminalSize = newPageSize;
- _renderer->setPageSize(newPageSize);
- auto const l = scoped_lock { terminal() };
- terminal().resizeScreen(newPageSize, newPixelsUsed);
+ applyResize(vtbackend::ImageSize { newWidth, newHeight }, *_session, *_renderer);
}
void TerminalDisplay::resizeWindow(vtbackend::LineCount newLineCount, vtbackend::ColumnCount newColumnCount)
@@ -1195,12 +1203,7 @@ void TerminalDisplay::setFonts(vtrasterizer::FontDescriptions fontDescriptions)
Require(_session != nullptr);
Require(_renderTarget != nullptr);
- if (applyFontDescription(gridMetrics().cellSize,
- pageSize(),
- pixelSize(),
- fontDPI(),
- *_renderer,
- std::move(fontDescriptions)))
+ if (applyFontDescription(fontDPI(), *_renderer, std::move(fontDescriptions)))
{
// resize widget (same pixels, but adjusted terminal rows/columns and margin)
applyResize(pixelSize(), *_session, *_renderer);
@@ -1210,20 +1213,14 @@ void TerminalDisplay::setFonts(vtrasterizer::FontDescriptions fontDescriptions)
bool TerminalDisplay::setFontSize(text::font_size newFontSize)
{
- Require(_session != nullptr);
- Require(_renderTarget != nullptr);
+ Require(_renderer != nullptr);
displayLog()("Setting display font size and recompute metrics: {}pt", newFontSize.pt);
if (!_renderer->setFontSize(newFontSize))
return false;
- auto const qtBaseDisplaySize =
- ImageSize { vtbackend::Width::cast_from(width()), vtbackend::Height::cast_from(height()) };
- _renderer->setMargin(computeMargin(gridMetrics().cellSize, pageSize(), qtBaseDisplaySize));
- // resize widget (same pixels, but adjusted terminal rows/columns and margin)
- auto const actualDisplaySize = qtBaseDisplaySize * contentScale();
- applyResize(actualDisplaySize, *_session, *_renderer);
+ adaptToWidgetSize();
updateMinimumSize();
// logDisplayInfo();
return true;
diff --git a/src/contour/display/TerminalDisplay.h b/src/contour/display/TerminalDisplay.h
index 7b46ec7003..3a420bdde5 100644
--- a/src/contour/display/TerminalDisplay.h
+++ b/src/contour/display/TerminalDisplay.h
@@ -124,6 +124,9 @@ class TerminalDisplay: public QQuickItem
[[nodiscard]] vtbackend::ImageSize pixelSize() const;
[[nodiscard]] vtbackend::ImageSize cellSize() const;
+ // general events
+ void adaptToWidgetSize();
+
// (user requested) actions
vtbackend::FontDef getFontDef();
static void copyToClipboard(std::string_view /*_data*/);
@@ -212,10 +215,17 @@ class TerminalDisplay: public QQuickItem
void watchKdeDpiSetting();
[[nodiscard]] float uptime() const noexcept;
- [[nodiscard]] vtbackend::PageSize pageSize() const
+ [[nodiscard]] vtbackend::PageSize calculatePageSize() const
{
assert(_renderer);
- return pageSizeForPixels(pixelSize(), _renderer->gridMetrics().cellSize);
+ assert(_session);
+
+ // auto const availablePixels = gridMetrics().cellSize * _session->terminal().pageSize();
+ auto const availablePixels = vtbackend::ImageSize { vtbackend::Width::cast_from(width()),
+ vtbackend::Height::cast_from(height()) };
+ return pageSizeForPixels(availablePixels,
+ _renderer->gridMetrics().cellSize,
+ applyContentScale(_session->profile().margins, _session->contentScale()));
}
void updateMinimumSize();
diff --git a/src/contour/helper.cpp b/src/contour/helper.cpp
index f9182dd471..3b4122b44c 100644
--- a/src/contour/helper.cpp
+++ b/src/contour/helper.cpp
@@ -54,59 +54,68 @@ namespace
{
vtbackend::CellLocation makeMouseCellLocation(int x, int y, TerminalSession const& session) noexcept
{
- auto constexpr MarginTop = 0;
- auto constexpr MarginLeft = 0;
-
auto const pageSize = session.terminal().totalPageSize();
auto const cellSize = session.display()->cellSize();
auto const dpr = session.contentScale();
+ auto const marginTop = static_cast(session.profile().margins.vertical * dpr);
+ auto const marginLeft = static_cast(session.profile().margins.horizontal * dpr);
+
auto const sx = int(double(x) * dpr);
auto const sy = int(double(y) * dpr);
auto const row = vtbackend::LineOffset(
- clamp((sy - MarginTop) / cellSize.height.as(), 0, *pageSize.lines - 1));
+ clamp((sy - marginTop) / cellSize.height.as(), 0, *pageSize.lines - 1));
auto const col = vtbackend::ColumnOffset(
- clamp((sx - MarginLeft) / cellSize.width.as(), 0, *pageSize.columns - 1));
+ clamp((sx - marginLeft) / cellSize.width.as(), 0, *pageSize.columns - 1));
return { row, col };
}
- PixelCoordinate makeMousePixelPosition(QHoverEvent* event, double dpr) noexcept
+ PixelCoordinate makeMousePixelPosition(QHoverEvent* event,
+ config::TerminalProfile::WindowMargins margins,
+ double dpr) noexcept
{
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
auto const position = event->position();
#else
auto const position = event->pos();
#endif
- // TODO: apply margin once supported
- return PixelCoordinate { PixelCoordinate::X { int(double(position.x()) * dpr) },
- PixelCoordinate::Y { int(double(position.y()) * dpr) } };
+ auto const marginLeft = static_cast(margins.horizontal * dpr);
+ auto const marginTop = static_cast(margins.vertical * dpr);
+ return PixelCoordinate { PixelCoordinate::X { int(double(position.x()) * dpr) - marginLeft },
+ PixelCoordinate::Y { int(double(position.y()) * dpr) - marginTop } };
}
- PixelCoordinate makeMousePixelPosition(QMouseEvent* event, double dpr) noexcept
+ PixelCoordinate makeMousePixelPosition(QMouseEvent* event,
+ config::TerminalProfile::WindowMargins margins,
+ double dpr) noexcept
{
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
auto const position = event->position();
#else
auto const position = QPointF { static_cast(event->x()), static_cast(event->y()) };
#endif
- // TODO: apply margin once supported
- return PixelCoordinate { PixelCoordinate::X { int(double(position.x()) * dpr) },
- PixelCoordinate::Y { int(double(position.y()) * dpr) } };
+ auto const marginLeft = static_cast(margins.horizontal * dpr);
+ auto const marginTop = static_cast(margins.vertical * dpr);
+ return PixelCoordinate { PixelCoordinate::X { int(double(position.x()) * dpr) - marginLeft },
+ PixelCoordinate::Y { int(double(position.y()) * dpr) - marginTop } };
}
- PixelCoordinate makeMousePixelPosition(QWheelEvent* event, double dpr) noexcept
+ PixelCoordinate makeMousePixelPosition(QWheelEvent* event,
+ config::TerminalProfile::WindowMargins margins,
+ double dpr) noexcept
{
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
auto const position = event->position();
#else
auto const position = event->posF();
#endif
- // TODO: apply margin once supported
- return PixelCoordinate { PixelCoordinate::X { int(double(position.x()) * dpr) },
- PixelCoordinate::Y { int(double(position.y()) * dpr) } };
+ auto const marginLeft = static_cast(margins.horizontal * dpr);
+ auto const marginTop = static_cast(margins.vertical * dpr);
+ return PixelCoordinate { PixelCoordinate::X { int(double(position.x()) * dpr) - marginLeft },
+ PixelCoordinate::Y { int(double(position.y()) * dpr) - marginTop } };
}
int mouseWheelDelta(QWheelEvent* event) noexcept
@@ -423,7 +432,8 @@ void sendWheelEvent(QWheelEvent* event, TerminalSession& session)
{
auto const modifier = makeModifiers(event->modifiers());
auto const button = xDelta > 0 ? VTMouseButton::WheelRight : VTMouseButton::WheelLeft;
- auto const pixelPosition = makeMousePixelPosition(event, session.contentScale());
+ auto const pixelPosition =
+ makeMousePixelPosition(event, session.profile().margins, session.contentScale());
session.sendMousePressEvent(modifier, button, pixelPosition);
event->accept();
@@ -434,7 +444,8 @@ void sendWheelEvent(QWheelEvent* event, TerminalSession& session)
{
auto const modifier = makeModifiers(event->modifiers());
auto const button = yDelta > 0 ? VTMouseButton::WheelUp : VTMouseButton::WheelDown;
- auto const pixelPosition = makeMousePixelPosition(event, session.contentScale());
+ auto const pixelPosition =
+ makeMousePixelPosition(event, session.profile().margins, session.contentScale());
session.sendMousePressEvent(modifier, button, pixelPosition);
event->accept();
@@ -443,25 +454,28 @@ void sendWheelEvent(QWheelEvent* event, TerminalSession& session)
void sendMousePressEvent(QMouseEvent* event, TerminalSession& session)
{
- session.sendMousePressEvent(makeModifiers(event->modifiers()),
- makeMouseButton(event->button()),
- makeMousePixelPosition(event, session.contentScale()));
+ session.sendMousePressEvent(
+ makeModifiers(event->modifiers()),
+ makeMouseButton(event->button()),
+ makeMousePixelPosition(event, session.profile().margins, session.contentScale()));
event->accept();
}
void sendMouseReleaseEvent(QMouseEvent* event, TerminalSession& session)
{
- session.sendMouseReleaseEvent(makeModifiers(event->modifiers()),
- makeMouseButton(event->button()),
- makeMousePixelPosition(event, session.contentScale()));
+ session.sendMouseReleaseEvent(
+ makeModifiers(event->modifiers()),
+ makeMouseButton(event->button()),
+ makeMousePixelPosition(event, session.profile().margins, session.contentScale()));
event->accept();
}
void sendMouseMoveEvent(QMouseEvent* event, TerminalSession& session)
{
- session.sendMouseMoveEvent(makeModifiers(event->modifiers()),
- makeMouseCellLocation(event->pos().x(), event->pos().y(), session),
- makeMousePixelPosition(event, session.contentScale()));
+ session.sendMouseMoveEvent(
+ makeModifiers(event->modifiers()),
+ makeMouseCellLocation(event->pos().x(), event->pos().y(), session),
+ makeMousePixelPosition(event, session.profile().margins, session.contentScale()));
event->accept();
}
@@ -472,9 +486,10 @@ void sendMouseMoveEvent(QHoverEvent* event, TerminalSession& session)
#else
auto const position = event->pos();
#endif
- session.sendMouseMoveEvent(makeModifiers(event->modifiers()),
- makeMouseCellLocation(position.x(), position.y(), session),
- makeMousePixelPosition(event, session.contentScale()));
+ session.sendMouseMoveEvent(
+ makeModifiers(event->modifiers()),
+ makeMouseCellLocation(position.x(), position.y(), session),
+ makeMousePixelPosition(event, session.profile().margins, session.contentScale()));
event->accept();
}
@@ -541,18 +556,19 @@ vtbackend::FontDef getFontDefinition(vtrasterizer::Renderer& renderer)
renderer.fontDescriptions().emoji.toPattern() };
}
-vtrasterizer::PageMargin computeMargin(ImageSize cellSize, PageSize charCells, ImageSize pixels) noexcept
+vtrasterizer::PageMargin computeMargin(ImageSize cellSize,
+ PageSize charCells,
+ ImageSize displaySize,
+ config::TerminalProfile::WindowMargins minimumMargins) noexcept
{
auto const usedHeight = unbox(charCells.lines) * unbox(cellSize.height);
- auto const freeHeight = unbox(pixels.height) - usedHeight;
- auto const bottomMargin = freeHeight;
- auto const topMargin = 0;
- // auto const usedWidth = charCells.columns * regularFont_.maxAdvance();
- // auto const freeWidth = pixels.width - usedWidth;
- auto constexpr LeftMargin = 0;
+ auto const topMargin = static_cast(minimumMargins.vertical);
+ auto const bottomMargin = static_cast(
+ std::min(unbox(displaySize.height) - usedHeight - topMargin, minimumMargins.vertical));
+ auto const leftMargin = static_cast(minimumMargins.horizontal);
- return { LeftMargin, topMargin, static_cast(bottomMargin) };
+ return { .left = leftMargin, .top = topMargin, .bottom = bottomMargin };
}
vtrasterizer::FontDescriptions sanitizeFontDescription(vtrasterizer::FontDescriptions fonts, text::DPI dpi)
@@ -564,20 +580,14 @@ vtrasterizer::FontDescriptions sanitizeFontDescription(vtrasterizer::FontDescrip
return fonts;
}
-bool applyFontDescription(ImageSize cellSize,
- PageSize pageSize,
- ImageSize pixelSize,
- text::DPI dpi,
+bool applyFontDescription(text::DPI dpi,
vtrasterizer::Renderer& renderer,
vtrasterizer::FontDescriptions fontDescriptions)
{
if (renderer.fontDescriptions() == fontDescriptions)
return false;
- auto const windowMargin = computeMargin(cellSize, pageSize, pixelSize);
-
renderer.setFonts(sanitizeFontDescription(std::move(fontDescriptions), dpi));
- renderer.setMargin(windowMargin);
renderer.updateFontMetrics();
return true;
@@ -591,14 +601,20 @@ void applyResize(vtbackend::ImageSize newPixelSize,
return;
auto const oldPageSize = session.terminal().pageSize();
- auto const newPageSize = pageSizeForPixels(newPixelSize, renderer.gridMetrics().cellSize);
+ auto const newPageSize =
+ pageSizeForPixels(newPixelSize,
+ renderer.gridMetrics().cellSize,
+ applyContentScale(session.profile().margins, session.contentScale()));
vtbackend::Terminal& terminal = session.terminal();
vtbackend::ImageSize cellSize = renderer.gridMetrics().cellSize;
Require(renderer.hasRenderTarget());
renderer.renderTarget().setRenderSize(newPixelSize);
renderer.setPageSize(newPageSize);
- renderer.setMargin(computeMargin(renderer.gridMetrics().cellSize, newPageSize, newPixelSize));
+ renderer.setMargin(computeMargin(renderer.gridMetrics().cellSize,
+ newPageSize,
+ newPixelSize,
+ applyContentScale(session.profile().margins, session.contentScale())));
if (oldPageSize.lines != newPageSize.lines)
emit session.lineCountChanged(newPageSize.lines.as());
@@ -607,9 +623,10 @@ void applyResize(vtbackend::ImageSize newPixelSize,
emit session.columnsCountChanged(newPageSize.columns.as());
auto const viewSize = cellSize * newPageSize;
- displayLog()("Applying resize {}/{} pixels and {} -> {} cells.",
+ displayLog()("Applying resize {}/{} pixels (margins {}) and {} -> {} cells.",
viewSize,
newPixelSize,
+ session.profile().margins,
terminal.pageSize(),
newPageSize);
diff --git a/src/contour/helper.h b/src/contour/helper.h
index eccda069d5..9f8be91b87 100644
--- a/src/contour/helper.h
+++ b/src/contour/helper.h
@@ -167,28 +167,49 @@ void spawnNewTerminal(std::string const& programPath,
vtbackend::FontDef getFontDefinition(vtrasterizer::Renderer& renderer);
+constexpr config::TerminalProfile::WindowMargins applyContentScale(
+ config::TerminalProfile::WindowMargins margins, double contentScale) noexcept
+{
+ return { .horizontal = static_cast(margins.horizontal * contentScale),
+ .vertical = static_cast(margins.vertical * contentScale) };
+}
+
vtrasterizer::PageMargin computeMargin(vtbackend::ImageSize cellSize,
vtbackend::PageSize charCells,
- vtbackend::ImageSize pixels) noexcept;
+ vtbackend::ImageSize displaySize,
+ config::TerminalProfile::WindowMargins minimumMargins) noexcept;
vtrasterizer::FontDescriptions sanitizeFontDescription(vtrasterizer::FontDescriptions fonts,
text::DPI screenDPI);
-constexpr vtbackend::PageSize pageSizeForPixels(vtbackend::ImageSize viewSize,
- vtbackend::ImageSize cellSize) noexcept
+constexpr vtbackend::PageSize pageSizeForPixels(vtbackend::ImageSize totalViewSize,
+ vtbackend::ImageSize cellSize,
+ config::TerminalProfile::WindowMargins margins)
{
- return vtbackend::PageSize { boxed_cast((viewSize / cellSize).height),
- boxed_cast((viewSize / cellSize).width) };
+ // NB: Multiplied by 2, because margins are applied on both sides of the terminal.
+ auto const marginSize = vtbackend::ImageSize { vtbackend::Width::cast_from(2 * margins.horizontal),
+ vtbackend::Height::cast_from(2 * margins.vertical) };
+
+ auto const usableViewSize = totalViewSize - marginSize;
+
+ auto const result =
+ vtbackend::PageSize { boxed_cast((usableViewSize / cellSize).height),
+ boxed_cast((usableViewSize / cellSize).width) };
+
+ fmt::print("calculatePageSize: totalViewSize: {}, cellSize: {}, margins: {}, usable: {}, result: {}\n",
+ totalViewSize,
+ cellSize,
+ marginSize,
+ usableViewSize,
+ result);
+ return result;
}
void applyResize(vtbackend::ImageSize newPixelSize,
TerminalSession& session,
vtrasterizer::Renderer& renderer);
-bool applyFontDescription(vtbackend::ImageSize cellSize,
- vtbackend::PageSize pageSize,
- vtbackend::ImageSize pixelSize,
- text::DPI dpi,
+bool applyFontDescription(text::DPI dpi,
vtrasterizer::Renderer& renderer,
vtrasterizer::FontDescriptions fontDescriptions);
diff --git a/src/contour/ui.template/main.qml.in b/src/contour/ui.template/main.qml.in
index e4309a8d68..6c57faaf80 100644
--- a/src/contour/ui.template/main.qml.in
+++ b/src/contour/ui.template/main.qml.in
@@ -38,13 +38,13 @@ ApplicationWindow
onWidthChanged : function() {
vtui.width = width
- vtui.session.requestWindowResize(width, height)
+ vtui.session.adaptToWidgetSize()
vtui.updateSizeWidget()
}
onHeightChanged: function() {
vtui.height = height
- vtui.session.requestWindowResize(width, height)
+ vtui.session.adaptToWidgetSize()
vtui.updateSizeWidget()
}