Skip to content

Feature request: Startup size specified in characters and snap size during window resize

Requesting the following features:

  1. Add a coreterminal setting to override the saved size with a fixed size on startup, specified in characters, not pixels. Window size in pixels can be computed from the patch below.

  2. Use the same character-pixel conversion formula to snap the window size to nearest character dimensions during resize events (as GTK terminals do)

The patch below correctly computes the window width and height for a 30 x 80 terminal and resizes the window on startup. It's tested on numerous fonts sizes and QT styles. It should be easy to adapt to any terminal size taken from CoreGarage settings (within reason).

I think the snap function can be easily done by inverting this formula to go from pixels to nearest character rows and cols, e.g.

cols = (width - qApp->style()->pixelMetric(QStyle::PM_ScrollBarExtent) - 2) / fm.averageCharWidth()

Code it to round or truncate rows and cols to nearest integer and apply the forward formula and resize() below to cause the snap.

Thanks!

--- coreterminal.cpp.orig       2021-07-31 03:36:34 UTC
+++ coreterminal.cpp
@@ -27,6 +27,7 @@
     *
 */
 
+#include <iostream>
 #include <QWidget>
 #include <QCloseEvent>
 #include <QHBoxLayout>
@@ -34,6 +35,8 @@
 #include <QDir>
 #include <QFileInfo>
 #include <QMessageBox>
+#include <QTabBar>
+#include <QStyle>
 
 #include <cprime/appopenfunc.h>
 #include <cprime/variables.h>
@@ -267,7 +270,40 @@ void CoreTerminal::setWindowProperties()
         setStyleSheet( "#base { background-color: palette(Window); }" );
     }
 
-    resize( 800, 500 );
+    QFontMetrics fm( terminalFont );
+    std::cerr  << "fm.boundingRect(\"M\").width() = " << fm.boundingRect( "M" ).width() 
+               << "\nfm.boundingRect(\"M\").height() = " << fm.boundingRect("M").height() 
+               << "\nfm.averageCharWidth() = " << fm.averageCharWidth()
+               << "\nfm.height() = " << fm.height()
+               << "\nfm.lineSpacing() = " << fm.lineSpacing()
+               << "\nfm.leading() = " << fm.leading()
+               << "\ntabBar.width() = " << TabWidget->tabBar()->width()
+               << "\ntabBar.height() = " << TabWidget->tabBar()->height()
+               << "\nframeGeometry.height() = " << frameGeometry().height()
+               << "\ngeometry.height() = " << geometry().height()
+               << "\nPM_ScrollBarExtent = " << qApp->style()->pixelMetric(QStyle::PM_ScrollBarExtent) 
+               << "\nPM_TabBarTabOverlap = " << qApp->style()->pixelMetric(QStyle::PM_TabBarTabOverlap)
+               << "\nPM_TabBarTabVSpace = " << qApp->style()->pixelMetric(QStyle::PM_TabBarTabVSpace)
+               << "\nPM_TabBarBaseHeight = " << qApp->style()->pixelMetric(QStyle::PM_TabBarBaseHeight)
+               << "\nPM_TabBarBaseOverlap = " << qApp->style()->pixelMetric(QStyle::PM_TabBarBaseOverlap)
+               << "\ntabBar()->height() = " << TabWidget->tabBar()->height()
+               << "\ntabBar()->tabRect().height() = " << TabWidget->tabBar()->tabRect(0).height()
+               << '\n';
+
+    int width = fm.averageCharWidth() * 80
+               + qApp->style()->pixelMetric(QStyle::PM_ScrollBarExtent)
+               + 2;
+    /*
+     * Perfect size =
+     * tabBar->height() +7 for Fusion, +4 for QtCurve, +3 for Windows
+     * tabBar->tabRect(0).height() seems to align:
+     * 36 for Fusion, 33 for QtCurve, 32 for Windows using 12pt font
+     * Also verified with several other styles and font sizes
+     */
+    int height = fm.height() * 30
+               + TabWidget->tabBar()->tabRect(0).height()
+               + 1;
+    resize(width, height);
 
     if (uiMode != 0) {
         setWindowFlags( windowFlags() );
Edited by Jason Bacon