xiterm

simple vte terminal emulator
git clone https://git.ce9e.org/xiterm.git

commit
cf2b783759464e9667f4a3f8273420563ced7843
parent
f9a3e506ac19375c82f4eafc06dfa12cbe869081
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2025-09-25 23:47
workaround: always use portal to open URL

GIO_USE_PORTALS=1 does not seem to work

Diffstat

M Makefile 6 +++---
A portal.h 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
M xiterm.c 12 ++++++------

3 files changed, 62 insertions, 9 deletions


diff --git a/Makefile b/Makefile

@@ -1,10 +1,10 @@
    1     1 PREFIX = /usr
    2    -1 CFLAGS = -std=c99 -Wall -O2 -fstack-protector-strong -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 `pkg-config --cflags gtk+-3.0 vte-2.91`
    3    -1 LDFLAGS = -s -Wl,-z,relro `pkg-config --libs gtk+-3.0 vte-2.91`
   -1     2 CFLAGS = -std=c99 -Wall -O2 -fstack-protector-strong -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 `pkg-config --cflags gio-2.0 gtk+-3.0 vte-2.91`
   -1     3 LDFLAGS = -s -Wl,-z,relro `pkg-config --libs gio-2.0 gtk+-3.0 vte-2.91`
    4     4 
    5     5 all: xiterm
    6     6 
    7    -1 xiterm: xiterm.c
   -1     7 xiterm: xiterm.c portal.h
    8     8 	gcc $< -o $@ ${CFLAGS} ${LDFLAGS}
    9     9 
   10    10 clean:

diff --git a/portal.h b/portal.h

@@ -0,0 +1,53 @@
   -1     1 /* workarounds for broken portal support in GTK */
   -1     2 
   -1     3 #include <string.h>
   -1     4 #include <gio/gio.h>
   -1     5 
   -1     6 static GDBusProxy *openuri_portal;
   -1     7 
   -1     8 static GDBusProxy *get_portal(const char *iface) {
   -1     9 	GError *error = NULL;
   -1    10 
   -1    11 	GDBusProxy *proxy = g_dbus_proxy_new_for_bus_sync(
   -1    12 		G_BUS_TYPE_SESSION,
   -1    13 		G_DBUS_PROXY_FLAGS_NONE,
   -1    14 		NULL,
   -1    15 		"org.freedesktop.portal.Desktop",
   -1    16 		"/org/freedesktop/portal/desktop",
   -1    17 		iface,
   -1    18 		NULL,
   -1    19 		&error
   -1    20 	);
   -1    21 
   -1    22 	if (error) {
   -1    23 		g_printerr("Failed connect to portal %s: %s\n", iface, error->message);
   -1    24 		g_clear_error(&error);
   -1    25 		return NULL;
   -1    26 	}
   -1    27 
   -1    28 	return proxy;
   -1    29 }
   -1    30 
   -1    31 void portal_setup(void) {
   -1    32 	openuri_portal = get_portal("org.freedesktop.portal.OpenURI");
   -1    33 }
   -1    34 
   -1    35 void portal_finalize(void) {
   -1    36 	if (openuri_portal) {
   -1    37 		g_clear_object(&openuri_portal);
   -1    38 	}
   -1    39 }
   -1    40 
   -1    41 void open_uri(const char *uri) {
   -1    42 	if (openuri_portal) {
   -1    43 		g_dbus_proxy_call_sync(
   -1    44 			openuri_portal,
   -1    45 			"OpenURI",
   -1    46 			g_variant_new("(ssa{sv})", "", uri, NULL),
   -1    47 			G_DBUS_CALL_FLAGS_NONE,
   -1    48 			-1,
   -1    49 			NULL,
   -1    50 			NULL
   -1    51 		);
   -1    52 	}
   -1    53 }

diff --git a/xiterm.c b/xiterm.c

@@ -5,6 +5,8 @@
    5     5 #define PCRE2_CODE_UNIT_WIDTH 0
    6     6 #include <pcre2.h>
    7     7 
   -1     8 #include "portal.h"
   -1     9 
    8    10 #define REGEX_URL "https?://[^\\s<>]*[^\\s\\])}<>.,:;?!\"']"
    9    11 #define KEY(v, s) (event->keyval == (v) && modifiers == (GDK_CONTROL_MASK|(s)))
   10    12 #define KEY_S(v) (event->keyval == (v) && (GDK_SHIFT_MASK|modifiers) == (GDK_SHIFT_MASK|GDK_CONTROL_MASK))
@@ -53,17 +55,12 @@ void on_term_title(VteTerminal *term, gpointer user_data) {
   53    55 }
   54    56 
   55    57 gboolean on_term_click(VteTerminal *term, GdkEventButton *event, gpointer user_data) {
   56    -1 	GError *err = NULL;
   57    58 	char *uri;
   58    59 
   59    60 	if (event->button == 3) {
   60    61 		uri = vte_terminal_match_check_event(term, (GdkEvent *)event, NULL);
   61    62 		if (uri != NULL) {
   62    -1 			gtk_show_uri_on_window(window, uri, gtk_get_current_event_time(), &err);
   63    -1 			if (err != NULL) {
   64    -1 				fprintf(stderr, "Unable to open URI: %s\n", err->message);
   65    -1 				g_error_free(err);
   66    -1 			}
   -1    63 			open_uri(uri);
   67    64 			g_free(uri);
   68    65 			return TRUE;
   69    66 		}
@@ -242,6 +239,8 @@ int main(int argc, char **argv) {
  242   239 	g_signal_connect(settings, "changed::color-scheme", G_CALLBACK(on_color_scheme_changed), NULL);
  243   240 	on_color_scheme_changed(settings, "color-scheme", NULL);
  244   241 
   -1   242 	portal_setup();
   -1   243 
  245   244 	widget = gtk_notebook_new();
  246   245 	gtk_container_add(GTK_CONTAINER(window), widget);
  247   246 	notebook = GTK_NOTEBOOK(widget);
@@ -252,6 +251,7 @@ int main(int argc, char **argv) {
  252   251 	add_tab(initial_cmd);
  253   252 	gtk_main();
  254   253 	vte_regex_unref(url_regex);
   -1   254 	portal_finalize();
  255   255 
  256   256 	return 0;
  257   257 }