1 /* vim: set ts=4 sts=4 sw=4 expandtab nowrap: */
2 /*
3 * This is free software; you can redistribute it and/or modify it under
4 * the terms of the GNU Library General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
12 *
13 * You should have received a copy of the GNU Library General Public
14 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include <tilda-config.h>
18
19 #include <errno.h>
20
21 #include "debug.h"
22 #include "tilda.h"
23 #include "wizard.h"
24 #include "key_grabber.h"
25 #include "configsys.h"
26 #include "screen-size.h"
27 #include "tilda-palettes.h"
28 #include "tilda_window.h"
29 #include "tilda-keybinding.h"
30
31 #include <gtk/gtk.h>
32 #include <gdk/gdkkeysyms.h>
33 #include <glib.h>
34 #include <glib/gi18n.h>
35 #include <vte/vte.h> /* VTE_* constants, mostly */
36 #include <stdio.h>
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <stdlib.h>
40
41 /* INT_MAX */
42 #include <limits.h>
43
44 struct TildaWizard_
45 {
46 tilda_window *tw;
47 TildaKeybindingTreeView *keybinding;
48 GtkBuilder *builder;
49 };
50
51 typedef struct TildaWizard_ TildaWizard;
52
53 /* This will hold the GtkBuilder representation of the .ui file.
54 * We keep this global so that we can look up any element from any routine.
55 *
56 * Note that for GtkBuilder to autoconnect signals, the functions that it hooks
57 * to must NOT be marked static. I decided against the autoconnect just to
58 * keep things "in the code" so that they can be grepped for easily. */
59 static GtkBuilder *xml = NULL;
60
61 /* Prototypes for use in the wizard() */
62 static void set_wizard_state_from_config (tilda_window *tw);
63 static void connect_wizard_signals (TildaWizard *wizard);
64 static void init_palette_scheme_menu (void);
65 static void update_palette_color_button(gint idx);
66 static void initialize_geometry_spinners(tilda_window *tw);
67
68 /* Show the wizard. This will show the wizard, then exit immediately. */
wizard(tilda_window * tw)69 gint wizard (tilda_window *tw)
70 {
71 DEBUG_FUNCTION ("wizard");
72 DEBUG_ASSERT (tw != NULL);
73
74 gchar *window_title;
75
76 /* Make sure that there isn't already a wizard showing */
77 if (tw->wizard_window) {
78 gtk_window_present (GTK_WINDOW (tw->wizard_window));
79 return 0;
80 }
81
82 TildaWizard *wizard = g_malloc (sizeof (TildaWizard));
83
84 GError* error = NULL;
85 xml = gtk_builder_new ();
86
87 #if ENABLE_NLS
88 gtk_builder_set_translation_domain (xml, PACKAGE);
89 #endif
90
91 if(!gtk_builder_add_from_resource (xml, "/org/tilda/tilda.ui", &error)) {
92 g_prefix_error(&error, "Error:");
93 return EXIT_FAILURE;
94 }
95
96 if (!xml) {
97 g_warning ("problem while loading the tilda.ui file");
98 return 2;
99 }
100
101 wizard->builder = xml;
102 wizard->tw = tw;
103
104 tw->wizard_window = GTK_WIDGET (
105 gtk_builder_get_object (xml, "wizard_window")
106 );
107
108 /* GtkDialog windows need to have a transient parent or a warning will be logged. */
109 gtk_window_set_transient_for (GTK_WINDOW(tw->wizard_window), GTK_WINDOW(tw->window));
110
111 init_palette_scheme_menu ();
112
113 /* Copy the current program state into the wizard */
114 set_wizard_state_from_config (tw);
115
116 wizard->keybinding = tilda_keybinding_init (wizard->builder);
117
118 /* Connect all signal handlers. We do this after copying the state into
119 * the wizard so that all of the handlers don't get called as we copy in
120 * the values. This function manually connects the required signals for
121 * all the widgets */
122 connect_wizard_signals (wizard);
123
124 /* Unbind the current keybinding. I'm aware that this opens up an opportunity to
125 * let "someone else" grab the key, but it also saves us some trouble, and makes
126 * validation easier. */
127 tilda_keygrabber_unbind (config_getstr ("key"));
128
129 /* Adding widget title for CSS selection */
130 gtk_widget_set_name (GTK_WIDGET(tw->wizard_window), "Wizard");
131
132 /* Set the icon for the wizard window to our tilda icon. */
133 gchar* filename = g_build_filename (DATADIR, "pixmaps", "tilda.png", NULL);
134 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(filename, NULL);
135 g_free(filename);
136 gtk_window_set_icon(GTK_WINDOW(tw->wizard_window), pixbuf);
137
138 window_title = g_strdup_printf (_("Tilda %d Config"), tw->instance);
139 gtk_window_set_title (GTK_WINDOW(tw->wizard_window), window_title);
140 gtk_window_set_type_hint (GTK_WINDOW(tw->wizard_window), GDK_WINDOW_TYPE_HINT_DIALOG);
141
142 gtk_widget_show_all (tw->wizard_window);
143
144 /* This is needed to ensure that the wizard appears above of the terminal window */
145 gtk_window_present(GTK_WINDOW(tw->wizard_window));
146
147 g_free (window_title);
148
149 /* Disable auto hide */
150 tw->disable_auto_hide = TRUE;
151
152 return 0;
153 }
154
155 # define GET_BUTTON_LABEL(BUTTON) ( gtk_button_get_label( GTK_BUTTON( \
156 gtk_builder_get_object (xml, BUTTON))))
157
158 /* Gets called just after the wizard is closed. This should clean up after
159 * the wizard, and do anything that couldn't be done immediately during the
160 * wizard's lifetime. */
wizard_close_dialog(TildaWizard * wizard)161 static void wizard_close_dialog (TildaWizard *wizard)
162 {
163 DEBUG_FUNCTION ("wizard_close_dialog");
164
165 tilda_window *tw = wizard->tw;
166
167 const GtkWidget *entry_custom_command =
168 GTK_WIDGET (gtk_builder_get_object(xml, "entry_custom_command"));
169 const GtkWidget *wizard_window = tw->wizard_window;
170 const gchar *command = gtk_entry_get_text (GTK_ENTRY(entry_custom_command));
171
172 if (!tilda_keybinding_save (wizard->keybinding, tw)) {
173 return;
174 }
175
176 tilda_keybinding_apply (wizard->keybinding);
177
178 tilda_keybinding_free (wizard->keybinding);
179
180 wizard->keybinding = NULL;
181
182 /* TODO: validate this?? */
183 config_setstr ("command", command);
184
185 /* Free the GtkBuilder data structure */
186 g_object_unref (G_OBJECT(xml));
187 xml = NULL;
188
189 /* Remove the wizard */
190 gtk_widget_destroy (GTK_WIDGET(wizard_window));
191 tw->wizard_window = NULL;
192
193 /* Write the config, because it probably changed. This saves us in case
194 * of an XKill (or crash) later ... */
195 config_write (tw->config_file);
196
197 /* Enables auto hide */
198 tw->disable_auto_hide = FALSE;
199
200 wizard->tw = NULL;
201 wizard->builder = NULL;
202 g_free (wizard);
203 }
204
205 /******************************************************************************/
206 /* Wizard set-up functions */
207 /******************************************************************************/
208
209 /* The following macro definitions are used to make the process of loading the
210 * configuration values a lot easier. Each macro takes the name of a GtkBuilder object
211 * and the name of a configuration option and sets the value for that widget to the value
212 * that is stored in this configuration option. The macros are mainly used in the function
213 * set_wizard_state_from_config() but they are used in some callback functions as well, so
214 * we need to define before the callback functions.
215 */
216
217 /** Setters */
218 #define CHECK_BUTTON(GLADE_NAME,CFG_BOOL) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON( \
219 gtk_builder_get_object (xml, (GLADE_NAME))), config_getbool ((CFG_BOOL)))
220 #define COMBO_BOX(GLADE_NAME,CFG_INT) gtk_combo_box_set_active (GTK_COMBO_BOX( \
221 gtk_builder_get_object (xml, (GLADE_NAME))), config_getint ((CFG_INT)))
222 #define FONT_BUTTON(GLADE_NAME,CFG_STR) gtk_font_chooser_set_font (GTK_FONT_CHOOSER( \
223 gtk_builder_get_object (xml, (GLADE_NAME))), config_getstr ((CFG_STR)))
224 #define TEXT_ENTRY(GLADE_NAME,CFG_STR) gtk_entry_set_text (GTK_ENTRY( \
225 gtk_builder_get_object (xml, (GLADE_NAME))), config_getstr ((CFG_STR)))
226 #define BUTTON_LABEL_FROM_CFG(GLADE_NAME,CFG_STR) gtk_button_set_label (GTK_BUTTON( \
227 gtk_builder_get_object (xml, (GLADE_NAME))), config_getstr ((CFG_STR)))
228 #define SPIN_BUTTON(GLADE_NAME,CFG_INT) gtk_spin_button_set_value (GTK_SPIN_BUTTON( \
229 gtk_builder_get_object (xml, (GLADE_NAME))), config_getint ((CFG_INT)))
230 #define SPIN_BUTTON_SET_RANGE(GLADE_NAME,LOWER,UPPER) gtk_spin_button_set_range (GTK_SPIN_BUTTON( \
231 gtk_builder_get_object (xml, (GLADE_NAME))), (LOWER), (UPPER))
232 #define SPIN_BUTTON_SET_VALUE(GLADE_NAME,VALUE) gtk_spin_button_set_value (GTK_SPIN_BUTTON( \
233 gtk_builder_get_object (xml, (GLADE_NAME))), (VALUE))
234 #define FILE_BUTTON(GLADE_NAME, FILENAME) gtk_file_chooser_set_filename (GTK_FILE_CHOOSER( \
235 gtk_builder_get_object (xml, (GLADE_NAME))), FILENAME)
236 #define COLOR_CHOOSER(GLADE_NAME,COLOR) gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER( \
237 gtk_builder_get_object (xml, (GLADE_NAME))), (COLOR))
238 #define SET_SENSITIVE_BY_CONFIG_BOOL(GLADE_NAME,CFG_BOOL) gtk_widget_set_sensitive ( \
239 GTK_WIDGET (gtk_builder_get_object (xml, (GLADE_NAME))), config_getbool ((CFG_BOOL)))
240 #define SET_SENSITIVE_BY_CONFIG_NBOOL(GLADE_NAME,CFG_BOOL) gtk_widget_set_sensitive ( \
241 GTK_WIDGET (gtk_builder_get_object (xml, (GLADE_NAME))), !config_getbool ((CFG_BOOL)))
242
243 /** Getters */
244 #define SPIN_BUTTON_GET_VALUE(GLADE_NAME) gtk_spin_button_get_value (GTK_SPIN_BUTTON( \
245 gtk_builder_get_object (xml, (GLADE_NAME))))
246 #define SPIN_BUTTON_GET_RANGE(GLADE_NAME,MIN_POINTER,MAX_POINTER) gtk_spin_button_get_range (GTK_SPIN_BUTTON( \
247 gtk_builder_get_object (xml, (GLADE_NAME))), MIN_POINTER, MAX_POINTER)
248
249 /******************************************************************************/
250 /* Utility functions to get the current monitors height and width */
251 /******************************************************************************/
get_max_height()252 static int get_max_height() {
253 gdouble height_min;
254 gdouble height_max;
255 SPIN_BUTTON_GET_RANGE("spin_height_pixels", &height_min, &height_max);
256 return (int) height_max;
257 }
258
get_max_width()259 static int get_max_width() {
260 gdouble width_min;
261 gdouble width_max;
262 SPIN_BUTTON_GET_RANGE("spin_width_pixels", &width_min, &width_max);
263 return (int) width_max;
264 }
265
266 /******************************************************************************/
267 /* ALL static callback helpers are below */
268 /******************************************************************************/
269
270 /**
271 * Get the number of screens and load the monitor geometry for each screen,
272 * then set the position of the window according to the x and y offset
273 * of that monitor. This function does not actually move or resize the window
274 * but only changes the value of the spin buttons. The moving and resizing
275 * is then done by the callback functions of the respective widgets.
276 */
277 static int
combo_monitor_selection_changed_cb(GtkWidget * widget,tilda_window * tw)278 combo_monitor_selection_changed_cb (GtkWidget* widget, tilda_window *tw)
279 {
280 DEBUG_FUNCTION ("combo_monitor_selection_changed_cb");
281
282 GdkDisplay *display = gdk_display_get_default ();
283 GdkMonitor *original_monitor = tilda_window_find_monitor_number (tw);
284 GdkMonitor *new_monitor;
285
286 GdkRectangle original_monitor_rectangle;
287 GdkRectangle selected_monitor_rectangle;
288
289 gdk_monitor_get_workarea (original_monitor, &original_monitor_rectangle);
290
291 GtkTreeIter active_iter;
292
293 GtkComboBox* combo_choose_monitor = GTK_COMBO_BOX(widget);
294
295 if(!gtk_combo_box_get_active_iter(combo_choose_monitor, &active_iter))
296 {
297 return FALSE;
298 }
299
300 gchar* new_monitor_name = NULL;
301 gint new_monitor_number;
302
303 gtk_tree_model_get(gtk_combo_box_get_model(combo_choose_monitor), &active_iter,
304 0, &new_monitor_name,
305 1, &new_monitor_number,
306 -1);
307
308 new_monitor = gdk_display_get_monitor (display, new_monitor_number);
309 gdk_monitor_get_workarea (new_monitor, &selected_monitor_rectangle);
310
311 //Save the new monitor value
312 config_setstr("show_on_monitor", new_monitor_name);
313
314 /* The dimensions of the monitor might have changed,
315 * so we need to update the spinner widgets for height,
316 * width, and their percentages as well as their ranges.
317 * Keep in mind that we use the max range of the pixel spinners
318 * to store the size of the screen.
319 */
320 GdkRectangle rectangle;
321 config_get_configured_window_size (&rectangle);
322
323 if(selected_monitor_rectangle.width != original_monitor_rectangle.width)
324 {
325 gint new_max_width = selected_monitor_rectangle.width;
326
327 SPIN_BUTTON_SET_RANGE ("spin_width_pixels", 0, new_max_width);
328 SPIN_BUTTON_SET_VALUE ("spin_width_pixels", rectangle.width);
329
330 gtk_window_resize (GTK_WINDOW(tw->window),
331 rectangle.width,
332 rectangle.height);
333 }
334
335 if(selected_monitor_rectangle.height != original_monitor_rectangle.height)
336 {
337 int new_max_height = selected_monitor_rectangle.height;
338
339 SPIN_BUTTON_SET_RANGE ("spin_height_pixels", 0, new_max_height);
340 SPIN_BUTTON_SET_VALUE ("spin_height_pixels", rectangle.height);
341
342 gtk_window_resize (GTK_WINDOW(tw->window),
343 rectangle.width,
344 rectangle.height);
345 }
346
347 gint screen_width, screen_height;
348 screen_size_get_dimensions (&screen_width, &screen_height);
349 SPIN_BUTTON_SET_RANGE ("spin_x_position", 0, screen_width);
350 SPIN_BUTTON_SET_VALUE("spin_x_position", selected_monitor_rectangle.x);
351 SPIN_BUTTON_SET_RANGE ("spin_y_position", 0, screen_height);
352 SPIN_BUTTON_SET_VALUE("spin_y_position", selected_monitor_rectangle.y);
353
354 tilda_window_update_window_position (tw);
355
356 return GDK_EVENT_STOP;
357 }
358
window_title_change_all(tilda_window * tw)359 static void window_title_change_all (tilda_window *tw)
360 {
361 DEBUG_FUNCTION ("window_title_change_all");
362
363 GtkWidget *page;
364 GtkWidget *label;
365 tilda_term *tt;
366 gchar *title;
367 gint i, size, list_count;
368
369 size = gtk_notebook_get_n_pages (GTK_NOTEBOOK(tw->notebook));
370 list_count = size-1;
371
372 for (i=0;i<size;i++,list_count--)
373 {
374 tt = g_list_nth (tw->terms, list_count)->data;
375 title = tilda_terminal_get_title (tt);
376 page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (tw->notebook), i);
377 label = gtk_notebook_get_tab_label (GTK_NOTEBOOK (tw->notebook), page);
378
379 guint length = config_getint ("title_max_length");
380 guint title_behaviour = config_getint("title_behaviour");
381 if(title_behaviour && strlen(title) > length) {
382 gchar *shortTitle = NULL;
383 if(title_behaviour == 1) {
384 shortTitle = g_strdup_printf ("%.*s...", length, title);
385 }
386 else {
387 gchar *titleOffset = title + strlen(title) - length;
388 shortTitle = g_strdup_printf ("...%s", titleOffset);
389 }
390 gtk_label_set_text (GTK_LABEL(label), shortTitle);
391 g_free(shortTitle);
392 } else {
393 gtk_label_set_text (GTK_LABEL(label), title);
394 }
395 if(config_getbool("show_title_tooltip"))
396 gtk_widget_set_tooltip_text(label, title);
397 else
398 gtk_widget_set_tooltip_text(label, "");
399
400 g_free (title);
401 }
402 }
403
set_spin_value_while_blocking_callback(GtkSpinButton * spin,void (* callback)(GtkWidget * w,tilda_window * tw),gdouble new_val,tilda_window * tw)404 static void set_spin_value_while_blocking_callback (GtkSpinButton *spin,
405 void (*callback)(GtkWidget *w, tilda_window *tw),
406 gdouble new_val,
407 tilda_window *tw)
408 {
409 DEBUG_FUNCTION ("set_spin_value_while_blocking_callback");
410
411 g_signal_handlers_block_by_func (spin, G_CALLBACK(*callback), tw);
412 gtk_spin_button_set_value (GTK_SPIN_BUTTON(spin), new_val);
413 g_signal_handlers_unblock_by_func (spin, G_CALLBACK(*callback), tw);
414 }
415
416 /******************************************************************************/
417 /* ALL Callbacks are below */
418 /******************************************************************************/
419
wizard_button_close_clicked_cb(GtkButton * button,TildaWizard * wizard)420 static void wizard_button_close_clicked_cb (GtkButton *button,
421 TildaWizard *wizard)
422 {
423 /* Call the clean-up function */
424 wizard_close_dialog (wizard);
425 }
426
wizard_window_delete_event_cb(GtkWidget * widget,GdkEvent * event,TildaWizard * wizard)427 static void wizard_window_delete_event_cb (GtkWidget *widget,
428 GdkEvent *event,
429 TildaWizard *wizard)
430 {
431 /* Call the clean-up function */
432 wizard_close_dialog (wizard);
433 }
434
check_display_on_all_workspaces_toggled_cb(GtkWidget * w,tilda_window * tw)435 static void check_display_on_all_workspaces_toggled_cb (GtkWidget *w, tilda_window *tw)
436 {
437 const gboolean status = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(w));
438
439 config_setbool ("pinned", status);
440
441 if (status)
442 gtk_window_stick (GTK_WINDOW (tw->window));
443 else
444 gtk_window_unstick (GTK_WINDOW (tw->window));
445 }
446
check_set_as_desktop_toggled_cb(GtkWidget * widget,tilda_window * tw)447 static void check_set_as_desktop_toggled_cb (GtkWidget *widget, tilda_window *tw)
448 {
449 const gboolean status = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(widget));
450 GtkWidget *check_display_on_all_workspaces = GTK_WIDGET (gtk_builder_get_object (xml, "check_display_on_all_workspaces"));
451 config_setbool ("set_as_desktop", status);
452
453 g_signal_handlers_block_by_func (check_display_on_all_workspaces, check_display_on_all_workspaces_toggled_cb, NULL);
454 gboolean status_display_on_all_workspaces = config_getbool ("pinned");
455 if (status) {
456
457 gtk_widget_set_sensitive (check_display_on_all_workspaces, FALSE);
458 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_display_on_all_workspaces), TRUE);
459 gtk_window_stick (GTK_WINDOW (tw->window));
460 } else {
461 gtk_widget_set_sensitive (check_display_on_all_workspaces, TRUE);
462 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_display_on_all_workspaces), status_display_on_all_workspaces);
463 gtk_window_unstick (GTK_WINDOW (tw->window));
464 }
465 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), status);
466 g_signal_handlers_unblock_by_func (check_display_on_all_workspaces, check_display_on_all_workspaces_toggled_cb, NULL);
467 }
468
check_do_not_show_in_taskbar_toggled_cb(GtkWidget * w,tilda_window * tw)469 static void check_do_not_show_in_taskbar_toggled_cb (GtkWidget *w, tilda_window *tw)
470 {
471 const gboolean status = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(w));
472
473 config_setbool ("notaskbar", status);
474 gtk_window_set_skip_taskbar_hint (GTK_WINDOW(tw->window), status);
475 }
476
check_show_notebook_border_toggled_cb(GtkWidget * w,tilda_window * tw)477 static void check_show_notebook_border_toggled_cb (GtkWidget *w, tilda_window *tw)
478 {
479 const gboolean status = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(w));
480
481 config_setbool ("notebook_border", status);
482 gtk_notebook_set_show_border (GTK_NOTEBOOK (tw->notebook), status);
483 }
484
check_always_on_top_toggled_cb(GtkWidget * w,tilda_window * tw)485 static void check_always_on_top_toggled_cb (GtkWidget *w, tilda_window *tw)
486 {
487 const gboolean status = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(w));
488
489 config_setbool ("above", status);
490 gtk_window_set_keep_above (GTK_WINDOW (tw->window), status);
491 }
492
493
check_start_tilda_hidden_toggled_cb(GtkWidget * w,tilda_window * tw)494 static void check_start_tilda_hidden_toggled_cb (GtkWidget *w, tilda_window *tw)
495 {
496 const gboolean status = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(w));
497
498 config_setbool ("hidden", status);
499 }
500
check_terminal_bell_toggled_cb(GtkWidget * w,tilda_window * tw)501 static void check_terminal_bell_toggled_cb (GtkWidget *w, tilda_window *tw)
502 {
503 const gboolean status = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(w));
504 guint i;
505 tilda_term *tt;
506
507 config_setbool ("bell", status);
508
509 for (i=0; i<g_list_length (tw->terms); i++) {
510 tt = g_list_nth_data (tw->terms, i);
511 vte_terminal_set_audible_bell (VTE_TERMINAL(tt->vte_term), status);
512 }
513 }
514
check_cursor_blinks_toggled_cb(GtkWidget * w,tilda_window * tw)515 static void check_cursor_blinks_toggled_cb (GtkWidget *w, tilda_window *tw)
516 {
517 const gboolean status = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(w));
518 guint i;
519 tilda_term *tt;
520
521 config_setbool ("blinks", status);
522
523 for (i=0; i<g_list_length (tw->terms); i++) {
524 tt = g_list_nth_data (tw->terms, i);
525 vte_terminal_set_cursor_blink_mode (VTE_TERMINAL(tt->vte_term),
526 (status)?VTE_CURSOR_BLINK_ON:VTE_CURSOR_BLINK_OFF);
527 }
528 }
529
spin_auto_hide_time_value_changed_cb(GtkWidget * w,tilda_window * tw)530 static void spin_auto_hide_time_value_changed_cb (GtkWidget *w, tilda_window *tw)
531 {
532 const gint auto_hide_time = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(w));
533 config_setint ("auto_hide_time", auto_hide_time);
534 tw->auto_hide_max_time = auto_hide_time;
535 }
536
check_auto_hide_on_focus_lost_toggled_cb(GtkWidget * w,tilda_window * tw)537 static void check_auto_hide_on_focus_lost_toggled_cb (GtkWidget *w, tilda_window *tw)
538 {
539 const gboolean status = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(w));
540
541 config_setbool ("auto_hide_on_focus_lost", status);
542 tw->auto_hide_on_focus_lost = status;
543 }
544
check_auto_hide_on_mouse_leave_toggled_cb(GtkWidget * w,tilda_window * tw)545 static void check_auto_hide_on_mouse_leave_toggled_cb (GtkWidget *w, tilda_window *tw)
546 {
547 const gboolean status = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(w));
548
549 config_setbool ("auto_hide_on_mouse_leave", status);
550 tw->auto_hide_on_mouse_leave = status;
551 }
552
combo_cursor_shape_changed_cb(GtkWidget * w,tilda_window * tw)553 static void combo_cursor_shape_changed_cb(GtkWidget *w, tilda_window *tw)
554 {
555 guint i;
556 tilda_term *tt;
557 gint status = gtk_combo_box_get_active (GTK_COMBO_BOX(w));
558
559 if (status < 0 || status > 2) {
560 DEBUG_ERROR ("Invalid Cursor Type");
561 g_printerr (_("Invalid Cursor Type, resetting to default\n"));
562 status = 0;
563 }
564 config_setint("cursor_shape", (VteCursorShape) status);
565
566 for (i=0; i<g_list_length (tw->terms); i++) {
567 tt = g_list_nth_data (tw->terms, i);
568 vte_terminal_set_cursor_shape (VTE_TERMINAL(tt->vte_term),
569 (VteCursorShape) status);
570 }
571 }
572
combo_non_focus_pull_up_behaviour_cb(GtkWidget * w,tilda_window * tw)573 static void combo_non_focus_pull_up_behaviour_cb (GtkWidget *w, tilda_window *tw)
574 {
575 const gint status = gtk_combo_box_get_active (GTK_COMBO_BOX(w));
576
577 if (status < 0 || status > 1) {
578 DEBUG_ERROR ("Non-focus pull up behaviour invalid");
579 g_printerr (_("Invalid non-focus pull up behaviour, ignoring\n"));
580 return;
581 }
582
583 if(1 == status) {
584 tw->hide_non_focused = TRUE;
585 }
586 else {
587 tw->hide_non_focused = FALSE;
588 }
589
590 config_setint ("non_focus_pull_up_behaviour", status);
591 }
592
button_font_font_set_cb(GtkWidget * w,tilda_window * tw)593 static void button_font_font_set_cb (GtkWidget *w, tilda_window *tw)
594 {
595 const gchar *font = gtk_font_chooser_get_font (GTK_FONT_CHOOSER (w));
596 guint i;
597 tilda_term *tt;
598
599 config_setstr ("font", font);
600 PangoFontDescription *description = pango_font_description_from_string (font);
601 tw->unscaled_font_size = pango_font_description_get_size(description);
602
603 for (i=0; i<g_list_length (tw->terms); i++) {
604 tt = g_list_nth_data (tw->terms, i);
605 vte_terminal_set_font (VTE_TERMINAL(tt->vte_term), description);
606 tilda_term_adjust_font_scale(tt, tw->current_scale_factor);
607 }
608 }
609
entry_title_changed_cb(GtkWidget * w,tilda_window * tw)610 static void entry_title_changed_cb (GtkWidget *w, tilda_window *tw)
611 {
612 const gchar *title = gtk_entry_get_text (GTK_ENTRY(w));
613
614 config_setstr ("title", title);
615 window_title_change_all (tw);
616 }
617
combo_dynamically_set_title_changed_cb(GtkWidget * w,tilda_window * tw)618 static void combo_dynamically_set_title_changed_cb (GtkWidget *w, tilda_window *tw)
619 {
620 const gint status = gtk_combo_box_get_active (GTK_COMBO_BOX(w));
621
622 config_setint ("d_set_title", status);
623 window_title_change_all (tw);
624 }
625
combo_title_behaviour_changed_cb(GtkWidget * w,tilda_window * tw)626 static void combo_title_behaviour_changed_cb (GtkWidget *w, tilda_window *tw)
627 {
628 DEBUG_FUNCTION ("combo_title_behaviour_changed_cb");
629
630 GtkWidget *entry = GTK_WIDGET(
631 gtk_builder_get_object (xml, ("spin_title_max_length"))
632 );
633 const gint status = gtk_combo_box_get_active (GTK_COMBO_BOX(w));
634 config_setint("title_behaviour", status);
635 if (status > 0) {
636 gtk_widget_set_sensitive (entry, TRUE);
637 } else {
638 gtk_widget_set_sensitive (entry, FALSE);
639 }
640 }
641
spin_max_title_length_changed_cb(GtkWidget * w,tilda_window * tw)642 static void spin_max_title_length_changed_cb (GtkWidget *w, tilda_window *tw)
643 {
644 DEBUG_FUNCTION ("spin_max_title_length_changed_cb");
645
646 int length = gtk_spin_button_get_value (GTK_SPIN_BUTTON (w));
647
648 config_setint ("title_max_length", length);
649 window_title_change_all (tw);
650 }
651
check_run_custom_command_toggled_cb(GtkWidget * w,tilda_window * tw)652 static void check_run_custom_command_toggled_cb (GtkWidget *w, tilda_window *tw)
653 {
654 const gboolean status = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(w));
655 GtkWidget *label_custom_command;
656 GtkWidget *entry_custom_command;
657 GtkWidget *check_command_login_shell;
658
659 config_setbool ("run_command", status);
660
661 label_custom_command =
662 GTK_WIDGET (gtk_builder_get_object (xml, "label_custom_command"));
663 entry_custom_command =
664 GTK_WIDGET (gtk_builder_get_object (xml, "entry_custom_command"));
665 check_command_login_shell =
666 GTK_WIDGET (gtk_builder_get_object (xml, "check_command_login_shell"));
667
668 gtk_widget_set_sensitive (label_custom_command, status);
669 gtk_widget_set_sensitive (entry_custom_command, status);
670 gtk_widget_set_sensitive (check_command_login_shell, !status);
671
672 if(!status) {
673 gtk_entry_set_icon_from_icon_name(GTK_ENTRY(entry_custom_command),
674 GTK_ENTRY_ICON_SECONDARY,
675 NULL);
676 }
677
678 gtk_widget_grab_focus(entry_custom_command);
679 }
680
681
682 /**
683 * Check that the value entered into the GtkEntry is a valid command
684 * which is accessible from the users PATH environment variable.
685 * If the command is not found on the users PATH then a small error
686 * icon is displayed on the end of the entry.
687 * This function can only be registered to Widgets of (sub)type GtkEntry
688 */
validate_executable_command_cb(GtkWidget * w,G_GNUC_UNUSED GdkEvent * event,G_GNUC_UNUSED tilda_window * tw)689 static void validate_executable_command_cb (GtkWidget *w,
690 G_GNUC_UNUSED GdkEvent *event,
691 G_GNUC_UNUSED tilda_window *tw)
692 {
693 g_return_if_fail(w != NULL && GTK_IS_ENTRY(w));
694 const char* command = gtk_entry_get_text (GTK_ENTRY(w));
695 /* Check that the command exists */
696 int argc = 0;
697 gchar** argv = NULL;
698 GError *error = NULL;
699 gboolean success = g_shell_parse_argv(command, &argc, &argv, &error);
700 char *command_filename = NULL;
701 if(success && argc > 0) {
702 command_filename = g_find_program_in_path(argv[0]);
703 }
704 g_strfreev(argv);
705
706 if (command_filename == NULL && gtk_widget_is_sensitive(w)) {
707 //wrong command
708 gtk_entry_set_icon_from_icon_name(GTK_ENTRY(w),
709 GTK_ENTRY_ICON_SECONDARY, "dialog-error");
710 gtk_entry_set_icon_tooltip_text(GTK_ENTRY(w),
711 GTK_ENTRY_ICON_SECONDARY,
712 "The command you have entered is not a valid command.\n"
713 "Make sure that the specified executable is in your PATH environment variable."
714 );
715 } else {
716 gtk_entry_set_icon_from_icon_name(GTK_ENTRY(w),
717 GTK_ENTRY_ICON_SECONDARY,
718 NULL);
719 free(command_filename);
720 }
721 }
722
check_confirm_close_tab_cb(GtkWidget * w,G_GNUC_UNUSED tilda_window * tw)723 static void check_confirm_close_tab_cb (GtkWidget *w,
724 G_GNUC_UNUSED tilda_window *tw)
725 {
726 const gboolean active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w));
727
728 config_setbool ("confirm_close_tab", active);
729 }
730
combo_command_exit_changed_cb(GtkWidget * w,tilda_window * tw)731 static void combo_command_exit_changed_cb (GtkWidget *w, tilda_window *tw) {
732 const gint status = gtk_combo_box_get_active (GTK_COMBO_BOX(w));
733
734 config_setint ("command_exit", status);
735 }
736
check_command_login_shell_cb(GtkWidget * w,tilda_window * tw)737 static void check_command_login_shell_cb (GtkWidget *w, tilda_window *tw) {
738 const gboolean active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w));
739
740 config_setbool("command_login_shell", active);
741 }
742
check_start_fullscreen_cb(GtkWidget * w,tilda_window * tw)743 static void check_start_fullscreen_cb(GtkWidget *w, tilda_window *tw) {
744 const gboolean start_fullscreen = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w));
745
746 config_setbool("start_fullscreen", start_fullscreen);
747 }
748
combo_on_last_terminal_exit_changed_cb(GtkWidget * w,tilda_window * tw)749 static void combo_on_last_terminal_exit_changed_cb (GtkWidget *w, tilda_window *tw)
750 {
751 const gint status = gtk_combo_box_get_active (GTK_COMBO_BOX(w));
752
753 config_setint ("on_last_terminal_exit", status);
754 }
755
check_prompt_on_exit_toggled_cb(GtkWidget * w,tilda_window * tw)756 static void check_prompt_on_exit_toggled_cb (GtkWidget *w, tilda_window *tw)
757 {
758 const gboolean prompt_on_exit = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w));
759
760 config_setbool("prompt_on_exit", prompt_on_exit);
761 }
762
check_show_title_tooltip_toggled_cb(GtkWidget * w,tilda_window * tw)763 static void check_show_title_tooltip_toggled_cb (GtkWidget *w, tilda_window *tw)
764 {
765 const gboolean show_title_tooltip = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w));
766
767 config_setbool("show_title_tooltip", show_title_tooltip);
768 window_title_change_all (tw);
769 }
770
entry_web_browser_changed(GtkWidget * w,tilda_window * tw)771 static void entry_web_browser_changed (GtkWidget *w, tilda_window *tw) {
772 const gchar *web_browser = gtk_entry_get_text (GTK_ENTRY(w));
773
774 config_setstr ("web_browser", web_browser);
775 }
776
entry_word_chars_changed(GtkWidget * w,tilda_window * tw)777 static void entry_word_chars_changed (GtkWidget *w, tilda_window *tw)
778 {
779 guint i;
780 tilda_term *tt;
781 const gchar *word_chars = gtk_entry_get_text (GTK_ENTRY(w));
782
783 /* restore to default value if user clears this setting */
784 if (NULL == word_chars || '\0' == word_chars[0])
785 word_chars = DEFAULT_WORD_CHARS;
786
787 config_setstr ("word_chars", word_chars);
788
789 for (i=0; i<g_list_length (tw->terms); i++) {
790 tt = g_list_nth_data (tw->terms, i);
791 vte_terminal_set_word_char_exceptions (VTE_TERMINAL (tt->vte_term), word_chars);
792 }
793 }
794
795 /*
796 * Prototypes for the next 4 functions.
797 */
798 //Both height functions depend on each other
799 static void spin_height_percentage_value_changed_cb (GtkWidget *w, tilda_window *tw);
800 static void spin_height_pixels_value_changed_cb (GtkWidget *w, tilda_window *tw);
801 //Both width functions depend on each other
802 static void spin_width_percentage_value_changed_cb (GtkWidget *w, tilda_window *tw);
803 static void spin_width_pixels_value_changed_cb (GtkWidget *w, tilda_window *tw);
804
805 static void initialize_scrollback_settings(void);
806 static void initialize_set_as_desktop_checkbox (void);
807
spin_height_percentage_value_changed_cb(GtkWidget * spin_height_percentage,tilda_window * tw)808 static void spin_height_percentage_value_changed_cb (GtkWidget *spin_height_percentage,
809 tilda_window *tw)
810 {
811 DEBUG_FUNCTION ("spin_height_percentage_value_changed_cb");
812
813 const GtkWidget *spin_height_pixels =
814 GTK_WIDGET (gtk_builder_get_object (xml, "spin_height_pixels"));
815
816 const gdouble height_percentage = gtk_spin_button_get_value (GTK_SPIN_BUTTON(spin_height_percentage)) / 100;
817 const gint height_pixels = pixels_ratio_to_absolute (get_max_height(), height_percentage);
818
819 config_setint ("height_percentage", GLONG_FROM_DOUBLE (height_percentage));
820
821 set_spin_value_while_blocking_callback (GTK_SPIN_BUTTON(spin_height_pixels),
822 &spin_height_pixels_value_changed_cb,
823 height_pixels, tw);
824
825 GdkRectangle rectangle;
826 config_get_configured_window_size (&rectangle);
827
828 gtk_window_resize (GTK_WINDOW(tw->window), rectangle.width, height_pixels);
829
830 if (config_getbool ("centered_vertically"))
831 {
832 config_setint ("y_pos", tilda_window_find_centering_coordinate (tw, HEIGHT));
833
834 gtk_window_move (GTK_WINDOW(tw->window),
835 config_getint ("x_pos"),
836 config_getint ("y_pos"));
837 }
838
839 /* Always regenerate animation positions when changing x or y position!
840 * Otherwise you get VERY strange things going on :) */
841 generate_animation_positions (tw);
842 }
843
844
spin_height_pixels_value_changed_cb(GtkWidget * spin_height_pixels,tilda_window * tw)845 static void spin_height_pixels_value_changed_cb (GtkWidget *spin_height_pixels,
846 tilda_window *tw)
847 {
848 DEBUG_FUNCTION ("spin_height_pixels_value_changed_cb");
849
850 const GtkWidget *spin_height_percentage =
851 GTK_WIDGET (gtk_builder_get_object (xml, "spin_height_percentage"));
852 const gint height_pixels = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(spin_height_pixels));
853 const gdouble height_percentage = pixels_absolute_to_ratio (get_max_height(), height_pixels);
854
855 config_setint ("height_percentage", GLONG_FROM_DOUBLE (height_percentage));
856
857 set_spin_value_while_blocking_callback (GTK_SPIN_BUTTON(spin_height_percentage),
858 &spin_height_percentage_value_changed_cb,
859 height_percentage * 100, tw);
860
861 GdkRectangle rectangle;
862 config_get_configured_window_size (&rectangle);
863
864 gtk_window_resize (GTK_WINDOW(tw->window), rectangle.width, height_pixels);
865
866 if (config_getbool ("centered_vertically"))
867 {
868 config_setint ("y_pos", tilda_window_find_centering_coordinate (tw, HEIGHT));
869
870 gtk_window_move (GTK_WINDOW(tw->window),
871 config_getint ("x_pos"),
872 config_getint ("y_pos"));
873 }
874
875 /* Always regenerate animation positions when changing x or y position!
876 * Otherwise you get VERY strange things going on :) */
877 generate_animation_positions (tw);
878 }
879
spin_width_percentage_value_changed_cb(GtkWidget * spin_width_percentage,tilda_window * tw)880 static void spin_width_percentage_value_changed_cb (GtkWidget *spin_width_percentage,
881 tilda_window *tw)
882 {
883 DEBUG_FUNCTION ("spin_width_percentage_value_changed_cb");
884
885 const GtkWidget *spin_width_pixels =
886 GTK_WIDGET (gtk_builder_get_object (xml, "spin_width_pixels"));
887
888 const gdouble width_percentage = gtk_spin_button_get_value (GTK_SPIN_BUTTON(spin_width_percentage)) / 100;
889 const gint width_pixels = pixels_ratio_to_absolute (get_max_width(), width_percentage);
890
891 config_setint ("width_percentage", GLONG_FROM_DOUBLE(width_percentage));
892
893 set_spin_value_while_blocking_callback (GTK_SPIN_BUTTON(spin_width_pixels),
894 &spin_width_pixels_value_changed_cb,
895 width_pixels, tw);
896
897 GdkRectangle rectangle;
898 config_get_configured_window_size (&rectangle);
899
900 gtk_window_resize (GTK_WINDOW(tw->window), width_pixels, rectangle.height);
901
902 if (config_getbool ("centered_horizontally"))
903 {
904 config_setint ("x_pos", tilda_window_find_centering_coordinate (tw, WIDTH));
905
906 gtk_window_move (GTK_WINDOW(tw->window),
907 config_getint ("x_pos"),
908 config_getint ("y_pos"));
909 }
910
911 /* Always regenerate animation positions when changing x or y position!
912 * Otherwise you get VERY strange things going on :) */
913 generate_animation_positions (tw);
914 }
915
spin_width_pixels_value_changed_cb(GtkWidget * spin_width_pixels,tilda_window * tw)916 static void spin_width_pixels_value_changed_cb (GtkWidget *spin_width_pixels, tilda_window *tw)
917 {
918 DEBUG_FUNCTION ("spin_width_pixels_value_changed_cb");
919
920 const GtkWidget *spin_width_percentage =
921 GTK_WIDGET (gtk_builder_get_object (xml, "spin_width_percentage"));
922
923 const gint width_pixels = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(spin_width_pixels));
924 const gdouble width_percentage = pixels_absolute_to_ratio (get_max_width(), width_pixels);
925
926 config_setint ("width_percentage", GLONG_FROM_DOUBLE(width_percentage));
927
928 set_spin_value_while_blocking_callback (GTK_SPIN_BUTTON(spin_width_percentage),
929 &spin_width_percentage_value_changed_cb,
930 width_percentage * 100, tw);
931
932 GdkRectangle rectangle;
933 config_get_configured_window_size (&rectangle);
934
935 gtk_window_resize (GTK_WINDOW(tw->window), width_pixels, rectangle.height);
936
937 if (config_getbool ("centered_horizontally"))
938 {
939 config_setint ("x_pos", tilda_window_find_centering_coordinate (tw, WIDTH));
940
941 gtk_window_move (GTK_WINDOW(tw->window),
942 config_getint ("x_pos"),
943 config_getint ("y_pos"));
944 }
945
946 /* Always regenerate animation positions when changing x or y position!
947 * Otherwise you get VERY strange things going on :) */
948 generate_animation_positions (tw);
949 }
950
check_centered_horizontally_toggled_cb(GtkWidget * w,tilda_window * tw)951 static void check_centered_horizontally_toggled_cb (GtkWidget *w, tilda_window *tw)
952 {
953 DEBUG_FUNCTION ("check_centered_horizontally_toggled_cb");
954
955 const gboolean active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(w));
956 const GtkWidget *label_x_position =
957 GTK_WIDGET (gtk_builder_get_object (xml, "label_x_position"));
958 const GtkWidget *spin_x_position =
959 GTK_WIDGET (gtk_builder_get_object (xml, "spin_x_position"));
960
961 config_setbool ("centered_horizontally", active);
962
963 if (active)
964 config_setint ("x_pos", tilda_window_find_centering_coordinate (tw, WIDTH));
965 else
966 config_setint ("x_pos", gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(spin_x_position)));
967
968 gtk_widget_set_sensitive (GTK_WIDGET(label_x_position), !active);
969 gtk_widget_set_sensitive (GTK_WIDGET(spin_x_position), !active);
970
971 gtk_window_move (GTK_WINDOW(tw->window), config_getint ("x_pos"), config_getint ("y_pos"));
972
973 /* Always regenerate animation positions when changing x or y position!
974 * Otherwise you get VERY strange things going on :) */
975 generate_animation_positions (tw);
976 }
977
spin_x_position_value_changed_cb(GtkWidget * w,tilda_window * tw)978 static void spin_x_position_value_changed_cb (GtkWidget *w, tilda_window *tw)
979 {
980 DEBUG_FUNCTION ("spin_x_position_value_changed_cb");
981
982 const gint x_pos = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(w));
983 const gint y_pos = config_getint ("y_pos");
984
985 config_setint ("x_pos", x_pos);
986 gtk_window_move (GTK_WINDOW(tw->window), x_pos, y_pos);
987
988 /* Always regenerate animation positions when changing x or y position!
989 * Otherwise you get VERY strange things going on :) */
990 generate_animation_positions (tw);
991 }
992
check_centered_vertically_toggled_cb(GtkWidget * w,tilda_window * tw)993 static void check_centered_vertically_toggled_cb (GtkWidget *w, tilda_window *tw)
994 {
995 DEBUG_FUNCTION ("check_centered_vertically_toggled_cb");
996
997 const gboolean active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(w));
998 const GtkWidget *label_y_position =
999 GTK_WIDGET (gtk_builder_get_object (xml, "label_y_position"));
1000 const GtkWidget *spin_y_position =
1001 GTK_WIDGET (gtk_builder_get_object (xml, "spin_y_position"));
1002
1003 config_setbool ("centered_vertically", active);
1004
1005 if (active)
1006 config_setint ("y_pos", tilda_window_find_centering_coordinate (tw, HEIGHT));
1007 else
1008 config_setint ("y_pos", gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(spin_y_position)));
1009
1010 gtk_widget_set_sensitive (GTK_WIDGET(label_y_position), !active);
1011 gtk_widget_set_sensitive (GTK_WIDGET(spin_y_position), !active);
1012
1013 gtk_window_move (GTK_WINDOW(tw->window), config_getint ("x_pos"), config_getint ("y_pos"));
1014
1015 /* Always regenerate animation positions when changing x or y position!
1016 * Otherwise you get VERY strange things going on :) */
1017 generate_animation_positions (tw);
1018 }
1019
spin_y_position_value_changed_cb(GtkWidget * w,tilda_window * tw)1020 static void spin_y_position_value_changed_cb (GtkWidget *w, tilda_window *tw)
1021 {
1022 DEBUG_FUNCTION ("spin_y_position_value_changed_cb");
1023
1024 const gint x_pos = config_getint ("x_pos");
1025 const gint y_pos = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(w));
1026
1027 config_setint ("y_pos", y_pos);
1028 gtk_window_move (GTK_WINDOW(tw->window), x_pos, y_pos);
1029
1030 /* Always regenerate animation positions when changing x or y position!
1031 * Otherwise you get VERY strange things going on :) */
1032 generate_animation_positions (tw);
1033 }
1034
combo_tab_pos_changed_cb(GtkWidget * w,tilda_window * tw)1035 static void combo_tab_pos_changed_cb (GtkWidget *w, tilda_window *tw)
1036 {
1037 const gint status = gtk_combo_box_get_active (GTK_COMBO_BOX(w));
1038 const GtkPositionType positions[] = {
1039 GTK_POS_TOP,
1040 GTK_POS_BOTTOM,
1041 GTK_POS_LEFT,
1042 GTK_POS_RIGHT };
1043
1044 if (status < 0 || status > 4) {
1045 DEBUG_ERROR ("Notebook tab position invalid");
1046 g_printerr (_("Invalid tab position setting, ignoring\n"));
1047 return;
1048 }
1049
1050 config_setint ("tab_pos", status);
1051
1052 if(NB_HIDDEN == status) {
1053 gtk_notebook_set_show_tabs (GTK_NOTEBOOK(tw->notebook), FALSE);
1054 }
1055 else {
1056 if (gtk_notebook_get_n_pages(GTK_NOTEBOOK (tw->notebook)) > 1) {
1057 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(tw->notebook), TRUE);
1058 }
1059 gtk_notebook_set_tab_pos (GTK_NOTEBOOK(tw->notebook), positions[status]);
1060 }
1061 }
1062
check_expand_tabs_toggled_cb(GtkWidget * w,tilda_window * tw)1063 static void check_expand_tabs_toggled_cb (GtkWidget *w, tilda_window *tw)
1064 {
1065 const gboolean status = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(w));
1066
1067 config_setbool ("expand_tabs", status);
1068
1069 int page = 0;
1070 GtkWidget *child = NULL;
1071 while((child = gtk_notebook_get_nth_page(GTK_NOTEBOOK (tw->notebook),
1072 page++)))
1073 {
1074 gtk_container_child_set (GTK_CONTAINER(tw->notebook),
1075 child,
1076 "tab-expand", status,
1077 "tab-fill", status,
1078 NULL);
1079 }
1080 }
1081
check_show_single_tab_toggled_cb(GtkWidget * w,tilda_window * tw)1082 static void check_show_single_tab_toggled_cb (GtkWidget *w, tilda_window *tw)
1083 {
1084 const gboolean status = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(w));
1085
1086 config_setbool ("show_single_tab", status);
1087
1088 /* Only need to do something if the current number of tabs is 1 */
1089 if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (tw->notebook)) == 1)
1090 gtk_notebook_set_show_tabs (GTK_NOTEBOOK (tw->notebook), status);
1091 }
1092
check_enable_transparency_toggled_cb(GtkWidget * w,tilda_window * tw)1093 static void check_enable_transparency_toggled_cb (GtkWidget *w, tilda_window *tw)
1094 {
1095 const gboolean status = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(w));
1096
1097 const GtkWidget *label_level_of_transparency =
1098 GTK_WIDGET (gtk_builder_get_object (xml, "label_level_of_transparency"));
1099 const GtkWidget *spin_level_of_transparency =
1100 GTK_WIDGET (gtk_builder_get_object (xml, "spin_level_of_transparency"));
1101
1102 gtk_widget_set_sensitive (GTK_WIDGET(label_level_of_transparency), status);
1103 gtk_widget_set_sensitive (GTK_WIDGET(spin_level_of_transparency), status);
1104
1105 tilda_window_toggle_transparency(tw);
1106 }
1107
spin_level_of_transparency_value_changed_cb(GtkWidget * w,tilda_window * tw)1108 static void spin_level_of_transparency_value_changed_cb (GtkWidget *w, tilda_window *tw)
1109 {
1110 const gint status = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(w));
1111 guint i;
1112 tilda_term *tt;
1113 GdkRGBA bg;
1114
1115 bg.red = GUINT16_TO_FLOAT(config_getint ("back_red"));
1116 bg.green = GUINT16_TO_FLOAT(config_getint ("back_green"));
1117 bg.blue = GUINT16_TO_FLOAT(config_getint ("back_blue"));
1118 bg.alpha = 1.0 - (status / 100.0);
1119
1120 config_setint ("back_alpha", GUINT16_FROM_FLOAT (bg.alpha));
1121 for (i=0; i<g_list_length (tw->terms); i++) {
1122 tt = g_list_nth_data (tw->terms, i);
1123 vte_terminal_set_color_background(VTE_TERMINAL(tt->vte_term), &bg);
1124 }
1125 }
1126
spin_animation_delay_value_changed_cb(GtkWidget * w,tilda_window * tw)1127 static void spin_animation_delay_value_changed_cb (GtkWidget *w, tilda_window *tw)
1128 {
1129 const gint status = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(w));
1130
1131 config_setint ("slide_sleep_usec", status);
1132 }
1133
combo_animation_orientation_changed_cb(GtkWidget * w,tilda_window * tw)1134 static void combo_animation_orientation_changed_cb (GtkWidget *w, tilda_window *tw)
1135 {
1136 const gint status = gtk_combo_box_get_active (GTK_COMBO_BOX(w));
1137
1138 config_setint ("animation_orientation", status);
1139 generate_animation_positions (tw);
1140 }
1141
check_animated_pulldown_toggled_cb(GtkWidget * w,tilda_window * tw)1142 static void check_animated_pulldown_toggled_cb (GtkWidget *w, tilda_window *tw)
1143 {
1144 const gint status = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(w));
1145 const GtkWidget *label_animation_delay =
1146 GTK_WIDGET (gtk_builder_get_object (xml, "label_animation_delay"));
1147 const GtkWidget *spin_animation_delay =
1148 GTK_WIDGET (gtk_builder_get_object (xml, "spin_animation_delay"));
1149 const GtkWidget *label_animation_orientation =
1150 GTK_WIDGET (gtk_builder_get_object (xml, "label_animation_orientation"));
1151 const GtkWidget *combo_animation_orientation =
1152 GTK_WIDGET (gtk_builder_get_object (xml, "combo_animation_orientation"));
1153
1154 gtk_widget_set_sensitive (GTK_WIDGET(label_animation_delay), status);
1155 gtk_widget_set_sensitive (GTK_WIDGET(spin_animation_delay), status);
1156 gtk_widget_set_sensitive (GTK_WIDGET(label_animation_orientation), status);
1157 gtk_widget_set_sensitive (GTK_WIDGET(combo_animation_orientation), status);
1158
1159 config_setbool ("animation", status);
1160
1161 /* If we just disabled animation, we have to reset the window size to the normal
1162 * size, since the animations change the size of the window, and pull() does nothing more
1163 * than show and place the window. */
1164 if (!status)
1165 {
1166 GdkRectangle rectangle;
1167 config_get_configured_window_size (&rectangle);
1168
1169 guint width = rectangle.width;
1170 guint height = rectangle.height;
1171
1172 gtk_window_resize (GTK_WINDOW(tw->window), width, height);
1173 gtk_window_move (GTK_WINDOW(tw->window), config_getint ("x_pos"), config_getint ("y_pos"));
1174 }
1175
1176 /* Avoids a nasty looking glitch if you switch on animation while the window is
1177 * hidden. It will briefly show at full size, then shrink to the first animation
1178 * position. From there it works fine. */
1179 if (status && tw->current_state == STATE_UP)
1180 {
1181 /* I don't know why, but width=0, height=0 doesn't work. Width=1, height=1 works
1182 * exactly as expected, so I'm leaving it that way. */
1183 gtk_window_resize (GTK_WINDOW(tw->window), 1, 1);
1184 }
1185 }
1186
combo_colorschemes_changed_cb(GtkWidget * w,tilda_window * tw)1187 static void combo_colorschemes_changed_cb (GtkWidget *w, tilda_window *tw)
1188 {
1189 const gint scheme = gtk_combo_box_get_active (GTK_COMBO_BOX(w));
1190 const GtkWidget *colorbutton_text =
1191 GTK_WIDGET (gtk_builder_get_object (xml, "colorbutton_text"));
1192 const GtkWidget *colorbutton_back =
1193 GTK_WIDGET (gtk_builder_get_object (xml, "colorbutton_back"));
1194 GdkRGBA gdk_text, gdk_back;
1195
1196 tilda_term *tt;
1197 guint i;
1198 gboolean nochange = FALSE;
1199
1200 config_setint ("scheme", scheme);
1201
1202 gdk_text.alpha = 1.0;
1203 gdk_back.alpha = 1.0;
1204
1205 switch (scheme) {
1206 /* Green on black */
1207 case 1:
1208 gdk_text.red = gdk_text.blue = 0.0;
1209 gdk_text.green = 1.0;
1210 gdk_back.red = gdk_back.green = gdk_back.blue = 0.0;
1211 break;
1212 /* Black on white */
1213 case 2:
1214 gdk_text.red = gdk_text.green = gdk_text.blue = 0.0;
1215 gdk_back.red = gdk_back.green = gdk_back.blue = 1.0;
1216 break;
1217 /* White on black */
1218 case 3:
1219 gdk_text.red = gdk_text.green = gdk_text.blue = 1.0;
1220 gdk_back.red = gdk_back.green = gdk_back.blue = 0.0;
1221 break;
1222 /* Zenburn */
1223 case 4:
1224 gdk_text.red = 0.86;
1225 gdk_text.green = gdk_text.blue = 0.64;
1226 gdk_back.red = gdk_back.green = gdk_back.blue = 0.25;
1227 break;
1228 /* Solarized Light */
1229 case 5:
1230 gdk_text.red = 0.4;
1231 gdk_text.green = 0.48;
1232 gdk_text.blue = 0.51;
1233 gdk_back.red = 0.99;
1234 gdk_back.green = 0.96;
1235 gdk_back.blue = 0.89;
1236 break;
1237 /* Solarized Dark */
1238 case 6:
1239 gdk_text.red = 0.51;
1240 gdk_text.green = 0.58;
1241 gdk_text.blue = 0.59;
1242 gdk_back.red = 0.0;
1243 gdk_back.green = 0.17;
1244 gdk_back.blue = 0.21;
1245 break;
1246 /* Snazzy */
1247 case 7:
1248 gdk_text.red = 0.94;
1249 gdk_text.green = 0.94;
1250 gdk_text.blue = 0.92;
1251 gdk_back.red = 0.16;
1252 gdk_back.green = 0.16;
1253 gdk_back.blue = 0.21;
1254 break;
1255 /* Custom */
1256 default:
1257 nochange = TRUE;
1258 break;
1259 }
1260
1261 /* If we switched to "Custom", then don't do anything. Let the user continue
1262 * from the current color choice. */
1263 if (!nochange) {
1264 config_setint ("back_red", GUINT16_FROM_FLOAT(gdk_back.red));
1265 config_setint ("back_green", GUINT16_FROM_FLOAT(gdk_back.green));
1266 config_setint ("back_blue", GUINT16_FROM_FLOAT(gdk_back.blue));
1267 config_setint ("text_red", GUINT16_FROM_FLOAT(gdk_text.red));
1268 config_setint ("text_green", GUINT16_FROM_FLOAT(gdk_text.green));
1269 config_setint ("text_blue", GUINT16_FROM_FLOAT(gdk_text.blue));
1270
1271 gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER(colorbutton_text), &gdk_text);
1272 gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER(colorbutton_back), &gdk_back);
1273
1274 for (i=0; i<g_list_length (tw->terms); i++) {
1275 tt = g_list_nth_data (tw->terms, i);
1276 vte_terminal_set_color_foreground (VTE_TERMINAL(tt->vte_term),
1277 &gdk_text);
1278 vte_terminal_set_color_background (VTE_TERMINAL(tt->vte_term),
1279 &gdk_back);
1280 }
1281
1282 tilda_window_refresh_transparency(tw);
1283 }
1284 }
colorbutton_cursor_color_set_cb(GtkWidget * w,tilda_window * tw)1285 static void colorbutton_cursor_color_set_cb (GtkWidget *w, tilda_window *tw)
1286 {
1287 const GtkWidget *combo_colorschemes =
1288 GTK_WIDGET (gtk_builder_get_object (xml, "combo_colorschemes"));
1289
1290 guint i;
1291 tilda_term *tt;
1292 GdkRGBA gdk_cursor_color;
1293
1294 /* The user just changed colors manually, so set the scheme to "Custom" */
1295 gtk_combo_box_set_active (GTK_COMBO_BOX(combo_colorschemes), 0);
1296 config_setint ("scheme", 0);
1297
1298 /* Now get the color that was set, save it, then set it */
1299 gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER(w), &gdk_cursor_color);
1300 config_setint ("cursor_red", GUINT16_FROM_FLOAT(gdk_cursor_color.red));
1301 config_setint ("cursor_green", GUINT16_FROM_FLOAT(gdk_cursor_color.green));
1302 config_setint ("cursor_blue", GUINT16_FROM_FLOAT(gdk_cursor_color.blue));
1303
1304 for (i=0; i<g_list_length (tw->terms); i++) {
1305 tt = g_list_nth_data (tw->terms, i);
1306 vte_terminal_set_color_cursor (VTE_TERMINAL(tt->vte_term),
1307 &gdk_cursor_color);
1308 }
1309 }
1310
colorbutton_text_color_set_cb(GtkWidget * w,tilda_window * tw)1311 static void colorbutton_text_color_set_cb (GtkWidget *w, tilda_window *tw)
1312 {
1313 const GtkWidget *combo_colorschemes =
1314 GTK_WIDGET (gtk_builder_get_object (xml, "combo_colorschemes"));
1315
1316 guint i;
1317 tilda_term *tt;
1318 GdkRGBA gdk_text_color;
1319
1320 /* The user just changed colors manually, so set the scheme to "Custom" */
1321 gtk_combo_box_set_active (GTK_COMBO_BOX(combo_colorschemes), 0);
1322 config_setint ("scheme", 0);
1323
1324 /* Now get the color that was set, save it, then set it */
1325 gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER(w), &gdk_text_color);
1326 config_setint ("text_red", GUINT16_FROM_FLOAT(gdk_text_color.red));
1327 config_setint ("text_green", GUINT16_FROM_FLOAT(gdk_text_color.green));
1328 config_setint ("text_blue", GUINT16_FROM_FLOAT(gdk_text_color.blue));
1329
1330 for (i=0; i<g_list_length (tw->terms); i++) {
1331 tt = g_list_nth_data (tw->terms, i);
1332 vte_terminal_set_color_foreground (VTE_TERMINAL(tt->vte_term),
1333 &gdk_text_color);
1334 }
1335 }
1336
colorbutton_back_color_set_cb(GtkWidget * w,tilda_window * tw)1337 static void colorbutton_back_color_set_cb (GtkWidget *w, tilda_window *tw)
1338 {
1339 const GtkWidget *combo_colorschemes =
1340 GTK_WIDGET (gtk_builder_get_object (xml, "combo_colorschemes"));
1341 guint i;
1342 tilda_term *tt;
1343 GdkRGBA gdk_back_color;
1344
1345 /* The user just changed colors manually, so set the scheme to "Custom" */
1346 gtk_combo_box_set_active (GTK_COMBO_BOX(combo_colorschemes), 0);
1347 config_setint ("scheme", 0);
1348
1349 /* Now get the color that was set, save it, then set it */
1350 gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER(w), &gdk_back_color);
1351 config_setint ("back_red", GUINT16_FROM_FLOAT(gdk_back_color.red));
1352 config_setint ("back_green", GUINT16_FROM_FLOAT(gdk_back_color.green));
1353 config_setint ("back_blue", GUINT16_FROM_FLOAT(gdk_back_color.blue));
1354
1355 for (i=0; i<g_list_length (tw->terms); i++) {
1356 tt = g_list_nth_data (tw->terms, i);
1357 vte_terminal_set_color_background (VTE_TERMINAL(tt->vte_term),
1358 &gdk_back_color);
1359 vte_terminal_set_color_cursor_foreground (VTE_TERMINAL(tt->vte_term),
1360 &gdk_back_color);
1361 }
1362 }
1363
1364
1365 /**
1366 * This function is called if a different color scheme is selected from the combo box.
1367 */
combo_palette_scheme_changed_cb(GtkWidget * w,tilda_window * tw)1368 static void combo_palette_scheme_changed_cb (GtkWidget *w, tilda_window *tw) {
1369 DEBUG_FUNCTION("combo_palette_scheme_changed_cb");
1370 gint i;
1371 guint j;
1372 tilda_term *tt;
1373 GdkRGBA fg, bg;
1374 GtkWidget *color_button;
1375
1376 i = gtk_combo_box_get_active (GTK_COMBO_BOX(w));
1377 /* i = 0 means custom, in that case we do nothing */
1378 TildaColorScheme *tildaPaletteSchemes = tilda_palettes_get_palette_schemes ();
1379
1380 if (i > 0 && i < tilda_palettes_get_n_palette_schemes ()) {
1381
1382 const GdkRGBA *current_palette = tildaPaletteSchemes[i].palette;
1383
1384 color_button =
1385 GTK_WIDGET (gtk_builder_get_object (xml, "colorbutton_text"));
1386 gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER(color_button), &fg);
1387 color_button =
1388 GTK_WIDGET (gtk_builder_get_object (xml, "colorbutton_back"));
1389 gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER(color_button), &bg);
1390
1391 bg.alpha = (config_getbool("enable_transparency")
1392 ? GUINT16_TO_FLOAT(config_getint ("back_alpha")) : 1.0);
1393
1394 tilda_palettes_set_current_palette (current_palette);
1395
1396 /* Set terminal palette. */
1397 for (j=0; j<g_list_length (tw->terms); j++) {
1398 tt = g_list_nth_data (tw->terms, j);
1399 vte_terminal_set_colors (VTE_TERMINAL(tt->vte_term),
1400 &fg,
1401 &bg,
1402 current_palette,
1403 TILDA_COLOR_PALETTE_SIZE);
1404 }
1405
1406 for (j=0; j<TILDA_COLOR_PALETTE_SIZE; j++) {
1407 update_palette_color_button(j);
1408
1409 /* Set palette in the config. */
1410 config_setnint ("palette", GUINT16_FROM_FLOAT(current_palette[j].red), j*3);
1411 config_setnint ("palette", GUINT16_FROM_FLOAT(current_palette[j].green), j*3+1);
1412 config_setnint ("palette", GUINT16_FROM_FLOAT(current_palette[j].blue), j*3+2);
1413 }
1414 }
1415
1416 /* Set palette scheme in the config*/
1417 config_setint ("palette_scheme", i);
1418 }
1419
1420 /**
1421 * This function is called, if the user has changed a single color. The function
1422 * handles this color change, and sets the color schema to "Custom".
1423 */
colorbutton_palette_n_set_cb(GtkWidget * w,tilda_window * tw)1424 static void colorbutton_palette_n_set_cb (GtkWidget *w, tilda_window *tw)
1425 {
1426 DEBUG_FUNCTION("colorbutton_palette_n_set_cb");
1427 const GtkWidget *combo_palette_scheme =
1428 GTK_WIDGET (gtk_builder_get_object (xml, "combo_palette_scheme"));
1429 const gchar* name = gtk_buildable_get_name(GTK_BUILDABLE(w));
1430 guint i;
1431 tilda_term *tt;
1432 GtkWidget *color_button;
1433 GdkRGBA fg, bg;
1434
1435 /* The user just changed the palette manually, so we set the palette scheme to "Custom".
1436 * "Custom" is the 0th element in the palette_schemes.
1437 */
1438 gtk_combo_box_set_active (GTK_COMBO_BOX(combo_palette_scheme), 0);
1439 config_setint ("palette_scheme", 0);
1440
1441 /* We need the index part of the name string, which looks like this:
1442 * "colorbutton_palette_12", so we set the button_index_str to the
1443 * position of the first digit and then convert it into an integer.
1444 */
1445 const char* button_index_str = &name[sizeof("colorbutton_palette_")-1];
1446 i = atoi(button_index_str);
1447
1448 /* Now get the color that was set, save it. */
1449 GdkRGBA *current_palette = tilda_palettes_get_current_palette ();
1450
1451 gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER(w), ¤t_palette[i]);
1452
1453 /* Why saving the whole palette, not the single color that was set,
1454 * is if the config file doesn't exist, and we save the single color,
1455 * then exit, the color always becomes the first color in the config file,
1456 * no matter which one it actually is, and leaves other colors unset.
1457 * Obviously this is not what we want.
1458 * However, maybe there is a better solution for this issue.
1459 */
1460 for (i=0; i<TILDA_COLOR_PALETTE_SIZE; i++)
1461 {
1462 config_setnint ("palette", GUINT16_FROM_FLOAT(current_palette[i].red), i*3);
1463 config_setnint ("palette", GUINT16_FROM_FLOAT(current_palette[i].green), i*3+1);
1464 config_setnint ("palette", GUINT16_FROM_FLOAT(current_palette[i].blue), i*3+2);
1465 }
1466
1467 /* Set terminal palette. */
1468 color_button =
1469 GTK_WIDGET (gtk_builder_get_object (xml, "colorbutton_text"));
1470 gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER(color_button), &fg);
1471 color_button =
1472 GTK_WIDGET (gtk_builder_get_object (xml, "colorbutton_back"));
1473 gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER(color_button), &bg);
1474
1475 for (i=0; i<g_list_length (tw->terms); i++)
1476 {
1477 tt = g_list_nth_data (tw->terms, i);
1478 vte_terminal_set_colors (VTE_TERMINAL (tt->vte_term),
1479 &fg,
1480 &bg,
1481 current_palette,
1482 TILDA_COLOR_PALETTE_SIZE);
1483 }
1484 }
1485
combo_scrollbar_position_changed_cb(GtkWidget * w,tilda_window * tw)1486 static void combo_scrollbar_position_changed_cb (GtkWidget *w, tilda_window *tw)
1487 {
1488 const gint status = gtk_combo_box_get_active (GTK_COMBO_BOX(w));
1489 guint i;
1490 tilda_term *tt;
1491
1492 config_setint ("scrollbar_pos", status);
1493
1494 for (i=0; i<g_list_length (tw->terms); i++)
1495 {
1496 tt = g_list_nth_data (tw->terms, i);
1497 tilda_term_set_scrollbar_position (tt, status);
1498 }
1499 }
1500
spin_scrollback_amount_value_changed_cb(GtkWidget * w,tilda_window * tw)1501 static void spin_scrollback_amount_value_changed_cb (GtkWidget *w, tilda_window *tw)
1502 {
1503 const gint status = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(w));
1504
1505 guint i;
1506 tilda_term *tt;
1507
1508 config_setint ("lines", status);
1509
1510 for (i=0; i<g_list_length (tw->terms); i++) {
1511 tt = g_list_nth_data (tw->terms, i);
1512 vte_terminal_set_scrollback_lines (VTE_TERMINAL(tt->vte_term), status);
1513 }
1514 }
1515
check_infinite_scrollback_toggled_cb(GtkWidget * w,tilda_window * tw)1516 static void check_infinite_scrollback_toggled_cb(GtkWidget *w, tilda_window *tw)
1517 {
1518 // if status is false then scrollback is infinite, otherwise the spinner is active
1519 const gboolean hasScrollbackLimit = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(w));
1520
1521 config_setbool ("scroll_history_infinite", !hasScrollbackLimit);
1522
1523 GtkWidget *spinner = (GtkWidget *) gtk_builder_get_object(xml, "spin_scrollback_amount");
1524 gint scrollback_lines = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(spinner));
1525 GtkWidget *label = (GtkWidget *) gtk_builder_get_object(xml, "label_scrollback_lines");
1526
1527 gtk_widget_set_sensitive(spinner, hasScrollbackLimit);
1528 gtk_widget_set_sensitive(label, hasScrollbackLimit);
1529
1530 guint i;
1531 tilda_term *tt;
1532
1533 if(!hasScrollbackLimit) {
1534 scrollback_lines = -1;
1535 }
1536
1537 for (i=0; i<g_list_length (tw->terms); i++) {
1538 tt = g_list_nth_data (tw->terms, i);
1539 vte_terminal_set_scrollback_lines(VTE_TERMINAL(tt->vte_term), scrollback_lines);
1540 }
1541 }
1542
check_scroll_on_output_toggled_cb(GtkWidget * w,tilda_window * tw)1543 static void check_scroll_on_output_toggled_cb (GtkWidget *w, tilda_window *tw)
1544 {
1545 const gboolean status = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(w));
1546 guint i;
1547 tilda_term *tt;
1548
1549 config_setbool ("scroll_on_output", status);
1550
1551 for (i=0; i<g_list_length (tw->terms); i++) {
1552 tt = g_list_nth_data (tw->terms, i);
1553 vte_terminal_set_scroll_on_output (VTE_TERMINAL(tt->vte_term), status);
1554 }
1555 }
1556
check_scroll_on_keystroke_toggled_cb(GtkWidget * w,tilda_window * tw)1557 static void check_scroll_on_keystroke_toggled_cb (GtkWidget *w, tilda_window *tw)
1558 {
1559 const gboolean status = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(w));
1560 guint i;
1561 tilda_term *tt;
1562
1563 config_setbool ("scroll_on_key", status);
1564
1565 for (i=0; i<g_list_length (tw->terms); i++) {
1566 tt = g_list_nth_data (tw->terms, i);
1567 vte_terminal_set_scroll_on_keystroke (VTE_TERMINAL(tt->vte_term), status);
1568 }
1569 }
1570
combo_backspace_binding_changed_cb(GtkWidget * w,tilda_window * tw)1571 static void combo_backspace_binding_changed_cb (GtkWidget *w, tilda_window *tw)
1572 {
1573 const gint status = gtk_combo_box_get_active (GTK_COMBO_BOX(w));
1574 const gint keys[] = { VTE_ERASE_ASCII_DELETE,
1575 VTE_ERASE_DELETE_SEQUENCE,
1576 VTE_ERASE_ASCII_BACKSPACE,
1577 VTE_ERASE_AUTO };
1578 guint i;
1579 tilda_term *tt;
1580
1581 config_setint ("backspace_key", status);
1582
1583 for (i=0; i<g_list_length (tw->terms); i++) {
1584 tt = g_list_nth_data (tw->terms, i);
1585 vte_terminal_set_backspace_binding (VTE_TERMINAL(tt->vte_term), keys[status]);
1586 }
1587 }
1588
combo_delete_binding_changed_cb(GtkWidget * w,tilda_window * tw)1589 static void combo_delete_binding_changed_cb (GtkWidget *w, tilda_window *tw)
1590 {
1591 const gint status = gtk_combo_box_get_active (GTK_COMBO_BOX(w));
1592 const gint keys[] = { VTE_ERASE_ASCII_DELETE,
1593 VTE_ERASE_DELETE_SEQUENCE,
1594 VTE_ERASE_ASCII_BACKSPACE,
1595 VTE_ERASE_AUTO };
1596 guint i;
1597 tilda_term *tt;
1598
1599 config_setint ("delete_key", status);
1600
1601 for (i=0; i<g_list_length (tw->terms); i++) {
1602 tt = g_list_nth_data (tw->terms, i);
1603 vte_terminal_set_delete_binding (VTE_TERMINAL(tt->vte_term), keys[status]);
1604 }
1605 }
1606
button_reset_compatibility_options_clicked_cb(tilda_window * tw)1607 static void button_reset_compatibility_options_clicked_cb (tilda_window *tw)
1608 {
1609 const GtkWidget *combo_backspace_binding =
1610 GTK_WIDGET (gtk_builder_get_object (xml, "combo_backspace_binding"));
1611 const GtkWidget *combo_delete_binding =
1612 GTK_WIDGET (gtk_builder_get_object (xml, "combo_delete_binding"));
1613
1614 config_setint ("backspace_key", 0);
1615 config_setint ("delete_key", 1);
1616
1617 gtk_combo_box_set_active (GTK_COMBO_BOX(combo_backspace_binding), 0);
1618 gtk_combo_box_set_active (GTK_COMBO_BOX(combo_delete_binding), 1);
1619 }
1620
1621 static void
initialize_combo_choose_monitor(tilda_window * tw)1622 initialize_combo_choose_monitor(tilda_window *tw)
1623 {
1624 DEBUG_FUNCTION ("initialize_combo_choose_monitor");
1625
1626 /**
1627 * First we need to initialize the "combo_choose_monitor" widget,
1628 * with the numbers of each monitor attached to the system.
1629 */
1630 GdkDisplay *display = gdk_display_get_default ();
1631 int num_monitors = gdk_display_get_n_monitors (display);
1632 GdkMonitor *active_monitor = tilda_window_find_monitor_number(tw);
1633
1634 GtkComboBox* combo_choose_monitor =
1635 GTK_COMBO_BOX(gtk_builder_get_object(xml,"combo_choose_monitor"));
1636 GtkListStore* monitor_model =
1637 GTK_LIST_STORE(gtk_combo_box_get_model(combo_choose_monitor));
1638 GtkTreeIter iter;
1639 gint i;
1640
1641 gtk_list_store_clear(monitor_model);
1642
1643 for (i = 0; i < num_monitors; i++) {
1644 GdkMonitor *monitor;
1645
1646 gtk_list_store_append(monitor_model, &iter);
1647 monitor = gdk_display_get_monitor (display, i);
1648
1649 const gchar *monitor_model_name = gdk_monitor_get_model (monitor);
1650 gchar *display_name = g_strdup_printf ("%d <i>(%s)</i>", i, monitor_model_name);
1651
1652 gtk_list_store_set(monitor_model, &iter,
1653 0, monitor_model_name,
1654 1, i,
1655 2, display_name,
1656 -1);
1657
1658 if(monitor == active_monitor) {
1659 gtk_combo_box_set_active_iter(combo_choose_monitor, &iter);
1660 }
1661
1662 g_free (display_name);
1663 }
1664 }
1665
1666 /**
1667 * Here the geometry options in the appearance tab get initialized. The options are:
1668 * height and width (both absolute and in percentage), x and y positions as well as the
1669 * check boxes for centering.
1670 * Because we might have multiple monitors we first need to get the monitor that
1671 * is currently selected to show the window and then load its geometry information.
1672 */
initialize_geometry_spinners(tilda_window * tw)1673 static void initialize_geometry_spinners(tilda_window *tw) {
1674 DEBUG_FUNCTION ("initialize_geometry_spinners");
1675
1676 GdkMonitor *monitor = tilda_window_find_monitor_number(tw);
1677 GdkRectangle rectangle;
1678
1679 gdk_monitor_get_workarea (monitor, &rectangle);
1680 int monitor_height = rectangle.height;
1681 int monitor_width = rectangle.width;
1682
1683 /* Update range and value of height spinners */
1684 GdkRectangle tilda_rectangle;
1685 config_get_configured_window_size (&tilda_rectangle);
1686
1687 gint width = tilda_rectangle.width;
1688 gint height = tilda_rectangle.height;
1689
1690 gdouble height_percentage =
1691 GLONG_TO_DOUBLE (config_getint("height_percentage")) * 100;
1692
1693 gdouble width_percentage =
1694 GLONG_TO_DOUBLE (config_getint("width_percentage")) * 100;
1695
1696 SPIN_BUTTON_SET_RANGE("spin_height_percentage", 0, 100);
1697 SPIN_BUTTON_SET_VALUE ("spin_height_percentage", height_percentage);
1698 SPIN_BUTTON_SET_RANGE("spin_height_pixels", 0, monitor_height);
1699 SPIN_BUTTON_SET_VALUE("spin_height_pixels", height);
1700
1701 /* Update range and value of width spinners */
1702 SPIN_BUTTON_SET_RANGE("spin_width_percentage", 0, 100);
1703 SPIN_BUTTON_SET_VALUE ("spin_width_percentage", width_percentage);
1704 SPIN_BUTTON_SET_RANGE("spin_width_pixels", 0, monitor_width);
1705 SPIN_BUTTON_SET_VALUE("spin_width_pixels", width);
1706
1707 CHECK_BUTTON("check_centered_horizontally", "centered_horizontally");
1708 CHECK_BUTTON("check_centered_vertically", "centered_vertically");
1709 CHECK_BUTTON("check_start_fullscreen", "start_fullscreen");
1710
1711 gint xpos = config_getint("x_pos");
1712 if(xpos < rectangle.x) {
1713 xpos = rectangle.x;
1714 config_setint("x_pos", xpos);
1715 }
1716
1717 gint screen_width, screen_height;
1718 screen_size_get_dimensions (&screen_width, &screen_height);
1719 SPIN_BUTTON_SET_RANGE("spin_x_position", 0, screen_width);
1720 SPIN_BUTTON_SET_VALUE("spin_x_position", xpos); /* TODO: Consider x in rectange.x for monitor displacement */
1721
1722 gint ypos = config_getint("y_pos");
1723 if(ypos < rectangle.y) {
1724 ypos = rectangle.y;
1725 config_setint("y_pos", ypos);
1726 }
1727 SPIN_BUTTON_SET_RANGE("spin_y_position", 0, screen_height);
1728 SPIN_BUTTON_SET_VALUE("spin_y_position", ypos);
1729
1730 SET_SENSITIVE_BY_CONFIG_NBOOL("spin_x_position", "centered_horizontally");
1731 SET_SENSITIVE_BY_CONFIG_NBOOL("label_x_position", "centered_horizontally");
1732 SET_SENSITIVE_BY_CONFIG_NBOOL("spin_y_position", "centered_vertically");
1733 SET_SENSITIVE_BY_CONFIG_NBOOL("label_y_position", "centered_vertically");
1734 }
1735
1736 /* Read all state from the config system, and put it into
1737 * its visual representation in the wizard. */
set_wizard_state_from_config(tilda_window * tw)1738 static void set_wizard_state_from_config (tilda_window *tw) {
1739 GdkRGBA text_color, back_color, cursor_color;
1740 guint i;
1741 GdkRGBA *current_palette;
1742
1743 /* General Tab */
1744 CHECK_BUTTON ("check_display_on_all_workspaces", "pinned");
1745 initialize_set_as_desktop_checkbox ();
1746 CHECK_BUTTON ("check_always_on_top", "above");
1747 CHECK_BUTTON ("check_do_not_show_in_taskbar", "notaskbar");
1748 CHECK_BUTTON ("check_start_tilda_hidden", "hidden");
1749 CHECK_BUTTON ("check_show_notebook_border", "notebook_border");
1750 COMBO_BOX ("combo_non_focus_pull_up_behaviour", "non_focus_pull_up_behaviour");
1751
1752 CHECK_BUTTON ("check_terminal_bell", "bell");
1753 CHECK_BUTTON ("check_cursor_blinks", "blinks");
1754 COMBO_BOX ("vte_cursor_shape", "cursor_shape");
1755
1756 FONT_BUTTON ("button_font", "font");
1757
1758 SPIN_BUTTON_SET_RANGE ("spin_auto_hide_time", 0, 99999);
1759 SPIN_BUTTON_SET_VALUE ("spin_auto_hide_time", config_getint ("auto_hide_time"));
1760 CHECK_BUTTON ("check_auto_hide_on_focus_lost", "auto_hide_on_focus_lost");
1761 CHECK_BUTTON ("check_auto_hide_on_mouse_leave", "auto_hide_on_mouse_leave");
1762
1763 /* Title and Command Tab */
1764 TEXT_ENTRY ("entry_title", "title");
1765 COMBO_BOX ("combo_dynamically_set_title", "d_set_title");
1766 // Whether to limit the length of the title
1767 COMBO_BOX ("combo_title_behaviour", "title_behaviour");
1768 // The maximum length of the title
1769 SPIN_BUTTON_SET_RANGE ("spin_title_max_length", 0, 99999);
1770 SPIN_BUTTON_SET_VALUE ("spin_title_max_length", config_getint ("title_max_length"));
1771
1772 CHECK_BUTTON ("check_run_custom_command", "run_command");
1773 TEXT_ENTRY ("entry_custom_command", "command");
1774 CHECK_BUTTON ("check_command_login_shell", "command_login_shell");
1775 COMBO_BOX ("combo_command_exit", "command_exit");
1776 COMBO_BOX ("combo_on_last_terminal_exit", "on_last_terminal_exit");
1777 CHECK_BUTTON ("check_prompt_on_exit", "prompt_on_exit");
1778 SET_SENSITIVE_BY_CONFIG_BOOL ("entry_custom_command","run_command");
1779 SET_SENSITIVE_BY_CONFIG_BOOL ("label_custom_command", "run_command");
1780
1781 TEXT_ENTRY ("entry_web_browser", "web_browser");
1782
1783 CHECK_BUTTON ("check_confirm_close_tab", "confirm_close_tab");
1784
1785 /* Appearance Tab */
1786 /* Initialize the monitor chooser combo box with the numbers of the monitor */
1787 initialize_combo_choose_monitor(tw);
1788
1789
1790 initialize_geometry_spinners(tw);
1791 CHECK_BUTTON ("check_enable_transparency", "enable_transparency");
1792 CHECK_BUTTON ("check_animated_pulldown", "animation");
1793 SPIN_BUTTON ("spin_animation_delay", "slide_sleep_usec");
1794 COMBO_BOX ("combo_animation_orientation", "animation_orientation");
1795
1796 COMBO_BOX ("combo_tab_pos", "tab_pos");
1797 CHECK_BUTTON ("check_expand_tabs", "expand_tabs");
1798 CHECK_BUTTON ("check_show_single_tab", "show_single_tab");
1799 CHECK_BUTTON ("check_show_title_tooltip", "show_title_tooltip");
1800
1801 SET_SENSITIVE_BY_CONFIG_BOOL ("label_level_of_transparency","enable_transparency");
1802 SET_SENSITIVE_BY_CONFIG_BOOL ("spin_level_of_transparency","enable_transparency");
1803 SET_SENSITIVE_BY_CONFIG_BOOL ("label_animation_delay","animation");
1804 SET_SENSITIVE_BY_CONFIG_BOOL ("spin_animation_delay","animation");
1805 SET_SENSITIVE_BY_CONFIG_BOOL ("label_animation_orientation","animation");
1806 SET_SENSITIVE_BY_CONFIG_BOOL ("combo_animation_orientation","animation");
1807
1808 /* Colors Tab */
1809 COMBO_BOX ("combo_colorschemes", "scheme");
1810 text_color.red = GUINT16_TO_FLOAT(config_getint ("text_red"));
1811 text_color.green = GUINT16_TO_FLOAT(config_getint ("text_green"));
1812 text_color.blue = GUINT16_TO_FLOAT(config_getint ("text_blue"));
1813 text_color.alpha = 1.0;
1814 COLOR_CHOOSER ("colorbutton_text", &text_color);
1815 back_color.red = GUINT16_TO_FLOAT(config_getint ("back_red"));
1816 back_color.green = GUINT16_TO_FLOAT(config_getint ("back_green"));
1817 back_color.blue = GUINT16_TO_FLOAT(config_getint ("back_blue"));
1818 back_color.alpha = 1.0;
1819 COLOR_CHOOSER ("colorbutton_back", &back_color);
1820 cursor_color.red = GUINT16_TO_FLOAT(config_getint ("cursor_red"));
1821 cursor_color.green = GUINT16_TO_FLOAT(config_getint ("cursor_green"));
1822 cursor_color.blue = GUINT16_TO_FLOAT(config_getint ("cursor_blue"));
1823 cursor_color.alpha = 1.0;
1824 COLOR_CHOOSER ("colorbutton_cursor", &cursor_color);
1825
1826 COMBO_BOX ("combo_palette_scheme", "palette_scheme");
1827
1828 current_palette = tilda_palettes_get_current_palette ();
1829
1830 for(i = 0;i < TILDA_COLOR_PALETTE_SIZE; i++) {
1831 current_palette[i].red = GUINT16_TO_FLOAT (config_getnint ("palette", i*3));
1832 current_palette[i].green = GUINT16_TO_FLOAT (config_getnint ("palette", i*3+1));
1833 current_palette[i].blue = GUINT16_TO_FLOAT (config_getnint ("palette", i*3+2));
1834 current_palette[i].alpha = 1.0;
1835
1836 update_palette_color_button(i);
1837 }
1838
1839 /* Scrolling Tab */
1840 initialize_scrollback_settings();
1841
1842 /* Compatibility Tab */
1843 COMBO_BOX ("combo_backspace_binding", "backspace_key");
1844 COMBO_BOX ("combo_delete_binding", "delete_key");
1845
1846 TEXT_ENTRY ("entry_word_chars", "word_chars");
1847
1848 gtk_spin_button_set_value(GTK_SPIN_BUTTON(gtk_builder_get_object(xml, ("spin_level_of_transparency"))),
1849 (100 - 100*GUINT16_TO_FLOAT(config_getint("back_alpha"))));
1850 }
1851
initialize_scrollback_settings(void)1852 static void initialize_scrollback_settings(void) {
1853 COMBO_BOX ("combo_scrollbar_position", "scrollbar_pos");
1854 SPIN_BUTTON ("spin_scrollback_amount", "lines");
1855
1856 /* For historical reasons the config value is named "scrollback_history_infinite", but we have changed the
1857 * UI semantics such that the checkbox is activated to limit the scrollback and deactivated to use an infinite
1858 * buffer. Therefore we need to negate the value from the config here. */
1859 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gtk_builder_get_object (xml, "check_infinite_scrollback")),
1860 !config_getbool ("scroll_history_infinite"));
1861 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (xml, ("label_scrollback_lines"))),
1862 !config_getbool ("scroll_history_infinite"));
1863 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (xml, ("spin_scrollback_amount"))),
1864 !config_getbool ("scroll_history_infinite"));
1865
1866 CHECK_BUTTON ("check_scroll_on_output", "scroll_on_output");
1867 CHECK_BUTTON ("check_scroll_on_keystroke", "scroll_on_key");
1868 }
1869
initialize_set_as_desktop_checkbox(void)1870 static void initialize_set_as_desktop_checkbox (void) {
1871 CHECK_BUTTON ("check_set_as_desktop", "set_as_desktop");
1872
1873 GtkWidget *check_set_as_desktop = GTK_WIDGET(gtk_builder_get_object (xml, "check_set_as_desktop"));
1874 GtkWidget *check_display_on_all_workspaces = GTK_WIDGET(gtk_builder_get_object (xml, "check_display_on_all_workspaces"));
1875
1876 gboolean status = config_getbool("set_as_desktop");
1877 gboolean status_display_on_all_workspaces = config_getbool ("pinned");
1878 if (status) {
1879 gtk_widget_set_sensitive (check_display_on_all_workspaces, FALSE);
1880 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_display_on_all_workspaces), TRUE);
1881 } else {
1882 gtk_widget_set_sensitive (check_display_on_all_workspaces, TRUE);
1883 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_display_on_all_workspaces), status_display_on_all_workspaces);
1884 }
1885 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_set_as_desktop), status);
1886 }
1887
1888 #define CONNECT_SIGNAL(GLADE_WIDGET,SIGNAL_NAME,SIGNAL_HANDLER,DATA) g_signal_connect ( \
1889 gtk_builder_get_object (xml, (GLADE_WIDGET)), (SIGNAL_NAME), G_CALLBACK((SIGNAL_HANDLER)), DATA)
1890
1891 /* Connect all signals in the wizard. This should be done after setting all
1892 * values, that way all of the signal handlers don't get called */
connect_wizard_signals(TildaWizard * wizard)1893 static void connect_wizard_signals (TildaWizard *wizard)
1894 {
1895 gint i;
1896 tilda_window *tw = wizard->tw;
1897
1898 /* General Tab */
1899 CONNECT_SIGNAL ("check_display_on_all_workspaces","toggled",check_display_on_all_workspaces_toggled_cb, tw);
1900 CONNECT_SIGNAL ("check_set_as_desktop","toggled",check_set_as_desktop_toggled_cb, tw);
1901 CONNECT_SIGNAL ("check_do_not_show_in_taskbar","toggled",check_do_not_show_in_taskbar_toggled_cb, tw);
1902 CONNECT_SIGNAL ("check_show_notebook_border","toggled",check_show_notebook_border_toggled_cb, tw);
1903 CONNECT_SIGNAL ("check_always_on_top","toggled",check_always_on_top_toggled_cb, tw);
1904 CONNECT_SIGNAL ("check_start_tilda_hidden","toggled",check_start_tilda_hidden_toggled_cb, tw);
1905 CONNECT_SIGNAL ("combo_non_focus_pull_up_behaviour","changed",combo_non_focus_pull_up_behaviour_cb, tw);
1906
1907 CONNECT_SIGNAL ("check_terminal_bell","toggled",check_terminal_bell_toggled_cb, tw);
1908 CONNECT_SIGNAL ("check_cursor_blinks","toggled",check_cursor_blinks_toggled_cb, tw);
1909 CONNECT_SIGNAL ("vte_cursor_shape","changed", combo_cursor_shape_changed_cb, tw);
1910
1911 CONNECT_SIGNAL ("check_start_fullscreen", "toggled", check_start_fullscreen_cb, tw);
1912
1913 CONNECT_SIGNAL ("button_font","font-set",button_font_font_set_cb, tw);
1914
1915 CONNECT_SIGNAL ("spin_auto_hide_time","value-changed",spin_auto_hide_time_value_changed_cb, tw);
1916 CONNECT_SIGNAL ("check_auto_hide_on_focus_lost","toggled",check_auto_hide_on_focus_lost_toggled_cb, tw);
1917 CONNECT_SIGNAL ("check_auto_hide_on_mouse_leave","toggled",check_auto_hide_on_mouse_leave_toggled_cb, tw);
1918
1919 CONNECT_SIGNAL ("combo_on_last_terminal_exit","changed",combo_on_last_terminal_exit_changed_cb, tw);
1920 CONNECT_SIGNAL ("check_prompt_on_exit","toggled",check_prompt_on_exit_toggled_cb, tw);
1921
1922 /* Title and Command Tab */
1923 CONNECT_SIGNAL ("entry_title","changed",entry_title_changed_cb, tw);
1924 CONNECT_SIGNAL ("combo_dynamically_set_title","changed",combo_dynamically_set_title_changed_cb, tw);
1925 CONNECT_SIGNAL ("combo_title_behaviour","changed",combo_title_behaviour_changed_cb, tw);
1926 CONNECT_SIGNAL ("spin_title_max_length","value-changed", spin_max_title_length_changed_cb, tw);
1927
1928 CONNECT_SIGNAL ("check_run_custom_command","toggled",check_run_custom_command_toggled_cb, tw);
1929 CONNECT_SIGNAL ("entry_custom_command","focus-out-event", validate_executable_command_cb, tw);
1930 CONNECT_SIGNAL ("combo_command_exit","changed",combo_command_exit_changed_cb, tw);
1931 CONNECT_SIGNAL ("check_command_login_shell", "toggled", check_command_login_shell_cb, tw);
1932
1933 CONNECT_SIGNAL ("entry_web_browser","changed",entry_web_browser_changed, tw);
1934 CONNECT_SIGNAL ("entry_web_browser","focus-out-event", validate_executable_command_cb, tw);
1935
1936 CONNECT_SIGNAL ("check_confirm_close_tab", "toggled", check_confirm_close_tab_cb, tw);
1937
1938 /* Appearance Tab */
1939 CONNECT_SIGNAL ("combo_choose_monitor", "changed", combo_monitor_selection_changed_cb, tw);
1940 CONNECT_SIGNAL ("spin_height_percentage","value-changed",spin_height_percentage_value_changed_cb, tw);
1941 CONNECT_SIGNAL ("spin_height_pixels","value-changed",spin_height_pixels_value_changed_cb, tw);
1942 CONNECT_SIGNAL ("spin_width_percentage","value-changed",spin_width_percentage_value_changed_cb, tw);
1943 CONNECT_SIGNAL ("spin_width_pixels","value-changed",spin_width_pixels_value_changed_cb, tw);
1944
1945 CONNECT_SIGNAL ("check_centered_horizontally","toggled",check_centered_horizontally_toggled_cb, tw);
1946 CONNECT_SIGNAL ("check_centered_vertically","toggled",check_centered_vertically_toggled_cb, tw);
1947 CONNECT_SIGNAL ("spin_x_position","value-changed",spin_x_position_value_changed_cb, tw);
1948 CONNECT_SIGNAL ("spin_y_position","value-changed",spin_y_position_value_changed_cb, tw);
1949
1950 CONNECT_SIGNAL ("combo_tab_pos","changed",combo_tab_pos_changed_cb, tw);
1951 CONNECT_SIGNAL ("check_expand_tabs","toggled",check_expand_tabs_toggled_cb, tw);
1952 CONNECT_SIGNAL ("check_show_single_tab","toggled",check_show_single_tab_toggled_cb, tw);
1953 CONNECT_SIGNAL ("check_show_title_tooltip","toggled",check_show_title_tooltip_toggled_cb, tw);
1954
1955 CONNECT_SIGNAL ("check_enable_transparency","toggled",check_enable_transparency_toggled_cb, tw);
1956 CONNECT_SIGNAL ("check_animated_pulldown","toggled",check_animated_pulldown_toggled_cb, tw);
1957 CONNECT_SIGNAL ("spin_level_of_transparency","value-changed",spin_level_of_transparency_value_changed_cb, tw);
1958 CONNECT_SIGNAL ("spin_animation_delay","value-changed",spin_animation_delay_value_changed_cb, tw);
1959 CONNECT_SIGNAL ("combo_animation_orientation","changed",combo_animation_orientation_changed_cb, tw);
1960
1961 /* Colors Tab */
1962 CONNECT_SIGNAL ("combo_colorschemes","changed",combo_colorschemes_changed_cb, tw);
1963 CONNECT_SIGNAL ("colorbutton_text","color-set",colorbutton_text_color_set_cb, tw);
1964 CONNECT_SIGNAL ("colorbutton_back","color-set",colorbutton_back_color_set_cb, tw);
1965 CONNECT_SIGNAL ("colorbutton_cursor","color-set",colorbutton_cursor_color_set_cb, tw);
1966 CONNECT_SIGNAL ("combo_palette_scheme","changed",combo_palette_scheme_changed_cb, tw);
1967 for(i = 0; i < TILDA_COLOR_PALETTE_SIZE; i++)
1968 {
1969 char *s = g_strdup_printf ("colorbutton_palette_%d", i);
1970 CONNECT_SIGNAL (s,"color-set",colorbutton_palette_n_set_cb, tw);
1971 g_free (s);
1972 }
1973
1974 /* Scrolling Tab */
1975 CONNECT_SIGNAL ("combo_scrollbar_position","changed",combo_scrollbar_position_changed_cb, tw);
1976 CONNECT_SIGNAL ("spin_scrollback_amount","value-changed",spin_scrollback_amount_value_changed_cb, tw);
1977 CONNECT_SIGNAL ("check_infinite_scrollback", "toggled", check_infinite_scrollback_toggled_cb, tw);
1978 CONNECT_SIGNAL ("check_scroll_on_output","toggled",check_scroll_on_output_toggled_cb, tw);
1979 CONNECT_SIGNAL ("check_scroll_on_keystroke","toggled",check_scroll_on_keystroke_toggled_cb, tw);
1980
1981 /* Compatibility Tab */
1982 CONNECT_SIGNAL ("combo_backspace_binding","changed",combo_backspace_binding_changed_cb, tw);
1983 CONNECT_SIGNAL ("combo_delete_binding","changed",combo_delete_binding_changed_cb, tw);
1984 CONNECT_SIGNAL ("button_reset_compatibility_options","clicked",button_reset_compatibility_options_clicked_cb, tw);
1985
1986 /* Close Button */
1987 CONNECT_SIGNAL ("button_wizard_close","clicked", wizard_button_close_clicked_cb, wizard);
1988 CONNECT_SIGNAL ("wizard_window","delete_event", wizard_window_delete_event_cb, wizard);
1989
1990 CONNECT_SIGNAL ("entry_word_chars", "changed", entry_word_chars_changed, tw);
1991 }
1992
1993 /* Initialize the palette scheme menu.
1994 * Add the predefined schemes to the combo box.*/
init_palette_scheme_menu(void)1995 static void init_palette_scheme_menu (void)
1996 {
1997 gint i;
1998 TildaColorScheme *paletteSchemes;
1999 GtkWidget *combo_palette;
2000
2001 combo_palette = GTK_WIDGET (gtk_builder_get_object (xml,
2002 "combo_palette_scheme"));
2003
2004 i = tilda_palettes_get_n_palette_schemes ();
2005 paletteSchemes = tilda_palettes_get_palette_schemes ();
2006
2007 while (i > 0) {
2008 --i;
2009 const char *palette_name = paletteSchemes[i].name;
2010 gtk_combo_box_text_prepend_text (GTK_COMBO_BOX_TEXT (combo_palette),
2011 _(palette_name));
2012 }
2013 }
2014
update_palette_color_button(gint idx)2015 static void update_palette_color_button(gint idx)
2016 {
2017 GdkRGBA * current_palette;
2018 char *s = g_strdup_printf ("colorbutton_palette_%d", idx);
2019 GtkWidget *color_button =
2020 GTK_WIDGET (gtk_builder_get_object (xml, s));
2021
2022 g_free (s);
2023
2024 current_palette = tilda_palettes_get_current_palette ();
2025
2026 const GdkRGBA *color = tilda_palettes_get_palette_color (current_palette, idx);
2027 gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (color_button),
2028 color);
2029 }
2030