[vte] pty: Fill in winsize.ws_xpixel and .ws_ypixel for TIOCGWINSZ



commit af384940fd393d85682aa1f2fd688d85f76c5ad8
Author: Hans Petter Jansson <hpj cl no>
Date:   Wed May 27 21:17:04 2020 +0200

    pty: Fill in winsize.ws_xpixel and .ws_ypixel for TIOCGWINSZ
    
    This makes the terminal's pixel size available to clients, which can use
    it to estimate the cell size and scale graphics accordingly.
    
    Fixes: https://gitlab.gnome.org/GNOME/vte/-/issues/251

 perf/printwinsize.py  | 26 ++++++++++++++++++++++++++
 src/pty.cc            |  8 +++++++-
 src/pty.hh            |  4 +++-
 src/vte.cc            | 12 +++++++++++-
 src/vtegtk.cc         |  8 +++++++-
 src/vtepty.cc         | 17 ++++++++++++++++-
 src/vteptyinternal.hh |  7 +++++++
 7 files changed, 77 insertions(+), 5 deletions(-)
---
diff --git a/perf/printwinsize.py b/perf/printwinsize.py
new file mode 100755
index 00000000..82f02e6b
--- /dev/null
+++ b/perf/printwinsize.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python
+# Copyright © 2020 Christian Persch
+#
+# This library is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# This library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+# General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library.  If not, see <https://www.gnu.org/licenses/>.
+
+import array, fcntl, sys, termios
+
+buffer = array.array('H', [0, 0, 0, 0])
+ret = fcntl.ioctl(sys.stdin.fileno(), termios.TIOCGWINSZ, buffer)
+if ret != 0:
+    print(f'ioctl(TIOCGWINSZ) failed: {ret}')
+    sys.exit(1)
+
+print(f'{buffer[0]} rows ({buffer[3]} px), {buffer[1]} columns ({buffer[2]} px)')
+sys.exit(0)
diff --git a/src/pty.cc b/src/pty.cc
index e9a93eb5..7f7958a0 100644
--- a/src/pty.cc
+++ b/src/pty.cc
@@ -262,6 +262,8 @@ Pty::child_setup() const noexcept
  * Pty::set_size:
  * @rows: the desired number of rows
  * @columns: the desired number of columns
+ * @cell_height_px: the height of a cell in px, or 0 for undetermined
+ * @cell_width_px: the width of a cell in px, or 0 for undetermined
  *
  * Attempts to resize the pseudo terminal's window size.  If successful, the
  * OS kernel will send #SIGWINCH to the child process group.
@@ -270,7 +272,9 @@ Pty::child_setup() const noexcept
  */
 bool
 Pty::set_size(int rows,
-              int columns) const noexcept
+              int columns,
+              int cell_height_px,
+              int cell_width_px) const noexcept
 {
         auto master = fd();
 
@@ -278,6 +282,8 @@ Pty::set_size(int rows,
        memset(&size, 0, sizeof(size));
        size.ws_row = rows > 0 ? rows : 24;
        size.ws_col = columns > 0 ? columns : 80;
+        size.ws_ypixel = size.ws_row * cell_height_px;
+        size.ws_xpixel = size.ws_col * cell_width_px;
        _vte_debug_print(VTE_DEBUG_PTY,
                        "Setting size on fd %d to (%d,%d).\n",
                        master, columns, rows);
diff --git a/src/pty.hh b/src/pty.hh
index a0764e25..a0ae6c38 100644
--- a/src/pty.hh
+++ b/src/pty.hh
@@ -57,7 +57,9 @@ public:
         void child_setup() const noexcept;
 
         bool set_size(int rows,
-                      int columns) const noexcept;
+                      int columns,
+                      int cell_height_px,
+                      int cell_width_px) const noexcept;
         bool get_size(int* rows,
                       int* columns) const noexcept;
         bool set_utf8(bool utf8) const noexcept;
diff --git a/src/vte.cc b/src/vte.cc
index 197aaa00..92d3df48 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -7218,6 +7218,13 @@ Terminal::apply_font_metrics(int cell_width,
        }
        /* Emit a signal that the font changed. */
        if (cresize) {
+                if (pty()) {
+                        /* Update pixel size of PTY. */
+                        pty()->set_size(m_row_count,
+                                        m_column_count,
+                                        m_cell_height,
+                                        m_cell_width);
+                }
                emit_char_size_changed(m_cell_width, m_cell_height);
        }
        /* Repaint. */
@@ -7559,7 +7566,10 @@ Terminal::set_size(long columns,
                /* Try to set the terminal size, and read it back,
                 * in case something went awry.
                  */
-               if (!pty()->set_size(rows, columns))
+               if (!pty()->set_size(rows,
+                                     columns,
+                                     m_cell_height,
+                                     m_cell_width))
                        g_warning("Failed to set PTY size: %m\n");
                refresh_size();
        } else {
diff --git a/src/vtegtk.cc b/src/vtegtk.cc
index 8452b1e2..cb315f1b 100644
--- a/src/vtegtk.cc
+++ b/src/vtegtk.cc
@@ -3027,7 +3027,13 @@ try
         if (!pty)
                 return nullptr;
 
-        vte_pty_set_size(pty.get(), IMPL(terminal)->m_row_count, IMPL(terminal)->m_column_count, NULL);
+        auto impl = IMPL(terminal);
+        _vte_pty_set_size(pty.get(),
+                          impl->m_row_count,
+                          impl->m_column_count,
+                          impl->m_cell_height,
+                          impl->m_cell_width,
+                          nullptr);
 
         return pty.release();
 }
diff --git a/src/vtepty.cc b/src/vtepty.cc
index b2ed5570..230d5b63 100644
--- a/src/vtepty.cc
+++ b/src/vtepty.cc
@@ -163,13 +163,27 @@ vte_pty_set_size(VtePty *pty,
                  int rows,
                  int columns,
                  GError **error) noexcept
+{
+        /* No way to determine the pixel size; set it to (0, 0), meaning
+         * "undefined".
+         */
+        return _vte_pty_set_size(pty, rows, columns, 0, 0, error);
+}
+
+bool
+_vte_pty_set_size(VtePty *pty,
+                  int rows,
+                  int columns,
+                  int cell_height_px,
+                  int cell_width_px,
+                  GError **error) noexcept
 try
 {
         g_return_val_if_fail(VTE_IS_PTY(pty), FALSE);
         auto impl = IMPL(pty);
         g_return_val_if_fail(impl != nullptr, FALSE);
 
-        if (impl->set_size(rows, columns))
+        if (impl->set_size(rows, columns, cell_height_px, cell_width_px))
                 return true;
 
         auto errsv = vte::libc::ErrnoSaver{};
@@ -185,6 +199,7 @@ catch (...)
         return vte::glib::set_error_from_exception(error);
 }
 
+
 /**
  * vte_pty_get_size:
  * @pty: a #VtePty
diff --git a/src/vteptyinternal.hh b/src/vteptyinternal.hh
index 0c78d895..a5d4559c 100644
--- a/src/vteptyinternal.hh
+++ b/src/vteptyinternal.hh
@@ -36,3 +36,10 @@ bool _vte_pty_spawn_sync(VtePty* pty,
                          GError** error) noexcept;
 
 bool _vte_pty_check_envv(char const* const* envv) noexcept;
+
+bool _vte_pty_set_size(VtePty *pty,
+                       int rows,
+                       int columns,
+                       int cell_height_px,
+                       int cell_width_px,
+                       GError **error) noexcept;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]