make more settings dynamically configurable
urgent_on_bell, dynamic_title and clickable_url can now be turned on and off dynamically
This commit is contained in:
		
							parent
							
								
									d84707ea77
								
							
						
					
					
						commit
						911ae4de61
					
				
							
								
								
									
										133
									
								
								termite.c
									
									
									
									
									
								
							
							
						
						
									
										133
									
								
								termite.c
									
									
									
									
									
								
							| @ -43,19 +43,29 @@ typedef struct search_panel_info { | |||||||
|     GtkWidget *entry; |     GtkWidget *entry; | ||||||
|     GtkWidget *panel; |     GtkWidget *panel; | ||||||
|     enum overlay_mode mode; |     enum overlay_mode mode; | ||||||
|     select_info select; |  | ||||||
| } search_panel_info; | } search_panel_info; | ||||||
| 
 | 
 | ||||||
|  | typedef struct config_info { | ||||||
|  |     gboolean dynamic_title, urgent_on_bell, clickable_url; | ||||||
|  |     int tag; | ||||||
|  | } config_info; | ||||||
|  | 
 | ||||||
|  | typedef struct keybind_info { | ||||||
|  |     search_panel_info panel; | ||||||
|  |     select_info select; | ||||||
|  |     config_info config; | ||||||
|  | } keybind_info; | ||||||
|  | 
 | ||||||
| static char *browser_cmd[3] = {NULL}; | static char *browser_cmd[3] = {NULL}; | ||||||
| 
 | 
 | ||||||
| static void launch_browser(char *url); | static void launch_browser(char *url); | ||||||
| 
 | 
 | ||||||
| static void window_title_cb(VteTerminal *vte, GtkWindow *window); | static void window_title_cb(VteTerminal *vte, gboolean *dynamic_title); | ||||||
| static gboolean key_press_cb(VteTerminal *vte, GdkEventKey *event, search_panel_info *info); | static gboolean key_press_cb(VteTerminal *vte, GdkEventKey *event, keybind_info *info); | ||||||
| static gboolean entry_key_press_cb(GtkEntry *entry, GdkEventKey *event, search_panel_info *info); | static gboolean entry_key_press_cb(GtkEntry *entry, GdkEventKey *event, search_panel_info *info); | ||||||
| static gboolean position_overlay_cb(GtkBin *overlay, GtkWidget *widget, GdkRectangle *alloc); | static gboolean position_overlay_cb(GtkBin *overlay, GtkWidget *widget, GdkRectangle *alloc); | ||||||
| static gboolean button_press_cb(VteTerminal *vte, GdkEventButton *event); | static gboolean button_press_cb(VteTerminal *vte, GdkEventButton *event, gboolean *clickable_url); | ||||||
| static void beep_cb(GtkWindow *window); | static void beep_cb(GtkWidget *vte, gboolean *urgent_on_bell); | ||||||
| static gboolean focus_cb(GtkWindow *window); | static gboolean focus_cb(GtkWindow *window); | ||||||
| 
 | 
 | ||||||
| static gboolean add_to_list_store(char *key, void *value, GtkListStore *store); | static gboolean add_to_list_store(char *key, void *value, GtkListStore *store); | ||||||
| @ -64,9 +74,8 @@ static void search(VteTerminal *vte, const char *pattern, bool reverse); | |||||||
| static void overlay_show(search_panel_info *info, overlay_mode mode, bool complete); | static void overlay_show(search_panel_info *info, overlay_mode mode, bool complete); | ||||||
| static void get_vte_padding(VteTerminal *vte, int *w, int *h); | static void get_vte_padding(VteTerminal *vte, int *w, int *h); | ||||||
| static char *check_match(VteTerminal *vte, int event_x, int event_y); | static char *check_match(VteTerminal *vte, int event_x, int event_y); | ||||||
| static void load_config(GtkWindow *window, VteTerminal *vte, | static void load_config(GtkWindow *window, VteTerminal *vte, config_info *info, | ||||||
|                         gboolean *dynamic_title, gboolean *urgent_on_bell, |                         const char **term); | ||||||
|                         gboolean *clickable_url, const char **term); |  | ||||||
| 
 | 
 | ||||||
| void launch_browser(char *url) { | void launch_browser(char *url) { | ||||||
|     browser_cmd[1] = url; |     browser_cmd[1] = url; | ||||||
| @ -184,14 +193,14 @@ static void move_to_row_start(VteTerminal *vte, select_info *select, long row) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* {{{ CALLBACKS */ | /* {{{ CALLBACKS */ | ||||||
| void window_title_cb(VteTerminal *vte, GtkWindow *window) { | void window_title_cb(VteTerminal *vte, gboolean *dynamic_title) { | ||||||
|     const char * const t = vte_terminal_get_window_title(vte); |     const char * const title = *dynamic_title ? vte_terminal_get_window_title(vte) : NULL; | ||||||
|     gtk_window_set_title(window, t ? t : "termite"); |     gtk_window_set_title(GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(vte))), | ||||||
|  |                          title ? title : "termite"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| gboolean key_press_cb(VteTerminal *vte, GdkEventKey *event, search_panel_info *info) { | gboolean key_press_cb(VteTerminal *vte, GdkEventKey *event, keybind_info *info) { | ||||||
|     const guint modifiers = event->state & gtk_accelerator_get_default_mod_mask(); |     const guint modifiers = event->state & gtk_accelerator_get_default_mod_mask(); | ||||||
|     gboolean dynamic_title = FALSE, urgent_on_bell = FALSE, clickable_url = FALSE; |  | ||||||
|     if (info->select.mode) { |     if (info->select.mode) { | ||||||
|         if (modifiers == GDK_CONTROL_MASK) { |         if (modifiers == GDK_CONTROL_MASK) { | ||||||
|             if (gdk_keyval_to_lower(event->keyval) == GDK_KEY_v) { |             if (gdk_keyval_to_lower(event->keyval) == GDK_KEY_v) { | ||||||
| @ -243,10 +252,10 @@ gboolean key_press_cb(VteTerminal *vte, GdkEventKey *event, search_panel_info *i | |||||||
|                 vte_terminal_copy_clipboard(vte); |                 vte_terminal_copy_clipboard(vte); | ||||||
|                 break; |                 break; | ||||||
|             case GDK_KEY_slash: |             case GDK_KEY_slash: | ||||||
|                 overlay_show(info, OVERLAY_SEARCH, true); |                 overlay_show(&info->panel, OVERLAY_SEARCH, true); | ||||||
|                 break; |                 break; | ||||||
|             case GDK_KEY_question: |             case GDK_KEY_question: | ||||||
|                 overlay_show(info, OVERLAY_RSEARCH, true); |                 overlay_show(&info->panel, OVERLAY_RSEARCH, true); | ||||||
|                 break; |                 break; | ||||||
|             case GDK_KEY_n: |             case GDK_KEY_n: | ||||||
|                 vte_terminal_search_find_next(vte); |                 vte_terminal_search_find_next(vte); | ||||||
| @ -278,12 +287,11 @@ gboolean key_press_cb(VteTerminal *vte, GdkEventKey *event, search_panel_info *i | |||||||
|                 return TRUE; |                 return TRUE; | ||||||
|             case GDK_KEY_Escape: |             case GDK_KEY_Escape: | ||||||
|                 load_config(GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(vte))), |                 load_config(GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(vte))), | ||||||
|                             vte, &dynamic_title, &urgent_on_bell, |                             vte, &info->config, NULL); | ||||||
|                             &clickable_url, NULL); |  | ||||||
|                 return TRUE; |                 return TRUE; | ||||||
|         } |         } | ||||||
|     } else if (modifiers == GDK_CONTROL_MASK && event->keyval == GDK_KEY_Tab) { |     } else if (modifiers == GDK_CONTROL_MASK && event->keyval == GDK_KEY_Tab) { | ||||||
|         overlay_show(info, OVERLAY_COMPLETION, true); |         overlay_show(&info->panel, OVERLAY_COMPLETION, true); | ||||||
|         return TRUE; |         return TRUE; | ||||||
|     } |     } | ||||||
|     return FALSE; |     return FALSE; | ||||||
| @ -338,18 +346,22 @@ gboolean position_overlay_cb(GtkBin *overlay, GtkWidget *widget, GdkRectangle *a | |||||||
|     return TRUE; |     return TRUE; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| gboolean button_press_cb(VteTerminal *vte, GdkEventButton *event) { | gboolean button_press_cb(VteTerminal *vte, GdkEventButton *event, gboolean *clickable_url) { | ||||||
|  |     if (*clickable_url) { | ||||||
|         char *match = check_match(vte, (int)event->x, (int)event->y); |         char *match = check_match(vte, (int)event->x, (int)event->y); | ||||||
|         if (event->button == 1 && event->type == GDK_BUTTON_PRESS && match) { |         if (event->button == 1 && event->type == GDK_BUTTON_PRESS && match) { | ||||||
|             launch_browser(match); |             launch_browser(match); | ||||||
|             g_free(match); |             g_free(match); | ||||||
|             return TRUE; |             return TRUE; | ||||||
|         } |         } | ||||||
|  |     } | ||||||
|     return FALSE; |     return FALSE; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void beep_cb(GtkWindow *window) { | void beep_cb(GtkWidget *vte, gboolean *urgent_on_bell) { | ||||||
|     gtk_window_set_urgency_hint(window, TRUE); |     if (*urgent_on_bell) { | ||||||
|  |         gtk_window_set_urgency_hint(GTK_WINDOW(gtk_widget_get_toplevel(vte)), TRUE); | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| gboolean focus_cb(GtkWindow *window) { | gboolean focus_cb(GtkWindow *window) { | ||||||
| @ -486,9 +498,8 @@ static bool get_config_color(GKeyFile *config, const char *key, GdkColor *color) | |||||||
|     return success; |     return success; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void load_config(GtkWindow *window, VteTerminal *vte, | static void load_config(GtkWindow *window, VteTerminal *vte, config_info *info, | ||||||
|                         gboolean *dynamic_title, gboolean *urgent_on_bell, |                         const char **term) { | ||||||
|                         gboolean *clickable_url, const char **term) { |  | ||||||
| 
 | 
 | ||||||
|     static const char * const filename = "termite.cfg"; |     static const char * const filename = "termite.cfg"; | ||||||
|     const char *dir = g_get_user_config_dir(); |     const char *dir = g_get_user_config_dir(); | ||||||
| @ -528,24 +539,38 @@ static void load_config(GtkWindow *window, VteTerminal *vte, | |||||||
|             vte_terminal_set_allow_bold(vte, cfgbool); |             vte_terminal_set_allow_bold(vte, cfgbool); | ||||||
|         } |         } | ||||||
|         if (get_config_boolean(config, "options", "dynamic_title", &cfgbool)) { |         if (get_config_boolean(config, "options", "dynamic_title", &cfgbool)) { | ||||||
|             *dynamic_title = cfgbool; |             info->dynamic_title = cfgbool; | ||||||
|         } |         } | ||||||
|         if (get_config_boolean(config, "options", "urgent_on_bell", &cfgbool)) { |         if (get_config_boolean(config, "options", "urgent_on_bell", &cfgbool)) { | ||||||
|             *urgent_on_bell = cfgbool; |             info->urgent_on_bell = cfgbool; | ||||||
|         } |  | ||||||
|         if (get_config_boolean(config, "options", "clickable_url", &cfgbool)) { |  | ||||||
|             *clickable_url = cfgbool; |  | ||||||
|         } |         } | ||||||
|         if (get_config_boolean(config, "options", "search_wrap", &cfgbool)) { |         if (get_config_boolean(config, "options", "search_wrap", &cfgbool)) { | ||||||
|             vte_terminal_search_set_wrap_around(vte, cfgbool); |             vte_terminal_search_set_wrap_around(vte, cfgbool); | ||||||
|         } |         } | ||||||
|  |         vte_terminal_match_remove(vte, info->tag); | ||||||
|  |         if (get_config_boolean(config, "options", "clickable_url", &cfgbool)) { | ||||||
|  |             info->clickable_url = cfgbool; | ||||||
|  |         } | ||||||
|  |         if (info->clickable_url) { | ||||||
|  |             info->tag = | ||||||
|  |                 vte_terminal_match_add_gregex(vte, | ||||||
|  |                                               g_regex_new(url_regex, | ||||||
|  |                                                           G_REGEX_CASELESS, | ||||||
|  |                                                           G_REGEX_MATCH_NOTEMPTY, | ||||||
|  |                                                           NULL), | ||||||
|  |                                               (GRegexMatchFlags)0); | ||||||
|  |             vte_terminal_match_set_cursor_type(vte, info->tag, GDK_HAND2); | ||||||
|  |         } else if (info->tag != -1) { | ||||||
|  |             vte_terminal_match_remove(vte, info->tag); | ||||||
|  |             info->tag = -1; | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         g_free(browser_cmd[0]); |         g_free(browser_cmd[0]); | ||||||
|         if (get_config_string(config, "options", "browser", &cfgstr)) { |         if (get_config_string(config, "options", "browser", &cfgstr)) { | ||||||
|             browser_cmd[0] = cfgstr; |             browser_cmd[0] = cfgstr; | ||||||
|         } else { |         } else { | ||||||
|             browser_cmd[0] = g_strdup(g_getenv("BROWSER")); |             browser_cmd[0] = g_strdup(g_getenv("BROWSER")); | ||||||
|             if (!browser_cmd[0]) *clickable_url = false; |             if (!browser_cmd[0]) info->clickable_url = false; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (get_config_string(config, "options", "font", &cfgstr)) { |         if (get_config_string(config, "options", "font", &cfgstr)) { | ||||||
| @ -653,7 +678,6 @@ static void load_config(GtkWindow *window, VteTerminal *vte, | |||||||
| int main(int argc, char **argv) { | int main(int argc, char **argv) { | ||||||
|     GError *error = NULL; |     GError *error = NULL; | ||||||
|     const char *term = "termite"; |     const char *term = "termite"; | ||||||
|     gboolean dynamic_title = FALSE, urgent_on_bell = FALSE, clickable_url = FALSE; |  | ||||||
|     gboolean version = FALSE; |     gboolean version = FALSE; | ||||||
| 
 | 
 | ||||||
|     GOptionContext *context = g_option_context_new(NULL); |     GOptionContext *context = g_option_context_new(NULL); | ||||||
| @ -720,58 +744,45 @@ int main(int argc, char **argv) { | |||||||
|         return 1; |         return 1; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     select_info select = {SELECT_OFF, 0, 0, 0, 0}; |     search_panel_info panel = {vte, gtk_entry_new(), | ||||||
|     search_panel_info info = {vte, gtk_entry_new(), |  | ||||||
|                                gtk_alignment_new(0, 0, 1, 1), |                                gtk_alignment_new(0, 0, 1, 1), | ||||||
|                               OVERLAY_HIDDEN, select}; |                                OVERLAY_HIDDEN}; | ||||||
|  |     keybind_info info = {panel, {SELECT_OFF, 0, 0, 0, 0}, {FALSE, FALSE, FALSE, -1}}; | ||||||
| 
 | 
 | ||||||
|     load_config(GTK_WINDOW(window), VTE_TERMINAL(vte), &dynamic_title, |     load_config(GTK_WINDOW(window), VTE_TERMINAL(vte), &info.config, &term); | ||||||
|                 &urgent_on_bell, &clickable_url, &term); |  | ||||||
| 
 | 
 | ||||||
|     vte_terminal_set_pty_object(VTE_TERMINAL(vte), pty); |     vte_terminal_set_pty_object(VTE_TERMINAL(vte), pty); | ||||||
|     vte_pty_set_term(pty, term); |     vte_pty_set_term(pty, term); | ||||||
| 
 | 
 | ||||||
|     gtk_alignment_set_padding(GTK_ALIGNMENT(info.panel), 5, 5, 5, 5); |     gtk_alignment_set_padding(GTK_ALIGNMENT(panel.panel), 5, 5, 5, 5); | ||||||
|     gtk_overlay_add_overlay(GTK_OVERLAY(overlay), info.panel); |     gtk_overlay_add_overlay(GTK_OVERLAY(overlay), panel.panel); | ||||||
| 
 | 
 | ||||||
|     gtk_widget_set_halign(info.entry, GTK_ALIGN_START); |     gtk_widget_set_halign(panel.entry, GTK_ALIGN_START); | ||||||
|     gtk_widget_set_valign(info.entry, GTK_ALIGN_END); |     gtk_widget_set_valign(panel.entry, GTK_ALIGN_END); | ||||||
| 
 | 
 | ||||||
|     gtk_container_add(GTK_CONTAINER(info.panel), info.entry); |     gtk_container_add(GTK_CONTAINER(panel.panel), panel.entry); | ||||||
|     gtk_container_add(GTK_CONTAINER(overlay), vte); |     gtk_container_add(GTK_CONTAINER(overlay), vte); | ||||||
|     gtk_container_add(GTK_CONTAINER(window), overlay); |     gtk_container_add(GTK_CONTAINER(window), overlay); | ||||||
| 
 | 
 | ||||||
|     g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); |     g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); | ||||||
|     g_signal_connect(vte, "child-exited", G_CALLBACK(gtk_main_quit), NULL); |     g_signal_connect(vte, "child-exited", G_CALLBACK(gtk_main_quit), NULL); | ||||||
|     g_signal_connect(vte, "key-press-event", G_CALLBACK(key_press_cb), &info); |     g_signal_connect(vte, "key-press-event", G_CALLBACK(key_press_cb), &info); | ||||||
|     g_signal_connect(info.entry, "key-press-event", G_CALLBACK(entry_key_press_cb), &info); |     g_signal_connect(panel.entry, "key-press-event", G_CALLBACK(entry_key_press_cb), &panel); | ||||||
|     g_signal_connect(overlay, "get-child-position", G_CALLBACK(position_overlay_cb), NULL); |     g_signal_connect(overlay, "get-child-position", G_CALLBACK(position_overlay_cb), NULL); | ||||||
| 
 | 
 | ||||||
|     if (clickable_url) { |     g_signal_connect(vte, "button-press-event", G_CALLBACK(button_press_cb), &info.config.clickable_url); | ||||||
|         int tag = vte_terminal_match_add_gregex(VTE_TERMINAL(vte), |  | ||||||
|                                                 g_regex_new(url_regex, |  | ||||||
|                                                             G_REGEX_CASELESS, |  | ||||||
|                                                             G_REGEX_MATCH_NOTEMPTY, |  | ||||||
|                                                             NULL), |  | ||||||
|                                                 (GRegexMatchFlags)0); |  | ||||||
|         vte_terminal_match_set_cursor_type(VTE_TERMINAL(vte), tag, GDK_HAND2); |  | ||||||
|         g_signal_connect(vte, "button-press-event", G_CALLBACK(button_press_cb), NULL); |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     if (urgent_on_bell) { |     g_signal_connect(vte, "beep", G_CALLBACK(beep_cb), &info.config.urgent_on_bell); | ||||||
|         g_signal_connect_swapped(vte, "beep", G_CALLBACK(beep_cb), window); |  | ||||||
|     g_signal_connect(window, "focus-in-event",  G_CALLBACK(focus_cb), NULL); |     g_signal_connect(window, "focus-in-event",  G_CALLBACK(focus_cb), NULL); | ||||||
|     g_signal_connect(window, "focus-out-event", G_CALLBACK(focus_cb), NULL); |     g_signal_connect(window, "focus-out-event", G_CALLBACK(focus_cb), NULL); | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     if (dynamic_title) { |     window_title_cb(VTE_TERMINAL(vte), &info.config.dynamic_title); | ||||||
|         window_title_cb(VTE_TERMINAL(vte), GTK_WINDOW(window)); |     g_signal_connect(vte, "window-title-changed", G_CALLBACK(window_title_cb), | ||||||
|         g_signal_connect(vte, "window-title-changed", G_CALLBACK(window_title_cb), window); |                      &info.config.dynamic_title); | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     if (geometry) { |     if (geometry) { | ||||||
|         gtk_widget_show_all(overlay); |         gtk_widget_show_all(overlay); | ||||||
|         gtk_widget_show_all(info.panel); |         gtk_widget_show_all(panel.panel); | ||||||
|         if (!gtk_window_parse_geometry(GTK_WINDOW(window), geometry)) { |         if (!gtk_window_parse_geometry(GTK_WINDOW(window), geometry)) { | ||||||
|             g_printerr("Invalid geometry string: %s\n", geometry); |             g_printerr("Invalid geometry string: %s\n", geometry); | ||||||
|         } |         } | ||||||
| @ -780,7 +791,7 @@ int main(int argc, char **argv) { | |||||||
| 
 | 
 | ||||||
|     gtk_widget_grab_focus(vte); |     gtk_widget_grab_focus(vte); | ||||||
|     gtk_widget_show_all(window); |     gtk_widget_show_all(window); | ||||||
|     gtk_widget_hide(info.panel); |     gtk_widget_hide(panel.panel); | ||||||
| 
 | 
 | ||||||
|     GdkWindow *gdk_window = gtk_widget_get_window(window); |     GdkWindow *gdk_window = gtk_widget_get_window(window); | ||||||
|     if (!gdk_window) { |     if (!gdk_window) { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Daniel Micay
						Daniel Micay