[ghex/libadwaita: 3/3] Port to libadwaita: Initial commit




commit f7e7187dfdb841465ef7340b951d8d536facd8a9
Author: Logan Rathbone <poprocks gmail com>
Date:   Thu Jun 16 19:20:46 2022 -0400

    Port to libadwaita: Initial commit

 .../actions/document-modified-symbolic.svg         | 407 ++++++++++++++++++++
 meson.build                                        |   3 +-
 src/configuration.c                                | 151 +-------
 src/configuration.h                                |   6 +-
 src/ghex-application-window.c                      | 412 ++++++++-------------
 src/ghex-application-window.h                      |   6 +-
 src/ghex-application-window.ui.in                  | 131 ++++---
 src/ghex-notebook-tab.c                            | 273 --------------
 src/ghex-notebook-tab.h                            |  47 ---
 src/gtkhex.c                                       |  16 +-
 src/hex-buffer-direct.c                            |   1 +
 src/main.c                                         |  12 +-
 src/meson.build                                    |   4 +-
 src/preferences.c                                  |   7 +-
 src/preferences.h                                  |   1 +
 15 files changed, 677 insertions(+), 800 deletions(-)
---
diff --git a/icons/hicolor/scalable/actions/document-modified-symbolic.svg 
b/icons/hicolor/scalable/actions/document-modified-symbolic.svg
new file mode 100644
index 0000000..842b6a7
--- /dev/null
+++ b/icons/hicolor/scalable/actions/document-modified-symbolic.svg
@@ -0,0 +1,407 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   height="16px"
+   viewBox="0 0 16 16"
+   width="16px"
+   version="1.1"
+   id="svg373"
+   sodipodi:docname="pin-location-symbolic.svg"
+   inkscape:version="1.1 (c68e22c387, 2021-05-23)"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:svg="http://www.w3.org/2000/svg";>
+  <defs
+     id="defs377" />
+  <sodipodi:namedview
+     id="namedview375"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     inkscape:pagecheckerboard="0"
+     showgrid="false"
+     inkscape:zoom="80.25"
+     inkscape:cx="5.9501558"
+     inkscape:cy="8"
+     inkscape:window-width="3840"
+     inkscape:window-height="2123"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg373" />
+  <filter
+     id="a"
+     height="1"
+     width="1"
+     x="0"
+     y="0">
+    <feColorMatrix
+       in="SourceGraphic"
+       type="matrix"
+       values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"
+       id="feColorMatrix210" />
+  </filter>
+  <mask
+     id="b">
+    <g
+       filter="url(#a)"
+       id="g215">
+      <path
+         d="m 0 0 h 16 v 16 h -16 z"
+         fill-opacity="0.3"
+         id="path213" />
+    </g>
+  </mask>
+  <clipPath
+     id="c">
+    <path
+       d="m 0 0 h 1024 v 800 h -1024 z"
+       id="path218" />
+  </clipPath>
+  <mask
+     id="d">
+    <g
+       filter="url(#a)"
+       id="g223">
+      <path
+         d="m 0 0 h 16 v 16 h -16 z"
+         fill-opacity="0.05"
+         id="path221" />
+    </g>
+  </mask>
+  <clipPath
+     id="e">
+    <path
+       d="m 0 0 h 1024 v 800 h -1024 z"
+       id="path226" />
+  </clipPath>
+  <mask
+     id="f">
+    <g
+       filter="url(#a)"
+       id="g231">
+      <path
+         d="m 0 0 h 16 v 16 h -16 z"
+         fill-opacity="0.05"
+         id="path229" />
+    </g>
+  </mask>
+  <clipPath
+     id="g">
+    <path
+       d="m 0 0 h 1024 v 800 h -1024 z"
+       id="path234" />
+  </clipPath>
+  <mask
+     id="h">
+    <g
+       filter="url(#a)"
+       id="g239">
+      <path
+         d="m 0 0 h 16 v 16 h -16 z"
+         fill-opacity="0.05"
+         id="path237" />
+    </g>
+  </mask>
+  <clipPath
+     id="i">
+    <path
+       d="m 0 0 h 1024 v 800 h -1024 z"
+       id="path242" />
+  </clipPath>
+  <mask
+     id="j">
+    <g
+       filter="url(#a)"
+       id="g247">
+      <path
+         d="m 0 0 h 16 v 16 h -16 z"
+         fill-opacity="0.05"
+         id="path245" />
+    </g>
+  </mask>
+  <clipPath
+     id="k">
+    <path
+       d="m 0 0 h 1024 v 800 h -1024 z"
+       id="path250" />
+  </clipPath>
+  <mask
+     id="l">
+    <g
+       filter="url(#a)"
+       id="g255">
+      <path
+         d="m 0 0 h 16 v 16 h -16 z"
+         fill-opacity="0.05"
+         id="path253" />
+    </g>
+  </mask>
+  <clipPath
+     id="m">
+    <path
+       d="m 0 0 h 1024 v 800 h -1024 z"
+       id="path258" />
+  </clipPath>
+  <mask
+     id="n">
+    <g
+       filter="url(#a)"
+       id="g263">
+      <path
+         d="m 0 0 h 16 v 16 h -16 z"
+         fill-opacity="0.05"
+         id="path261" />
+    </g>
+  </mask>
+  <clipPath
+     id="o">
+    <path
+       d="m 0 0 h 1024 v 800 h -1024 z"
+       id="path266" />
+  </clipPath>
+  <mask
+     id="p">
+    <g
+       filter="url(#a)"
+       id="g271">
+      <path
+         d="m 0 0 h 16 v 16 h -16 z"
+         fill-opacity="0.3"
+         id="path269" />
+    </g>
+  </mask>
+  <clipPath
+     id="q">
+    <path
+       d="m 0 0 h 1024 v 800 h -1024 z"
+       id="path274" />
+  </clipPath>
+  <mask
+     id="r">
+    <g
+       filter="url(#a)"
+       id="g279">
+      <path
+         d="m 0 0 h 16 v 16 h -16 z"
+         fill-opacity="0.5"
+         id="path277" />
+    </g>
+  </mask>
+  <clipPath
+     id="s">
+    <path
+       d="m 0 0 h 1024 v 800 h -1024 z"
+       id="path282" />
+  </clipPath>
+  <mask
+     id="t">
+    <g
+       filter="url(#a)"
+       id="g287">
+      <path
+         d="m 0 0 h 16 v 16 h -16 z"
+         fill-opacity="0.4"
+         id="path285" />
+    </g>
+  </mask>
+  <clipPath
+     id="u">
+    <path
+       d="m 0 0 h 1024 v 800 h -1024 z"
+       id="path290" />
+  </clipPath>
+  <mask
+     id="v">
+    <g
+       filter="url(#a)"
+       id="g295">
+      <path
+         d="m 0 0 h 16 v 16 h -16 z"
+         fill-opacity="0.4"
+         id="path293" />
+    </g>
+  </mask>
+  <clipPath
+     id="w">
+    <path
+       d="m 0 0 h 1024 v 800 h -1024 z"
+       id="path298" />
+  </clipPath>
+  <mask
+     id="x">
+    <g
+       filter="url(#a)"
+       id="g303">
+      <path
+         d="m 0 0 h 16 v 16 h -16 z"
+         fill-opacity="0.5"
+         id="path301" />
+    </g>
+  </mask>
+  <clipPath
+     id="y">
+    <path
+       d="m 0 0 h 1024 v 800 h -1024 z"
+       id="path306" />
+  </clipPath>
+  <mask
+     id="z">
+    <g
+       filter="url(#a)"
+       id="g311">
+      <path
+         d="m 0 0 h 16 v 16 h -16 z"
+         fill-opacity="0.5"
+         id="path309" />
+    </g>
+  </mask>
+  <clipPath
+     id="A">
+    <path
+       d="m 0 0 h 1024 v 800 h -1024 z"
+       id="path314" />
+  </clipPath>
+  <g
+     clip-path="url(#c)"
+     mask="url(#b)"
+     transform="matrix(1 0 0 1 -760 -60)"
+     id="g319">
+    <path
+       d="m 562.460938 212.058594 h 10.449218 c -1.183594 0.492187 -1.296875 2.460937 0 3 h -10.449218 z m 0 
0"
+       fill="#2e3436"
+       id="path317" />
+  </g>
+  <path
+     d="m 12,8 c 0,2.210938 -1.789062,4 -4,4 C 5.789062,12 4,10.210938 4,8 4,5.789062 5.789062,4 8,4 c 
2.210938,0 4,1.789062 4,4 z m 0,0"
+     fill="#2e3436"
+     id="path323" />
+  <g
+     clip-path="url(#e)"
+     mask="url(#d)"
+     transform="matrix(1 0 0 1 -760 -60)"
+     id="g327">
+    <path
+       d="m 16 632 h 1 v 1 h -1 z m 0 0"
+       fill="#2e3436"
+       fill-rule="evenodd"
+       id="path325" />
+  </g>
+  <g
+     clip-path="url(#g)"
+     mask="url(#f)"
+     transform="matrix(1 0 0 1 -760 -60)"
+     id="g331">
+    <path
+       d="m 17 631 h 1 v 1 h -1 z m 0 0"
+       fill="#2e3436"
+       fill-rule="evenodd"
+       id="path329" />
+  </g>
+  <g
+     clip-path="url(#i)"
+     mask="url(#h)"
+     transform="matrix(1 0 0 1 -760 -60)"
+     id="g335">
+    <path
+       d="m 18 634 h 1 v 1 h -1 z m 0 0"
+       fill="#2e3436"
+       fill-rule="evenodd"
+       id="path333" />
+  </g>
+  <g
+     clip-path="url(#k)"
+     mask="url(#j)"
+     transform="matrix(1 0 0 1 -760 -60)"
+     id="g339">
+    <path
+       d="m 16 634 h 1 v 1 h -1 z m 0 0"
+       fill="#2e3436"
+       fill-rule="evenodd"
+       id="path337" />
+  </g>
+  <g
+     clip-path="url(#m)"
+     mask="url(#l)"
+     transform="matrix(1 0 0 1 -760 -60)"
+     id="g343">
+    <path
+       d="m 17 635 h 1 v 1 h -1 z m 0 0"
+       fill="#2e3436"
+       fill-rule="evenodd"
+       id="path341" />
+  </g>
+  <g
+     clip-path="url(#o)"
+     mask="url(#n)"
+     transform="matrix(1 0 0 1 -760 -60)"
+     id="g347">
+    <path
+       d="m 19 635 h 1 v 1 h -1 z m 0 0"
+       fill="#2e3436"
+       fill-rule="evenodd"
+       id="path345" />
+  </g>
+  <g
+     clip-path="url(#q)"
+     mask="url(#p)"
+     transform="matrix(1 0 0 1 -760 -60)"
+     id="g351">
+    <path
+       d="m 136 660 v 7 h 7 v -7 z m 0 0"
+       fill="#2e3436"
+       id="path349" />
+  </g>
+  <g
+     clip-path="url(#s)"
+     mask="url(#r)"
+     transform="matrix(1 0 0 1 -760 -60)"
+     id="g355">
+    <path
+       d="m 199 642 h 3 v 12 h -3 z m 0 0"
+       fill="#2e3436"
+       id="path353" />
+  </g>
+  <g
+     clip-path="url(#u)"
+     mask="url(#t)"
+     transform="matrix(1 0 0 1 -760 -60)"
+     id="g359">
+    <path
+       d="m 209.5 144.160156 c 0.277344 0 0.5 0.222656 0.5 0.5 v 1 c 0 0.277344 -0.222656 0.5 -0.5 0.5 s 
-0.5 -0.222656 -0.5 -0.5 v -1 c 0 -0.277344 0.222656 -0.5 0.5 -0.5 z m 0 0"
+       fill="#2e3436"
+       id="path357" />
+  </g>
+  <g
+     clip-path="url(#w)"
+     mask="url(#v)"
+     transform="matrix(1 0 0 1 -760 -60)"
+     id="g363">
+    <path
+       d="m 206.5 144.160156 c 0.277344 0 0.5 0.222656 0.5 0.5 v 1 c 0 0.277344 -0.222656 0.5 -0.5 0.5 s 
-0.5 -0.222656 -0.5 -0.5 v -1 c 0 -0.277344 0.222656 -0.5 0.5 -0.5 z m 0 0"
+       fill="#2e3436"
+       id="path361" />
+  </g>
+  <g
+     clip-path="url(#y)"
+     mask="url(#x)"
+     transform="matrix(1 0 0 1 -760 -60)"
+     id="g367">
+    <path
+       d="m 229.5 143.160156 c -0.546875 0 -1 0.457032 -1 1 c 0 0.546875 0.453125 1 1 1 s 1 -0.453125 1 -1 c 
0 -0.542968 -0.453125 -1 -1 -1 z m 0 0"
+       fill="#2e3436"
+       id="path365" />
+  </g>
+  <g
+     clip-path="url(#A)"
+     mask="url(#z)"
+     transform="matrix(1 0 0 1 -760 -60)"
+     id="g371">
+    <path
+       d="m 226.453125 143.160156 c -0.519531 0 -0.953125 0.433594 -0.953125 0.953125 v 0.09375 c 0 0.519531 
0.433594 0.953125 0.953125 0.953125 h 0.09375 c 0.519531 0 0.953125 -0.433594 0.953125 -0.953125 v -0.09375 c 
0 -0.519531 -0.433594 -0.953125 -0.953125 -0.953125 z m 0 0"
+       fill="#2e3436"
+       id="path369" />
+  </g>
+</svg>
diff --git a/meson.build b/meson.build
index 63d6c15..2f247a6 100644
--- a/meson.build
+++ b/meson.build
@@ -147,7 +147,8 @@ glib_ver = '>= 2.68.0'
 gmodule_dep = dependency('gmodule-2.0')
 glib_dep = dependency('glib-2.0', version: glib_ver)
 gio_dep = dependency('gio-2.0', version: glib_ver)
-gtk_dep = dependency('gtk4', version: '>= 4.0.0')
+gtk_dep = dependency('gtk4', version: '>= 4.4.0')
+adw_dep = dependency('libadwaita-1')
 
 configure_file(
   output: 'config.h',
diff --git a/src/configuration.c b/src/configuration.c
index 959853b..032fa86 100644
--- a/src/configuration.c
+++ b/src/configuration.c
@@ -45,9 +45,6 @@ char *data_font_name;
 guint shaded_box_size;
 gboolean show_offsets_column;
 int def_dark_mode;
-/* Will default to false here. We can't set it until we get a 'screen', so
- * we'll save calling get_sys_default_is_dark() until GHex launches. */
-gboolean sys_default_is_dark;
 
 static void
 offsets_column_changed_cb (GSettings   *settings,
@@ -72,147 +69,27 @@ dark_mode_changed_cb (GSettings   *settings,
                   const gchar *key,
                   gpointer     user_data)
 {
-    def_dark_mode = g_settings_get_enum (settings, key);
-}
-
-
-/* NOTE: for GTK 4.0 backwards compatibility, we manually define these
- * here. If we wish to add an additional dependency on
- * gsettings-desktop-schemas >= 42, this can be eliminated.
- */
-enum system_color_scheme {
-       SYSTEM_DEFAULT,
-       SYSTEM_PREFER_DARK,
-       SYSTEM_PREFER_LIGHT,
-};
-
-static gboolean
-try_dark_from_gsettings (void)
-{
-       int color_scheme;
-       GSettingsSchemaSource *source;
-       GSettingsSchema *schema;
-       char *schema_id = NULL;
-
-       source = g_settings_schema_source_get_default ();
-       schema = g_settings_schema_source_lookup (source, "org.freedesktop.appearance", TRUE);
-
-       if (schema && g_settings_schema_has_key (schema, "color-scheme"))
-       {
-               schema_id = "org.freedesktop.appearance";
-       }
-       else
-       {
-               g_clear_pointer (&schema, g_settings_schema_unref);
-               schema = g_settings_schema_source_lookup (source, "org.gnome.desktop.interface", TRUE);
-               if (schema && g_settings_schema_has_key (schema, "color-scheme"))
-               {
-                       schema_id = "org.gnome.desktop.interface";
-               }
-               g_clear_pointer (&schema, g_settings_schema_unref);
-       }
-
-       if (schema_id)
-       {
-               GSettings *set = g_settings_new (schema_id);
-               color_scheme = g_settings_get_enum (set, "color-scheme");
-               if (color_scheme == SYSTEM_PREFER_DARK)
-                       sys_default_is_dark = TRUE;
-               g_object_unref (set);
+       AdwStyleManager *manager = adw_style_manager_get_default ();
 
-               return TRUE;
-       }
-       return FALSE;
-}
+    def_dark_mode = g_settings_get_enum (settings, key);
 
-static gboolean
-try_dark_from_portal (void)
-{
-       int color_scheme;
-       char *color_scheme_str = NULL;
-       GDBusProxy *settings_portal = NULL;
-       GVariant *gvar = NULL, *gvar2 = NULL;
-       gboolean retval = FALSE;
-
-       settings_portal = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
-                       G_DBUS_PROXY_FLAGS_NONE,
-                       NULL,
-                       "org.freedesktop.portal.Desktop",
-                       "/org/freedesktop/portal/desktop",
-                       "org.freedesktop.portal.Settings",
-                       NULL,
-                       NULL);
-
-       if (! settings_portal)
-               goto out;
-
-       gvar = g_dbus_proxy_call_sync (settings_portal,
-                       "Read",
-                       g_variant_new ("(ss)", "org.freedesktop.appearance", "color-scheme"),
-                       G_DBUS_CALL_FLAGS_NONE,
-                       G_MAXINT,
-                       NULL,
-                       NULL);
-
-       if (gvar)
+       switch (def_dark_mode)
        {
-               g_variant_get (gvar, "(v)", &gvar2);
-               g_variant_get (g_variant_get_variant (gvar2), "u", &color_scheme);
-               retval = TRUE;
-               goto out;
-       }
-
-       gvar = g_dbus_proxy_call_sync (settings_portal,
-                       "Read",
-                       g_variant_new ("(ss)", "org.gnome.desktop.interface", "color-scheme"),
-                       G_DBUS_CALL_FLAGS_NONE,
-                       G_MAXINT,
-                       NULL,
-                       NULL);
+               case DARK_MODE_OFF:
+                       adw_style_manager_set_color_scheme (manager, ADW_COLOR_SCHEME_FORCE_LIGHT);
+                       break;
 
-       if (! gvar)
-               goto out;
+               case DARK_MODE_ON:
+                       adw_style_manager_set_color_scheme (manager, ADW_COLOR_SCHEME_FORCE_DARK);
+                       break;
 
-       g_variant_get (gvar, "(v)", &gvar2);
-       g_variant_get (g_variant_get_variant (gvar2), "s", &color_scheme_str);
+               case DARK_MODE_SYSTEM:
+                       adw_style_manager_set_color_scheme (manager, ADW_COLOR_SCHEME_DEFAULT);
+                       break;
 
-       if (color_scheme_str)
-       {
-               retval = TRUE;
-               if (g_strcmp0 (color_scheme_str, "prefer-dark") == 0)
-                       color_scheme = SYSTEM_PREFER_DARK;
+               default:
+                       break;
        }
-
-out:
-       if (color_scheme == SYSTEM_PREFER_DARK)
-               sys_default_is_dark = TRUE;
-
-       g_clear_object (&settings_portal);
-       g_clear_pointer (&gvar, g_variant_unref);
-       g_clear_pointer (&gvar2, g_variant_unref);
-
-       return retval;
-}
-
-void
-get_sys_default_is_dark (void)
-{
-       GtkSettings *gtk_settings;
-       gboolean got_dark_pref;
-
-       got_dark_pref = try_dark_from_portal ();
-       if (got_dark_pref)
-               return;
-
-       got_dark_pref = try_dark_from_gsettings ();
-       if (got_dark_pref)
-               return;
-
-       /* If all else fails, try to fetch from GtkSettings. */
-       gtk_settings = gtk_settings_get_default ();
-       g_object_get (gtk_settings,
-                       "gtk-application-prefer-dark-theme", &sys_default_is_dark,
-                       NULL);
 }
 
 static void
diff --git a/src/configuration.h b/src/configuration.h
index af17e1a..ffea2a8 100644
--- a/src/configuration.h
+++ b/src/configuration.h
@@ -34,6 +34,7 @@
 #define GHEX_CONFIGURATION_H
 
 #include <gtk/gtk.h>
+#include <adwaita.h>
 
 G_BEGIN_DECLS
 
@@ -62,7 +63,6 @@ extern gboolean               show_offsets_column;
 extern guint           shaded_box_size;
 extern int                     def_group_type;
 extern int                     def_dark_mode;
-extern gboolean                sys_default_is_dark;
 
 extern GSettings       *settings;
 extern GtkCssProvider *provider;
@@ -70,10 +70,6 @@ extern GtkCssProvider *provider;
 /* Initializes the gsettings client */
 void ghex_init_configuration (void);
 
-/* Cache the system default of prefer-dark-theme as gtk does not do this for
- * us. */
-void get_sys_default_is_dark (void);
-
 G_END_DECLS
 
 #endif /* GHEX_CONFIGURATION_H */
diff --git a/src/ghex-application-window.c b/src/ghex-application-window.c
index 32b39e9..b36ce14 100644
--- a/src/ghex-application-window.c
+++ b/src/ghex-application-window.c
@@ -37,6 +37,17 @@
 #define ACTIVE_GH      \
        (ghex_application_window_get_hex (self))
 
+#define GH_FOR_TAB(TV, NUM) \
+               (HEX_WIDGET(adw_tab_page_get_child (adw_tab_view_get_nth_page (TV, NUM))));
+
+#define TAB_FOR_GH(GH) \
+       (adw_tab_view_get_page (ADW_TAB_VIEW(self->hex_tab_view), GTK_WIDGET(GH)))
+
+/* Translators: this is the string for an untitled buffer that will
+ * be displayed in the titlebar when a user does File->New
+ */
+#define UNTITLED_STRING N_("Untitled")
+
 static GFile *tmp_global_gfile_for_nag_screen;
 
 /* This is dumb, but right now I can't think of a simpler solution. */
@@ -48,7 +59,7 @@ static gpointer extra_user_data;
 
 struct _GHexApplicationWindow
 {
-       GtkApplicationWindow parent_instance;
+       AdwApplicationWindow parent_instance;
 
        HexWidget *gh;
        HexDialog *dialog;
@@ -69,7 +80,8 @@ struct _GHexApplicationWindow
 
        /* From GtkBuilder: */
        GtkWidget *no_doc_label;
-       GtkWidget *hex_notebook;
+       GtkWidget *tab_view_box;
+       GtkWidget *hex_tab_view;
        GtkWidget *conversions_box;
        GtkWidget *findreplace_box;
        GtkWidget *pane_toggle_button;
@@ -120,8 +132,7 @@ static const char *main_actions[] = {
        NULL                            /* last action */
 };
 
-G_DEFINE_TYPE (GHexApplicationWindow, ghex_application_window,
-               GTK_TYPE_APPLICATION_WINDOW)
+G_DEFINE_TYPE (GHexApplicationWindow, ghex_application_window, ADW_TYPE_APPLICATION_WINDOW)
 
 /* ---- */
 
@@ -141,47 +152,46 @@ static void ghex_application_window_set_show_jump (GHexApplicationWindow *self,
                gboolean show);
 static void ghex_application_window_set_can_save (GHexApplicationWindow *self,
                gboolean can_save);
-static void ghex_application_window_remove_tab (GHexApplicationWindow *self,
-               GHexNotebookTab *tab);
-static GHexNotebookTab * ghex_application_window_get_current_tab (GHexApplicationWindow *self);
 
 static void update_status_message (GHexApplicationWindow *self);
 static void update_gui_data (GHexApplicationWindow *self);
 static gboolean assess_can_save (HexDocument *doc);
 static void do_close_window (GHexApplicationWindow *self);
-static void close_doc_confirmation_dialog (GHexApplicationWindow *self, GHexNotebookTab *tab);
+static void close_doc_confirmation_dialog (GHexApplicationWindow *self,
+               AdwTabPage *page);
 static void show_no_file_loaded_label (GHexApplicationWindow *self);
 
 static void doc_read_ready_cb (GObject *source_object, GAsyncResult *res,
                gpointer user_data);
+static void file_loaded (HexDocument *doc, GHexApplicationWindow *self);
 
 /* GHexApplicationWindow -- PRIVATE FUNCTIONS */
 
-/* Common macro to apply something to the 'gh' of each tab of the notebook.
+/* Common macro to apply something to the 'gh' of each tab of the tab view.
  *
  * Between _START and _END, put in function calls that use `gh` to be applied
- * to each gh in a tab. Technically you'll also have access to `notebook`
- * and `tab`, but there is generally no reason to directly access these.
+ * to each gh in a tab.
  */
-#define NOTEBOOK_GH_FOREACH_START                                                                            
          \
+#define TAB_VIEW_GH_FOREACH_START                                                                            
          \
 {                                                                                                            
                                          \
-       GtkNotebook *notebook = GTK_NOTEBOOK(self->hex_notebook);                               \
+       AdwTabView *tab_view = ADW_TAB_VIEW(self->hex_tab_view);                                \
        int i;                                                                                                
                                  \
-       for (i = gtk_notebook_get_n_pages(notebook) - 1; i >= 0; --i) {                 \
+       for (i = adw_tab_view_get_n_pages(tab_view) - 1; i >= 0; --i) {                 \
                HexWidget *gh;                                                                                
                          \
-               gh = HEX_WIDGET(gtk_notebook_get_nth_page (notebook, i));                       \
-/* !NOTEBOOK_GH_FOREACH_START */
+               gh = HEX_WIDGET(adw_tab_page_get_child (                                                      
  \
+                                       adw_tab_view_get_nth_page (tab_view, i)));
+/* !TAB_VIEW_GH_FOREACH_START */
 
-#define NOTEBOOK_GH_FOREACH_END                                                                              
                  \
+#define TAB_VIEW_GH_FOREACH_END                                                                              
                  \
        }                                                                                                     
                                          \
 }                                                                                                            
                                          \
-/* !NOTEBOOK_GH_FOREACH_END    */
+/* !TAB_VIEW_GH_FOREACH_END    */
 
 /* set_*_from_settings
  * These functions all basically set properties from the GSettings global
  * variables. They should be used when a new gh is created, and when we're
  * `foreaching` through all of our tabs via a settings-change cb. See also
- * the `NOTEBOOK_GH_FOREACH_{START,END}` macros above.
+ * the `TAB_VIEW_GH_FOREACH_{START,END}` macros above.
  */
 
 static void
@@ -196,27 +206,6 @@ set_gtkhex_group_type_from_settings (HexWidget *gh)
        hex_widget_set_group_type (gh, def_group_type);
 }
 
-static void
-set_dark_mode_from_settings (GHexApplicationWindow *self)
-{
-       GtkSettings *gtk_settings;
-
-       gtk_settings = gtk_settings_get_default ();
-
-       if (def_dark_mode == DARK_MODE_SYSTEM) {
-               g_object_set (G_OBJECT(gtk_settings),
-                               "gtk-application-prefer-dark-theme",
-                               sys_default_is_dark,
-                               NULL);
-       } else {
-               g_object_set (G_OBJECT(gtk_settings),
-                               "gtk-application-prefer-dark-theme",
-                               def_dark_mode == DARK_MODE_ON ? TRUE : FALSE,
-                               NULL);
-       }
-}
-       
-
 static void
 settings_font_changed_cb (GSettings   *settings,
                const gchar     *key,
@@ -224,11 +213,11 @@ settings_font_changed_cb (GSettings   *settings,
 {
        GHexApplicationWindow *self = GHEX_APPLICATION_WINDOW(user_data);
 
-       NOTEBOOK_GH_FOREACH_START
+       TAB_VIEW_GH_FOREACH_START
 
        common_set_gtkhex_font_from_settings (gh);
 
-       NOTEBOOK_GH_FOREACH_END
+       TAB_VIEW_GH_FOREACH_END
 }
 
 static void
@@ -238,11 +227,11 @@ settings_offsets_column_changed_cb (GSettings   *settings,
 {
        GHexApplicationWindow *self = GHEX_APPLICATION_WINDOW(user_data);
 
-       NOTEBOOK_GH_FOREACH_START
+       TAB_VIEW_GH_FOREACH_START
 
        set_gtkhex_offsets_column_from_settings (gh);
 
-       NOTEBOOK_GH_FOREACH_END
+       TAB_VIEW_GH_FOREACH_END
 }
 
 static void
@@ -252,11 +241,11 @@ settings_group_type_changed_cb (GSettings   *settings,
 {
        GHexApplicationWindow *self = GHEX_APPLICATION_WINDOW(user_data);
 
-       NOTEBOOK_GH_FOREACH_START
+       TAB_VIEW_GH_FOREACH_START
 
        set_gtkhex_group_type_from_settings (gh);
 
-       NOTEBOOK_GH_FOREACH_END
+       TAB_VIEW_GH_FOREACH_END
 }
 
 /* ! settings*changed_cb 's */
@@ -272,47 +261,6 @@ refresh_dialogs (GHexApplicationWindow *self)
        }
 }
 
-static GHexNotebookTab *
-ghex_application_window_get_current_tab (GHexApplicationWindow *self)
-{
-       GtkNotebook *notebook;
-       HexWidget *gh;
-       GHexNotebookTab *tab;
-
-       notebook = GTK_NOTEBOOK(self->hex_notebook);
-       gh = HEX_WIDGET(gtk_notebook_get_nth_page (notebook,
-                       gtk_notebook_get_current_page (notebook)));
-
-       if (gh)
-               tab = GHEX_NOTEBOOK_TAB(gtk_notebook_get_tab_label (notebook,
-                                       GTK_WIDGET(gh)));
-       else
-               tab = NULL;
-
-       return tab;
-}
-
-static void
-ghex_application_window_remove_tab (GHexApplicationWindow *self,
-               GHexNotebookTab *tab)
-{
-       GtkNotebook *notebook = GTK_NOTEBOOK(self->hex_notebook);
-       int page_num;
-       HexWidget *tab_gh;
-
-       tab_gh = ghex_notebook_tab_get_hex (tab);
-       page_num = gtk_notebook_page_num (notebook, GTK_WIDGET(tab_gh));
-       gtk_notebook_remove_page (notebook, page_num);
-
-       if (gtk_notebook_get_n_pages (GTK_NOTEBOOK(self->hex_notebook)) == 1)
-               gtk_notebook_set_show_tabs (GTK_NOTEBOOK(self->hex_notebook), FALSE);
-
-       update_gui_data (self);
-
-       if (gtk_notebook_get_n_pages (GTK_NOTEBOOK(self->hex_notebook)) == 0)
-               show_no_file_loaded_label (self);
-}
-
 static void
 file_save_write_cb (HexDocument *doc,
                GAsyncResult *res,
@@ -326,6 +274,7 @@ file_save_write_cb (HexDocument *doc,
        if (write_successful)
        {
                g_debug ("%s: File saved successfully.", __func__);
+               file_loaded (doc, self);
        }
        else
        {
@@ -361,27 +310,6 @@ do_close_window (GHexApplicationWindow *self)
        gtk_window_set_application (GTK_WINDOW(self), NULL);
 }
 
-static void
-close_all_tabs (GHexApplicationWindow *self)
-{
-       GtkNotebook *notebook = GTK_NOTEBOOK(self->hex_notebook);
-       int i;
-
-       g_debug("%s: %d", __func__, gtk_notebook_get_n_pages (notebook));
-
-       for (i = gtk_notebook_get_n_pages(notebook) - 1; i >= 0; --i)
-       {
-               GHexNotebookTab *tab;
-               HexWidget *gh;
-
-               gh = HEX_WIDGET(gtk_notebook_get_nth_page (notebook, i));
-               tab = GHEX_NOTEBOOK_TAB(gtk_notebook_get_tab_label (notebook,
-                                       GTK_WIDGET(gh)));
-
-               ghex_application_window_remove_tab (self, tab);
-       }
-}
-
 static void
 close_all_tabs_response_cb (GtkDialog *dialog,
                int        response_id,
@@ -389,15 +317,14 @@ close_all_tabs_response_cb (GtkDialog *dialog,
 {
        GHexApplicationWindow *self = GHEX_APPLICATION_WINDOW(user_data);
        
-       /* Regardless of what the user chose, get rid of the dialog. */
-       gtk_window_destroy (GTK_WINDOW(dialog));
-
        if (response_id == GTK_RESPONSE_ACCEPT)
        {
-               g_debug ("%s: Decided to CLOSE despite changes.",       __func__);
-               close_all_tabs (self);
                do_close_window (self);
        }
+
+       /* Regardless of what the user chose, get rid of the dialog. */
+       gtk_window_destroy (GTK_WINDOW(dialog));
+
 }
 
 static void
@@ -426,28 +353,10 @@ close_all_tabs_confirmation_dialog (GHexApplicationWindow *self)
 static void
 check_close_window (GHexApplicationWindow *self)
 {
-       GtkNotebook *notebook = GTK_NOTEBOOK(self->hex_notebook);
+       AdwTabView *tab_view = ADW_TAB_VIEW(self->hex_tab_view);
        gboolean unsaved_found = FALSE;
        int i;
-       const int num_pages = gtk_notebook_get_n_pages (notebook);
-
-       /* We have only one tab open: */
-       if (num_pages == 1)
-       {
-               GHexNotebookTab *tab = ghex_application_window_get_current_tab (self);
-               HexDocument *doc = hex_widget_get_document (ACTIVE_GH);
-
-               if (hex_document_has_changed (doc))
-               {
-                       close_doc_confirmation_dialog (self,
-                                       ghex_application_window_get_current_tab (self));
-               }
-               else
-               {
-                       do_close_window (self);
-               }
-               return;
-       }
+       const int num_pages = adw_tab_view_get_n_pages (tab_view);
 
        /* We have more than one tab open: */
        for (i = num_pages - 1; i >= 0; --i)
@@ -455,7 +364,7 @@ check_close_window (GHexApplicationWindow *self)
                HexWidget *gh;
                HexDocument *doc = NULL;
 
-               gh = HEX_WIDGET(gtk_notebook_get_nth_page (notebook, i));
+               gh = GH_FOR_TAB (tab_view, i);
                doc = hex_widget_get_document (gh);
 
                if (hex_document_has_changed (doc))
@@ -465,7 +374,6 @@ check_close_window (GHexApplicationWindow *self)
        if (unsaved_found) {
                close_all_tabs_confirmation_dialog (self);
        } else {
-               close_all_tabs (self);
                do_close_window (self);
        }
 }
@@ -487,40 +395,39 @@ close_doc_response_cb (GtkDialog *dialog,
                gpointer   user_data)
 {
        GHexApplicationWindow *self = GHEX_APPLICATION_WINDOW(user_data);
-       GHexNotebookTab *tab;
+       AdwTabView *tab_view = ADW_TAB_VIEW(self->hex_tab_view);
+       AdwTabPage *page = ADW_TAB_PAGE(extra_user_data);
        
-       tab = ghex_application_window_get_current_tab (self);
-
        if (response_id == GTK_RESPONSE_ACCEPT)
        {
                file_save (self);
-               ghex_application_window_remove_tab (self, tab);
+               adw_tab_view_close_page_finish (tab_view, page, TRUE);
        }
        else if (response_id == GTK_RESPONSE_REJECT)
        {
-               ghex_application_window_remove_tab (self, tab);
+               adw_tab_view_close_page_finish (tab_view, page, TRUE);
+       }
+       else
+       {
+               adw_tab_view_close_page_finish (tab_view, page, FALSE);
        }
 
        gtk_window_destroy (GTK_WINDOW(dialog));
-
-       /* GtkNotebook likes to grab the focus. Possible TODO would be to subclass
-        * GtkNotebook so we can maintain the grab on the gh widget more easily.
-        */
        gtk_widget_grab_focus (GTK_WIDGET (ACTIVE_GH));
+       extra_user_data = NULL;
 }
 
 static void
-close_doc_confirmation_dialog (GHexApplicationWindow *self,
-               GHexNotebookTab *tab)
+close_doc_confirmation_dialog (GHexApplicationWindow *self, AdwTabPage *page)
 {
        GtkWidget *dialog;
        HexDocument *doc;
        GFile *file;
        char *message;
        char *basename = NULL;
-
-       HexWidget *gh = ghex_notebook_tab_get_hex (tab);
+       HexWidget *gh = HEX_WIDGET(adw_tab_page_get_child (page));
        doc = hex_widget_get_document (gh);
+
        g_return_if_fail (HEX_IS_DOCUMENT (doc));
 
        if (G_IS_FILE (file = hex_document_get_file (doc)))
@@ -555,6 +462,7 @@ close_doc_confirmation_dialog (GHexApplicationWindow *self,
                        _("_Go Back"),                  GTK_RESPONSE_CANCEL,
                        NULL);
 
+       extra_user_data = page;
        g_signal_connect (dialog, "response",
                        G_CALLBACK(close_doc_response_cb), self);
 
@@ -580,10 +488,10 @@ close_tab_shortcut_cb (GtkWidget *widget,
                gpointer user_data)
 {
        GHexApplicationWindow *self = GHEX_APPLICATION_WINDOW(widget);
-       GHexNotebookTab *tab = ghex_application_window_get_current_tab (self);
+       AdwTabPage *page = adw_tab_view_get_selected_page (ADW_TAB_VIEW(self->hex_tab_view));
 
-       if (tab)
-               g_signal_emit_by_name (tab, "close-request");
+       if (page)
+               adw_tab_view_close_page (ADW_TAB_VIEW(self->hex_tab_view), page);
        else
                do_close_window (self);
 
@@ -650,19 +558,42 @@ assess_can_save (HexDocument *doc)
 }
 
 static void
-show_hex_notebook (GHexApplicationWindow *self)
+show_hex_tab_view (GHexApplicationWindow *self)
 {
        gtk_widget_hide (self->no_doc_label);
-       gtk_widget_show (self->hex_notebook);
+       gtk_widget_show (self->tab_view_box);
 }
 
 static void
 show_no_file_loaded_label (GHexApplicationWindow *self)
 {
-       gtk_widget_hide (self->hex_notebook);
+       gtk_widget_hide (self->tab_view_box);
        gtk_widget_show (self->no_doc_label);
 }
 
+static void
+update_tabs (GHexApplicationWindow *self)
+{
+       char *basename;
+       GFile *gfile = NULL;
+
+       TAB_VIEW_GH_FOREACH_START
+
+       /* set text of context menu tab switcher to the filename rather than
+        * 'Page X' */
+       gfile = hex_document_get_file (hex_widget_get_document (gh));
+
+       if (gfile)
+               basename = g_file_get_basename (gfile);
+       else
+               basename = g_strdup (UNTITLED_STRING);
+
+       adw_tab_page_set_title (TAB_FOR_GH (gh), basename);
+       g_free (basename);
+
+       TAB_VIEW_GH_FOREACH_END
+}
+
 static void
 file_saved_cb (HexDocument *doc,
                gpointer user_data)
@@ -690,9 +621,9 @@ file_loaded (HexDocument *doc, GHexApplicationWindow *self)
 {
        document_loaded_or_saved_common (self, doc);
        update_gui_data (self);
+       adw_tab_page_set_icon (TAB_FOR_GH (ACTIVE_GH), NULL);
 }
 
-
 static void
 document_changed_cb (HexDocument *doc,
                gpointer change_data,
@@ -702,29 +633,42 @@ document_changed_cb (HexDocument *doc,
        GHexApplicationWindow *self = GHEX_APPLICATION_WINDOW(user_data);
 
        document_loaded_or_saved_common (self, doc);
+
+       TAB_VIEW_GH_FOREACH_START
+
+       if (hex_widget_get_document (gh) == doc)
+       {
+               GIcon *icon = g_themed_icon_new ("document-modified-symbolic");
+               adw_tab_page_set_icon (TAB_FOR_GH (gh), icon);
+               g_object_unref (icon);
+       }
+
+       TAB_VIEW_GH_FOREACH_END
 }
 
-static void
-tab_close_request_cb (GHexNotebookTab *tab,
+static gboolean
+tab_view_close_page_cb (AdwTabView *tab_view,
+               AdwTabPage* page,
                gpointer user_data)
 {
        GHexApplicationWindow *self = GHEX_APPLICATION_WINDOW(user_data);
        HexDocument *doc;
        HexWidget *gh;
 
-       gh = ghex_notebook_tab_get_hex (tab);
+       gh = HEX_WIDGET(adw_tab_page_get_child (page));
        doc = hex_widget_get_document (gh);
-       g_return_if_fail (HEX_IS_DOCUMENT (doc));
 
        if (hex_document_has_changed (doc)) {
-               close_doc_confirmation_dialog (self, tab);
+               close_doc_confirmation_dialog (self, page);
        } else {
-               ghex_application_window_remove_tab (self, tab);
+               adw_tab_view_close_page_finish (tab_view, page, TRUE);
        }
+
+       return GDK_EVENT_STOP;
 }
 
 static void
-notebook_page_changed_cb (GtkNotebook *notebook,
+tab_view_page_changed_cb (AdwTabView *tab_view,
                GParamSpec *pspec,
                gpointer    user_data)
 {
@@ -739,20 +683,17 @@ notebook_page_changed_cb (GtkNotebook *notebook,
        doc = hex_widget_get_document (ACTIVE_GH);
        ghex_application_window_set_can_save (self, assess_can_save (doc));
 
-       /* Update dialogs, offset status bar, etc. */
        update_gui_data (self);
 }
 
 static void
-notebook_page_added_cb (GtkNotebook *notebook,
-               GtkWidget   *child,
-               guint        page_num,
-               gpointer     user_data)
+tab_view_page_attached_cb (AdwTabView *tab_view,
+               AdwTabPage *page,
+               int page_num,
+               gpointer user_data)
 {
        GHexApplicationWindow *self = GHEX_APPLICATION_WINDOW(user_data);
        
-       g_assert (GTK_WIDGET(notebook) == self->hex_notebook);
-
        /* Let's play this super dumb. If a page is added, that will generally
         * mean we don't have to count the pages to see if we have > 0.
         */
@@ -760,16 +701,14 @@ notebook_page_added_cb (GtkNotebook *notebook,
 }
 
 static void
-notebook_page_removed_cb (GtkNotebook *notebook,
-               GtkWidget   *child,
-               guint        page_num,
-               gpointer     user_data)
+tab_view_page_detached_cb (AdwTabView *tab_view,
+               AdwTabPage *page,
+               int page_num,
+               gpointer user_data)
 {
        GHexApplicationWindow *self = GHEX_APPLICATION_WINDOW(user_data);
 
-       g_assert (GTK_WIDGET(notebook) == self->hex_notebook);
-       
-       if (gtk_notebook_get_n_pages (notebook) == 0) {
+       if (adw_tab_view_get_n_pages (tab_view) == 0) {
                enable_main_actions (self, FALSE);
                ghex_application_window_set_show_find (self, FALSE);
                ghex_application_window_set_show_replace (self, FALSE);
@@ -779,6 +718,7 @@ notebook_page_removed_cb (GtkNotebook *notebook,
 
                show_no_file_loaded_label (self);
        }
+       update_gui_data (self);
 }
 
 static void
@@ -847,7 +787,7 @@ update_titlebar (GHexApplicationWindow *self)
                         * we hold any further references to gh doesn't seem to work
                         * reliably.
                         */
-                       gtk_notebook_get_n_pages (GTK_NOTEBOOK(self->hex_notebook)))
+                       adw_tab_view_get_n_pages (ADW_TAB_VIEW(self->hex_tab_view)))
        {
                char *basename;
                char *title;
@@ -856,10 +796,7 @@ update_titlebar (GHexApplicationWindow *self)
                if (G_IS_FILE (file = hex_document_get_file (doc)))
                        basename = g_file_get_basename (file);
                else
-                       /* Translators: this is the string for an untitled buffer that will
-                        * be displayed in the titlebar when a user does File->New
-                        */
-                       basename = g_strdup (_("Untitled"));
+                       basename = g_strdup (UNTITLED_STRING);
 
                title = g_strdup_printf ("%s - GHex", basename);
                gtk_window_set_title (GTK_WINDOW(self), title);
@@ -882,6 +819,7 @@ update_gui_data (GHexApplicationWindow *self)
 
        update_status_message (self);
        update_titlebar (self);
+       update_tabs (self);
 
        if (ACTIVE_GH)
        {
@@ -995,11 +933,11 @@ ghex_application_window_set_insert_mode (GHexApplicationWindow *self,
 {
        self->insert_mode = insert_mode;
 
-       NOTEBOOK_GH_FOREACH_START
+       TAB_VIEW_GH_FOREACH_START
 
        hex_widget_set_insert_mode (gh, insert_mode);
 
-       NOTEBOOK_GH_FOREACH_END
+       TAB_VIEW_GH_FOREACH_END
 
        g_object_notify_by_pspec (G_OBJECT(self), properties[PROP_INSERT_MODE]);
 }
@@ -1585,12 +1523,6 @@ ghex_application_window_init (GHexApplicationWindow *self)
 
        gtk_widget_init_template (widget);
 
-       /* Cache system default of prefer-dark-mode; gtk does not do this. This
-        * is run here as it cannot be done until we have a 'screen'. */
-       get_sys_default_is_dark ();
-       /* Do dark mode if requested */
-       set_dark_mode_from_settings (self);
-
        /* Setup conversions box and pane */
        self->dialog = hex_dialog_new ();
        self->dialog_widget = hex_dialog_getview (self->dialog);
@@ -1628,9 +1560,6 @@ ghex_application_window_init (GHexApplicationWindow *self)
     g_signal_connect (settings, "changed::" GHEX_PREF_GROUP,
                       G_CALLBACK (settings_group_type_changed_cb), self);
 
-    g_signal_connect_swapped (settings, "changed::" GHEX_PREF_DARK_MODE,
-                      G_CALLBACK (set_dark_mode_from_settings), self);
-
        /* Actions - SETTINGS */
 
        /* for the 'group data by' stuff. There isn't a function to do this from
@@ -1640,16 +1569,19 @@ ghex_application_window_init (GHexApplicationWindow *self)
        action = g_settings_create_action (settings, GHEX_PREF_GROUP);
        g_action_map_add_action (G_ACTION_MAP(self), action);
 
-       /* Setup notebook signals */
+       /* Setup tab view signals */
+
+       g_signal_connect (self->hex_tab_view, "notify::selected-page",
+                       G_CALLBACK(tab_view_page_changed_cb), self);
 
-       g_signal_connect (self->hex_notebook, "notify::page",
-                       G_CALLBACK(notebook_page_changed_cb), self);
+       g_signal_connect (self->hex_tab_view, "page-attached",
+                       G_CALLBACK(tab_view_page_attached_cb), self);
 
-       g_signal_connect (self->hex_notebook, "page-added",
-                       G_CALLBACK(notebook_page_added_cb), self);
+       g_signal_connect (self->hex_tab_view, "page-detached",
+                       G_CALLBACK(tab_view_page_detached_cb), self);
 
-       g_signal_connect (self->hex_notebook, "page-removed",
-                       G_CALLBACK(notebook_page_removed_cb), self);
+       g_signal_connect (self->hex_tab_view, "close-page",
+                       G_CALLBACK(tab_view_close_page_cb), self);
 
        /* Get find_dialog and friends geared up */
 
@@ -1960,7 +1892,7 @@ ghex_application_window_class_init(GHexApplicationWindowClass *klass)
                        NULL);
 
        /* In case you're looking for Ctrl+PageUp & PageDown - those are baked in
-        * via GtkNotebook */
+        * via AdwTabView */
 
        /* WIDGET TEMPLATE .UI */
 
@@ -1970,7 +1902,9 @@ ghex_application_window_class_init(GHexApplicationWindowClass *klass)
        gtk_widget_class_bind_template_child (widget_class, GHexApplicationWindow,
                        no_doc_label);
        gtk_widget_class_bind_template_child (widget_class, GHexApplicationWindow,
-                       hex_notebook);
+                       tab_view_box);
+       gtk_widget_class_bind_template_child (widget_class, GHexApplicationWindow,
+                       hex_tab_view);
        gtk_widget_class_bind_template_child (widget_class, GHexApplicationWindow,
                        conversions_box);
        gtk_widget_class_bind_template_child (widget_class, GHexApplicationWindow,
@@ -1988,7 +1922,7 @@ ghex_application_window_class_init(GHexApplicationWindowClass *klass)
 }
 
 GtkWidget *
-ghex_application_window_new (GtkApplication *app)
+ghex_application_window_new (AdwApplication *app)
 {
        return g_object_new (GHEX_TYPE_APPLICATION_WINDOW,
                        "application", app,
@@ -1999,15 +1933,13 @@ void
 ghex_application_window_activate_tab (GHexApplicationWindow *self,
                HexWidget *gh)
 {
-       GtkNotebook *notebook = GTK_NOTEBOOK(self->hex_notebook);
-       int page_num;
+       AdwTabView *tab_view = ADW_TAB_VIEW(self->hex_tab_view);
 
        g_return_if_fail (HEX_IS_WIDGET (gh));
-       g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
 
-       page_num = gtk_notebook_page_num (notebook, GTK_WIDGET(gh));
+       adw_tab_view_set_selected_page (tab_view,
+                       adw_tab_view_get_page (tab_view, GTK_WIDGET(gh)));
 
-       gtk_notebook_set_current_page (notebook, page_num);
        gtk_widget_grab_focus (GTK_WIDGET(gh));
 }
 
@@ -2033,52 +1965,15 @@ ghex_application_window_add_hex (GHexApplicationWindow *self,
        /* HexWidget: Set insert mode based on our global appwindow prop */
        hex_widget_set_insert_mode (gh, self->insert_mode);
 
-       /* Generate a tab */
-       tab = ghex_notebook_tab_new (gh);
-
-       g_signal_connect (tab, "close-request",
-                       G_CALLBACK(tab_close_request_cb), self);
-
-       gtk_notebook_append_page (GTK_NOTEBOOK(self->hex_notebook),
-                       GTK_WIDGET(gh),
-                       tab);
-
-       /* Because we ellipsize labels in ghex-notebook-tab, we need to set this
-        * property to TRUE according to TFM, otherwise all the labels will just
-        * show up as '...' */
-       g_object_set (gtk_notebook_get_page (GTK_NOTEBOOK(self->hex_notebook), GTK_WIDGET(gh)),
-                       "tab-expand", TRUE,
-                       NULL);
-
-       /* Only show the tab bar if there's more than one (1) tab. */
-       if (gtk_notebook_get_n_pages (GTK_NOTEBOOK(self->hex_notebook)) > 1)
-               gtk_notebook_set_show_tabs (GTK_NOTEBOOK(self->hex_notebook), TRUE);
-
-       /* FIXME - this seems to result in GTK_IS_BOX assertion failures.
-        * These seem harmless as everything still seems to *work*, but just
-        * documenting it here in case it becomes an issue in future.
-        */
-       gtk_notebook_set_tab_reorderable (GTK_NOTEBOOK(self->hex_notebook),
-                       GTK_WIDGET(gh),
-                       TRUE);
-
-       /* set text of context menu tab switcher to the filename rather than
-        * 'Page X' */
-       gtk_notebook_set_menu_label_text (GTK_NOTEBOOK(self->hex_notebook),
-                       GTK_WIDGET(gh),
-                       ghex_notebook_tab_get_filename (GHEX_NOTEBOOK_TAB(tab)));
+       /* Add tab */
+       adw_tab_view_append (ADW_TAB_VIEW(self->hex_tab_view), GTK_WIDGET(gh));
 
        /* Setup signals */
-    g_signal_connect (gh, "cursor-moved",
-                       G_CALLBACK(cursor_moved_cb), self);
-
-       g_signal_connect (doc, "document-changed",
-                       G_CALLBACK(document_changed_cb), self);
+    g_signal_connect (gh, "cursor-moved", G_CALLBACK(cursor_moved_cb), self);
+       g_signal_connect (doc, "document-changed", G_CALLBACK(document_changed_cb), self);
+       g_signal_connect (doc, "file-saved", G_CALLBACK(file_saved_cb), self);
 
-       g_signal_connect (doc, "file-saved",
-                       G_CALLBACK(file_saved_cb), self);
-
-       show_hex_notebook (self);
+       show_hex_tab_view (self);
 }
 
 /* Helper */
@@ -2139,6 +2034,7 @@ doc_read_ready_cb (GObject *source_object,
        GHexApplicationWindow *self = GHEX_APPLICATION_WINDOW(user_data);
        HexWidget *gh = HEX_WIDGET(extra_user_data);
        HexDocument *doc = HEX_DOCUMENT(source_object);
+       AdwTabView *tab_view = ADW_TAB_VIEW(self->hex_tab_view);
        gboolean result;
        GError *local_error = NULL;
 
@@ -2153,8 +2049,8 @@ doc_read_ready_cb (GObject *source_object,
        }
        else
        {
-               ghex_application_window_remove_tab (self,
-                               ghex_application_window_get_current_tab (self));
+               adw_tab_view_close_page (tab_view,
+                               adw_tab_view_get_selected_page (tab_view));
 
                if (local_error)
                {
@@ -2246,14 +2142,14 @@ ghex_application_window_open_file (GHexApplicationWindow *self, GFile *file)
 HexWidget *
 ghex_application_window_get_hex (GHexApplicationWindow *self)
 {
-       GHexNotebookTab *tab;
-       HexWidget *gh = NULL;
+       AdwTabPage *page;
 
        g_return_val_if_fail (GHEX_IS_APPLICATION_WINDOW (self), NULL);
 
-       tab = ghex_application_window_get_current_tab (self);
-       if (tab)
-               gh = ghex_notebook_tab_get_hex (tab);
+       page = adw_tab_view_get_selected_page (ADW_TAB_VIEW(self->hex_tab_view));
 
-       return gh;
+       if (page)
+               return HEX_WIDGET(adw_tab_page_get_child (page));
+       else
+               return NULL;
 }
diff --git a/src/ghex-application-window.h b/src/ghex-application-window.h
index ff27ee2..1fca8cc 100644
--- a/src/ghex-application-window.h
+++ b/src/ghex-application-window.h
@@ -26,11 +26,11 @@
 #define GHEX_APPLICATION_WINDOW_H
 
 #include <gtk/gtk.h>
+#include <adwaita.h>
 #include <glib/gi18n.h>
 
 #include "gtkhex.h"
 #include "configuration.h"
-#include "ghex-notebook-tab.h"
 #include "hex-statusbar.h"
 #include "hex-dialog.h"
 #include "findreplace.h"
@@ -45,9 +45,9 @@ G_BEGIN_DECLS
 #define GHEX_TYPE_APPLICATION_WINDOW (ghex_application_window_get_type ())
 G_DECLARE_FINAL_TYPE (GHexApplicationWindow, ghex_application_window,
                                GHEX, APPLICATION_WINDOW,
-                               GtkApplicationWindow)
+                               AdwApplicationWindow)
 
-GtkWidget *    ghex_application_window_new (GtkApplication *app);
+GtkWidget *    ghex_application_window_new (AdwApplication *app);
 void           ghex_application_window_add_hex (GHexApplicationWindow *self,
                                HexWidget *gh);
 void           ghex_application_window_set_hex (GHexApplicationWindow *self,
diff --git a/src/ghex-application-window.ui.in b/src/ghex-application-window.ui.in
index 6d8eef8..9b773ac 100644
--- a/src/ghex-application-window.ui.in
+++ b/src/ghex-application-window.ui.in
@@ -145,59 +145,60 @@
                </section>
        </menu>
 
-       <template class="GHexApplicationWindow" parent="GtkApplicationWindow">
+       <template class="GHexApplicationWindow" parent="AdwApplicationWindow">
                <property name="title" translatable="yes">GHex</property>
                <property name="default-width">800</property>
                <property name="default-height">600</property>
                <property name="icon-name">@app_id@</property>
 
-               <child type="titlebar">
-                       <object class="GtkHeaderBar" id="headerbar">
-                               <property name="show-title-buttons">true</property>
+               <child> <!-- main vert gtkbox -->
+                       <object class="GtkBox"> <!-- main vert gtkbox -->
+                               <property name="orientation">vertical</property>
+
 
                                <child>
-                                       <object class="GtkButton">
-                                               <property name="valign">center</property>
-                                               <property name="label">Open</property>
-                                               <property name="action-name">ghex.open</property>
-                                               <property name="tooltip-text" translatable="yes">Open a file 
for hex editing</property>
-                                       </object>
-                               </child>
+                                       <object class="GtkHeaderBar" id="headerbar">
+                                               <property name="show-title-buttons">true</property>
 
-                               <child type="end">
-                                       <object class="GtkMenuButton" id="hamburger_menu_button">
-                                               <property name="valign">center</property>
-                                               <property name="menu-model">hamburger_menu</property>
-                                               <property name="icon-name">open-menu-symbolic</property>
-                                               <accessibility>
-                                                       <property name="label" translatable="yes">Main 
menu</property>
-                                               </accessibility>
-                                       </object>
-                               </child>
+                                               <child>
+                                                       <object class="GtkButton">
+                                                               <property name="valign">center</property>
+                                                               <property name="label">Open</property>
+                                                               <property 
name="action-name">ghex.open</property>
+                                                               <property name="tooltip-text" 
translatable="yes">Open a file for hex editing</property>
+                                                       </object>
+                                               </child>
 
-                               <child type="end">
-                                       <object class="GtkToggleButton" id="find_button">
-                                               <property name="valign">center</property>
-                                               <property name="icon-name">edit-find-symbolic</property>
-                                               <property name="action-name">ghex.find</property>
-                                               <property name="tooltip-text" translatable="yes">Find a 
string in the hex document</property>
-                                       </object>
-                               </child>
+                                               <child type="end">
+                                                       <object class="GtkMenuButton" 
id="hamburger_menu_button">
+                                                               <property name="valign">center</property>
+                                                               <property 
name="menu-model">hamburger_menu</property>
+                                                               <property 
name="icon-name">open-menu-symbolic</property>
+                                                               <accessibility>
+                                                                       <property name="label" 
translatable="yes">Main menu</property>
+                                                               </accessibility>
+                                                       </object>
+                                               </child>
 
-                               <child type="end">
-                                       <object class="GtkButton">
-                                               <property name="valign">center</property>
-                                               <property name="icon-name">document-save-symbolic</property>
-                                               <property name="action-name">ghex.save</property>
-                                               <property name="tooltip-text" translatable="yes">Save 
document</property>
-                                       </object>
-                               </child>
-                       </object> <!-- headerbar -->
-               </child> <!-- titlebar -->
+                                               <child type="end">
+                                                       <object class="GtkToggleButton" id="find_button">
+                                                               <property name="valign">center</property>
+                                                               <property 
name="icon-name">edit-find-symbolic</property>
+                                                               <property 
name="action-name">ghex.find</property>
+                                                               <property name="tooltip-text" 
translatable="yes">Find a string in the hex document</property>
+                                                       </object>
+                                               </child>
 
-               <child> <!-- main vert gtkbox -->
-                       <object class="GtkBox"> <!-- main vert gtkbox -->
-                               <property name="orientation">vertical</property>
+                                               <child type="end">
+                                                       <object class="GtkButton">
+                                                               <property name="valign">center</property>
+                                                               <property 
name="icon-name">document-save-symbolic</property>
+                                                               <property 
name="action-name">ghex.save</property>
+                                                               <property name="tooltip-text" 
translatable="yes">Save document</property>
+                                                       </object>
+                                               </child>
+                                       </object> <!-- headerbar -->
+                               </child> <!-- titlebar -->
 
                                <child> <!-- child_box for notebook & content area -->
                                        <object class="GtkBox" id="child_box">
@@ -207,14 +208,18 @@
                                                <property name="hexpand">true</property>
 
                                                <child> <!-- label showing no doc loaded -->
-                                                       <object class="GtkLabel" id="no_doc_label">
-                                                               <style>
-                                                                       <class name="title" />
-                                                               </style>
-                                                               <property name="use-markup">true</property>
-                                                               <property name="label" translatable="yes">No 
file loaded.</property>
-                                                               <property name="halign">center</property>
-                                                               <property name="valign">center</property>
+                                                       <object class="AdwStatusPage" id="no_doc_label">
+                                                               <property name="title" translatable="yes">No 
File Loaded</property>
+                                                               <property name="child">
+                                                                       <object class="GtkLabel">
+                                                                               <property name="label" 
translatable="yes">• Press the Open button
+• Press Ctrl+N to start a new document
+• Press Ctrl+O to browse for a document
+
+Or, press Ctrl+W to close the window.</property>
+                                                                       </object>
+                                                               </property>
+                                                               <property 
name="icon-name">accessories-text-editor-symbolic</property>
                                                                <property name="hexpand">true</property>
                                                                <property name="vexpand">true</property>
                                                        </object>
@@ -232,18 +237,24 @@
                                                        </object>
                                                </child> <!-- /doc_loading_spinner -->
 
-                                               <child> <!-- hex_notebook - tabs for GtkHex widget -->
-                                                       <object class="GtkNotebook" id="hex_notebook">
-                                                               <property name="enable-popup">true</property>
-                                                               <property name="group-name">hex</property>
-                                                               <property name="scrollable">true</property>
-                                                               <property name="vexpand">true</property>
-                                                               <property name="hexpand">true</property>
-                                                               <property name="show-tabs">false</property>
+                                               <child>
+                                                       <object class="GtkBox" id="tab_view_box">
+                                                               <property 
name="orientation">vertical</property>
                                                                <!-- invisible by default to show the 
no_doc_label -->
                                                                <property name="visible">false</property>
-                                                       </object>       
-                                               </child> <!-- hex_notebook -->
+                                                               <child>
+                                                                       <object class="AdwTabBar">
+                                                                               <property 
name="view">hex_tab_view</property>
+                                                                       </object>
+                                                               </child>
+                                                               <child>
+                                                                       <object class="AdwTabView" 
id="hex_tab_view">
+                                                                               <property 
name="hexpand">true</property>
+                                                                               <property 
name="vexpand">true</property>
+                                                                       </object>
+                                                               </child>
+                                                       </object>
+                                               </child> <!-- tab_view_box -->
 
                                        </object> <!-- child_box -->
                                </child> <!-- child_box -->
diff --git a/src/gtkhex.c b/src/gtkhex.c
index 6ddb3b3..6913524 100644
--- a/src/gtkhex.c
+++ b/src/gtkhex.c
@@ -1618,14 +1618,20 @@ key_press_cb (GtkEventControllerKey *controller,
                        break;
 
                case GDK_KEY_Page_Up:
-                       hex_widget_set_cursor (self, MAX (0, self->cursor_pos - self->vis_lines*self->cpl));
-                       ret = GDK_EVENT_STOP;
+                       if (! (state & GDK_CONTROL_MASK))
+                       {
+                               hex_widget_set_cursor (self, MAX (0, self->cursor_pos - 
self->vis_lines*self->cpl));
+                               ret = GDK_EVENT_STOP;
+                       }
                        break;
 
                case GDK_KEY_Page_Down:
-                       hex_widget_set_cursor(self, MIN (payload_size,
-                                               self->cursor_pos + self->vis_lines*self->cpl));
-                       ret = GDK_EVENT_STOP;
+                       if (! (state & GDK_CONTROL_MASK))
+                       {
+                               hex_widget_set_cursor(self, MIN (payload_size,
+                                                       self->cursor_pos + self->vis_lines*self->cpl));
+                               ret = GDK_EVENT_STOP;
+                       }
                        break;
 
                case GDK_KEY_Home:
diff --git a/src/hex-buffer-direct.c b/src/hex-buffer-direct.c
index e5d6aff..4df521f 100644
--- a/src/hex-buffer-direct.c
+++ b/src/hex-buffer-direct.c
@@ -521,6 +521,7 @@ hex_buffer_direct_write_to_file (HexBuffer *buf,
        g_return_val_if_fail (self->fd != -1, FALSE);
        g_return_val_if_fail (G_IS_FILE (file), FALSE);
 
+       errno = 0;
        if (g_strcmp0 (self->path, g_file_peek_path (file)) != 0)
        {
                set_error (self, _("With direct-write mode, you cannot save a file "
diff --git a/src/main.c b/src/main.c
index 14750b9..ec6539c 100644
--- a/src/main.c
+++ b/src/main.c
@@ -86,7 +86,7 @@ ghex_locale_dir (void)
 }
 
 static void
-do_app_window (GtkApplication *app)
+do_app_window (AdwApplication *app)
 {
        if (! window)
                window = GTK_WINDOW(ghex_application_window_new (app));
@@ -110,7 +110,7 @@ handle_local_options (GApplication *application,
 }
 
 static void
-activate (GtkApplication *app,
+activate (AdwApplication *app,
        gpointer user_data)
 {
        /* WORKAROUND https://gitlab.gnome.org/GNOME/gtk/-/issues/4880 */
@@ -119,7 +119,7 @@ activate (GtkApplication *app,
 
        do_app_window (app);
 
-       gtk_window_set_application (window, app);
+       gtk_window_set_application (window, GTK_APPLICATION(app));
        gtk_window_present (window);
 }
 
@@ -132,7 +132,7 @@ open (GApplication *application,
 {
        GHexApplicationWindow *app_win;
 
-       activate (GTK_APPLICATION(application), NULL);
+       activate (ADW_APPLICATION(application), NULL);
        app_win = GHEX_APPLICATION_WINDOW(window);
 
        for (int i = 0; i < n_files; ++i)
@@ -142,7 +142,7 @@ open (GApplication *application,
 int
 main (int argc, char *argv[])
 {
-       GtkApplication *app;
+       AdwApplication *app;
        char *locale_dir;
        int status;
 
@@ -158,7 +158,7 @@ main (int argc, char *argv[])
 
        ghex_init_configuration ();
 
-       app = gtk_application_new (APP_ID, G_APPLICATION_HANDLES_OPEN);
+       app = adw_application_new (APP_ID, G_APPLICATION_HANDLES_OPEN);
 
        g_application_add_main_option_entries (G_APPLICATION(app), entries);
 
diff --git a/src/meson.build b/src/meson.build
index 80a37b4..4268a11 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -119,7 +119,6 @@ ghex_sources = [
   'converter.c',
   'findreplace.c',
   'ghex-application-window.c',
-  'ghex-notebook-tab.c',
   'gtkhex-paste-data.c',
   'hex-dialog.c',
   'hex-statusbar.c',
@@ -137,7 +136,8 @@ ghex = executable(
   meson.project_name(),
   ghex_sources + res,
   include_directories: ghex_root_dir,
-  dependencies: libgtkhex_dep,
+  dependencies: [adw_dep, libgtkhex_dep],
+  #  dependencies: [libgtkhex_dep, adw_dep],
   c_args: ghex_c_args,
   install: true
 )
diff --git a/src/preferences.c b/src/preferences.c
index 29f188a..7e4a4ef 100644
--- a/src/preferences.c
+++ b/src/preferences.c
@@ -373,7 +373,7 @@ setup_signals (void)
 static void
 grab_widget_values_from_settings (void)
 {
-       GtkSettings *gtk_settings;
+       AdwStyleManager *manager = adw_style_manager_get_default ();
 
        /* font_button */
        gtk_font_chooser_set_font (GTK_FONT_CHOOSER(font_button),
@@ -388,8 +388,9 @@ grab_widget_values_from_settings (void)
                                TRUE);
                gtk_widget_set_sensitive (dark_mode_switch, FALSE);
                gtk_switch_set_state (GTK_SWITCH(dark_mode_switch),
-                               sys_default_is_dark);
-       } else
+                               adw_style_manager_get_dark (manager));
+       }
+       else
        {
                gtk_check_button_set_active (GTK_CHECK_BUTTON(system_default_chkbtn),
                                FALSE);
diff --git a/src/preferences.h b/src/preferences.h
index 8510a64..aa80418 100644
--- a/src/preferences.h
+++ b/src/preferences.h
@@ -34,6 +34,7 @@
 #define GHEX_PREFERENCES_H
 
 #include <gtk/gtk.h>
+#include <adwaita.h>
 #include <glib/gi18n.h>
 #include <string.h>
 


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