initial simple implementation of clickable urls

This commit is contained in:
Daniel Micay 2012-05-22 07:15:28 -04:00
parent f45220a6ee
commit b64cf58a50
3 changed files with 45 additions and 2 deletions

View File

@ -19,7 +19,6 @@ TODO
==== ====
* saner scrollback search widget * saner scrollback search widget
* click to open urls
* keyboard binding for opening urls * keyboard binding for opening urls
* configurable keybindings for the above functionality * configurable keybindings for the above functionality
* urgent_on_bell setting * urgent_on_bell setting

View File

@ -4,6 +4,7 @@
#include <stdbool.h> #include <stdbool.h>
static const char *url_regex = "(ftp|http)s?://[-a-zA-Z0-9.?$%&/=_~#.,:;+]*"; static const char *url_regex = "(ftp|http)s?://[-a-zA-Z0-9.?$%&/=_~#.,:;+]*";
static const char *url_command = "/usr/bin/firefox";
static const char *font = "Monospace 9"; static const char *font = "Monospace 9";
static const long scrollback_lines = 1000; static const long scrollback_lines = 1000;

43
term.c
View File

@ -82,6 +82,48 @@ static gboolean key_press_cb(GtkWidget *vte, GdkEventKey *event) {
return FALSE; return FALSE;
} }
#if VTE_CHECK_VERSION(0, 24, 0)
static void get_vte_padding(VteTerminal *vte, int *w, int *h) {
GtkBorder *border = NULL;
gtk_widget_style_get(GTK_WIDGET(vte), "inner-border", &border, NULL);
if (border == NULL) {
g_warning("VTE's inner-border property unavailable");
*w = *h = 0;
} else {
*w = border->left + border->right;
*h = border->top + border->bottom;
gtk_border_free(border);
}
}
#else
#define get_vte_padding vte_terminal_get_padding
#endif
static char *check_match(VteTerminal *vte, int event_x, int event_y) {
int xpad, ypad, tag;
get_vte_padding(vte, &xpad, &ypad);
char *ret = vte_terminal_match_check(vte,
(event_x - ypad) / vte_terminal_get_char_width(vte),
(event_y - ypad) / vte_terminal_get_char_height(vte),
&tag);
return ret;
}
static gboolean button_press_cb(VteTerminal *vte, GdkEventButton *event) {
char *match = check_match(vte, event->x, event->y);
if (event->button == 1 && event->type == GDK_BUTTON_PRESS && match != NULL) {
const char *argv[3] = {url_command, match, NULL};
g_spawn_async(NULL, (char **)argv, NULL, 0, NULL, NULL, NULL, NULL);
g_free(match);
return TRUE;
}
return FALSE;
}
int main(int argc, char **argv) { int main(int argc, char **argv) {
GError *error = NULL; GError *error = NULL;
@ -159,6 +201,7 @@ int main(int argc, char **argv) {
gtk_widget_grab_focus(vte); gtk_widget_grab_focus(vte);
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL); g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(vte, "button-press-event", G_CALLBACK(button_press_cb), NULL);
g_signal_connect(vte, "key-press-event", G_CALLBACK(key_press_cb), NULL); g_signal_connect(vte, "key-press-event", G_CALLBACK(key_press_cb), NULL);
gtk_widget_show_all(window); gtk_widget_show_all(window);