Skip to content
Commits on Source (100)
=============
GHex 43.alpha
=============
This release includes libgtkhex 4.1.90 (alpha release of 4.2) - note that there
has been an ABI break with a soname versioning bump since 4.0.x. This was not
intentional, but unfortunately unavoidable.
Changes and Bugfixes since GHex 42.3 (Logan Rathbone):
- Port to libadwaita, and fix UI papercuts that stood out more thereafter
(thanks to: Alexander Mikhaylenko, Bilal Elmoussaoui and Maximiliano for their
review: #48)
* Remove custom tab widget
* Rework preferences dialog as AdwPreferencesWindow
- Introduce custom statusbar with monospace support
- HexWidget:
* Add API to show/hide specific columns
* Disallow keyboard shortcuts to activate hidden panes
* Support PRIMARY selection
- Find and Replace improvements:
* Support options for case-sensitivity, regex
* Choose visibility of hex/ascii/both in find/replace dialogs
* Show number of replacements with Replace All
- New backend: HexBufferDirect, and support for reading/writing block devices
(disabled on Flatpak)
- Load default backend plugins more intelligently
* docs: document slight change in hex_buffer_util_new behaviour when a
non-existent plugin is requested (return NULL instead of falling back to
malloc).
- chartable: ESC should close dialog
- Animate opening and closing of find/replace and conversions panes
- paste-special: Move space-delim hex pairs to UTF8 list
- build: Fix incorrect soname numbering; split resources between app and library
- docs: document expanded HexDocument and HexWidget APIs
- Error handling improvements and code cleanups
Translation updates:
UI translations:
- Anders Jonsson (sv)
- Andika Triwidada (id)
- Asier Sarasua Garmendia (eu)
- Enrico Nicoletto (pt_BR)
- Piotr Drąg (pl)
- Sergej A (ru)
- Yuri Chornoivan (uk)
- Мирослав Николић (sr)
Doc translations:
- Andika Triwidada (id)
=========
GHex 42.3
=========
......
......@@ -30,10 +30,12 @@
<kudo>UserDocs</kudo>
</kudos>
<releases>
<release version="42.3" date="2022-06-13"/>
<release version="42.2" date="2022-04-26"/>
<release version="42.1" date="2022-04-16"/>
<release version="42.0" date="2022-04-05"/>
<release version="3.41.1" date="2021-12-04"/>
<release version="3.41.0" date="2021-09-24"/>
<release version="3.18.4" date="2019-07-13"/>
<release version="3.18.3" date="2016-10-12"/>
<release version="3.18.2" date="2016-06-13"/>
</releases>
<url type="homepage">https://gitlab.gnome.org/GNOME/ghex</url>
<url type="bugtracker">https://gitlab.gnome.org/GNOME/ghex/issues</url>
......
<?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>
project(
'ghex', 'c',
version: '42.3',
version: '43.alpha',
meson_version: '>=0.59.0',
license: 'GPL2'
)
......@@ -17,6 +17,7 @@ endif
# Backend plugins: (nb: only mmap exists at this time along with malloc, which is baked in)
mmap_backend = get_option('mmap-buffer-backend')
direct_backend = get_option('direct-buffer-backend')
gir = find_program('g-ir-scanner', required : get_option('introspection'))
generate_gir = gir.found() and (not meson.is_cross_build() or get_option('introspection').enabled())
......@@ -29,9 +30,9 @@ ghex_version_major = version_arr[0].to_int()
# libgtkhex version info
libgtkhex_api_version = 4
libgtkhex_version_major = 0
libgtkhex_version_minor = 0
libgtkhex_version_micro = 0
libgtkhex_version_major = 1 # for soname (ABI major version) only
libgtkhex_version_minor = 1
libgtkhex_version_micro = 90
libgtkhex_version = '@0@.@1@.@2@'.format(libgtkhex_api_version, libgtkhex_version_minor, libgtkhex_version_micro)
ghex_prefix = get_option('prefix')
......@@ -89,11 +90,6 @@ config_h.set('LOCALEDIR', 'PACKAGE_LOCALE_DIR')
config_h.set('CONFIG_H_SHADED_BOX_MAX', shaded_box_max)
# nb: this config.h flag will likely be removed in a future release
if mmap_backend
config_h.set('BACKEND_MMAP', true)
endif
config_h.set_quoted('LIBGTKHEX_RELEASE_STRING', 'gtkhex-@0@.0'.format(libgtkhex_api_version))
config_h.set('STATIC_HTML_HELP', get_option('static-html-help'))
......@@ -130,9 +126,29 @@ if mmap_backend
message('...DONE')
endif
# direct buffer backend: Check for required headers
if direct_backend
message('Checking dependencies for `direct` buffer backend...')
check_headers_direct = [
'unistd.h',
'fcntl.h',
'sys/ioctl.h',
'linux/fs.h',
]
foreach h : check_headers_direct
cc.has_header(h, required: true)
endforeach
message('...DONE')
endif
glib_ver = '>= 2.68.0'
gmodule_dep = dependency('gmodule-2.0')
gio_dep = dependency('gio-2.0', version: '>= 2.66.0')
gtk_dep = dependency('gtk4', version: '>= 4.0.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.4.0')
adw_dep = dependency('libadwaita-1')
configure_file(
output: 'config.h',
......@@ -163,6 +179,7 @@ summary({'prefix': ghex_prefix,
summary({'Development build': get_option('development'),
'`mmap` buffer backend': mmap_backend,
'`direct` buffer backend': direct_backend,
'Static HTML help': get_option('static-html-help'),
'API Documentation': build_gtk_doc,
}, section: 'Configuration')
......@@ -3,7 +3,8 @@
option('docdir', type: 'string', value: 'share/doc', description: 'docdir (defaults to: share/doc)')
option('development', type: 'boolean', value: false, description: 'If this is a development build')
option('mmap-buffer-backend', type : 'boolean', value: true, description: 'Build mmap buffer backend')
option('mmap-buffer-backend', type : 'boolean', value: true, description: 'Build `mmap` buffer backend')
option('direct-buffer-backend', type : 'boolean', value: true, description: 'Build `direct` buffer backend')
option('introspection', type: 'feature', value: 'auto', description: 'Generate gir data (requires gobject-introspection)')
option('gtk_doc', type: 'boolean', value: false, description: 'Build reference manual (requires gtk-doc)')
option('static-html-help', type: 'boolean', value: false, description: 'Install static HTML help files (for systems without Yelp)')
......@@ -10,7 +10,6 @@
"--share=ipc",
"--socket=fallback-x11",
"--socket=wayland",
"--talk-name=org.gtk.vfs",
"--talk-name=org.gtk.vfs.*",
"--filesystem=xdg-run/gvfsd",
"--filesystem=host"
......@@ -20,7 +19,10 @@
"name": "ghex",
"builddir" : true,
"buildsystem": "meson",
"config-opts" : [ "-Ddevelopment=true" ],
"config-opts" : [
"-Ddevelopment=true",
"-Ddirect-buffer-backend=false"
],
"sources": [{
"type": "git",
"url": "https://gitlab.gnome.org/GNOME/ghex.git"
......
......@@ -4,15 +4,22 @@ data/org.gnome.GHex.appdata.xml.in.in
data/org.gnome.GHex.desktop.in.in
src/chartable.c
src/common-ui.c
src/context-menu.ui
src/converter.c
src/find-dialog.ui
src/find-options.ui
src/findreplace.c
src/ghex-application-window.c
src/ghex-notebook-tab.c
src/ghex-application-window.ui.in
src/help-overlay.ui
src/hex-buffer-direct.c
src/hex-buffer-mmap.c
src/hex-dialog.c
src/hex-document.c
src/jump-dialog.ui
src/main.c
src/paste-special.c
src/paste-special.ui
src/preferences.ui
src/print.c
src/replace-dialog.ui
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -10,7 +10,7 @@
to maintain the source code under the licensing terms described
herein and below.
Copyright © 2021 Logan Rathbone <poprocks@gmail.com>
Copyright © 2021-2022 Logan Rathbone <poprocks@gmail.com>
GHex is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
......@@ -125,30 +125,34 @@ inbtn_clicked_cb (GtkButton *button, gpointer user_data)
g_return_if_fail (GTK_IS_TREE_VIEW(treeview));
(void)button; /* unused */
model = gtk_tree_view_get_model (treeview);
insert_char (treeview, model);
}
static void
hide_chartable_cb (GtkButton *button, gpointer user_data)
static gboolean
key_press_cb (GtkEventControllerKey *key,
guint keyval,
guint keycode,
GdkModifierType state,
GtkWindow *ct)
{
GtkWindow *win = GTK_WINDOW(user_data);
(void)button; /* unused */
gtk_window_close (win);
if (keyval == GDK_KEY_Escape)
{
gtk_window_close (ct);
return GDK_EVENT_STOP;
}
return GDK_EVENT_PROPAGATE;
}
GtkWidget *create_char_table(GtkWindow *parent_win, HexWidget *gh)
GtkWidget *create_char_table (GtkWindow *parent_win, HexWidget *gh)
{
static gchar *fmt[] = { NULL, "%02X", "%03d", "%03o" };
static gchar *titles[] = { N_("ASCII"), N_("Hex"), N_("Decimal"),
N_("Octal"), N_("Binary") };
gchar *real_titles[5];
GtkWidget *ct, *sw, *ctv, *inbtn, *cbtn, *vbox, *hbox, *lbl;
GtkWidget *ct, *sw, *ctv, *inbtn, *cbtn, *vbox, *hbox, *lbl, *sep;
GtkListStore *store;
GtkCellRenderer *cell_renderer;
GtkTreeViewColumn *column;
......@@ -156,6 +160,7 @@ GtkWidget *create_char_table(GtkWindow *parent_win, HexWidget *gh)
GtkTreeSelection *selection;
int i, col;
gchar *label, ascii_printable_label[2], bin_label[9], *row[5];
GtkEventController *key;
/* set global HexWidget widget */
g_assert (HEX_IS_WIDGET(gh));
......@@ -166,6 +171,10 @@ GtkWidget *create_char_table(GtkWindow *parent_win, HexWidget *gh)
*/
ct = gtk_window_new ();
key = gtk_event_controller_key_new ();
gtk_widget_add_controller (ct, key);
g_signal_connect (key, "key-pressed", G_CALLBACK(key_press_cb), ct);
if (parent_win) {
g_assert (GTK_IS_WINDOW (parent_win));
......@@ -245,23 +254,27 @@ GtkWidget *create_char_table(GtkWindow *parent_win, HexWidget *gh)
G_CALLBACK(inbtn_clicked_cb), ctv);
cbtn = gtk_button_new_with_mnemonic (_("_Close"));
g_signal_connect(G_OBJECT (cbtn), "clicked",
G_CALLBACK(hide_chartable_cb), ct);
g_signal_connect_swapped (cbtn, "clicked", G_CALLBACK(gtk_window_close), ct);
lbl = gtk_label_new ("");
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
gtk_widget_set_name (hbox, "chartable-action-area");
sep = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
gtk_box_append (GTK_BOX(vbox), sw);
gtk_box_append (GTK_BOX(hbox), lbl);
gtk_box_append (GTK_BOX(hbox), inbtn);
gtk_box_append (GTK_BOX(hbox), cbtn);
gtk_box_append (GTK_BOX(vbox), sw);
gtk_box_append (GTK_BOX(vbox), sep);
gtk_box_append (GTK_BOX(vbox), hbox);
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW(sw), ctv);
gtk_window_set_child (GTK_WINDOW (ct), vbox);
gtk_window_set_child (GTK_WINDOW(ct), vbox);
gtk_widget_set_size_request(ct, 320, 320);
gtk_widget_set_size_request (ct, 320, 320);
return ct;
}
......@@ -182,7 +182,7 @@ set_css_provider_font_from_settings (void)
desc = pango_font_description_from_string (def_font_name);
css_str = pango_font_description_to_css (desc, ".hex");
gtk_css_provider_load_from_data (provider,
gtk_css_provider_load_from_data (global_provider,
css_str, -1);
g_free (css_str);
}
......@@ -191,13 +191,13 @@ void
common_set_gtkhex_font_from_settings (HexWidget *gh)
{
g_return_if_fail (HEX_IS_WIDGET(gh));
g_return_if_fail (GTK_IS_STYLE_PROVIDER(provider));
g_return_if_fail (GTK_IS_STYLE_PROVIDER(global_provider));
/* Ensure global provider and settings are in sync font-wise. */
set_css_provider_font_from_settings ();
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER (global_provider),
GTK_STYLE_PROVIDER_PRIORITY_SETTINGS);
}
......
......@@ -36,7 +36,7 @@
GSettings *settings;
/* Global CSS provider for our HexWidget widgets */
GtkCssProvider *provider;
GtkCssProvider *global_provider;
int def_group_type;
char *def_font_name;
......@@ -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
......@@ -296,5 +173,5 @@ void ghex_init_configuration ()
/* Global CSS provider */
provider = gtk_css_provider_new ();
global_provider = gtk_css_provider_new ();
}
......@@ -34,6 +34,7 @@
#define GHEX_CONFIGURATION_H
#include <gtk/gtk.h>
#include <adwaita.h>
G_BEGIN_DECLS
......@@ -62,18 +63,13 @@ 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;
extern GtkCssProvider *global_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 */
......@@ -197,6 +197,7 @@ GtkWidget *create_converter (GtkWindow *parent_win, /* can-NULL */
G_CALLBACK(close_converter), conv->window);
grid = gtk_grid_new ();
gtk_widget_set_name (grid, "converter-grid");
gtk_grid_set_row_spacing (GTK_GRID (grid), 4);
gtk_grid_set_column_spacing (GTK_GRID (grid), 4);
gtk_box_append (GTK_BOX(gtk_dialog_get_content_area (GTK_DIALOG(conv->window))),
......
<?xml version="1.0" encoding="UTF-8"?>
<!-- vim: ts=2 sw=2
-->
<!--
Copyright © 2022 Logan Rathbone <poprocks@gmail.com>
GHex 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 2 of the
License, or (at your option) any later version.
GHex 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 GHex; see the file COPYING.
If not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Original GHex Author: Jaka Mocnik <jaka@gnu.org>
-->
<interface domain="gtk40">
<template class="FindDialog" parent="PaneDialog">
<child><object class="GtkBox" id="vbox">
<property name="orientation">vertical</property>
<child><object class="GtkBox" id="find_frame">
<property name="orientation">vertical</property>
<style>
<class name="findreplace-frame" />
</style>
<accessibility>
<property name="description" translatable="yes">Enter the hex data or ASCII data to search for</property>
</accessibility>
<child><object class="GtkLabel" id="find_string_label">
<property name="label" translatable="yes">Find String</property>
<property name="use-markup">true</property>
<property name="halign">start</property>
<property name="hexpand">true</property>
<property name="visible">false</property>
<style>
<class name="findreplace-label" />
</style>
</object></child>
</object></child>
<child><object class="GtkBox" id="hbox">
<property name="name">findreplace-buttonbox</property>
<property name="orientation">horizontal</property>
<property name="spacing">6</property>
<child><object class="GtkButton" id="f_next">
<property name="label" translatable="yes">Find _Next</property>
<property name="use-underline">true</property>
<property name="receives-default">true</property>
<accessibility>
<property name="description" translatable="yes">Finds the next occurrence of the search string</property>
</accessibility>
</object></child>
<child><object class="GtkButton" id="f_prev">
<property name="label" translatable="yes">Find _Previous</property>
<property name="use-underline">true</property>
<accessibility>
<property name="description" translatable="yes">Finds the previous occurrence of the search string</property>
</accessibility>
</object></child>
<child><object class="GtkButton" id="f_clear">
<property name="label" translatable="yes">_Clear</property>
<property name="use-underline">true</property>
<accessibility>
<property name="description" translatable="yes">Clears the data you are searching for</property>
</accessibility>
</object></child>
<child><object class="GtkMenuButton" id="options_btn">
<property name="hexpand">true</property>
<property name="halign">end</property>
<property name="icon-name">emblem-system-symbolic</property>
<property name="has-frame">false</property>
<accessibility>
<property name="label" translatable="yes">Find options</property>
<property name="description" translatable="yes">View options of the find pane</property>
</accessibility>
</object></child>
<child><object class="GtkButton" id="close">
<property name="icon-name">window-close-symbolic</property>
<property name="has-frame">false</property>
<property name="hexpand">false</property>
<property name="halign">end</property>
<accessibility>
<property name="label" translatable="yes">Close</property>
<property name="description" translatable="yes">Closes the find pane</property>
</accessibility>
</object></child>
</object></child> <!-- hbox -->
</object></child> <!-- vbox -->
</template> <!-- FindDialog -->
</interface>
<?xml version="1.0" encoding="UTF-8"?>
<!-- vim: ts=2 sw=2
-->
<!--
Copyright © 2022 Logan Rathbone <poprocks@gmail.com>
GHex 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 2 of the
License, or (at your option) any later version.
GHex 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 GHex; see the file COPYING.
If not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Original GHex Author: Jaka Mocnik <jaka@gnu.org>
-->
<interface>
<object class="GtkPopover" id="find_options_popover">
<child>
<object class="GtkGrid" id="find_options_grid">
<property name="column-spacing">6</property>
<property name="row-spacing">6</property>
<child><object class="GtkCheckButton" id="find_options_regex">
<property name="use-underline">true</property>
<property name="label">_Regular expressions</property>
<layout>
<property name="column">0</property>
<property name="row">0</property>
</layout>
</object></child>
<child><object class="GtkCheckButton" id="find_options_ignore_case">
<property name="use-underline">true</property>
<property name="label">_Ignore case</property>
<layout>
<property name="column">1</property>
<property name="row">0</property>
</layout>
</object></child>
<child><object class="GtkBox">
<property name="orientation">horizontal</property>
<property name="spacing">6</property>
<layout>
<property name="column">0</property>
<property name="row">1</property>
</layout>
<child><object class="GtkLabel">
<property name="label" translatable="yes">Show:</property>
</object></child>
<child><object class="GtkComboBoxText" id="find_options_show_pane">
<property name="hexpand">true</property>
<items>
<item translatable="yes" id="hex">Hex</item>
<item translatable="yes" id="ascii">ASCII</item>
<item translatable="yes" id="both">Both</item>
</items>
<property name="active">2</property>
</object></child>
</object></child> <!-- hbox -->
</object> <!-- grid -->
</child>
</object> <!-- popover -->
</interface>