14 Commits

Author SHA1 Message Date
7c8c33db47 Handle Win32 WM_SYSCOMMAND minimize/restore workaround 2026-04-01 23:45:51 -06:00
51e9ac15df fix zoitechat.svg 2026-04-01 00:21:44 -06:00
deepend-tildeclub
4df579e0d3 Merge pull request #185 from ZoiteChat/improve-appimage-URI-folder-opening
Sanitize Linux open env for AppImage, add safer fallbacks
2026-04-01 00:15:53 -06:00
2cf69d2e67 Sanitize Linux open env for AppImage, add safer fallbacks 2026-03-31 23:26:40 -06:00
deepend-tildeclub
64bffd0dc8 Merge pull request #184 from ZoiteChat/add-gtk3-themes-windows-installer
Theme: Adding themes users can select at install time.
2026-03-31 19:38:40 -06:00
deepend-tildeclub
b451240dfd Merge pull request #181 from ZoiteChat/prefs-option-disable-tab-close-button
Add pref for tab close buttons
2026-03-31 19:30:26 -06:00
41cc1f617f Theme: Adding themes users can select at install time. 2026-03-31 19:28:45 -06:00
ed671eac25 Add pref for tab close buttons 2026-03-31 18:10:28 -06:00
9f2529adb6 Update all links to new domain. 2026-03-30 18:25:26 -06:00
deepend-tildeclub
3903d7b9e5 Change official documentation link in README
Updated the link for the official documentation from zoitechat.zoite.net to zoitechat.org.
2026-03-30 17:16:01 -06:00
ec4d698021 Bump to 2.18.0~pre6 2026-03-30 13:04:00 -06:00
deepend-tildeclub
da06c71389 Merge pull request #177 from ZoiteChat/client-cert-importer
Add client SSL cert import action
2026-03-30 12:30:26 -06:00
0f508bf438 Sanitize OpenSSL env for client cert actions 2026-03-30 11:57:58 -06:00
97dd7c5d57 Add client SSL cert import action 2026-03-30 11:46:08 -06:00
20 changed files with 353 additions and 74 deletions

View File

@@ -1,6 +1,30 @@
ZoiteChat ChangeLog
=================
2.18.0~pre6 (2026-03-30)
- Applied app theme CSS to the menubar consistently across the app.
- Restored horizontal separator lines in menus.
- Improved Windows installer VC++ redistributable handling by failing loudly when missing and using the official Microsoft download endpoint.
- Fixed Windows locale path resolution in both GTK and text frontends.
- Fixed duplicate dialog buttons persisting in the UI.
- Fixed GTK auto-replace cursor snapback.
- Restored hiding of formatting control bytes so only formatted output is shown.
- Added one-click client SSL certificate tools, including generation with P-256 certificates.
- Added client SSL certificate import support in the network editor.
- Added 99-color support.
- Fixed xtext link hit-testing coordinates.
- Fixed short-palette fallback clobbering tab colors.
- Lazy-loads Preferences pages on first open for faster dialog startup.
- Removed unused UI icons.
- Added a None option for resetting the GTK3 theme back to system/default behavior.
- Added channel-only mode to Ctrl+F search.
- Disabled disk info in sysinfo.
- Wrapped the topic bar in a scroller with bounded height.
- Added close buttons to tabs.
- Fixed fallback GTK menu highlight states.
- Applied configured font preferences to the topic bar, channel tree, user list, and input box.
2.18.0~pre5 (2026-03-22)
------------------------
- Overhauled preferences/config saving: fully staged and transactional, debounced

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -4,7 +4,7 @@
<extends>net.zoite.Zoitechat</extends>
<name>@NAME@ Plugin</name>
<summary>@SUMMARY@</summary>
<url type="homepage">https://zoitechat.zoite.net/</url>
<url type="homepage">https://zoitechat.org/</url>
<project_license>@LICENSE@</project_license>
<metadata_license>CC0-1.0</metadata_license>
<update_contact>deepend_AT_zoite.net</update_contact>

View File

@@ -16,12 +16,12 @@
<p>ZoiteChat is an easy to use yet extensible IRC Client based on Hexchat. It allows you to securely join multiple networks and talk to users privately or in channels using a customizable interface. You can even transfer files.</p>
<p>ZoiteChat supports features such as: DCC, SASL, proxies, spellcheck, alerts, logging, custom themes, and Python/Perl scripts.</p>
</description>
<url type="homepage">https://zoitechat.zoite.net</url>
<url type="homepage">https://zoitechat.org</url>
<url type="bugtracker">https://github.com/zoitechat/zoitechat</url>
<url type="help">https://docs.zoitechat.zoite.net/en/latest/</url>
<url type="help">https://docs.zoitechat.org/en/latest/</url>
<screenshots>
<screenshot type="default">
<image>https://zoitechat.zoite.net/assets/ZoiteChat.png</image>
<image>https://zoitechat.org/assets/ZoiteChat.png</image>
<caption>Main Chat Window</caption>
</screenshot>
</screenshots>
@@ -29,6 +29,46 @@
<id>zoitechat.desktop</id>
</provides>
<releases>
<release date="2026-03-30" version="2.18.0~pre6">
<description>
<p>GTK theme and UI:</p>
<ul>
<li>Applied app theme CSS to the menubar consistently across the app.</li>
<li>Restored horizontal separator lines in menus.</li>
<li>Fixed duplicate dialog buttons persisting in the UI.</li>
<li>Fixed GTK auto-replace cursor snapback.</li>
<li>Restored hiding of formatting control bytes so only formatted output is shown.</li>
<li>Fixed xtext link hit-testing coordinates.</li>
<li>Fixed short-palette fallback clobbering tab colors.</li>
<li>Added a None option for resetting the GTK3 theme back to system/default behavior.</li>
<li>Wrapped the topic bar in a scroller with bounded height.</li>
<li>Fixed fallback GTK menu highlight states.</li>
<li>Applied configured font preferences to the topic bar, channel tree, user list, and input box.</li>
<li>Removed unused UI icons.</li>
<li>Added close buttons to tabs.</li>
</ul>
<p>Preferences and search:</p>
<ul>
<li>Lazy-loads Preferences pages on first open for faster dialog startup.</li>
<li>Added channel-only mode to Ctrl+F search.</li>
</ul>
<p>Security and certificates:</p>
<ul>
<li>Added one-click client SSL certificate tools, including generation with P-256 certificates.</li>
<li>Added client SSL certificate import support in the network editor.</li>
</ul>
<p>Windows and packaging:</p>
<ul>
<li>Improved Windows installer VC++ redistributable handling by failing loudly when missing and using the official Microsoft download endpoint.</li>
<li>Fixed Windows locale path resolution in both GTK and text frontends.</li>
</ul>
<p>Other changes:</p>
<ul>
<li>Added 99-color support.</li>
<li>Disabled disk info in sysinfo.</li>
</ul>
</description>
</release>
<release date="2026-03-22" version="2.18.0~pre5">
<description>
<p>Preferences and config saving:</p>
@@ -60,14 +100,6 @@
</ul>
</description>
</release>
<release date="2026-03-22" version="2.18.0~pre5">
<description>
<p>Version metadata update:</p>
<ul>
<li>Bumped release version references to <code>2.18.0~pre5</code> across build and packaging files.</li>
</ul>
</description>
</release>
<release date="2026-03-14" version="2.18.0~pre4">
<description>
<p>UI fixes, topic bar improvements, and selection styling updates:</p>

View File

@@ -1,5 +1,5 @@
project('zoitechat', 'c',
version: '2.18.0~pre5',
version: '2.18.0~pre6',
meson_version: '>= 0.55.0',
default_options: [
'c_std=c17',

View File

@@ -1457,14 +1457,14 @@ perl_load_file (char *filename)
"You must have a Visual C++ build of Perl "
PERL_REQUIRED_VERSION " installed in order to\n"
"run Perl scripts. A reboot may be required.\n\n"
"http://zoitechat.zoite.net/downloads.html\n\n"
"http://zoitechat.org/downloads.html\n\n"
"I have found Perl 5.6, but that is too old.");
} else {
thread_mbox ("Cannot open " PERL_DLL "!\n\n"
"You must have a Visual C++ build of Perl "
PERL_REQUIRED_VERSION " installed in order to\n"
"run Perl scripts. A reboot may be required.\n\n"
"http://zoitechat.zoite.net/downloads.html\n\n"
"http://zoitechat.org/downloads.html\n\n"
"Make sure Perl's bin directory is in your PATH.");
}
}

View File

@@ -19,7 +19,7 @@ else:
if not hasattr(sys, 'argv'):
sys.argv = ['<zoitechat>']
VERSION = b'2.18.0~pre5'
VERSION = b'2.18.0~pre6'
PLUGIN_NAME = ffi.new('char[]', b'Python')
PLUGIN_DESC = ffi.new('char[]', b'Python %d.%d scripting interface' % (sys.version_info[0], sys.version_info[1]))
PLUGIN_VERSION = ffi.new('char[]', VERSION)

View File

@@ -24,7 +24,7 @@
#include "zoitechat-plugin.h"
#define APPCAST_URL "https://zoitechat.zoite.net/appcast.xml"
#define APPCAST_URL "https://zoitechat.org/appcast.xml"
static zoitechat_plugin *ph;
static char name[] = "Update Checker";

View File

@@ -8,7 +8,7 @@
[![Version][github-version-img]][github-version-uri] [![Downloads][github-downloads-img]][github-downloads-uri] [![Size][github-size-img]][github-size-img] [![Last Commit][github-commit-img]][github-commit-img] [![Contributors][contribs-all-img]](#contributors-)
[![View Official Documentation](https://img.shields.io/badge/View_Official_Documentation-526CFE?style=for-the-badge&logo=MaterialForMkDocs&logoColor=white)](https://docs.zoitechat.zoite.net)
[![View Official Documentation](https://img.shields.io/badge/View_Official_Documentation-526CFE?style=for-the-badge&logo=MaterialForMkDocs&logoColor=white)](https://docs.zoitechat.org)
</div>
@@ -33,8 +33,8 @@
ZoiteChat is an HexChat based IRC client for Windows and UNIX-like operating systems.
See [IRCHelp.org](http://irchelp.org) for information about IRC in general.
For more information on ZoiteChat please read our [documentation](https://docs.zoitechat.zoite.net/):
- [Downloads](https://zoitechat.zoite.net/download)
For more information on ZoiteChat please read our [documentation](https://docs.zoitechat.org/):
- [Downloads](https://zoitechat.org/download)
- [Troubleshooting](troubleshooting.md)

View File

@@ -445,6 +445,7 @@ const struct prefs vars[] =
{"gui_dark_mode", P_OFFINT (hex_gui_dark_mode), TYPE_INT},
{"gui_gtk3_variant", P_OFFINT (hex_gui_gtk3_variant), TYPE_INT},
{"gui_tab_layout", P_OFFINT (hex_gui_tab_layout), TYPE_INT},
{"gui_tab_closebuttons", P_OFFINT (hex_gui_tab_closebuttons), TYPE_BOOL},
{"gui_tab_middleclose", P_OFFINT (hex_gui_tab_middleclose), TYPE_BOOL},
{"gui_tab_newtofront", P_OFFINT (hex_gui_tab_newtofront), TYPE_INT},
{"gui_tab_pos", P_OFFINT (hex_gui_tab_pos), TYPE_INT},
@@ -777,6 +778,7 @@ load_default_config(void)
prefs.hex_gui_tab_chans = 1;
prefs.hex_gui_tab_dialogs = 1;
prefs.hex_gui_tab_icons = 1;
prefs.hex_gui_tab_closebuttons = 1;
prefs.hex_gui_tab_middleclose = 1;
prefs.hex_gui_tab_server = 1;
prefs.hex_gui_tab_sort = 1;

View File

@@ -4070,7 +4070,7 @@ const struct commands xc_cmds[] = {
{"ME", cmd_me, 0, 0, 1,
N_("ME <action>, sends the action to the current channel (actions are written in the 3rd person, like /me jumps)")},
{"MENU", cmd_menu, 0, 0, 1, "MENU [-eX] [-i<ICONFILE>] [-k<mod>,<key>] [-m] [-pX] [-r<X,group>] [-tX] {ADD|DEL} <path> [command] [unselect command]\n"
" See https://docs.zoitechat.zoite.net/en/latest/en/latest/plugins.html#controlling-the-gui for more details."},
" See https://docs.zoitechat.org/en/latest/en/latest/plugins.html#controlling-the-gui for more details."},
{"MHOP", cmd_mhop, 1, 1, 1,
N_("MHOP, Mass hop's all users in the current channel (needs chanop)")},
{"MKICK", cmd_mkick, 1, 1, 1,

View File

@@ -265,6 +265,7 @@ struct zoitechatprefs
int hex_gui_search_pos;
int hex_gui_slist_select;
int hex_gui_tab_layout;
int hex_gui_tab_closebuttons;
int hex_gui_tab_middleclose;
int hex_gui_tab_newtofront;
int hex_gui_tab_pos;

View File

@@ -653,7 +653,7 @@ tab_click_cb (GtkWidget *wid, GdkEventButton *event, chan *ch)
if (event->button == 1 && event->type == GDK_BUTTON_PRESS)
{
close_button = g_object_get_data (G_OBJECT (wid), "tab-close-button");
if (close_button &&
if (prefs.hex_gui_tab_closebuttons && close_button &&
gtk_widget_translate_coordinates (close_button, wid, 0, 0, &close_x, &close_y))
{
gtk_widget_get_allocation (close_button, &close_alloc);
@@ -679,7 +679,7 @@ tab_close_motion_cb (GtkWidget *wid, GdkEventMotion *event, chan *ch)
gboolean hover = FALSE;
close_button = g_object_get_data (G_OBJECT (wid), "tab-close-button");
if (close_button &&
if (prefs.hex_gui_tab_closebuttons && close_button &&
gtk_widget_translate_coordinates (close_button, wid, 0, 0, &close_x, &close_y))
{
gtk_widget_get_allocation (close_button, &close_alloc);
@@ -714,7 +714,7 @@ tab_close_leave_cb (GtkWidget *wid, GdkEventCrossing *event, chan *ch)
GtkWidget *close_button;
close_button = g_object_get_data (G_OBJECT (wid), "tab-close-button");
if (close_button)
if (prefs.hex_gui_tab_closebuttons && close_button)
gtk_widget_unset_state_flags (close_button, GTK_STATE_FLAG_PRELIGHT);
if (gtk_widget_get_window (wid))
gdk_window_set_cursor (gtk_widget_get_window (wid), NULL);
@@ -780,6 +780,8 @@ cv_tabs_add (chanview *cv, chan *ch, char *name, GtkTreeIter *parent)
G_CALLBACK (tab_toggled_cb), ch);
g_object_set_data (G_OBJECT (but), "u", ch->userdata);
gtk_widget_show_all (hbox);
if (!prefs.hex_gui_tab_closebuttons)
gtk_widget_hide (close_button);
tab_add_real (cv, but, ch);

View File

@@ -1308,17 +1308,38 @@ maybe_escape_uri (const char *uri)
return g_strdup (uri);
}
#ifndef WIN32
static gchar **
fe_open_url_env_sanitized (void)
{
gchar **env = g_get_environ ();
const char *vars[] = {"LD_LIBRARY_PATH", "LD_PRELOAD", "APPDIR", "APPIMAGE", "ARGV0", NULL};
int i;
for (i = 0; vars[i]; i++)
{
gchar **tmp_env = env;
env = g_environ_unsetenv (tmp_env, vars[i]);
if (env != tmp_env)
g_strfreev (tmp_env);
}
return env;
}
#endif
static void
fe_open_url_inner (const char *url)
{
GError *error = NULL;
char *escaped_url = maybe_escape_uri (url);
gboolean opened = g_app_info_launch_default_for_uri (escaped_url, NULL, &error);
gboolean opened = FALSE;
#ifdef WIN32
opened = g_app_info_launch_default_for_uri (escaped_url, NULL, &error);
if (!opened)
{
g_clear_error (&error);
#ifdef WIN32
gunichar2 *url_utf16 = g_utf8_to_utf16 (escaped_url, -1, NULL, NULL, NULL);
if (url_utf16 != NULL)
@@ -1326,22 +1347,11 @@ fe_open_url_inner (const char *url)
opened = ((INT_PTR) ShellExecuteW (0, L"open", url_utf16, NULL, NULL, SW_SHOWNORMAL)) > 32;
g_free (url_utf16);
}
#else
gchar *xdg_open_argv[] = {(gchar *) "xdg-open", escaped_url, NULL};
gchar **spawn_env = NULL;
spawn_env = g_get_environ ();
{
gchar **tmp_env = spawn_env;
spawn_env = g_environ_unsetenv (tmp_env, "LD_LIBRARY_PATH");
if (spawn_env != tmp_env)
g_strfreev (tmp_env);
tmp_env = spawn_env;
spawn_env = g_environ_unsetenv (tmp_env, "LD_PRELOAD");
if (spawn_env != tmp_env)
g_strfreev (tmp_env);
}
#else
{
gchar *xdg_open_argv[] = {(gchar *) "xdg-open", escaped_url, NULL};
gchar **spawn_env = fe_open_url_env_sanitized ();
if (g_spawn_async (NULL, xdg_open_argv, spawn_env,
G_SPAWN_SEARCH_PATH | G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL,
@@ -1354,6 +1364,16 @@ fe_open_url_inner (const char *url)
g_clear_error (&error);
}
g_strfreev (spawn_env);
}
if (!opened)
{
opened = g_app_info_launch_default_for_uri (escaped_url, NULL, &error);
if (!opened)
g_clear_error (&error);
}
if (!opened && gtk_show_uri_on_window (NULL, escaped_url, GDK_CURRENT_TIME, &error))
{
opened = TRUE;
@@ -1362,10 +1382,7 @@ fe_open_url_inner (const char *url)
{
g_clear_error (&error);
}
g_strfreev (spawn_env);
#endif
}
if (!opened)
{

View File

@@ -4431,7 +4431,7 @@ mg_create_topwindow (session *sess)
#ifdef G_OS_WIN32
parent_win = gtk_widget_get_window (win);
gdk_window_add_filter (parent_win, mg_win32_filter, NULL);
gdk_window_add_filter (parent_win, mg_win32_filter, win);
#endif
}
@@ -4464,6 +4464,8 @@ static GdkFilterReturn
mg_win32_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data)
{
MSG *msg = (MSG*)xevent;
GtkWidget *win = GTK_IS_WIDGET (data) ? GTK_WIDGET (data) : NULL;
static gboolean handling_syscommand = FALSE;
if (!msg)
return GDK_FILTER_CONTINUE;
@@ -4480,6 +4482,30 @@ mg_win32_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data)
return GDK_FILTER_CONTINUE;
}
if (msg->message == WM_SYSCOMMAND && win && !handling_syscommand)
{
const UINT command = ((UINT) msg->wParam) & 0xFFF0u;
if (command == SC_MINIMIZE || command == SC_RESTORE)
{
handling_syscommand = TRUE;
if (command == SC_MINIMIZE)
{
ShowWindow (msg->hwnd, SW_MINIMIZE);
}
else
{
ShowWindow (msg->hwnd, SW_RESTORE);
ShowWindow (msg->hwnd, SW_SHOW);
SetForegroundWindow (msg->hwnd);
}
handling_syscommand = FALSE;
return GDK_FILTER_REMOVE;
}
}
if (msg->message == WM_COPYDATA)
{
COPYDATASTRUCT *copy_data = (COPYDATASTRUCT *)msg->lParam;
@@ -4609,7 +4635,7 @@ mg_create_tabwindow (session *sess)
#ifdef G_OS_WIN32
parent_win = gtk_widget_get_window (win);
gdk_window_add_filter (parent_win, mg_win32_filter, NULL);
gdk_window_add_filter (parent_win, mg_win32_filter, win);
#endif
}

View File

@@ -1717,7 +1717,7 @@ menu_ctcpguiopen (void)
static void
menu_docs (GtkWidget *wid, gpointer none)
{
fe_open_url ("https://docs.zoitechat.zoite.net/en/latest/");
fe_open_url ("https://docs.zoitechat.org/en/latest/");
}
/*static void
@@ -1862,7 +1862,7 @@ about_dialog_response (GtkDialog *dialog, int response, gpointer data)
{
if (response == GTK_RESPONSE_HELP)
{
fe_open_url ("http://zoitechat.zoite.net");
fe_open_url ("http://zoitechat.org");
return;
}
if (response == GTK_RESPONSE_APPLY)

View File

@@ -91,6 +91,7 @@ static GtkWidget *edit_label_real;
static GtkWidget *edit_label_user;
static GtkWidget *edit_trees[N_TREES];
static GtkWidget *edit_button_cert_generate;
static GtkWidget *edit_button_cert_import;
static GtkWidget *edit_button_cert_info;
static GtkWidget *edit_button_cert_delete;
@@ -135,12 +136,98 @@ servlist_update_cert_buttons (ircnet *net)
if (edit_button_cert_generate)
gtk_widget_set_visible (edit_button_cert_generate, !has_cert);
if (edit_button_cert_import)
gtk_widget_set_visible (edit_button_cert_import, !has_cert);
if (edit_button_cert_info)
gtk_widget_set_visible (edit_button_cert_info, has_cert);
if (edit_button_cert_delete)
gtk_widget_set_visible (edit_button_cert_delete, has_cert);
}
static void
servlist_import_client_cert_cb (GtkWidget *button, gpointer userdata)
{
ircnet *net = (ircnet *)userdata;
GtkWidget *dialog;
GtkWidget *message;
GtkFileFilter *filter;
char *cert_dir;
char *cert_file;
char *source_file;
char *contents;
gsize length;
if (!net || !net->name || !net->name[0])
return;
dialog = gtk_file_chooser_dialog_new (_("Import Client Certificate"),
GTK_WINDOW (edit_win),
GTK_FILE_CHOOSER_ACTION_OPEN,
_("_Cancel"), GTK_RESPONSE_CANCEL,
_("_Open"), GTK_RESPONSE_ACCEPT,
NULL);
filter = gtk_file_filter_new ();
gtk_file_filter_set_name (filter, _("Certificate files"));
gtk_file_filter_add_pattern (filter, "*.pem");
gtk_file_filter_add_pattern (filter, "*.crt");
gtk_file_filter_add_pattern (filter, "*.cer");
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
filter = gtk_file_filter_new ();
gtk_file_filter_set_name (filter, _("All files"));
gtk_file_filter_add_pattern (filter, "*");
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
theme_manager_attach_window (dialog);
if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_ACCEPT)
{
gtk_widget_destroy (dialog);
return;
}
source_file = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
gtk_widget_destroy (dialog);
if (!source_file)
return;
cert_dir = g_build_filename (get_xdir (), "certs", NULL);
cert_file = servlist_get_cert_file (net);
contents = NULL;
length = 0;
if (cert_file &&
g_mkdir_with_parents (cert_dir, 0700) == 0 &&
g_file_get_contents (source_file, &contents, &length, NULL) &&
g_file_set_contents (cert_file, contents, length, NULL))
{
chmod (cert_file, 0600);
servlist_update_cert_buttons (net);
message = gtk_message_dialog_new (GTK_WINDOW (edit_win),
GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL,
GTK_MESSAGE_INFO,
GTK_BUTTONS_CLOSE,
_("Client certificate imported for \"%s\"."),
net->name);
}
else
{
message = gtk_message_dialog_new (GTK_WINDOW (edit_win),
GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
_("Failed to import client certificate for \"%s\"."),
net->name);
}
theme_manager_attach_window (message);
g_signal_connect_swapped (message, "response", G_CALLBACK (gtk_widget_destroy), message);
gtk_widget_show (message);
g_free (contents);
g_free (cert_file);
g_free (cert_dir);
g_free (source_file);
}
static void
servlist_generate_client_cert_cb (GtkWidget *button, gpointer userdata)
{
@@ -165,6 +252,7 @@ servlist_generate_client_cert_cb (GtkWidget *button, gpointer userdata)
gboolean success;
gint status;
char *argv[20];
char **envp;
if (!net || !net->name || !net->name[0])
return;
@@ -187,6 +275,7 @@ servlist_generate_client_cert_cb (GtkWidget *button, gpointer userdata)
crt_len = 0;
success = FALSE;
status = 0;
envp = g_environ_unsetenv (g_get_environ (), "LD_LIBRARY_PATH");
if (g_mkdir_with_parents (cert_dir, 0700) == 0 &&
g_file_set_contents (openssl_conf, conf_data, -1, NULL))
@@ -212,7 +301,7 @@ servlist_generate_client_cert_cb (GtkWidget *button, gpointer userdata)
argv[18] = subject;
argv[19] = NULL;
spawned = g_spawn_sync (NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL,
spawned = g_spawn_sync (NULL, argv, envp, G_SPAWN_SEARCH_PATH, NULL, NULL,
&stdout_data, &stderr_data, &status, NULL);
if (spawned && g_spawn_check_exit_status (status, NULL) &&
g_file_get_contents (key_file, &key_data, &key_len, NULL) &&
@@ -267,6 +356,7 @@ servlist_generate_client_cert_cb (GtkWidget *button, gpointer userdata)
g_free (openssl_conf);
g_free (cert_file);
g_free (cert_dir);
g_strfreev (envp);
#else
return;
#endif
@@ -284,6 +374,7 @@ servlist_cert_info_cb (GtkWidget *button, gpointer userdata)
gboolean spawned;
gint status;
char *argv[12];
char **envp;
cert_file = servlist_get_cert_file (net);
if (!cert_file)
@@ -292,6 +383,7 @@ servlist_cert_info_cb (GtkWidget *button, gpointer userdata)
stdout_data = NULL;
stderr_data = NULL;
status = 0;
envp = g_environ_unsetenv (g_get_environ (), "LD_LIBRARY_PATH");
argv[0] = "openssl";
argv[1] = "x509";
argv[2] = "-in";
@@ -305,7 +397,7 @@ servlist_cert_info_cb (GtkWidget *button, gpointer userdata)
argv[10] = "-sha256";
argv[11] = NULL;
spawned = g_spawn_sync (NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL,
spawned = g_spawn_sync (NULL, argv, envp, G_SPAWN_SEARCH_PATH, NULL, NULL,
&stdout_data, &stderr_data, &status, NULL);
if (spawned && g_spawn_check_exit_status (status, NULL) && stdout_data && stdout_data[0])
@@ -336,6 +428,7 @@ servlist_cert_info_cb (GtkWidget *button, gpointer userdata)
g_free (stdout_data);
g_free (stderr_data);
g_free (cert_file);
g_strfreev (envp);
#else
return;
#endif
@@ -2285,6 +2378,11 @@ servlist_open_edit (GtkWidget *parent, ircnet *net)
G_CALLBACK (servlist_generate_client_cert_cb), net);
gtk_box_pack_start (GTK_BOX (hbox_cert_buttons), edit_button_cert_generate, FALSE, FALSE, 0);
edit_button_cert_import = gtk_button_new_with_mnemonic (_("Import client SSL cert"));
g_signal_connect (G_OBJECT (edit_button_cert_import), "clicked",
G_CALLBACK (servlist_import_client_cert_cb), net);
gtk_box_pack_start (GTK_BOX (hbox_cert_buttons), edit_button_cert_import, FALSE, FALSE, 0);
edit_button_cert_info = gtk_button_new_with_mnemonic (_("Client SSL cert info"));
g_signal_connect (G_OBJECT (edit_button_cert_info), "clicked",
G_CALLBACK (servlist_cert_info_cb), net);

View File

@@ -330,6 +330,7 @@ static const setting tabs_settings[] =
{ST_TOGGLE, N_("Show icons in the channel tree"), P_OFFINTNL(hex_gui_tab_icons), 0, 0, 0},
{ST_TOGGLE, N_("Show dotted lines in the channel tree"), P_OFFINTNL(hex_gui_tab_dots), 0, 0, 0},
{ST_TOGGLE, N_("Scroll mouse-wheel to change tabs"), P_OFFINTNL (hex_gui_tab_scrollchans), 0, 0, 0},
{ST_TOGGLE, N_("Show close button on tabs"), P_OFFINTNL(hex_gui_tab_closebuttons), 0, 0, 0},
{ST_TOGGLE, N_("Middle click to close tab"), P_OFFINTNL(hex_gui_tab_middleclose), 0, 0, 0},
{ST_TOGGLE, N_("Smaller text"), P_OFFINTNL(hex_gui_tab_small), 0, 0, 0},
{ST_MENU, N_("Focus new tabs:"), P_OFFINTNL(hex_gui_tab_newtofront), 0, focusnewtabsmenu, 0},
@@ -2186,6 +2187,8 @@ setup_apply (struct zoitechatprefs *pr)
noapply = TRUE;
if (DIFF (hex_gui_tab_icons))
noapply = TRUE;
if (DIFF (hex_gui_tab_closebuttons))
noapply = TRUE;
if (DIFF (hex_gui_tab_server))
noapply = TRUE;
if (DIFF (hex_gui_tab_small))

View File

@@ -9,10 +9,10 @@ AppName=ZoiteChat
AppVersion={#APPVER}
AppVerName=ZoiteChat {#APPVER}
AppPublisher=ZoiteChat
AppPublisherURL=http://zoitechat.zoite.net
AppPublisherURL=http://zoitechat.org
AppCopyright=Copyright (C) 1998-2010 Peter Zelezny
AppSupportURL=https://github.com/zoitechat/zoitechat/issues
AppUpdatesURL=http://zoitechat.zoite.net/downloads.html
AppUpdatesURL=http://zoitechat.org/downloads.html
LicenseFile=share\doc\zoitechat\COPYING
UninstallDisplayIcon={app}\zoitechat.exe
UninstallDisplayName=ZoiteChat
@@ -61,6 +61,9 @@ Name: "langs"; Description: "Language Interfaces"; Types: custom; Flags: disable
Name: "langs\lua"; Description: "Lua"; Types: normal custom; Flags: disablenouninstallwarning
Name: "langs\perl"; Description: "Perl (requires Perl 5.42)"; Types: custom; Flags: disablenouninstallwarning
Name: "langs\python"; Description: "Python (requires Python 3.14.3)"; Types: custom; Flags: disablenouninstallwarning
Name: "themes"; Description: "GTK3 Themes"; Types: normal minimal custom; Flags: disablenouninstallwarning
Name: "themes\windows10"; Description: "Windows 10"; Types: normal minimal custom; Flags: disablenouninstallwarning
Name: "themes\windows10dark"; Description: "Windows 10 Dark"; Types: normal minimal custom; Flags: disablenouninstallwarning
Name: "deps"; Description: "Dependencies"; Types: custom; Flags: disablenouninstallwarning
Name: "deps\vcredist2015"; Description: "Visual C++ Redistributable 2015"; Types: normal minimal custom; Flags: disablenouninstallwarning
@@ -88,6 +91,11 @@ Filename: "{tmp}\perl.msi"; StatusMsg: "Installing Perl"; Components: langs\perl
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}\spelling-dicts.exe"; Parameters: "/verysilent"; StatusMsg: "Installing Spelling Dictionaries"; Components: spell; Flags: skipifdoesntexist; Tasks: not portable
Filename: "{sys}\WindowsPowerShell\v1.0\powershell.exe"; Parameters: "-NoProfile -ExecutionPolicy Bypass -Command ""Expand-Archive -LiteralPath '{tmp}\Windows-10-3.2.1.zip' -DestinationPath '{userappdata}\ZoiteChat\gtk3-themes' -Force"""; StatusMsg: "Installing GTK3 Theme: Windows 10"; Components: themes\windows10; Flags: runhidden waituntilterminated skipifdoesntexist
Filename: "{sys}\WindowsPowerShell\v1.0\powershell.exe"; Parameters: "-NoProfile -ExecutionPolicy Bypass -Command ""Expand-Archive -LiteralPath '{tmp}\Windows-10-Dark-3.2.1-dark.zip' -DestinationPath '{userappdata}\ZoiteChat\gtk3-themes' -Force"""; StatusMsg: "Installing GTK3 Theme: Windows 10 Dark"; Components: themes\windows10dark; Flags: runhidden waituntilterminated skipifdoesntexist
[Dirs]
Name: "{userappdata}\ZoiteChat\gtk3-themes"; Components: themes
[Files]
Source: "portable-mode"; DestDir: "{app}"; Tasks: portable
@@ -196,6 +204,10 @@ Name: "{commonappdata}\Microsoft\Internet Explorer\Quick Launch\ZoiteChat"; File
[Messages]
BeveledLabel= {#APPNAM}
[UninstallDelete]
Type: filesandordirs; Name: "{userappdata}\ZoiteChat\gtk3-themes\Windows-10-3.2.1"; Components: themes\windows10
Type: filesandordirs; Name: "{userappdata}\ZoiteChat\gtk3-themes\Windows-10-Dark-3.2.1-dark"; Components: themes\windows10dark
[Code]
#ifndef USE_INNO_DOWNLOAD_PLUGIN
var
@@ -336,6 +348,12 @@ begin
begin
idpClearFiles;
if IsComponentSelected('themes\windows10') then
idpAddFile('https://dl.zoitechat.zoite.net/themes/GTK3Themes/Windows-10-3.2.1.zip', ExpandConstant('{tmp}\Windows-10-3.2.1.zip'));
if IsComponentSelected('themes\windows10dark') then
idpAddFile('https://dl.zoitechat.zoite.net/themes/GTK3Themes/Windows-10-Dark-3.2.1-dark.zip', ExpandConstant('{tmp}\Windows-10-Dark-3.2.1-dark.zip'));
if not IsTaskSelected('portable') then
begin
@@ -389,6 +407,21 @@ begin
end;
if CurPageID = wpReady then
begin
if IsComponentSelected('themes\windows10') and not FileExists(ExpandConstant('{tmp}\Windows-10-3.2.1.zip')) then
begin
MsgBox('Windows 10 GTK3 theme could not be downloaded. Please retry setup and rerun setup.', mbError, MB_OK);
Result := False;
Exit;
end;
if IsComponentSelected('themes\windows10dark') and not FileExists(ExpandConstant('{tmp}\Windows-10-Dark-3.2.1-dark.zip')) then
begin
MsgBox('Windows 10 Dark GTK3 theme could not be downloaded. Please retry setup and rerun setup.', mbError, MB_OK);
Result := False;
Exit;
end;
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);
@@ -396,6 +429,7 @@ begin
Exit;
end;
end;
end;
/////////////////////////////////////////////////////////////////////
// these are required for x86->x64 or reverse upgrades

View File

@@ -1 +1 @@
2.18.0~pre5
2.18.0~pre6