Доброго времени суток уважаемые Хабровчане!
Как говорится дело быловечером под конец рабочего дня, делать было нечего.
Мне показалось удобным закрытие средней кнопкой мыши вкладок в броузере и то ли отсутствие работы то ли просто спортивный интерес, я решил реализовать сие в gnome-terminal.
Не то что бы мне не хватало горячих клавиш, просто хотел что бы такая возможность была, тем более кушать оно не просит.
Если вам интересно как это происходило и с какими проблемами я столкнулся, добро пожаловать под кат.
Вооружившись кофе я пошел искать исходники gnome-terminal. Гугл бодро выдал первой ссылкой исходники .
Скачав последнюю версию терминала (думаю, а чего мелочится ..) я был жестко обломан, откомпилировать мне его не удалось :(
Плюнув на это дело я скачал версию текущего установленного в системе терминала (2.33.0), который был успешно откомпилирован. Я приступил к своим «исследованиям».
Разбор
Мои знания GTK очень поверхностные, поэтому я понадеялся на читаемость кода и удачу приступил к изучению исходников.
В ходе просмотра файлов я нашел terminal-tab-label.c он мне показался интересным и когда я нашел там создание кнопки закрытия вкладки я решил что нахожусь в нужном месте.
Немного пошуршав документацией (немного расстроил тот факт что в документации куча битых ссылок ) я понял что для того что бы отловить нажатие мышки на надписи нужно вставить следующий код:
Но меня ждало разочарование, событие не обрабатывало.
В документации также было сказано: «To receive this signal, the GdkWindow associated to the widget needs to enable the GDK_BUTTON_PRESS_MASK mask.» (на сайте кстати эта ссылка была битой, но я потом разгадал секрет построения ссылок и нашел нужную страницу.)
Ну что же, раз нужно, значит нужно. Методом поиска и частичного анализа кода я везде добавил строки вида:
Но в который раз был обломан, эффекта не было. Хотя все же есть и плюс. В ходе поиска главного окна я наткнулся на интересную функцию terminal_window_init ( terminal-window.c ), а именно строка:
В итоге я попробовал вклинится туда.
Немного повозившись я пришел к такому решению:
Ну вот и все! Работает!
Окрыленный успехом я решил «заодно» убрать одну досадную мелочь (подтверждение на закрытие вкладки, если что то запущено) прошерстив код я наткнулся на строку:
Немного погуглив на тему gconf_client_get_bool я нашел у себя в ~/.gconf/apps/gnome-terminal файлы настройки.
Установив нужное свойство ( а может и не совсем правильно установил ) это не дало, к сожалению, нужного
эффекта. Поэтому я решил идти дальше.
В исходниках я нашел установку confirm_window_close в двух местах gnome-terminal.schemas и gnome-terminal.schemas.in
выглядит это примерно так:
Изменив default значение на false все заработало. Ура!
Ну а дальше нужно установить внесенные нам изменения это можно сделать либо сборкой пакета (рекомендуется) и установить его, либо make install (не рекомендуется)
Заранее извиняюсь за сумбурный стиль изложения.
Спасибо вам за внимание!
Как говорится дело было
Мне показалось удобным закрытие средней кнопкой мыши вкладок в броузере и то ли отсутствие работы то ли просто спортивный интерес, я решил реализовать сие в 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 (не рекомендуется)
Заранее извиняюсь за сумбурный стиль изложения.
Спасибо вам за внимание!