Доброго времени суток уважаемые Хабровчане!

Как говорится дело было вечером под конец рабочего дня, делать было нечего.

Мне показалось удобным закрытие средней кнопкой мыши вкладок в броузере и то ли отсутствие работы то ли просто спортивный интерес, я решил реализовать сие в gnome-terminal.
Не то что бы мне не хватало горячих клавиш, просто хотел что бы такая возможность была, тем более кушать оно не просит.
Если вам интересно как это происходило и с какими проблемами я столкнулся, добро пожаловать под кат.

Начало


Вооружившись кофе я пошел искать исходники gnome-terminal. Гугл бодро выдал первой ссылкой исходники .

Скачав последнюю версию терминала (думаю, а чего мелочится ..) я был жестко обломан, откомпилировать мне его не удалось :(

Плюнув на это дело я скачал версию текущего установленного в системе терминала (2.33.0), который был успешно откомпилирован. Я приступил к своим «исследованиям».

Разбор полётов исходников



Мои знания GTK очень поверхностные, поэтому я понадеялся на читаемость кода и удачу приступил к изучению исходников.

В ходе просмотра файлов я нашел terminal-tab-label.c он мне показался интересным и когда я нашел там создание кнопки закрытия вкладки я решил что нахожусь в нужном месте.

Немного пошуршав документацией (немного расстроил тот факт что в документации куча битых ссылок ) я понял что для того что бы отловить нажатие мышки на надписи нужно вставить следующий код:
g_signal_connect (label, "button-press-event", G_CALLBACK (click_label_cb), tab_label);

Но меня ждало разочарование, событие не обрабатывало.

В документации также было сказано: «To receive this signal, the GdkWindow associated to the widget needs to enable the GDK_BUTTON_PRESS_MASK mask.» (на сайте кстати эта ссылка была битой, но я потом разгадал секрет построения ссылок и нашел нужную страницу.)

Ну что же, раз нужно, значит нужно. Методом поиска и частичного анализа кода я везде добавил строки вида:
gdk_window_set_events(root_window, GDK_BUTTON_PRESS_MASK|GDK_BUTTON_RELEASE_MASK);

Но в который раз был обломан, эффекта не было. Хотя все же есть и плюс. В ходе поиска главного окна я наткнулся на интересную функцию terminal_window_init ( terminal-window.c ), а именно строка:
  g_signal_connect (priv->notebook, "button-press-event",
                    G_CALLBACK (notebook_button_press_cb), window);

В итоге я попробовал вклинится туда.
Немного повозившись я пришел к такому решению:
....
static gboolean
notebook_button_press_cb (GtkWidget *widget,
                          GdkEventButton *event,
                          TerminalWindow *window)
{
  TerminalWindowPrivate *priv = window->priv;
  GtkNotebook *notebook = GTK_NOTEBOOK (widget);
  GtkWidget *menu;
  GtkAction *action;
  int tab_clicked;

  // Начало добавленного кода.
  if (event->type == GDK_BUTTON_PRESS && event->button == 2 ){
    tab_clicked = find_tab_num_at_pos (notebook, event->x_root, event->y_root);
    if (tab_clicked < 0) return FALSE;
    /* switch to the page the mouse is over */
    gtk_notebook_set_current_page (notebook, tab_clicked);
    action = gtk_action_group_get_action (priv->action_group, "PopupCloseTab");
    gtk_action_activate (action);
    return TRUE;
  }
  // конец добавленного кода.

  if (event->type != GDK_BUTTON_PRESS ||
.....

Ну вот и все! Работает!

Мелочи



Окрыленный успехом я решил «заодно» убрать одну досадную мелочь (подтверждение на закрытие вкладки, если что то запущено) прошерстив код я наткнулся на строку:
do_confirm = gconf_client_get_bool (client, CONF_GLOBAL_PREFIX "/confirm_window_close", NULL);

Немного погуглив на тему gconf_client_get_bool я нашел у себя в ~/.gconf/apps/gnome-terminal файлы настройки.
Установив нужное свойство ( а может и не совсем правильно установил ) это не дало, к сожалению, нужного
эффекта. Поэтому я решил идти дальше.

В исходниках я нашел установку confirm_window_close в двух местах gnome-terminal.schemas и gnome-terminal.schemas.in
выглядит это примерно так:
    <schema>
      <key>/schemas/apps/gnome-terminal/global/confirm_window_close</key>
      <applyto>/apps/gnome-terminal/global/confirm_window_close</applyto>
      <owner>gnome-terminal</owner>
      <type>bool</type>
      <default>true</default>
      <gettext_domain>gnome-terminal</gettext_domain>
      <locale name="C">
         <short>Whether to ask for confirmation when closing terminal windows</short>
         <long>Whether to ask for confirmation when closing a terminal window which has more than one open tab.</long>
      </locale>
    </schema>


Изменив default значение на false все заработало. Ура!

Ну а дальше нужно установить внесенные нам изменения это можно сделать либо сборкой пакета (рекомендуется) и установить его, либо make install (не рекомендуется)

Заранее извиняюсь за сумбурный стиль изложения.
Спасибо вам за внимание!