1 Commits

Author SHA1 Message Date
ab54d9f782 Bump to 2.18.0~pre5 + changelog/AppStream 2026-03-22 11:45:56 -06:00
21 changed files with 323 additions and 319 deletions

View File

@@ -1325,7 +1325,7 @@ msgstr "%C29*%O$t%C29MOTD übersprungen%O"
#: src/common/textevents.h:277 #: src/common/textevents.h:277
msgid "%C23*%O$t%C28$1%C is already in use. Retrying with %C18$2%O..." msgid "%C23*%O$t%C28$1%C is already in use. Retrying with %C18$2%O..."
msgstr "%C23*%O$t%C28$1%C wird bereits verwendet. Erneuter Versuch mit %C18$2%O …" msgstr "%C23*%O$t%C28$1%C wird bereits verwendet. Erneurter Versuch mit %C18$2%O …"
#: src/common/textevents.h:280 #: src/common/textevents.h:280
msgid "%C23*%O$t%C28$1%C is erroneous. Retrying with %C18$2%O..." msgid "%C23*%O$t%C28$1%C is erroneous. Retrying with %C18$2%O..."

View File

@@ -44,7 +44,6 @@ For more information on ZoiteChat please read our [documentation](https://docs.z
<sub> <sub>
X-Chat ("xchat") Copyright (c) 1998-2010 By Peter Zelezny. X-Chat ("xchat") Copyright (c) 1998-2010 By Peter Zelezny.
HexChat ("hexchat") Copyright (c) 2009-2014 By Berke Viktor. HexChat ("hexchat") Copyright (c) 2009-2014 By Berke Viktor.
Hexchat ("hexchat") Copyright (c) 2015-2025 By Patrick Griffis.
ZoiteChat ("zoitechat") Copyright (c) 2026 By deepend. ZoiteChat ("zoitechat") Copyright (c) 2026 By deepend.
</sub> </sub>

View File

@@ -411,7 +411,6 @@ const struct prefs vars[] =
{"gui_chanlist_width_topic", P_OFFINT (hex_gui_chanlist_width_topic), TYPE_INT}, {"gui_chanlist_width_topic", P_OFFINT (hex_gui_chanlist_width_topic), TYPE_INT},
{"gui_chanlist_width_users", P_OFFINT (hex_gui_chanlist_width_users), TYPE_INT}, {"gui_chanlist_width_users", P_OFFINT (hex_gui_chanlist_width_users), TYPE_INT},
{"gui_compact", P_OFFINT (hex_gui_compact), TYPE_BOOL}, {"gui_compact", P_OFFINT (hex_gui_compact), TYPE_BOOL},
{"gui_ctrlq_quit", P_OFFINT (hex_gui_ctrlq_quit), TYPE_BOOL},
{"gui_dialog_height", P_OFFINT (hex_gui_dialog_height), TYPE_INT}, {"gui_dialog_height", P_OFFINT (hex_gui_dialog_height), TYPE_INT},
{"gui_dialog_left", P_OFFINT (hex_gui_dialog_left), TYPE_INT}, {"gui_dialog_left", P_OFFINT (hex_gui_dialog_left), TYPE_INT},
{"gui_dialog_top", P_OFFINT (hex_gui_dialog_top), TYPE_INT}, {"gui_dialog_top", P_OFFINT (hex_gui_dialog_top), TYPE_INT},
@@ -766,7 +765,6 @@ load_default_config(void)
#ifdef HAVE_GTK_MAC #ifdef HAVE_GTK_MAC
prefs.hex_gui_hide_menu = 1; prefs.hex_gui_hide_menu = 1;
#endif #endif
prefs.hex_gui_ctrlq_quit = 1;
prefs.hex_gui_input_attr = 1; prefs.hex_gui_input_attr = 1;
prefs.hex_gui_input_icon = 1; prefs.hex_gui_input_icon = 1;
prefs.hex_gui_input_nick = 1; prefs.hex_gui_input_nick = 1;

View File

@@ -35,13 +35,20 @@ GTree *url_btree = NULL;
static gboolean regex_match (const GRegex *re, const char *word, static gboolean regex_match (const GRegex *re, const char *word,
int *start, int *end); int *start, int *end);
static const GRegex *re_url (void); static const GRegex *re_url (void);
static const GRegex *re_url_no_scheme (void);
static const GRegex *re_host (void);
static const GRegex *re_host6 (void);
static const GRegex *re_email (void); static const GRegex *re_email (void);
static const GRegex *re_nick (void); static const GRegex *re_nick (void);
static const GRegex *re_channel (void); static const GRegex *re_channel (void);
static const GRegex *re_path (void);
static gboolean match_nick (const char *word, int *start, int *end); static gboolean match_nick (const char *word, int *start, int *end);
static gboolean match_channel (const char *word, int *start, int *end); static gboolean match_channel (const char *word, int *start, int *end);
static gboolean match_url (const char *word, int *start, int *end);
static gboolean match_email (const char *word, int *start, int *end); static gboolean match_email (const char *word, int *start, int *end);
static gboolean match_url (const char *word, int *start, int *end);
static gboolean match_host (const char *word, int *start, int *end);
static gboolean match_host6 (const char *word, int *start, int *end);
static gboolean match_path (const char *word, int *start, int *end);
static int static int
url_free (char *url, void *data) url_free (char *url, void *data)
@@ -109,18 +116,12 @@ url_add (char *urltext, int len)
{ {
char *data; char *data;
int size; int size;
GUri *parsed;
if (!prefs.hex_url_grabber && !prefs.hex_url_logging) if (!prefs.hex_url_grabber && !prefs.hex_url_logging)
{ {
return; return;
} }
if (len <= 0)
{
return;
}
data = g_strndup (urltext, len); data = g_strndup (urltext, len);
if (data[len - 1] == '.') if (data[len - 1] == '.')
@@ -133,16 +134,6 @@ url_add (char *urltext, int len)
data[len - 1] = 0; data[len - 1] = 0;
} }
parsed = g_uri_parse (data, G_URI_FLAGS_NONE, NULL);
if (parsed == NULL || g_uri_get_host (parsed) == NULL || *g_uri_get_host (parsed) == '\0')
{
if (parsed)
g_uri_unref (parsed);
g_free (data);
return;
}
g_uri_unref (parsed);
if (prefs.hex_url_logging) if (prefs.hex_url_logging)
{ {
url_save_node (data); url_save_node (data);
@@ -202,6 +193,9 @@ url_check_word (const char *word)
{ match_url, WORD_URL }, { match_url, WORD_URL },
{ match_email, WORD_EMAIL }, { match_email, WORD_EMAIL },
{ match_channel, WORD_CHANNEL }, { match_channel, WORD_CHANNEL },
{ match_host6, WORD_HOST6 },
{ match_host, WORD_HOST },
{ match_path, WORD_PATH },
{ match_nick, WORD_NICK }, { match_nick, WORD_NICK },
{ NULL, 0} { NULL, 0}
}; };
@@ -274,18 +268,45 @@ match_channel (const char *word, int *start, int *end)
return FALSE; return FALSE;
} }
static gboolean
match_url (const char *word, int *start, int *end)
{
return regex_match (re_url (), word, start, end);
}
static gboolean static gboolean
match_email (const char *word, int *start, int *end) match_email (const char *word, int *start, int *end)
{ {
return regex_match (re_email (), word, start, end); return regex_match (re_email (), word, start, end);
} }
static gboolean
match_url (const char *word, int *start, int *end)
{
if (regex_match (re_url (), word, start, end))
return TRUE;
return regex_match (re_url_no_scheme (), word, start, end);
}
static gboolean
match_host (const char *word, int *start, int *end)
{
return regex_match (re_host (), word, start, end);
}
static gboolean
match_host6 (const char *word, int *start, int *end)
{
if (!regex_match (re_host6 (), word, start, end))
return FALSE;
if (word[*start] != '[')
return FALSE;
return TRUE;
}
static gboolean
match_path (const char *word, int *start, int *end)
{
return regex_match (re_path (), word, start, end);
}
/* List of IRC commands for which contents (and thus possible URLs) /* List of IRC commands for which contents (and thus possible URLs)
* are visible to the user. NOTE: Trailing blank required in each. */ * are visible to the user. NOTE: Trailing blank required in each. */
static char *commands[] = { static char *commands[] = {
@@ -430,7 +451,34 @@ make_re (const char *grist)
return ret; return ret;
} }
/* HOST description --- */
/* (see miscellaneous above) */
static const GRegex *
re_host (void)
{
static GRegex *host_ret;
if (host_ret) return host_ret;
host_ret = make_re ("(" "(" HOST_URL PORT ")|(" HOST ")" ")");
return host_ret;
}
static const GRegex *
re_host6 (void)
{
static GRegex *host6_ret;
if (host6_ret) return host6_ret;
host6_ret = make_re ("(" "(" IPV6ADDR ")|(" "\\[" IPV6ADDR "\\]" PORT ")" ")");
return host6_ret;
}
/* URL description --- */ /* URL description --- */
#define SCHEME "(%s)"
#define LPAR "\\(" #define LPAR "\\("
#define RPAR "\\)" #define RPAR "\\)"
#define NOPARENS "[^() \t]*" #define NOPARENS "[^() \t]*"
@@ -441,20 +489,86 @@ make_re (const char *grist)
"(" NOPARENS ")" \ "(" NOPARENS ")" \
")*" /* Zero or more occurrences of either of these */ \ ")*" /* Zero or more occurrences of either of these */ \
"(?<![.,?!\\]])" /* Not allowed to end with these */ "(?<![.,?!\\]])" /* Not allowed to end with these */
#define USERINFO "([-a-z0-9._~%]+(:[-a-z0-9._~%]*)?@)"
/* Flags used to describe URIs (RFC 3986)
*
* Bellow is an example of what the flags match.
*
* URI_AUTHORITY - http://example.org:80/foo/bar
* ^^^^^^^^^^^^^^^^
* URI_USERINFO/URI_OPT_USERINFO - http://user@example.org:80/foo/bar
* ^^^^^
* URI_PATH - http://example.org:80/foo/bar
* ^^^^^^^^
*/
#define URI_AUTHORITY (1 << 0)
#define URI_OPT_USERINFO (1 << 1)
#define URI_USERINFO (1 << 2)
#define URI_PATH (1 << 3)
struct struct
{ {
const char *scheme; const char *scheme; /* scheme name. e.g. http */
const char *path_sep; /* string that begins the path */
int flags; /* see above (flag macros) */
} uri[] = { } uri[] = {
{ "http" }, { "irc", "/", URI_PATH },
{ "https" }, { "ircs", "/", URI_PATH },
{ "ftp" }, { "rtsp", "/", URI_AUTHORITY | URI_PATH },
{ "gopher" }, { "feed", "/", URI_AUTHORITY | URI_PATH },
{ "gemini" }, { "teamspeak", "?", URI_AUTHORITY | URI_PATH },
{ "irc" }, { "ftp", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
{ "ircs" }, { "sftp", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
{ NULL } { "ftps", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
{ "http", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
{ "https", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
{ "cvs", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
{ "svn", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
{ "git", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
{ "bzr", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
{ "rsync", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
{ "mumble", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
{ "ventrilo", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
{ "xmpp", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
{ "h323", ";", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
{ "imap", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
{ "pop", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
{ "nfs", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
{ "smb", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
{ "gopher", "/", URI_AUTHORITY | URI_PATH },
{ "gemini", "/", URI_AUTHORITY | URI_PATH },
{ "ssh", "", URI_AUTHORITY | URI_OPT_USERINFO },
{ "sip", "", URI_AUTHORITY | URI_USERINFO },
{ "sips", "", URI_AUTHORITY | URI_USERINFO },
{ "magnet", "?", URI_PATH },
{ "mailto", "", URI_PATH },
{ "bitcoin", "", URI_PATH },
{ "gtalk", "", URI_PATH },
{ "steam", "", URI_PATH },
{ "file", "/", URI_PATH },
{ "callto", "", URI_PATH },
{ "skype", "", URI_PATH },
{ "geo", "", URI_PATH },
{ "spotify", "", URI_PATH },
{ "lastfm", "/", URI_PATH },
{ "xfire", "", URI_PATH },
{ "ts3server", "", URI_PATH },
{ NULL, "", 0}
}; };
static const GRegex *
re_url_no_scheme (void)
{
static GRegex *url_ret = NULL;
if (url_ret) return url_ret;
url_ret = make_re ("(" HOST_URL OPT_PORT "/" "(" PATH ")?" ")");
return url_ret;
}
static const GRegex * static const GRegex *
re_url (void) re_url (void)
{ {
@@ -473,9 +587,27 @@ re_url (void)
g_string_append (grist_gstr, "|"); g_string_append (grist_gstr, "|");
g_string_append (grist_gstr, "("); g_string_append (grist_gstr, "(");
g_string_append_printf (grist_gstr, "%s://", uri[i].scheme); g_string_append_printf (grist_gstr, "%s:", uri[i].scheme);
g_string_append (grist_gstr, HOST_URL_OPT_TLD OPT_PORT);
g_string_append_printf (grist_gstr, "(/" PATH ")?"); if (uri[i].flags & URI_AUTHORITY)
g_string_append (grist_gstr, "//");
if (uri[i].flags & URI_USERINFO)
g_string_append (grist_gstr, USERINFO);
else if (uri[i].flags & URI_OPT_USERINFO)
g_string_append (grist_gstr, USERINFO "?");
if (uri[i].flags & URI_AUTHORITY)
g_string_append (grist_gstr, HOST_URL_OPT_TLD OPT_PORT);
if (uri[i].flags & URI_PATH)
{
char *sep_escaped = g_regex_escape_string (uri[i].path_sep, strlen(uri[i].path_sep));
g_string_append_printf (grist_gstr, "(" "%s" PATH ")?", sep_escaped);
g_free (sep_escaped);
}
g_string_append (grist_gstr, ")"); g_string_append (grist_gstr, ")");
} }
@@ -488,9 +620,8 @@ re_url (void)
return url_ret; return url_ret;
} }
#define EMAIL_LOCAL_ATOM "[\\pL\\pN!#$%&'*+/=?^_`{|}~-]+" /* EMAIL description --- */
#define EMAIL_LOCAL EMAIL_LOCAL_ATOM "(\\." EMAIL_LOCAL_ATOM ")*" #define EMAIL "[a-z0-9][._%+-a-z0-9]+@" "(" HOST_URL ")"
#define EMAIL EMAIL_LOCAL "@" DOMAIN TLD
static const GRegex * static const GRegex *
re_email (void) re_email (void)
@@ -549,3 +680,24 @@ re_channel (void)
return channel_ret; return channel_ret;
} }
/* PATH description --- */
#ifdef WIN32
/* Windows path can be .\ ..\ or C: D: etc */
#define FS_PATH "^(\\.{1,2}\\\\|[a-z]:).*"
#else
/* Linux path can be / or ./ or ../ etc */
#define FS_PATH "^(/|\\./|\\.\\./).*"
#endif
static const GRegex *
re_path (void)
{
static GRegex *path_ret;
if (path_ret) return path_ret;
path_ret = make_re ("(" FS_PATH ")");
return path_ret;
}

View File

@@ -122,7 +122,6 @@ struct zoitechatprefs
unsigned int hex_gui_autoopen_recv; unsigned int hex_gui_autoopen_recv;
unsigned int hex_gui_autoopen_send; unsigned int hex_gui_autoopen_send;
unsigned int hex_gui_compact; unsigned int hex_gui_compact;
unsigned int hex_gui_ctrlq_quit;
unsigned int hex_gui_filesize_iec; unsigned int hex_gui_filesize_iec;
unsigned int hex_gui_focus_omitalerts; unsigned int hex_gui_focus_omitalerts;
unsigned int hex_gui_hide_menu; unsigned int hex_gui_hide_menu;

View File

@@ -29,7 +29,6 @@
#ifdef WIN32 #ifdef WIN32
#include <windows.h> #include <windows.h>
#include <dwmapi.h> #include <dwmapi.h>
#include <glib/gwin32.h>
#else #else
#include <unistd.h> #include <unistd.h>
#endif #endif
@@ -302,28 +301,9 @@ fe_args (int argc, char *argv[])
GOptionContext *context; GOptionContext *context;
char *buffer; char *buffer;
const char *desktop_id = "net.zoite.Zoitechat"; const char *desktop_id = "net.zoite.Zoitechat";
#ifdef WIN32
char *base_path = NULL;
char *locale_path = NULL;
#endif
#ifdef ENABLE_NLS #ifdef ENABLE_NLS
#ifdef WIN32
base_path = g_win32_get_package_installation_directory_of_module (NULL);
if (base_path)
{
locale_path = g_build_filename (base_path, "share", "locale", NULL);
bindtextdomain (GETTEXT_PACKAGE, locale_path);
}
else
{
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
}
g_free (locale_path);
g_free (base_path);
#else
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
#endif
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE); textdomain (GETTEXT_PACKAGE);
#endif #endif

View File

@@ -170,7 +170,7 @@ typedef struct session_gui
GtkWidget *shbox, *shentry; /* search bar hbox */ GtkWidget *shbox, *shentry; /* search bar hbox */
gulong search_changed_signal; /* hook for search change event so blanking the box doesn't suck */ gulong search_changed_signal; /* hook for search change event so blanking the box doesn't suck */
#define MENU_ID_NUM 15 #define MENU_ID_NUM 14
GtkWidget *menu_item[MENU_ID_NUM+1]; /* some items we may change state of */ GtkWidget *menu_item[MENU_ID_NUM+1]; /* some items we may change state of */
void *chanview; /* chanview.h */ void *chanview; /* chanview.h */

View File

@@ -4206,7 +4206,7 @@ mg_create_menu (session_gui *gui, GtkWidget *table, int away_state)
gui->menu_item); gui->menu_item);
gtk_widget_set_hexpand (gui->menu, TRUE); gtk_widget_set_hexpand (gui->menu, TRUE);
gtk_widget_set_vexpand (gui->menu, FALSE); gtk_widget_set_vexpand (gui->menu, FALSE);
gtk_widget_set_halign (gui->menu, GTK_ALIGN_START); gtk_widget_set_halign (gui->menu, GTK_ALIGN_FILL);
gtk_widget_set_valign (gui->menu, GTK_ALIGN_FILL); gtk_widget_set_valign (gui->menu, GTK_ALIGN_FILL);
gtk_grid_attach (GTK_GRID (table), gui->menu, 0, 0, 3, 1); gtk_grid_attach (GTK_GRID (table), gui->menu, 0, 0, 3, 1);
} }

View File

@@ -1802,44 +1802,6 @@ menu_change_layout (void)
} }
} }
void
menu_update_quit_accel (void)
{
GSList *list;
list = sess_list;
while (list)
{
session *sess = list->data;
session_gui *gui = sess->gui;
GtkWidget *item;
GtkAccelGroup *accel_group;
int enabled;
list = list->next;
if (!gui)
continue;
item = gui->menu_item[MENU_ID_QUIT];
if (!item)
continue;
enabled = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (item), "zc-ctrlq-enabled"));
if (enabled == (int)prefs.hex_gui_ctrlq_quit)
continue;
accel_group = g_object_get_data (G_OBJECT (item), "zc-quit-accel-group");
if (!accel_group)
continue;
if (prefs.hex_gui_ctrlq_quit)
gtk_widget_add_accelerator (item, "activate", accel_group, GDK_KEY_q, STATE_CTRL, GTK_ACCEL_VISIBLE);
else
gtk_widget_remove_accelerator (item, accel_group, GDK_KEY_q, STATE_CTRL);
g_object_set_data (G_OBJECT (item), "zc-ctrlq-enabled", GINT_TO_POINTER (prefs.hex_gui_ctrlq_quit));
}
}
static void static void
menu_layout_cb (GtkWidget *item, gpointer none) menu_layout_cb (GtkWidget *item, gpointer none)
{ {
@@ -1917,46 +1879,25 @@ about_dialog_openurl (GtkAboutDialog *dialog, char *uri, gpointer data)
return TRUE; return TRUE;
} }
static void
about_dialog_button_openurl (GtkButton *button, gpointer data)
{
fe_open_url ((const char *)data);
}
static void static void
about_dialog_add_links (GtkAboutDialog *dialog) about_dialog_add_links (GtkAboutDialog *dialog)
{ {
GtkWidget *actions = gtk_dialog_get_action_area (GTK_DIALOG (dialog)); GtkWidget *content = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
GtkWidget *website = gtk_button_new_with_label ("Website"); GtkWidget *row = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
GtkWidget *license = gtk_button_new_with_label ("License"); GtkWidget *website = gtk_link_button_new_with_label ("http://zoitechat.zoite.net", "Website");
GtkWidget *license = gtk_link_button_new_with_label ("https://www.gnu.org/licenses/old-licenses/gpl-2.0.html", "License");
g_signal_connect (G_OBJECT (website), "clicked", G_CALLBACK (about_dialog_button_openurl), "http://zoitechat.zoite.net"); gtk_button_set_relief (GTK_BUTTON (website), GTK_RELIEF_NONE);
g_signal_connect (G_OBJECT (license), "clicked", G_CALLBACK (about_dialog_button_openurl), "https://www.gnu.org/licenses/old-licenses/gpl-2.0.html"); gtk_button_set_relief (GTK_BUTTON (license), GTK_RELIEF_NONE);
gtk_box_pack_start (GTK_BOX (actions), website, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (row), website, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (actions), license, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (row), license, FALSE, FALSE, 0);
gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (actions), website, TRUE); gtk_box_pack_start (GTK_BOX (content), row, FALSE, FALSE, 0);
gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (actions), license, TRUE); gtk_widget_show_all (row);
gtk_widget_show_all (actions);
}
static void
about_dialog_strip_actions (GtkDialog *dialog)
{
GtkWidget *area = gtk_dialog_get_action_area (dialog);
GList *children = gtk_container_get_children (GTK_CONTAINER (area));
GList *node;
for (node = children; node != NULL; node = node->next)
gtk_widget_destroy (GTK_WIDGET (node->data));
g_list_free (children);
} }
static void static void
menu_about (GtkWidget *wid, gpointer sess) menu_about (GtkWidget *wid, gpointer sess)
{ {
GtkAboutDialog *dialog = GTK_ABOUT_DIALOG(gtk_about_dialog_new()); GtkAboutDialog *dialog = GTK_ABOUT_DIALOG(gtk_about_dialog_new());
static const gchar *empty_people[] = { NULL };
theme_manager_attach_window (GTK_WIDGET (dialog)); theme_manager_attach_window (GTK_WIDGET (dialog));
char comment[512]; char comment[512];
g_snprintf (comment, sizeof(comment), "" g_snprintf (comment, sizeof(comment), ""
@@ -1973,20 +1914,14 @@ menu_about (GtkWidget *wid, gpointer sess)
gtk_about_dialog_set_program_name (dialog, _(DISPLAY_NAME)); gtk_about_dialog_set_program_name (dialog, _(DISPLAY_NAME));
gtk_about_dialog_set_version (dialog, PACKAGE_VERSION); gtk_about_dialog_set_version (dialog, PACKAGE_VERSION);
gtk_about_dialog_set_authors (dialog, empty_people); gtk_about_dialog_set_authors (dialog, NULL);
gtk_about_dialog_set_documenters (dialog, empty_people); gtk_about_dialog_set_documenters (dialog, NULL);
gtk_about_dialog_set_artists (dialog, empty_people); gtk_about_dialog_set_artists (dialog, NULL);
gtk_about_dialog_set_translator_credits (dialog, ""); gtk_about_dialog_set_translator_credits (dialog, NULL);
gtk_about_dialog_set_website (dialog, NULL);
gtk_about_dialog_set_website_label (dialog, NULL);
gtk_about_dialog_set_license (dialog, NULL);
gtk_about_dialog_set_wrap_license (dialog, FALSE);
gtk_about_dialog_set_logo (dialog, pix_zoitechat); gtk_about_dialog_set_logo (dialog, pix_zoitechat);
gtk_about_dialog_set_copyright (dialog, "\302\251 1998-2010 Peter \305\275elezn\303\275\n\302\251 2009-2014 Berke Viktor\n\302\251 2015-2025 Patrick Griffis\n\302\251 2026 deepend"); gtk_about_dialog_set_copyright (dialog, "\302\251 1998-2010 Peter \305\275elezn\303\275\n\302\251 2009-2014 Berke Viktor\n\302\251 2026 deepend");
gtk_about_dialog_set_comments (dialog, comment); gtk_about_dialog_set_comments (dialog, comment);
about_dialog_strip_actions (GTK_DIALOG (dialog));
about_dialog_add_links (dialog); about_dialog_add_links (dialog);
gtk_dialog_add_button (GTK_DIALOG (dialog), _("_Close"), GTK_RESPONSE_CLOSE);
gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(parent_window)); gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(parent_window));
g_signal_connect (G_OBJECT(dialog), "response", G_CALLBACK(about_dialog_close), NULL); g_signal_connect (G_OBJECT(dialog), "response", G_CALLBACK(about_dialog_close), NULL);
@@ -2015,7 +1950,7 @@ static struct mymenu mymenu[] = {
#define CLOSE_OFFSET (13) #define CLOSE_OFFSET (13)
{0, menu_close, 0, M_MENUITEM, 0, 0, 1}, {0, menu_close, 0, M_MENUITEM, 0, 0, 1},
{0, 0, 0, M_SEP, 0, 0, 0}, {0, 0, 0, M_SEP, 0, 0, 0},
{N_("_Quit"), menu_quit, 0, M_MENUITEM, MENU_ID_QUIT, 0, 1, GDK_KEY_q}, /* 15 */ {N_("_Quit"), menu_quit, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_q}, /* 15 */
{N_("_View"), 0, 0, M_NEWMENU, 0, 0, 1}, {N_("_View"), 0, 0, M_NEWMENU, 0, 0, 1},
#define MENUBAR_OFFSET (17) #define MENUBAR_OFFSET (17)
@@ -2699,7 +2634,7 @@ menu_create_main (void *accel_group, int bar, int away, int toplevel,
case M_MENUITEM: case M_MENUITEM:
item = gtk_menu_item_new_with_mnemonic (_(mymenu[i].text)); item = gtk_menu_item_new_with_mnemonic (_(mymenu[i].text));
normalitem: normalitem:
if (mymenu[i].key != 0 && !(mymenu[i].id == MENU_ID_QUIT && !prefs.hex_gui_ctrlq_quit)) if (mymenu[i].key != 0)
gtk_widget_add_accelerator (item, "activate", accel_group, gtk_widget_add_accelerator (item, "activate", accel_group,
mymenu[i].key, mymenu[i].key,
mymenu[i].key == GDK_KEY_F1 ? 0 : mymenu[i].key == GDK_KEY_F1 ? 0 :
@@ -2709,11 +2644,6 @@ normalitem:
STATE_SHIFT | STATE_CTRL : STATE_SHIFT | STATE_CTRL :
STATE_CTRL, STATE_CTRL,
GTK_ACCEL_VISIBLE); GTK_ACCEL_VISIBLE);
if (mymenu[i].id == MENU_ID_QUIT)
{
g_object_set_data (G_OBJECT (item), "zc-quit-accel-group", accel_group);
g_object_set_data (G_OBJECT (item), "zc-ctrlq-enabled", GINT_TO_POINTER (prefs.hex_gui_ctrlq_quit));
}
if (mymenu[i].callback) if (mymenu[i].callback)
g_signal_connect (G_OBJECT (item), "activate", g_signal_connect (G_OBJECT (item), "activate",
G_CALLBACK (mymenu[i].callback), 0); G_CALLBACK (mymenu[i].callback), 0);
@@ -2755,11 +2685,9 @@ togitem:
goto togitem; goto togitem;
case M_SEP: case M_SEP:
item = gtk_separator_menu_item_new (); item = gtk_menu_item_new ();
if (submenu) gtk_widget_set_sensitive (item, FALSE);
gtk_menu_shell_append (GTK_MENU_SHELL (submenu), item); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
else
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
gtk_widget_show (item); gtk_widget_show (item);
break; break;

View File

@@ -38,7 +38,6 @@ void menu_create (GtkWidget *menu, GSList *list, char *target, int check_path);
void menu_bar_toggle (void); void menu_bar_toggle (void);
void menu_add_plugin_items (GtkWidget *menu, char *root, char *target); void menu_add_plugin_items (GtkWidget *menu, char *root, char *target);
void menu_change_layout (void); void menu_change_layout (void);
void menu_update_quit_accel (void);
void menu_set_away (session_gui *gui, int away); void menu_set_away (session_gui *gui, int away);
void menu_set_fullscreen (session_gui *gui, int fullscreen); void menu_set_fullscreen (session_gui *gui, int fullscreen);
@@ -64,9 +63,8 @@ void menu_set_fullscreen (session_gui *gui, int fullscreen);
#define MENU_ID_USERMENU 12 #define MENU_ID_USERMENU 12
#define MENU_ID_FULLSCREEN 13 #define MENU_ID_FULLSCREEN 13
#define MENU_ID_ZOITECHAT 14 #define MENU_ID_ZOITECHAT 14
#define MENU_ID_QUIT 15
#if (MENU_ID_NUM < MENU_ID_QUIT) #if (MENU_ID_NUM < MENU_ID_ZOITECHAT)
#error MENU_ID_NUM is set wrong #error MENU_ID_NUM is set wrong
#endif #endif

View File

@@ -536,7 +536,6 @@ static const setting general_settings[] =
{ST_TOGGLE, N_("WHOIS on notify"), P_OFFINTNL(hex_notify_whois_online), N_("Sends a /WHOIS when a user comes online in your notify list."), 0, 0}, {ST_TOGGLE, N_("WHOIS on notify"), P_OFFINTNL(hex_notify_whois_online), N_("Sends a /WHOIS when a user comes online in your notify list."), 0, 0},
{ST_TOGGLE, N_("Hide join and part messages"), P_OFFINTNL(hex_irc_conf_mode), N_("Hide channel join/part messages by default."), 0, 0}, {ST_TOGGLE, N_("Hide join and part messages"), P_OFFINTNL(hex_irc_conf_mode), N_("Hide channel join/part messages by default."), 0, 0},
{ST_TOGGLE, N_("Hide nick change messages"), P_OFFINTNL(hex_irc_hide_nickchange), 0, 0, 0}, {ST_TOGGLE, N_("Hide nick change messages"), P_OFFINTNL(hex_irc_hide_nickchange), 0, 0, 0},
{ST_TOGGLE, N_("Enable Ctrl+Q to quit"), P_OFFINTNL(hex_gui_ctrlq_quit), 0, 0, 0},
{ST_END, 0, 0, 0, 0, 0} {ST_END, 0, 0, 0, 0, 0}
}; };
@@ -2071,7 +2070,6 @@ setup_apply_real (const ThemeChangedEvent *event)
} }
mg_apply_setup (); mg_apply_setup ();
menu_update_quit_accel ();
tray_apply_setup (); tray_apply_setup ();
zoitechat_reinit_timers (); zoitechat_reinit_timers ();

View File

@@ -102,12 +102,6 @@ theme_manager_save_preferences (void)
return TRUE; return TRUE;
} }
void
theme_manager_dispatch_changed (ThemeChangedReason reasons)
{
(void)reasons;
}
ThemePaletteBehavior ThemePaletteBehavior
theme_manager_get_userlist_palette_behavior (const PangoFontDescription *font_desc) theme_manager_get_userlist_palette_behavior (const PangoFontDescription *font_desc)
{ {

View File

@@ -26,29 +26,16 @@
#include "theme-runtime.h" #include "theme-runtime.h"
#include "theme-gtk3.h" #include "theme-gtk3.h"
#include "../maingui.h" #include "../maingui.h"
#ifdef G_OS_WIN32
#include <gtk/gtk.h> #include <gtk/gtk.h>
#if defined(__GNUC__) || defined(__clang__)
extern char *theme_css_build_toplevel_classes (void) __attribute__ ((weak));
#else
extern char *theme_css_build_toplevel_classes (void);
#endif
static char *
theme_application_build_toplevel_css (void)
{
if (theme_css_build_toplevel_classes)
return theme_css_build_toplevel_classes ();
return g_strdup ("");
}
static void static void
theme_application_apply_toplevel_theme (gboolean dark) theme_application_apply_windows_theme (gboolean dark)
{ {
GtkSettings *settings = gtk_settings_get_default (); GtkSettings *settings = gtk_settings_get_default ();
static GtkCssProvider *theme_provider = NULL; static GtkCssProvider *win_theme_provider = NULL;
static gboolean theme_provider_installed = FALSE; static gboolean win_theme_provider_installed = FALSE;
GdkScreen *screen; GdkScreen *screen;
gboolean prefer_dark = dark; gboolean prefer_dark = dark;
char *css; char *css;
@@ -69,21 +56,33 @@ theme_application_apply_toplevel_theme (gboolean dark)
if (!screen) if (!screen)
return; return;
if (!theme_provider) if (theme_gtk3_is_active ())
theme_provider = gtk_css_provider_new (); {
if (win_theme_provider_installed && win_theme_provider)
{
gtk_style_context_remove_provider_for_screen (screen,
GTK_STYLE_PROVIDER (win_theme_provider));
win_theme_provider_installed = FALSE;
}
return;
}
css = theme_application_build_toplevel_css (); if (!win_theme_provider)
gtk_css_provider_load_from_data (theme_provider, css, -1, NULL); win_theme_provider = gtk_css_provider_new ();
css = theme_css_build_toplevel_classes ();
gtk_css_provider_load_from_data (win_theme_provider, css, -1, NULL);
g_free (css); g_free (css);
if (!theme_provider_installed) if (!win_theme_provider_installed)
{ {
gtk_style_context_add_provider_for_screen (screen, gtk_style_context_add_provider_for_screen (screen,
GTK_STYLE_PROVIDER (theme_provider), GTK_STYLE_PROVIDER (win_theme_provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION + 1); GTK_STYLE_PROVIDER_PRIORITY_APPLICATION + 1);
theme_provider_installed = TRUE; win_theme_provider_installed = TRUE;
} }
} }
#endif
gboolean gboolean
theme_application_apply_mode (unsigned int mode, gboolean *palette_changed) theme_application_apply_mode (unsigned int mode, gboolean *palette_changed)
@@ -92,7 +91,10 @@ theme_application_apply_mode (unsigned int mode, gboolean *palette_changed)
theme_runtime_load (); theme_runtime_load ();
dark = theme_runtime_apply_mode (mode, palette_changed); dark = theme_runtime_apply_mode (mode, palette_changed);
theme_application_apply_toplevel_theme (dark);
#ifdef G_OS_WIN32
theme_application_apply_windows_theme (dark);
#endif
theme_application_reload_input_style (); theme_application_reload_input_style ();

View File

@@ -361,22 +361,20 @@ theme_css_build_toplevel_classes (void)
"color: #f0f0f0;" "color: #f0f0f0;"
"border-color: #202020;" "border-color: #202020;"
"}" "}"
"window.%s menubar, window.%s menubar:backdrop, window.%s menubar box, window.%s menubar box:backdrop, window.%s menuitem, window.%s menuitem:backdrop {" "window.%s menubar, window.%s menubar:backdrop, window.%s menuitem, window.%s menuitem:backdrop {"
"background-color: @theme_bg_color;" "background-color: #202020;"
"background-image: none;" "color: #f0f0f0;"
"color: @theme_fg_color;" "border-color: #202020;"
"border-color: @theme_bg_color;"
"}" "}"
"window.%s, window.%s:backdrop, .%s {" "window.%s, window.%s:backdrop, .%s {"
"background-color: #f6f6f6;" "background-color: #f6f6f6;"
"color: #101010;" "color: #101010;"
"border-color: #f6f6f6;" "border-color: #f6f6f6;"
"}" "}"
"window.%s menubar, window.%s menubar:backdrop, window.%s menubar box, window.%s menubar box:backdrop, window.%s menuitem, window.%s menuitem:backdrop {" "window.%s menubar, window.%s menubar:backdrop, window.%s menuitem, window.%s menuitem:backdrop {"
"background-color: @theme_bg_color;" "background-color: #f6f6f6;"
"background-image: none;" "color: #101010;"
"color: @theme_fg_color;" "border-color: #f6f6f6;"
"border-color: @theme_bg_color;"
"}", "}",
theme_css_selector_dark_class, theme_css_selector_dark_class,
theme_css_selector_dark_class, theme_css_selector_dark_class,
@@ -385,10 +383,6 @@ theme_css_build_toplevel_classes (void)
theme_css_selector_dark_class, theme_css_selector_dark_class,
theme_css_selector_dark_class, theme_css_selector_dark_class,
theme_css_selector_dark_class, theme_css_selector_dark_class,
theme_css_selector_dark_class,
theme_css_selector_dark_class,
theme_css_selector_light_class,
theme_css_selector_light_class,
theme_css_selector_light_class, theme_css_selector_light_class,
theme_css_selector_light_class, theme_css_selector_light_class,
theme_css_selector_light_class, theme_css_selector_light_class,

View File

@@ -216,6 +216,8 @@ theme_manager_queue_auto_refresh (GtkSettings *settings, GParamSpec *pspec, gpoi
void void
theme_manager_init (void) theme_manager_init (void)
{ {
GtkSettings *settings;
if (!theme_manager_listeners) if (!theme_manager_listeners)
theme_manager_listeners = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, theme_manager_listeners = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
theme_listener_free); theme_listener_free);
@@ -223,10 +225,21 @@ theme_manager_init (void)
if (!theme_manager_setup_listener_id) if (!theme_manager_setup_listener_id)
theme_manager_setup_listener_id = theme_listener_register ("setup.apply", theme_manager_setup_apply_listener, NULL); theme_manager_setup_listener_id = theme_listener_register ("setup.apply", theme_manager_setup_apply_listener, NULL);
fe_set_auto_dark_mode_state (FALSE); settings = gtk_settings_get_default ();
if (settings)
fe_set_auto_dark_mode_state (theme_policy_system_prefers_dark ());
theme_application_apply_mode (prefs.hex_gui_dark_mode, NULL); theme_application_apply_mode (prefs.hex_gui_dark_mode, NULL);
theme_gtk3_init (); theme_gtk3_init ();
zoitechat_set_theme_post_apply_callback (theme_manager_handle_theme_applied); zoitechat_set_theme_post_apply_callback (theme_manager_handle_theme_applied);
if (settings)
{
g_signal_connect (settings, "notify::gtk-application-prefer-dark-theme",
G_CALLBACK (theme_manager_queue_auto_refresh), NULL);
g_signal_connect (settings, "notify::gtk-theme-name",
G_CALLBACK (theme_manager_queue_auto_refresh), NULL);
}
} }
gboolean gboolean
@@ -481,6 +494,7 @@ theme_manager_apply_wayland_kde_csd (GtkWidget *window)
static void static void
theme_manager_apply_platform_window_theme (GtkWidget *window) theme_manager_apply_platform_window_theme (GtkWidget *window)
{ {
#ifdef G_OS_WIN32
GtkStyleContext *context; GtkStyleContext *context;
gboolean dark; gboolean dark;
@@ -502,7 +516,6 @@ theme_manager_apply_platform_window_theme (GtkWidget *window)
gtk_style_context_remove_class (context, "zoitechat-light"); gtk_style_context_remove_class (context, "zoitechat-light");
gtk_style_context_add_class (context, dark ? "zoitechat-dark" : "zoitechat-light"); gtk_style_context_add_class (context, dark ? "zoitechat-dark" : "zoitechat-light");
} }
#ifdef G_OS_WIN32
fe_win32_apply_native_titlebar (window, dark); fe_win32_apply_native_titlebar (window, dark);
#else #else
theme_manager_apply_wayland_kde_csd (window); theme_manager_apply_wayland_kde_csd (window);

View File

@@ -27,7 +27,38 @@
gboolean gboolean
theme_policy_system_prefers_dark (void) theme_policy_system_prefers_dark (void)
{ {
return FALSE; GtkSettings *settings = gtk_settings_get_default ();
gboolean prefer_dark = FALSE;
char *theme_name = NULL;
#ifdef G_OS_WIN32
gboolean have_win_pref = FALSE;
if (fe_win32_high_contrast_is_enabled ())
return FALSE;
have_win_pref = fe_win32_try_get_system_dark (&prefer_dark);
if (!have_win_pref)
#endif
if (settings && g_object_class_find_property (G_OBJECT_GET_CLASS (settings),
"gtk-application-prefer-dark-theme"))
{
g_object_get (settings, "gtk-application-prefer-dark-theme", &prefer_dark, NULL);
}
if (settings && !prefer_dark)
{
g_object_get (settings, "gtk-theme-name", &theme_name, NULL);
if (theme_name)
{
char *lower = g_ascii_strdown (theme_name, -1);
if (g_str_has_suffix (lower, "-dark") || g_strrstr (lower, "dark"))
prefer_dark = TRUE;
g_free (lower);
g_free (theme_name);
}
}
return prefer_dark;
} }
gboolean gboolean

View File

@@ -1350,19 +1350,6 @@ theme_preferences_gtk3_sync_remove_state (theme_preferences_ui *ui)
gtk_widget_set_sensitive (ui->gtk3_remove, source == ZOITECHAT_GTK3_THEME_SOURCE_USER); gtk_widget_set_sensitive (ui->gtk3_remove, source == ZOITECHAT_GTK3_THEME_SOURCE_USER);
} }
static gboolean
theme_preferences_gtk3_apply_and_refresh (GError **error)
{
if (!theme_gtk3_apply_current (error))
return FALSE;
theme_manager_dispatch_changed (THEME_CHANGED_REASON_THEME_PACK |
THEME_CHANGED_REASON_PALETTE |
THEME_CHANGED_REASON_WIDGET_STYLE |
THEME_CHANGED_REASON_USERLIST |
THEME_CHANGED_REASON_MODE);
return TRUE;
}
static void static void
theme_preferences_gtk3_changed_cb (GtkComboBox *combo, gpointer user_data) theme_preferences_gtk3_changed_cb (GtkComboBox *combo, gpointer user_data)
{ {
@@ -1393,7 +1380,7 @@ theme_preferences_gtk3_changed_cb (GtkComboBox *combo, gpointer user_data)
ui->setup_prefs->hex_gui_gtk3_variant = prefs.hex_gui_gtk3_variant; ui->setup_prefs->hex_gui_gtk3_variant = prefs.hex_gui_gtk3_variant;
} }
if (selection_changed && !theme_preferences_gtk3_apply_and_refresh (&error)) if (selection_changed && !theme_gtk3_apply_current (&error))
{ {
theme_preferences_show_message (ui, GTK_MESSAGE_ERROR, theme_preferences_show_message (ui, GTK_MESSAGE_ERROR,
error ? error->message : _("Failed to apply GTK3 theme.")); error ? error->message : _("Failed to apply GTK3 theme."));
@@ -1570,7 +1557,7 @@ theme_preferences_populate_gtk3 (theme_preferences_ui *ui)
g_free (final_id); g_free (final_id);
} }
if (should_apply && !theme_preferences_gtk3_apply_and_refresh (&error)) if (should_apply && !theme_gtk3_apply_current (&error))
{ {
theme_preferences_show_message (ui, GTK_MESSAGE_ERROR, theme_preferences_show_message (ui, GTK_MESSAGE_ERROR,
error ? error->message : _("Failed to apply GTK3 theme.")); error ? error->message : _("Failed to apply GTK3 theme."));

View File

@@ -44,29 +44,14 @@
enum enum
{ {
COL_PIX=0, /* GdkPixbuf * */ COL_PIX=0, /* GdkPixbuf * */
COL_PREFIX=1, /* char * */ COL_NICK=1, /* char * */
COL_NICK=2, /* char * */ COL_HOST=2, /* char * */
COL_HOST=3, /* char * */ COL_USER=3, /* struct User * */
COL_USER=4, /* struct User * */ COL_GDKCOLOR=4 /* GdkRGBA */
COL_GDKCOLOR=5 /* GdkRGBA */
}; };
static void userlist_store_color (GtkListStore *store, GtkTreeIter *iter, ThemeSemanticToken token, gboolean has_token); static void userlist_store_color (GtkListStore *store, GtkTreeIter *iter, ThemeSemanticToken token, gboolean has_token);
static const char *
userlist_prefix_color (char prefix)
{
switch (prefix)
{
case '~': return "#d46a6a";
case '@': return "#5ea36a";
case '%': return "#d39a5f";
case '&': return "#79aecd";
case '+': return "#d2bf6a";
default: return NULL;
}
}
static void static void
userlist_column_width_notify_cb (GtkTreeViewColumn *column, GParamSpec *pspec, gpointer userdata) userlist_column_width_notify_cb (GtkTreeViewColumn *column, GParamSpec *pspec, gpointer userdata)
{ {
@@ -515,11 +500,6 @@ fe_userlist_insert (session *sess, struct User *newuser, gboolean sel)
GdkPixbuf *pix = get_user_icon (sess->server, newuser); GdkPixbuf *pix = get_user_icon (sess->server, newuser);
GtkTreeIter iter; GtkTreeIter iter;
char *nick; char *nick;
char *nick_escaped;
char *prefix = NULL;
char *prefix_escaped;
char prefix_text[2];
const char *prefix_color;
ThemeSemanticToken nick_token = THEME_TOKEN_TEXT_FOREGROUND; ThemeSemanticToken nick_token = THEME_TOKEN_TEXT_FOREGROUND;
gboolean have_nick_token = FALSE; gboolean have_nick_token = FALSE;
@@ -539,36 +519,30 @@ fe_userlist_insert (session *sess, struct User *newuser, gboolean sel)
} }
} }
nick_escaped = g_markup_escape_text (newuser->nick, -1); nick = newuser->nick;
nick = nick_escaped;
if (!prefs.hex_gui_ulist_icons) if (!prefs.hex_gui_ulist_icons)
{ {
if (newuser->prefix[0] != '\0' && newuser->prefix[0] != ' ') nick = g_malloc (strlen (newuser->nick) + 2);
{ nick[0] = newuser->prefix[0];
prefix_text[0] = newuser->prefix[0]; if (nick[0] == '\0' || nick[0] == ' ')
prefix_text[1] = '\0'; strcpy (nick, newuser->nick);
prefix_escaped = g_markup_escape_text (prefix_text, -1); else
prefix_color = userlist_prefix_color (newuser->prefix[0]); strcpy (nick + 1, newuser->nick);
if (prefix_color)
prefix = g_strdup_printf ("<b><span foreground=\"%s\">%s</span></b>", prefix_color, prefix_escaped);
else
prefix = g_strdup_printf ("<b>%s</b>", prefix_escaped);
g_free (prefix_escaped);
}
pix = NULL; pix = NULL;
} }
gtk_list_store_insert_with_values (GTK_LIST_STORE (model), &iter, 0, gtk_list_store_insert_with_values (GTK_LIST_STORE (model), &iter, 0,
COL_PIX, pix, COL_PIX, pix,
COL_PREFIX, prefix,
COL_NICK, nick, COL_NICK, nick,
COL_HOST, newuser->hostname, COL_HOST, newuser->hostname,
COL_USER, newuser, COL_USER, newuser,
-1); -1);
userlist_store_color (GTK_LIST_STORE (model), &iter, nick_token, have_nick_token); userlist_store_color (GTK_LIST_STORE (model), &iter, nick_token, have_nick_token);
g_free (prefix); if (!prefs.hex_gui_ulist_icons)
g_free (nick_escaped); {
g_free (nick);
}
userlist_row_map_set (sess, model, newuser, &iter); userlist_row_map_set (sess, model, newuser, &iter);
@@ -697,8 +671,8 @@ userlist_create_model (session *sess)
GtkTreeIterCompareFunc cmp_func; GtkTreeIterCompareFunc cmp_func;
GtkSortType sort_type; GtkSortType sort_type;
store = gtk_list_store_new (6, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, store = gtk_list_store_new (5, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_STRING, G_TYPE_POINTER, THEME_GTK_COLOR_TYPE); G_TYPE_POINTER, THEME_GTK_COLOR_TYPE);
switch (prefs.hex_gui_ulist_sort) switch (prefs.hex_gui_ulist_sort)
{ {
@@ -743,29 +717,19 @@ userlist_add_columns (GtkTreeView * treeview)
g_object_set (G_OBJECT (renderer), "ypad", 0, NULL); g_object_set (G_OBJECT (renderer), "ypad", 0, NULL);
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview), gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
-1, NULL, renderer, -1, NULL, renderer,
"pixbuf", COL_PIX, NULL); "pixbuf", 0, NULL);
column = gtk_tree_view_get_column (GTK_TREE_VIEW (treeview), 0); column = gtk_tree_view_get_column (GTK_TREE_VIEW (treeview), 0);
gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED); gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
/* nick column */ /* nick column */
column = gtk_tree_view_column_new ();
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
renderer = gtk_cell_renderer_text_new ();
if (prefs.hex_gui_compact)
g_object_set (G_OBJECT (renderer), "ypad", 0, NULL);
gtk_cell_renderer_text_set_fixed_height_from_font (GTK_CELL_RENDERER_TEXT (renderer), 1);
gtk_tree_view_column_pack_start (column, renderer, FALSE);
gtk_tree_view_column_add_attribute (column, renderer, "markup", COL_PREFIX);
renderer = gtk_cell_renderer_text_new (); renderer = gtk_cell_renderer_text_new ();
if (prefs.hex_gui_compact) if (prefs.hex_gui_compact)
g_object_set (G_OBJECT (renderer), "ypad", 0, NULL); g_object_set (G_OBJECT (renderer), "ypad", 0, NULL);
g_object_set (G_OBJECT (renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL); g_object_set (G_OBJECT (renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
gtk_cell_renderer_text_set_fixed_height_from_font (GTK_CELL_RENDERER_TEXT (renderer), 1); gtk_cell_renderer_text_set_fixed_height_from_font (GTK_CELL_RENDERER_TEXT (renderer), 1);
gtk_tree_view_column_pack_start (column, renderer, TRUE); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
gtk_tree_view_column_add_attribute (column, renderer, "markup", COL_NICK); -1, NULL, renderer,
gtk_tree_view_column_add_attribute (column, renderer, THEME_GTK_FOREGROUND_PROPERTY, COL_GDKCOLOR); "text", 1, THEME_GTK_FOREGROUND_PROPERTY, 4, NULL);
column = gtk_tree_view_get_column (GTK_TREE_VIEW (treeview), 1); column = gtk_tree_view_get_column (GTK_TREE_VIEW (treeview), 1);
gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED); gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
gtk_tree_view_column_set_expand (column, TRUE); gtk_tree_view_column_set_expand (column, TRUE);
@@ -786,7 +750,7 @@ userlist_add_columns (GtkTreeView * treeview)
gtk_cell_renderer_text_set_fixed_height_from_font (GTK_CELL_RENDERER_TEXT (renderer), 1); gtk_cell_renderer_text_set_fixed_height_from_font (GTK_CELL_RENDERER_TEXT (renderer), 1);
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview), gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
-1, NULL, renderer, -1, NULL, renderer,
"text", COL_HOST, NULL); "text", 2, NULL);
column = gtk_tree_view_get_column (GTK_TREE_VIEW (treeview), 2); column = gtk_tree_view_get_column (GTK_TREE_VIEW (treeview), 2);
gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED); gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
gtk_tree_view_column_set_expand (column, TRUE); gtk_tree_view_column_set_expand (column, TRUE);

View File

@@ -2640,11 +2640,6 @@ gtk_xtext_button_press (GtkWidget * widget, GdkEventButton * event)
xtext->select_start_x = x; xtext->select_start_x = x;
xtext->select_start_y = y; xtext->select_start_y = y;
xtext->select_start_adj = xtext_adj_get_value (xtext->adj); xtext->select_start_adj = xtext_adj_get_value (xtext->adj);
if (xtext->buffer->last_ent_start)
{
gtk_xtext_unselect (xtext);
xtext->mark_stamp = FALSE;
}
return FALSE; return FALSE;
} }

View File

@@ -26,7 +26,6 @@
#endif #endif
#ifdef WIN32 #ifdef WIN32
#include <io.h> #include <io.h>
#include <glib/gwin32.h>
#define STDIN_FILENO 0 #define STDIN_FILENO 0
#define STDOUT_FILENO 1 #define STDOUT_FILENO 1
#else #else
@@ -479,28 +478,9 @@ fe_args (int argc, char *argv[])
{ {
GError *error = NULL; GError *error = NULL;
GOptionContext *context; GOptionContext *context;
#ifdef WIN32
char *base_path = NULL;
char *locale_path = NULL;
#endif
#ifdef ENABLE_NLS #ifdef ENABLE_NLS
#ifdef WIN32
base_path = g_win32_get_package_installation_directory_of_module (NULL);
if (base_path)
{
locale_path = g_build_filename (base_path, "share", "locale", NULL);
bindtextdomain (GETTEXT_PACKAGE, locale_path);
}
else
{
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
}
g_free (locale_path);
g_free (base_path);
#else
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
#endif
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE); textdomain (GETTEXT_PACKAGE);
#endif #endif

View File

@@ -83,7 +83,7 @@ Root: HKCR; Subkey: "ZoiteChat.Theme\shell\open\command"; ValueType: string; Val
[Run] [Run]
Filename: "{app}\zoitechat.exe"; Description: "Run ZoiteChat after closing the Wizard"; Flags: nowait postinstall skipifsilent Filename: "{app}\zoitechat.exe"; Description: "Run ZoiteChat after closing the Wizard"; Flags: nowait postinstall skipifsilent
Filename: "http://docs.zoitechat.org/en/latest/changelog.html"; Description: "See what's changed"; Flags: shellexec runasoriginaluser postinstall skipifsilent unchecked Filename: "http://docs.zoitechat.org/en/latest/changelog.html"; Description: "See what's changed"; Flags: shellexec runasoriginaluser postinstall skipifsilent unchecked
Filename: "{tmp}\vcredist.exe"; Parameters: "/install /quiet /norestart"; StatusMsg: "Installing Visual C++ Redistributable"; Components: deps\vcredist2015; Tasks: not portable Filename: "{tmp}\vcredist.exe"; Parameters: "/install /quiet /norestart"; StatusMsg: "Installing Visual C++ Redistributable"; Components: deps\vcredist2015; Flags: skipifdoesntexist; Tasks: not portable
Filename: "{tmp}\perl.msi"; StatusMsg: "Installing Perl"; Components: langs\perl; Flags: shellexec skipifdoesntexist; Tasks: not portable Filename: "{tmp}\perl.msi"; StatusMsg: "Installing Perl"; Components: langs\perl; Flags: shellexec skipifdoesntexist; Tasks: not portable
Filename: "{tmp}\python.msi"; StatusMsg: "Installing Python"; Components: langs\python; Flags: shellexec skipifdoesntexist; Tasks: not portable Filename: "{tmp}\python.msi"; StatusMsg: "Installing Python"; Components: langs\python; Flags: shellexec skipifdoesntexist; Tasks: not portable
Filename: "{tmp}\python.exe"; Parameters: "InstallAllUsers=1 PrependPath=1"; StatusMsg: "Installing Python"; Components: langs\python; Flags: shellexec skipifdoesntexist; Tasks: not portable Filename: "{tmp}\python.exe"; Parameters: "InstallAllUsers=1 PrependPath=1"; StatusMsg: "Installing Python"; Components: langs\python; Flags: shellexec skipifdoesntexist; Tasks: not portable
@@ -339,7 +339,7 @@ begin
if not IsTaskSelected('portable') then if not IsTaskSelected('portable') then
begin begin
REDIST := 'https://aka.ms/vs/17/release/vc_redist.x64.exe'; REDIST := 'https://github.com/ZoiteChat/gvsbuild/releases/download/zoitechat-2.18.0-pre4/vc_redist.x64.exe';
PERL := 'https://github.com/StrawberryPerl/Perl-Dist-Strawberry/releases/download/SP_54201_64bit/strawberry-perl-5.42.0.1-64bit.msi'; PERL := 'https://github.com/StrawberryPerl/Perl-Dist-Strawberry/releases/download/SP_54201_64bit/strawberry-perl-5.42.0.1-64bit.msi';
PY3 := 'https://www.python.org/ftp/python/3.14.3/python-3.14.3-amd64.exe'; PY3 := 'https://www.python.org/ftp/python/3.14.3/python-3.14.3-amd64.exe';
SPELL := 'https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.16.2/ZoiteChat.Spelling.Dictionaries.r2.exe'; SPELL := 'https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.16.2/ZoiteChat.Spelling.Dictionaries.r2.exe';
@@ -387,14 +387,6 @@ begin
WizardForm.TasksList.Checked[1] := False WizardForm.TasksList.Checked[1] := False
MsgBox('Portable mode is only intended for use on portable drives and has been disabled.', mbInformation, MB_OK) MsgBox('Portable mode is only intended for use on portable drives and has been disabled.', mbInformation, MB_OK)
end; end;
if CurPageID = wpReady then
if IsComponentSelected('deps\vcredist2015') and not CheckVCInstall() and not FileExists(ExpandConstant('{tmp}\vcredist.exe')) then
begin
MsgBox('Visual C++ Redistributable could not be downloaded. Please retry setup or install it manually and rerun setup.', mbError, MB_OK);
Result := False;
Exit;
end;
end; end;
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////