[vte] widget: Add alignment properties



commit 1be3d3d9fa160874ccf162acd1adb88ca8ba05a8
Author: Christian Persch <chpe src gnome org>
Date:   Sat Mar 13 22:10:42 2021 +0100

    widget: Add alignment properties
    
    Add API to set how to distribute extra-grid space allocated to the
    widget. Previously, vte always positioned the content at the left and top
    of the allocation.
    
    Fixes: https://gitlab.gnome.org/GNOME/vte/-/issues/337

 doc/reference/vte-sections.txt.in |   4 ++
 src/app/app.cc                    |  33 +++++++++
 src/vte.cc                        | 127 ++++++++++++++++++++-------------
 src/vte/vteterminal.h             |  14 ++++
 src/vtedefines.hh                 |   3 +
 src/vtegtk.cc                     | 144 +++++++++++++++++++++++++++++++++++++-
 src/vtegtk.hh                     |   2 +
 src/vteinternal.hh                |  22 ++++--
 src/widget.cc                     |   8 ++-
 src/widget.hh                     |  28 +++++++-
 10 files changed, 325 insertions(+), 60 deletions(-)
---
diff --git a/doc/reference/vte-sections.txt.in b/doc/reference/vte-sections.txt.in
index 7e735f5b..3f6cd2bb 100644
--- a/doc/reference/vte-sections.txt.in
+++ b/doc/reference/vte-sections.txt.in
@@ -103,6 +103,10 @@ vte_terminal_search_set_wrap_around
 vte_terminal_event_check_regex_array
 vte_terminal_event_check_regex_simple
 #endif /* VTE_GTK */
+vte_terminal_get_xalign
+vte_terminal_set_xalign
+vte_terminal_get_yalign
+vte_terminal_set_yalign
 
 <SUBSECTION>
 VteFeatureFlags
diff --git a/src/app/app.cc b/src/app/app.cc
index 1c772718..2712ca52 100644
--- a/src/app/app.cc
+++ b/src/app/app.cc
@@ -122,6 +122,8 @@ public:
         VteCursorBlinkMode cursor_blink_mode{VTE_CURSOR_BLINK_SYSTEM};
         VteCursorShape cursor_shape{VTE_CURSOR_SHAPE_BLOCK};
         VteTextBlinkMode text_blink_mode{VTE_TEXT_BLINK_ALWAYS};
+        GtkAlign xalign{GtkAlign(-1)};
+        GtkAlign yalign{GtkAlign(-1)};
         vte::glib::RefPtr<GtkCssProvider> css{};
 
 #if VTE_GTK == 3
@@ -476,6 +478,28 @@ private:
                 return true;
         }
 
+        static gboolean
+        parse_xalign(char const* option, char const* value, void* data, GError** error)
+        {
+                auto const that = static_cast<Options*>(data);
+                auto v = int{};
+                auto const rv = that->parse_enum(GTK_TYPE_ALIGN, value, v, error);
+                if (rv)
+                        that->xalign = GtkAlign(v);
+                return rv;
+        }
+
+        static gboolean
+        parse_yalign(char const* option, char const* value, void* data, GError** error)
+        {
+                auto const that = static_cast<Options*>(data);
+                auto v = int{};
+                auto const rv = that->parse_enum(GTK_TYPE_ALIGN, value, v, error);
+                if (rv)
+                        that->yalign = GtkAlign(v);
+                return rv;
+        }
+
 public:
 
         double get_alpha() const
@@ -668,6 +692,11 @@ public:
                         { "use-theme-colors", 0, 0, G_OPTION_ARG_NONE, &use_theme_colors,
                           "Use foreground and background colors from the gtk+ theme", nullptr },
 
+                        { "xalign", 0, 0, G_OPTION_ARG_CALLBACK, (void*)parse_xalign,
+                          "Horizontal alignment (fill|start|end|center)", "ALIGN" },
+                        { "yalign", 0, 0, G_OPTION_ARG_CALLBACK, (void*)parse_yalign,
+                          "Vertical alignment (fill|start|end|center)", "ALIGN" },
+
 #if VTE_GTK == 3
                         { "no-argb-visual", 0, 0, G_OPTION_ARG_NONE, &no_argb_visual,
                           "Don't use an ARGB visual", nullptr },
@@ -2549,6 +2578,10 @@ vteapp_window_constructed(GObject *object)
         vte_terminal_set_scroll_unit_is_pixels(window->terminal, options.scroll_unit_is_pixels);
         vte_terminal_set_scrollback_lines(window->terminal, options.scrollback_lines);
         vte_terminal_set_text_blink_mode(window->terminal, options.text_blink_mode);
+        if (options.xalign != GtkAlign(-1))
+            vte_terminal_set_xalign(window->terminal, options.xalign);
+        if (options.yalign != GtkAlign(-1))
+            vte_terminal_set_yalign(window->terminal, options.yalign);
 
         /* Style */
         if (options.font_string != nullptr) {
diff --git a/src/vte.cc b/src/vte.cc
index 7819dbec..05340843 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -4447,16 +4447,15 @@ Terminal::set_border_padding(GtkBorder const* padding)
 {
         if (memcmp(padding, &m_padding, sizeof(*padding)) != 0) {
                 _vte_debug_print(VTE_DEBUG_MISC | VTE_DEBUG_WIDGET_SIZE,
-                                 "Setting padding to (%d,%d,%d,%d)\n",
+                                 "Setting style padding to (%d,%d,%d,%d)\n",
                                  padding->left, padding->right,
                                  padding->top, padding->bottom);
 
-                m_padding = *padding;
-                update_view_extents();
+                m_style_padding = *padding;
                 gtk_widget_queue_resize(m_widget);
         } else {
                 _vte_debug_print(VTE_DEBUG_MISC | VTE_DEBUG_WIDGET_SIZE,
-                                 "Keeping padding the same at (%d,%d,%d,%d)\n",
+                                 "Keeping style padding the same at (%d,%d,%d,%d)\n",
                                  padding->left, padding->right,
                                  padding->top, padding->bottom);
 
@@ -7762,13 +7761,11 @@ Terminal::widget_measure_width(int *minimum_width,
 
         refresh_size();
 
-       *minimum_width = m_cell_width * 2;  /* have room for a CJK or emoji */
+       *minimum_width = m_cell_width * VTE_MIN_GRID_WIDTH;
         *natural_width = m_cell_width * m_column_count;
 
-       *minimum_width += m_padding.left +
-                          m_padding.right;
-       *natural_width += m_padding.left +
-                          m_padding.right;
+        *minimum_width += m_style_padding.left + m_style_padding.right;
+        *natural_width += m_style_padding.left + m_style_padding.right;
 
        _vte_debug_print(VTE_DEBUG_WIDGET_SIZE,
                        "[Terminal %p] minimum_width=%d, natural_width=%d for %ldx%ld cells (padding 
%d,%d;%d,%d).\n",
@@ -7776,7 +7773,8 @@ Terminal::widget_measure_width(int *minimum_width,
                        *minimum_width, *natural_width,
                        m_column_count,
                          m_row_count,
-                         m_padding.left, m_padding.right, m_padding.top, m_padding.bottom);
+                         m_style_padding.left, m_style_padding.right,
+                         m_style_padding.top, m_style_padding.bottom);
 }
 
 void
@@ -7787,13 +7785,11 @@ Terminal::widget_measure_height(int *minimum_height,
 
         refresh_size();
 
-       *minimum_height = m_cell_height * 1;
+       *minimum_height = m_cell_height * VTE_MIN_GRID_HEIGHT;
         *natural_height = m_cell_height * m_row_count;
 
-       *minimum_height += m_padding.top +
-                          m_padding.bottom;
-       *natural_height += m_padding.top +
-                          m_padding.bottom;
+        *minimum_height += m_style_padding.top + m_style_padding.bottom;
+        *natural_height += m_style_padding.top + m_style_padding.bottom;
 
        _vte_debug_print(VTE_DEBUG_WIDGET_SIZE,
                        "[Terminal %p] minimum_height=%d, natural_height=%d for %ldx%ld cells (padding 
%d,%d;%d,%d).\n",
@@ -7801,7 +7797,8 @@ Terminal::widget_measure_height(int *minimum_height,
                        *minimum_height, *natural_height,
                        m_column_count,
                          m_row_count,
-                         m_padding.left, m_padding.right, m_padding.top, m_padding.bottom);
+                         m_style_padding.left, m_style_padding.right,
+                         m_style_padding.top, m_style_padding.bottom);
 }
 
 void
@@ -7810,38 +7807,71 @@ Terminal::widget_size_allocate(int allocation_x,
                                int allocation_y,
                                int allocation_width,
                                int allocation_height,
-                               int allocation_baseline)
+                               int allocation_baseline,
+                               Alignment xalign,
+                               Alignment yalign)
 #elif VTE_GTK == 4
 Terminal::widget_size_allocate(int allocation_width,
                                int allocation_height,
-                               int allocation_baseline)
+                               int allocation_baseline,
+                               Alignment xalign,
+                               Alignment yalign)
 #endif /* VTE_GTK */
 {
-       glong width, height;
-       gboolean repaint, update_scrollback;
+        auto width = allocation_width - (m_style_padding.left + m_style_padding.right);
+        auto height = allocation_height - (m_style_padding.top + m_style_padding.bottom);
 
-       _vte_debug_print(VTE_DEBUG_LIFECYCLE,
-                       "vte_terminal_size_allocate()\n");
+        auto grid_width = int(width / m_cell_width);
+        auto grid_height = int(height / m_cell_height);
 
-       width = (allocation_width - (m_padding.left + m_padding.right)) /
-               m_cell_width;
-       height = (allocation_height - (m_padding.top + m_padding.bottom)) /
-                m_cell_height;
-       width = MAX(width, 1);
-       height = MAX(height, 1);
+        width -= grid_width * m_cell_width;
+        height -= grid_height * m_cell_height;
+        /* assert(width >= 0); assert(height >= 0); */
 
-       _vte_debug_print(VTE_DEBUG_WIDGET_SIZE,
-                       "[Terminal %p] Sizing window to %dx%d (%ldx%ld, padding %d,%d;%d,%d).\n",
-                        m_terminal,
-                       allocation_width, allocation_height,
-                         width, height,
-                         m_padding.left, m_padding.right, m_padding.top, m_padding.bottom);
+        /* Distribute extra space according to alignment */
+        auto lpad = 0, rpad = 0;
+        switch (xalign) {
+        default:
+        case Alignment::FILL:
+        case Alignment::BASELINE:
+        case Alignment::START:  lpad = 0; rpad = width; break;
+        case Alignment::END:    lpad = width; rpad = 0; break;
+        case Alignment::CENTRE: lpad = width / 2; rpad = width - lpad; break;
+        }
+
+        auto tpad = 0, bpad = 0;
+        switch (yalign) {
+        default:
+        case Alignment::FILL:   tpad = bpad = 0; break;
+        case Alignment::BASELINE:
+        case Alignment::START:  tpad = 0; bpad = height; break;
+        case Alignment::END:    tpad = height; bpad = 0; break;
+        case Alignment::CENTRE: tpad = height / 2; bpad = height - tpad; break;
+        }
 
-        auto current_allocation = get_allocated_rect();
+        m_padding.left   = m_style_padding.left   + lpad;
+        m_padding.right  = m_style_padding.right  + rpad;
+        m_padding.top    = m_style_padding.top    + tpad;
+        m_padding.bottom = m_style_padding.bottom + bpad;
 
-       repaint = current_allocation.width != allocation_width ||
+        /* The minimum size returned from  ::widget_measure_width/height()
+         * is VTE_MIN_GRID_WIDTH/HEIGHT, but let's be extra safe.
+         */
+        grid_width = std::max(grid_width, VTE_MIN_GRID_WIDTH);
+        grid_height = std::max(grid_height, VTE_MIN_GRID_HEIGHT);
+
+        _vte_debug_print(VTE_DEBUG_WIDGET_SIZE,
+                         "[Terminal %p] Sizing window to %dx%d (%dx%d, effective padding %d,%d;%d,%d).\n",
+                         m_terminal,
+                         allocation_width, allocation_height,
+                         grid_width, grid_height,
+                         m_padding.left, m_padding.right, m_padding.top, m_padding.bottom);
+
+        auto const current_allocation = get_allocated_rect();
+        auto const repaint = current_allocation.width != allocation_width ||
                 current_allocation.height != allocation_height;
-       update_scrollback = current_allocation.height != allocation_height;
+        /* FIXME: remove this */
+        auto const update_scrollback = current_allocation.height != allocation_height;
 
 #if VTE_GTK == 3
         set_allocated_rect({allocation_x, allocation_y, allocation_width, allocation_height});
@@ -7849,24 +7879,21 @@ Terminal::widget_size_allocate(int allocation_width,
         set_allocated_rect({0, 0, allocation_width, allocation_height});
 #endif
 
-       if (width != m_column_count
-                       || height != m_row_count
-                       || update_scrollback)
-       {
-               /* Set the size of the pseudo-terminal. */
-               set_size(width, height);
+        if (grid_width != m_column_count ||
+            grid_height != m_row_count ||
+            update_scrollback) {
+                /* Set the size of the pseudo-terminal. */
+                set_size(grid_width, grid_height);
 
                /* Notify viewers that the contents have changed. */
                queue_contents_changed();
        }
 
-       if (widget_realized()) {
-               /* Force a repaint if we were resized. */
-               if (repaint) {
-                       reset_update_rects();
-                       invalidate_all();
-               }
-       }
+        /* Force a repaint if we were resized. */
+        if (widget_realized() && repaint) {
+                reset_update_rects();
+                invalidate_all();
+        }
 }
 
 void
diff --git a/src/vte/vteterminal.h b/src/vte/vteterminal.h
index 05f6674f..a3cfc307 100644
--- a/src/vte/vteterminal.h
+++ b/src/vte/vteterminal.h
@@ -545,6 +545,20 @@ void vte_terminal_set_enable_sixel(VteTerminal *terminal,
 _VTE_PUBLIC
 gboolean vte_terminal_get_enable_sixel(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
+_VTE_PUBLIC
+void vte_terminal_set_xalign(VteTerminal* terminal,
+                             GtkAlign align) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
+
+_VTE_PUBLIC
+GtkAlign vte_terminal_get_xalign(VteTerminal* terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
+
+_VTE_PUBLIC
+void vte_terminal_set_yalign(VteTerminal* terminal,
+                             GtkAlign align) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
+
+_VTE_PUBLIC
+GtkAlign vte_terminal_get_yalign(VteTerminal* terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
+
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(VteTerminal, g_object_unref)
 
 G_END_DECLS
diff --git a/src/vtedefines.hh b/src/vtedefines.hh
index 16f6ae78..fe8d6e97 100644
--- a/src/vtedefines.hh
+++ b/src/vtedefines.hh
@@ -151,3 +151,6 @@
 
 #define VTE_MIN_CURSOR_BLINK_CYCLE (50 /* ms */)
 #define VTE_MIN_CURSOR_BLINK_TIMEOUT (50 /* ms */)
+
+#define VTE_MIN_GRID_WIDTH (2) /* space for one wide character */
+#define VTE_MIN_GRID_HEIGHT (1)
diff --git a/src/vtegtk.cc b/src/vtegtk.cc
index 900c9cfb..5714a5b7 100644
--- a/src/vtegtk.cc
+++ b/src/vtegtk.cc
@@ -1012,7 +1012,15 @@ try
                         g_value_set_string (value, vte_terminal_get_word_char_exceptions (terminal));
                         break;
 
-               default:
+                case PROP_XALIGN:
+                        g_value_set_enum(value, vte_terminal_get_xalign(terminal));
+                        break;
+
+                case PROP_YALIGN:
+                        g_value_set_enum(value, vte_terminal_get_yalign(terminal));
+                        break;
+
+                default:
                        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                        return;
                 }
@@ -1130,6 +1138,14 @@ try
                         vte_terminal_set_word_char_exceptions (terminal, g_value_get_string (value));
                         break;
 
+                case PROP_XALIGN:
+                        vte_terminal_set_xalign(terminal, GtkAlign(g_value_get_enum(value)));
+                        break;
+
+                case PROP_YALIGN:
+                        vte_terminal_set_yalign(terminal, GtkAlign(g_value_get_enum(value)));
+                        break;
+
                         /* Not writable */
                 case PROP_CURRENT_DIRECTORY_URI:
                 case PROP_CURRENT_FILE_URI:
@@ -2328,6 +2344,32 @@ vte_terminal_class_init(VteTerminalClass *klass)
                                      NULL,
                                      (GParamFlags) (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS | 
G_PARAM_EXPLICIT_NOTIFY));
 
+        /**
+         * VteTerminal:xalign:
+         *
+         * The horizontal alignment of @terminal within its allocation.
+         *
+         * Since: 0.66
+         */
+        pspecs[PROP_XALIGN] =
+                g_param_spec_enum("xalign", nullptr, nullptr,
+                                  GTK_TYPE_ALIGN,
+                                  GTK_ALIGN_FILL,
+                                  GParamFlags(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | 
G_PARAM_EXPLICIT_NOTIFY));
+
+        /**
+         * VteTerminal:yalign:
+         *
+         * The vertical alignment of @terminal within its allocation
+         *
+         * Since: 0.66
+         */
+        pspecs[PROP_YALIGN] =
+                g_param_spec_enum("yalign", nullptr, nullptr,
+                                  GTK_TYPE_ALIGN,
+                                  GTK_ALIGN_FILL,
+                                  GParamFlags(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | 
G_PARAM_EXPLICIT_NOTIFY));
+
         g_object_class_install_properties(gobject_class, LAST_PROP, pspecs);
 
 #if VTE_GTK == 3
@@ -6142,6 +6184,106 @@ catch (...)
         return false;
 }
 
+/**
+ * vte_terminal_set_xalign:
+ * @terminal: a #VteTerminal
+ * @align: alignment value from #GtkAlign
+ *
+ * Sets the horizontal alignment of @terminal within its allocation.
+ *
+ * Note: %GTK_ALIGN_FILL and %GTK_ALIGN_BASELINE are not supported and
+ * will be treated like %GTK_ALIGN_START.
+ *
+ * Since: 0.66
+ */
+void
+vte_terminal_set_xalign(VteTerminal* terminal,
+                        GtkAlign align) noexcept
+try
+{
+        g_return_if_fail(VTE_IS_TERMINAL(terminal));
+        g_return_if_fail(align >= GTK_ALIGN_FILL && align <= GTK_ALIGN_BASELINE);
+
+        if (WIDGET(terminal)->set_xalign(align))
+                g_object_notify_by_pspec(G_OBJECT(terminal), pspecs[PROP_XALIGN]);
+}
+catch (...)
+{
+        vte::log_exception();
+}
+
+/**
+ * vte_terminal_get_xalign:
+ * @terminal: a #VteTerminal
+ *
+ * Returns: the horizontal alignment of @terminal within its allocation
+ *
+ * Since: 0.66
+ */
+GtkAlign
+vte_terminal_get_xalign(VteTerminal* terminal) noexcept
+try
+{
+        g_return_val_if_fail(VTE_IS_TERMINAL(terminal), GTK_ALIGN_START);
+
+        return WIDGET(terminal)->xalign();
+}
+catch (...)
+{
+        vte::log_exception();
+        return GTK_ALIGN_FILL;
+}
+
+/**
+ * vte_terminal_set_yalign:
+ * @terminal: a #VteTerminal
+ * @align: alignment value from #GtkAlign
+ *
+ * Sets the vertical alignment of @terminal within its allocation.
+ *
+ * Note: %GTK_ALIGN_BASELINE is not supported and will be treated like
+ * %GTK_ALIGN_START.
+ *
+ * Since: 0.66
+ */
+void
+vte_terminal_set_yalign(VteTerminal* terminal,
+                        GtkAlign align) noexcept
+try
+{
+        g_return_if_fail(VTE_IS_TERMINAL(terminal));
+        g_return_if_fail(align >= GTK_ALIGN_FILL && align <= GTK_ALIGN_BASELINE);
+
+        if (WIDGET(terminal)->set_yalign(align))
+                g_object_notify_by_pspec(G_OBJECT(terminal), pspecs[PROP_YALIGN]);
+}
+catch (...)
+{
+        vte::log_exception();
+}
+
+/**
+ * vte_terminal_get_yalign:
+ * @terminal: a #VteTerminal
+ *
+ * Returns: the vertical alignment of @terminal within its allocation
+ *
+ * Since: 0.66
+ */
+GtkAlign
+vte_terminal_get_yalign(VteTerminal* terminal) noexcept
+try
+{
+        g_return_val_if_fail(VTE_IS_TERMINAL(terminal), GTK_ALIGN_FILL);
+
+        return WIDGET(terminal)->yalign();
+}
+catch (...)
+{
+        vte::log_exception();
+        return GTK_ALIGN_FILL;
+}
+
 namespace vte {
 
 using namespace std::literals;
diff --git a/src/vtegtk.hh b/src/vtegtk.hh
index 6b7a1ea2..e32430be 100644
--- a/src/vtegtk.hh
+++ b/src/vtegtk.hh
@@ -92,6 +92,8 @@ enum {
         PROP_TEXT_BLINK_MODE,
         PROP_WINDOW_TITLE,
         PROP_WORD_CHAR_EXCEPTIONS,
+        PROP_XALIGN,
+        PROP_YALIGN,
         LAST_PROP,
 
         /* override properties */
diff --git a/src/vteinternal.hh b/src/vteinternal.hh
index 9e5eabd8..a9ca86b3 100644
--- a/src/vteinternal.hh
+++ b/src/vteinternal.hh
@@ -209,6 +209,14 @@ private:
                eLINE,
         };
 
+        enum class Alignment : uint8_t {
+                FILL,
+                START,
+                END,
+                CENTRE,
+                BASELINE
+        };
+
 protected:
 
         /* NOTE: This needs to be kept in sync with the public VteCursorBlinkMode enum */
@@ -725,11 +733,11 @@ public:
 
         /* Style stuff */
 #if VTE_GTK == 3
-        GtkBorder m_padding{1, 1, 1, 1};
+        GtkBorder m_style_padding{1, 1, 1, 1};
 #elif VTE_GTK == 4
-        GtkBorder m_padding{0, 0, 0, 0};
+        GtkBorder m_style_padding{0, 0, 0, 0};
 #endif
-        auto padding() const noexcept { return &m_padding; }
+        GtkBorder m_padding{m_style_padding};
 
         /* Hyperlinks */
         bool m_allow_hyperlink{false};
@@ -923,11 +931,15 @@ public:
                                   int y,
                                   int width,
                                   int height,
-                                  int baseline);
+                                  int baseline,
+                                  Alignment xalign,
+                                  Alignment yalign);
 #elif VTE_GTK == 4
         void widget_size_allocate(int width,
                                   int height,
-                                  int baseline);
+                                  int baseline,
+                                  Alignment xalign,
+                                  Alignment yalign);
 #endif /* VTE_GTK */
 
         void set_blink_settings(bool blink,
diff --git a/src/widget.cc b/src/widget.cc
index 233f36fc..7adc7031 100644
--- a/src/widget.cc
+++ b/src/widget.cc
@@ -1405,7 +1405,9 @@ Widget::size_allocate(GtkAllocation* allocation)
 
         m_terminal->widget_size_allocate(allocation->x, allocation->y,
                                          allocation->width, allocation->height,
-                                         -1);
+                                         -1,
+                                         vte::terminal::Terminal::Alignment(m_xalign),
+                                         vte::terminal::Terminal::Alignment(m_yalign));
 
         gtk_widget_set_allocation(gtk(), allocation);
 
@@ -1427,7 +1429,9 @@ Widget::size_allocate(int width,
         _vte_debug_print(VTE_DEBUG_WIDGET_SIZE, "Widget size allocate width=%d height=%d baseline=%d\n",
                          width, height, baseline);
 
-        terminal()->widget_size_allocate(width, height, baseline);
+        terminal()->widget_size_allocate(width, height, baseline,
+                                         vte::terminal::Terminal::Alignment(m_xalign),
+                                         vte::terminal::Terminal::Alignment(m_yalign));
 
         gtk_widget_allocate(gtk(), width, height, baseline, nullptr);
 }
diff --git a/src/widget.hh b/src/widget.hh
index 277ca1ea..19aaf733 100644
--- a/src/widget.hh
+++ b/src/widget.hh
@@ -373,8 +373,6 @@ public:
 
         constexpr auto scroll_unit_is_pixels() const noexcept { return m_scroll_unit_is_pixels; }
 
-        auto padding() const noexcept { return terminal()->padding(); }
-
         bool set_cursor_blink_mode(VteCursorBlinkMode mode) { return 
terminal()->set_cursor_blink_mode(vte::terminal::Terminal::CursorBlinkMode(mode)); }
         auto cursor_blink_mode() const noexcept { return 
VteCursorBlinkMode(terminal()->cursor_blink_mode()); }
 
@@ -446,6 +444,29 @@ public:
         bool set_sixel_enabled(bool enabled) noexcept { return m_terminal->set_sixel_enabled(enabled); }
         bool sixel_enabled() const noexcept { return m_terminal->sixel_enabled(); }
 
+        constexpr auto xalign() const noexcept { return m_xalign; }
+        constexpr auto yalign() const noexcept { return m_yalign; }
+
+        bool set_xalign(GtkAlign align) noexcept
+        {
+                if (align == m_xalign)
+                        return false;
+
+                m_xalign = align;
+                gtk_widget_queue_allocate(gtk());
+                return true;
+        }
+
+        bool set_yalign(GtkAlign align) noexcept
+        {
+                if (align == m_yalign)
+                        return false;
+
+                m_yalign = align;
+                gtk_widget_queue_allocate(gtk());
+                return true;
+        }
+
 protected:
 
         enum class CursorType {
@@ -549,6 +570,9 @@ private:
         unsigned m_vscroll_policy:1{GTK_SCROLL_NATURAL};
         unsigned m_scroll_unit_is_pixels:1{false};
         unsigned m_changing_scroll_position:1{false};
+
+        GtkAlign m_xalign{GTK_ALIGN_START};
+        GtkAlign m_yalign{GTK_ALIGN_FILL};
 };
 
 } // namespace platform


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