[@] A light, but functional terminal emulator - LilyTerm _ O X
[Home] [Features] [Download] [Changelog] [Tips] [About]
Almost all vte based terminal emulators have big problems on geometry. Some terminals can't always keep 80x24 after added/removed tabs. Some terminals can't resize to correct size when its font changed. Some terminals even can't reduce its size after increasing it.

Due to the widget resize behaviors changed in GTK2+ to GTK3+, this problem became almost unfixable.

The following is a tiny vte terminal, which has good geometry with 80x24 and window hints supporting:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79

#include <vte/vte.h>

#if GTK_CHECK_VERSION(2,90,6)
#define gtk_vscrollbar_new(a) gtk_scrollbar_new(GTK_ORIENTATION_VERTICAL,a)
#endif

int main(int argc, char **argv)
{
  gtk_init(&argc, &argv);

  GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  g_signal_connect(G_OBJECT(window), "delete_event",
                   G_CALLBACK(gtk_main_quit), NULL);

#if GTK_CHECK_VERSION(2,91,1)
  gtk_window_set_has_resize_grip(GTK_WINDOW(window), FALSE);
#endif

#if GTK_CHECK_VERSION(2,90,0)
  GtkWidget *box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
  gtk_box_set_homogeneous(GTK_BOX(box), FALSE);
#else
  GtkWidget *box = gtk_hbox_new(FALSE, 0);
#endif
  gtk_container_add(GTK_CONTAINER(window), box);

  GtkWidget *vte = vte_terminal_new();

#if !defined(VTE_CHECK_VERSION)
#define VTE_CHECK_VERSION(a,b,c) FALSE
#endif
#if VTE_CHECK_VERSION(0,25,1)
  gchar *fake_argv[] = {"/bin/bash", "-", NULL};
  vte_terminal_fork_command_full(VTE_TERMINAL(vte), 0, NULL,
                                 fake_argv, NULL, 0, NULL, NULL, NULL, NULL);
#else
  vte_terminal_fork_command(VTE_TERMINAL(vte), NULL, NULL,
                            NULL, NULL, FALSE, FALSE, FALSE);
#endif
  g_signal_connect(G_OBJECT(vte), "child_exited",
                   G_CALLBACK(gtk_main_quit), NULL);
  vte_terminal_set_font_from_string(VTE_TERMINAL(vte), "Monospace 14");
  gtk_box_pack_start(GTK_BOX(box), vte, TRUE, TRUE, 0);

  GtkWidget *scrollbar = gtk_vscrollbar_new(vte_terminal_get_adjustment(
                                            VTE_TERMINAL(vte)));
  gtk_box_pack_end(GTK_BOX(box), scrollbar, FALSE, FALSE, 0);

  GdkGeometry hints = {0};
  GtkBorder *inner_border = NULL;
  gtk_widget_style_get(GTK_WIDGET(vte), "inner-border", &inner_border, NULL);
  if (inner_border)
  {
    hints.base_width = inner_border->left + inner_border->right;
    hints.base_height = inner_border->top + inner_border->bottom;
    hints.width_inc = vte_terminal_get_char_width(VTE_TERMINAL(vte));
    hints.height_inc = vte_terminal_get_char_height(VTE_TERMINAL(vte));
    hints.min_width = hints.base_width + hints.width_inc;
    hints.min_height = hints.base_height + hints.height_inc;
    gtk_window_set_geometry_hints(GTK_WINDOW(window), GTK_WIDGET(vte), &hints,
                                  GDK_HINT_RESIZE_INC | GDK_HINT_MIN_SIZE |
                                  GDK_HINT_BASE_SIZE);
  }

#if GTK_CHECK_VERSION(2,91,5)
  gtk_widget_set_size_request(vte, 80*hints.width_inc+hints.base_width,
                              24*hints.height_inc+hints.base_height);
#endif

  gtk_widget_show_all(window);

#if GTK_CHECK_VERSION(2,91,5)
  gtk_widget_set_size_request(vte, -1, -1);
#endif

  gtk_main();

  return 0;
}

For GTK 2.8 ~ GTK 2.24, Please compile it with:
gcc -Wall -g tiny_vte.c -o tiny_vte `pkg-config --cflags --libs vte`
and, For GTK+ 3.x, Please compile it with:
gcc -Wall -g tiny_vte.c -o tiny_vte `pkg-config --cflags --libs vte-2.90`
The GTK+2 version of tiny_vte may work fine with the most of Window Managers. But the GTK+3 version is not. You may test the GTK+3 version under KWin, the Window Manager of KDE. It will start with 80x24, and reduce its size to 80x2 immediately.

I have no idea how to fix it. Yes, It may be fixed with removing neither the scrollbar (line 47) or window hints (line 60-62). But both scrollbar and window hints are basic components of an terminal emulator. I don't want to remove any of them from LilyTerm just for migrating to GTK3+.

Any idea?