├── .editorconfig ├── .gitignore ├── .gitlab-ci.yml ├── .gitlab-ci └── ci-32-cross ├── COPYING ├── NEWS ├── README.md ├── build-aux └── flatpak │ └── org.gnome.Console.Devel.json ├── console.doap ├── data ├── meson.build ├── org.gnome.Console-symbolic.svg ├── org.gnome.Console.Devel.svg ├── org.gnome.Console.Source.svg ├── org.gnome.Console.desktop.in.in ├── org.gnome.Console.gschema.xml.in ├── org.gnome.Console.metainfo.xml.in.in ├── org.gnome.Console.service.in ├── org.gnome.Console.svg └── screenshots │ └── 01-Terminal.png ├── gcovr.cfg ├── logo.png ├── meson.build ├── meson.format ├── meson.options ├── po ├── LINGUAS ├── POTFILES.in ├── ab.po ├── ar.po ├── az.po ├── be.po ├── bg.po ├── ca.po ├── cs.po ├── da.po ├── de.po ├── el.po ├── en_GB.po ├── eo.po ├── es.po ├── eu.po ├── fa.po ├── fi.po ├── fr.po ├── fur.po ├── gl.po ├── he.po ├── hi.po ├── hr.po ├── hu.po ├── id.po ├── ie.po ├── it.po ├── ja.po ├── ka.po ├── kab.po ├── kk.po ├── ko.po ├── lt.po ├── lv.po ├── meson.build ├── nb.po ├── ne.po ├── nl.po ├── oc.po ├── pa.po ├── pl.po ├── pt.po ├── pt_BR.po ├── ro.po ├── ru.po ├── sk.po ├── sl.po ├── sr.po ├── sr@latin.po ├── sv.po ├── th.po ├── tr.po ├── uk.po ├── uz.po ├── vi.po ├── zh_CN.po └── zh_TW.po ├── src ├── help-overlay.ui ├── icons │ └── scalable │ │ └── status │ │ ├── bell-outline-symbolic.svg │ │ ├── emblem-ok-symbolic.svg │ │ ├── external-link-symbolic.svg │ │ ├── status-privileged-symbolic.svg │ │ ├── status-regular-symbolic.svg │ │ ├── status-remote-symbolic.svg │ │ └── theme-check-symbolic.svg ├── kgx-about.c ├── kgx-about.h ├── kgx-application.c ├── kgx-application.h ├── kgx-close-dialog.c ├── kgx-close-dialog.h ├── kgx-colour-utils.c ├── kgx-colour-utils.h ├── kgx-depot.c ├── kgx-depot.h ├── kgx-despatcher.c ├── kgx-despatcher.h ├── kgx-drop-target.c ├── kgx-drop-target.h ├── kgx-empty.c ├── kgx-empty.h ├── kgx-empty.ui ├── kgx-file-closures.h ├── kgx-git-tag.h.in ├── kgx-icon-closures.h ├── kgx-livery-manager.c ├── kgx-livery-manager.h ├── kgx-livery.c ├── kgx-livery.h ├── kgx-locale.h ├── kgx-marshals.list ├── kgx-page-expression.ui ├── kgx-pages.c ├── kgx-pages.h ├── kgx-pages.ui ├── kgx-palette.c ├── kgx-palette.h ├── kgx-paste-dialog.c ├── kgx-paste-dialog.h ├── kgx-process.c ├── kgx-process.h ├── kgx-proxy-info.c ├── kgx-proxy-info.h ├── kgx-settings.c ├── kgx-settings.h ├── kgx-shared-closures.h ├── kgx-simple-tab.c ├── kgx-simple-tab.h ├── kgx-simple-tab.ui ├── kgx-spad-source.c ├── kgx-spad-source.h ├── kgx-spad.c ├── kgx-spad.h ├── kgx-spad.ui ├── kgx-system-info.c ├── kgx-system-info.h ├── kgx-tab.c ├── kgx-tab.h ├── kgx-tab.ui ├── kgx-terminal.c ├── kgx-terminal.h ├── kgx-terminal.ui ├── kgx-theme-switcher.c ├── kgx-theme-switcher.h ├── kgx-theme-switcher.ui ├── kgx-train.c ├── kgx-train.h ├── kgx-utils.c ├── kgx-utils.h ├── kgx-watcher.c ├── kgx-watcher.h ├── kgx-window.c ├── kgx-window.h ├── kgx-window.ui ├── kgx.gresource.xml.in ├── logo.txt ├── main.c ├── meson.build ├── org.freedesktop.FileManager1.xml ├── pids │ ├── kgx-gtop.c │ ├── kgx-gtop.h │ ├── kgx-pids.c │ ├── kgx-pids.h │ └── meson.build ├── preferences │ ├── kgx-font-picker.c │ ├── kgx-font-picker.h │ ├── kgx-font-picker.ui │ ├── kgx-preferences-window.c │ ├── kgx-preferences-window.h │ └── kgx-preferences-window.ui ├── rgba.h ├── style-dark.css └── style.css ├── subprojects ├── adwaita.wrap ├── glib.wrap ├── gtk.wrap ├── pango.wrap └── vte.wrap └── tests ├── meson.build ├── test-colour-utils.c ├── test-empty.c ├── test-file-closures.c ├── test-icon-closures.c ├── test-livery.c ├── test-locale.c ├── test-palette.c ├── test-settings.c ├── test-shared-closures.c ├── test-spad-source.c ├── test-spad.c ├── test-tab.c ├── test-theme-switcher.c └── test-utils.c /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*.{c,h}] 4 | indent_size = 2 5 | indent_style = space 6 | trim_trailing_whitespace = true 7 | insert_final_newline = true 8 | 9 | [meson.{build,options,format}] 10 | indent_style = space 11 | trim_trailing_whitespace = true 12 | insert_final_newline = true 13 | indent_size = 2 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .buildconfig 2 | *~ 3 | build 4 | .vscode 5 | /subprojects/vte 6 | /subprojects/adwaita 7 | -------------------------------------------------------------------------------- /.gitlab-ci/ci-32-cross: -------------------------------------------------------------------------------- 1 | [binaries] 2 | c = ['/usr/bin/clang', '-target', 'i686-redhat-linux-gnu'] 3 | cpp = ['/usr/bin/clang++', '-target', 'i686-redhat-linux-gnu'] 4 | ar = '/usr/bin/llvm-ar' 5 | strip = '/usr/bin/strip' 6 | pkg-config = '/usr/bin/i686-redhat-linux-gnu-pkg-config' 7 | 8 | [built-in options] 9 | prefix = '/usr' 10 | libdir = 'lib' 11 | bindir = 'bin' 12 | 13 | [host_machine] 14 | system = 'linux' 15 | cpu_family = 'x86' 16 | cpu = 'i686' 17 | endian = 'little' 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Console / KGX 2 | 3 | ![](logo.png) 4 | 5 | Console aims to be a simple terminal emulator for the average user to carry out casual cli tasks. 6 | 7 | We are not however trying to replace GNOME Terminal/Tilix, these advanced tools are great for developers and administrators, rather Console aims to serve the casual linux user who rarely needs a terminal 8 | 9 | ## Use of Generative AI 10 | 11 | *[Adopted from Loupe](https://gitlab.gnome.org/GNOME/loupe)* 12 | 13 | This project does not allow contributions generated by large languages models (LLMs) and chatbots. This ban includes tools like ChatGPT, Claude, Copilot, DeepSeek, and Devin AI. We are taking these steps as precaution due to the potential negative influence of AI generated content on quality, as well as likely copyright violations. 14 | 15 | This ban of AI generated content applies to all parts of the projects, including, but not limited to, code, documentation, issues, and artworks. An exception applies for purely translating texts for issues and comments to English. 16 | 17 | AI tools can be used to answer questions and find information. However, we encourage contributors to avoid them in favor of using [existing documentation](https://developer.gnome.org) and our [chats and forums](https://welcome.gnome.org). Since AI generated information is frequently misleading or false, we cannot supply support on anything referencing AI output. 18 | -------------------------------------------------------------------------------- /build-aux/flatpak/org.gnome.Console.Devel.json: -------------------------------------------------------------------------------- 1 | { 2 | "app-id": "org.gnome.Console.Devel", 3 | "runtime": "org.gnome.Platform", 4 | "runtime-version": "master", 5 | "sdk": "org.gnome.Sdk", 6 | "command": "kgx-devel", 7 | "tags": [ 8 | "devel", 9 | "development", 10 | "nightly" 11 | ], 12 | "finish-args": [ 13 | "--device=dri", 14 | "--share=ipc", 15 | "--socket=fallback-x11", 16 | "--socket=wayland", 17 | "--talk-name=org.gtk.vfs.*", 18 | "--filesystem=xdg-run/gvfsd" 19 | ], 20 | "cleanup": [ 21 | "/include", 22 | "/lib/pkgconfig", 23 | "/man", 24 | "/share/doc", 25 | "/share/gtk-doc", 26 | "/share/man", 27 | "/share/pkgconfig", 28 | "*.la", 29 | "*.a" 30 | ], 31 | "modules": [ 32 | { 33 | "name": "fast_float", 34 | "buildsystem": "cmake-ninja", 35 | "sources": [ 36 | { 37 | "type": "git", 38 | "url": "https://github.com/fastfloat/fast_float.git", 39 | "tag": "v6.1.6" 40 | } 41 | ] 42 | }, 43 | { 44 | "name": "simdutf", 45 | "buildsystem": "cmake-ninja", 46 | "config-opts": [ 47 | "-DCMAKE_POSITION_INDEPENDENT_CODE=TRUE", 48 | "-DCMAKE_CXX_VISIBILITY_PRESET=hidden", 49 | "-DCMAKE_VISIBILITY_INLINES_HIDDEN=TRUE" 50 | ], 51 | "sources": [ 52 | { 53 | "type": "git", 54 | "url": "https://github.com/simdutf/simdutf", 55 | "tag": "v6.4.0" 56 | } 57 | ] 58 | }, 59 | { 60 | "name": "vte", 61 | "config-opts": [ 62 | "-Dgir=false", 63 | "-Dvapi=false", 64 | "-Dgtk3=false", 65 | "-Dgtk4=true" 66 | ], 67 | "buildsystem": "meson", 68 | "sources": [ 69 | { 70 | "type": "git", 71 | "url": "https://gitlab.gnome.org/GNOME/vte.git" 72 | } 73 | ] 74 | }, 75 | { 76 | "name": "libgtop", 77 | "buildsystem": "autotools", 78 | "sources": [ 79 | { 80 | "type": "git", 81 | "url": "https://gitlab.gnome.org/GNOME/libgtop.git" 82 | } 83 | ] 84 | }, 85 | { 86 | "name": "gnome-console", 87 | "run-tests": true, 88 | "builddir": true, 89 | "buildsystem": "meson", 90 | "build-options": { 91 | "test-args": [ 92 | "--device=dri", 93 | "--share=ipc", 94 | "--socket=fallback-x11", 95 | "--socket=wayland", 96 | "--talk-name=org.gtk.vfs.*", 97 | "--filesystem=xdg-run/gvfsd" 98 | ] 99 | }, 100 | "config-opts": [ 101 | "-Ddevel=true" 102 | ], 103 | "sources": [ 104 | { 105 | "type": "dir", 106 | "path": "../../" 107 | } 108 | ] 109 | } 110 | ] 111 | } -------------------------------------------------------------------------------- /console.doap: -------------------------------------------------------------------------------- 1 | 4 | Console 5 | Terminal Emulator 6 | 7 | 8 | 9 | C 10 | GTK 4 11 | Libadwaita 12 | 13 | A simple user-friendly terminal emulator for the GNOME desktop. 14 | 15 | 16 | 17 | Zander Brown 18 | 19 | zbrown 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /data/meson.build: -------------------------------------------------------------------------------- 1 | desktop_utils = find_program( 2 | 'desktop-file-validate', 3 | required: get_option('tests'), 4 | ) 5 | appstreamcli = find_program('appstreamcli', required: get_option('tests')) 6 | compile_schemas = find_program('glib-compile-schemas') 7 | 8 | desktop_filename = 'org.gnome.Console.desktop.in.in' 9 | if get_option('devel') 10 | icon_filename = 'org.gnome.Console.Devel.svg' 11 | else 12 | icon_filename = 'org.gnome.Console.svg' 13 | endif 14 | 15 | desktop_file = i18n.merge_file( 16 | input: configure_file( 17 | input: desktop_filename, 18 | output: '@BASENAME@', 19 | configuration: conf 20 | ), 21 | output: app_id + '.desktop', 22 | type: 'desktop', 23 | po_dir: '../po', 24 | install: true, 25 | install_dir: datadir / 'applications' 26 | ) 27 | 28 | if get_option('tests') 29 | test('Validate desktop file', desktop_utils, args: [desktop_file]) 30 | endif 31 | 32 | appstream_file = i18n.merge_file( 33 | input: configure_file( 34 | input: 'org.gnome.Console.metainfo.xml.in.in', 35 | output: '@BASENAME@', 36 | configuration: conf 37 | ), 38 | output: app_id + '.metainfo.xml', 39 | po_dir: '../po', 40 | install: true, 41 | install_dir: datadir / 'metainfo' 42 | ) 43 | 44 | if get_option('tests') 45 | test( 46 | 'Validate appstream file', 47 | appstreamcli, 48 | args: ['validate', '--no-net', '--explain', appstream_file], 49 | ) 50 | endif 51 | 52 | schema_file = configure_file( 53 | input: 'org.gnome.Console.gschema.xml.in', 54 | output: app_id + '.gschema.xml', 55 | configuration: conf, 56 | install_dir: datadir / 'glib-2.0/schemas' 57 | ) 58 | 59 | # gnome.compile_schemas only looks at the source tree 60 | kgx_schemas = custom_target('kgx-schemas', 61 | input: schema_file, 62 | output: 'gschemas.compiled', 63 | command: [compile_schemas, meson.current_build_dir()], 64 | ) 65 | meson.add_devenv({'GSETTINGS_SCHEMA_DIR': meson.current_build_dir()}) 66 | 67 | if get_option('tests') 68 | test( 69 | 'Validate schema file', 70 | compile_schemas, 71 | args: ['--strict', '--dry-run', meson.current_build_dir()], 72 | ) 73 | endif 74 | 75 | configure_file( 76 | input: 'org.gnome.Console.service.in', 77 | output: app_id + '.service', 78 | configuration: conf, 79 | install_dir: datadir / 'dbus-1/services' 80 | ) 81 | 82 | install_data(icon_filename, 83 | install_dir: datadir / 'icons/hicolor/scalable/apps', 84 | rename: app_id + '.svg', 85 | ) 86 | 87 | install_data('org.gnome.Console-symbolic.svg', 88 | install_dir: datadir / 'icons/hicolor/symbolic/apps', 89 | rename: app_id + '-symbolic.svg', 90 | ) 91 | -------------------------------------------------------------------------------- /data/org.gnome.Console-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /data/org.gnome.Console.Devel.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /data/org.gnome.Console.desktop.in.in: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=Console 3 | Exec=@BIN_NAME@ 4 | # Translators: Do NOT translate or transliterate this text (this is an icon file name)! 5 | Icon=@KGX_APPLICATION_ID_RAW@ 6 | # Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! 7 | Keywords=command;prompt;cmd;commandline;run;shell;terminal;kgx;kings cross; 8 | Terminal=false 9 | Type=Application 10 | Categories=System;TerminalEmulator;Utility;GTK;GNOME; 11 | StartupNotify=true 12 | DBusActivatable=true 13 | X-GNOME-UsesNotifications=true 14 | Actions=new-window;new-tab; 15 | # Translators: Do NOT translate or transliterate this text (these are enum types)! 16 | X-Purism-FormFactor=Workstation;Mobile; 17 | 18 | [Desktop Action new-window] 19 | Exec=@BIN_NAME@ 20 | Name=New Window 21 | # Translators: Do NOT translate or transliterate this text (this is an icon file name)! 22 | Icon=window-new 23 | 24 | [Desktop Action new-tab] 25 | Exec=@BIN_NAME@ --tab 26 | Name=New Tab 27 | # Translators: Do NOT translate or transliterate this text (this is an icon file name)! 28 | Icon=tab-new 29 | -------------------------------------------------------------------------------- /data/org.gnome.Console.gschema.xml.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 'night' 14 | 15 | 16 | 17 | 1.0 18 | 19 | 20 | "" 21 | 22 | 23 | true 24 | 25 | 26 | [] 27 | 28 | 29 | false 30 | 31 | 32 | 10000 33 | 34 | 35 | (-1, -1) 36 | 37 | 38 | false 39 | 40 | 41 | true 42 | 43 | 44 | true 45 | 46 | 47 | true 48 | 49 | 50 | false 51 | 52 | 53 | false 54 | 55 | 56 | @KGX_LIVERY_UUID_KGX@ 57 | 58 | 59 | {} 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /data/org.gnome.Console.service.in: -------------------------------------------------------------------------------- 1 | [D-BUS Service] 2 | Name=@KGX_APPLICATION_ID_RAW@ 3 | Exec=@BIN_DIR@/@BIN_NAME@ --gapplication-service 4 | -------------------------------------------------------------------------------- /data/org.gnome.Console.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /data/screenshots/01-Terminal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GNOME/console/ea383188b90cbe5402bf7da528f16052f6f64f8b/data/screenshots/01-Terminal.png -------------------------------------------------------------------------------- /gcovr.cfg: -------------------------------------------------------------------------------- 1 | exclude-lines-by-pattern = (\W*)g_return_(.*) 2 | exclude-lines-by-pattern = (\W*)KGX_INVALID_PROP(.*) 3 | exclude = build/* 4 | exclude = subprojects/ -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GNOME/console/ea383188b90cbe5402bf7da528f16052f6f64f8b/logo.png -------------------------------------------------------------------------------- /meson.build: -------------------------------------------------------------------------------- 1 | project( 2 | 'gnome-console', 3 | 'c', 4 | version: '49.alpha', 5 | meson_version: '>= 1.5.0', 6 | license: 'GPL-3.0-or-later', 7 | license_files: ['COPYING'], 8 | default_options: [ 9 | 'buildtype=debugoptimized', 10 | 'c_std=c17', 11 | 'adwaita:examples=false', 12 | 'adwaita:introspection=disabled', 13 | 'adwaita:tests=false', 14 | 'adwaita:vapi=false', 15 | 'gtk:build-examples=false', 16 | 'gtk:build-tests=false', 17 | 'gtk:build-testsuite=false', 18 | 'gtk:build-demos=false', 19 | 'gtk:introspection=disabled', 20 | 'libsass:werror=false', 21 | 'vte:c_std=gnu11', 22 | 'vte:cpp_std=gnu++17', 23 | 'vte:gir=false', 24 | 'vte:gtk3=false', 25 | 'vte:gtk4=true', 26 | 'vte:vapi=false', 27 | 'vte:werror=false', 28 | ], 29 | ) 30 | 31 | i18n = import('i18n') 32 | gnome = import('gnome') 33 | 34 | 35 | if get_option('devel') 36 | app_id = 'org.gnome.Console.Devel' 37 | app_path = '/org/gnome/Console/Devel/' 38 | bin_name = 'kgx-devel' 39 | log_domain = 'KgxDevel' 40 | else 41 | app_id = 'org.gnome.Console' 42 | app_path = '/org/gnome/Console/' 43 | bin_name = 'kgx' 44 | log_domain = 'Kgx' 45 | endif 46 | 47 | kgx_homepage_url = 'https://apps.gnome.org/Console/' 48 | kgx_issue_url = 'https://gitlab.gnome.org/GNOME/console/-/issues/' 49 | copyright_range = '2019-2025' 50 | vcs_tag_fallback = 'no-tag' 51 | 52 | prefix = get_option('prefix') 53 | bindir = prefix / get_option('bindir') 54 | libdir = prefix / get_option('libdir') 55 | datadir = prefix / get_option('datadir') 56 | pkglibdir = prefix / libdir / bin_name 57 | pkgdatadir = datadir / bin_name 58 | 59 | conf = configuration_data() 60 | conf.set_quoted('PACKAGE_VERSION', meson.project_version()) 61 | conf.set_quoted('GETTEXT_PACKAGE', bin_name) 62 | conf.set_quoted('KGX_APPLICATION_ID', app_id) 63 | conf.set('KGX_APPLICATION_ID_RAW', app_id) 64 | conf.set_quoted('KGX_APPLICATION_PATH', app_path) 65 | conf.set('KGX_APPLICATION_PATH_RAW', app_path) 66 | conf.set_quoted('KGX_LIVERY_UUID_KGX', '9f1374fd-f199-429f-bae6-9cf1260f6e3e') 67 | conf.set_quoted('KGX_LIVERY_UUID_LINUX', '131b4aac-399b-4ee4-a8e1-f22e5c3c7bdd') 68 | conf.set_quoted('KGX_LIVERY_UUID_XTERM', '54156855-4a0d-454a-9d5a-7d3e2c9f26f5') 69 | conf.set_quoted('LOCALEDIR', prefix / get_option('localedir')) 70 | conf.set('BIN_DIR', prefix / bindir) 71 | conf.set('BIN_NAME', bin_name) 72 | conf.set_quoted('KGX_BIN_NAME', bin_name) 73 | conf.set_quoted('KGX_ISSUE_URL', kgx_issue_url) 74 | conf.set('KGX_ISSUE_URL_RAW', kgx_issue_url) 75 | conf.set_quoted('KGX_HOMEPAGE_URL', kgx_homepage_url) 76 | conf.set('KGX_HOMEPAGE_URL_RAW', kgx_homepage_url) 77 | conf.set_quoted('KGX_COPYRIGHT_RANGE', copyright_range) 78 | conf.set('KGX_COPYRIGHT_RANGE_RAW', copyright_range) 79 | conf.set_quoted('KGX_GIT_TAG_FALLBACK', vcs_tag_fallback) 80 | conf.set('IS_DEVEL', get_option('devel')) 81 | 82 | if get_option('tests') 83 | conf.set_quoted('TRUE_BIN_PATH', find_program('true').full_path()) 84 | endif 85 | 86 | # Gtk Requirement 87 | gtk_min_ver = '4.19' 88 | gtk_min_ver_parts = gtk_min_ver.split('.') 89 | if gtk_min_ver_parts[1].to_int().is_odd() 90 | gtk_sym_ver = 'GDK_VERSION_@0@_@1@'.format( 91 | gtk_min_ver_parts[0], 92 | gtk_min_ver_parts[1].to_int() + 1, 93 | ) 94 | else 95 | gtk_sym_ver = 'GDK_VERSION_@0@@_@_@1@'.format( 96 | gtk_min_ver_parts[0], 97 | gtk_min_ver_parts[1], 98 | ) 99 | endif 100 | 101 | # GLib Requirement 102 | glib_min_ver = '2.80' 103 | glib_sym_ver = 'GLIB_VERSION_@0@'.format(glib_min_ver.replace('.', '_')) 104 | 105 | # Adwaita Requirement 106 | adw_min_ver = '1.7' 107 | adw_sym_ver = 'ADW_VERSION_@0@'.format(adw_min_ver.replace('.', '_')) 108 | 109 | kgx_cargs = [ 110 | '-DG_LOG_DOMAIN="@0@"'.format(log_domain), 111 | '-DG_LOG_USE_STRUCTURED', 112 | '-DGLIB_VERSION_MIN_REQUIRED=@0@'.format(glib_sym_ver), 113 | '-DGLIB_VERSION_MAX_ALLOWED=@0@'.format(glib_sym_ver), 114 | '-DGDK_VERSION_MIN_REQUIRED=@0@'.format(gtk_sym_ver), 115 | '-DGDK_VERSION_MAX_ALLOWED=@0@'.format(gtk_sym_ver), 116 | '-DADW_VERSION_MIN_REQUIRED=@0@'.format(adw_sym_ver), 117 | '-DADW_VERSION_MAX_ALLOWED=@0@'.format(adw_sym_ver), 118 | ] 119 | 120 | cc = meson.get_compiler('c') 121 | 122 | foreach arg : [ 123 | '-Wdeclaration-after-statement', 124 | ['-Werror=format-security', '-Werror=format=2'], 125 | '-Werror=missing-declarations', 126 | '-Wformat-nonliteral', 127 | '-Wformat-security', 128 | '-Werror=format', 129 | '-Winit-self', 130 | '-Wmaybe-uninitialized', 131 | '-Wno-strict-aliasing', 132 | '-Wno-unused-parameter', 133 | '-Wold-style-definition', 134 | '-Wshadow', 135 | '-Wstrict-prototypes', 136 | '-Wswitch-default', 137 | '-Wswitch-enum', 138 | '-Wunused-function', 139 | ] 140 | if cc.has_multi_arguments(arg) 141 | kgx_cargs += arg 142 | endif 143 | endforeach 144 | 145 | global_cargs = [] 146 | 147 | if get_option('buildtype') != 'plain' 148 | foreach arg : [ 149 | '-fstack-protector-strong', 150 | '-fno-omit-frame-pointer', 151 | '-mno-omit-leaf-frame-pointer', 152 | '-fasynchronous-unwind-tables', 153 | ] 154 | if cc.has_multi_arguments(arg) 155 | global_cargs += arg 156 | endif 157 | endforeach 158 | endif 159 | 160 | add_global_arguments(global_cargs, language: 'c') 161 | 162 | gio_dep = dependency('gio-2.0', version: '>= @0@'.format(glib_min_ver)) 163 | gio_unix_dep = dependency('gio-unix-2.0', version: '>= @0@'.format(glib_min_ver)) 164 | adw_dep = dependency('libadwaita-1', version: '>= @0@'.format(adw_min_ver)) 165 | vte_dep = dependency('vte-2.91-gtk4', version: '>= 0.77.0') 166 | gtk_dep = dependency('gtk4', version: '>= @0@'.format(gtk_min_ver)) 167 | pango_dep = dependency('pango', version: '>= 1.51.2') 168 | gtop_dep = dependency('libgtop-2.0') 169 | pcre_dep = dependency('libpcre2-8', version: '>= 10.32') 170 | schemas_dep = dependency('gsettings-desktop-schemas') 171 | 172 | subdir('data') 173 | subdir('src') 174 | subdir('po') 175 | if get_option('tests') 176 | subdir('tests') 177 | endif 178 | 179 | gnome.post_install( 180 | glib_compile_schemas: true, 181 | gtk_update_icon_cache: true, 182 | update_desktop_database: true, 183 | ) 184 | -------------------------------------------------------------------------------- /meson.format: -------------------------------------------------------------------------------- 1 | sort_files = True 2 | use_editor_config = True 3 | -------------------------------------------------------------------------------- /meson.options: -------------------------------------------------------------------------------- 1 | option( 2 | 'devel', 3 | type: 'boolean', 4 | value: false, 5 | description: 'Produce a parallel installable development build', 6 | ) 7 | 8 | option('tests', type: 'boolean', value: true, description: 'Enable tests') 9 | -------------------------------------------------------------------------------- /po/LINGUAS: -------------------------------------------------------------------------------- 1 | ab 2 | ar 3 | az 4 | be 5 | bg 6 | ca 7 | cs 8 | da 9 | de 10 | el 11 | en_GB 12 | eo 13 | es 14 | eu 15 | fa 16 | fi 17 | fr 18 | fur 19 | gl 20 | he 21 | hi 22 | hr 23 | hu 24 | id 25 | ie 26 | it 27 | ja 28 | ka 29 | kab 30 | kk 31 | ko 32 | lt 33 | lv 34 | nb 35 | ne 36 | nl 37 | oc 38 | pa 39 | pl 40 | pt 41 | pt_BR 42 | ro 43 | ru 44 | sk 45 | sl 46 | sr 47 | sr@latin 48 | sv 49 | th 50 | tr 51 | uk 52 | uz 53 | vi 54 | zh_CN 55 | zh_TW 56 | -------------------------------------------------------------------------------- /po/POTFILES.in: -------------------------------------------------------------------------------- 1 | data/org.gnome.Console.desktop.in.in 2 | data/org.gnome.Console.gschema.xml.in 3 | data/org.gnome.Console.metainfo.xml.in.in 4 | src/help-overlay.ui 5 | src/kgx-about.c 6 | src/kgx-application.c 7 | src/kgx-application.h 8 | src/kgx-close-dialog.c 9 | src/kgx-colour-utils.c 10 | src/kgx-drop-target.c 11 | src/kgx-livery-manager.c 12 | src/kgx-pages.c 13 | src/kgx-pages.ui 14 | src/kgx-paste-dialog.c 15 | src/kgx-process.c 16 | src/kgx-simple-tab.c 17 | src/kgx-spad.c 18 | src/kgx-spad.ui 19 | src/kgx-tab.c 20 | src/kgx-tab.ui 21 | src/kgx-terminal.c 22 | src/kgx-terminal.ui 23 | src/kgx-theme-switcher.ui 24 | src/kgx-utils.c 25 | src/kgx-window.c 26 | src/kgx-window.ui 27 | src/main.c 28 | src/preferences/kgx-font-picker.ui 29 | src/preferences/kgx-preferences-window.c 30 | src/preferences/kgx-preferences-window.ui 31 | -------------------------------------------------------------------------------- /po/meson.build: -------------------------------------------------------------------------------- 1 | i18n.gettext(bin_name, preset: 'glib') 2 | -------------------------------------------------------------------------------- /src/help-overlay.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | True 6 | 7 | 8 | shortcuts 9 | 12 10 | 11 | 12 | Application 13 | 14 | 15 | win.new-window 16 | New Window 17 | 18 | 19 | 20 | 21 | 22 | 23 | Terminal 24 | 25 | 26 | win.find 27 | Find 28 | 29 | 30 | 31 | 32 | term.copy 33 | Copy 34 | 35 | 36 | 37 | 38 | term.paste 39 | Paste 40 | 41 | 42 | 43 | 44 | 45 | 46 | Tabs 47 | 48 | 49 | win.new-tab 50 | New Tab 51 | 52 | 53 | 54 | 55 | win.close-tab 56 | Close Tab 57 | 58 | 59 | 60 | 61 | win.show-tabs 62 | Show All Tabs 63 | 64 | 65 | 66 | 67 | <primary>Page_Down <primary>Tab 68 | Next Tab 69 | 70 | 71 | 72 | 73 | <primary>Page_Up <shift><primary>Tab 74 | Previous Tab 75 | 76 | 77 | 78 | 79 | <shift><primary>Page_Down 80 | Move Tab Right 81 | 82 | 83 | 84 | 85 | <shift><primary>Page_Up 86 | Move Tab Left 87 | 88 | 89 | 90 | 91 | <alt>1...9 92 | Switch to Tab 1–9 93 | 94 | 95 | 96 | 97 | <alt>0 98 | Switch to Tab 10 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /src/icons/scalable/status/bell-outline-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/icons/scalable/status/emblem-ok-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/icons/scalable/status/external-link-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/icons/scalable/status/status-privileged-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/icons/scalable/status/status-regular-symbolic.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/icons/scalable/status/status-remote-symbolic.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/icons/scalable/status/theme-check-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 34 | 37 | 38 | 40 | 44 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /src/kgx-about.h: -------------------------------------------------------------------------------- 1 | /* kgx-about.h 2 | * 3 | * Copyright 2024 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | G_BEGIN_DECLS 24 | 25 | void kgx_about_print_logo (void); 26 | void kgx_about_print_version (void); 27 | char *kgx_about_dup_version_string (void); 28 | char *kgx_about_dup_copyright_string (void); 29 | void kgx_about_present_dialogue (GtkWidget *parent); 30 | void kgx_about_append_sys_info (GString *buf, 31 | GtkRoot *root); 32 | 33 | G_END_DECLS 34 | -------------------------------------------------------------------------------- /src/kgx-application.h: -------------------------------------------------------------------------------- 1 | /* kgx-application.h 2 | * 3 | * Copyright 2019-2023 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "kgx-tab.h" 22 | #include "kgx-window.h" 23 | 24 | G_BEGIN_DECLS 25 | 26 | #define KGX_DISPLAY_NAME _("Console") 27 | 28 | #define KGX_TYPE_APPLICATION (kgx_application_get_type()) 29 | 30 | G_DECLARE_FINAL_TYPE (KgxApplication, kgx_application, KGX, APPLICATION, AdwApplication) 31 | 32 | 33 | void kgx_application_add_page (KgxApplication *self, 34 | KgxTab *page); 35 | KgxTab *kgx_application_lookup_page (KgxApplication *self, 36 | guint id); 37 | KgxTab * kgx_application_add_terminal (KgxApplication *self, 38 | KgxWindow *existing_window, 39 | GFile *working_directory, 40 | GStrv command, 41 | const char *title); 42 | 43 | G_END_DECLS 44 | -------------------------------------------------------------------------------- /src/kgx-close-dialog.h: -------------------------------------------------------------------------------- 1 | /* kgx-close-dialog.h 2 | * 3 | * Copyright 2019-2023 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | #include "kgx-enums.h" 24 | 25 | G_BEGIN_DECLS 26 | 27 | typedef enum { 28 | KGX_CONTEXT_WINDOW, 29 | KGX_CONTEXT_TAB, 30 | } KgxCloseDialogContext; 31 | 32 | 33 | typedef enum { 34 | KGX_CLOSE_ANYWAY, 35 | KGX_CLOSE_CANCELLED, 36 | } KgxCloseDialogResult; 37 | 38 | 39 | #define KGX_TYPE_CLOSE_DIALOG (kgx_close_dialog_get_type ()) 40 | 41 | G_DECLARE_FINAL_TYPE (KgxCloseDialog, kgx_close_dialog, KGX, CLOSE_DIALOG, GObject) 42 | 43 | void kgx_close_dialog_run (KgxCloseDialog *restrict self, 44 | GtkWidget *restrict parent, 45 | GCancellable *restrict cancellable, 46 | GAsyncReadyCallback callback, 47 | gpointer user_data); 48 | KgxCloseDialogResult kgx_close_dialog_run_finish (KgxCloseDialog *restrict self, 49 | GAsyncResult *restrict res, 50 | GError **restrict error); 51 | 52 | G_END_DECLS 53 | -------------------------------------------------------------------------------- /src/kgx-colour-utils.c: -------------------------------------------------------------------------------- 1 | /* kgx-colour-utils.c 2 | * 3 | * Copyright 2024 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include "kgx-config.h" 20 | 21 | #include 22 | 23 | #include "kgx-colour-utils.h" 24 | 25 | 26 | G_DEFINE_QUARK (kgx-colour-parse-error-quark, kgx_colour_parse_error) 27 | 28 | 29 | static inline double 30 | read_component (const char **const ptr) 31 | { 32 | int first = g_unichar_xdigit_value (g_utf8_get_char (*ptr)); 33 | int second = 0; 34 | 35 | *ptr = g_utf8_next_char (*ptr); 36 | second = g_unichar_xdigit_value (g_utf8_get_char (*ptr)); 37 | *ptr = g_utf8_next_char (*ptr); 38 | 39 | return ((first << 4) + second) / 255.0; 40 | } 41 | 42 | 43 | void 44 | kgx_colour_from_string (const char *const string, 45 | GdkRGBA *const colour, 46 | GError **error) 47 | { 48 | const char *ptr = string; 49 | 50 | g_return_if_fail (string != NULL); 51 | g_return_if_fail (colour != NULL); 52 | g_return_if_fail (error != NULL); 53 | 54 | if (g_utf8_strlen (string, -1) != 6) { 55 | g_set_error_literal (error, 56 | KGX_COLOUR_PARSE_ERROR, 57 | KGX_COLOUR_PARSE_ERROR_WRONG_LENGTH, 58 | _("Color string is wrong length")); 59 | return; 60 | } 61 | 62 | colour->red = read_component (&ptr); 63 | colour->green = read_component (&ptr); 64 | colour->blue = read_component (&ptr); 65 | colour->alpha = 0.0; 66 | } 67 | -------------------------------------------------------------------------------- /src/kgx-colour-utils.h: -------------------------------------------------------------------------------- 1 | /* kgx-colour-utils.h 2 | * 3 | * Copyright 2024 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "kgx-config.h" 22 | 23 | #include 24 | 25 | #include 26 | 27 | G_BEGIN_DECLS 28 | 29 | 30 | static inline char * 31 | kgx_colour_to_string (GdkRGBA *colour) 32 | { 33 | /* intentionally not using gdk_rgba_to_string here */ 34 | return g_strdup_printf ("%02X%02X%02X", 35 | (unsigned int) (colour->red * 255), 36 | (unsigned int) (colour->green * 255), 37 | (unsigned int) (colour->blue * 255)); 38 | } 39 | 40 | 41 | typedef enum /*< enum,prefix=KGX >*/ { 42 | KGX_COLOUR_PARSE_ERROR_WRONG_LENGTH, 43 | } KgxColourParseError; 44 | 45 | 46 | #define KGX_COLOUR_PARSE_ERROR (kgx_colour_parse_error_quark ()) 47 | 48 | 49 | GQuark kgx_colour_parse_error_quark (void); 50 | void kgx_colour_from_string (const char *const string, 51 | GdkRGBA *const colour, 52 | GError **error); 53 | 54 | 55 | G_END_DECLS 56 | -------------------------------------------------------------------------------- /src/kgx-depot.h: -------------------------------------------------------------------------------- 1 | /* kgx-depot.h 2 | * 3 | * Copyright 2021-2024 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | #include "kgx-settings.h" 24 | #include "kgx-train.h" 25 | 26 | G_BEGIN_DECLS 27 | 28 | #define KGX_TYPE_DEPOT (kgx_depot_get_type ()) 29 | 30 | G_DECLARE_FINAL_TYPE (KgxDepot, kgx_depot, KGX, DEPOT, GObject) 31 | 32 | void kgx_depot_spawn (KgxDepot *self, 33 | KgxSettings *settings, 34 | VtePty *pty, 35 | const char *const working_directory, 36 | const char *const *const argv, 37 | const char *const *const env, 38 | GCancellable *cancellable, 39 | GAsyncReadyCallback callback, 40 | gpointer user_data); 41 | KgxTrain *kgx_depot_spawn_finish (KgxDepot *self, 42 | GAsyncResult *result, 43 | GError **error); 44 | 45 | G_END_DECLS 46 | -------------------------------------------------------------------------------- /src/kgx-despatcher.h: -------------------------------------------------------------------------------- 1 | /* kgx-despatcher.h 2 | * 3 | * Copyright 2023 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | G_BEGIN_DECLS 24 | 25 | #define KGX_TYPE_DESPATCHER (kgx_despatcher_get_type ()) 26 | 27 | G_DECLARE_FINAL_TYPE (KgxDespatcher, kgx_despatcher, KGX, DESPATCHER, GObject) 28 | 29 | 30 | void kgx_despatcher_open (KgxDespatcher *self, 31 | const char *uri, 32 | GtkWindow *window, 33 | GCancellable *cancellable, 34 | GAsyncReadyCallback callback, 35 | gpointer user_data); 36 | void kgx_despatcher_open_finish (KgxDespatcher *self, 37 | GAsyncResult *result, 38 | GError **error); 39 | void kgx_despatcher_show_item (KgxDespatcher *self, 40 | const char *uri, 41 | GtkWindow *window, 42 | GCancellable *cancellable, 43 | GAsyncReadyCallback callback, 44 | gpointer user_data); 45 | void kgx_despatcher_show_item_finish (KgxDespatcher *self, 46 | GAsyncResult *result, 47 | GError **error); 48 | void kgx_despatcher_show_folder (KgxDespatcher *self, 49 | const char *uri, 50 | GtkWindow *window, 51 | GCancellable *cancellable, 52 | GAsyncReadyCallback callback, 53 | gpointer user_data); 54 | void kgx_despatcher_show_folder_finish (KgxDespatcher *self, 55 | GAsyncResult *result, 56 | GError **error); 57 | 58 | 59 | G_END_DECLS 60 | -------------------------------------------------------------------------------- /src/kgx-drop-target.h: -------------------------------------------------------------------------------- 1 | /* kgx-drop-target.h 2 | * 3 | * Copyright 2023 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | G_BEGIN_DECLS 24 | 25 | #define KGX_TYPE_DROP_TARGET (kgx_drop_target_get_type ()) 26 | 27 | G_DECLARE_FINAL_TYPE (KgxDropTarget, kgx_drop_target, KGX, DROP_TARGET, GObject) 28 | 29 | 30 | void kgx_drop_target_extra_drop (KgxDropTarget *self, 31 | const GValue *value); 32 | void kgx_drop_target_mount_on (KgxDropTarget *self, 33 | GtkWidget *widget); 34 | 35 | 36 | G_END_DECLS 37 | -------------------------------------------------------------------------------- /src/kgx-empty.c: -------------------------------------------------------------------------------- 1 | /* kgx-empty.c 2 | * 3 | * Copyright 2024-2025 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include "kgx-config.h" 20 | 21 | #include 22 | #include 23 | 24 | #include "kgx-utils.h" 25 | 26 | #include "kgx-empty.h" 27 | 28 | 29 | struct _KgxEmpty { 30 | GtkBox parent_instance; 31 | 32 | gboolean working; 33 | 34 | gboolean logo_visible; 35 | guint logo_timeout; 36 | 37 | gboolean spinner_visible; 38 | guint spinner_timeout; 39 | 40 | gboolean had_first_map; 41 | }; 42 | 43 | 44 | G_DEFINE_FINAL_TYPE (KgxEmpty, kgx_empty, GTK_TYPE_BOX) 45 | 46 | 47 | enum { 48 | PROP_0, 49 | PROP_WORKING, 50 | PROP_LOGO_VISIBLE, 51 | PROP_SPINNER_VISIBLE, 52 | LAST_PROP 53 | }; 54 | static GParamSpec *pspecs[LAST_PROP] = { NULL, }; 55 | 56 | 57 | static void 58 | kgx_empty_dispose (GObject *object) 59 | { 60 | KgxEmpty *self = KGX_EMPTY (object); 61 | 62 | g_clear_handle_id (&self->logo_timeout, g_source_remove); 63 | g_clear_handle_id (&self->spinner_timeout, g_source_remove); 64 | 65 | G_OBJECT_CLASS (kgx_empty_parent_class)->dispose (object); 66 | } 67 | 68 | 69 | static void 70 | kgx_empty_get_property (GObject *object, 71 | guint property_id, 72 | GValue *value, 73 | GParamSpec *pspec) 74 | { 75 | KgxEmpty *self = KGX_EMPTY (object); 76 | 77 | switch (property_id) { 78 | case PROP_WORKING: 79 | g_value_set_boolean (value, self->working); 80 | break; 81 | case PROP_LOGO_VISIBLE: 82 | g_value_set_boolean (value, self->logo_visible); 83 | break; 84 | case PROP_SPINNER_VISIBLE: 85 | g_value_set_boolean (value, self->spinner_visible); 86 | break; 87 | KGX_INVALID_PROP (object, property_id, pspec); 88 | } 89 | } 90 | 91 | 92 | static void 93 | show_spinner (gpointer user_data) 94 | { 95 | KgxEmpty *self = KGX_EMPTY (user_data); 96 | 97 | self->spinner_visible = TRUE; 98 | g_object_notify_by_pspec (G_OBJECT (self), pspecs[PROP_SPINNER_VISIBLE]); 99 | 100 | self->spinner_timeout = 0; 101 | } 102 | 103 | 104 | static inline void 105 | update_spinner (KgxEmpty *self) 106 | { 107 | g_clear_handle_id (&self->spinner_timeout, g_source_remove); 108 | 109 | if (self->working) { 110 | self->spinner_timeout = g_timeout_add_once (100, show_spinner, self); 111 | } else { 112 | self->spinner_visible = FALSE; 113 | g_object_notify_by_pspec (G_OBJECT (self), pspecs[PROP_SPINNER_VISIBLE]); 114 | } 115 | } 116 | 117 | 118 | static void 119 | kgx_empty_set_property (GObject *object, 120 | guint property_id, 121 | const GValue *value, 122 | GParamSpec *pspec) 123 | { 124 | KgxEmpty *self = KGX_EMPTY (object); 125 | 126 | switch (property_id) { 127 | case PROP_WORKING: 128 | if (kgx_set_boolean_prop (object, pspec, &self->working, value)) { 129 | update_spinner (self); 130 | } 131 | break; 132 | KGX_INVALID_PROP (object, property_id, pspec); 133 | } 134 | } 135 | 136 | 137 | static void 138 | show_logo (gpointer user_data) 139 | { 140 | KgxEmpty *self = KGX_EMPTY (user_data); 141 | 142 | self->logo_visible = TRUE; 143 | g_object_notify_by_pspec (G_OBJECT (self), pspecs[PROP_LOGO_VISIBLE]); 144 | 145 | self->logo_timeout = 0; 146 | } 147 | 148 | 149 | static void 150 | kgx_empty_map (GtkWidget *widget) 151 | { 152 | KgxEmpty *self = KGX_EMPTY (widget); 153 | 154 | if (!self->had_first_map) { 155 | self->had_first_map = TRUE; 156 | self->logo_timeout = g_timeout_add_once (80, show_logo, self); 157 | } 158 | 159 | GTK_WIDGET_CLASS (kgx_empty_parent_class)->map (widget); 160 | } 161 | 162 | 163 | static void 164 | kgx_empty_unmap (GtkWidget *widget) 165 | { 166 | KgxEmpty *self = KGX_EMPTY (widget); 167 | 168 | g_clear_handle_id (&self->logo_timeout, g_source_remove); 169 | g_clear_handle_id (&self->spinner_timeout, g_source_remove); 170 | 171 | GTK_WIDGET_CLASS (kgx_empty_parent_class)->unmap (widget); 172 | } 173 | 174 | 175 | static void 176 | kgx_empty_class_init (KgxEmptyClass *klass) 177 | { 178 | GObjectClass *object_class = G_OBJECT_CLASS (klass); 179 | GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); 180 | 181 | object_class->dispose = kgx_empty_dispose; 182 | object_class->get_property = kgx_empty_get_property; 183 | object_class->set_property = kgx_empty_set_property; 184 | 185 | widget_class->map = kgx_empty_map; 186 | widget_class->unmap = kgx_empty_unmap; 187 | 188 | pspecs[PROP_WORKING] = 189 | g_param_spec_boolean ("working", NULL, NULL, 190 | FALSE, 191 | G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); 192 | 193 | pspecs[PROP_LOGO_VISIBLE] = 194 | g_param_spec_boolean ("logo-visible", NULL, NULL, 195 | FALSE, 196 | G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); 197 | 198 | pspecs[PROP_SPINNER_VISIBLE] = 199 | g_param_spec_boolean ("spinner-visible", NULL, NULL, 200 | FALSE, 201 | G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); 202 | 203 | g_object_class_install_properties (object_class, LAST_PROP, pspecs); 204 | 205 | g_type_ensure (ADW_TYPE_SPINNER); 206 | 207 | gtk_widget_class_set_template_from_resource (widget_class, 208 | KGX_APPLICATION_PATH "kgx-empty.ui"); 209 | 210 | gtk_widget_class_set_css_name (widget_class, "kgx-empty"); 211 | } 212 | 213 | 214 | static void 215 | kgx_empty_init (KgxEmpty *self) 216 | { 217 | gtk_widget_init_template (GTK_WIDGET (self)); 218 | } 219 | -------------------------------------------------------------------------------- /src/kgx-empty.h: -------------------------------------------------------------------------------- 1 | /* kgx-empty.h 2 | * 3 | * Copyright 2024 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | G_BEGIN_DECLS 24 | 25 | #define KGX_TYPE_EMPTY (kgx_empty_get_type ()) 26 | 27 | G_DECLARE_FINAL_TYPE (KgxEmpty, kgx_empty, KGX, EMPTY, GtkBox) 28 | 29 | 30 | G_END_DECLS 31 | -------------------------------------------------------------------------------- /src/kgx-empty.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 42 | -------------------------------------------------------------------------------- /src/kgx-file-closures.h: -------------------------------------------------------------------------------- 1 | /* kgx-file-closures.h 2 | * 3 | * Copyright 2025 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | G_BEGIN_DECLS 24 | 25 | 26 | G_GNUC_UNUSED 27 | static char * 28 | kgx_file_as_subtitle (G_GNUC_UNUSED GObject *object, 29 | GFile *file, 30 | const char *window_title) 31 | { 32 | g_autoptr (GFile) home = NULL; 33 | g_autoptr (GError) error = NULL; 34 | g_autofree char *path_raw = NULL; 35 | g_autofree char *path_utf8 = NULL; 36 | g_autofree char *path_rel_raw = NULL; 37 | g_autofree char *path_rel_utf8 = NULL; 38 | g_autofree char *short_home = NULL; 39 | const char *home_path = NULL; 40 | 41 | if (!file) { 42 | return NULL; 43 | } 44 | 45 | path_raw = g_file_get_path (file); 46 | if (G_UNLIKELY (!path_raw || g_strcmp0 (path_raw, window_title) == 0)) { 47 | return NULL; 48 | } 49 | 50 | path_utf8 = g_filename_to_utf8 (path_raw, -1, NULL, NULL, &error); 51 | if (G_UNLIKELY (error)) { 52 | g_debug ("path had unexpected encoding (%s)", error->message); 53 | return g_file_get_uri (file); 54 | } 55 | 56 | home_path = g_get_home_dir (); 57 | if (G_UNLIKELY (!g_str_has_prefix (path_raw, home_path))) { 58 | return g_steal_pointer (&path_utf8); 59 | } 60 | 61 | home = g_file_new_for_path (home_path); 62 | if (!g_file_equal (home, file)) { 63 | path_rel_raw = g_file_get_relative_path (home, file); 64 | 65 | /* In practice we should have discounted non-utf8 already, but better 66 | * safe than sorry and replacement chars beats a crash */ 67 | path_rel_utf8 = g_filename_display_name (path_rel_raw); 68 | 69 | short_home = g_strdup_printf ("~/%s", path_rel_utf8); 70 | } else { 71 | short_home = g_strdup ("~"); 72 | } 73 | 74 | if (G_LIKELY (g_strcmp0 (short_home, window_title) == 0)) { 75 | /* Avoid duplicating the title */ 76 | return NULL; 77 | } 78 | 79 | return g_steal_pointer (&short_home); 80 | } 81 | 82 | 83 | G_GNUC_UNUSED 84 | static char * 85 | kgx_file_as_display (G_GNUC_UNUSED GObject *object, 86 | GFile *file) 87 | { 88 | g_autofree char *raw_path = NULL; 89 | 90 | if (!file) { 91 | return NULL; 92 | } 93 | 94 | raw_path = g_file_get_path (file); 95 | 96 | /* Probably impossible in KGX, but you never know */ 97 | if (G_UNLIKELY (!raw_path)) { 98 | return NULL; 99 | } 100 | 101 | return g_filename_display_name (raw_path); 102 | } 103 | 104 | 105 | G_GNUC_UNUSED 106 | static char * 107 | kgx_file_as_display_or_uri (G_GNUC_UNUSED GObject *object, 108 | GFile *file) 109 | { 110 | g_autofree char *path_raw = NULL; 111 | g_autofree char *path_utf8 = NULL; 112 | g_autoptr (GError) error = NULL; 113 | 114 | if (!file) { 115 | return NULL; 116 | } 117 | 118 | path_raw = g_file_get_path (file); 119 | if (G_UNLIKELY (!path_raw)) { 120 | return g_file_get_uri (file); 121 | } 122 | 123 | path_utf8 = g_filename_to_utf8 (path_raw, -1, NULL, NULL, &error); 124 | if (G_UNLIKELY (error)) { 125 | g_debug ("path had unexpected encoding (%s)", error->message); 126 | return g_file_get_uri (file); 127 | } 128 | 129 | return g_steal_pointer (&path_utf8); 130 | } 131 | 132 | 133 | G_END_DECLS 134 | -------------------------------------------------------------------------------- /src/kgx-git-tag.h.in: -------------------------------------------------------------------------------- 1 | /* kgx-git-tag.h 2 | * 3 | * Copyright 2025 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | G_BEGIN_DECLS 24 | 25 | #define KGX_GIT_TAG "@VCS_TAG@" 26 | 27 | 28 | G_END_DECLS 29 | -------------------------------------------------------------------------------- /src/kgx-icon-closures.h: -------------------------------------------------------------------------------- 1 | /* kgx-icon-closures.h 2 | * 3 | * Copyright 2025 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | #include "kgx-train.h" 24 | 25 | #include "kgx-utils.h" 26 | 27 | G_BEGIN_DECLS 28 | 29 | 30 | G_GNUC_UNUSED 31 | static GIcon * 32 | kgx_status_as_icon (G_GNUC_UNUSED GObject *self, 33 | KgxStatus status) 34 | { 35 | if (status & KGX_REMOTE) { 36 | return g_themed_icon_new ("status-remote-symbolic"); 37 | } else if (status & KGX_PRIVILEGED) { 38 | return g_themed_icon_new ("status-privileged-symbolic"); 39 | } 40 | 41 | return NULL; 42 | } 43 | 44 | 45 | G_GNUC_UNUSED 46 | static GIcon * 47 | kgx_ringing_as_icon (G_GNUC_UNUSED GObject *self, 48 | gboolean ringing) 49 | { 50 | if (ringing) { 51 | return g_themed_icon_new ("bell-outline-symbolic"); 52 | } 53 | 54 | return NULL; 55 | } 56 | 57 | 58 | G_END_DECLS 59 | -------------------------------------------------------------------------------- /src/kgx-livery-manager.h: -------------------------------------------------------------------------------- 1 | /* kgx-livery-manager.h 2 | * 3 | * Copyright 2024 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "kgx-livery.h" 22 | 23 | G_BEGIN_DECLS 24 | 25 | #define KGX_TYPE_LIVERY_MANAGER (kgx_livery_manager_get_type ()) 26 | 27 | G_DECLARE_FINAL_TYPE (KgxLiveryManager, kgx_livery_manager, KGX, LIVERY_MANAGER, GObject) 28 | 29 | GVariant *kgx_livery_manager_get_custom_liveries (KgxLiveryManager *self); 30 | void kgx_livery_manager_set_custom_liveries (KgxLiveryManager *self, 31 | GVariant *variant); 32 | KgxLivery *kgx_livery_manager_resolve (KgxLiveryManager *self, 33 | const char *uuid); 34 | KgxLivery *kgx_livery_manager_dup_fallback (KgxLiveryManager *self); 35 | 36 | G_END_DECLS 37 | -------------------------------------------------------------------------------- /src/kgx-livery.h: -------------------------------------------------------------------------------- 1 | /* kgx-livery.h 2 | * 3 | * Copyright 2023-2024 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | #include "kgx-palette.h" 24 | 25 | G_BEGIN_DECLS 26 | 27 | typedef struct _KgxLivery KgxLivery; 28 | 29 | #define KGX_TYPE_LIVERY (kgx_livery_get_type ()) 30 | 31 | KgxLivery *kgx_livery_new (const char *uuid, 32 | const char *name, 33 | KgxPalette *night, 34 | KgxPalette *day); 35 | GType kgx_livery_get_type (void); 36 | KgxLivery *kgx_livery_ref (KgxLivery *self); 37 | void kgx_livery_unref (KgxLivery *self); 38 | const char *kgx_livery_get_uuid (KgxLivery *self); 39 | const char *kgx_livery_get_name (KgxLivery *self); 40 | KgxPalette *kgx_livery_get_night (KgxLivery *self); 41 | KgxPalette *kgx_livery_get_day (KgxLivery *self); 42 | KgxLivery *kgx_livery_deserialise (GVariant *variant); 43 | void kgx_livery_serialise_to (KgxLivery *self, 44 | GVariantBuilder *builder); 45 | GVariant *kgx_livery_serialise (KgxLivery *self); 46 | void kgx_livery_import_from (GFile *file, 47 | GCancellable *cancellable, 48 | GAsyncReadyCallback callback, 49 | gpointer user_data); 50 | KgxLivery *kgx_livery_import_from_finish (GAsyncResult *res, 51 | GError **error); 52 | void kgx_livery_export_to (KgxLivery *self, 53 | GFile *file, 54 | GCancellable *cancellable, 55 | GAsyncReadyCallback callback, 56 | gpointer user_data); 57 | void kgx_livery_export_to_finish (KgxLivery *self, 58 | GAsyncResult *res, 59 | GError **error); 60 | KgxPalette *kgx_livery_resolve (KgxLivery *self, 61 | gboolean is_day, 62 | gboolean translucency); 63 | 64 | G_DEFINE_AUTOPTR_CLEANUP_FUNC (KgxLivery, kgx_livery_unref) 65 | 66 | static inline gboolean 67 | kgx_set_livery (KgxLivery **livery_ptr, 68 | KgxLivery *new_livery) 69 | { 70 | KgxLivery *old_livery = *livery_ptr; 71 | 72 | if (old_livery == new_livery) { 73 | return FALSE; 74 | } 75 | 76 | *livery_ptr = new_livery ? kgx_livery_ref (new_livery) : NULL; 77 | 78 | if (old_livery != NULL) { 79 | kgx_livery_unref (old_livery); 80 | } 81 | 82 | return TRUE; 83 | } 84 | 85 | G_END_DECLS 86 | -------------------------------------------------------------------------------- /src/kgx-locale.h: -------------------------------------------------------------------------------- 1 | /* kgx-locale.h 2 | * 3 | * Copyright 2025 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "kgx-config.h" 22 | 23 | #include 24 | 25 | #include 26 | 27 | G_BEGIN_DECLS 28 | 29 | 30 | #define KGX_LOCALE_DYNAMIC "" 31 | #define KGX_LOCALE_TEST "C.UTF-8" 32 | 33 | 34 | G_GNUC_UNUSED 35 | static inline void 36 | kgx_locale_init (const char *locale) 37 | { 38 | setlocale (LC_ALL, locale); 39 | bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); 40 | bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); 41 | textdomain (GETTEXT_PACKAGE); 42 | } 43 | 44 | 45 | G_END_DECLS 46 | -------------------------------------------------------------------------------- /src/kgx-marshals.list: -------------------------------------------------------------------------------- 1 | BOOLEAN: STRING, VARIANT 2 | BOXED: BOOLEAN, BOXED, BOXED 3 | INT64: BOOLEAN, INT64 4 | OBJECT: VOID 5 | VOID: BOXED 6 | VOID: ENUM 7 | VOID: ENUM, STRING, BOOLEAN 8 | VOID: INT 9 | VOID: STRING 10 | VOID: UINT, UINT 11 | VOID: VOID 12 | -------------------------------------------------------------------------------- /src/kgx-page-expression.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 52 | -------------------------------------------------------------------------------- /src/kgx-pages.h: -------------------------------------------------------------------------------- 1 | /* kgx-pages.h 2 | * 3 | * Copyright 2019-2023 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | #include "kgx-tab.h" 24 | #include "kgx-train.h" 25 | 26 | G_BEGIN_DECLS 27 | 28 | #define KGX_TYPE_PAGES (kgx_pages_get_type()) 29 | 30 | /** 31 | * KgxPagesClass: 32 | */ 33 | struct _KgxPagesClass { 34 | AdwBinClass parent; 35 | }; 36 | 37 | 38 | G_DECLARE_DERIVABLE_TYPE (KgxPages, kgx_pages, KGX, PAGES, AdwBin) 39 | 40 | 41 | void kgx_pages_add_page (KgxPages *self, 42 | KgxTab *page); 43 | int kgx_pages_count (KgxPages *self); 44 | GPtrArray *kgx_pages_get_children (KgxPages *self); 45 | void kgx_pages_focus_page (KgxPages *self, 46 | KgxTab *page); 47 | KgxStatus kgx_pages_current_status (KgxPages *self); 48 | gboolean kgx_pages_is_ringing (KgxPages *self); 49 | void kgx_pages_close_page (KgxPages *self); 50 | void kgx_pages_detach_page (KgxPages *self); 51 | AdwTabPage *kgx_pages_get_selected_page (KgxPages *self); 52 | 53 | G_END_DECLS 54 | -------------------------------------------------------------------------------- /src/kgx-pages.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 97 | 98 |
99 | 100 | _Detach Tab 101 | tab.detach 102 | 103 |
104 |
105 | 106 | _Close 107 | tab.close 108 | 109 |
110 |
111 | 112 | status-regular-symbolic 113 | 114 | 115 | KgxTab 116 | 118 | 119 | 120 | 122 | 123 | 124 | KgxSettings 125 | 126 | 127 | 128 | AdwStyleManager 129 | 130 | 131 | 132 | KgxPages 133 | 134 | 135 | 136 | 137 |
-------------------------------------------------------------------------------- /src/kgx-palette.h: -------------------------------------------------------------------------------- 1 | /* kgx-palette.h 2 | * 3 | * Copyright 2023-2024 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | G_BEGIN_DECLS 24 | 25 | #define KGX_TYPE_PALETTE (kgx_palette_get_type ()) 26 | 27 | typedef struct _KgxPalette KgxPalette; 28 | 29 | KgxPalette *kgx_palette_new (const GdkRGBA *const foreground, 30 | const GdkRGBA *const background, 31 | double transparency, 32 | size_t n_colours, 33 | const GdkRGBA colours[const n_colours]); 34 | GType kgx_palette_get_type (void); 35 | KgxPalette *kgx_palette_ref (KgxPalette *self); 36 | void kgx_palette_unref (KgxPalette *self); 37 | KgxPalette *kgx_palette_deserialise (GVariant *variant); 38 | void kgx_palette_serialise_to (KgxPalette *self, 39 | GVariantBuilder *builder); 40 | GVariant *kgx_palette_serialise (KgxPalette *self); 41 | KgxPalette *kgx_palette_new_from_group (GKeyFile *key_file, 42 | const char *const group, 43 | GError **error); 44 | void kgx_palette_export_to_group (KgxPalette *self, 45 | GKeyFile *key_file, 46 | const char *const group); 47 | KgxPalette *kgx_palette_as_opaque (KgxPalette *self); 48 | double kgx_palette_get_transparency (KgxPalette *self); 49 | void kgx_palette_get_colours (KgxPalette *self, 50 | GdkRGBA *const foreground, 51 | GdkRGBA *const background, 52 | size_t *const n_colours, 53 | const GdkRGBA *colours[const *n_colours]); 54 | 55 | G_DEFINE_AUTOPTR_CLEANUP_FUNC (KgxPalette, kgx_palette_unref) 56 | 57 | static inline gboolean 58 | kgx_set_palette (KgxPalette **palette_ptr, 59 | KgxPalette *new_palette) 60 | { 61 | KgxPalette *old_palette = *palette_ptr; 62 | 63 | if (old_palette == new_palette) { 64 | return FALSE; 65 | } 66 | 67 | *palette_ptr = new_palette ? kgx_palette_ref (new_palette) : NULL; 68 | 69 | if (old_palette != NULL) { 70 | kgx_palette_unref (old_palette); 71 | } 72 | 73 | return TRUE; 74 | } 75 | 76 | G_END_DECLS 77 | -------------------------------------------------------------------------------- /src/kgx-paste-dialog.h: -------------------------------------------------------------------------------- 1 | /* kgx-paste-dialog.h 2 | * 3 | * Copyright 2024 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | #include "kgx-enums.h" 24 | 25 | G_BEGIN_DECLS 26 | 27 | typedef enum { 28 | KGX_PASTE_ANYWAY, 29 | KGX_PASTE_CANCELLED, 30 | } KgxPasteDialogResult; 31 | 32 | 33 | #define KGX_TYPE_PASTE_DIALOG (kgx_paste_dialog_get_type ()) 34 | 35 | G_DECLARE_FINAL_TYPE (KgxPasteDialog, kgx_paste_dialog, KGX, PASTE_DIALOG, GObject) 36 | 37 | void kgx_paste_dialog_run (KgxPasteDialog *restrict self, 38 | GtkWidget *restrict parent, 39 | GCancellable *restrict cancellable, 40 | GAsyncReadyCallback callback, 41 | gpointer user_data); 42 | KgxPasteDialogResult kgx_paste_dialog_run_finish (KgxPasteDialog *restrict self, 43 | GAsyncResult *restrict res, 44 | const char *restrict *restrict const content, 45 | GError **restrict error); 46 | 47 | G_END_DECLS 48 | -------------------------------------------------------------------------------- /src/kgx-process.h: -------------------------------------------------------------------------------- 1 | /* kgx-process.h 2 | * 3 | * Copyright 2019 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | #include 23 | 24 | #include "kgx-config.h" 25 | 26 | G_BEGIN_DECLS 27 | 28 | typedef struct _KgxProcess KgxProcess; 29 | 30 | #define KGX_TYPE_PROCESS (kgx_process_get_type ()) 31 | 32 | GTree *kgx_process_get_list (void); 33 | KgxProcess *kgx_process_new (GPid pid); 34 | GPid kgx_process_get_pid (KgxProcess *self); 35 | gboolean kgx_process_get_is_root (KgxProcess *self); 36 | GPid kgx_process_get_parent (KgxProcess *self); 37 | GStrv kgx_process_get_argv (KgxProcess *self); 38 | void kgx_process_get_title (KgxProcess *self, 39 | char **title, 40 | char **subtitle); 41 | GType kgx_process_get_type (void); 42 | void kgx_process_unref (KgxProcess *self); 43 | 44 | int kgx_pid_cmp (gconstpointer a, 45 | gconstpointer b, 46 | gpointer data); 47 | 48 | G_DEFINE_AUTOPTR_CLEANUP_FUNC (KgxProcess, kgx_process_unref) 49 | 50 | G_END_DECLS 51 | -------------------------------------------------------------------------------- /src/kgx-proxy-info.h: -------------------------------------------------------------------------------- 1 | /* kgx-proxy-info.h 2 | * 3 | * Copyright 2021 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | G_BEGIN_DECLS 24 | 25 | #define KGX_TYPE_PROXY_INFO kgx_proxy_info_get_type () 26 | 27 | G_DECLARE_FINAL_TYPE (KgxProxyInfo, kgx_proxy_info, KGX, PROXY_INFO, GObject) 28 | 29 | void kgx_proxy_info_apply_to_environ (KgxProxyInfo *self, 30 | char ***env); 31 | 32 | G_END_DECLS 33 | -------------------------------------------------------------------------------- /src/kgx-settings.h: -------------------------------------------------------------------------------- 1 | /* kgx-settings.h 2 | * 3 | * Copyright 2022-2024 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | #include 23 | 24 | #include "kgx-enums.h" 25 | #include "kgx-livery.h" 26 | 27 | G_BEGIN_DECLS 28 | 29 | 30 | /** 31 | * KgxTheme: 32 | * @KGX_THEME_AUTO: Matches %KGX_THEME_DAY or %KGX_THEME_NIGHT depending on 33 | * the user's global setting 34 | * @KGX_THEME_NIGHT: The default, dark, theme 35 | * @KGX_THEME_DAY: Alternate, light, theme 36 | * @KGX_THEME_HACKER: Legacy alias for night 37 | * 38 | * Until [meson#1687](https://github.com/mesonbuild/meson/issues/1687) is 39 | * resolved this enum must be manually kept in sync with 40 | * the ‘Theme’ enum in our gschema 41 | */ 42 | typedef enum /*< enum,prefix=KGX >*/ { 43 | KGX_THEME_AUTO = 0, /*< nick=auto >*/ 44 | KGX_THEME_NIGHT = 1, /*< nick=night >*/ 45 | KGX_THEME_DAY = 2, /*< nick=day >*/ 46 | KGX_THEME_HACKER = 3, /*< nick=hacker >*/ 47 | } KgxTheme; 48 | 49 | 50 | /** 51 | * KGX_FONT_SCALE_MIN: 52 | * The smallest font scale/zoom 53 | */ 54 | #define KGX_FONT_SCALE_MIN 0.5 55 | 56 | 57 | /** 58 | * KGX_FONT_SCALE_MAX: 59 | * The largest font scale/zoom 60 | */ 61 | #define KGX_FONT_SCALE_MAX 4.0 62 | 63 | 64 | /** 65 | * KGX_FONT_SCALE_DEFAULT: 66 | * The standard font scale/zoom 67 | */ 68 | #define KGX_FONT_SCALE_DEFAULT 1.0 69 | 70 | 71 | #define KGX_TYPE_SETTINGS kgx_settings_get_type () 72 | 73 | G_DECLARE_FINAL_TYPE (KgxSettings, kgx_settings, KGX, SETTINGS, GObject) 74 | 75 | void kgx_settings_increase_scale (KgxSettings *self); 76 | void kgx_settings_decrease_scale (KgxSettings *self); 77 | void kgx_settings_reset_scale (KgxSettings *self); 78 | GStrv kgx_settings_get_shell (KgxSettings *self); 79 | void kgx_settings_set_custom_shell (KgxSettings *self, 80 | const char *const *shell); 81 | void kgx_settings_set_scrollback_limit (KgxSettings *self, 82 | int64_t value); 83 | gboolean kgx_settings_get_restore_size (KgxSettings *self); 84 | void kgx_settings_get_size (KgxSettings *self, 85 | int *width, 86 | int *height, 87 | gboolean *maximised); 88 | void kgx_settings_set_custom_size (KgxSettings *self, 89 | int width, 90 | int height, 91 | gboolean maximised); 92 | gboolean kgx_settings_get_audible_bell (KgxSettings *self); 93 | gboolean kgx_settings_get_visual_bell (KgxSettings *self); 94 | PangoFontDescription *kgx_settings_get_custom_font (KgxSettings *self); 95 | void kgx_settings_set_custom_font (KgxSettings *self, 96 | PangoFontDescription *custom_font); 97 | gboolean kgx_settings_get_software_flow_control (KgxSettings *self); 98 | KgxLivery *kgx_settings_get_livery (KgxSettings *self); 99 | void kgx_settings_set_livery (KgxSettings *self, 100 | KgxLivery *livery); 101 | KgxTheme kgx_settings_resolve_theme (KgxSettings *self, 102 | gboolean dark_environment); 103 | 104 | G_END_DECLS 105 | -------------------------------------------------------------------------------- /src/kgx-shared-closures.h: -------------------------------------------------------------------------------- 1 | /* kgx-shared-closures.h 2 | * 3 | * Copyright 2024-2025 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | #include "kgx-utils.h" 24 | 25 | G_BEGIN_DECLS 26 | 27 | 28 | G_GNUC_UNUSED 29 | static AdwStyleManager * 30 | kgx_style_manager_for_display (G_GNUC_UNUSED GObject *self, 31 | GdkDisplay *display) 32 | { 33 | if (G_UNLIKELY (!display)) { 34 | return NULL; 35 | } 36 | 37 | return g_object_ref (adw_style_manager_get_for_display (display)); 38 | } 39 | 40 | 41 | G_GNUC_UNUSED 42 | static GtkSettings * 43 | kgx_gtk_settings_for_display (G_GNUC_UNUSED GObject *self, 44 | GdkDisplay *display) 45 | { 46 | if (G_UNLIKELY (!display)) { 47 | return NULL; 48 | } 49 | 50 | return g_object_ref (gtk_settings_get_for_display (display)); 51 | } 52 | 53 | 54 | G_GNUC_UNUSED 55 | static char * 56 | kgx_text_or_fallback (G_GNUC_UNUSED GObject *self, 57 | const char *text, 58 | const char *fallback) 59 | { 60 | if (!kgx_str_non_empty (text)) { 61 | return g_strdup (fallback); 62 | } 63 | 64 | return g_strdup (text); 65 | } 66 | 67 | 68 | G_GNUC_UNUSED 69 | static GObject * 70 | kgx_object_or_fallback (G_GNUC_UNUSED GObject *self, 71 | GObject *object, 72 | GObject *fallback) 73 | { 74 | if (G_UNLIKELY (!object)) { 75 | return fallback ? g_object_ref (fallback) : NULL; 76 | } 77 | 78 | return g_object_ref (object); 79 | } 80 | 81 | 82 | G_GNUC_UNUSED 83 | static gboolean 84 | kgx_enum_is (G_GNUC_UNUSED GObject *self, 85 | int a, 86 | int b) 87 | { 88 | return a == b; 89 | } 90 | 91 | 92 | G_GNUC_UNUSED 93 | static gboolean 94 | kgx_flags_includes (G_GNUC_UNUSED GObject *self, 95 | guint a, 96 | guint b) 97 | { 98 | return (a & b) == b; 99 | } 100 | 101 | 102 | G_GNUC_UNUSED 103 | static gboolean 104 | kgx_bool_and (G_GNUC_UNUSED GObject *self, 105 | gboolean a, 106 | gboolean b) 107 | { 108 | return a && b; 109 | } 110 | 111 | 112 | G_GNUC_UNUSED 113 | static char * 114 | kgx_format_percentage (G_GNUC_UNUSED GObject *object, double scale) 115 | { 116 | return g_strdup_printf ("%i%%", (int) round (scale * 100)); 117 | } 118 | 119 | 120 | G_GNUC_UNUSED 121 | static GVariant * 122 | kgx_text_as_variant (G_GNUC_UNUSED GObject *self, const char *text) 123 | { 124 | if (!kgx_str_non_empty (text)) { 125 | return NULL; 126 | } 127 | 128 | return g_variant_ref_sink (g_variant_new_string (text)); 129 | } 130 | 131 | 132 | G_GNUC_UNUSED 133 | static gboolean 134 | kgx_text_non_empty (G_GNUC_UNUSED GObject *self, const char *text) 135 | { 136 | return kgx_str_non_empty (text); 137 | } 138 | 139 | 140 | G_GNUC_UNUSED 141 | static gboolean 142 | kgx_decoration_layout_is_inverted (G_GNUC_UNUSED GObject *object, 143 | const char *decoration_layout) 144 | { 145 | g_auto (GStrv) sides = g_strsplit (decoration_layout ? 146 | decoration_layout : "", 147 | ":", 148 | 2); 149 | int counts[2] = { 0 }; 150 | 151 | for (size_t i = 0; i < G_N_ELEMENTS (counts); i++) { 152 | g_auto (GStrv) elements = NULL; 153 | 154 | if (sides[i] == NULL) 155 | continue; 156 | 157 | elements = g_strsplit (sides[i], ",", -1); 158 | 159 | for (size_t j = 0; elements[j]; j++) { 160 | if (g_str_equal (elements[j], "close")) { 161 | counts[i]++; 162 | } 163 | } 164 | } 165 | 166 | return counts[0] > counts[1]; 167 | } 168 | 169 | 170 | G_END_DECLS 171 | -------------------------------------------------------------------------------- /src/kgx-simple-tab.h: -------------------------------------------------------------------------------- 1 | /* kgx-simple-tab.h 2 | * 3 | * Copyright 2019-2023 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "kgx-tab.h" 22 | 23 | G_BEGIN_DECLS 24 | 25 | #define KGX_TYPE_SIMPLE_TAB kgx_simple_tab_get_type () 26 | 27 | G_DECLARE_FINAL_TYPE (KgxSimpleTab, kgx_simple_tab, KGX, SIMPLE_TAB, KgxTab) 28 | 29 | 30 | G_END_DECLS 31 | -------------------------------------------------------------------------------- /src/kgx-simple-tab.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 35 | 36 | -------------------------------------------------------------------------------- /src/kgx-spad-source.c: -------------------------------------------------------------------------------- 1 | /* kgx-spad-source.c 2 | * 3 | * Copyright 2025 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include "kgx-config.h" 20 | 21 | #include 22 | 23 | #include "kgx-spad.h" 24 | #include "kgx-utils.h" 25 | #include "kgx-marshals.h" 26 | 27 | #include "kgx-spad-source.h" 28 | 29 | 30 | G_DEFINE_INTERFACE (KgxSpadSource, kgx_spad_source, G_TYPE_OBJECT) 31 | 32 | 33 | enum { 34 | SPAD_THROWN, 35 | N_SIGNALS 36 | }; 37 | static guint signals[N_SIGNALS]; 38 | 39 | 40 | static void 41 | kgx_spad_source_default_init (KgxSpadSourceInterface *iface) 42 | { 43 | signals[SPAD_THROWN] = g_signal_new ("spad-thrown", 44 | G_TYPE_FROM_INTERFACE (iface), 45 | G_SIGNAL_RUN_LAST, 46 | 0, 47 | g_signal_accumulator_true_handled, 48 | NULL, 49 | kgx_marshals_BOOLEAN__STRING_VARIANT, 50 | G_TYPE_BOOLEAN, 51 | 2, 52 | G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE, 53 | G_TYPE_VARIANT | G_SIGNAL_TYPE_STATIC_SCOPE); 54 | g_signal_set_va_marshaller (signals[SPAD_THROWN], 55 | G_TYPE_FROM_INTERFACE (iface), 56 | kgx_marshals_BOOLEAN__STRING_VARIANTv); 57 | } 58 | 59 | 60 | void 61 | kgx_spad_source_throw (KgxSpadSource *source, 62 | const char *title, 63 | KgxSpadFlags flags, 64 | const char *error_body, 65 | const char *error_content, 66 | GError *error) 67 | { 68 | g_autoptr (GVariant) bundle = kgx_spad_build_bundle (title, 69 | flags, 70 | error_body, 71 | error_content, 72 | error); 73 | gboolean handled = FALSE; 74 | 75 | g_return_if_fail (kgx_str_non_empty (error_body)); 76 | 77 | g_debug ("raising spad: %s", title); 78 | 79 | g_signal_emit (source, signals[SPAD_THROWN], 0, title, bundle, &handled); 80 | 81 | if (G_UNLIKELY (!handled)) { 82 | g_log_structured (G_LOG_DOMAIN, 83 | G_LOG_LEVEL_CRITICAL, 84 | "CODE_FILE", __FILE__, 85 | "CODE_LINE", G_STRINGIFY (__LINE__), 86 | "CODE_FUNC", G_STRFUNC, 87 | "KGX_SPAD_BODY", error_body, 88 | "KGX_SPAD_CONTENT", kgx_str_non_empty (error_content) ? 89 | error_content : "None", 90 | "KGX_SPAD_ERROR", error ? error->message : "None", 91 | "MESSAGE", "unhandled-spad: ‘%s’", 92 | title); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/kgx-spad-source.h: -------------------------------------------------------------------------------- 1 | /* kgx-spad-source.h 2 | * 3 | * Copyright 2025 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | #include "kgx-spad.h" 24 | 25 | G_BEGIN_DECLS 26 | 27 | #define KGX_TYPE_SPAD_SOURCE (kgx_spad_source_get_type ()) 28 | 29 | G_DECLARE_INTERFACE (KgxSpadSource, kgx_spad_source, KGX, SPAD_SOURCE, GObject) 30 | 31 | 32 | struct _KgxSpadSourceInterface { 33 | GTypeInterface g_iface; 34 | }; 35 | 36 | 37 | void kgx_spad_source_throw (KgxSpadSource *source, 38 | const char *title, 39 | KgxSpadFlags flags, 40 | const char *error_body, 41 | const char *error_content, 42 | GError *error); 43 | 44 | 45 | G_END_DECLS 46 | -------------------------------------------------------------------------------- /src/kgx-spad.h: -------------------------------------------------------------------------------- 1 | /* kgx-spad.h 2 | * 3 | * Copyright 2025 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | G_BEGIN_DECLS 24 | 25 | 26 | typedef enum /*< flags,prefix=KGX >*/ { 27 | KGX_SPAD_NONE = 0, /*< nick=none >*/ 28 | KGX_SPAD_SHOW_REPORT = (1 << 0), /*< nick=show-report >*/ 29 | KGX_SPAD_SHOW_SYS_INFO = (1 << 1), /*< nick=show-sys-info >*/ 30 | } KgxSpadFlags; 31 | 32 | 33 | #define KGX_TYPE_SPAD (kgx_spad_get_type ()) 34 | 35 | G_DECLARE_FINAL_TYPE (KgxSpad, kgx_spad, KGX, SPAD, AdwDialog) 36 | 37 | 38 | GVariant *kgx_spad_build_bundle (const char *title, 39 | KgxSpadFlags flags, 40 | const char *error_body, 41 | const char *error_content, 42 | GError *error); 43 | AdwDialog *kgx_spad_new_from_bundle (GVariant *bundle); 44 | 45 | 46 | G_END_DECLS 47 | -------------------------------------------------------------------------------- /src/kgx-spad.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 116 | -------------------------------------------------------------------------------- /src/kgx-system-info.c: -------------------------------------------------------------------------------- 1 | /* kgx-system-info.c 2 | * 3 | * Copyright 2024 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include "kgx-config.h" 20 | 21 | #include 22 | #include 23 | 24 | #include "kgx-system-info.h" 25 | 26 | #define INTERFACE_SETTINGS_SCHEMA "org.gnome.desktop.interface" 27 | #define MONOSPACE_FONT_KEY_NAME "monospace-font-name" 28 | 29 | 30 | struct _KgxSystemInfo { 31 | GObject parent; 32 | 33 | GSettings *desktop_interface; 34 | PangoFontDescription *monospace_font; 35 | }; 36 | 37 | G_DEFINE_FINAL_TYPE (KgxSystemInfo, kgx_system_info, G_TYPE_OBJECT) 38 | 39 | 40 | enum { 41 | PROP_0, 42 | PROP_MONOSPACE_FONT, 43 | LAST_PROP 44 | }; 45 | static GParamSpec *pspecs[LAST_PROP] = { NULL, }; 46 | 47 | 48 | static void 49 | kgx_system_info_dispose (GObject *object) 50 | { 51 | KgxSystemInfo *self = KGX_SYSTEM_INFO (object); 52 | 53 | g_clear_object (&self->desktop_interface); 54 | g_clear_pointer (&self->monospace_font, pango_font_description_free); 55 | 56 | G_OBJECT_CLASS (kgx_system_info_parent_class)->dispose (object); 57 | } 58 | 59 | 60 | static void 61 | kgx_system_info_get_property (GObject *object, 62 | guint property_id, 63 | GValue *value, 64 | GParamSpec *pspec) 65 | { 66 | KgxSystemInfo *self = KGX_SYSTEM_INFO (object); 67 | 68 | switch (property_id) { 69 | case PROP_MONOSPACE_FONT: 70 | g_value_set_boxed (value, self->monospace_font); 71 | break; 72 | default: 73 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); 74 | break; 75 | } 76 | } 77 | 78 | 79 | static void 80 | kgx_system_info_class_init (KgxSystemInfoClass *klass) 81 | { 82 | GObjectClass *object_class = G_OBJECT_CLASS (klass); 83 | 84 | object_class->dispose = kgx_system_info_dispose; 85 | object_class->get_property = kgx_system_info_get_property; 86 | 87 | pspecs[PROP_MONOSPACE_FONT] = g_param_spec_boxed ("monospace-font", NULL, NULL, 88 | PANGO_TYPE_FONT_DESCRIPTION, 89 | G_PARAM_READABLE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY); 90 | 91 | g_object_class_install_properties (object_class, LAST_PROP, pspecs); 92 | } 93 | 94 | 95 | static void 96 | monospace_changed (GSettings *settings, 97 | const char *key, 98 | KgxSystemInfo *self) 99 | { 100 | g_autofree char *font = g_settings_get_string (self->desktop_interface, 101 | MONOSPACE_FONT_KEY_NAME); 102 | 103 | g_clear_pointer (&self->monospace_font, pango_font_description_free); 104 | self->monospace_font = pango_font_description_from_string (font); 105 | 106 | g_object_notify_by_pspec (G_OBJECT (self), pspecs[PROP_MONOSPACE_FONT]); 107 | } 108 | 109 | 110 | static void 111 | kgx_system_info_init (KgxSystemInfo *self) 112 | { 113 | self->desktop_interface = g_settings_new (INTERFACE_SETTINGS_SCHEMA); 114 | g_signal_connect_object (self->desktop_interface, 115 | "changed::" MONOSPACE_FONT_KEY_NAME, G_CALLBACK (monospace_changed), 116 | self, G_CONNECT_DEFAULT); 117 | monospace_changed (self->desktop_interface, MONOSPACE_FONT_KEY_NAME, self); 118 | } 119 | -------------------------------------------------------------------------------- /src/kgx-system-info.h: -------------------------------------------------------------------------------- 1 | /* kgx-system-info.h 2 | * 3 | * Copyright 2024 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | G_BEGIN_DECLS 24 | 25 | #define KGX_TYPE_SYSTEM_INFO (kgx_system_info_get_type ()) 26 | 27 | G_DECLARE_FINAL_TYPE (KgxSystemInfo, kgx_system_info, KGX, SYSTEM_INFO, GObject) 28 | 29 | G_END_DECLS 30 | -------------------------------------------------------------------------------- /src/kgx-tab.h: -------------------------------------------------------------------------------- 1 | /* kgx-tab.h 2 | * 3 | * Copyright 2019-2024 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | #include "kgx-process.h" 24 | #include "kgx-train.h" 25 | 26 | G_BEGIN_DECLS 27 | 28 | 29 | #ifndef __GTK_DOC_IGNORE__ 30 | typedef struct _KgxPages KgxPages; 31 | #endif 32 | 33 | #define KGX_TYPE_TAB kgx_tab_get_type () 34 | 35 | G_DECLARE_DERIVABLE_TYPE (KgxTab, kgx_tab, KGX, TAB, AdwBin) 36 | 37 | 38 | /** 39 | * KgxTabClass: 40 | * @start: start whatever it is that run in the tab 41 | * @start_finish: complete @start 42 | * 43 | * Stability: Private 44 | */ 45 | struct _KgxTabClass { 46 | AdwBinClass parent; 47 | 48 | void (*start) (KgxTab *tab, 49 | GAsyncReadyCallback callback, 50 | gpointer callback_data); 51 | KgxTrain * (*start_finish) (KgxTab *tab, 52 | GAsyncResult *res, 53 | GError **error); 54 | 55 | void (*died) (KgxTab *self, 56 | GtkMessageType type, 57 | const char *message, 58 | gboolean success); 59 | void (*bell) (KgxTab *self); 60 | }; 61 | 62 | 63 | guint kgx_tab_get_id (KgxTab *self); 64 | void kgx_tab_start (KgxTab *self, 65 | GAsyncReadyCallback callback, 66 | gpointer callback_data); 67 | void kgx_tab_start_finish (KgxTab *self, 68 | GAsyncResult *res, 69 | GError **error); 70 | void kgx_tab_died (KgxTab *self, 71 | GtkMessageType type, 72 | const char *message, 73 | gboolean success); 74 | void kgx_tab_bell (KgxTab *self); 75 | KgxPages *kgx_tab_get_pages (KgxTab *self); 76 | gboolean kgx_tab_is_active (KgxTab *self); 77 | GPtrArray *kgx_tab_get_children (KgxTab *self); 78 | void kgx_tab_extra_drop (KgxTab *self, 79 | const GValue *value); 80 | void kgx_tab_set_initial_title (KgxTab *self, 81 | const char *title, 82 | GFile *path); 83 | void kgx_tab_mark_working (KgxTab *self); 84 | void kgx_tab_unmark_working (KgxTab *self); 85 | 86 | G_END_DECLS 87 | -------------------------------------------------------------------------------- /src/kgx-tab.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 109 | 110 | KgxTrain 111 | 112 | 113 | 114 | KgxTerminal 115 | 116 | 117 | 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /src/kgx-terminal.h: -------------------------------------------------------------------------------- 1 | /* kgx-terminal.h 2 | * 3 | * Copyright 2019-2023 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | #include 23 | 24 | G_BEGIN_DECLS 25 | 26 | /** 27 | * KgxZoom: 28 | * @KGX_ZOOM_IN: Make text bigger 29 | * @KGX_ZOOM_OUT: Shrink text 30 | * 31 | * Indicates the zoom direction the zoom action was triggered for 32 | * 33 | * See #KgxTab::zoom, #KgxPages::zoom 34 | */ 35 | typedef enum /*< enum,prefix=KGX >*/ { 36 | KGX_ZOOM_IN = 0, /*< nick=in >*/ 37 | KGX_ZOOM_OUT = 1, /*< nick=out >*/ 38 | } KgxZoom; 39 | 40 | 41 | #define KGX_TYPE_TERMINAL kgx_terminal_get_type() 42 | 43 | G_DECLARE_FINAL_TYPE (KgxTerminal, kgx_terminal, KGX, TERMINAL, VteTerminal) 44 | 45 | void kgx_terminal_accept_paste (KgxTerminal *self, 46 | const char *text); 47 | 48 | G_END_DECLS 49 | -------------------------------------------------------------------------------- /src/kgx-terminal.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | _Open Link 8 | term.open-link 9 | action-disabled 10 | 11 | 12 | Copy _Link Address 13 | term.copy-link 14 | action-disabled 15 | 16 |
17 |
18 | 19 | _Copy 20 | term.copy 21 | action-disabled 22 | 23 | 24 | _Paste 25 | term.paste 26 | action-disabled 27 | 28 | 29 | _Select All 30 | term.select-all 31 | action-disabled 32 | 33 |
34 |
35 | 36 | Show in _Files 37 | term.show-in-files 38 | action-disabled 39 | 40 |
41 |
42 | 131 |
132 | -------------------------------------------------------------------------------- /src/kgx-theme-switcher.c: -------------------------------------------------------------------------------- 1 | /* kgx-theme-switcher.c 2 | * 3 | * Copyright 2021 Purism SPC 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include "kgx-config.h" 20 | 21 | #include "kgx-settings.h" 22 | #include "kgx-shared-closures.h" 23 | 24 | #include "kgx-theme-switcher.h" 25 | 26 | 27 | struct _KgxThemeSwitcher { 28 | AdwBin parent_instance; 29 | 30 | KgxTheme theme; 31 | 32 | GtkWidget *system_selector; 33 | GtkWidget *light_selector; 34 | GtkWidget *dark_selector; 35 | }; 36 | 37 | 38 | G_DEFINE_TYPE (KgxThemeSwitcher, kgx_theme_switcher, ADW_TYPE_BIN) 39 | 40 | 41 | enum { 42 | PROP_0, 43 | PROP_THEME, 44 | LAST_PROP 45 | }; 46 | static GParamSpec *pspecs[LAST_PROP] = { NULL, }; 47 | 48 | 49 | static void 50 | theme_check_active_changed (KgxThemeSwitcher *self) 51 | { 52 | KgxTheme theme; 53 | 54 | if (gtk_check_button_get_active (GTK_CHECK_BUTTON (self->system_selector))) { 55 | theme = KGX_THEME_AUTO; 56 | } else if (gtk_check_button_get_active (GTK_CHECK_BUTTON (self->light_selector))) { 57 | theme = KGX_THEME_DAY; 58 | } else { 59 | theme = KGX_THEME_NIGHT; 60 | } 61 | 62 | if (theme == self->theme) { 63 | return; 64 | } 65 | 66 | self->theme = theme; 67 | g_object_notify_by_pspec (G_OBJECT (self), pspecs[PROP_THEME]); 68 | } 69 | 70 | 71 | static inline void 72 | set_theme (KgxThemeSwitcher *self, 73 | KgxTheme theme) 74 | { 75 | if (self->theme == theme) 76 | return; 77 | 78 | switch (theme) { 79 | case KGX_THEME_AUTO: 80 | gtk_check_button_set_active (GTK_CHECK_BUTTON (self->system_selector), TRUE); 81 | break; 82 | case KGX_THEME_DAY: 83 | gtk_check_button_set_active (GTK_CHECK_BUTTON (self->light_selector), TRUE); 84 | break; 85 | case KGX_THEME_NIGHT: 86 | case KGX_THEME_HACKER: 87 | default: 88 | gtk_check_button_set_active (GTK_CHECK_BUTTON (self->dark_selector), TRUE); 89 | break; 90 | } 91 | 92 | self->theme = theme; 93 | g_object_notify_by_pspec (G_OBJECT (self), pspecs[PROP_THEME]); 94 | } 95 | 96 | 97 | static void 98 | kgx_theme_switcher_get_property (GObject *object, 99 | guint prop_id, 100 | GValue *value, 101 | GParamSpec *pspec) 102 | { 103 | KgxThemeSwitcher *self = KGX_THEME_SWITCHER (object); 104 | 105 | switch (prop_id) { 106 | case PROP_THEME: 107 | g_value_set_enum (value, self->theme); 108 | break; 109 | KGX_INVALID_PROP (object, prop_id, pspec); 110 | } 111 | } 112 | 113 | 114 | static void 115 | kgx_theme_switcher_set_property (GObject *object, 116 | guint prop_id, 117 | const GValue *value, 118 | GParamSpec *pspec) 119 | { 120 | KgxThemeSwitcher *self = KGX_THEME_SWITCHER (object); 121 | 122 | switch (prop_id) { 123 | case PROP_THEME: 124 | set_theme (self, g_value_get_enum (value)); 125 | break; 126 | KGX_INVALID_PROP (object, prop_id, pspec); 127 | } 128 | } 129 | 130 | 131 | static void 132 | kgx_theme_switcher_class_init (KgxThemeSwitcherClass *klass) 133 | { 134 | GObjectClass *object_class = G_OBJECT_CLASS (klass); 135 | GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); 136 | 137 | object_class->get_property = kgx_theme_switcher_get_property; 138 | object_class->set_property = kgx_theme_switcher_set_property; 139 | 140 | pspecs[PROP_THEME] = 141 | g_param_spec_enum ("theme", NULL, NULL, 142 | KGX_TYPE_THEME, 143 | KGX_THEME_NIGHT, 144 | G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); 145 | 146 | g_object_class_install_properties (object_class, LAST_PROP, pspecs); 147 | 148 | gtk_widget_class_set_template_from_resource (widget_class, 149 | KGX_APPLICATION_PATH "kgx-theme-switcher.ui"); 150 | 151 | gtk_widget_class_bind_template_child (widget_class, KgxThemeSwitcher, system_selector); 152 | gtk_widget_class_bind_template_child (widget_class, KgxThemeSwitcher, light_selector); 153 | gtk_widget_class_bind_template_child (widget_class, KgxThemeSwitcher, dark_selector); 154 | 155 | gtk_widget_class_bind_template_callback (widget_class, theme_check_active_changed); 156 | gtk_widget_class_bind_template_callback (widget_class, kgx_style_manager_for_display); 157 | 158 | gtk_widget_class_set_css_name (widget_class, "themeswitcher"); 159 | gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT); 160 | } 161 | 162 | 163 | static void 164 | kgx_theme_switcher_init (KgxThemeSwitcher *self) 165 | { 166 | gtk_widget_init_template (GTK_WIDGET (self)); 167 | } 168 | -------------------------------------------------------------------------------- /src/kgx-theme-switcher.h: -------------------------------------------------------------------------------- 1 | /* kgx-theme-switcher.h 2 | * 3 | * Copyright 2021 Purism SPC 4 | * Copyright 2023 Zander Brown 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | G_BEGIN_DECLS 25 | 26 | #define KGX_TYPE_THEME_SWITCHER (kgx_theme_switcher_get_type ()) 27 | 28 | G_DECLARE_FINAL_TYPE (KgxThemeSwitcher, kgx_theme_switcher, KGX, THEME_SWITCHER, AdwBin) 29 | 30 | 31 | G_END_DECLS 32 | -------------------------------------------------------------------------------- /src/kgx-theme-switcher.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 104 | 105 | -------------------------------------------------------------------------------- /src/kgx-train.h: -------------------------------------------------------------------------------- 1 | /* kgx-train.h 2 | * 3 | * Copyright 2021-2024 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | #include "kgx-process.h" 24 | 25 | G_BEGIN_DECLS 26 | 27 | 28 | /** 29 | * KgxStatus: 30 | * @KGX_NONE: It's a regular #KgxTab 31 | * @KGX_REMOTE: The #KgxTab is connected to a "remote" session 32 | * @KGX_PRIVILEGED: The #KgxTab is running as someone other than the current 33 | * user 34 | * 35 | * Indicates the status of the session the #KgxTab represents 36 | */ 37 | typedef enum /*< flags,prefix=KGX >*/ { 38 | KGX_NONE = 0, /*< nick=none >*/ 39 | KGX_REMOTE = (1 << 0), /*< nick=remote >*/ 40 | KGX_PRIVILEGED = (1 << 1), /*< nick=privileged >*/ 41 | } KgxStatus; 42 | 43 | 44 | struct _KgxTrainClass { 45 | GObjectClass parent; 46 | }; 47 | 48 | #define KGX_TYPE_TRAIN (kgx_train_get_type ()) 49 | 50 | G_DECLARE_DERIVABLE_TYPE (KgxTrain, kgx_train, KGX, TRAIN, GObject) 51 | 52 | const char *kgx_train_get_uuid (KgxTrain *self); 53 | const char *kgx_train_get_tag (KgxTrain *self); 54 | GPid kgx_train_get_pid (KgxTrain *self); 55 | GPtrArray *kgx_train_get_children (KgxTrain *self); 56 | void kgx_train_push_child (KgxTrain *self, 57 | KgxProcess *process); 58 | void kgx_train_pop_child (KgxTrain *self, 59 | KgxProcess *process); 60 | 61 | G_END_DECLS 62 | -------------------------------------------------------------------------------- /src/kgx-watcher.h: -------------------------------------------------------------------------------- 1 | /* kgx-watcher.h 2 | * 3 | * Copyright 2022-2024 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | #include "kgx-train.h" 24 | 25 | G_BEGIN_DECLS 26 | 27 | #define KGX_TYPE_WATCHER (kgx_watcher_get_type ()) 28 | 29 | G_DECLARE_FINAL_TYPE (KgxWatcher, kgx_watcher, KGX, WATCHER, GObject) 30 | 31 | void kgx_watcher_watch (KgxWatcher *self, 32 | KgxTrain *train); 33 | 34 | G_END_DECLS 35 | -------------------------------------------------------------------------------- /src/kgx-window.h: -------------------------------------------------------------------------------- 1 | /* kgx-window.h 2 | * 3 | * Copyright 2019-2023 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | #include "kgx-tab.h" 24 | 25 | G_BEGIN_DECLS 26 | 27 | #define KGX_WINDOW_STYLE_ROOT "root" 28 | #define KGX_WINDOW_STYLE_REMOTE "remote" 29 | #define KGX_WINDOW_STYLE_RINGING "bell" 30 | 31 | 32 | #define KGX_TYPE_WINDOW (kgx_window_get_type ()) 33 | 34 | struct _KgxWindowClass { 35 | AdwApplicationWindowClass parent; 36 | }; 37 | 38 | G_DECLARE_DERIVABLE_TYPE (KgxWindow, kgx_window, KGX, WINDOW, AdwApplicationWindow) 39 | 40 | GFile *kgx_window_get_working_dir (KgxWindow *self); 41 | void kgx_window_add_tab (KgxWindow *self, 42 | KgxTab *tab); 43 | 44 | G_END_DECLS 45 | -------------------------------------------------------------------------------- /src/kgx.gresource.xml.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | kgx-empty.ui 5 | kgx-page-expression.ui 6 | kgx-pages.ui 7 | kgx-simple-tab.ui 8 | kgx-spad.ui 9 | kgx-tab.ui 10 | kgx-terminal.ui 11 | kgx-theme-switcher.ui 12 | kgx-window.ui 13 | preferences/kgx-font-picker.ui 14 | preferences/kgx-preferences-window.ui 15 | style.css 16 | style-dark.css 17 | logo.txt 18 | icons/scalable/status/bell-outline-symbolic.svg 19 | icons/scalable/status/emblem-ok-symbolic.svg 20 | icons/scalable/status/external-link-symbolic.svg 21 | icons/scalable/status/status-privileged-symbolic.svg 22 | icons/scalable/status/status-regular-symbolic.svg 23 | icons/scalable/status/status-remote-symbolic.svg 24 | icons/scalable/status/theme-check-symbolic.svg 25 | 26 | 27 | help-overlay.ui 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- 1 | /* main.c 2 | * 3 | * Copyright 2019-2025 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include "kgx-config.h" 20 | 21 | #include 22 | 23 | #include 24 | 25 | #include "kgx-application.h" 26 | #include "kgx-locale.h" 27 | 28 | 29 | int 30 | main (int argc, char *argv[]) 31 | { 32 | g_autoptr (GtkApplication) app = NULL; 33 | 34 | kgx_locale_init (KGX_LOCALE_DYNAMIC); 35 | 36 | g_set_prgname (KGX_BIN_NAME); 37 | g_set_application_name (KGX_DISPLAY_NAME); 38 | gtk_window_set_default_icon_name (KGX_APPLICATION_ID); 39 | 40 | app = g_object_new (KGX_TYPE_APPLICATION, 41 | "application_id", KGX_APPLICATION_ID, 42 | "version", PACKAGE_VERSION, 43 | "flags", G_APPLICATION_HANDLES_COMMAND_LINE | 44 | G_APPLICATION_HANDLES_OPEN | 45 | G_APPLICATION_SEND_ENVIRONMENT | 46 | G_APPLICATION_CAN_OVERRIDE_APP_ID, 47 | "register-session", TRUE, 48 | NULL); 49 | 50 | return g_application_run (G_APPLICATION (app), argc, argv); 51 | } 52 | -------------------------------------------------------------------------------- /src/meson.build: -------------------------------------------------------------------------------- 1 | kgx_config_dep = declare_dependency( 2 | sources: [configure_file(output: 'kgx-config.h', configuration: conf)], 3 | include_directories: '.', 4 | ) 5 | 6 | subdir('pids') 7 | 8 | kgx_sources = files( 9 | 'kgx-about.c', 10 | 'kgx-about.h', 11 | 'kgx-application.c', 12 | 'kgx-application.h', 13 | 'kgx-close-dialog.c', 14 | 'kgx-close-dialog.h', 15 | 'kgx-colour-utils.c', 16 | 'kgx-colour-utils.h', 17 | 'kgx-depot.c', 18 | 'kgx-depot.h', 19 | 'kgx-despatcher.c', 20 | 'kgx-despatcher.h', 21 | 'kgx-drop-target.c', 22 | 'kgx-drop-target.h', 23 | 'kgx-empty.c', 24 | 'kgx-empty.h', 25 | 'kgx-file-closures.h', 26 | 'kgx-icon-closures.h', 27 | 'kgx-livery-manager.c', 28 | 'kgx-livery-manager.h', 29 | 'kgx-livery.c', 30 | 'kgx-livery.h', 31 | 'kgx-locale.h', 32 | 'kgx-pages.c', 33 | 'kgx-pages.h', 34 | 'kgx-palette.c', 35 | 'kgx-palette.h', 36 | 'kgx-paste-dialog.c', 37 | 'kgx-paste-dialog.h', 38 | 'kgx-process.c', 39 | 'kgx-process.h', 40 | 'kgx-proxy-info.c', 41 | 'kgx-proxy-info.h', 42 | 'kgx-settings.c', 43 | 'kgx-settings.h', 44 | 'kgx-shared-closures.h', 45 | 'kgx-simple-tab.c', 46 | 'kgx-simple-tab.h', 47 | 'kgx-spad-source.c', 48 | 'kgx-spad-source.h', 49 | 'kgx-spad.c', 50 | 'kgx-spad.h', 51 | 'kgx-system-info.c', 52 | 'kgx-system-info.h', 53 | 'kgx-tab.c', 54 | 'kgx-tab.h', 55 | 'kgx-terminal.c', 56 | 'kgx-terminal.h', 57 | 'kgx-theme-switcher.c', 58 | 'kgx-theme-switcher.h', 59 | 'kgx-train.c', 60 | 'kgx-train.h', 61 | 'kgx-utils.c', 62 | 'kgx-utils.h', 63 | 'kgx-watcher.c', 64 | 'kgx-watcher.h', 65 | 'kgx-window.c', 66 | 'kgx-window.h', 67 | 'preferences/kgx-font-picker.c', 68 | 'preferences/kgx-font-picker.h', 69 | 'preferences/kgx-preferences-window.c', 70 | 'preferences/kgx-preferences-window.h', 71 | ) 72 | 73 | kgx_deps = [ 74 | gio_dep, 75 | gio_unix_dep, 76 | pango_dep, 77 | gtk_dep, 78 | adw_dep, 79 | vte_dep, 80 | pcre_dep, 81 | schemas_dep, 82 | kgx_pids_dep, 83 | kgx_config_dep, 84 | cc.find_library('m', required: false), 85 | ] 86 | 87 | kgx_generated_sources = [ 88 | vcs_tag( 89 | input: 'kgx-git-tag.h.in', 90 | output: 'kgx-git-tag.h', 91 | command: ['git', 'rev-parse', '--short', 'HEAD'], 92 | fallback: vcs_tag_fallback, 93 | ), 94 | gnome.compile_resources( 95 | 'kgx-resources', 96 | configure_file( 97 | input: 'kgx.gresource.xml.in', 98 | output: 'kgx.gresource.xml', 99 | configuration: conf, 100 | ), 101 | c_name: 'kgx', 102 | ), 103 | gnome.genmarshal( 104 | 'kgx-marshals', 105 | sources: 'kgx-marshals.list', 106 | internal: true, 107 | prefix: 'kgx_marshals', 108 | valist_marshallers: true, 109 | ), 110 | gnome.gdbus_codegen( 111 | 'xdg-fm1', 112 | sources: 'org.freedesktop.FileManager1.xml', 113 | interface_prefix: 'org.freedesktop.', 114 | namespace: 'Xdg', 115 | ), 116 | gnome.mkenums_simple( 117 | 'kgx-enums', 118 | sources: files( 119 | 'kgx-close-dialog.h', 120 | 'kgx-colour-utils.h', 121 | 'kgx-paste-dialog.h', 122 | 'kgx-settings.h', 123 | 'kgx-spad.h', 124 | 'kgx-terminal.h', 125 | 'kgx-train.h', 126 | 'kgx-utils.h', 127 | ), 128 | ), 129 | ] 130 | 131 | kgx_lib = static_library( 132 | bin_name, 133 | kgx_sources + kgx_generated_sources, 134 | dependencies: kgx_deps, 135 | c_args: kgx_cargs, 136 | install: false, 137 | gnu_symbol_visibility: 'internal', 138 | ) 139 | 140 | kgx_dep = declare_dependency( 141 | sources: [kgx_generated_sources, kgx_schemas], 142 | include_directories: '.', 143 | link_with: kgx_lib, 144 | dependencies: kgx_deps, 145 | ) 146 | 147 | executable( 148 | bin_name, 149 | 'main.c', 150 | dependencies: kgx_dep, 151 | c_args: kgx_cargs, 152 | install: true, 153 | gnu_symbol_visibility: 'internal', 154 | ) 155 | -------------------------------------------------------------------------------- /src/org.freedesktop.FileManager1.xml: -------------------------------------------------------------------------------- 1 | 4 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/pids/kgx-gtop.c: -------------------------------------------------------------------------------- 1 | /* kgx-gtop.c 2 | * 3 | * Copyright 2025 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include "kgx-config.h" 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "kgx-gtop.h" 27 | 28 | 29 | KgxPidsResult 30 | kgx_gtop_get_pid_status (GPid pid, GPid *parent, uid_t *euid) 31 | { 32 | glibtop_proc_uid info; 33 | 34 | glibtop_get_proc_uid (&info, pid); 35 | 36 | *parent = info.ppid; 37 | *euid = info.euid; 38 | 39 | return KGX_PIDS_OK; 40 | } 41 | 42 | 43 | KgxPidsResult 44 | kgx_gtop_get_cmdline (GPid pid, GStrv *args) 45 | { 46 | glibtop_proc_args args_size; 47 | 48 | *args = glibtop_get_proc_argv (&args_size, pid, 0); 49 | 50 | return KGX_PIDS_OK; 51 | } 52 | 53 | 54 | KgxPidsResult 55 | kgx_gtop_get_list (GPid **pids, size_t *n_pids) 56 | { 57 | glibtop_proclist pid_list; 58 | GPid *res = glibtop_get_proclist (&pid_list, GLIBTOP_KERN_PROC_ALL, 0); 59 | 60 | if (G_UNLIKELY (res == NULL)) { 61 | *pids = NULL; 62 | *n_pids = 0; 63 | 64 | return KGX_PIDS_ERR; 65 | } 66 | 67 | *pids = res; 68 | *n_pids = pid_list.number; 69 | 70 | return KGX_PIDS_OK; 71 | } 72 | -------------------------------------------------------------------------------- /src/pids/kgx-gtop.h: -------------------------------------------------------------------------------- 1 | /* kgx-gtop.h 2 | * 3 | * Copyright 2025 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | #include 23 | 24 | #include "kgx-pids-enums.h" 25 | #include "kgx-pids.h" 26 | 27 | G_BEGIN_DECLS 28 | 29 | KgxPidsResult kgx_gtop_get_pid_status (GPid pid, 30 | GPid *parent, 31 | uid_t *euid); 32 | KgxPidsResult kgx_gtop_get_cmdline (GPid pid, 33 | GStrv *args); 34 | KgxPidsResult kgx_gtop_get_list (GPid **pids, 35 | size_t *n_pids); 36 | 37 | G_END_DECLS 38 | -------------------------------------------------------------------------------- /src/pids/kgx-pids.c: -------------------------------------------------------------------------------- 1 | /* kgx-pids.c 2 | * 3 | * Copyright 2025 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include "kgx-config.h" 20 | 21 | #include "kgx-gtop.h" 22 | 23 | #include "kgx-pids.h" 24 | 25 | 26 | KgxPidsResult 27 | kgx_pids_get_pid_info (GPid pid, 28 | GPid *parent, 29 | uid_t *euid) 30 | { 31 | return kgx_gtop_get_pid_status (pid, parent, euid); 32 | } 33 | 34 | 35 | KgxPidsResult 36 | kgx_pids_get_pid_cmdline (GPid pid, 37 | GStrv *args) 38 | { 39 | return kgx_gtop_get_cmdline (pid, args); 40 | } 41 | 42 | 43 | KgxPidsResult 44 | kgx_pids_get_running_pids (GPid **pids, 45 | size_t *n_pids) 46 | { 47 | return kgx_gtop_get_list (pids, n_pids); 48 | } 49 | -------------------------------------------------------------------------------- /src/pids/kgx-pids.h: -------------------------------------------------------------------------------- 1 | /* kgx-pids.h 2 | * 3 | * Copyright 2025 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | #include 23 | 24 | #include "kgx-pids-enums.h" 25 | 26 | G_BEGIN_DECLS 27 | 28 | typedef enum { 29 | KGX_PIDS_OK, 30 | KGX_PIDS_ERR, 31 | } KgxPidsResult; 32 | 33 | 34 | KgxPidsResult kgx_pids_get_pid_info (GPid pid, 35 | GPid *parent, 36 | uid_t *euid); 37 | KgxPidsResult kgx_pids_get_pid_cmdline (GPid pid, 38 | GStrv *args); 39 | KgxPidsResult kgx_pids_get_running_pids (GPid **pids, 40 | size_t *n_pids); 41 | 42 | G_END_DECLS 43 | -------------------------------------------------------------------------------- /src/pids/meson.build: -------------------------------------------------------------------------------- 1 | kgx_pids_sources = files('kgx-gtop.c', 'kgx-gtop.h', 'kgx-pids.c', 'kgx-pids.h') 2 | 3 | kgx_pids_enum_sources = files('kgx-pids.h') 4 | 5 | kgx_pids_enums = gnome.mkenums_simple( 6 | 'kgx-pids-enums', 7 | sources: kgx_pids_enum_sources, 8 | ) 9 | 10 | kgx_pids_lib = static_library( 11 | '@0@-pids'.format(bin_name), 12 | kgx_pids_sources + kgx_pids_enums, 13 | dependencies: [kgx_config_dep, gtop_dep, gio_unix_dep], 14 | c_args: kgx_cargs, 15 | install: false, 16 | gnu_symbol_visibility: 'internal', 17 | ) 18 | kgx_pids_inc = include_directories('.') 19 | 20 | kgx_pids_dep = declare_dependency( 21 | sources: [kgx_pids_enums], 22 | include_directories: kgx_pids_inc, 23 | link_with: kgx_pids_lib, 24 | dependencies: [kgx_config_dep, gtop_dep, gio_unix_dep], 25 | ) 26 | -------------------------------------------------------------------------------- /src/preferences/kgx-font-picker.h: -------------------------------------------------------------------------------- 1 | /* kgx-font-picker.h 2 | * 3 | * Copyright 2023 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | G_BEGIN_DECLS 24 | 25 | #define KGX_TYPE_FONT_PICKER (kgx_font_picker_get_type ()) 26 | 27 | G_DECLARE_FINAL_TYPE (KgxFontPicker, kgx_font_picker, KGX, FONT_PICKER, AdwNavigationPage) 28 | 29 | 30 | G_END_DECLS 31 | -------------------------------------------------------------------------------- /src/preferences/kgx-preferences-window.h: -------------------------------------------------------------------------------- 1 | /* kgx-preferences-window.h 2 | * 3 | * Copyright 2023 Maximiliano Sandoval 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | G_BEGIN_DECLS 24 | 25 | #define KGX_TYPE_PREFERENCES_WINDOW (kgx_preferences_window_get_type ()) 26 | 27 | G_DECLARE_FINAL_TYPE (KgxPreferencesWindow, kgx_preferences_window, KGX, PREFERENCES_WINDOW, AdwPreferencesDialog) 28 | 29 | 30 | G_END_DECLS 31 | -------------------------------------------------------------------------------- /src/preferences/kgx-preferences-window.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 110 | 111 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /src/rgba.h: -------------------------------------------------------------------------------- 1 | /** 2 | * SECTION:rgba 3 | * @title: RGBA 4 | * @short_description: #GdkRGBA utils 5 | * @include: rgba.h 6 | * @author: chergert 7 | * 8 | * https://gist.github.com/chergert/acc7f41c4d5a45ba254188bb19764f72 9 | */ 10 | 11 | #pragma once 12 | 13 | #include 14 | 15 | # define _GDK_RGBA_DECODE(c) ((unsigned)((c >= 'A' && c <= 'F') ? (c-'A'+10) : (c >= 'a' && c <= 'f') ? (c-'a'+10) : (c >= '0' && c <= '9') ? (c-'0') : -1)) 16 | # define _GDK_RGBA_HIGH(c) (_GDK_RGBA_DECODE(c) << 4) 17 | # define _GDK_RGBA_LOW(c) _GDK_RGBA_DECODE(c) 18 | # define _GDK_RGBA(r,g,b,a) ((GdkRGBA){(r)/255.,(g)/255.,(b)/255.,(a)/255.}) 19 | # define _GDK_RGBA8(str) \ 20 | _GDK_RGBA(_GDK_RGBA_HIGH(str[0]) | _GDK_RGBA_LOW(str[1]), \ 21 | _GDK_RGBA_HIGH(str[2]) | _GDK_RGBA_LOW(str[3]), \ 22 | _GDK_RGBA_HIGH(str[4]) | _GDK_RGBA_LOW(str[5]), \ 23 | _GDK_RGBA_HIGH(str[6]) | _GDK_RGBA_LOW(str[7])) 24 | # define _GDK_RGBA6(str) \ 25 | _GDK_RGBA(_GDK_RGBA_HIGH(str[0]) | _GDK_RGBA_LOW(str[1]), \ 26 | _GDK_RGBA_HIGH(str[2]) | _GDK_RGBA_LOW(str[3]), \ 27 | _GDK_RGBA_HIGH(str[4]) | _GDK_RGBA_LOW(str[5]), \ 28 | 0xFF) 29 | # define _GDK_RGBA4(str) \ 30 | _GDK_RGBA(_GDK_RGBA_HIGH(str[0]) | _GDK_RGBA_LOW(str[0]), \ 31 | _GDK_RGBA_HIGH(str[1]) | _GDK_RGBA_LOW(str[1]), \ 32 | _GDK_RGBA_HIGH(str[2]) | _GDK_RGBA_LOW(str[2]), \ 33 | _GDK_RGBA_HIGH(str[3]) | _GDK_RGBA_LOW(str[3])) 34 | # define _GDK_RGBA3(str) \ 35 | _GDK_RGBA(_GDK_RGBA_HIGH(str[0]) | _GDK_RGBA_LOW(str[0]), \ 36 | _GDK_RGBA_HIGH(str[1]) | _GDK_RGBA_LOW(str[1]), \ 37 | _GDK_RGBA_HIGH(str[2]) | _GDK_RGBA_LOW(str[2]), \ 38 | 0xFF) 39 | /** 40 | * GDK_RGBA: 41 | * @str: Hex string 42 | * 43 | * Compile time parsing of hex encoded colours 44 | */ 45 | # define GDK_RGBA(str) ((sizeof(str) == 9) ? _GDK_RGBA8(str) : \ 46 | (sizeof(str) == 7) ? _GDK_RGBA6(str) : \ 47 | (sizeof(str) == 5) ? _GDK_RGBA4(str) : \ 48 | (sizeof(str) == 4) ? _GDK_RGBA3(str) : \ 49 | ((GdkRGBA){0,0,0,0})) 50 | -------------------------------------------------------------------------------- /src/style-dark.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --headerbar-bg-oklch: 0.32 calc(c * 0.32) h; 3 | --headerbar-backdrop-oklch: 0.27 calc(c * 0.27) h; 4 | --headerbar-bell-oklch: 0.42 calc(c * 0.6) h; 5 | } 6 | -------------------------------------------------------------------------------- /src/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --headerbar-bg-oklch: 0.95 calc(c * 0.3) h; 3 | --headerbar-backdrop-oklch: 0.9 calc(c * 0.25) h; 4 | --headerbar-bell-oklch: 1 c h; 5 | --system-accent: var(--accent-bg-color); 6 | } 7 | 8 | @keyframes bell { 9 | 50% { 10 | background-color: oklch(from var(--accent-orange) var(--headerbar-bell-oklch)); 11 | } 12 | } 13 | 14 | kgx-tab .top-bar { 15 | background-image: none; 16 | background-color: var(--view-bg-color); 17 | color: var(--view-fg-color); 18 | } 19 | 20 | .terminal-window.translucent { 21 | background: transparent; 22 | } 23 | 24 | .terminal-window.root { 25 | --headerbar-bg-color: oklch(from var(--accent-red) var(--headerbar-bg-oklch)); 26 | --headerbar-backdrop-color: oklch(from var(--accent-red) var(--headerbar-backdrop-oklch)); 27 | } 28 | 29 | .terminal-window.remote { 30 | --headerbar-bg-color: oklch(from var(--accent-purple) var(--headerbar-bg-oklch)); 31 | --headerbar-backdrop-color: oklch(from var(--accent-purple) var(--headerbar-backdrop-oklch)); 32 | } 33 | 34 | .terminal-window.root .top-bar.raised, 35 | .terminal-window.remote .top-bar.raised { 36 | --accent-bg-color: color-mix(in srgb, currentColor 75%, transparent); 37 | --accent-color: oklab(from var(--accent-bg-color) var(--standalone-color-oklab)); 38 | } 39 | 40 | .terminal-window.root .top-bar.raised popover, 41 | .terminal-window.remote .top-bar.raised popover { 42 | --accent-bg-color: var(--system-accent); 43 | --accent-color: oklab(from var(--accent-bg-color) var(--standalone-color-oklab)); 44 | } 45 | 46 | .terminal-window.bell .top-bar.raised { 47 | animation: bell 0.5s ease-out; 48 | } 49 | 50 | .terminal-window vte-terminal { 51 | padding-left: 6px; 52 | padding-right: 6px; 53 | } 54 | 55 | /* Taken from nautilus */ 56 | .floating-bar { 57 | padding: 3px 8px; 58 | background-color: var(--view-bg-color); 59 | color: var(--view-fg-color); 60 | box-shadow: inset 0 100px 0 0 color-mix(in srgb, currentColor 5%, transparent); 61 | margin: 4px; 62 | border-radius: 8px; 63 | } 64 | 65 | .floating-bar:backdrop { 66 | opacity: 0.7; 67 | } 68 | 69 | kgx-empty { 70 | background: var(--view-bg-color); 71 | color: color-mix(in srgb, var(--view-fg-color) var(--dim-opacity), transparent); 72 | } 73 | 74 | .exit-info { 75 | padding: 6px; 76 | border-top: 2px solid var(--accent-bg-color); 77 | background: oklch(from var(--accent-bg-color) l calc(c * 2) h / 20%); 78 | } 79 | 80 | .process-list row .header { 81 | min-height: 0; 82 | } 83 | 84 | .process-list row .title { 85 | font-family: monospace; 86 | } 87 | 88 | themeswitcher { 89 | padding: 6px; 90 | } 91 | 92 | themeswitcher .check { 93 | background: var(--accent-bg-color); 94 | color: var(--accent-fg-color); 95 | padding: 2px; 96 | border-radius: 17px; 97 | margin: 3px; 98 | } 99 | 100 | /* Adapted from https://gitlab.gnome.org/GNOME/gnome-text-editor/-/blob/bf8c0c249f06a0be69e65aed3b786ba02a9f999e/src/TextEditor.css#L51 */ 101 | 102 | themeswitcher checkbutton { 103 | outline-offset: 1px; 104 | transition: none; 105 | } 106 | 107 | themeswitcher checkbutton radio { 108 | -gtk-icon-source: none; 109 | background: none; 110 | padding: 12px; 111 | min-height: 24px; 112 | min-width: 24px; 113 | border: none; 114 | outline-color: currentColor; 115 | transition: none; 116 | box-shadow: inset 0 0 0 1px var(--border-color); 117 | 118 | --light-bg: white; 119 | --dark-bg: #1e1e1e; 120 | } 121 | 122 | themeswitcher checkbutton radio:checked { 123 | box-shadow: inset 0 0 0 2px var(--accent-bg-color); 124 | } 125 | 126 | themeswitcher checkbutton.system radio { 127 | background: linear-gradient(-45deg, var(--dark-bg) 49.99%, var(--light-bg) 50.01%); 128 | } 129 | 130 | themeswitcher checkbutton.light radio { 131 | background-color: var(--light-bg); 132 | } 133 | 134 | themeswitcher checkbutton.dark radio { 135 | background-color: var(--dark-bg); 136 | } 137 | 138 | .font-picker { 139 | margin: 6px; 140 | } 141 | 142 | .font-picker .font-item { 143 | margin: 6px; 144 | } 145 | 146 | /* Remove default adwaita style */ 147 | kgx-tab:drop(active):focus, 148 | kgx-tab:drop(active) { 149 | box-shadow: none; 150 | } 151 | 152 | /* Drag overlay */ 153 | .drop-highlight { 154 | border-radius: 8px; 155 | background-color: color-mix(in srgb, var(--accent-bg-color) 35%, transparent); 156 | margin: 24px; 157 | } 158 | 159 | dialog.error-details textview { 160 | background: none; 161 | color: inherit; 162 | } 163 | 164 | .error-message { 165 | padding: 12px; 166 | font-size: 0.95em; 167 | } 168 | -------------------------------------------------------------------------------- /subprojects/adwaita.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | directory = adwaita 3 | url = https://gitlab.gnome.org/GNOME/libadwaita.git 4 | push-url = ssh://git@ssh.gitlab.gnome.org:GNOME/libadwaita.git 5 | revision = main 6 | depth = 1 7 | 8 | [provide] 9 | libadwaita-1 = libadwaita_dep 10 | -------------------------------------------------------------------------------- /subprojects/glib.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | directory = glib 3 | url = https://gitlab.gnome.org/GNOME/glib.git 4 | push-url = ssh://git@ssh.gitlab.gnome.org:GNOME/glib.git 5 | revision = main 6 | depth = 1 7 | 8 | [provide] 9 | dependency_names = gthread-2.0, gobject-2.0, gmodule-no-export-2.0, gmodule-export-2.0, gmodule-2.0, glib-2.0, gio-2.0, gio-windows-2.0, gio-unix-2.0 10 | program_names = glib-genmarshal, glib-mkenums, glib-compile-schemas, glib-compile-resources, gio-querymodules, gdbus-codegen 11 | -------------------------------------------------------------------------------- /subprojects/gtk.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | directory = gtk 3 | url = https://gitlab.gnome.org/GNOME/gtk.git 4 | push-url = ssh://git@ssh.gitlab.gnome.org:GNOME/gtk.git 5 | revision = main 6 | depth = 1 7 | 8 | [provide] 9 | dependency_names = gtk4, gtk4-wayland, gtk4-x11 10 | program_names = gtk4-update-icon-cache, gtk4-builder-tool, gtk4-query-settings, gtk4-encode-symbolic-svg 11 | -------------------------------------------------------------------------------- /subprojects/pango.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | directory = pango 3 | url = https://gitlab.gnome.org/GNOME/pango.git 4 | push-url = ssh://git@ssh.gitlab.gnome.org:GNOME/pango.git 5 | revision = main 6 | depth = 1 7 | 8 | [provide] 9 | dependency_names = pango 10 | -------------------------------------------------------------------------------- /subprojects/vte.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | directory = vte 3 | url = https://gitlab.gnome.org/GNOME/vte.git 4 | push-url = ssh://git@ssh.gitlab.gnome.org:GNOME/vte.git 5 | revision = master 6 | depth = 1 7 | 8 | [provide] 9 | vte-2.91-gtk4=libvte_gtk4_dep 10 | -------------------------------------------------------------------------------- /tests/meson.build: -------------------------------------------------------------------------------- 1 | tests = [ 2 | 'colour-utils', 3 | 'empty', 4 | 'file-closures', 5 | 'icon-closures', 6 | 'livery', 7 | 'locale', 8 | 'palette', 9 | 'settings', 10 | 'shared-closures', 11 | 'spad-source', 12 | 'spad', 13 | 'tab', 14 | 'theme-switcher', 15 | 'utils', 16 | ] 17 | 18 | test_env = { 19 | 'G_DEBUG': 'gc-friendly,fatal-warnings', 20 | 'G_ENABLE_DIAGNOSTIC': '1', 21 | 'G_TEST_BUILDDIR': meson.current_build_dir(), 22 | 'G_TEST_SRCDIR': meson.current_source_dir(), 23 | 'GDK_DEBUG': 'no-portals', 24 | 'GDK_DISABLE': 'vulkan', 25 | 'GIO_USE_VFS': 'local', 26 | 'GSETTINGS_BACKEND': 'memory', 27 | 'GSETTINGS_SCHEMA_DIR': meson.project_build_root() / 'data', 28 | 'GTK_A11Y': 'test', 29 | 'MALLOC_CHECK_': '2', 30 | 'NO_AT_BRIDGE': '1', 31 | 'PYTHONDEVMODE': '1', 32 | 'PYTHONDONTWRITEBYTECODE': 'yes', 33 | } 34 | 35 | foreach test : tests 36 | test( 37 | test, 38 | executable( 39 | 'test-@0@'.format(test), 40 | 'test-@0@.c'.format(test), 41 | c_args: kgx_cargs, 42 | dependencies: kgx_dep, 43 | ), 44 | env: test_env, 45 | protocol: 'tap', 46 | ) 47 | endforeach 48 | -------------------------------------------------------------------------------- /tests/test-colour-utils.c: -------------------------------------------------------------------------------- 1 | /* test-colour-utils.c 2 | * 3 | * Copyright 2024 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | 20 | #include "kgx-colour-utils.h" 21 | 22 | 23 | static void 24 | test_colour_error_quark (void) 25 | { 26 | g_assert_nonnull (g_quark_to_string (kgx_colour_parse_error_quark ())); 27 | } 28 | 29 | 30 | static void 31 | test_colour_to_string (void) 32 | { 33 | GdkRGBA colour = { .red = 1.0, .green = 0.75, .blue = 0.5 }; 34 | g_autofree char *string = kgx_colour_to_string (&colour); 35 | 36 | g_assert_cmpstr ("FFBF7F", ==, string); 37 | } 38 | 39 | 40 | static void 41 | assert_colour (const GdkRGBA *a, const GdkRGBA *b) 42 | { 43 | g_assert_cmpfloat_with_epsilon (a->red, b->red, 0.0095); 44 | g_assert_cmpfloat_with_epsilon (a->green, b->green, 0.0095); 45 | g_assert_cmpfloat_with_epsilon (a->blue, b->blue, 0.0095); 46 | g_assert_cmpfloat_with_epsilon (a->alpha, b->alpha, 0.0095); 47 | } 48 | 49 | 50 | static void 51 | test_colour_from_string (void) 52 | { 53 | g_autoptr (GError) error = NULL; 54 | GdkRGBA colour = { .red = 1.0, .green = 0.75, .blue = 0.5 }; 55 | 56 | kgx_colour_from_string ("FFBF7F", &colour, &error); 57 | 58 | g_assert_no_error (error); 59 | assert_colour (&((GdkRGBA) { .red = 1.0, .green = 0.75, .blue = 0.5 }), 60 | &colour); 61 | 62 | kgx_colour_from_string ("ABC", &colour, &error); 63 | 64 | g_assert_error (error, 65 | KGX_COLOUR_PARSE_ERROR, 66 | KGX_COLOUR_PARSE_ERROR_WRONG_LENGTH); 67 | } 68 | 69 | 70 | int 71 | main (int argc, char *argv[]) 72 | { 73 | g_test_init (&argc, &argv, NULL); 74 | 75 | g_test_add_func ("/kgx/colour-utils/error_quark", test_colour_error_quark); 76 | g_test_add_func ("/kgx/colour-utils/to_string", test_colour_to_string); 77 | g_test_add_func ("/kgx/colour-utils/from_string", test_colour_from_string); 78 | 79 | return g_test_run (); 80 | } 81 | -------------------------------------------------------------------------------- /tests/test-icon-closures.c: -------------------------------------------------------------------------------- 1 | /* test-icon-closures.c 2 | * 3 | * Copyright 2025 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include "kgx-config.h" 20 | 21 | #include "kgx-train.h" 22 | 23 | #include "kgx-icon-closures.h" 24 | 25 | 26 | static void 27 | test_status_as_icon (void) 28 | { 29 | g_autoptr (GIcon) remote_icon = kgx_status_as_icon (NULL, KGX_REMOTE); 30 | g_autoptr (GIcon) root_icon = kgx_status_as_icon (NULL, KGX_PRIVILEGED); 31 | g_autoptr (GIcon) remote_root_icon = 32 | kgx_status_as_icon (NULL, KGX_REMOTE | KGX_PRIVILEGED); 33 | 34 | g_assert_nonnull (remote_icon); 35 | g_assert_true (G_IS_THEMED_ICON (remote_icon)); 36 | g_assert_true (g_strv_contains (g_themed_icon_get_names (G_THEMED_ICON (remote_icon)), 37 | "status-remote-symbolic")); 38 | 39 | g_assert_nonnull (root_icon); 40 | g_assert_true (G_IS_THEMED_ICON (root_icon)); 41 | g_assert_true (g_strv_contains (g_themed_icon_get_names (G_THEMED_ICON (root_icon)), 42 | "status-privileged-symbolic")); 43 | 44 | g_assert_nonnull (remote_root_icon); 45 | g_assert_true (G_IS_THEMED_ICON (remote_root_icon)); 46 | g_assert_true (g_strv_contains (g_themed_icon_get_names (G_THEMED_ICON (remote_root_icon)), 47 | "status-remote-symbolic")); 48 | 49 | g_assert_null (kgx_status_as_icon (NULL, KGX_NONE)); 50 | } 51 | 52 | 53 | static void 54 | test_ringing_as_icon (void) 55 | { 56 | g_autoptr (GIcon) icon = kgx_ringing_as_icon (NULL, TRUE); 57 | 58 | g_assert_nonnull (icon); 59 | g_assert_true (G_IS_THEMED_ICON (icon)); 60 | g_assert_true (g_strv_contains (g_themed_icon_get_names (G_THEMED_ICON (icon)), 61 | "bell-outline-symbolic")); 62 | 63 | g_assert_null (kgx_ringing_as_icon (NULL, FALSE)); 64 | } 65 | 66 | 67 | int 68 | main (int argc, char *argv[]) 69 | { 70 | g_test_init (&argc, &argv, NULL); 71 | 72 | g_test_add_func ("/kgx/icon-closures/status_as_icon", test_status_as_icon); 73 | g_test_add_func ("/kgx/icon-closures/ringing_as_icon", test_ringing_as_icon); 74 | 75 | return g_test_run (); 76 | } 77 | -------------------------------------------------------------------------------- /tests/test-livery.c: -------------------------------------------------------------------------------- 1 | /* test-livery.c 2 | * 3 | * Copyright 2024 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include "kgx-config.h" 20 | 21 | #include "kgx-livery.h" 22 | 23 | 24 | static void 25 | test_livery_type (void) 26 | { 27 | g_assert_true (G_TYPE_IS_BOXED (KGX_TYPE_LIVERY)); 28 | g_assert_cmpstr ("KgxLivery", ==, g_type_name (KGX_TYPE_LIVERY)); 29 | } 30 | 31 | 32 | static void 33 | test_livery_new (void) 34 | { 35 | GdkRGBA fg = {}; 36 | GdkRGBA bg = {}; 37 | g_autoptr (KgxPalette) palette = kgx_palette_new (&fg, &bg, 0.0, 0, NULL); 38 | g_autoptr (KgxLivery) livery = kgx_livery_new (KGX_LIVERY_UUID_KGX, "Test", NULL, NULL); 39 | 40 | kgx_livery_ref (livery); 41 | kgx_livery_unref (livery); 42 | } 43 | 44 | 45 | static void 46 | assert_colour (const GdkRGBA *a, const GdkRGBA *b) 47 | { 48 | g_assert_cmpfloat (a->red, ==, b->red); 49 | g_assert_cmpfloat (a->green, ==, b->green); 50 | g_assert_cmpfloat (a->blue, ==, b->blue); 51 | g_assert_cmpfloat (a->alpha, ==, b->alpha); 52 | } 53 | 54 | 55 | static void 56 | test_livery_roundtrip (void) 57 | { 58 | g_autoptr (KgxPalette) palette = NULL; 59 | g_autoptr (KgxLivery) livery = NULL; 60 | g_autoptr (GVariant) variant = NULL; 61 | g_autoptr (KgxLivery) livery_after = NULL; 62 | g_autoptr (KgxPalette) palette_after = NULL; 63 | GdkRGBA fg_in = {.alpha = 1.0}, fg_out = {}, bg_in = { .alpha = 1.0 }, bg_out = {}; 64 | GdkRGBA colours_in[] = { {.alpha = 1.0}, }; 65 | const GdkRGBA *colours_out = NULL; 66 | size_t n_colours_in = G_N_ELEMENTS (colours_in), n_colours_out = 0; 67 | 68 | palette = kgx_palette_new (&fg_in, 69 | &bg_in, 70 | 0.0, 71 | n_colours_in, 72 | colours_in); 73 | livery = kgx_livery_new (KGX_LIVERY_UUID_KGX, "Test", palette, NULL); 74 | variant = kgx_livery_serialise (livery); 75 | 76 | livery_after = kgx_livery_deserialise (variant); 77 | 78 | g_assert_cmpstr (kgx_livery_get_uuid (livery), 79 | ==, 80 | kgx_livery_get_uuid (livery_after)); 81 | g_assert_cmpstr (kgx_livery_get_name (livery), 82 | ==, 83 | kgx_livery_get_name (livery_after)); 84 | 85 | palette_after = kgx_livery_resolve (livery_after, FALSE, TRUE); 86 | kgx_palette_get_colours (palette_after, &fg_out, &bg_out, &n_colours_out, &colours_out); 87 | 88 | g_assert_cmpint (n_colours_in, ==, n_colours_out); 89 | 90 | assert_colour (&fg_in, &fg_out); 91 | assert_colour (&bg_in, &bg_out); 92 | 93 | for (size_t i = 0; i < n_colours_out; i++) { 94 | assert_colour (&colours_in[i], &colours_out[i]); 95 | } 96 | } 97 | 98 | 99 | static void 100 | test_livery_set_livery (void) 101 | { 102 | g_autoptr (KgxPalette) palette = kgx_palette_new (&((GdkRGBA) { 0, }), 103 | &((GdkRGBA) { 0, }), 104 | 0.0, 105 | 0, 106 | NULL); 107 | g_autoptr (KgxLivery) livery_a = kgx_livery_new (KGX_LIVERY_UUID_KGX, 108 | "Test", 109 | palette, 110 | palette); 111 | g_autoptr (KgxLivery) livery_b = kgx_livery_new (KGX_LIVERY_UUID_KGX, 112 | "Test", 113 | palette, 114 | palette); 115 | 116 | g_assert_true (kgx_set_livery (&livery_a, livery_b)); 117 | g_assert_true (livery_a == livery_b); 118 | } 119 | 120 | 121 | static void 122 | test_livery_set_livery_same (void) 123 | { 124 | g_autoptr (KgxPalette) palette = kgx_palette_new (&((GdkRGBA) { 0, }), 125 | &((GdkRGBA) { 0, }), 126 | 0.0, 127 | 0, 128 | NULL); 129 | g_autoptr (KgxLivery) livery = kgx_livery_new (KGX_LIVERY_UUID_KGX, 130 | "Test", 131 | palette, 132 | palette); 133 | 134 | g_assert_false (kgx_set_palette (&palette, palette)); 135 | } 136 | 137 | 138 | int 139 | main (int argc, char *argv[]) 140 | { 141 | g_test_init (&argc, &argv, NULL); 142 | 143 | g_test_add_func ("/kgx/livery/type", test_livery_type); 144 | g_test_add_func ("/kgx/livery/new", test_livery_new); 145 | g_test_add_func ("/kgx/livery/roundtrip", test_livery_roundtrip); 146 | g_test_add_func ("/kgx/livery/set_palette", test_livery_set_livery); 147 | g_test_add_func ("/kgx/livery/set_palette_same", test_livery_set_livery_same); 148 | 149 | return g_test_run (); 150 | } 151 | -------------------------------------------------------------------------------- /tests/test-locale.c: -------------------------------------------------------------------------------- 1 | /* test-locale.c 2 | * 3 | * Copyright 2025 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | 20 | #include "kgx-locale.h" 21 | 22 | 23 | static void 24 | test_locale_init (void) 25 | { 26 | kgx_locale_init ("C.UTF-8"); 27 | 28 | g_assert_cmpstr (setlocale (LC_ALL, NULL), ==, "C.UTF-8"); 29 | } 30 | 31 | 32 | int 33 | main (int argc, char *argv[]) 34 | { 35 | g_test_init (&argc, &argv, NULL); 36 | 37 | g_test_add_func ("/kgx/locale/init", test_locale_init); 38 | 39 | return g_test_run (); 40 | } 41 | -------------------------------------------------------------------------------- /tests/test-spad-source.c: -------------------------------------------------------------------------------- 1 | /* test-spad-source.c 2 | * 3 | * Copyright 2025 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include "kgx-config.h" 20 | 21 | #include "kgx-locale.h" 22 | 23 | #include "kgx-spad-source.h" 24 | 25 | 26 | #define KGX_TYPE_TEST_SOURCE (kgx_test_source_get_type ()) 27 | 28 | G_DECLARE_FINAL_TYPE (KgxTestSource, kgx_test_source, KGX, TEST_SOURCE, GObject) 29 | 30 | 31 | struct _KgxTestSource { 32 | GObject parent; 33 | }; 34 | 35 | 36 | G_DEFINE_FINAL_TYPE_WITH_CODE (KgxTestSource, kgx_test_source, G_TYPE_OBJECT, 37 | G_IMPLEMENT_INTERFACE (KGX_TYPE_SPAD_SOURCE, NULL)) 38 | 39 | 40 | static void 41 | kgx_test_source_class_init (KgxTestSourceClass *klass) 42 | { 43 | } 44 | 45 | 46 | static void 47 | kgx_test_source_init (KgxTestSource *self) 48 | { 49 | } 50 | 51 | 52 | static void 53 | test_spad_source_new_destroy (void) 54 | { 55 | KgxTestSource *source = g_object_new (KGX_TYPE_TEST_SOURCE, NULL); 56 | 57 | g_assert_true (KGX_IS_SPAD_SOURCE (source)); 58 | 59 | g_assert_finalize_object (source); 60 | } 61 | 62 | 63 | struct spad_thrown { 64 | const char *title; 65 | gboolean got_spad; 66 | }; 67 | 68 | 69 | static gboolean 70 | spad_thrown (KgxSpadSource *source, 71 | const char *title, 72 | GVariant *bundle, 73 | gpointer user_data) 74 | { 75 | g_auto (GVariantDict) dict = G_VARIANT_DICT_INIT (bundle); 76 | struct spad_thrown *thrown = user_data; 77 | 78 | g_assert_cmpstr (thrown->title, ==, title); 79 | 80 | g_assert_true (g_variant_dict_contains (&dict, "title")); 81 | g_assert_true (g_variant_dict_contains (&dict, "flags")); 82 | g_assert_true (g_variant_dict_contains (&dict, "error-body")); 83 | g_assert_true (g_variant_dict_contains (&dict, "error-content")); 84 | g_assert_false (g_variant_dict_contains (&dict, "error")); 85 | 86 | thrown->got_spad = TRUE; 87 | 88 | return TRUE; 89 | } 90 | 91 | 92 | static void 93 | test_spad_source_throw (void) 94 | { 95 | g_autoptr (KgxSpadSource) source = g_object_new (KGX_TYPE_TEST_SOURCE, NULL); 96 | struct spad_thrown thrown = { 97 | .title = "Title", 98 | .got_spad = FALSE, 99 | }; 100 | 101 | g_signal_connect (source, "spad-thrown", G_CALLBACK (spad_thrown), &thrown); 102 | 103 | g_assert_false (thrown.got_spad); 104 | 105 | kgx_spad_source_throw (source, 106 | "Title", 107 | KGX_SPAD_SHOW_REPORT, 108 | "Error Body", 109 | "Error Content", 110 | NULL); 111 | 112 | g_assert_true (thrown.got_spad); 113 | } 114 | 115 | 116 | static void 117 | test_spad_source_throw_unhandled_case_1 (void) 118 | { 119 | if (g_test_subprocess ()) { 120 | g_autoptr (KgxSpadSource) source = g_object_new (KGX_TYPE_TEST_SOURCE, NULL); 121 | 122 | kgx_spad_source_throw (source, "Title", KGX_SPAD_NONE, "Error Body", NULL, NULL); 123 | 124 | return; 125 | } 126 | 127 | g_test_trap_subprocess (NULL, 0, 0); 128 | g_test_trap_assert_failed (); 129 | g_test_trap_assert_stderr ("*unhandled-spad: ‘Title’*"); 130 | } 131 | 132 | 133 | static void 134 | test_spad_source_throw_unhandled_case_2 (void) 135 | { 136 | if (g_test_subprocess ()) { 137 | g_autoptr (KgxSpadSource) source = g_object_new (KGX_TYPE_TEST_SOURCE, NULL); 138 | 139 | kgx_spad_source_throw (source, 140 | "Oh No", 141 | KGX_SPAD_NONE, 142 | "Error Body", 143 | "Content", 144 | NULL); 145 | 146 | return; 147 | } 148 | 149 | g_test_trap_subprocess (NULL, 0, 0); 150 | g_test_trap_assert_failed (); 151 | g_test_trap_assert_stderr ("*unhandled-spad: ‘Oh No’*"); 152 | } 153 | 154 | 155 | int 156 | main (int argc, char *argv[]) 157 | { 158 | kgx_locale_init (KGX_LOCALE_TEST); 159 | 160 | g_test_init (&argc, &argv, NULL); 161 | 162 | g_test_add_func ("/kgx/spad-source/new-destroy", test_spad_source_new_destroy); 163 | g_test_add_func ("/kgx/spad-source/throw", test_spad_source_throw); 164 | g_test_add_func ("/kgx/spad-source/throw/unhandled/case_1", test_spad_source_throw_unhandled_case_1); 165 | g_test_add_func ("/kgx/spad-source/throw/unhandled/case_2", test_spad_source_throw_unhandled_case_2); 166 | 167 | return g_test_run (); 168 | } 169 | -------------------------------------------------------------------------------- /tests/test-theme-switcher.c: -------------------------------------------------------------------------------- 1 | /* test-theme-switcher.c 2 | * 3 | * Copyright 2025 Zander Brown 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include "kgx-config.h" 20 | 21 | #include "kgx-locale.h" 22 | #include "kgx-settings.h" 23 | 24 | #include "kgx-theme-switcher.h" 25 | 26 | 27 | static void 28 | test_theme_switcher_new_destroy (void) 29 | { 30 | KgxThemeSwitcher *spad = 31 | g_object_new (KGX_TYPE_THEME_SWITCHER, NULL); 32 | 33 | g_object_ref_sink (spad); 34 | 35 | g_assert_finalize_object (spad); 36 | } 37 | 38 | 39 | static void 40 | test_theme_switcher_get_set (void) 41 | { 42 | g_autoptr (KgxThemeSwitcher) switcher = 43 | g_object_new (KGX_TYPE_THEME_SWITCHER, NULL); 44 | KgxTheme themes[] = { 45 | KGX_THEME_NIGHT, KGX_THEME_DAY, KGX_THEME_AUTO, KGX_THEME_NIGHT, 46 | KGX_THEME_AUTO, KGX_THEME_DAY, KGX_THEME_DAY, KGX_THEME_NIGHT, 47 | }; 48 | KgxTheme result = KGX_THEME_AUTO; 49 | 50 | g_object_ref_sink (switcher); 51 | 52 | for (size_t i = 0; i < G_N_ELEMENTS (themes); i++) { 53 | g_object_set (switcher, "theme", themes[i], NULL); 54 | g_object_get (switcher, "theme", &result, NULL); 55 | 56 | g_assert_cmpuint (result, ==, themes[i]); 57 | } 58 | } 59 | 60 | 61 | int 62 | main (int argc, char *argv[]) 63 | { 64 | kgx_locale_init (KGX_LOCALE_TEST); 65 | 66 | gtk_test_init (&argc, &argv, NULL); 67 | 68 | g_test_add_func ("/kgx/theme-switcher/new-destroy", test_theme_switcher_new_destroy); 69 | g_test_add_func ("/kgx/theme-switcher/get-set", test_theme_switcher_get_set); 70 | 71 | return g_test_run (); 72 | } 73 | --------------------------------------------------------------------------------