Доброго времени суток уважаемые Хабровчане!
Как говорится дело быловечером под конец рабочего дня, делать было нечего.
Мне показалось удобным закрытие средней кнопкой мыши вкладок в броузере и то ли отсутствие работы то ли просто спортивный интерес, я решил реализовать сие в 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 (не рекомендуется)
Заранее извиняюсь за сумбурный стиль изложения.
Спасибо вам за внимание!
