Нечитаемые ники в чате, или как я Pidgin патчил

Одна из замечательных возможностей протокола Jabber - это конференции. Выглядит и работает как чат, что очень удобно для обсуждения какой-либо задачи, да и просто потрещать с друзьями годится. Мне часто требуется иметь дело с несколькими протоколами одновременно, поэтому и в Windows, и в Linux я использую Pidgin. Pidgin - программа дубовая, с базовым функционалом, но дело своё делает достойно: всё, что в ней реализовано - работает. Однако, меня преследовали вырвиглазные цвета ников в чате. Хочу рассказать небольшую историю, как я с этим боролся.


Pidgin в Linux с системным оформлением по умолчанию в большинстве дистрибутивов использует белый фон для окна сообщений, списка контактов, для чата и списка участников чата. И именно в Linux версии Pidgin использует просто адскую окраску для ников - выкрученный на максимум зеленый а-ля #00FF00. В сочетании с белым фоном это выглядит очень сурово для глаз.
Pidgin - это open source приложение, и я решил наведаться в святую святых - его исходники.

Беглый осмотр кода позволил быстро найти функцию get_nick_color, которая и отвечает за цвет ника. Немного поэспериментровав, я решил немного изменить её и ограничить максимальное значение каждого из цветового каналов вполовину.
Результат получился вполне приемлимым.
До изменений:

beforeИ после:

afterОтмечу, что Windows-версия приложения цвета выбирает "читаемые", органично подходящие к белому фону:

WinXPПосмотрим код

Распаковав исходники, обратимся к файлу pidgin/gtkconv.c. В нём и находится вышеупомянутая функция, которая выглядит вот так:

static const GdkColor *get_nick_color(PidginConversation *gtkconv, const char *name)
{
	static GdkColor col;
	GtkStyle *style = gtk_widget_get_style(gtkconv->imhtml);
	float scale;

	col = nick_colors[g_str_hash(name) % nbr_nick_colors];
	scale = ((1-(LUMINANCE(style->base[GTK_STATE_NORMAL]) / LUMINANCE(style->white))) *
		       (LUMINANCE(style->white)/MAX(MAX(col.red, col.blue), col.green)));

	/* The colors are chosen to look fine on white; we should never have to darken */
	if (scale > 1) {
		col.red   *= scale;
		col.green *= scale;
		col.blue  *= scale;
	}
	return &col;
}

Я изменил её, ограничив значения полей структуры GdkColor половиной от максимального: 65535/2 = 32767.
Получилось вот так:

static const GdkColor *get_nick_color(PidginConversation *gtkconv, const char *name)
{
	static GdkColor col;
	GtkStyle *style = gtk_widget_get_style(gtkconv->imhtml);
	float scale;

	col = nick_colors[g_str_hash(name) % nbr_nick_colors];
	scale = ((1-(LUMINANCE(style->base[GTK_STATE_NORMAL]) / LUMINANCE(style->white))) *
		       (LUMINANCE(style->white)/MAX(MAX(col.red, col.blue), col.green)));

	/* The colors are chosen to look fine on white; we should never have to darken */
	if (scale > 1) {
		col.red   *= scale;
		col.green *= scale;
		col.blue  *= scale;
	}
	col.red = MIN(col.red,32767);
	col.green = MIN(col.green,32767);
	col.blue = MIN(col.blue,32767);
	return &col;
}

Проблема решена, но есть минус - Pidgin придется собирать самому каждый раз, когда он обновляется. Я создал тикет на сайте проекта Pidgin, но сомневаюсь, что разработчики будут заморачиваться.

💡Узнавайте о новых статьях быстрее. Подпишитесь на наши каналы в Telegram и Twitter.

Судя по тому, что вы читаете этот текст, вы дочитали эту статью до конца. Если она вам понравилась, поделитесь, пожалуйста, с помощью кнопок ниже. Спасибо за вашу поддержку!

Автор: Сергей Ткаченко

Сергей Ткаченко создал этот сайт в далёком 2009 году, и с тех пор продолжает над ним работать, публикуя новые материалы о Windows и её приложениях практически каждый день.

Нечитаемые ники в чате, или как я Pidgin патчил: 3 комментария

  1. замечательно!
    спасибо, надо попробовать как-нибудь.
    где ж сриншот с измененным цветом?
    p.s. painter’у привет от рубордян

  2. фу ты, проглядел, может не наполовину, а на две трети надо было?

    1. Да, я теперь тоже так думаю, надо было резать каналы ещё сильнее.

Обсуждение закрыто.

css.php