[gnome-builder] plugins/meson-templates: port to C



commit 893f2c6784f1aaa0abc7cd98243ae560952fe54e
Author: Christian Hergert <chergert redhat com>
Date:   Mon Jul 11 23:04:16 2022 -0700

    plugins/meson-templates: port to C
    
    This cleans up our template expansion quite a bit for meson. The port to
    C also took the liberty to clean up a lot of how we did templates (and
    moved it to libide-projects).
    
    Some old/not-useful templates were dropped as part of this.

 .../meson-templates/gbp-meson-template-provider.c  | 276 ++++++++++
 .../meson-templates/gbp-meson-template-provider.h  |  31 ++
 src/plugins/meson-templates/gbp-meson-template.c   | 311 ++++++++++++
 src/plugins/meson-templates/gbp-meson-template.h   |  54 ++
 .../icons/scalable/actions/pattern-browse.svg      | 284 -----------
 .../icons/scalable/actions/pattern-cli.svg         | 178 -------
 .../icons/scalable/actions/pattern-gnome.svg       | 150 ------
 .../icons/scalable/actions/pattern-grid.svg        | 270 ----------
 .../icons/scalable/actions/pattern-gtk.svg         |  34 --
 .../icons/scalable/actions/pattern-legacy.svg      | 243 ---------
 .../icons/scalable/actions/pattern-library.svg     | 141 -----
 .../meson-templates/meson-templates-plugin.c       |  35 ++
 .../meson-templates/meson-templates.gresource.xml  |  46 +-
 src/plugins/meson-templates/meson-templates.plugin |  17 +-
 src/plugins/meson-templates/meson.build            |  28 +-
 src/plugins/meson-templates/meson_templates.py     | 565 ---------------------
 .../resources/data/hello.desktop.in                |   3 -
 .../meson-templates/resources/data/meson.build     |  32 +-
 .../resources/flatpak-gtksharp.json.tmpl           |  63 ---
 .../meson-templates/resources/flatpak.json.in      | 143 +-----
 src/plugins/meson-templates/resources/meson.build  |  94 +++-
 src/plugins/meson-templates/resources/po/POTFILES  |  11 +-
 .../meson-templates/resources/src/Cargo.toml       |  24 -
 .../resources/src/application-gtk4.c               | 102 ++++
 .../src/{application.h => application-gtk4.h}      |   2 +-
 .../src/{application.rs => application-gtk4.rs}    |   2 +
 .../meson-templates/resources/src/application.c    | 109 ----
 .../meson-templates/resources/src/application.in   |   3 -
 .../meson-templates/resources/src/config.rs.in     |   5 -
 .../resources/src/hello.gresource.xml              |   4 +-
 .../meson-templates/resources/src/main-cli.c       |   2 +-
 .../meson-templates/resources/src/main-gtk4.c      |  20 +-
 .../meson-templates/resources/src/main-gtk4.rs     |   2 +
 src/plugins/meson-templates/resources/src/main.c   |  73 ---
 src/plugins/meson-templates/resources/src/main.cpp |  48 --
 src/plugins/meson-templates/resources/src/main.cs  |  25 -
 .../meson-templates/resources/src/main.js.tmpl     |  27 -
 src/plugins/meson-templates/resources/src/main.py  |  27 -
 src/plugins/meson-templates/resources/src/main.rs  |  29 --
 .../meson-templates/resources/src/main.vala        |  14 -
 .../resources/src/meson-c-vala.build               |  26 +-
 .../meson-templates/resources/src/meson-clib.build |  35 +-
 .../meson-templates/resources/src/meson-cs.build   |  21 -
 .../resources/src/meson-py-cli.build               |  11 +-
 .../meson-templates/resources/src/meson-py.build   |  34 --
 .../meson-templates/resources/src/meson-rs.build   |  55 --
 .../resources/src/{window.c => window-gtk4.c}      |   7 +-
 .../resources/src/{window.h => window-gtk4.h}      |   6 +-
 .../src/{window.js.tmpl => window-gtk4.js}         |   5 +-
 .../meson-templates/resources/src/window-gtk4.py   |   6 +-
 .../meson-templates/resources/src/window-gtk4.rs   |  12 +-
 .../meson-templates/resources/src/window-gtk4.ui   |  36 +-
 .../meson-templates/resources/src/window-gtk4.vala |   2 +-
 .../meson-templates/resources/src/window.cpp       |  35 --
 .../meson-templates/resources/src/window.hpp       |  23 -
 .../meson-templates/resources/src/window.py        |  13 -
 .../meson-templates/resources/src/window.rs        |  16 -
 .../meson-templates/resources/src/window.ui        |  37 --
 .../meson-templates/resources/src/window.vala      |  13 -
 59 files changed, 1035 insertions(+), 2885 deletions(-)
---
diff --git a/src/plugins/meson-templates/gbp-meson-template-provider.c 
b/src/plugins/meson-templates/gbp-meson-template-provider.c
new file mode 100644
index 000000000..81f8a7c4c
--- /dev/null
+++ b/src/plugins/meson-templates/gbp-meson-template-provider.c
@@ -0,0 +1,276 @@
+/* gbp-meson-template-provider.c
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define G_LOG_DOMAIN "gbp-meson-template-provider"
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+
+#include <libide-projects.h>
+
+#include "gbp-meson-template.h"
+#include "gbp-meson-template-provider.h"
+
+struct _GbpMesonTemplateProvider
+{
+  GObject parent_instance;
+};
+
+typedef struct _GbpMesonTemplateInfo
+{
+  int                                  priority;
+  const char                          *id;
+  const char                          *name;
+  const char                          *description;
+  const char * const                  *languages;
+  const GbpMesonTemplateExpansion     *expansions;
+  guint                                n_expansions;
+  const GbpMesonTemplateLanguageScope *language_scope;
+  guint                                n_language_scope;
+  const char * const                  *extra_scope;
+} GbpMesonTemplateInfo;
+
+static GbpMesonTemplateExpansion gtk4_expansions[] = {
+  { "meson.build",                                         "meson.build" },
+  { "flatpak.json",                                        "{{appid}}.json" },
+  { "data/hello.desktop.in",                               "data/{{appid}}.desktop.in" },
+  { "data/hello.appdata.xml.in",                           "data/{{appid}}.appdata.xml.in" },
+  { "data/hello.gschema.xml",                              "data/{{appid}}.gschema.xml" },
+  { "data/meson.build",                                    "data/meson.build" },
+  { "data/icons/meson.build",                              "data/icons/meson.build" },
+  { "data/icons/hicolor/scalable/apps/hello.svg",          "data/icons/hicolor/scalable/apps/{{appid}}.svg" 
},
+  { "data/icons/hicolor/symbolic/apps/hello-symbolic.svg", 
"data/icons/hicolor/symbolic/apps/{{appid}}-symbolic.svg" },
+  { "po/LINGUAS",                                          "po/LINGUAS" },
+  { "po/meson.build",                                      "po/meson.build" },
+  { "po/POTFILES",                                         "po/POTFILES" },
+  { "src/help-overlay.ui",                                 "src/gtk/help-overlay.ui" },
+
+  /* C */
+  { "src/application-gtk4.c", "src/{{prefix}}-application.c", IDE_STRV_INIT ("C") },
+  { "src/application-gtk4.h", "src/{{prefix}}-application.h", IDE_STRV_INIT ("C") },
+  { "src/hello.gresource.xml", "src/{{prefix}}.gresource.xml", IDE_STRV_INIT ("C") },
+  { "src/main-gtk4.c", "src/main.c", IDE_STRV_INIT ("C") },
+  { "src/meson-c-vala.build", "src/meson.build", IDE_STRV_INIT ("C") },
+  { "src/window-gtk4.ui", "src/{{prefix}}-window.ui", IDE_STRV_INIT ("C") },
+  { "src/window-gtk4.c", "src/{{prefix}}-window.c", IDE_STRV_INIT ("C") },
+  { "src/window-gtk4.h", "src/{{prefix}}-window.h", IDE_STRV_INIT ("C") },
+
+  /* JavaScript */
+  { "src/hello.gresource.xml", "src/{{appid}}.data.gresource.xml", IDE_STRV_INIT ("JavaScript") },
+  { "src/hello.gresource.xml", "src/{{prefix}}.data.gresource.xml", IDE_STRV_INIT ("JavaScript") },
+  { "src/hello.js.in", "src/{{appid}}.in", IDE_STRV_INIT ("JavaScript"), TRUE },
+  { "src/hello.src.gresource.xml", "src/{{appid}}.src.gresource.xml", IDE_STRV_INIT ("JavaScript") },
+  { "src/main-gtk4.js.tmpl", "src/main.js", IDE_STRV_INIT ("JavaScript") },
+  { "src/meson-js.build", "src/meson.build", IDE_STRV_INIT ("JavaScript") },
+  { "src/window-gtk4.ui", "src/window.ui", IDE_STRV_INIT ("JavaScript") },
+  { "src/window-gtk4.js", "src/window.js", IDE_STRV_INIT ("JavaScript") },
+
+  /* Python */
+  { "src/__init__.py", "src/__init__.py", IDE_STRV_INIT ("Python") },
+  { "src/hello.gresource.xml", "src/{{prefix}}.gresource.xml", IDE_STRV_INIT ("Python") },
+  { "src/hello.py.in", "src/{{name}}.in", IDE_STRV_INIT ("Python"), TRUE },
+  { "src/main-gtk4.py", "src/main.py", IDE_STRV_INIT ("Python") },
+  { "src/meson-py-gtk4.build", "src/meson.build", IDE_STRV_INIT ("Python") },
+  { "src/window-gtk4.py", "src/window.py", IDE_STRV_INIT ("Python") },
+  { "src/window-gtk4.ui", "src/window.ui", IDE_STRV_INIT ("Python") },
+
+  /* Rust */
+  { "build-aux/cargo.sh", "build-aux/cargo.sh", IDE_STRV_INIT ("Rust") },
+  { "src/Cargo-gtk4.toml", "Cargo.toml", IDE_STRV_INIT ("Rust") },
+  { "src/Cargo.lock", "Cargo.lock", IDE_STRV_INIT ("Rust") },
+  { "src/application-gtk4.rs", "src/application.rs", IDE_STRV_INIT ("Rust") },
+  { "src/config-gtk4.rs.in", "src/config.rs.in", IDE_STRV_INIT ("Rust") },
+  { "src/hello.gresource.xml", "src/{{prefix}}.gresource.xml", IDE_STRV_INIT ("Rust") },
+  { "src/main-gtk4.rs", "src/main.rs", IDE_STRV_INIT ("Rust") },
+  { "src/meson-rs-gtk4.build", "src/meson.build", IDE_STRV_INIT ("Rust") },
+  { "src/window-gtk4.rs", "src/window.rs", IDE_STRV_INIT ("Rust") },
+  { "src/window-gtk4.ui", "src/window.ui", IDE_STRV_INIT ("Rust") },
+
+  /* Vala */
+  { "src/application-gtk4.vala", "src/application.vala", IDE_STRV_INIT ("Vala") },
+  { "src/hello.gresource.xml", "src/{{prefix}}.gresource.xml", IDE_STRV_INIT ("Vala") },
+  { "src/main-gtk4.vala", "src/main.vala", IDE_STRV_INIT ("Vala") },
+  { "src/meson-c-vala.build", "src/meson.build", IDE_STRV_INIT ("Vala") },
+  { "src/window-gtk4.ui", "src/window.ui", IDE_STRV_INIT ("Vala") },
+  { "src/window-gtk4.vala", "src/window.vala", IDE_STRV_INIT ("Vala") },
+};
+
+static const GbpMesonTemplateLanguageScope gtk4_language_scope[] = {
+  { "C",          IDE_STRV_INIT ("ui_file={{prefix}}-window.ui") },
+  { "JavaScript", IDE_STRV_INIT ("exec_name={{appid}}") },
+};
+
+static GbpMesonTemplateExpansion library_expansions[] = {
+  { "meson.build", "meson.build" },
+  { "src/meson-clib.build", "src/meson.build" },
+  { "src/hello.c", "src/{{name}}.c" },
+  { "src/hello.h", "src/{{name}}.h" },
+  { "src/hello-version.h.in", "src/{{name}}-version.h.in" },
+};
+
+static GbpMesonTemplateExpansion cli_expansions[] = {
+  /* Shared */
+  { "meson.build", "meson.build" },
+
+  /* C */
+  { "src/meson-cli.build", "src/meson.build", IDE_STRV_INIT ("C") },
+  { "src/main-cli.c", "src/main.c", IDE_STRV_INIT ("C") },
+
+  /* C++ */
+  { "src/meson-cli.build", "src/meson.build", IDE_STRV_INIT ("C++") },
+  { "src/main-cli.cpp", "src/main.cpp", IDE_STRV_INIT ("C++") },
+
+  /* Python */
+  { "src/meson-py-cli.build", "src/meson.build", IDE_STRV_INIT ("Python") },
+  { "src/hello-cli.py.in", "src/{{name}}.in", IDE_STRV_INIT ("Python") },
+  { "src/__init__.py", "src/__init__.py", IDE_STRV_INIT ("Python") },
+  { "src/main-cli.py", "src/main.py", IDE_STRV_INIT ("Python") },
+
+  /* Rust */
+  { "src/meson-cli.build", "src/meson.build", IDE_STRV_INIT ("Rust") },
+  { "src/Cargo.lock", "Cargo.lock", IDE_STRV_INIT ("Rust") },
+  { "src/Cargo-cli.toml", "Cargo.toml", IDE_STRV_INIT ("Rust") },
+  { "src/main-cli.rs", "src/main.rs", IDE_STRV_INIT ("Rust") },
+  { "build-aux/cargo.sh", "build-aux/cargo.sh", IDE_STRV_INIT ("Rust") },
+
+  /* Vala */
+  { "src/meson-cli.build", "src/meson.build", IDE_STRV_INIT ("Vala") },
+  { "src/main-cli.vala", "src/main.vala", IDE_STRV_INIT ("Vala") },
+};
+
+static GbpMesonTemplateExpansion empty_expansions[] = {
+  /* Shared */
+  { "meson.build", "meson.build" },
+  { "src/meson-empty.build", "src/meson.build" },
+
+  /* Rust */
+  { "src/Cargo.lock", "Cargo.lock", IDE_STRV_INIT ("Rust") },
+  { "src/Cargo-cli.toml", "Cargo.toml", IDE_STRV_INIT ("Rust") },
+};
+
+static const GbpMesonTemplateInfo templates[] = {
+  {
+    -1000,
+    "adwaita",
+    N_("GNOME Application"),
+    N_("A Meson-based project for GNOME using GTK 4 and libadwaita"),
+    IDE_STRV_INIT ("C", "JavaScript", "Python", "Rust", "Vala"),
+    gtk4_expansions, G_N_ELEMENTS (gtk4_expansions),
+    gtk4_language_scope, G_N_ELEMENTS (gtk4_language_scope),
+    IDE_STRV_INIT ("is_adwaita=true",
+                   "is_gtk4=true",
+                   "enable_i18n=true",
+                   "enable_gnome=true",
+                   "ui_file=window.ui",
+                   "exec_name={{name}}"),
+  },
+  {
+    -900,
+    "gtk4",
+    N_("GTK 4 Application"),
+    N_("A Meson-based project using GTK 4"),
+    IDE_STRV_INIT ("C", "JavaScript", "Python", "Rust", "Vala"),
+    gtk4_expansions, G_N_ELEMENTS (gtk4_expansions),
+    gtk4_language_scope, G_N_ELEMENTS (gtk4_language_scope),
+    IDE_STRV_INIT ("is_adwaita=false",
+                   "is_gtk4=true",
+                   "enable_i18n=true",
+                   "enable_gnome=true",
+                   "ui_file=window.ui",
+                   "exec_name={{name}}"),
+  },
+  {
+    -800,
+    "library",
+    N_("Shared Library"),
+    N_("A Meson-based project for a shared library"),
+    IDE_STRV_INIT ("C"),
+    library_expansions, G_N_ELEMENTS (library_expansions),
+  },
+  {
+    -700,
+    "empty",
+    N_("Command Line Toool"),
+    N_("An Meson-based project for a command-line program"),
+    IDE_STRV_INIT ("C", "C++", "Python", "Rust", "Vala"),
+    cli_expansions, G_N_ELEMENTS (cli_expansions),
+  },
+  {
+    -600,
+    "empty",
+    N_("Empty Meson Project"),
+    N_("An empty Meson project skeleton"),
+    IDE_STRV_INIT ("C", "C++", "C♯", "JavaScript", "Python", "Rust", "Vala"),
+    empty_expansions, G_N_ELEMENTS (empty_expansions),
+  },
+};
+
+static GList *
+gbp_meson_template_provider_get_project_templates (IdeTemplateProvider *provider)
+{
+  GList *list = NULL;
+
+  g_assert (GBP_IS_MESON_TEMPLATE_PROVIDER (provider));
+
+  for (guint i = 0; i < G_N_ELEMENTS (templates); i++)
+    {
+      g_autofree char *id = NULL;
+      g_autoptr(GbpMesonTemplate) template = NULL;
+
+      id = g_strdup_printf ("meson-templates:%s", templates[i].id);
+      template = g_object_new (GBP_TYPE_MESON_TEMPLATE,
+                               "description", g_dgettext (GETTEXT_PACKAGE, templates[i].description),
+                               "id", id,
+                               "languages", templates[i].languages,
+                               "name", g_dgettext (GETTEXT_PACKAGE, templates[i].name),
+                               "priority", templates[i].priority,
+                               NULL);
+      gbp_meson_template_set_expansions (template,
+                                         templates[i].expansions,
+                                         templates[i].n_expansions);
+      gbp_meson_template_set_extra_scope (template, templates[i].extra_scope);
+      gbp_meson_template_set_language_scope (template,
+                                             templates[i].language_scope,
+                                             templates[i].n_language_scope);
+      list = g_list_prepend (list, g_steal_pointer (&template));
+    }
+
+  return list;
+}
+
+static void
+template_provider_iface_init (IdeTemplateProviderInterface *iface)
+{
+  iface->get_project_templates = gbp_meson_template_provider_get_project_templates;
+}
+
+G_DEFINE_FINAL_TYPE_WITH_CODE (GbpMesonTemplateProvider, gbp_meson_template_provider, G_TYPE_OBJECT,
+                               G_IMPLEMENT_INTERFACE (IDE_TYPE_TEMPLATE_PROVIDER, 
template_provider_iface_init))
+
+static void
+gbp_meson_template_provider_class_init (GbpMesonTemplateProviderClass *klass)
+{
+}
+
+static void
+gbp_meson_template_provider_init (GbpMesonTemplateProvider *self)
+{
+}
diff --git a/src/plugins/meson-templates/gbp-meson-template-provider.h 
b/src/plugins/meson-templates/gbp-meson-template-provider.h
new file mode 100644
index 000000000..aea19ad19
--- /dev/null
+++ b/src/plugins/meson-templates/gbp-meson-template-provider.h
@@ -0,0 +1,31 @@
+/* gbp-meson-template-provider.h
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GBP_TYPE_MESON_TEMPLATE_PROVIDER (gbp_meson_template_provider_get_type())
+
+G_DECLARE_FINAL_TYPE (GbpMesonTemplateProvider, gbp_meson_template_provider, GBP, MESON_TEMPLATE_PROVIDER, 
GObject)
+
+G_END_DECLS
diff --git a/src/plugins/meson-templates/gbp-meson-template.c 
b/src/plugins/meson-templates/gbp-meson-template.c
new file mode 100644
index 000000000..10e6e7ed0
--- /dev/null
+++ b/src/plugins/meson-templates/gbp-meson-template.c
@@ -0,0 +1,311 @@
+/* gbp-meson-template.c
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define G_LOG_DOMAIN "gbp-meson-template"
+
+#include "config.h"
+
+#include <string.h>
+
+#include <libide-threading.h>
+
+#include "gbp-meson-template.h"
+
+struct _GbpMesonTemplate
+{
+  IdeProjectTemplate parent_instance;
+  const char * const *extra_scope;
+  const GbpMesonTemplateExpansion *expansions;
+  guint n_expansions;
+  const GbpMesonTemplateLanguageScope *language_scope;
+  guint n_language_scope;
+};
+
+G_DEFINE_FINAL_TYPE (GbpMesonTemplate, gbp_meson_template, IDE_TYPE_PROJECT_TEMPLATE)
+
+static void
+add_to_scope (TmplScope  *scope,
+              const char *pattern)
+{
+  g_autofree char *key = NULL;
+  const char *val;
+
+  g_assert (scope != NULL);
+  g_assert (pattern != NULL);
+
+  val = strchr (pattern, '=');
+
+  /* If it is just "FOO" then set "FOO" to True */
+  if (val == NULL)
+    {
+      tmpl_scope_set_boolean (scope, pattern, TRUE);
+      return;
+    }
+
+  key = g_strndup (pattern, val - pattern);
+  val++;
+
+  /* If simple key=value, set the bool/string */
+  if (strstr (val, "{{") == NULL)
+    {
+      if (ide_str_equal0 (val, "false"))
+        tmpl_scope_set_boolean (scope, key, FALSE);
+      else if (ide_str_equal0 (val, "true"))
+        tmpl_scope_set_boolean (scope, key, TRUE);
+      else
+        tmpl_scope_set_string (scope, key, val);
+
+      return;
+    }
+
+  /* More complex, we have a template to expand from scope */
+  {
+    g_autoptr(TmplTemplate) template = tmpl_template_new (NULL);
+    g_autoptr(GError) error = NULL;
+    g_autofree char *expanded = NULL;
+
+    if (!tmpl_template_parse_string (template, val, &error))
+      {
+        g_warning ("Failed to parse template %s: %s",
+                   val, error->message);
+        return;
+      }
+
+    if (!(expanded = tmpl_template_expand_string (template, scope, &error)))
+      {
+        g_warning ("Failed to expand template %s: %s",
+                   val, error->message);
+        return;
+      }
+
+    tmpl_scope_set_string (scope, key, expanded);
+  }
+}
+
+static void
+gbp_meson_template_expand_cb (GObject      *object,
+                              GAsyncResult *result,
+                              gpointer      user_data)
+{
+  GbpMesonTemplate *self = (GbpMesonTemplate *)object;
+  g_autoptr(IdeTask) task = user_data;
+  g_autoptr(GError) error = NULL;
+
+  IDE_ENTRY;
+
+  g_assert (GBP_IS_MESON_TEMPLATE (self));
+  g_assert (G_IS_ASYNC_RESULT (result));
+  g_assert (IDE_IS_TASK (task));
+
+  if (!ide_template_base_expand_all_finish (IDE_TEMPLATE_BASE (self), result, &error))
+    ide_task_return_error (task, g_steal_pointer (&error));
+  else
+    ide_task_return_boolean (task, TRUE);
+
+  IDE_EXIT;
+}
+
+static void
+gbp_meson_template_expand_async (IdeProjectTemplate  *template,
+                                 IdeTemplateInput    *input,
+                                 TmplScope           *scope,
+                                 GCancellable        *cancellable,
+                                 GAsyncReadyCallback  callback,
+                                 gpointer             user_data)
+{
+  GbpMesonTemplate *self = (GbpMesonTemplate *)template;
+  g_autofree char *license_path = NULL;
+  g_autoptr(IdeTask) task = NULL;
+  g_autoptr(GFile) destdir = NULL;
+  const char *language;
+  const char *name;
+  GFile *directory;
+
+  IDE_ENTRY;
+
+  g_assert (GBP_IS_MESON_TEMPLATE (template));
+  g_assert (IDE_IS_TEMPLATE_INPUT (input));
+  g_assert (scope != NULL);
+  g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  task = ide_task_new (template, cancellable, callback, user_data);
+  ide_task_set_source_tag (task, gbp_meson_template_expand_async);
+
+  name = ide_template_input_get_name (input);
+  language = ide_template_input_get_language (input);
+  directory = ide_template_input_get_directory (input);
+  destdir = g_file_get_child (directory, name);
+
+  if (self->expansions == NULL || self->n_expansions == 0)
+    {
+      ide_task_return_unsupported_error (task);
+      IDE_EXIT;
+    }
+
+  /* Setup our license for the project */
+  if ((license_path = ide_template_input_get_license_path (input)))
+    {
+      g_autoptr(GFile) copying = g_file_get_child (destdir, "COPYING");
+      ide_template_base_add_resource (IDE_TEMPLATE_BASE (self),
+                                      license_path, copying, scope, 0);
+    }
+
+  /* First setup some defaults for our scope */
+  tmpl_scope_set_boolean (scope, "is_adwaita", FALSE);
+  tmpl_scope_set_boolean (scope, "is_gtk4", FALSE);
+  tmpl_scope_set_boolean (scope, "enable_gnome", FALSE);
+  tmpl_scope_set_boolean (scope, "enable_i18n", FALSE);
+
+  /* Add any extra scope to the expander which might be needed */
+  if (self->extra_scope != NULL)
+    {
+      for (guint j = 0; self->extra_scope[j]; j++)
+        add_to_scope (scope, self->extra_scope[j]);
+    }
+
+  /* Now add any per-language scope necessary */
+  if (self->language_scope != NULL)
+    {
+      for (guint j = 0; j < self->n_language_scope; j++)
+        {
+          if (!ide_str_equal0 (language, self->language_scope[j].language) ||
+              self->language_scope[j].extra_scope == NULL)
+            continue;
+
+          for (guint k = 0; self->language_scope[j].extra_scope[k]; k++)
+            add_to_scope (scope, self->language_scope[j].extra_scope[k]);
+        }
+    }
+
+  for (guint i = 0; i < self->n_expansions; i++)
+    {
+      const char *src = self->expansions[i].input;
+      const char *dest = self->expansions[i].output_pattern;
+      g_autofree char *dest_eval = NULL;
+      g_autofree char *resource_path = NULL;
+      g_autoptr(GFile) dest_file = NULL;
+      int mode = 0;
+
+      if (self->expansions[i].languages != NULL &&
+          !g_strv_contains (self->expansions[i].languages, language))
+        continue;
+
+      /* Expand the destination filename if necessary using a template */
+      if (strstr (dest, "{{") != NULL)
+        {
+          g_autoptr(TmplTemplate) expander = tmpl_template_new (NULL);
+          g_autoptr(GError) error = NULL;
+
+          if (!tmpl_template_parse_string (expander, dest, &error))
+            {
+              ide_task_return_error (task, g_steal_pointer (&error));
+              IDE_EXIT;
+            }
+
+          if (!(dest_eval = tmpl_template_expand_string (expander, scope, &error)))
+            {
+              ide_task_return_error (task, g_steal_pointer (&error));
+              IDE_EXIT;
+            }
+
+          dest = dest_eval;
+        }
+
+      resource_path = g_strdup_printf ("/plugins/meson-templates/resources/%s", src);
+      dest_file = g_file_get_child (destdir, dest);
+
+      if (self->expansions[i].executable)
+        mode = 0750;
+
+      ide_template_base_add_resource (IDE_TEMPLATE_BASE (self),
+                                      resource_path, dest_file, scope, mode);
+    }
+
+  ide_template_base_expand_all_async (IDE_TEMPLATE_BASE (self),
+                                      cancellable,
+                                      gbp_meson_template_expand_cb,
+                                      g_steal_pointer (&task));
+
+  IDE_EXIT;
+}
+
+static gboolean
+gbp_meson_template_expand_finish (IdeProjectTemplate  *template,
+                                  GAsyncResult        *result,
+                                  GError             **error)
+{
+  gboolean ret;
+
+  IDE_ENTRY;
+
+  g_assert (GBP_IS_MESON_TEMPLATE (template));
+  g_assert (IDE_IS_TASK (result));
+
+  ret = ide_task_propagate_boolean (IDE_TASK (result), error);
+
+  IDE_RETURN (ret);
+}
+
+static void
+gbp_meson_template_class_init (GbpMesonTemplateClass *klass)
+{
+  IdeProjectTemplateClass *template_class = IDE_PROJECT_TEMPLATE_CLASS (klass);
+
+  template_class->expand_async = gbp_meson_template_expand_async;
+  template_class->expand_finish = gbp_meson_template_expand_finish;
+}
+
+static void
+gbp_meson_template_init (GbpMesonTemplate *self)
+{
+}
+
+void
+gbp_meson_template_set_expansions (GbpMesonTemplate                *self,
+                                   const GbpMesonTemplateExpansion *expansions,
+                                   guint                            n_expansions)
+{
+  g_return_if_fail (GBP_IS_MESON_TEMPLATE (self));
+  g_return_if_fail (n_expansions == 0 || expansions != NULL);
+
+  self->expansions = expansions;
+  self->n_expansions = n_expansions;
+}
+
+void
+gbp_meson_template_set_extra_scope (GbpMesonTemplate   *self,
+                                    const char * const *extra_scope)
+{
+  g_return_if_fail (GBP_IS_MESON_TEMPLATE (self));
+
+  self->extra_scope = extra_scope;
+}
+
+void
+gbp_meson_template_set_language_scope (GbpMesonTemplate                    *self,
+                                       const GbpMesonTemplateLanguageScope *language_scope,
+                                       guint                                n_language_scope)
+{
+  g_return_if_fail (GBP_IS_MESON_TEMPLATE (self));
+  g_return_if_fail (n_language_scope == 0 || language_scope != NULL);
+
+  self->language_scope = language_scope;
+  self->n_language_scope = n_language_scope;
+}
diff --git a/src/plugins/meson-templates/gbp-meson-template.h 
b/src/plugins/meson-templates/gbp-meson-template.h
new file mode 100644
index 000000000..8942eace5
--- /dev/null
+++ b/src/plugins/meson-templates/gbp-meson-template.h
@@ -0,0 +1,54 @@
+/* gbp-meson-template.h
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <libide-projects.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GbpMesonTemplateExpansion
+{
+  const char         *input;
+  const char         *output_pattern;
+  const char * const *languages;
+  gboolean            executable;
+} GbpMesonTemplateExpansion;
+
+typedef struct _GbpMesonTemplateLanguageScope
+{
+  const char *language;
+  const char * const *extra_scope;
+} GbpMesonTemplateLanguageScope;
+
+#define GBP_TYPE_MESON_TEMPLATE (gbp_meson_template_get_type())
+
+G_DECLARE_FINAL_TYPE (GbpMesonTemplate, gbp_meson_template, GBP, MESON_TEMPLATE, IdeProjectTemplate)
+
+void gbp_meson_template_set_expansions     (GbpMesonTemplate                    *self,
+                                            const GbpMesonTemplateExpansion     *expansions,
+                                            guint                                n_expansions);
+void gbp_meson_template_set_extra_scope    (GbpMesonTemplate                    *self,
+                                            const char * const                  *extra_scope);
+void gbp_meson_template_set_language_scope (GbpMesonTemplate                    *self,
+                                            const GbpMesonTemplateLanguageScope *language_scope,
+                                            guint                                n_language_scope);
+
+G_END_DECLS
diff --git a/src/plugins/meson-templates/meson-templates-plugin.c 
b/src/plugins/meson-templates/meson-templates-plugin.c
new file mode 100644
index 000000000..0d432e232
--- /dev/null
+++ b/src/plugins/meson-templates/meson-templates-plugin.c
@@ -0,0 +1,35 @@
+/* meson-templates-plugin.c
+ *
+ * Copyright 2017-2022 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "config.h"
+
+#include <libpeas/peas.h>
+
+#include <libide-projects.h>
+
+#include "gbp-meson-template-provider.h"
+
+_IDE_EXTERN void
+_gbp_meson_templates_register_types (PeasObjectModule *module)
+{
+  peas_object_module_register_extension_type (module,
+                                              IDE_TYPE_TEMPLATE_PROVIDER,
+                                              GBP_TYPE_MESON_TEMPLATE_PROVIDER);
+}
diff --git a/src/plugins/meson-templates/meson-templates.gresource.xml 
b/src/plugins/meson-templates/meson-templates.gresource.xml
index aac749e2e..32bb3853d 100644
--- a/src/plugins/meson-templates/meson-templates.gresource.xml
+++ b/src/plugins/meson-templates/meson-templates.gresource.xml
@@ -1,71 +1,52 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <gresources>
-  <gresource prefix="/plugins/meson_templates">
-    <file compressed="true">resources/src/window.ui</file>
+  <gresource prefix="/plugins/meson-templates">
+    <file>meson-templates.plugin</file>
     <file compressed="true">resources/src/window-gtk4.ui</file>
     <file compressed="true">resources/src/help-overlay.ui</file>
-    <file compressed="true">resources/src/window.js.tmpl</file>
-    <file compressed="true">resources/src/meson-py.build</file>
+    <file compressed="true">resources/src/window-gtk4.js</file>
     <file compressed="true">resources/src/meson-py-gtk4.build</file>
-    <file compressed="true">resources/src/window.h</file>
+    <file compressed="true">resources/src/window-gtk4.h</file>
     <file compressed="true">resources/src/hello.js.in</file>
     <file compressed="true">resources/src/hello.gresource.xml</file>
     <file compressed="true">resources/src/hello-version.h.in</file>
     <file compressed="true">resources/src/meson-clib.build</file>
     <file compressed="true">resources/src/meson-js.build</file>
-    <file compressed="true">resources/src/meson-rs.build</file>
     <file compressed="true">resources/src/meson-rs-gtk4.build</file>
     <file compressed="true">resources/src/hello.c</file>
     <file compressed="true">resources/src/hello.h</file>
-    <file compressed="true">resources/src/application.c</file>
+    <file compressed="true">resources/src/application-gtk4.c</file>
     <file compressed="true">resources/src/application-gtk4.vala</file>
-    <file compressed="true">resources/src/application.h</file>
-    <file compressed="true">resources/src/application.rs</file>
+    <file compressed="true">resources/src/application-gtk4.h</file>
+    <file compressed="true">resources/src/application-gtk4.rs</file>
     <file compressed="true">resources/src/__init__.py</file>
     <file compressed="true">resources/src/meson-c-vala.build</file>
     <file compressed="true">resources/src/meson-empty.build</file>
-    <file compressed="true">resources/src/main.js.tmpl</file>
     <file compressed="true">resources/src/main-gtk4.js.tmpl</file>
-    <file compressed="true">resources/src/main.c</file>
     <file compressed="true">resources/src/main-gtk4.c</file>
     <file compressed="true">resources/src/main-cli.c</file>
-    <file compressed="true">resources/src/main.cpp</file>
     <file compressed="true">resources/src/main-cli.cpp</file>
     <file compressed="true">resources/src/hello.src.gresource.xml</file>
-    <file compressed="true">resources/src/window.c</file>
-    <file compressed="true">resources/src/window.cpp</file>
-    <file compressed="true">resources/src/window.hpp</file>
-    <file compressed="true">resources/src/window.py</file>
+    <file compressed="true">resources/src/window-gtk4.c</file>
     <file compressed="true">resources/src/window-gtk4.py</file>
-    <file compressed="true">resources/src/window.vala</file>
     <file compressed="true">resources/src/window-gtk4.vala</file>
-    <file compressed="true">resources/src/config.rs.in</file>
     <file compressed="true">resources/src/config-gtk4.rs.in</file>
-    <file compressed="true">resources/src/window.rs</file>
     <file compressed="true">resources/src/window-gtk4.rs</file>
-    <file compressed="true">resources/src/main.vala</file>
     <file compressed="true">resources/src/main-gtk4.vala</file>
     <file compressed="true">resources/src/main-cli.vala</file>
     <file compressed="true">resources/src/hello.py.in</file>
     <file compressed="true">resources/src/hello-cli.py.in</file>
-    <file compressed="true">resources/src/main.py</file>
     <file compressed="true">resources/src/main-gtk4.py</file>
     <file compressed="true">resources/src/main-cli.py</file>
-    <file compressed="true">resources/src/main.rs</file>
     <file compressed="true">resources/src/main-gtk4.rs</file>
     <file compressed="true">resources/src/main-cli.rs</file>
-    <file compressed="true">resources/src/application.in</file>
-    <file compressed="true">resources/src/main.cs</file>
     <file compressed="true">resources/src/Cargo.lock</file>
-    <file compressed="true">resources/src/Cargo.toml</file>
     <file compressed="true">resources/src/Cargo-gtk4.toml</file>
     <file compressed="true">resources/src/Cargo-cli.toml</file>
-    <file compressed="true">resources/src/meson-cs.build</file>
     <file compressed="true">resources/build-aux/cargo.sh</file>
     <file compressed="true">resources/meson.build</file>
     <file compressed="true">resources/src/meson-cli.build</file>
     <file compressed="true">resources/src/meson-py-cli.build</file>
-    <file compressed="true">resources/flatpak-gtksharp.json.tmpl</file>
     <file compressed="true">resources/data/meson.build</file>
     <file compressed="true">resources/data/hello.gschema.xml</file>
     <file compressed="true">resources/data/hello.desktop.in</file>
@@ -77,16 +58,7 @@
     <file compressed="true">resources/po/POTFILES</file>
     <file compressed="true">resources/po/LINGUAS</file>
   </gresource>
-  <gresource prefix="/plugins/meson_templates/resources">
+  <gresource prefix="/plugins/meson-templates/resources">
     <file compressed="true">flatpak.json</file>
   </gresource>
-  <gresource prefix="/org/gnome/builder">
-    <file compressed="true">icons/scalable/actions/pattern-legacy.svg</file>
-    <file compressed="true">icons/scalable/actions/pattern-library.svg</file>
-    <file compressed="true">icons/scalable/actions/pattern-grid.svg</file>
-    <file compressed="true">icons/scalable/actions/pattern-browse.svg</file>
-    <file compressed="true">icons/scalable/actions/pattern-cli.svg</file>
-    <file compressed="true">icons/scalable/actions/pattern-gnome.svg</file>
-    <file compressed="true">icons/scalable/actions/pattern-gtk.svg</file>
-  </gresource>
 </gresources>
diff --git a/src/plugins/meson-templates/meson-templates.plugin 
b/src/plugins/meson-templates/meson-templates.plugin
index eace1c33f..dbab4337a 100644
--- a/src/plugins/meson-templates/meson-templates.plugin
+++ b/src/plugins/meson-templates/meson-templates.plugin
@@ -1,11 +1,10 @@
 [Plugin]
-Authors=Patrick Griffis <tingping tingping se>
-Copyright=Copyright © 2016 Patrick Griffis
+Authors=Patrick Griffis <tingping tingping se>, Christian hergert <chergert redhat com>
+Builtin=true
+Copyright=Copyright © 2016 Patrick Griffis, Copyright © 2022 Christian Hergert
 Depends=create-project;
-Description=Provides templates for creating meson projects
-Hidden=true
-Loader=python3
-Module=meson_templates
-Name=Meson Templates
-X-Builder-ABI=@PACKAGE_ABI@
-X-Has-Resources=true
+Description=Provides templates for creating new meson projects
+Embedded=_gbp_meson_templates_register_types
+Module=meson-templates
+Name=Meson Project Templates
+X-Category=templates
diff --git a/src/plugins/meson-templates/meson.build b/src/plugins/meson-templates/meson.build
index d2ce17c50..ad901b1d4 100644
--- a/src/plugins/meson-templates/meson.build
+++ b/src/plugins/meson-templates/meson.build
@@ -1,3 +1,11 @@
+if get_option('plugin_meson_templates')
+
+plugins_sources += files([
+  'meson-templates-plugin.c',
+  'gbp-meson-template.c',
+  'gbp-meson-template-provider.c',
+])
+
 flatpak_json_data = configuration_data()
 flatpak_json_data.set('gnome_sdk_version', get_option('gnome_sdk_version'))
 flatpak_json = configure_file(
@@ -5,21 +13,13 @@ flatpak_json = configure_file(
   output: 'flatpak.json',
   configuration: flatpak_json_data)
 
-meson_templates_resources = gnome.compile_resources(
-  'meson_templates',
+plugin_meson_templates_resources = gnome.compile_resources(
+  'gbp-meson-templates',
   'meson-templates.gresource.xml',
-  gresource_bundle: true,
-           install: true,
-       install_dir: plugindir,
-      dependencies: [flatpak_json],
+        c_name: 'gbp_meson_templates',
+  dependencies: [flatpak_json],
 )
 
-install_data('meson_templates.py', install_dir: plugindir)
+plugins_sources += plugin_meson_templates_resources
 
-configure_file(
-          input: 'meson-templates.plugin',
-         output: 'meson-templates.plugin',
-  configuration: config_h,
-        install: true,
-    install_dir: plugindir,
-)
+endif
diff --git a/src/plugins/meson-templates/resources/data/hello.desktop.in 
b/src/plugins/meson-templates/resources/data/hello.desktop.in
index 108d8099b..36d0711b3 100644
--- a/src/plugins/meson-templates/resources/data/hello.desktop.in
+++ b/src/plugins/meson-templates/resources/data/hello.desktop.in
@@ -1,10 +1,7 @@
 [Desktop Entry]
 Name={{name}}
-
 Exec={{exec_name}}
-
 Icon={{appid}}
-
 Terminal=false
 Type=Application
 Categories=GTK;
diff --git a/src/plugins/meson-templates/resources/data/meson.build 
b/src/plugins/meson-templates/resources/data/meson.build
index e37dec014..1be2d69fb 100644
--- a/src/plugins/meson-templates/resources/data/meson.build
+++ b/src/plugins/meson-templates/resources/data/meson.build
@@ -1,32 +1,28 @@
 desktop_file = i18n.merge_file(
-  input: '{{appid}}.desktop.in',
-  output: '{{appid}}.desktop',
-  type: 'desktop',
-  po_dir: '../po',
-  install: true,
+        input: '{{appid}}.desktop.in',
+       output: '{{appid}}.desktop',
+         type: 'desktop',
+       po_dir: '../po',
+      install: true,
   install_dir: join_paths(get_option('datadir'), 'applications')
 )
 
 desktop_utils = find_program('desktop-file-validate', required: false)
 if desktop_utils.found()
-  test('Validate desktop file', desktop_utils,
-    args: [desktop_file]
-  )
+  test('Validate desktop file', desktop_utils, args: [desktop_file])
 endif
 
 appstream_file = i18n.merge_file(
-  input: '{{appid}}.appdata.xml.in',
-  output: '{{appid}}.appdata.xml',
-  po_dir: '../po',
-  install: true,
+        input: '{{appid}}.appdata.xml.in',
+       output: '{{appid}}.appdata.xml',
+       po_dir: '../po',
+      install: true,
   install_dir: join_paths(get_option('datadir'), 'appdata')
 )
 
 appstream_util = find_program('appstream-util', required: false)
 if appstream_util.found()
-  test('Validate appstream file', appstream_util,
-    args: ['validate', appstream_file]
-  )
+  test('Validate appstream file', appstream_util, args: ['validate', appstream_file])
 endif
 
 install_data('{{appid}}.gschema.xml',
@@ -35,9 +31,9 @@ install_data('{{appid}}.gschema.xml',
 
 compile_schemas = find_program('glib-compile-schemas', required: false)
 if compile_schemas.found()
-  test('Validate schema file', compile_schemas,
-    args: ['--strict', '--dry-run', meson.current_source_dir()]
-  )
+  test('Validate schema file',
+       compile_schemas,
+       args: ['--strict', '--dry-run', meson.current_source_dir()])
 endif
 
 subdir('icons')
diff --git a/src/plugins/meson-templates/resources/flatpak.json.in 
b/src/plugins/meson-templates/resources/flatpak.json.in
index 8fd56f0af..6112dabcd 100644
--- a/src/plugins/meson-templates/resources/flatpak.json.in
+++ b/src/plugins/meson-templates/resources/flatpak.json.in
@@ -13,9 +13,9 @@
         "--share=network",
         "--share=ipc",
         "--socket=fallback-x11",
-{{if (template == "gnome-app-gtk4") || (template == "gnome-app-adwaita")}}
+{{if is_gtk4}}
         "--device=dri",
-{{endif}}
+{{end}}
         "--socket=wayland"
     ],
 {{if language == "rust"}}
@@ -45,145 +45,6 @@
         "*.a"
     ],
     "modules" : [
-{{if template == "gnome-app"}}
-{{if language == "c++"}}
-        {
-           "name" : "mm-common",
-           "buildsystem" : "meson",
-           "sources" : [
-               {
-                   "type" : "archive",
-                   "url" : "https://download.gnome.org/sources/mm-common/1.0/mm-common-1.0.4.tar.xz";,
-                   "sha256" : "e954c09b4309a7ef93e13b69260acdc5738c907477eb381b78bb1e414ee6dbd8"
-               }
-           ]
-        },
-        {
-            "name" : "sigc++-2",
-            "buildsystem" : "meson",
-            "sources" : [
-                {
-                    "type" : "archive",
-                    "url" : "https://download.gnome.org/sources/libsigc++/2.10/libsigc++-2.10.8.tar.xz";,
-                    "sha256" : "235a40bec7346c7b82b6a8caae0456353dc06e71f14bc414bcc858af1838719a"
-                }
-            ]
-        },
-        {
-            "name" : "sigc++",
-            "buildsystem" : "meson",
-            "config-opts" : [ "-Dbuild-documentation=false", "-Dmaintainer-mode=false" ],
-            "sources" : [
-                {
-                    "type" : "git",
-                    "url" : "https://github.com/libsigcplusplus/libsigcplusplus.git";,
-                    "tag" : "3.2.0"
-                }
-            ]
-        },
-        {
-            "name" : "glibmm-2-70",
-            "buildsystem" : "meson",
-            "config-opts" : [ "-Dbuild-documentation=false", "-Dmaintainer-mode=false" ],
-            "sources" : [
-                {
-                    "type" : "archive",
-                    "url" : "https://download.gnome.org/sources/glibmm/2.70/glibmm-2.70.0.tar.xz";,
-                    "sha256" : "8008fd8aeddcc867a3f97f113de625f6e96ef98cf7860379813a9c0feffdb520"
-                }
-            ]
-        },
-        {
-            "name" : "glibmm-2-66",
-            "buildsystem" : "meson",
-            "config-opts" : [ "-Dbuild-documentation=false", "-Dmaintainer-mode=false" ],
-            "sources" : [
-                {
-                    "type" : "archive",
-                    "url" : "https://download.gnome.org/sources/glibmm/2.66/glibmm-2.66.2.tar.xz";,
-                    "sha256" : "b2a4cd7b9ae987794cbb5a1becc10cecb65182b9bb841868625d6bbb123edb1d"
-                }
-            ]
-        },
-        {
-            "name" : "cairomm-1-14",
-            "buildsystem" : "meson",
-            "sources" : [
-                {
-                    "type" : "archive",
-                    "url" : "https://cairographics.org/releases/cairomm-1.14.3.tar.xz";,
-                    "sha256" : "0d37e067c5c4ca7808b7ceddabfe1932c5bd2a750ad64fb321e1213536297e78"
-                }
-            ]
-        },
-        {
-            "name" : "cairomm-1-16",
-            "buildsystem" : "meson",
-            "sources" : [
-                {
-                    "type" : "archive",
-                    "url" : "https://cairographics.org/releases/cairomm-1.16.1.tar.xz";,
-                    "sha256" : "6f6060d8e98dd4b8acfee2295fddbdd38cf487c07c26aad8d1a83bb9bff4a2c6"
-                }
-            ]
-        },
-        {
-            "name" : "pangomm-2-46",
-            "buildsystem" : "meson",
-            "sources" : [
-                {
-                    "type" : "archive",
-                    "url" : "https://download.gnome.org/sources/pangomm/2.46/pangomm-2.46.2.tar.xz";,
-                    "sha256" : "57442ab4dc043877bfe3839915731ab2d693fc6634a71614422fb530c9eaa6f4"
-                }
-            ]
-        },
-        {
-            "name" : "pangomm-2-50",
-            "buildsystem" : "meson",
-            "sources" : [
-                {
-                    "type" : "archive",
-                    "url" : "https://download.gnome.org/sources/pangomm/2.50/pangomm-2.50.0.tar.xz";,
-                    "sha256" : "a27aa77e017b9afce9e751d85bd1cf890abbb3a58bf59d0fac917eef82db3b5b"
-                }
-            ]
-        },
-        {
-            "name" : "atkmm-2-28",
-            "buildsystem" : "meson",
-            "sources" : [
-                {
-                    "type" : "archive",
-                    "url" : "https://download.gnome.org/sources/atkmm/2.28/atkmm-2.28.2.tar.xz";,
-                    "sha256" : "a0bb49765ceccc293ab2c6735ba100431807d384ffa14c2ebd30e07993fd2fa4"
-                }
-            ]
-        },
-        {
-            "name" : "atkmm-2-36",
-            "buildsystem" : "meson",
-            "sources" : [
-                {
-                    "type" : "archive",
-                    "url" : "https://download.gnome.org/sources/atkmm/2.36/atkmm-2.36.1.tar.xz";,
-                    "sha256" : "e11324bfed1b6e330a02db25cecc145dca03fb0dff47f0710c85e317687da458"
-                }
-            ]
-        },
-        {
-            "name" : "gtkmm-3-24",
-            "buildsystem" : "meson",
-            "sources" : [
-                {
-                    "type" : "archive",
-                    "url" : "https://download.gnome.org/sources/gtkmm/3.24/gtkmm-3.24.5.tar.xz";,
-                    "sha256" : "856333de86689f6a81c123f2db15d85db9addc438bc3574c36f15736aeae22e6"
-                }
-            ]
-        },
-{{end}}
-{{end}}
         {
             "name" : "{{name}}",
             "builddir" : true,
diff --git a/src/plugins/meson-templates/resources/meson.build 
b/src/plugins/meson-templates/resources/meson.build
index 29d36f389..def9f1832 100644
--- a/src/plugins/meson-templates/resources/meson.build
+++ b/src/plugins/meson-templates/resources/meson.build
@@ -2,24 +2,18 @@ project('{{name}}',{{if language == "c"}} 'c',{{else if language == "c++"}} ['cp
 
           version: '{{project_version}}',
     meson_version: '>= 0.59.0',
-  default_options: [ 'warning_level=2',
-                     'werror=false',
-{{if language == "c"}}
-                     'c_std=gnu11',
-{{end}}
-{{if language == "c++"}}
-                     'cpp_std=gnu++2a',
-{{end}}
-                   ],
+  default_options: [ 'warning_level=2', 'werror=false',{{if language == "c"}} 'c_std=gnu11',{{else if 
language == "c++"}} 'cpp_std=gnu++2a',{{end}} ],
 )
 
 {{if enable_i18n}}
 i18n = import('i18n')
 {{end}}
-
 {{if enable_gnome}}
 gnome = import('gnome')
 {{end}}
+{{if language == "c"}}
+cc = meson.get_compiler('c')
+{{end}}
 
 {{if language == "c"}}
 config_h = configuration_data()
@@ -28,15 +22,77 @@ config_h.set_quoted('PACKAGE_VERSION', meson.project_version())
 config_h.set_quoted('GETTEXT_PACKAGE', '{{name}}')
 config_h.set_quoted('LOCALEDIR', join_paths(get_option('prefix'), get_option('localedir')))
 {{end}}
-configure_file(
-  output: '{{prefix}}-config.h',
-  configuration: config_h,
-)
-add_project_arguments([
-  '-I' + meson.project_build_root(),
-], language: 'c')
+configure_file(output: 'config.h', configuration: config_h)
+add_project_arguments(['-I' + meson.project_build_root()], language: 'c')
 {{end}}
 
+{{if language == "c"}}
+project_c_args = []
+test_c_args = [
+  '-Wcast-align',
+  '-Wdeclaration-after-statement',
+  '-Werror=address',
+  '-Werror=array-bounds',
+  '-Werror=empty-body',
+  '-Werror=implicit',
+  '-Werror=implicit-function-declaration',
+  '-Werror=incompatible-pointer-types',
+  '-Werror=init-self',
+  '-Werror=int-conversion',
+  '-Werror=int-to-pointer-cast',
+  '-Werror=main',
+  '-Werror=misleading-indentation',
+  '-Werror=missing-braces',
+  '-Werror=missing-include-dirs',
+  '-Werror=nonnull',
+  '-Werror=overflow',
+  '-Werror=parenthesis',
+  '-Werror=pointer-arith',
+  '-Werror=pointer-to-int-cast',
+  '-Werror=redundant-decls',
+  '-Werror=return-type',
+  '-Werror=sequence-point',
+  '-Werror=shadow',
+  '-Werror=strict-prototypes',
+  '-Werror=trigraphs',
+  '-Werror=undef',
+  '-Werror=write-strings',
+  '-Wformat-nonliteral',
+  '-Wignored-qualifiers',
+  '-Wimplicit-function-declaration',
+  '-Wlogical-op',
+  '-Wmissing-declarations',
+  '-Wmissing-format-attribute',
+  '-Wmissing-include-dirs',
+  '-Wmissing-noreturn',
+  '-Wnested-externs',
+  '-Wno-cast-function-type',
+  '-Wno-dangling-pointer',
+  '-Wno-missing-field-initializers',
+  '-Wno-sign-compare',
+  '-Wno-unused-parameter',
+  '-Wold-style-definition',
+  '-Wpointer-arith',
+  '-Wredundant-decls',
+  '-Wstrict-prototypes',
+  '-Wswitch-default',
+  '-Wswitch-enum',
+  '-Wundef',
+  '-Wuninitialized',
+  '-Wunused',
+  '-fno-strict-aliasing',
+  ['-Werror=format-security', '-Werror=format=2'],
+]
+if get_option('buildtype') != 'plain'
+  test_c_args += '-fstack-protector-strong'
+endif
+foreach arg: test_c_args
+  if cc.has_multi_arguments(arg)
+    project_c_args += arg
+  endif
+endforeach
+add_project_arguments(project_c_args, language: 'c')
+{{end}}
 {{if language == "rust"}}
 cargo_sources = files(
   'Cargo.toml',
@@ -54,8 +110,8 @@ subdir('po')
 
 {{if enable_gnome}}
 gnome.post_install(
-  glib_compile_schemas: true,
-  gtk_update_icon_cache: true,
+     glib_compile_schemas: true,
+    gtk_update_icon_cache: true,
   update_desktop_database: true,
 )
 {{end}}
diff --git a/src/plugins/meson-templates/resources/po/POTFILES 
b/src/plugins/meson-templates/resources/po/POTFILES
index e9b7255fb..38e497942 100644
--- a/src/plugins/meson-templates/resources/po/POTFILES
+++ b/src/plugins/meson-templates/resources/po/POTFILES
@@ -1,27 +1,22 @@
 data/{{appid}}.desktop.in
 data/{{appid}}.appdata.xml.in
 data/{{appid}}.gschema.xml
-{{if ui_file}}
-src/{{ui_file}}
-
-{{end}}
 {{if language == "c"}}
 src/main.c
 src/{{prefix}}-window.c
-
 {{end}}
 {{if language == "vala"}}
 src/main.vala
 src/window.vala
-
 {{end}}
 {{if language == "javascript"}}
 src/main.js
 src/window.js
-
 {{end}}
 {{if language == "python"}}
 src/main.py
 src/window.py
-
+{{end}}
+{{if ui_file}}
+src/{{ui_file}}
 {{end}}
diff --git a/src/plugins/meson-templates/resources/src/application-gtk4.c 
b/src/plugins/meson-templates/resources/src/application-gtk4.c
new file mode 100644
index 000000000..636652a3d
--- /dev/null
+++ b/src/plugins/meson-templates/resources/src/application-gtk4.c
@@ -0,0 +1,102 @@
+{{include "license.c"}}
+
+#include "config.h"
+
+#include "{{prefix}}-application.h"
+#include "{{prefix}}-window.h"
+
+struct _{{PreFix}}Application
+{
+{{if is_adwaita}}
+  AdwApplication parent_instance;
+{{else}}
+  GtkApplication parent_instance;
+{{end}}
+};
+
+G_DEFINE_TYPE ({{PreFix}}Application, {{prefix_}}_application, {{if 
is_adwaita}}ADW_TYPE_APPLICATION{{else}}GTK_TYPE_APPLICATION{{end}})
+
+{{PreFix}}Application *
+{{prefix_}}_application_new (const char        *application_id,
+{{spaces}}                  GApplicationFlags  flags)
+{
+  g_return_val_if_fail (application_id != NULL, NULL);
+
+  return g_object_new ({{PREFIX}}_TYPE_APPLICATION,
+                       "application-id", application_id,
+                       "flags", flags,
+                       NULL);
+}
+
+static void
+{{prefix_}}_application_activate (GApplication *app)
+{
+  GtkWindow *window;
+
+  g_assert ({{PREFIX}}_IS_APPLICATION (app));
+
+  window = gtk_application_get_active_window (GTK_APPLICATION (app));
+  if (window == NULL)
+    window = g_object_new ({{PREFIX}}_TYPE_WINDOW,
+                           "application", app,
+                           NULL);
+
+  gtk_window_present (window);
+}
+
+static void
+{{prefix_}}_application_class_init ({{PreFix}}ApplicationClass *klass)
+{
+  GApplicationClass *app_class = G_APPLICATION_CLASS (klass);
+
+  app_class->activate = {{prefix_}}_application_activate;
+}
+
+static void
+{{prefix_}}_application_about_action (GSimpleAction *action,
+{{spaces}}                           GVariant      *parameter,
+{{spaces}}                           gpointer       user_data)
+{
+  static const char *authors[] = {"{{author}}", NULL};
+  {{PreFix}}Application *self = user_data;
+  GtkWindow *window = NULL;
+
+  g_assert ({{PREFIX}}_IS_APPLICATION (self));
+
+  window = gtk_application_get_active_window (GTK_APPLICATION (self));
+
+  gtk_show_about_dialog (window,
+                         "program-name", "{{name}}",
+                         "authors", authors,
+                         "version", "{{project_version}}",
+                         NULL);
+}
+
+static void
+{{prefix_}}_application_quit_action (GSimpleAction *action,
+{{spaces}}                          GVariant      *parameter,
+{{spaces}}                          gpointer       user_data)
+{
+  {{PreFix}}Application *self = user_data;
+
+  g_assert ({{PREFIX}}_IS_APPLICATION (self));
+
+  g_application_quit (G_APPLICATION (self));
+}
+
+static const GActionEntry app_actions[] = {
+  { "quit", {{prefix_}}_application_quit_action },
+  { "about", {{prefix_}}_application_about_action },
+};
+
+static void
+{{prefix_}}_application_init ({{PreFix}}Application *self)
+{
+  g_action_map_add_action_entries (G_ACTION_MAP (self),
+                                   app_actions,
+                                   G_N_ELEMENTS (app_actions),
+                                   self);
+  gtk_application_set_accels_for_action (GTK_APPLICATION (self),
+                                         "app.quit",
+                                         (const char *[]) { "<primary>q", NULL });
+}
diff --git a/src/plugins/meson-templates/resources/src/application.h 
b/src/plugins/meson-templates/resources/src/application-gtk4.h
similarity index 83%
rename from src/plugins/meson-templates/resources/src/application.h
rename to src/plugins/meson-templates/resources/src/application-gtk4.h
index b63af79ae..6b89d98a4 100644
--- a/src/plugins/meson-templates/resources/src/application.h
+++ b/src/plugins/meson-templates/resources/src/application-gtk4.h
@@ -14,7 +14,7 @@ G_BEGIN_DECLS
 
 G_DECLARE_FINAL_TYPE ({{PreFix}}Application, {{prefix_}}_application, {{PREFIX}}, APPLICATION, {{if 
is_adwaita}}AdwApplication{{else}}GtkApplication{{end}})
 
-{{PreFix}}Application *{{prefix_}}_application_new (gchar *application_id,
+{{PreFix}}Application *{{prefix_}}_application_new (const char        *application_id,
 {{Spaces}}{{spaces}}                               GApplicationFlags  flags);
 
 G_END_DECLS
diff --git a/src/plugins/meson-templates/resources/src/application.rs 
b/src/plugins/meson-templates/resources/src/application-gtk4.rs
similarity index 99%
rename from src/plugins/meson-templates/resources/src/application.rs
rename to src/plugins/meson-templates/resources/src/application-gtk4.rs
index 9d2b56cb3..0314259a8 100644
--- a/src/plugins/meson-templates/resources/src/application.rs
+++ b/src/plugins/meson-templates/resources/src/application-gtk4.rs
@@ -1,3 +1,5 @@
+{{include "license.rs"}}
+
 use glib::clone;
 use gtk::prelude::*;
 use gtk::subclass::prelude::*;
diff --git a/src/plugins/meson-templates/resources/src/hello.gresource.xml 
b/src/plugins/meson-templates/resources/src/hello.gresource.xml
index 198ae49fc..41902a2d5 100644
--- a/src/plugins/meson-templates/resources/src/hello.gresource.xml
+++ b/src/plugins/meson-templates/resources/src/hello.gresource.xml
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <gresources>
   <gresource prefix="{{appid_path}}">
-    <file>{{ui_file}}</file>
+    <file preprocess="xml-stripblanks">{{ui_file}}</file>
 {{if (template == "gnome-app-gtk4") || (template == "gnome-app-adwaita")}}
-    <file>gtk/help-overlay.ui</file>
+    <file preprocess="xml-stripblanks">gtk/help-overlay.ui</file>
 {{end}}
   </gresource>
 </gresources>
diff --git a/src/plugins/meson-templates/resources/src/main-cli.c 
b/src/plugins/meson-templates/resources/src/main-cli.c
index fe5e9bab8..1cdc55b63 100644
--- a/src/plugins/meson-templates/resources/src/main-cli.c
+++ b/src/plugins/meson-templates/resources/src/main-cli.c
@@ -1,6 +1,6 @@
 {{include "license.c"}}
 
-#include "{{prefix}}-config.h"
+#include "config.h"
 
 #include <glib.h>
 {{if enable_i18n}}
diff --git a/src/plugins/meson-templates/resources/src/main-gtk4.c 
b/src/plugins/meson-templates/resources/src/main-gtk4.c
index ebaa237a4..848061839 100644
--- a/src/plugins/meson-templates/resources/src/main-gtk4.c
+++ b/src/plugins/meson-templates/resources/src/main-gtk4.c
@@ -1,8 +1,9 @@
 {{include "license.c"}}
 
+#include "config.h"
+
 #include <glib/gi18n.h>
 
-#include "{{prefix}}-config.h"
 #include "{{prefix}}-application.h"
 
 int
@@ -12,28 +13,11 @@ main (int   argc,
        g_autoptr({{PreFix}}Application) app = NULL;
        int ret;
 
-       /* Set up gettext translations */
        bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
        bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
        textdomain (GETTEXT_PACKAGE);
 
-       /*
-        * Create a new GtkApplication. The application manages our main loop,
-        * application windows, integration with the window manager/compositor, and
-        * desktop features such as file opening and single-instance applications.
-        */
        app = {{prefix_}}_application_new ("{{appid}}", G_APPLICATION_FLAGS_NONE);
-
-       /*
-        * Run the application. This function will block until the application
-        * exits. Upon return, we have our exit code to return to the shell. (This
-        * is the code you see when you do `echo $?` after running a command in a
-        * terminal.
-        *
-        * Since GtkApplication inherits from GApplication, we use the parent class
-        * method "run". But we need to cast, which is what the "G_APPLICATION()"
-        * macro does.
-        */
        ret = g_application_run (G_APPLICATION (app), argc, argv);
 
        return ret;
diff --git a/src/plugins/meson-templates/resources/src/main-gtk4.rs 
b/src/plugins/meson-templates/resources/src/main-gtk4.rs
index abafbd171..25e5dab99 100644
--- a/src/plugins/meson-templates/resources/src/main-gtk4.rs
+++ b/src/plugins/meson-templates/resources/src/main-gtk4.rs
@@ -1,3 +1,5 @@
+{{include "license.rs"}}
+
 mod application;
 mod config;
 mod window;
diff --git a/src/plugins/meson-templates/resources/src/meson-c-vala.build 
b/src/plugins/meson-templates/resources/src/meson-c-vala.build
index ab73b14de..f76b265cd 100644
--- a/src/plugins/meson-templates/resources/src/meson-c-vala.build
+++ b/src/plugins/meson-templates/resources/src/meson-c-vala.build
@@ -1,44 +1,28 @@
 {{name_}}_sources = [
 {{if language == "c"}}
   'main.c',
-  '{{prefix}}-window.c',
-{{if (template == "gnome-app-gtk4") || (template == "gnome-app-adwaita")}}
   '{{prefix}}-application.c',
-{{end}}
-{{else if language == "c++"}}
-  'main.cpp',
-  '{{prefix}}-window.cpp',
+  '{{prefix}}-window.c',
 {{else if language == "vala"}}
   'main.vala',
-  'window.vala',
-{{if (template == "gnome-app-gtk4") || (template == "gnome-app-adwaita")}}
   'application.vala',
-{{end}}
+  'window.vala',
 {{end}}
 ]
 
 {{name_}}_deps = [
-{{if language == "c++"}}
-  dependency('gtkmm-3.0', version: '>= 3.18'),
-{{else if template == "gnome-app-gtk4"}}
   dependency('gtk4'),
-{{else if template == "gnome-app-adwaita"}}
-  dependency('libadwaita-1', version: '>= 1.0'),
-{{else}}
-  dependency('gio-2.0', version: '>= 2.50'),
-  dependency('gtk+-3.0', version: '>= 3.22'),
+{{if is_adwaita}}
+  dependency('libadwaita-1'),
 {{end}}
 ]
 
-gnome = import('gnome')
-
 {{name_}}_sources += gnome.compile_resources('{{prefix}}-resources',
   '{{prefix}}.gresource.xml',
   c_name: '{{prefix_}}'
 )
 
 executable('{{name}}', {{name_}}_sources,
-{{if language == "vala"}}  vala_args: '--target-glib=2.50',{{end}}
   dependencies: {{name_}}_deps,
-  install: true,
+       install: true,
 )
diff --git a/src/plugins/meson-templates/resources/src/meson-clib.build 
b/src/plugins/meson-templates/resources/src/meson-clib.build
index af5b27723..47821e2a8 100644
--- a/src/plugins/meson-templates/resources/src/meson-clib.build
+++ b/src/plugins/meson-templates/resources/src/meson-clib.build
@@ -9,38 +9,33 @@ api_version = '0.1'
 ]
 
 version_split = meson.project_version().split('.')
-MAJOR_VERSION = version_split[0]
-MINOR_VERSION = version_split[1]
-MICRO_VERSION = version_split[2]
-
 version_conf = configuration_data()
 version_conf.set('VERSION', meson.project_version())
-version_conf.set('MAJOR_VERSION', MAJOR_VERSION)
-version_conf.set('MINOR_VERSION', MINOR_VERSION)
-version_conf.set('MICRO_VERSION', MICRO_VERSION)
+version_conf.set('MAJOR_VERSION', version_split[0])
+version_conf.set('MINOR_VERSION', version_split[1])
+version_conf.set('MICRO_VERSION', version_split[2])
 
 configure_file(
-  input: '{{name}}-version.h.in',
-  output: '{{name}}-version.h',
+          input: '{{name}}-version.h.in',
+         output: '{{name}}-version.h',
   configuration: version_conf,
-  install: true,
-  install_dir: join_paths(get_option('includedir'), '{{name}}')
+        install: true,
+    install_dir: join_paths(get_option('includedir'), '{{name}}')
 )
 
 {{name_}}_deps = [
-  dependency('gio-2.0', version: '>= 2.50'),
+  dependency('gio-2.0'),
 ]
 
 {{name_}}_lib = shared_library('{{name}}-' + api_version,
   {{name_}}_sources,
   dependencies: {{name_}}_deps,
-  install: true,
+       install: true,
 )
 
 install_headers({{name_}}_headers, subdir: '{{name}}')
 
 pkg = import('pkgconfig')
-
 pkg.generate(
   description: 'A shared library for ...',
     libraries: {{name_}}_lib,
@@ -48,6 +43,16 @@ pkg.generate(
      filebase: '{{name}}-' + api_version,
       version: meson.project_version(),
       subdirs: '{{name}}',
-     requires: 'glib-2.0',
+     requires: 'gio-2.0',
   install_dir: join_paths(get_option('libdir'), 'pkgconfig')
 )
+
+gnome = import('gnome')
+{{name_}}_gir = gnome.generate_gir({{name_}}_lib,
+            nsversion: api_version,
+            namespace: '{{Prefix}}',
+        symbol_prefix: '{{prefix}}',
+    identifier_prefix: '{{Prefix}}',
+             includes: [ 'Gio-2.0' ],
+              install: true,
+)
diff --git a/src/plugins/meson-templates/resources/src/meson-py-cli.build 
b/src/plugins/meson-templates/resources/src/meson-py-cli.build
index cbc888a74..6ff464cda 100644
--- a/src/plugins/meson-templates/resources/src/meson-py-cli.build
+++ b/src/plugins/meson-templates/resources/src/meson-py-cli.build
@@ -4,15 +4,14 @@ moduledir = join_paths(pkgdatadir, '{{name_}}')
 python = import('python')
 
 conf = configuration_data()
-conf.set('PYTHON', python.find_installation('python3').path())
+conf.set('PYTHON', python.find_installation('python3').full_path())
 conf.set('pkgdatadir', pkgdatadir)
-
 configure_file(
-    input: '{{name}}.in',
-    output: '{{name}}',
+            input: '{{name}}.in',
+           output: '{{name}}',
     configuration: conf,
-    install: true,
-    install_dir: get_option('bindir')
+          install: true,
+      install_dir: get_option('bindir')
 )
 
 {{name_}}_sources = [
diff --git a/src/plugins/meson-templates/resources/src/window.c 
b/src/plugins/meson-templates/resources/src/window-gtk4.c
similarity index 75%
rename from src/plugins/meson-templates/resources/src/window.c
rename to src/plugins/meson-templates/resources/src/window-gtk4.c
index 689d03968..d2098b936 100644
--- a/src/plugins/meson-templates/resources/src/window.c
+++ b/src/plugins/meson-templates/resources/src/window-gtk4.c
@@ -1,18 +1,19 @@
 {{include "license.c"}}
 
-#include "{{prefix}}-config.h"
+#include "config.h"
+
 #include "{{prefix}}-window.h"
 
 struct _{{PreFix}}Window
 {
-  GtkApplicationWindow  parent_instance;
+  {{if is_adwaita}}Adw{{else}}Gtk{{end}}ApplicationWindow  parent_instance;
 
   /* Template widgets */
   GtkHeaderBar        *header_bar;
   GtkLabel            *label;
 };
 
-G_DEFINE_TYPE ({{PreFix}}Window, {{prefix_}}_window, GTK_TYPE_APPLICATION_WINDOW)
+G_DEFINE_FINAL_TYPE ({{PreFix}}Window, {{prefix_}}_window, {{if 
is_adwaita}}ADW{{else}}GTK{{end}}_TYPE_APPLICATION_WINDOW)
 
 static void
 {{prefix_}}_window_class_init ({{PreFix}}WindowClass *klass)
diff --git a/src/plugins/meson-templates/resources/src/window.h 
b/src/plugins/meson-templates/resources/src/window-gtk4.h
similarity index 62%
rename from src/plugins/meson-templates/resources/src/window.h
rename to src/plugins/meson-templates/resources/src/window-gtk4.h
index 3e757b50f..6ba8f3f5c 100644
--- a/src/plugins/meson-templates/resources/src/window.h
+++ b/src/plugins/meson-templates/resources/src/window-gtk4.h
@@ -2,12 +2,16 @@
 
 #pragma once
 
+{{if is_adwaita}}
+#include <adwaita.h>
+{{else}}
 #include <gtk/gtk.h>
+{{end}}
 
 G_BEGIN_DECLS
 
 #define {{PREFIX}}_TYPE_WINDOW ({{prefix_}}_window_get_type())
 
-G_DECLARE_FINAL_TYPE ({{PreFix}}Window, {{prefix_}}_window, {{PREFIX}}, WINDOW, GtkApplicationWindow)
+G_DECLARE_FINAL_TYPE ({{PreFix}}Window, {{prefix_}}_window, {{PREFIX}}, WINDOW, {{if 
is_adwaita}}Adw{{else}}Gtk{{end}}ApplicationWindow)
 
 G_END_DECLS
diff --git a/src/plugins/meson-templates/resources/src/window.js.tmpl 
b/src/plugins/meson-templates/resources/src/window-gtk4.js
similarity index 70%
rename from src/plugins/meson-templates/resources/src/window.js.tmpl
rename to src/plugins/meson-templates/resources/src/window-gtk4.js
index 4d1f4020c..4d6f053fa 100644
--- a/src/plugins/meson-templates/resources/src/window.js.tmpl
+++ b/src/plugins/meson-templates/resources/src/window-gtk4.js
@@ -2,12 +2,15 @@
 
 import GObject from 'gi://GObject';
 import Gtk from 'gi://Gtk';
+{{if is_adwaita}}
+import Adw from 'gi://Adw';
+{{end}}
 
 export const {{PreFix}}Window = GObject.registerClass({
     GTypeName: '{{PreFix}}Window',
     Template: 'resource://{{appid_path}}/{{ui_file}}',
     InternalChildren: ['label'],
-}, class {{PreFix}}Window extends Gtk.ApplicationWindow {
+}, class {{PreFix}}Window extends {{if is_adwaita}}Adw{{else}}Gtk{{end}}.ApplicationWindow {
     _init(application) {
         super._init({ application });
     }
diff --git a/src/plugins/meson-templates/resources/src/window-gtk4.py 
b/src/plugins/meson-templates/resources/src/window-gtk4.py
index b8065c27e..a41beaa94 100644
--- a/src/plugins/meson-templates/resources/src/window-gtk4.py
+++ b/src/plugins/meson-templates/resources/src/window-gtk4.py
@@ -1,10 +1,12 @@
 {{include "license.py"}}
 
+{{if is_adwaita}}
+from gi.repository import Adw
+{{end}}
 from gi.repository import Gtk
 
-
 @Gtk.Template(resource_path='{{appid_path}}/{{ui_file}}')
-class {{PreFix}}Window(Gtk.ApplicationWindow):
+class {{PreFix}}Window({{if is_adwaita}}Adw{{else}}Gtk{{end}}.ApplicationWindow):
     __gtype_name__ = '{{PreFix}}Window'
 
     label = Gtk.Template.Child()
diff --git a/src/plugins/meson-templates/resources/src/window-gtk4.rs 
b/src/plugins/meson-templates/resources/src/window-gtk4.rs
index 0ef2d37c2..23732815a 100644
--- a/src/plugins/meson-templates/resources/src/window-gtk4.rs
+++ b/src/plugins/meson-templates/resources/src/window-gtk4.rs
@@ -1,3 +1,8 @@
+{{include "license.rs"}}
+
+{{if is_adwaita}}
+use adw::subclass::prelude::*;
+{{end}}
 use gtk::prelude::*;
 use gtk::subclass::prelude::*;
 use gtk::{gio, glib, CompositeTemplate};
@@ -19,7 +24,7 @@ mod imp {
     impl ObjectSubclass for {{PreFix}}Window {
         const NAME: &'static str = "{{PreFix}}Window";
         type Type = super::{{PreFix}}Window;
-        type ParentType = gtk::ApplicationWindow;
+        type ParentType = {{if is_adwaita}}adw{{else}}gtk{{end}}::ApplicationWindow;
 
         fn class_init(klass: &mut Self::Class) {
             Self::bind_template(klass);
@@ -34,11 +39,14 @@ mod imp {
     impl WidgetImpl for {{PreFix}}Window {}
     impl WindowImpl for {{PreFix}}Window {}
     impl ApplicationWindowImpl for {{PreFix}}Window {}
+{{if is_adwaita}}
+    impl AdwApplicationWindowImpl for {{Prefix}}Window {}
+{{end}}
 }
 
 glib::wrapper! {
     pub struct {{PreFix}}Window(ObjectSubclass<imp::{{PreFix}}Window>)
-        @extends gtk::Widget, gtk::Window, gtk::ApplicationWindow,
+        @extends gtk::Widget, gtk::Window, gtk::ApplicationWindow,{{if is_adwaita}} 
adw::ApplicationWindow,{{end}}
         @implements gio::ActionGroup, gio::ActionMap;
 }
 
diff --git a/src/plugins/meson-templates/resources/src/window-gtk4.ui 
b/src/plugins/meson-templates/resources/src/window-gtk4.ui
index f9a03a124..2163ba420 100644
--- a/src/plugins/meson-templates/resources/src/window-gtk4.ui
+++ b/src/plugins/meson-templates/resources/src/window-gtk4.ui
@@ -1,9 +1,39 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
   <requires lib="gtk" version="4.0"/>
-  <template class="{{PreFix}}Window" parent="GtkApplicationWindow">
+{{if is_adwaita}}
+  <requires lib="Adw" version="1.0"/>
+{{end}}
+  <template class="{{PreFix}}Window" parent="{{if is_adwaita}}Adw{{else}}Gtk{{end}}ApplicationWindow">
     <property name="default-width">600</property>
     <property name="default-height">300</property>
+{{if is_adwaita}}
+    <child>
+      <object class="GtkBox">
+        <property name="orientation">vertical</property>
+        <child>
+          <object class="GtkHeaderBar" id="header_bar">
+            <child type="end">
+              <object class="GtkMenuButton">
+                <property name="icon-name">open-menu-symbolic</property>
+                <property name="menu-model">primary_menu</property>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkLabel" id="label">
+            <property name="label">Hello, World!</property>
+            <property name="vexpand">true</property>
+            <attributes>
+              <attribute name="weight" value="bold"/>
+              <attribute name="scale" value="2"/>
+            </attributes>
+          </object>
+        </child>
+      </object>
+    </child>
+{{else}}
     <child type="titlebar">
       <object class="GtkHeaderBar" id="header_bar">
         <child type="end">
@@ -23,8 +53,8 @@
         </attributes>
       </object>
     </child>
+{{end}}
   </template>
-
   <menu id="primary_menu">
     <section>
       <item>
@@ -36,7 +66,7 @@
         <attribute name="action">win.show-help-overlay</attribute>
       </item>
       <item>
-        <attribute name="label" translatable="yes">_About {{name}}</attribute>
+        <attribute name="label" translatable="yes">_About {{Title}}</attribute>
         <attribute name="action">app.about</attribute>
       </item>
     </section>
diff --git a/src/plugins/meson-templates/resources/src/window-gtk4.vala 
b/src/plugins/meson-templates/resources/src/window-gtk4.vala
index 4cacdb12f..226d1c5ff 100644
--- a/src/plugins/meson-templates/resources/src/window-gtk4.vala
+++ b/src/plugins/meson-templates/resources/src/window-gtk4.vala
@@ -2,7 +2,7 @@
 
 namespace {{PreFix}} {
     [GtkTemplate (ui = "{{appid_path}}/{{ui_file}}")]
-    public class Window : Gtk.ApplicationWindow {
+    public class Window : {{if is_adwaita}}Adw{{else}}Gtk{{end}}.ApplicationWindow {
         [GtkChild]
         private unowned Gtk.Label label;
 


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