From 1084ba988d4f46ee2cc4642ec9560a69eee50526 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=96yvind=20S=C3=A6ther?= <oyvinds@everdot.org>
Date: Mon, 31 Aug 2020 05:26:58 +0200
Subject: [PATCH] All  Xfce-Classic / libxfce4ui-nocsd changes per 2020-08-31

---
 libxfce4ui/Makefile.am             |   2 +
 libxfce4ui/libxfce4ui-dialog-ui.ui |   4 +-
 libxfce4ui/xfce-dialogs.c          |   7 -
 libxfce4ui/xfce-heading.c          | 546 +++++++++++++++++++++++++++++
 libxfce4ui/xfce-heading.h          |  57 +++
 libxfce4ui/xfce-titled-dialog.c    | 430 +++++------------------
 libxfce4ui/xfce-titled-dialog.h    |  36 +-
 7 files changed, 719 insertions(+), 363 deletions(-)
 create mode 100644 libxfce4ui/xfce-heading.c
 create mode 100644 libxfce4ui/xfce-heading.h

diff --git a/libxfce4ui/Makefile.am b/libxfce4ui/Makefile.am
index 49edf47..b008ef6 100644
--- a/libxfce4ui/Makefile.am
+++ b/libxfce4ui/Makefile.am
@@ -46,6 +46,8 @@ libxfce4ui_sources = \
 	xfce-dialogs.c \
 	xfce-gdk-extensions.c \
 	xfce-gtk-extensions.c \
+	xfce-heading.c \
+	xfce-heading.h \
 	xfce-sm-client.c \
 	xfce-spawn.c \
 	xfce-filename-input.c \
diff --git a/libxfce4ui/libxfce4ui-dialog-ui.ui b/libxfce4ui/libxfce4ui-dialog-ui.ui
index 619a744..a82743c 100644
--- a/libxfce4ui/libxfce4ui-dialog-ui.ui
+++ b/libxfce4ui/libxfce4ui-dialog-ui.ui
@@ -2,9 +2,9 @@
 <!-- Generated with glade 3.18.3 -->
 <interface>
   <requires lib="gtk+" version="3.12"/>
-  <object class="GtkMessageDialog" id="xfce4ui-dialog">
+  <object class="GtkDialog" id="xfce4ui-dialog">
     <property name="can_focus">False</property>
-    <property name="message_type">GTK_MESSAGE_OTHER</property>
+    <property name="type_hint">dialog</property>
     <child internal-child="vbox">
       <object class="GtkBox" id="dialog-vbox1">
         <property name="can_focus">False</property>
diff --git a/libxfce4ui/xfce-dialogs.c b/libxfce4ui/xfce-dialogs.c
index cd505da..2949bec 100644
--- a/libxfce4ui/xfce-dialogs.c
+++ b/libxfce4ui/xfce-dialogs.c
@@ -587,7 +587,6 @@ xfce_message_dialog_new_valist (GtkWindow   *parent,
   GtkWidget   *dialog_image;
   GtkWidget   *image;
   GtkWidget   *button;
-  GtkWidget   *content_area;
   GtkWidget   *label_box;
   const gchar *text = first_button_text;
   const gchar *label;
@@ -595,7 +594,6 @@ xfce_message_dialog_new_valist (GtkWindow   *parent,
   gint         response;
   GdkPixbuf   *pixbuf, *scaled;
   gint         w, h;
-  GList       *children;
 
   g_return_val_if_fail (primary_text != NULL || secondary_text != NULL, NULL);
   g_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), NULL);
@@ -608,11 +606,6 @@ xfce_message_dialog_new_valist (GtkWindow   *parent,
   dialog_image = GTK_WIDGET(gtk_builder_get_object(gxml, "icon_stock_id"));
   gtk_window_set_default_size (GTK_WINDOW (dialog), 500, -1);
 
-  /* Remove the original message area of the GtkMessageDialog as we add our own */
-  content_area = GTK_WIDGET (gtk_dialog_get_content_area (GTK_DIALOG (dialog)));
-  children = gtk_container_get_children (GTK_CONTAINER (content_area));
-  gtk_container_remove (GTK_CONTAINER (content_area), GTK_WIDGET ((g_list_nth (children, 1))->data));
-
   if (parent)
     {
       gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
diff --git a/libxfce4ui/xfce-heading.c b/libxfce4ui/xfce-heading.c
new file mode 100644
index 0000000..fa00141
--- /dev/null
+++ b/libxfce4ui/xfce-heading.c
@@ -0,0 +1,546 @@
+/*
+ * Copyright (c) 2006 Benedikt Meurer <benny@xfce.org>.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <libxfce4ui/xfce-heading.h>
+#include <libxfce4ui/libxfce4ui-private.h>
+#include <libxfce4ui/libxfce4ui-alias.h>
+
+
+
+#define XFCE_HEADING_BORDER      6
+#define XFCE_HEADING_SPACING    12
+#define XFCE_HEADING_ICON_SIZE  48
+
+
+static void         _xfce_heading_finalize             (GObject          *object);
+static void         _xfce_heading_realize              (GtkWidget        *widget);
+static void         _xfce_heading_size_request         (GtkWidget        *widget,
+                                                        GtkRequisition   *requisition);
+static void         _xfce_heading_get_preferred_width  (GtkWidget        *widget,
+                                                        gint             *min,
+                                                        gint             *natural);
+static void         _xfce_heading_get_preferred_height (GtkWidget        *widget,
+                                                        gint             *min,
+                                                        gint             *natural);
+static gboolean     _xfce_heading_draw                 (GtkWidget        *widget,
+                                                        cairo_t          *ctx);
+static AtkObject   *_xfce_heading_get_accessible       (GtkWidget        *widget);
+static PangoLayout *_xfce_heading_make_layout          (XfceHeading      *heading);
+static GdkPixbuf   *_xfce_heading_make_pixbuf          (XfceHeading      *heading);
+
+
+
+
+struct _XfceHeadingClass
+{
+  /*< private >*/
+  GtkWidgetClass __parent__;
+};
+
+struct _XfceHeading
+{
+  /*< private >*/
+  GtkWidget       __parent__;
+
+  GdkPixbuf       *icon;
+  gchar           *icon_name;
+  gchar           *subtitle;
+  gchar           *title;
+};
+
+
+
+G_DEFINE_TYPE (XfceHeading, _xfce_heading, GTK_TYPE_WIDGET)
+
+
+
+static void
+_xfce_heading_class_init (XfceHeadingClass *klass)
+{
+  GtkWidgetClass *gtkwidget_class;
+  GObjectClass   *gobject_class;
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = _xfce_heading_finalize;
+
+  gtkwidget_class = GTK_WIDGET_CLASS (klass);
+  gtkwidget_class->realize = _xfce_heading_realize;
+  gtkwidget_class->get_accessible = _xfce_heading_get_accessible;
+  gtkwidget_class->get_preferred_width = _xfce_heading_get_preferred_width;
+  gtkwidget_class->get_preferred_height = _xfce_heading_get_preferred_height;
+  gtkwidget_class->draw = _xfce_heading_draw;
+}
+
+
+
+static void
+_xfce_heading_init (XfceHeading *heading)
+{
+  /* setup the widget parameters */
+  gtk_widget_set_has_window (GTK_WIDGET (heading), TRUE);
+}
+
+
+
+static void
+_xfce_heading_finalize (GObject *object)
+{
+  XfceHeading *heading = XFCE_HEADING (object);
+
+  /* release the private data */
+  if (G_UNLIKELY (heading->icon != NULL))
+    g_object_unref (G_OBJECT (heading->icon));
+
+  g_free (heading->icon_name);
+  g_free (heading->subtitle);
+  g_free (heading->title);
+
+  (*G_OBJECT_CLASS (_xfce_heading_parent_class)->finalize) (object);
+}
+
+
+
+static void
+_xfce_heading_realize (GtkWidget *widget)
+{
+  GdkWindowAttr  attributes;
+  GtkAllocation  allocation;
+  GdkWindow     *window;
+
+  /* mark the widget as realized */
+  gtk_widget_set_realized (widget, TRUE);
+  gtk_widget_get_allocation (widget, &allocation);
+
+  /* setup the window attributes */
+  attributes.x = allocation.x;
+  attributes.y = allocation.y;
+  attributes.width = allocation.width;
+  attributes.height = allocation.height;
+  attributes.wclass = GDK_INPUT_OUTPUT;
+  attributes.window_type = GDK_WINDOW_CHILD;
+  attributes.visual = gtk_widget_get_visual (widget);
+  attributes.event_mask = gtk_widget_get_events (widget)
+                        | GDK_EXPOSURE_MASK;
+
+  /* allocate the widget window */
+  window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes,
+                           GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL);
+  gtk_widget_set_window (widget, window);
+  gdk_window_set_user_data (window, widget);
+}
+
+
+
+static void
+_xfce_heading_get_preferred_width (GtkWidget *widget,
+                                   gint      *min,
+                                   gint      *natural)
+{
+  GtkRequisition requisition;
+
+  _xfce_heading_size_request (widget, &requisition);
+
+  *min = *natural = requisition.width;
+}
+
+
+
+static void
+_xfce_heading_get_preferred_height (GtkWidget *widget,
+                                    gint      *min,
+                                    gint      *natural)
+{
+
+  GtkRequisition requisition;
+
+  _xfce_heading_size_request (widget, &requisition);
+
+  *min = *natural = requisition.height;
+}
+
+
+
+static gboolean
+_xfce_heading_draw (GtkWidget *widget,
+                    cairo_t   *ctx)
+{
+  XfceHeading     *heading = XFCE_HEADING (widget);
+  PangoLayout     *layout;
+  GdkPixbuf       *pixbuf;
+  gboolean         rtl;
+  gint             width;
+  gint             height;
+  gint             x;
+  gint             y;
+  GtkAllocation    allocation;
+  GtkStyleContext *context;
+
+  gtk_widget_get_allocation (widget, &allocation);
+
+  context = gtk_widget_get_style_context (widget);
+
+  gtk_style_context_save (context);
+  /* Add "view" as default style class as that resembles the "base color" look of Gtk2 best */
+  gtk_style_context_add_class (context, "view");
+  gtk_style_context_add_class (context, "XfceHeading");
+
+  /* check if we should render from right to left */
+  rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
+
+  /* determine the initial horizontal position */
+  x = (rtl ? allocation.width - XFCE_HEADING_BORDER : XFCE_HEADING_BORDER);
+
+  gtk_render_background (context, ctx,
+                         allocation.x, allocation.y,
+                         allocation.x + allocation.width,
+                         allocation.y + allocation.height);
+
+  /* check if we have a pixbuf to render */
+  pixbuf = _xfce_heading_make_pixbuf (heading);
+  if (G_LIKELY (pixbuf != NULL))
+    {
+      /* determine the pixbuf dimensions */
+      width = gdk_pixbuf_get_width (pixbuf);
+      height = gdk_pixbuf_get_height (pixbuf);
+
+      /* determine the vertical position */
+      y = (allocation.height - height) / 2;
+
+      gtk_render_icon (context, ctx,
+                       pixbuf,
+                       rtl ? x - width : x,
+                       y);
+
+      /* release the pixbuf */
+      g_object_unref (G_OBJECT (pixbuf));
+
+      /* advance the horizontal position */
+      x += (rtl ? -1 : 1) * (width + XFCE_HEADING_SPACING);
+    }
+
+  /* generate the title layout */
+  layout = _xfce_heading_make_layout (heading);
+  pango_layout_get_pixel_size (layout, &width, &height);
+
+  /* determine the vertical position */
+  y = (allocation.height - height) / 2;
+
+  gtk_render_layout (context, ctx,
+                     rtl ? x - width : x, y,
+                     layout);
+
+  /* release the layout */
+  g_object_unref (G_OBJECT (layout));
+
+  gtk_style_context_restore (context);
+
+  return FALSE;
+}
+
+
+
+static void
+_xfce_heading_size_request (GtkWidget      *widget,
+                            GtkRequisition *requisition)
+{
+  XfceHeading *heading = XFCE_HEADING (widget);
+  PangoLayout *layout;
+  GdkPixbuf   *pixbuf;
+  gint         layout_width;
+  gint         layout_height;
+  gint         pixbuf_width = 0;
+  gint         pixbuf_height = 0;
+
+  /* determine the dimensions of the title text */
+  layout = _xfce_heading_make_layout (heading);
+  pango_layout_get_pixel_size (layout, &layout_width, &layout_height);
+  g_object_unref (G_OBJECT (layout));
+
+  /* determine the dimensions of the pixbuf */
+  pixbuf = _xfce_heading_make_pixbuf (heading);
+  if (G_LIKELY (pixbuf != NULL))
+    {
+      pixbuf_width = gdk_pixbuf_get_width (pixbuf);
+      pixbuf_height = gdk_pixbuf_get_height (pixbuf);
+      g_object_unref (G_OBJECT (pixbuf));
+    }
+
+  /* determine the base dimensions */
+  requisition->width = layout_width + pixbuf_width + ((pixbuf_width > 0) ? XFCE_HEADING_SPACING : 0);
+  requisition->height = MAX (XFCE_HEADING_ICON_SIZE, MAX (pixbuf_height, layout_height));
+
+  /* add border size */
+  requisition->width += 2 * XFCE_HEADING_BORDER;
+  requisition->height += 2 * XFCE_HEADING_BORDER;
+}
+
+
+
+static AtkObject*
+_xfce_heading_get_accessible (GtkWidget *widget)
+{
+  AtkObject *object;
+
+  object = (*GTK_WIDGET_CLASS (_xfce_heading_parent_class)->get_accessible) (widget);
+  atk_object_set_role (object, ATK_ROLE_HEADER);
+
+  return object;
+}
+
+
+
+static PangoLayout*
+_xfce_heading_make_layout (XfceHeading *heading)
+{
+  PangoAttribute *attribute;
+  PangoAttrList  *attr_list;
+  PangoLayout    *layout;
+  GString        *text;
+  gint            title_length = 0;
+
+  /* generate the full text */
+  text = g_string_sized_new (128);
+  if (G_LIKELY (heading->title != NULL))
+    {
+      /* add the main title */
+      title_length = strlen (heading->title);
+      g_string_append (text, heading->title);
+    }
+  if (heading->subtitle != NULL && *heading->subtitle != '\0')
+    {
+      /* add an empty line between the title and the subtitle */
+      if (G_LIKELY (heading->title != NULL))
+        g_string_append (text, "\n");
+
+      /* add the subtitle */
+      g_string_append (text, heading->subtitle);
+    }
+
+  /* allocate and setup a new layout from the widget's context */
+  layout = gtk_widget_create_pango_layout (GTK_WIDGET (heading), text->str);
+
+
+  /* allocate an attribute list (large bold title) */
+  attr_list = pango_attr_list_new ();
+  attribute = pango_attr_scale_new (PANGO_SCALE_LARGE); /* large title */
+  attribute->start_index = 0;
+  attribute->end_index = title_length;
+  pango_attr_list_insert (attr_list, attribute);
+  attribute = pango_attr_weight_new (PANGO_WEIGHT_BOLD); /* bold title */
+  attribute->start_index = 0;
+  attribute->end_index = title_length;
+  pango_attr_list_insert (attr_list, attribute);
+  pango_layout_set_attributes (layout, attr_list);
+  pango_attr_list_unref (attr_list);
+
+  /* cleanup */
+  g_string_free (text, TRUE);
+
+  return layout;
+}
+
+
+
+static GdkPixbuf*
+_xfce_heading_make_pixbuf (XfceHeading *heading)
+{
+  GtkIconTheme *icon_theme;
+  GdkPixbuf    *pixbuf = NULL;
+  GdkScreen    *screen;
+  GdkPixbuf    *scaled;
+
+  if (G_UNLIKELY (heading->icon != NULL))
+    {
+      /* just use the specified icon */
+      pixbuf = g_object_ref (G_OBJECT (heading->icon));
+    }
+  else if (G_LIKELY (heading->icon_name != NULL))
+    {
+      /* determine the icon theme for the current screen */
+      screen = gtk_widget_get_screen (GTK_WIDGET (heading));
+      icon_theme = gtk_icon_theme_get_for_screen (screen);
+
+      /* try to load the icon from the icon theme */
+      pixbuf = gtk_icon_theme_load_icon (icon_theme, heading->icon_name,
+                                         XFCE_HEADING_ICON_SIZE,
+                                         GTK_ICON_LOOKUP_USE_BUILTIN, NULL);
+
+      if (pixbuf != NULL
+          && (gdk_pixbuf_get_height (pixbuf) > XFCE_HEADING_ICON_SIZE
+              || gdk_pixbuf_get_width (pixbuf) > XFCE_HEADING_ICON_SIZE))
+        {
+          /* this doesn't happen often, so be stupid
+           * and assume icons are always squared */
+          scaled = gdk_pixbuf_scale_simple (pixbuf,
+                                            XFCE_HEADING_ICON_SIZE,
+                                            XFCE_HEADING_ICON_SIZE,
+                                            GDK_INTERP_BILINEAR);
+          g_object_unref (pixbuf);
+          pixbuf = scaled;
+        }
+
+      /* cache the icon, this does not take theme changes in account,
+       * but because of the only use in the titled dialog, this works
+       * fine, since the window properties are emitted on icon changes */
+      if (heading->icon == NULL
+          && pixbuf != NULL)
+        heading->icon = g_object_ref (pixbuf);
+    }
+
+  return pixbuf;
+}
+
+
+
+/**
+ * _xfce_heading_set_icon:
+ * @heading : a #XfceHeading.
+ * @icon    : the new icon or %NULL.
+ *
+ * If @icon is not %NULL, @heading will display the new @icon
+ * aside the title. Else, if @icon is %NULL no icon is displayed
+ * unless an icon name was set with _xfce_heading_set_icon_name().
+ **/
+void
+_xfce_heading_set_icon (XfceHeading *heading,
+                        GdkPixbuf   *icon)
+{
+  _libxfce4ui_return_if_fail (XFCE_IS_HEADING (heading));
+  _libxfce4ui_return_if_fail (icon == NULL || GDK_IS_PIXBUF (icon));
+
+  /* check if we have a new icon */
+  if (G_LIKELY (heading->icon != icon))
+    {
+      /* disconnect from the previous icon */
+      if (G_LIKELY (heading->icon != NULL))
+        g_object_unref (G_OBJECT (heading->icon));
+
+      if (icon != NULL)
+        {
+          if (gdk_pixbuf_get_height (icon) > XFCE_HEADING_ICON_SIZE
+              || gdk_pixbuf_get_width (icon) > XFCE_HEADING_ICON_SIZE)
+            {
+              /* this doesn't happen often, so be stupid
+               * and assume icons are always squared */
+              heading->icon = gdk_pixbuf_scale_simple (icon,
+                                                       XFCE_HEADING_ICON_SIZE,
+                                                       XFCE_HEADING_ICON_SIZE,
+                                                       GDK_INTERP_BILINEAR);
+            }
+          else
+            {
+              heading->icon = g_object_ref (icon);
+            }
+        }
+      else
+        {
+          heading->icon = NULL;
+        }
+
+      gtk_widget_queue_resize (GTK_WIDGET (heading));
+    }
+}
+
+
+
+/**
+ * _xfce_heading_set_icon_name:
+ * @heading   : a #XfceHeading.
+ * @icon_name : the new icon name, or %NULL.
+ *
+ * If @icon_name is not %NULL and the "icon" property is set to
+ * %NULL, see _xfce_heading_set_icon(), the @heading will display
+ * the name icon identified by the @icon_name.
+ **/
+void
+_xfce_heading_set_icon_name (XfceHeading *heading,
+                             const gchar *icon_name)
+{
+  _libxfce4ui_return_if_fail (XFCE_IS_HEADING (heading));
+
+  /* activate the new icon name */
+  g_free (heading->icon_name);
+  heading->icon_name = g_strdup (icon_name);
+
+  gtk_widget_queue_resize (GTK_WIDGET (heading));
+}
+
+
+
+/**
+ * _xfce_heading_set_subtitle:
+ * @heading  : a #XfceHeading.
+ * @subtitle : the new subtitle for @heading, or %NULL.
+ *
+ * If @subtitle is not %NULL and not the empty string, it
+ * will be displayed by @heading below the main title.
+ **/
+void
+_xfce_heading_set_subtitle (XfceHeading *heading,
+                            const gchar *subtitle)
+{
+  _libxfce4ui_return_if_fail (XFCE_IS_HEADING (heading));
+  _libxfce4ui_return_if_fail (subtitle == NULL || g_utf8_validate (subtitle, -1, NULL));
+
+  /* activate the new subtitle */
+  g_free (heading->subtitle);
+  heading->subtitle = g_strdup (subtitle);
+
+  gtk_widget_queue_resize (GTK_WIDGET (heading));
+}
+
+
+
+/**
+ * _xfce_heading_set_title:
+ * @heading : a #XfceHeading.
+ * @title   : the new title for the @heading.
+ *
+ * Sets the title displayed by the @heading to the
+ * specified @title.
+ **/
+void
+_xfce_heading_set_title (XfceHeading *heading,
+                         const gchar *title)
+{
+  _libxfce4ui_return_if_fail (XFCE_IS_HEADING (heading));
+  _libxfce4ui_return_if_fail (title == NULL || g_utf8_validate (title, -1, NULL));
+
+  /* activate the new title */
+  g_free (heading->title);
+  heading->title = g_strdup (title);
+
+  gtk_widget_queue_resize (GTK_WIDGET (heading));
+}
+
+
+
+#define __XFCE_HEADING_C__
+#include <libxfce4ui/libxfce4ui-aliasdef.c>
diff --git a/libxfce4ui/xfce-heading.h b/libxfce4ui/xfce-heading.h
new file mode 100644
index 0000000..03bd379
--- /dev/null
+++ b/libxfce4ui/xfce-heading.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2006 Benedikt Meurer <benny@xfce.org>.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#if !defined (LIBXFCE4UI_INSIDE_LIBXFCE4UI_H) && !defined (LIBXFCE4UI_COMPILATION)
+#error "Only <libxfce4ui/libxfce4ui.h> can be included directly, this file is not part of the public API."
+#endif
+
+#ifndef __XFCE_HEADING_H__
+#define __XFCE_HEADING_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+typedef struct _XfceHeadingClass   XfceHeadingClass;
+typedef struct _XfceHeading        XfceHeading;
+
+#define XFCE_TYPE_HEADING             (_xfce_heading_get_type ())
+#define XFCE_HEADING(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFCE_TYPE_HEADING, XfceHeading))
+#define XFCE_HEADING_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), XFCE_TYPE_HEADING, XfceHeadingClass))
+#define XFCE_IS_HEADING(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XFCE_TYPE_HEADING))
+#define XFCE_IS_HEADING_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), XFCE_TYPE_HEADING))
+#define XFCE_HEADING_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), XFCE_TYPE_HEADING, XfceHeadingClass))
+
+GType      _xfce_heading_get_type      (void) G_GNUC_CONST;
+
+void       _xfce_heading_set_icon      (XfceHeading *heading,
+                                        GdkPixbuf   *icon);
+
+void       _xfce_heading_set_icon_name (XfceHeading *heading,
+                                        const gchar *icon_name);
+
+void       _xfce_heading_set_subtitle  (XfceHeading *heading,
+                                        const gchar *subtitle);
+
+void       _xfce_heading_set_title     (XfceHeading *heading,
+                                        const gchar *title);
+
+G_END_DECLS
+
+#endif /* !__XFCE_HEADING_H__ */
diff --git a/libxfce4ui/xfce-titled-dialog.c b/libxfce4ui/xfce-titled-dialog.c
index 7587f36..8fc2803 100644
--- a/libxfce4ui/xfce-titled-dialog.c
+++ b/libxfce4ui/xfce-titled-dialog.c
@@ -1,5 +1,7 @@
 /*
  * Copyright (c) 2006 Benedikt Meurer <benny@xfce.org>.
+ * Copyright (c) 2020 Shawn Anastasio
+ * Copyright (c) 2020 Öyvind Sæther
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -38,6 +40,7 @@
 
 #include <gdk/gdkkeysyms.h>
 
+#include <libxfce4ui/xfce-heading.h>
 #include <libxfce4ui/xfce-titled-dialog.h>
 #include <libxfce4ui/libxfce4ui-private.h>
 #include <libxfce4ui/libxfce4ui-alias.h>
@@ -55,29 +58,21 @@ enum
   PROP_SUBTITLE,
 };
 
-
-static GObject *xfce_titled_dialog_constructor    (GType                   type,
-                                                   guint                   n_construct_params,
-                                                   GObjectConstructParam  *construct_params);
-static void     xfce_titled_dialog_finalize       (GObject                *object);
-static void     xfce_titled_dialog_get_property   (GObject                *object,
-                                                   guint                   prop_id,
-                                                   GValue                 *value,
-                                                   GParamSpec             *pspec);
-static void     xfce_titled_dialog_set_property   (GObject                *object,
-                                                   guint                   prop_id,
-                                                   const GValue           *value,
-                                                   GParamSpec             *pspec);
-static void     xfce_titled_dialog_close          (GtkDialog              *dialog);
-static void     xfce_titled_dialog_update_icon    (XfceTitledDialog       *titled_dialog);
-
-
+static void xfce_titled_dialog_finalize       (GObject                *object);
+static void xfce_titled_dialog_get_property   (GObject                *object,
+                                               guint                   prop_id,
+                                               GValue                 *value,
+                                               GParamSpec             *pspec);
+static void xfce_titled_dialog_set_property   (GObject                *object,
+                                               guint                   prop_id,
+                                               const GValue           *value,
+                                               GParamSpec             *pspec);
+static void xfce_titled_dialog_close          (GtkDialog              *dialog);
+static void xfce_titled_dialog_update_heading (XfceTitledDialog       *titled_dialog);
 
 struct _XfceTitledDialogPrivate
 {
-  GtkWidget *headerbar;
-  GtkWidget *icon;
-  GtkWidget *action_area;
+  GtkWidget *heading;
   gchar     *subtitle;
 };
 
@@ -105,7 +100,7 @@ xfce_titled_dialog_class_init (XfceTitledDialogClass *klass)
   g_type_class_add_private (klass, sizeof (XfceTitledDialogPrivate));
 
   gobject_class = G_OBJECT_CLASS (klass);
-  gobject_class->constructor = xfce_titled_dialog_constructor;
+  gobject_class->finalize = xfce_titled_dialog_finalize;
   gobject_class->get_property = xfce_titled_dialog_get_property;
   gobject_class->set_property = xfce_titled_dialog_set_property;
   gobject_class->finalize = xfce_titled_dialog_finalize;
@@ -134,43 +129,44 @@ xfce_titled_dialog_class_init (XfceTitledDialogClass *klass)
 }
 
 
-
-static GObject *
-xfce_titled_dialog_constructor (GType                  type,
-                                guint                  n_construct_params,
-                                GObjectConstructParam *construct_params)
-{
-  GObject *object;
-
-  object = G_OBJECT_CLASS (xfce_titled_dialog_parent_class)->constructor (type,
-                                                           n_construct_params,
-                                                           construct_params);
-  g_object_set (G_OBJECT (object), "use-header-bar", TRUE, NULL);
-
-  return object;
-}
-
-
-
 static void
 xfce_titled_dialog_init (XfceTitledDialog *titled_dialog)
 {
+  GtkWidget *line;
+  GtkWidget *vbox;
+  GtkWidget *content_area;
+
   /* connect the private data */
   titled_dialog->priv = XFCE_TITLED_DIALOG_GET_PRIVATE (titled_dialog);
 
-  /* Get the headerbar of the dialog */
-  titled_dialog->priv->headerbar = gtk_dialog_get_header_bar (GTK_DIALOG (titled_dialog));
-  g_return_if_fail (GTK_IS_HEADER_BAR (titled_dialog->priv->headerbar));
-
-  /* Pack the window icon into the headerbar */
-  titled_dialog->priv->icon = gtk_image_new ();
-  gtk_header_bar_pack_start (GTK_HEADER_BAR (titled_dialog->priv->headerbar), titled_dialog->priv->icon);
-  gtk_header_bar_set_show_close_button (GTK_HEADER_BAR (titled_dialog->priv->headerbar), TRUE);
-  gtk_widget_show (titled_dialog->priv->icon);
-
-  /* make sure to update the icon whenever one of the relevant window properties changes */
-  g_signal_connect (G_OBJECT (titled_dialog), "notify::icon", G_CALLBACK (xfce_titled_dialog_update_icon), NULL);
-  g_signal_connect (G_OBJECT (titled_dialog), "notify::icon-name", G_CALLBACK (xfce_titled_dialog_update_icon), NULL);
+  /* remove the main dialog box from the window */
+  content_area = gtk_dialog_get_content_area (GTK_DIALOG (titled_dialog));
+  g_object_ref (G_OBJECT (content_area));
+  gtk_container_remove (GTK_CONTAINER (titled_dialog), content_area);
+
+  /* add a new vbox w/o border to the main window */
+  vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+  gtk_container_add (GTK_CONTAINER (titled_dialog), vbox);
+  gtk_widget_show (vbox);
+
+  /* add the heading to the window */
+  titled_dialog->priv->heading = g_object_new (XFCE_TYPE_HEADING, NULL);
+  gtk_box_pack_start (GTK_BOX (vbox), titled_dialog->priv->heading, FALSE, FALSE, 0);
+  gtk_widget_show (titled_dialog->priv->heading);
+
+  /* add the separator between header and content */
+  line = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
+  gtk_box_pack_start (GTK_BOX (vbox), line, FALSE, FALSE, 0);
+  gtk_widget_show (line);
+
+  /* add the main dialog box to the new vbox */
+  gtk_box_pack_start (GTK_BOX (vbox), content_area, TRUE, TRUE, 0);
+  g_object_unref (G_OBJECT(content_area));
+
+  /* make sure to update the heading whenever one of the relevant window properties changes */
+  g_signal_connect (G_OBJECT (titled_dialog), "notify::icon", G_CALLBACK (xfce_titled_dialog_update_heading), NULL);
+  g_signal_connect (G_OBJECT (titled_dialog), "notify::icon-name", G_CALLBACK (xfce_titled_dialog_update_heading), NULL);
+  g_signal_connect (G_OBJECT (titled_dialog), "notify::title", G_CALLBACK (xfce_titled_dialog_update_heading), NULL);
 }
 
 
@@ -252,110 +248,12 @@ xfce_titled_dialog_close (GtkDialog *dialog)
 
 
 static void
-xfce_titled_dialog_update_icon (XfceTitledDialog *titled_dialog)
-{
-  const gchar *icon_name = gtk_window_get_icon_name (GTK_WINDOW (titled_dialog));
-
-  g_return_if_fail (GTK_IS_HEADER_BAR (titled_dialog->priv->headerbar));
-  _libxfce4ui_return_if_fail (icon_name == NULL);
-
-  gtk_image_set_from_icon_name (GTK_IMAGE (titled_dialog->priv->icon), icon_name, GTK_ICON_SIZE_LARGE_TOOLBAR);
-  gtk_image_set_pixel_size (GTK_IMAGE (titled_dialog->priv->icon), 24);
-}
-
-
-/* Borrowed from gtkdialog.c */
-static void
-response_data_free (gpointer data)
-{
-  g_slice_free (ResponseData, data);
-}
-
-
-
-static ResponseData *
-get_response_data (GtkWidget *widget,
-                   gboolean   create)
-{
-  ResponseData *ad = g_object_get_data (G_OBJECT (widget),
-                                        "gtk-dialog-response-data");
-
-  if (ad == NULL && create)
-    {
-      ad = g_slice_new (ResponseData);
-
-      g_object_set_data_full (G_OBJECT (widget),
-                              I_("gtk-dialog-response-data"),
-                              ad,
-                              response_data_free);
-    }
-
-  return ad;
-}
-
-
-
-static void
-action_widget_activated (GtkWidget *widget, GtkDialog *dialog)
+xfce_titled_dialog_update_heading (XfceTitledDialog *titled_dialog)
 {
-  gint response_id;
-
-  response_id = gtk_dialog_get_response_for_widget (dialog, widget);
-
-  gtk_dialog_response (dialog, response_id);
-}
-
-
-
-static void
-add_response_data (GtkDialog *dialog,
-                   GtkWidget *child,
-                   gint       response_id)
-{
-  ResponseData *ad;
-  guint signal_id;
-
-  ad = get_response_data (child, TRUE);
-  ad->response_id = response_id;
-
-  if (GTK_IS_BUTTON (child))
-    signal_id = g_signal_lookup ("clicked", GTK_TYPE_BUTTON);
-  else
-    signal_id = GTK_WIDGET_GET_CLASS (child)->activate_signal;
-
-  if (signal_id)
-    {
-      GClosure *closure;
-
-      closure = g_cclosure_new_object (G_CALLBACK (action_widget_activated),
-                                       G_OBJECT (dialog));
-      g_signal_connect_closure_by_id (child, signal_id, 0, closure, FALSE);
-    }
-  else
-    g_warning ("Only 'activatable' widgets can be packed into the action area of a GtkDialog");
-}
-/* End: Borrowed from gtkdialog.c */
-
-
-
-/* Repack all the buttons that would normally end up in the headerbar to the action area */
-static void
-xfce_titled_dialog_repack_dialog (GtkWidget *action_area,
-                                  GtkWidget *headerbar,
-                                  GtkWidget *button,
-                                  gint       response_id)
-{
-  g_return_if_fail (GTK_IS_WIDGET (action_area));
-  g_return_if_fail (GTK_IS_WIDGET (headerbar));
-  g_return_if_fail (GTK_IS_WIDGET (button));
-
-  g_object_ref (G_OBJECT (button));
-  gtk_container_remove (GTK_CONTAINER (headerbar), button);
-  gtk_container_add (GTK_CONTAINER (action_area), button);
-  g_object_unref (G_OBJECT (button));
-  /* always add help buttons as secondary */
-  if (response_id == GTK_RESPONSE_HELP)
-    gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (action_area), button, TRUE);
+  /* update the heading properties using the window property values */
+  _xfce_heading_set_icon (XFCE_HEADING (titled_dialog->priv->heading), gtk_window_get_icon (GTK_WINDOW (titled_dialog)));
+  _xfce_heading_set_icon_name (XFCE_HEADING (titled_dialog->priv->heading), gtk_window_get_icon_name (GTK_WINDOW (titled_dialog)));
+  _xfce_heading_set_title (XFCE_HEADING (titled_dialog->priv->heading), gtk_window_get_title (GTK_WINDOW (titled_dialog)));
 }
 
 
@@ -387,8 +285,6 @@ xfce_titled_dialog_new (void)
  * parameters and the returned dialog.
  *
  * Return value: the newly allocated #XfceTitledDialog.
- *
- * Deprecated: 4.16: Use #xfce_titled_dialog_new_with_mixed_buttons instead.
  **/
 GtkWidget*
 xfce_titled_dialog_new_with_buttons (const gchar    *title,
@@ -399,9 +295,6 @@ xfce_titled_dialog_new_with_buttons (const gchar    *title,
 {
   const gchar *button_text;
   GtkWidget   *dialog;
-  GtkWidget   *button;
-  GtkWidget   *headerbar;
-  GtkWidget   *action_area;
   va_list      args;
   gint         response_id;
 
@@ -416,21 +309,12 @@ xfce_titled_dialog_new_with_buttons (const gchar    *title,
   if (G_LIKELY (parent != NULL))
     gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
 
-G_GNUC_BEGIN_IGNORE_DEPRECATIONS
-  action_area = gtk_dialog_get_action_area (GTK_DIALOG (dialog));
-G_GNUC_END_IGNORE_DEPRECATIONS
-  headerbar = gtk_dialog_get_header_bar (GTK_DIALOG (dialog));
-
   /* add all additional buttons */
   va_start (args, first_button_text);
   for (button_text = first_button_text; button_text != NULL; )
     {
       response_id = va_arg (args, gint);
-G_GNUC_BEGIN_IGNORE_DEPRECATIONS
-      button = gtk_button_new_from_stock (button_text);
-G_GNUC_END_IGNORE_DEPRECATIONS
-      gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, response_id);
-      xfce_titled_dialog_repack_dialog (action_area, headerbar, button, response_id);
+      gtk_dialog_add_button (GTK_DIALOG (dialog), button_text, response_id);
       button_text = va_arg (args, const gchar *);
     }
   va_end (args);
@@ -468,8 +352,6 @@ xfce_titled_dialog_new_with_mixed_buttons (const gchar    *title,
   const gchar *icon_name;
   const gchar *button_text;
   GtkWidget   *dialog;
-  GtkWidget   *headerbar;
-  GtkWidget   *action_area;
   va_list      args;
   gint         response_id;
 
@@ -484,11 +366,6 @@ xfce_titled_dialog_new_with_mixed_buttons (const gchar    *title,
   if (G_LIKELY (parent != NULL))
     gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
 
-G_GNUC_BEGIN_IGNORE_DEPRECATIONS
-  action_area = gtk_dialog_get_action_area (GTK_DIALOG (dialog));
-G_GNUC_END_IGNORE_DEPRECATIONS
-  headerbar = gtk_dialog_get_header_bar (GTK_DIALOG (dialog));
-
   /* add all additional buttons */
   icon_name = first_button_icon_name;
   button_text = first_button_text;
@@ -506,7 +383,6 @@ G_GNUC_END_IGNORE_DEPRECATIONS
       gtk_widget_set_can_default (button, TRUE);
 
       gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, response_id);
-      xfce_titled_dialog_repack_dialog (action_area, headerbar, button, response_id);
       gtk_widget_show (button);
 
       /* this is to pickup for the next button.
@@ -520,176 +396,16 @@ G_GNUC_END_IGNORE_DEPRECATIONS
     }
   va_end (args);
 
-  /* since we just removed all buttons from the headerbar we have to show the close button again explicitly */
-  gtk_header_bar_set_show_close_button (GTK_HEADER_BAR (headerbar), TRUE);
-
   return dialog;
 }
 
 
-
-/**
- * xfce_titled_dialog_create_action_area:
- * @titled_dialog : a #XfceTitledDialog.
- *
- * This function creates a custom action area (of type #GtkButtonBox) and has to
- * be used in combination with #xfce_titled_dialog_add_action_widget.
- *
- * When using the XfceTitledDialogClass directly to create dialogs this function is
- * useful to keep action widgets out of the #GtkHeaderBar in which they would
- * normally end up by calling #gtk_dialog_add_action_widget.
- *
- * Since: 4.16
- *
- **/
-void
-xfce_titled_dialog_create_action_area (XfceTitledDialog *titled_dialog)
-{
-  GtkWidget *dialog_vbox;
-
-  g_return_if_fail (XFCE_IS_TITLED_DIALOG (titled_dialog));
-
-  /* Create new buttonbox to act as custom action area for the dialog */
-  titled_dialog->priv->action_area = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
-  gtk_button_box_set_layout (GTK_BUTTON_BOX (titled_dialog->priv->action_area), GTK_BUTTONBOX_END);
-  gtk_box_set_spacing (GTK_BOX (titled_dialog->priv->action_area), 6);
-
-  /* Pack the buttonbox in the dialog's main vbox */
-  dialog_vbox = gtk_bin_get_child (GTK_BIN (titled_dialog));
-  gtk_box_pack_end (GTK_BOX (dialog_vbox), titled_dialog->priv->action_area, FALSE, TRUE, 0);
-  gtk_box_reorder_child (GTK_BOX (dialog_vbox), titled_dialog->priv->action_area, 0);
-  gtk_widget_show (titled_dialog->priv->action_area);
-}
-
-
-
-/**
- * xfce_titled_dialog_add_button:
- * @titled_dialog : a #XfceTitledDialog.
- * @button_text   : text of button.
- * @response_id   : response ID for @child.
- *
- * This function is a replacement for #gtk_dialog_add_button and assumes that
- * you have called #xfce_titled_dialog_create_action_area before.
- *
- * Buttons with #GTK_RESPONSE_HELP will be added to the secondary group of children
- * (see #gtk_button_box_set_child_secondary for reference).
- *
- * Return value: (transfer none): the GtkButton widget that was added.
- *
- * Since: 4.16
- *
- **/
-GtkWidget *
-xfce_titled_dialog_add_button (XfceTitledDialog *titled_dialog,
-                               const gchar      *button_text,
-                               gint              response_id)
-{
-  GtkWidget *button;
-
-  g_return_val_if_fail (XFCE_IS_TITLED_DIALOG (titled_dialog), NULL);
-  g_return_val_if_fail (GTK_IS_WIDGET (titled_dialog->priv->action_area), NULL);
-  g_return_val_if_fail (button_text != NULL, NULL);
-
-  button = gtk_button_new_with_label (button_text);
-  gtk_button_set_use_underline (GTK_BUTTON (button), TRUE);
-
-  xfce_titled_dialog_add_action_widget (titled_dialog, button, response_id);
-
-  return button;
-}
-
-
-
-/**
- * xfce_titled_dialog_add_action_widget:
- * @titled_dialog : a #XfceTitledDialog.
- * @child         : an activatable widget.
- * @response_id   : response ID for @child.
- *
- * This function is a replacement for #gtk_dialog_add_action_widget and assumes that
- * you have called #xfce_titled_dialog_create_action_area before.
- *
- * Children with #GTK_RESPONSE_HELP will be added to the secondary group of children
- * (see #gtk_button_box_set_child_secondary for reference).
- *
- * Since: 4.16
- *
- **/
-void
-xfce_titled_dialog_add_action_widget (XfceTitledDialog *titled_dialog,
-                                      GtkWidget        *child,
-                                      gint              response_id)
-{
-  g_return_if_fail (XFCE_IS_TITLED_DIALOG (titled_dialog));
-  g_return_if_fail (GTK_IS_WIDGET (titled_dialog->priv->action_area));
-  g_return_if_fail (GTK_IS_WIDGET (child));
-
-  add_response_data (GTK_DIALOG (titled_dialog), child, response_id);
-
-  gtk_box_pack_start (GTK_BOX (titled_dialog->priv->action_area), child, FALSE, TRUE, 0);
-  gtk_widget_show (child);
-
-  if (response_id == GTK_RESPONSE_HELP)
-    gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (titled_dialog->priv->action_area), child, TRUE);
-}
-
-
-
-/**
- * xfce_titled_dialog_set_default_response:
- * @titled_dialog : a #XfceTitledDialog.
- * @response_id   : a response ID
- *
- * Sets the last widget in the dialog’s action area with the given @response_id
- * as the default widget for the dialog. Pressing “Enter” normally activates
- * the default widget.
- *
- * This function is a replacement for #gtk_dialog_set_default_response, which does
- * not work with #XfceTitledDialog.
- *
- * Since: 4.16
- *
- **/
-void
-xfce_titled_dialog_set_default_response (XfceTitledDialog *titled_dialog,
-                                         gint              response_id)
-{
-  GtkWidget *action_area;
-  GList     *children;
-  GList     *tmp_list;
-
-  g_return_if_fail (XFCE_IS_TITLED_DIALOG (titled_dialog));
-
-G_GNUC_BEGIN_IGNORE_DEPRECATIONS
-  action_area = gtk_dialog_get_action_area (GTK_DIALOG (titled_dialog));
-G_GNUC_END_IGNORE_DEPRECATIONS
-
-  children = gtk_container_get_children (GTK_CONTAINER (action_area));
-  tmp_list = children;
-  while (tmp_list != NULL)
-    {
-      GtkWidget *widget = tmp_list->data;
-      ResponseData *rd = get_response_data (widget, FALSE);
-
-      if (rd && rd->response_id == response_id)
-        gtk_window_set_default (GTK_WINDOW (titled_dialog), widget);
-
-      tmp_list = tmp_list->next;
-    }
-
-  g_list_free (children);
-}
-
-
-
 /**
  * xfce_titled_dialog_get_subtitle:
  * @titled_dialog : a #XfceTitledDialog.
  *
  * Returns the subtitle of the @titled_dialog, or %NULL
  * if no subtitle is displayed in the @titled_dialog.
- * This is just a convenience function around #gtk_header_bar_get_subtitle.
  *
  * Return value: the subtitle of @titled_dialog, or %NULL.
  **/
@@ -709,7 +425,6 @@ xfce_titled_dialog_get_subtitle (XfceTitledDialog *titled_dialog)
  *
  * Sets the subtitle displayed by @titled_dialog to @subtitle; if
  * @subtitle is %NULL no subtitle will be displayed by the @titled_dialog.
- * This is just a convenience function around #gtk_header_bar_set_subtitle.
  **/
 void
 xfce_titled_dialog_set_subtitle (XfceTitledDialog *titled_dialog,
@@ -724,14 +439,45 @@ xfce_titled_dialog_set_subtitle (XfceTitledDialog *titled_dialog,
   /* activate the new subtitle */
   titled_dialog->priv->subtitle = g_strdup (subtitle);
 
-  /* update the subtitle of the headerbar */
-  gtk_header_bar_set_subtitle (GTK_HEADER_BAR (titled_dialog->priv->headerbar),
-                               titled_dialog->priv->subtitle);
+  /* update the subtitle for the heading */
+  _xfce_heading_set_subtitle (XFCE_HEADING (titled_dialog->priv->heading), subtitle);
 
   /* notify listeners */
   g_object_notify (G_OBJECT (titled_dialog), "subtitle");
 }
 
+//
+// libxfce4ui 4.15.1 no-CSD shims
+//
+
+void
+xfce_titled_dialog_create_action_area (XfceTitledDialog *titled_dialog)
+{
+    (void)titled_dialog;
+}
+
+void
+xfce_titled_dialog_add_action_widget (XfceTitledDialog *titled_dialog,
+                                      GtkWidget        *child,
+                                      gint              response_id)
+{
+    gtk_dialog_add_action_widget (GTK_DIALOG (titled_dialog), child, response_id);
+}
+
+void
+xfce_titled_dialog_set_default_response (XfceTitledDialog *titled_dialog,
+                                         gint              response_id)
+{
+    gtk_dialog_set_default_response (GTK_DIALOG (titled_dialog), response_id);
+}
+
+GtkWidget *
+xfce_titled_dialog_add_button (XfceTitledDialog *titled_dialog,
+                               const gchar      *button_text,
+                               gint              response_id)
+{
+    return gtk_dialog_add_button (GTK_DIALOG (titled_dialog), button_text, response_id);
+}
 
 
 #define __XFCE_TITLED_DIALOG_C__
diff --git a/libxfce4ui/xfce-titled-dialog.h b/libxfce4ui/xfce-titled-dialog.h
index 4f436ca..5ba4ee6 100644
--- a/libxfce4ui/xfce-titled-dialog.h
+++ b/libxfce4ui/xfce-titled-dialog.h
@@ -81,18 +81,30 @@ GtkWidget            *xfce_titled_dialog_new_with_mixed_buttons (const gchar
                                                                  const gchar    *first_button_text,
                                                                  ...) G_GNUC_MALLOC;
 
-void                  xfce_titled_dialog_create_action_area   (XfceTitledDialog *titled_dialog);
-GtkWidget            *xfce_titled_dialog_add_button           (XfceTitledDialog *titled_dialog,
-                                                               const gchar      *button_text,
-                                                               gint              response_id);
-void                  xfce_titled_dialog_add_action_widget    (XfceTitledDialog *titled_dialog,
-                                                               GtkWidget        *child,
-                                                               gint              response_id);
-void                  xfce_titled_dialog_set_default_response (XfceTitledDialog *titled_dialog,
-                                                               gint              response_id);
-const gchar          *xfce_titled_dialog_get_subtitle         (XfceTitledDialog *titled_dialog);
-void                  xfce_titled_dialog_set_subtitle         (XfceTitledDialog *titled_dialog,
-                                                               const gchar      *subtitle);
+const gchar          *xfce_titled_dialog_get_subtitle     (XfceTitledDialog *titled_dialog);
+void                  xfce_titled_dialog_set_subtitle     (XfceTitledDialog *titled_dialog,
+                                                           const gchar      *subtitle);
+
+//
+// libxfce4ui 4.15.1 no-CSD shims
+//
+
+void
+xfce_titled_dialog_create_action_area (XfceTitledDialog *titled_dialog);
+
+void
+xfce_titled_dialog_add_action_widget (XfceTitledDialog *titled_dialog,
+                                      GtkWidget        *child,
+                                      gint              response_id);
+void
+xfce_titled_dialog_set_default_response (XfceTitledDialog *titled_dialog,
+                                         gint              response_id);
+
+GtkWidget *
+xfce_titled_dialog_add_button (XfceTitledDialog *titled_dialog,
+                               const gchar      *button_text,
+                               gint              response_id);
+
 
 G_END_DECLS
 
-- 
2.26.2

