[vte] widget: Fix padding borders



commit 17024047b06f72ad6cd431b200bd710d11ffd268
Author: Christian Persch <chpe src gnome org>
Date:   Mon Apr 18 19:39:01 2022 +0200

    widget: Fix padding borders
    
    On gtk3, the padding needs to be added to the widget's size request, and
    is inside its allocation, while on gtk4, the padding is outside the
    widget's allocation.  The inner padding (use to [xy]align and [xy]fill
    properties) is always inside the allocation.
    
    Also fixes event coordinate translation on gtk4 to take the inner border
    into account.
    
    Fixes: https://gitlab.gnome.org/GNOME/vte/-/issues/2554

 src/vte.cc         | 239 +++++++++++++++++++++++++++++++++++------------------
 src/vteaccess.cc   |   4 +-
 src/vtegtk.cc      |   4 +-
 src/vteinternal.hh |  35 +++++---
 src/widget.cc      |  54 +++++-------
 src/widget.hh      |   6 +-
 6 files changed, 207 insertions(+), 135 deletions(-)
---
diff --git a/src/vte.cc b/src/vte.cc
index c0053900..f6b4e952 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -51,6 +51,10 @@
 #include "widget.hh"
 #include "cairo-glue.hh"
 
+#if VTE_GTK == 4
+#include "graphene-glue.hh"
+#endif
+
 #ifdef HAVE_WCHAR_H
 #include <wchar.h>
 #endif
@@ -388,7 +392,7 @@ Terminal::cursor_is_onscreen() const noexcept
 {
         /* Note: the cursor can only be offscreen below the visible area, not above. */
         auto cursor_top = row_to_pixel (m_screen->cursor.row) - VTE_LINE_WIDTH;
-        auto display_bottom = m_view_usable_extents.height() + MIN(m_padding.bottom, VTE_LINE_WIDTH);
+        auto display_bottom = m_view_usable_extents.height() + MIN(m_border.bottom, VTE_LINE_WIDTH);
         return cursor_top < display_bottom;
 }
 
@@ -454,8 +458,8 @@ Terminal::invalidate_rows(vte::grid::row_t row_start,
                add_update_timeout(this);
        } else {
                 auto allocation = get_allocated_rect();
-                rect.x += allocation.x + m_padding.left;
-                rect.y += allocation.y + m_padding.top;
+                rect.x += allocation.x + m_border.left;
+                rect.y += allocation.y + m_border.top;
                 cairo_region_t *region = cairo_region_create_rectangle(&rect);
 #if VTE_GTK == 3
                gtk_widget_queue_draw_region(m_widget, region);
@@ -598,8 +602,8 @@ Terminal::invalidate_all()
         if (m_active_terminals_link != nullptr) {
                 auto allocation = get_allocated_rect();
                 cairo_rectangle_int_t rect;
-                rect.x = -m_padding.left;
-                rect.y = -m_padding.top;
+                rect.x = -m_border.left;
+                rect.y = -m_border.top;
                 rect.width = allocation.width;
                 rect.height = allocation.height;
 
@@ -1525,11 +1529,7 @@ Terminal::regex_match_check(vte::grid::column_t column,
 vte::view::coords
 Terminal::view_coords_from_event(vte::platform::MouseEvent const& event) const
 {
-#if VTE_GTK == 3
-        return vte::view::coords(event.x() - m_padding.left, event.y() - m_padding.top);
-#elif VTE_GTK == 4
-        return vte::view::coords(event.x(), event.y());
-#endif
+        return vte::view::coords(event.x() - m_border.left, event.y() - m_border.top);
 }
 
 bool
@@ -4435,32 +4435,20 @@ Terminal::im_update_cursor()
                 return;
 
         cairo_rectangle_int_t rect;
-        rect.x = m_screen->cursor.col * m_cell_width + m_padding.left +
+        rect.x = m_screen->cursor.col * m_cell_width + m_border.left +
                  get_preedit_width(true) * m_cell_width;
         rect.width = m_cell_width; // FIXMEchpe: if columns > 1 ?
-        rect.y = row_to_pixel(m_screen->cursor.row) + m_padding.top;
+        rect.y = row_to_pixel(m_screen->cursor.row) + m_border.top;
         rect.height = m_cell_height;
         m_real_widget->im_set_cursor_location(&rect);
 }
 
-void
-Terminal::set_border_padding(GtkBorder const* padding)
+bool
+Terminal::set_style_border(GtkBorder const& border) noexcept
 {
-        if (memcmp(padding, &m_padding, sizeof(*padding)) != 0) {
-                _vte_debug_print(VTE_DEBUG_MISC | VTE_DEBUG_WIDGET_SIZE,
-                                 "Setting style padding to (%d,%d,%d,%d)\n",
-                                 padding->left, padding->right,
-                                 padding->top, padding->bottom);
-
-                m_style_padding = *padding;
-                gtk_widget_queue_resize(m_widget);
-        } else {
-                _vte_debug_print(VTE_DEBUG_MISC | VTE_DEBUG_WIDGET_SIZE,
-                                 "Keeping style padding the same at (%d,%d,%d,%d)\n",
-                                 padding->left, padding->right,
-                                 padding->top, padding->bottom);
-
-        }
+        auto const changing = memcmp(&border, &m_style_border, sizeof(border)) != 0;
+        m_style_border = border;
+        return changing;
 }
 
 void
@@ -5731,8 +5719,8 @@ Terminal::hyperlink_invalidate_and_get_bbox(vte::base::Ring::hyperlink_idx_t idx
         g_assert (top != LONG_MAX && bottom != -1 && left != LONG_MAX && right != -1);
 
         auto allocation = get_allocated_rect();
-        bbox->x = allocation.x + m_padding.left + left * m_cell_width;
-        bbox->y = allocation.y + m_padding.top + row_to_pixel(top);
+        bbox->x = allocation.x + m_border.left + left * m_cell_width;
+        bbox->y = allocation.y + m_border.top + row_to_pixel(top);
         bbox->width = (right - left + 1) * m_cell_width;
         bbox->height = (bottom - top + 1) * m_cell_height;
         _vte_debug_print (VTE_DEBUG_HYPERLINK,
@@ -7637,7 +7625,6 @@ Terminal::Terminal(vte::platform::Widget* w,
        m_cell_height = 1;
        m_char_ascent = 1;
        m_char_descent = 1;
-       m_char_padding = {0, 0, 0, 0};
        m_line_thickness = 1;
        m_underline_position = 1;
         m_double_underline_position = 1;
@@ -7701,7 +7688,7 @@ Terminal::Terminal(vte::platform::Widget* w,
 
 void
 Terminal::widget_measure_width(int *minimum_width,
-                               int *natural_width)
+                               int *natural_width) noexcept
 {
        ensure_font();
 
@@ -7710,8 +7697,10 @@ Terminal::widget_measure_width(int *minimum_width,
        *minimum_width = m_cell_width * VTE_MIN_GRID_WIDTH;
         *natural_width = m_cell_width * m_column_count;
 
-        *minimum_width += m_style_padding.left + m_style_padding.right;
-        *natural_width += m_style_padding.left + m_style_padding.right;
+#if VTE_GTK == 3
+        *minimum_width += m_style_border.left + m_style_border.right;
+        *natural_width += m_style_border.left + m_style_border.right;
+#endif
 
        _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",
@@ -7719,13 +7708,13 @@ Terminal::widget_measure_width(int *minimum_width,
                        *minimum_width, *natural_width,
                        m_column_count,
                          m_row_count,
-                         m_style_padding.left, m_style_padding.right,
-                         m_style_padding.top, m_style_padding.bottom);
+                         m_style_border.left, m_style_border.right,
+                         m_style_border.top, m_style_border.bottom);
 }
 
 void
 Terminal::widget_measure_height(int *minimum_height,
-                                int *natural_height)
+                                int *natural_height) noexcept
 {
        ensure_font();
 
@@ -7734,8 +7723,10 @@ Terminal::widget_measure_height(int *minimum_height,
        *minimum_height = m_cell_height * VTE_MIN_GRID_HEIGHT;
         *natural_height = m_cell_height * m_row_count;
 
-        *minimum_height += m_style_padding.top + m_style_padding.bottom;
-        *natural_height += m_style_padding.top + m_style_padding.bottom;
+#if VTE_GTK == 3
+        *minimum_height += m_style_border.top + m_style_border.bottom;
+        *natural_height += m_style_border.top + m_style_border.bottom;
+#endif
 
        _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",
@@ -7743,33 +7734,34 @@ Terminal::widget_measure_height(int *minimum_height,
                        *minimum_height, *natural_height,
                        m_column_count,
                          m_row_count,
-                         m_style_padding.left, m_style_padding.right,
-                         m_style_padding.top, m_style_padding.bottom);
+                         m_style_border.left, m_style_border.right,
+                         m_style_border.top, m_style_border.bottom);
 }
 
 void
+Terminal::widget_size_allocate(
 #if VTE_GTK == 3
-Terminal::widget_size_allocate(int allocation_x,
+                               int allocation_x,
                                int allocation_y,
+#endif /* VTE_GTK == 3 */
                                int allocation_width,
                                int allocation_height,
                                int allocation_baseline,
                                Alignment xalign,
                                Alignment yalign,
                                bool xfill,
-                               bool yfill)
-#elif VTE_GTK == 4
-Terminal::widget_size_allocate(int allocation_width,
-                               int allocation_height,
-                               int allocation_baseline,
-                               Alignment xalign,
-                               Alignment yalign,
-                               bool xfill,
-                               bool yfill)
-#endif /* VTE_GTK */
+                               bool yfill) noexcept
 {
-        auto width = allocation_width - (m_style_padding.left + m_style_padding.right);
-        auto height = allocation_height - (m_style_padding.top + m_style_padding.bottom);
+        /* On gtk3, the style border is part of the widget's allocation;
+         * on gtk4, is is not.
+         */
+#if VTE_GTK == 3
+        auto width = allocation_width - (m_style_border.left + m_style_border.right);
+        auto height = allocation_height - (m_style_border.top + m_style_border.bottom);
+#elif VTE_GTK == 4
+        auto width = allocation_width;
+        auto height = allocation_height;
+#endif
 
         auto grid_width = int(width / m_cell_width);
         auto grid_height = int(height / m_cell_height);
@@ -7801,10 +7793,16 @@ Terminal::widget_size_allocate(int allocation_width,
         case Alignment::END:         tpad = height; bpad = 0; break;
         }
 
-        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;
+#if VTE_GTK == 3
+        m_border = m_style_border;
+#elif VTE_GTK == 4
+        m_border = {};
+#endif
+
+        m_border.left   += lpad;
+        m_border.right  += rpad;
+        m_border.top    += tpad;
+        m_border.bottom += bpad;
 
         /* The minimum size returned from  ::widget_measure_width/height()
          * is VTE_MIN_GRID_WIDTH/HEIGHT, but let's be extra safe.
@@ -7813,11 +7811,11 @@ Terminal::widget_size_allocate(int allocation_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",
+                         "[Terminal %p] Sizing window to %dx%d (%dx%d, effective border %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);
+                         m_border.left, m_border.right, m_border.top, m_border.bottom);
 
         auto const current_allocation = get_allocated_rect();
         auto const repaint = current_allocation.width != allocation_width ||
@@ -8668,10 +8666,14 @@ Terminal::draw_rows(VteScreen *screen_,
          * chopped off by another cell's background, not even across changes of the
          * background or any other attribute.
          * Process each row independently. */
+#if VTE_GTK == 3
         int const rect_width = get_allocated_width();
+#elif VTE_GTK == 4
+        int const rect_width = get_allocated_width() + m_style_border.left + m_style_border.right;
+#endif
 
         /* The rect contains the area of the row, and is moved row-wise in the loop. */
-        auto rect = cairo_rectangle_int_t{-m_padding.left, start_y, rect_width, row_height};
+        auto rect = cairo_rectangle_int_t{-m_border.left, start_y, rect_width, row_height};
         for (row = start_row, y = start_y;
              row < end_row;
              row++, y += row_height, rect.y = y /* same as rect.y += row_height */) {
@@ -8692,15 +8694,15 @@ Terminal::draw_rows(VteScreen *screen_,
                                 bg.green = (bg.green + 0xC000) / 2;
                                 bg.blue  = (bg.blue  + 0xC000) / 2;
                                 m_draw.fill_rectangle(
-                                                          -m_padding.left,
+                                                          -m_border.left,
                                                           y,
-                                                          m_padding.left,
+                                                          m_border.left,
                                                           row_height,
                                                           &bg, VTE_DRAW_OPAQUE);
                                 m_draw.fill_rectangle(
                                                           column_count * column_width,
                                                           y,
-                                                          rect_width - m_padding.left - column_count * 
column_width,
+                                                          rect_width - m_border.left - column_count * 
column_width,
                                                           row_height,
                                                           &bg, VTE_DRAW_OPAQUE);
                         }
@@ -8790,7 +8792,7 @@ Terminal::draw_rows(VteScreen *screen_,
          * The rect contains the area of the row (enlarged a bit at the top and bottom
          * to allow the text to overdraw a bit), and is moved row-wise in the loop.
          */
-        rect = cairo_rectangle_int_t{-m_padding.left,
+        rect = cairo_rectangle_int_t{-m_border.left,
                                      start_y - cell_overflow_top(),
                                      rect_width,
                                      row_height + cell_overflow_top() + cell_overflow_bottom()};
@@ -9189,7 +9191,7 @@ Terminal::paint_im_preedit_string()
 #if VTE_GTK == 3
 
 void
-Terminal::widget_draw(cairo_t* cr)
+Terminal::widget_draw(cairo_t* cr) noexcept
 {
 #ifdef VTE_DEBUG
         _VTE_DEBUG_IF(VTE_DEBUG_LIFECYCLE | VTE_DEBUG_WORK | VTE_DEBUG_UPDATES) do {
@@ -9205,21 +9207,66 @@ Terminal::widget_draw(cairo_t* cr)
         } while (0);
 #endif /* VTE_DEBUG */
 
+        /* Transform to view coordinates */
+        cairo_translate(cr, m_border.left, m_border.top);
+
         auto region = vte_cairo_get_clip_region(cr);
         if (!region)
                 return;
 
-        /* Transform to view coordinates */
-        cairo_region_translate(region.get(), -m_padding.left, -m_padding.top);
+        /* Both cr and region should be in view coordinates now.
+         * No need to further translation.
+         */
 
-        draw(cr, region.get());
+        //        cairo_region_translate(region.get(), -m_border.left, -m_border.top);
+
+        return draw(cr, region.get());
 }
 
 #endif /* VTE_GTK == 3 */
 
+#if VTE_GTK == 4
+
+void
+Terminal::widget_snapshot(GtkSnapshot* snapshot_object) noexcept
+{
+        _vte_debug_print(VTE_DEBUG_DRAW, "Widget snapshot\n");
+
+        auto const rect = allocated_rect();
+
+        /* We need to draw the border too, so make the rect wider than the widget's
+         * allocated area.
+         */
+        auto grect = vte::graphene::make_rect(-m_style_border.left,
+                                              -m_style_border.top,
+                                              rect->width + m_style_border.left + m_style_border.right,
+                                              rect->height + m_style_border.top + m_style_border.bottom);
+        auto cr = vte::take_freeable(gtk_snapshot_append_cairo(snapshot_object, &grect));
+
+        cairo_translate(cr.get(),
+                        m_border.left,
+                        m_border.top);
+
+        auto const clip_rect = cairo_rectangle_int_t{
+                -m_style_border.left - m_border.left,
+                -m_style_border.top - m_border.top,
+                rect->width + m_style_border.left + m_style_border.right,
+                rect->height + m_style_border.top + m_style_border.bottom};
+
+        auto const region = vte::take_freeable(cairo_region_create_rectangle(&clip_rect));
+
+        /* Both cr and region should be in view coordinates, relative to
+         * (rect.x, rect.y) here. No need to further translation.
+         */
+
+        return draw(cr.get(), region.get());
+}
+
+#endif /* VTE_GTK == 4 */
+
 void
 Terminal::draw(cairo_t* cr,
-               cairo_region_t const* region)
+               cairo_region_t const* region) noexcept
 {
         int allocated_width, allocated_height;
         int extra_area_for_cursor;
@@ -9232,23 +9279,43 @@ Terminal::draw(cairo_t* cr,
         allocated_width = get_allocated_width();
         allocated_height = get_allocated_height();
 
+        /* Note: @cr's origin is at the top left of the view area; the left/top border
+         * is entirely to the left/top of this point.
+         */
+
        /* Designate the start of the drawing operation and clear the area. */
        m_draw.set_cairo(cr);
 
         if (G_LIKELY(m_clear_background)) {
-                m_draw.clear(0, 0,
-                                 allocated_width, allocated_height,
-                                 get_color(VTE_DEFAULT_BG), m_background_alpha);
+                m_draw.clear(
+#if VTE_GTK == 3
+                             -m_border.left,
+                             -m_border.top,
+                             allocated_width,
+                             allocated_height,
+#elif VTE_GTK == 4
+                             -m_border.left - m_style_border.left,
+                             -m_border.top - m_style_border.top,
+                             allocated_width + m_style_border.left + m_style_border.right,
+                             allocated_height + m_style_border.top + m_style_border.bottom,
+#endif
+                             get_color(VTE_DEFAULT_BG), m_background_alpha);
         }
 
         /* Clip vertically, for the sake of smooth scrolling. We want the top and bottom paddings to be 
unused.
          * Don't clip horizontally so that antialiasing can legally overflow to the right padding. */
         cairo_save(cr);
-        cairo_rectangle(cr, 0, m_padding.top, allocated_width, allocated_height - m_padding.top - 
m_padding.bottom);
+        cairo_rectangle(cr,
+                        -m_border.left,
+                        0,
+#if VTE_GTK == 3
+                        allocated_width,
+#elif VTE_GTK == 4
+                        allocated_width + m_style_border.left + m_style_border.right,
+#endif
+                        allocated_height - m_border.top - m_border.bottom);
         cairo_clip(cr);
 
-        cairo_translate(cr, m_padding.left, m_padding.top);
-
 #ifdef WITH_SIXEL
        /* Draw images */
        if (m_images_enabled) {
@@ -9305,10 +9372,18 @@ Terminal::draw(cairo_t* cr,
         /* TODOegmont: It's really ugly to do it here. */
         cairo_save(cr);
         extra_area_for_cursor = (decscusr_cursor_shape() == CursorShape::eBLOCK && !m_has_focus) ? 
VTE_LINE_WIDTH : 0;
-        cairo_rectangle(cr, 0, m_padding.top - extra_area_for_cursor, allocated_width, allocated_height - 
m_padding.top - m_padding.bottom + 2 * extra_area_for_cursor);
-        cairo_clip(cr);
 
-        cairo_translate(cr, m_padding.left, m_padding.top);
+        cairo_rectangle(cr,
+                        -m_border.left,
+                        -extra_area_for_cursor,
+#if VTE_GTK == 3
+                        allocated_width,
+#elif VTE_GTK == 4
+                        allocated_width + m_style_border.left + m_style_border.right,
+#endif
+                        allocated_height - m_border.top - m_border.bottom + 2 * extra_area_for_cursor);
+
+        cairo_clip(cr);
 
        paint_cursor();
 
@@ -10451,8 +10526,8 @@ Terminal::invalidate_dirty_rects_and_process_updates()
 
         auto allocation = get_allocated_rect();
         cairo_region_translate(region,
-                               allocation.x + m_padding.left,
-                               allocation.y + m_padding.top);
+                               allocation.x + m_border.left,
+                               allocation.y + m_border.top);
 
        /* and perform the merge with the window visible area */
         gtk_widget_queue_draw_region(m_widget, region);
diff --git a/src/vteaccess.cc b/src/vteaccess.cc
index 8cf6feee..302635a4 100644
--- a/src/vteaccess.cc
+++ b/src/vteaccess.cc
@@ -1582,8 +1582,8 @@ vte_terminal_accessible_set_size(AtkComponent *component,
         /* If the size is an exact multiple of the cell size, use that,
          * otherwise round down. */
         try {
-                width -= impl->m_padding.left + impl->m_padding.right;
-                height -= impl->m_padding.top + impl->m_padding.bottom;
+                width -= impl->m_border.left + impl->m_border.right;
+                height -= impl->m_border.top + impl->m_border.bottom;
 
                 auto columns = width / impl->m_cell_width;
                 auto rows = height / impl->m_cell_height;
diff --git a/src/vtegtk.cc b/src/vtegtk.cc
index f94b8121..dba6ed76 100644
--- a/src/vtegtk.cc
+++ b/src/vtegtk.cc
@@ -2439,10 +2439,8 @@ vte_terminal_class_init(VteTerminalClass *klass)
 #endif
         gtk_css_provider_load_from_data (GTK_CSS_PROVIDER (klass->priv->style_provider),
                                          "VteTerminal, " VTE_TERMINAL_CSS_NAME " {\n"
-#if VTE_GTK == 3
                                          "padding: 1px 1px 1px 1px;\n"
-#endif
-#if GTK_CHECK_VERSION (3, 24, 22)
+#if (VTE_GTK == 4) || ((VTE_GTK == 3) && GTK_CHECK_VERSION (3, 24, 22))
                                          "background-color: @text_view_bg;\n"
 #else
                                          "background-color: @theme_base_color;\n"
diff --git a/src/vteinternal.hh b/src/vteinternal.hh
index 54409499..c00f34c1 100644
--- a/src/vteinternal.hh
+++ b/src/vteinternal.hh
@@ -730,12 +730,21 @@ public:
         double m_undercurl_thickness{VTE_LINE_WIDTH};
 
         /* Style stuff */
+        /* On gtk3, the style border (comprising padding, margins and border)
+         * is part of the widget's allocation; on gtk4, it's outside of it.
+         */
+        GtkBorder m_style_border{
 #if VTE_GTK == 3
-        GtkBorder m_style_padding{1, 1, 1, 1};
+                1, 1, 1, 1
 #elif VTE_GTK == 4
-        GtkBorder m_style_padding{0, 0, 0, 0};
+                0, 0, 0, 0
 #endif
-        GtkBorder m_padding{m_style_padding};
+        };
+        /* The total padding. On gtk3, this comprises the style border as above,
+         * plus the inner border due to [xy]align and [xy]fill properties; on gtk4,
+         * it comprises only the latter.
+         */
+        GtkBorder m_border{m_style_border};
 
         /* Hyperlinks */
         bool m_allow_hyperlink{false};
@@ -857,8 +866,8 @@ public:
         void set_allocated_rect(cairo_rectangle_int_t const& r) { m_allocated_rect = r; 
update_view_extents(); }
         void update_view_extents() {
                 m_view_usable_extents =
-                        vte::view::extents(m_allocated_rect.width - m_padding.left - m_padding.right,
-                                           m_allocated_rect.height - m_padding.top - m_padding.bottom);
+                        vte::view::extents(m_allocated_rect.width - m_border.left - m_border.right,
+                                           m_allocated_rect.height - m_border.top - m_border.bottom);
         }
 
         bool widget_realized() const noexcept;
@@ -886,7 +895,7 @@ public:
         void confine_coordinates(long *xp,
                                  long *yp);
 
-        void set_border_padding(GtkBorder const* padding);
+        bool set_style_border(GtkBorder const& border) noexcept;
         void set_cursor_aspect(float aspect);
 
         void widget_copy(vte::platform::ClipboardType selection,
@@ -916,12 +925,14 @@ public:
         bool widget_key_modifiers(unsigned modifiers);
 #endif /* VTE_GTK == 4 */
 #if VTE_GTK == 3
-        void widget_draw(cairo_t *cr);
+        void widget_draw(cairo_t *cr) noexcept;
+#elif VTE_GTK == 4
+        void widget_snapshot(GtkSnapshot* snapshot_object) noexcept;
 #endif /* VTE_GTK == 3 */
         void widget_measure_width(int *minimum_width,
-                                  int *natural_width);
+                                  int *natural_width) noexcept;
         void widget_measure_height(int *minimum_height,
-                                   int *natural_height);
+                                   int *natural_height) noexcept;
 
 #if VTE_GTK == 3
         void widget_size_allocate(int x,
@@ -932,7 +943,7 @@ public:
                                   Alignment xalign,
                                   Alignment yalign,
                                   bool xfill,
-                                  bool yfill);
+                                  bool yfill) noexcept;
 #elif VTE_GTK == 4
         void widget_size_allocate(int width,
                                   int height,
@@ -940,7 +951,7 @@ public:
                                   Alignment xalign,
                                   Alignment yalign,
                                   bool xfill,
-                                  bool yfill);
+                                  bool yfill) noexcept;
 #endif /* VTE_GTK */
 
         void set_blink_settings(bool blink,
@@ -948,7 +959,7 @@ public:
                                 int blink_timeout) noexcept;
 
         void draw(cairo_t *cr,
-                  cairo_region_t const* region);
+                  cairo_region_t const* region) noexcept;
         void paint_cursor();
         void paint_im_preedit_string();
         void draw_cells(vte::view::DrawingContext::TextRequest* items,
diff --git a/src/widget.cc b/src/widget.cc
index 264a72cc..47baa04e 100644
--- a/src/widget.cc
+++ b/src/widget.cc
@@ -32,10 +32,6 @@
 #include "debug.h"
 #include "gobject-glue.hh"
 
-#if VTE_GTK == 4
-#include "graphene-glue.hh"
-#endif
-
 #if VTE_GTK == 3
 #define VTE_STYLE_CLASS_MONOSPACE GTK_STYLE_CLASS_MONOSPACE
 #elif VTE_GTK == 4
@@ -702,14 +698,15 @@ Widget::constructed() noexcept
 void
 Widget::css_changed(GtkCssStyleChange* change)
 {
-        padding_changed();
-
         /* This function is inefficient, since there's no public API
          * for GtkCssStyleChange to see what exactly changed, and if
-         * we do need to queue the resize for it or not; so we must
-         * always do so.
+         * we do need to queue the resize for it or not.
          */
-        gtk_widget_queue_resize(gtk());
+
+        auto need_resize = padding_changed();
+
+        if (need_resize)
+                gtk_widget_queue_resize(gtk());
 }
 
 #endif /* VTE_GTK == 4 */
@@ -1510,7 +1507,7 @@ Widget::measure(GtkOrientation orientation,
                 int* minimum,
                 int* natural,
                 int* minimum_baseline,
-                int* natural_baseline)
+                int* natural_baseline) noexcept
 {
         _vte_debug_print(VTE_DEBUG_WIDGET_SIZE, "Widget measure for_size=%d orientation=%s\n",
                          for_size,
@@ -1529,19 +1526,22 @@ Widget::measure(GtkOrientation orientation,
 
 #endif /* VTE_GTK == 4 */
 
-void
-Widget::padding_changed()
+bool
+Widget::padding_changed() noexcept
 {
-#if VTE_GTK == 3
         auto padding = GtkBorder{};
-        auto context = gtk_widget_get_style_context(gtk());
+        auto const context = gtk_widget_get_style_context(gtk());
         gtk_style_context_get_padding(context,
 #if VTE_GTK == 3
                                       gtk_style_context_get_state(context),
 #endif
                                       &padding);
-        terminal()->set_border_padding(&padding);
-#endif /* VTE_GTK FIXMEgtk4 how to handle margin/padding? */
+
+        /* FIXMEchpe: do we need to add the border from
+         * gtk_style_context_get_border() to the padding?
+         */
+
+        return terminal()->set_style_border(padding);
 }
 
 bool
@@ -1909,22 +1909,6 @@ Widget::state_flags_changed(GtkStateFlags old_flags)
         _vte_debug_print(VTE_DEBUG_STYLE, "Widget state flags changed\n");
 }
 
-#if VTE_GTK == 4
-
-void
-Widget::snapshot(GtkSnapshot* snapshot_object)
-{
-        _vte_debug_print(VTE_DEBUG_DRAW, "Widget snapshot\n");
-
-        auto rect = terminal()->allocated_rect();
-        auto region = vte::take_freeable(cairo_region_create_rectangle(rect));
-        auto grect = vte::graphene::make_rect(rect);
-        auto cr = vte::take_freeable(gtk_snapshot_append_cairo(snapshot_object, &grect));
-        terminal()->draw(cr.get(), region.get());
-}
-
-#endif /* VTE_GTK == 4 */
-
 #if VTE_GTK == 3
 
 void
@@ -1932,13 +1916,17 @@ Widget::style_updated() noexcept
 {
         _vte_debug_print(VTE_DEBUG_STYLE, "Widget style changed\n");
 
-        padding_changed();
+        auto need_resize = padding_changed();
 
         auto aspect = float{};
         gtk_widget_style_get(gtk(), "cursor-aspect-ratio", &aspect, nullptr);
         m_terminal->set_cursor_aspect(aspect);
 
         m_terminal->widget_style_updated();
+
+        if (need_resize)
+                gtk_widget_queue_resize(m_widget);
+
 }
 
 #endif /* VTE_GTK == 3 */
diff --git a/src/widget.hh b/src/widget.hh
index 2acb0e07..448ef58d 100644
--- a/src/widget.hh
+++ b/src/widget.hh
@@ -278,7 +278,7 @@ public:
                            GtkTooltip* tooltip) noexcept;
 
         void connect_settings();
-        void padding_changed();
+        bool padding_changed() noexcept;
         void settings_changed();
 
 #if VTE_GTK == 3
@@ -315,11 +315,11 @@ public:
                      int* minimum,
                      int* natural,
                      int* minimum_baseline,
-                     int* natural_baseline);
+                     int* natural_baseline) noexcept;
         std::pair<bool, bool> compute_expand();
         void css_changed(GtkCssStyleChange* change);
         void system_setting_changed(GtkSystemSetting setting);
-        void snapshot(GtkSnapshot* snapshot_object);
+        void snapshot(GtkSnapshot* snapshot) noexcept { terminal()->widget_snapshot(snapshot); }
         bool contains(double x,
                       double y);
         void display_changed() noexcept;


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