24 June 2011

gnome-terminal Закрытие вкладки средней кнопкой мыши

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

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

Мне показалось удобным закрытие средней кнопкой мыши вкладок в броузере и то ли отсутствие работы то ли просто спортивный интерес, я решил реализовать сие в 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 (не рекомендуется)

Заранее извиняюсь за сумбурный стиль изложения.
Спасибо вам за внимание!
Tags:gnome-terminalдоработка
Hubs: Configuring Linux
+5
1.2k 2
Comments 3
Popular right now
Administrator Linux. Professional
January 18, 202180,000 ₽OTUS
Безопасность Linux
February 12, 202130,000 ₽OTUS
SEO-специалист
December 7, 202064,900 ₽Нетология
Профессия iOS-разработчик
December 7, 202090,000 ₽SkillFactory