#include <gtk/gtk.h>

static void
fill_buffer (GtkTextBuffer *buffer,
             GtkTextTag    *tag)
{
  GtkTextIter iter;

  gtk_text_buffer_get_start_iter (buffer, &iter);

  gtk_text_buffer_insert_with_tags (buffer,
                                    &iter,
                                    "some\ntext",
                                    -1,
                                    tag,
                                    NULL);
}

static void
weight_toggled_cb (GtkToggleButton *weight_button,
                   GtkTextTag      *tag)
{
  /* Emits the tag-changed signal with size_changed=TRUE, triggers the bug */
  if (gtk_toggle_button_get_active (weight_button))
    g_object_set (tag, "weight", PANGO_WEIGHT_BOLD, NULL);
  else
    g_object_set (tag, "weight", PANGO_WEIGHT_NORMAL, NULL);
}

static void
underline_toggled_cb (GtkToggleButton *underline_button,
                      GtkTextTag      *tag)
{
  /* Emits the tag-changed signal with size_changed=FALSE, OK */
  if (gtk_toggle_button_get_active (underline_button))
    g_object_set (tag, "underline", PANGO_UNDERLINE_SINGLE, NULL);
  else
    g_object_set (tag, "underline", PANGO_UNDERLINE_NONE, NULL);
}

static void
both_toggled_cb (GtkToggleButton *both_button,
                 GtkTextTag      *tag)
{
  /* If the tag-changed signal is emitted only once, it is emitted with
   * size_changed=TRUE which triggers the bug.
   */
  if (gtk_toggle_button_get_active (both_button))
    g_object_set (tag,
                  "underline", PANGO_UNDERLINE_SINGLE,
                  "weight", PANGO_WEIGHT_BOLD,
                  NULL);
  else
    g_object_set (tag,
                  "underline", PANGO_UNDERLINE_NONE,
                  "weight", PANGO_WEIGHT_NORMAL,
                  NULL);
}

static void
create_window (void)
{
  GtkWidget *window;
  GtkWidget *hgrid;
  GtkWidget *panel_grid;
  GtkWidget *scrolled_window;
  GtkWidget *weight_button;
  GtkWidget *underline_button;
  GtkWidget *both_button;
  GtkTextView *view;
  GtkTextBuffer *buffer;
  GtkTextTag *tag;

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_default_size (GTK_WINDOW (window), 800, 600);
  g_signal_connect (window, "destroy", gtk_main_quit, NULL);

  hgrid = gtk_grid_new ();
  gtk_orientable_set_orientation (GTK_ORIENTABLE (hgrid),
				  GTK_ORIENTATION_HORIZONTAL);

  view = GTK_TEXT_VIEW (gtk_text_view_new ());

  g_object_set (view, "expand", TRUE, NULL);

  buffer = gtk_text_view_get_buffer (view);
  tag = gtk_text_buffer_create_tag (buffer, NULL, NULL);
  fill_buffer (buffer, tag);

  panel_grid = gtk_grid_new ();
  gtk_orientable_set_orientation (GTK_ORIENTABLE (panel_grid),
				  GTK_ORIENTATION_VERTICAL);
  gtk_container_add (GTK_CONTAINER (hgrid), panel_grid);

  gtk_grid_set_row_spacing (GTK_GRID (panel_grid), 6);
  g_object_set (panel_grid, "margin", 6, NULL);

  weight_button = gtk_check_button_new_with_label ("weight");
  gtk_container_add (GTK_CONTAINER (panel_grid), weight_button);
  g_signal_connect (weight_button, "toggled", G_CALLBACK (weight_toggled_cb), tag);

  underline_button = gtk_check_button_new_with_label ("underline");
  gtk_container_add (GTK_CONTAINER (panel_grid), underline_button);
  g_signal_connect (underline_button, "toggled", G_CALLBACK (underline_toggled_cb), tag);

  both_button = gtk_check_button_new_with_label ("both");
  gtk_container_add (GTK_CONTAINER (panel_grid), both_button);
  g_signal_connect (both_button, "toggled", G_CALLBACK (both_toggled_cb), tag);

  scrolled_window = gtk_scrolled_window_new (NULL, NULL);
  gtk_container_add (GTK_CONTAINER (scrolled_window), GTK_WIDGET (view));
  gtk_container_add (GTK_CONTAINER (hgrid), scrolled_window);

  gtk_container_add (GTK_CONTAINER (window), hgrid);

  gtk_widget_show_all (window);
}

gint
main (gint    argc,
      gchar **argv)
{
  gtk_init (&argc, &argv);

  create_window ();

  gtk_main ();

  return 0;
}
