20 Commits

Author SHA1 Message Date
deepend-tildeclub
c43915d609 Merge pull request #111 from ZoiteChat/perl-python-flatpak
flatpak: enable Python/Perl plugins; bundle Perl runtime module
2026-03-13 01:04:32 -06:00
989ecc5a23 flatpak: bump pycparser/cffi 2026-03-13 00:48:56 -06:00
a225af6d71 fix: add strings.h for Perl strcasecmp funcs 2026-03-12 22:33:28 -06:00
d2407c39c7 flatpak: fix Perl source checksum for 5.40.1 build 2026-03-12 20:38:54 -06:00
4754cf3927 flatpak: enable Python/Perl plugins; bundle Perl runtime module 2026-03-12 20:28:24 -06:00
deepend-tildeclub
b23c1a73ca Merge pull request #109 from ZoiteChat/fix-tray-icon-restore-hide
fix: keep tray hide/restore label synced to real window state
2026-03-12 19:40:40 -06:00
4cebe2ac8b fix: expose shared tray label updater on Windows; keep non-win tray bits guarded 2026-03-12 19:34:17 -06:00
44431d2c10 fix: unnest tray cb guards so Windows callbacks actually get defined 2026-03-12 19:13:26 -06:00
14a1ac0dfb fix: keep tray hide/restore label synced to real window state 2026-03-12 18:51:07 -06:00
deepend-tildeclub
166542f1e3 Merge pull request #108 from ZoiteChat/fix-flatpak-titlebar
Fix flatpak titlebar
2026-03-12 18:45:48 -06:00
05f4bf382d flatpak: enable GTK_CSD=1 for GTK titlebars on KDE 2026-03-12 18:39:22 -06:00
52af960175 fix: refresh AppIndicator tray label on menu map/open 2026-03-12 18:31:20 -06:00
deepend-tildeclub
a2e2bdf803 Merge pull request #106 from ZoiteChat/remove-icons
ui: drop menubar icons
2026-03-12 18:15:12 -06:00
deepend-tildeclub
3baa5d92f4 Merge pull request #105 from ZoiteChat/plugins-retention
fix: persist manual addons by copying em into user addon dir
2026-03-12 16:54:27 -06:00
99f97b82a6 ui: drop menubar icons; make Away plain item w/ toggle handler 2026-03-12 16:52:06 -06:00
deepend-tildeclub
6d1e7da475 Merge pull request #104 from ZoiteChat/bug-fixes-pre3-prep
Merge color-changer: import colors.conf, fix userlist/GTK3 tabs, embed SVG icon, clean GTK/OpenSSL warnings.
2026-03-12 15:22:04 -06:00
deepend-tildeclub
f676aa56e6 Merge pull request #103 from ZoiteChat/theme-features-fixes
Theme update
2026-03-09 10:50:12 -06:00
deepend-tildeclub
5e86f363ed Merge pull request #100 from ZoiteChat/theme-module
Theme module
2026-03-02 19:59:43 -07:00
deepend-tildeclub
0523b0639b Merge pull request #99 from ZoiteChat/consistent-icons
icon-resolver unifies gtk icons; win32/ci now ships real hicolor theme
2026-03-01 14:55:32 -07:00
deepend-tildeclub
b3f692f00c Update server addresses for Zoite 2026-02-28 23:02:02 -07:00
9 changed files with 149 additions and 67 deletions

View File

@@ -16,11 +16,10 @@
"--filesystem=~/.themes:ro",
"--filesystem=~/.icons:ro",
"--filesystem=xdg-run/tray-icon:create",
"--env=GTK_CSD=1",
"--talk-name=org.freedesktop.Notifications",
"--talk-name=org.kde.StatusNotifierWatcher",
"--talk-name=com.canonical.AppMenu.Registrar",
"--talk-name=org.mpris.MediaPlayer2.*"
],
"add-extensions": {
@@ -40,6 +39,7 @@
"shared-modules/libcanberra/libcanberra.json",
"shared-modules/libayatana-appindicator/libayatana-appindicator-gtk3.json",
"python3-cffi.json",
"perl.json",
{
"name": "lgi",
"buildsystem": "meson",
@@ -56,8 +56,8 @@
"buildsystem": "meson",
"config-opts": [
"-Ddbus-service-use-appid=true",
"-Dwith-perl=false",
"-Dwith-python=false",
"-Dwith-perl=perl",
"-Dwith-python=python3",
"-Dwith-lua=lua"
],
"build-options": {

20
flatpak/perl.json Normal file
View File

@@ -0,0 +1,20 @@
{
"name": "perl",
"buildsystem": "simple",
"build-commands": [
"./Configure -des -Dprefix=/app -Dvendorprefix=/app -Duseshrplib -Dman1dir=none -Dman3dir=none",
"make -j${FLATPAK_BUILDER_N_JOBS}",
"make install"
],
"cleanup": [
"/share/man",
"/lib/perl5/*/*/CORE/*.a"
],
"sources": [
{
"type": "archive",
"url": "https://www.cpan.org/src/5.0/perl-5.40.1.tar.xz",
"sha256": "dfa20c2eef2b4af133525610bbb65dd13777ecf998c9c5b1ccf0d308e732ee3f"
}
]
}

View File

@@ -7,13 +7,13 @@
"sources": [
{
"type": "file",
"url": "https://files.pythonhosted.org/packages/0f/86/e19659527668d70be91d0369aeaa055b4eb396b0f387a4f92293a20035bd/pycparser-2.20.tar.gz",
"sha256": "2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0"
"url": "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz",
"sha256": "491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"
},
{
"type": "file",
"url": "https://files.pythonhosted.org/packages/a8/20/025f59f929bbcaa579704f443a438135918484fffaacfaddba776b374563/cffi-1.14.5.tar.gz",
"sha256": "fd78e5fee591709f32ef6edb9a015b4aa1a5022598e36227500c8f4e02328d9c"
"url": "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz",
"sha256": "1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"
}
]
}

View File

@@ -32,6 +32,7 @@
#include <stdbool.h>
#else
#include <dirent.h>
#include <strings.h>
#endif
#include <glib.h>

View File

@@ -338,8 +338,8 @@ static const struct defaultserver def[] =
{"Zoite", 0, 0, 0, LOGIN_SASL, 0, TRUE},
{0, "irc.zoite.net"},
{0, "penumbra.newnet.net"},
{0, "hedy.newnet.net"},
{0, "penumbra.zoite.net"},
{0, "hedy.zoite.net"},
{0,0}
};

View File

@@ -1144,6 +1144,12 @@ fe_gui_info (session *sess, int info_type)
return 2; /* hidden (iconified or systray) */
}
{
GdkWindow *gdk_win = gtk_widget_get_window (GTK_WIDGET (sess->gui->window));
if (gdk_win && (gdk_window_get_state (gdk_win) & GDK_WINDOW_STATE_ICONIFIED))
return 2;
}
if (gtk_window_is_active (GTK_WINDOW (sess->gui->window)))
{
return 1; /* active/focused */

View File

@@ -1572,6 +1572,12 @@ menu_away (GtkCheckMenuItem *item, gpointer none)
handle_command (current_sess, gtk_check_menu_item_get_active (item) ? "away" : "back", FALSE);
}
static void
menu_away_toggle (GtkWidget *item, gpointer none)
{
handle_command (current_sess, current_sess->server->is_away ? "back" : "away", FALSE);
}
static void
menu_chanlist (GtkWidget * wid, gpointer none)
{
@@ -1888,30 +1894,12 @@ menu_about (GtkWidget *wid, gpointer sess)
gtk_widget_show_all (GTK_WIDGET(dialog));
}
#define ICON_NEW "zc-menu-new"
#define ICON_NETWORK_LIST "zc-menu-network-list"
#define ICON_LOAD_PLUGIN "zc-menu-load-plugin"
#define ICON_DETACH "zc-menu-detach"
#define ICON_CLOSE "zc-menu-close"
#define ICON_QUIT "zc-menu-quit"
#define ICON_DISCONNECT "zc-menu-disconnect"
#define ICON_CONNECT "zc-menu-connect"
#define ICON_JOIN "zc-menu-join"
#define ICON_CHANLIST "zc-menu-chanlist"
#define ICON_PREFERENCES "zc-menu-preferences"
#define ICON_CLEAR "zc-menu-clear"
#define ICON_SAVE "zc-menu-save"
#define ICON_SEARCH "zc-menu-search"
#define ICON_FIND "zc-menu-find"
#define ICON_HELP "zc-menu-help"
#define ICON_ABOUT "zc-menu-about"
static struct mymenu mymenu[] = {
{N_("_ZoiteChat"), 0, 0, M_NEWMENU, MENU_ID_ZOITECHAT, 0, 1},
{N_("Network Li_st"), menu_open_server_list, ICON_NETWORK_LIST, M_MENUSTOCK, 0, 0, 1, GDK_KEY_s},
{N_("Network Li_st"), menu_open_server_list, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_s},
{0, 0, 0, M_SEP, 0, 0, 0},
{N_("_New"), 0, ICON_NEW, M_MENUSUB, 0, 0, 1},
{N_("_New"), 0, 0, M_MENUSUB, 0, 0, 1},
{N_("Server Tab"), menu_newserver_tab, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_t},
{N_("Channel Tab"), menu_newchannel_tab, 0, M_MENUITEM, 0, 0, 1},
{N_("Server Window"), menu_newserver_window, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_n},
@@ -1919,14 +1907,14 @@ static struct mymenu mymenu[] = {
{0, 0, 0, M_END, 0, 0, 0},
{0, 0, 0, M_SEP, 0, 0, 0},
{N_("_Load Plugin or Script" ELLIPSIS), menu_loadplugin, ICON_LOAD_PLUGIN, M_MENUSTOCK, 0, 0, 1},
{N_("_Load Plugin or Script" ELLIPSIS), menu_loadplugin, 0, M_MENUITEM, 0, 0, 1},
{0, 0, 0, M_SEP, 0, 0, 0}, /* 11 */
#define DETACH_OFFSET (12)
{0, menu_detach, ICON_DETACH, M_MENUSTOCK, 0, 0, 1}, /* 12 */
{0, menu_detach, 0, M_MENUITEM, 0, 0, 1}, /* 12 */
#define CLOSE_OFFSET (13)
{0, menu_close, ICON_CLOSE, M_MENUSTOCK, 0, 0, 1},
{0, menu_close, 0, M_MENUITEM, 0, 0, 1},
{0, 0, 0, M_SEP, 0, 0, 0},
{N_("_Quit"), menu_quit, ICON_QUIT, M_MENUSTOCK, 0, 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},
#define MENUBAR_OFFSET (17)
@@ -1952,18 +1940,18 @@ static struct mymenu mymenu[] = {
{N_ ("_Fullscreen"), menu_fullscreen_toggle, 0, M_MENUTOG, MENU_ID_FULLSCREEN, 0, 1, GDK_KEY_F11},
{N_("_Server"), 0, 0, M_NEWMENU, 0, 0, 1},
{N_("_Disconnect"), menu_disconnect, ICON_DISCONNECT, M_MENUSTOCK, MENU_ID_DISCONNECT, 0, 1},
{N_("_Reconnect"), menu_reconnect, ICON_CONNECT, M_MENUSTOCK, MENU_ID_RECONNECT, 0, 1},
{N_("_Join a Channel" ELLIPSIS), menu_join, ICON_JOIN, M_MENUSTOCK, MENU_ID_JOIN, 0, 1},
{N_("Channel _List"), menu_chanlist, ICON_CHANLIST, M_MENUSTOCK, 0, 0, 1},
{N_("_Disconnect"), menu_disconnect, 0, M_MENUITEM, MENU_ID_DISCONNECT, 0, 1},
{N_("_Reconnect"), menu_reconnect, 0, M_MENUITEM, MENU_ID_RECONNECT, 0, 1},
{N_("_Join a Channel" ELLIPSIS), menu_join, 0, M_MENUITEM, MENU_ID_JOIN, 0, 1},
{N_("Channel _List"), menu_chanlist, 0, M_MENUITEM, 0, 0, 1},
{0, 0, 0, M_SEP, 0, 0, 0},
#define AWAY_OFFSET (41)
{N_("Marked _Away"), menu_away, 0, M_MENUTOG, MENU_ID_AWAY, 0, 1, GDK_KEY_a},
{N_("Marked _Away"), menu_away_toggle, 0, M_MENUITEM, MENU_ID_AWAY, 0, 1, GDK_KEY_a},
{N_("_Usermenu"), 0, 0, M_NEWMENU, MENU_ID_USERMENU, 0, 1}, /* 40 */
{N_("S_ettings"), 0, 0, M_NEWMENU, 0, 0, 1},
{N_("_Preferences"), menu_settings, ICON_PREFERENCES, M_MENUSTOCK, 0, 0, 1},
{N_("_Preferences"), menu_settings, 0, M_MENUITEM, 0, 0, 1},
{0, 0, 0, M_SEP, 0, 0, 0},
{N_("Auto Replace"), menu_rpopup, 0, M_MENUITEM, 0, 0, 1},
{N_("CTCP Replies"), menu_ctcpguiopen, 0, M_MENUITEM, 0, 0, 1},
@@ -1989,18 +1977,18 @@ static struct mymenu mymenu[] = {
{N_("Reset Marker Line"), menu_resetmarker, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_m},
{N_("Move to Marker Line"), menu_movetomarker, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_M},
{N_("_Copy Selection"), menu_copy_selection, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_C},
{N_("C_lear Text"), menu_flushbuffer, ICON_CLEAR, M_MENUSTOCK, 0, 0, 1},
{N_("Save Text" ELLIPSIS), menu_savebuffer, ICON_SAVE, M_MENUSTOCK, 0, 0, 1},
{N_("C_lear Text"), menu_flushbuffer, 0, M_MENUITEM, 0, 0, 1},
{N_("Save Text" ELLIPSIS), menu_savebuffer, 0, M_MENUITEM, 0, 0, 1},
#define SEARCH_OFFSET (70)
{N_("Search"), 0, ICON_SEARCH, M_MENUSUB, 0, 0, 1},
{N_("Search Text" ELLIPSIS), menu_search, ICON_FIND, M_MENUSTOCK, 0, 0, 1, GDK_KEY_f},
{N_("Search Next" ), menu_search_next, ICON_FIND, M_MENUSTOCK, 0, 0, 1, GDK_KEY_g},
{N_("Search Previous" ), menu_search_prev, ICON_FIND, M_MENUSTOCK, 0, 0, 1, GDK_KEY_G},
{N_("Search"), 0, 0, M_MENUSUB, 0, 0, 1},
{N_("Search Text" ELLIPSIS), menu_search, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_f},
{N_("Search Next" ), menu_search_next, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_g},
{N_("Search Previous" ), menu_search_prev, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_G},
{0, 0, 0, M_END, 0, 0, 0},
{N_("_Help"), 0, 0, M_NEWMENU, 0, 0, 1}, /* 74 */
{N_("_Contents"), menu_docs, ICON_HELP, M_MENUSTOCK, 0, 0, 1, GDK_KEY_F1},
{N_("_About"), menu_about, ICON_ABOUT, M_MENUSTOCK, 0, 0, 1},
{N_("_Contents"), menu_docs, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_F1},
{N_("_About"), menu_about, 0, M_MENUITEM, 0, 0, 1},
{0, 0, 0, M_END, 0, 0, 0},
};
@@ -2008,11 +1996,14 @@ static struct mymenu mymenu[] = {
void
menu_set_away (session_gui *gui, int away)
{
GtkCheckMenuItem *item = GTK_CHECK_MENU_ITEM (gui->menu_item[MENU_ID_AWAY]);
if (GTK_IS_CHECK_MENU_ITEM (gui->menu_item[MENU_ID_AWAY]))
{
GtkCheckMenuItem *item = GTK_CHECK_MENU_ITEM (gui->menu_item[MENU_ID_AWAY]);
g_signal_handlers_block_by_func (G_OBJECT (item), menu_away, NULL);
gtk_check_menu_item_set_active (item, away);
g_signal_handlers_unblock_by_func (G_OBJECT (item), menu_away, NULL);
g_signal_handlers_block_by_func (G_OBJECT (item), menu_away, NULL);
gtk_check_menu_item_set_active (item, away);
g_signal_handlers_unblock_by_func (G_OBJECT (item), menu_away, NULL);
}
}
void

View File

@@ -122,6 +122,9 @@ static void tray_init (void);
static void tray_set_icon_state (TrayIcon icon, TrayIconState state);
static void tray_menu_restore_cb (GtkWidget *item, gpointer userdata);
static void tray_menu_notify_cb (GObject *tray, GParamSpec *pspec, gpointer user_data);
static void tray_update_toggle_item_label (void);
static gboolean tray_window_state_cb (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata);
static void tray_window_visibility_cb (GtkWidget *widget, gpointer userdata);
#if HAVE_APPINDICATOR_BACKEND
static void tray_menu_show_cb (GtkWidget *menu, gpointer userdata) G_GNUC_UNUSED;
#endif
@@ -165,6 +168,7 @@ static int tray_pub_count = 0;
static int tray_hilight_count = 0;
static int tray_file_count = 0;
static int tray_restore_timer = 0;
static GtkWidget *tray_toggle_item = NULL;
#if HAVE_APPINDICATOR_BACKEND
static TrayCustomIcon
@@ -424,6 +428,8 @@ tray_app_indicator_init (void)
tray_menu = gtk_menu_new ();
g_signal_connect (G_OBJECT (tray_menu), "show",
G_CALLBACK (tray_menu_show_cb), NULL);
g_signal_connect (G_OBJECT (tray_menu), "map",
G_CALLBACK (tray_menu_show_cb), NULL);
app_indicator_set_menu (tray_indicator, GTK_MENU (tray_menu));
app_indicator_set_status (tray_indicator, APP_INDICATOR_STATUS_ACTIVE);
@@ -581,11 +587,21 @@ static WinStatus
tray_get_window_status (void)
{
GtkWindow *win;
GtkWidget *widget;
GdkWindow *gdk_win;
const char *st;
win = GTK_WINDOW (zoitechat_get_info (ph, "gtkwin_ptr"));
if (win && !gtk_widget_get_visible (GTK_WIDGET (win)))
return WS_HIDDEN;
if (win)
{
widget = GTK_WIDGET (win);
if (!gtk_widget_get_visible (widget))
return WS_HIDDEN;
gdk_win = gtk_widget_get_window (widget);
if (gdk_win && (gdk_window_get_state (gdk_win) & GDK_WINDOW_STATE_ICONIFIED))
return WS_HIDDEN;
}
st = zoitechat_get_info (ph, "win_status");
@@ -878,6 +894,8 @@ tray_toggle_visibility (gboolean force_hide)
gtk_window_present (win);
}
tray_update_toggle_item_label ();
return TRUE;
}
@@ -1071,10 +1089,8 @@ tray_menu_populate (GtkWidget *menu)
/* ph may have an invalid context now */
zoitechat_set_context (ph, zoitechat_find_context (ph, NULL, NULL));
if (tray_get_window_status () == WS_HIDDEN)
tray_make_item (menu, _("_Restore Window"), tray_menu_restore_cb, NULL);
else
tray_make_item (menu, _("_Hide Window"), tray_menu_restore_cb, NULL);
tray_toggle_item = tray_make_item (menu, _("_Hide Window"), tray_menu_restore_cb, NULL);
tray_update_toggle_item_label ();
tray_make_item (menu, NULL, tray_menu_quit_cb, NULL);
#ifndef WIN32 /* submenus are buggy on win32 */
@@ -1116,8 +1132,28 @@ tray_menu_clear (GtkWidget *menu)
for (iter = children; iter; iter = iter->next)
gtk_widget_destroy (GTK_WIDGET (iter->data));
g_list_free (children);
tray_toggle_item = NULL;
}
#endif
static void
tray_update_toggle_item_label (void)
{
const char *label;
if (!tray_toggle_item)
return;
if (tray_get_window_status () == WS_HIDDEN)
label = _("_Restore Window");
else
label = _("_Hide Window");
gtk_menu_item_set_label (GTK_MENU_ITEM (tray_toggle_item), label);
gtk_menu_item_set_use_underline (GTK_MENU_ITEM (tray_toggle_item), TRUE);
}
#if !defined(WIN32)
static void G_GNUC_UNUSED
tray_menu_show_cb (GtkWidget *menu, gpointer userdata)
{
@@ -1128,6 +1164,27 @@ tray_menu_show_cb (GtkWidget *menu, gpointer userdata)
}
#endif
static gboolean
tray_window_state_cb (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
{
(void)widget;
(void)event;
(void)userdata;
tray_update_toggle_item_label ();
return FALSE;
}
static void
tray_window_visibility_cb (GtkWidget *widget, gpointer userdata)
{
(void)widget;
(void)userdata;
tray_update_toggle_item_label ();
}
#if !HAVE_APPINDICATOR_BACKEND
static void
tray_menu_cb (GtkWidget *widget, guint button, guint time, gpointer userdata)
@@ -1369,6 +1426,19 @@ tray_plugin_init (zoitechat_plugin *plugin_handle, char **plugin_name,
zoitechat_hook_print (ph, "Focus Window", -1, tray_focus_cb, NULL);
GtkWindow *window = GTK_WINDOW(zoitechat_get_info (ph, "gtkwin_ptr"));
GtkWidget *window_widget;
if (window)
{
window_widget = GTK_WIDGET (window);
g_signal_connect (G_OBJECT (window_widget), "window-state-event",
G_CALLBACK (tray_window_state_cb), NULL);
g_signal_connect (G_OBJECT (window_widget), "show",
G_CALLBACK (tray_window_visibility_cb), NULL);
g_signal_connect (G_OBJECT (window_widget), "hide",
G_CALLBACK (tray_window_visibility_cb), NULL);
}
if (prefs.hex_gui_tray && gtkutil_tray_icon_supported (window))
tray_init ();

View File

@@ -198,8 +198,6 @@ plugingui_load_cb (session *sess, char *file)
char *addons_dir;
char *basename;
char *addons_target;
char *canonical_addons;
char *canonical_file;
gboolean file_in_addons;
target_sess = is_session (sess) ? sess : current_sess;
@@ -211,11 +209,9 @@ plugingui_load_cb (session *sess, char *file)
load_target = g_strdup (file);
addons_dir = g_build_filename (get_xdir (), "addons", NULL);
canonical_addons = g_canonicalize_filename (addons_dir, NULL);
canonical_file = g_canonicalize_filename (file, NULL);
file_in_addons = g_str_has_prefix (canonical_file, canonical_addons)
&& (canonical_file[strlen (canonical_addons)] == G_DIR_SEPARATOR
|| canonical_file[strlen (canonical_addons)] == '\0');
file_in_addons = g_str_has_prefix (file, addons_dir)
&& (file[strlen (addons_dir)] == G_DIR_SEPARATOR
|| file[strlen (addons_dir)] == '\0');
if (!file_in_addons)
{
@@ -240,8 +236,6 @@ plugingui_load_cb (session *sess, char *file)
}
}
g_free (canonical_addons);
g_free (canonical_file);
g_free (addons_dir);
#ifdef WIN32