diff --git a/.github/workflows/appimage-build.yml b/.github/workflows/appimage-build.yml index 741e6e80..fee334f9 100644 --- a/.github/workflows/appimage-build.yml +++ b/.github/workflows/appimage-build.yml @@ -17,7 +17,7 @@ jobs: artifact-metadata: write steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: submodules: true @@ -217,7 +217,7 @@ jobs: subject-path: Zoitechat-*-x86_64.AppImage - name: Upload AppImage artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: zoitechat-appimage path: Zoitechat-*-x86_64.AppImage diff --git a/.github/workflows/flatpak-build.yml b/.github/workflows/flatpak-build.yml index 6a619a46..97654657 100644 --- a/.github/workflows/flatpak-build.yml +++ b/.github/workflows/flatpak-build.yml @@ -21,7 +21,7 @@ jobs: options: --privileged steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: submodules: true @@ -36,7 +36,7 @@ jobs: - name: Upload Flatpak Bundle id: upload_flatpak - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: zoitechat.flatpak path: zoitechat.flatpak diff --git a/.github/workflows/manjaro-package-build.yml b/.github/workflows/manjaro-package-build.yml index 1e73801d..5706262f 100644 --- a/.github/workflows/manjaro-package-build.yml +++ b/.github/workflows/manjaro-package-build.yml @@ -44,7 +44,7 @@ jobs: pciutils - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: fetch-depth: 0 submodules: true @@ -74,7 +74,7 @@ jobs: cp -v "$GITHUB_WORKSPACE"/packaging/manjaro/.SRCINFO artifacts/ - name: Upload package artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: zoitechat-manjaro-package path: artifacts/* diff --git a/.github/workflows/windows-build.yml b/.github/workflows/windows-build.yml index 16c02cde..83a4619a 100644 --- a/.github/workflows/windows-build.yml +++ b/.github/workflows/windows-build.yml @@ -25,9 +25,9 @@ jobs: fail-fast: false steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - - uses: actions/setup-python@v5 + - uses: actions/setup-python@v6 with: python-version: '3.14.2' architecture: ${{ matrix.arch }} @@ -143,7 +143,7 @@ jobs: - name: Upload Installer id: upload_installer - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: Installer ${{ matrix.arch }} path: ZoiteChat-*.exe @@ -157,7 +157,7 @@ jobs: - name: Upload Build Files id: upload_buildfiles - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: Build Files ${{ matrix.arch }} path: zoitechat-build diff --git a/data/zoitechat.gresource.xml b/data/zoitechat.gresource.xml index 45b158f2..d7bdfdf2 100644 --- a/data/zoitechat.gresource.xml +++ b/data/zoitechat.gresource.xml @@ -2,6 +2,7 @@ icons/zoitechat.png + icons/zoitechat.svg icons/book.png icons/ulist_voice.png diff --git a/meson.build b/meson.build index 3d9056fa..72131ff7 100644 --- a/meson.build +++ b/meson.build @@ -34,7 +34,6 @@ config_h.set_quoted('PACKAGE_NAME', meson.project_name()) config_h.set_quoted('GETTEXT_PACKAGE', 'zoitechat') config_h.set_quoted('LOCALEDIR', join_paths(get_option('prefix'), get_option('datadir'), 'locale')) -config_h.set_quoted('G_LOG_DOMAIN', 'zoitechat') config_h.set10('ENABLE_NLS', true) # Optional features @@ -48,8 +47,6 @@ config_h.set('G_DISABLE_SINGLE_INCLUDES', true) config_h.set('GTK_DISABLE_DEPRECATED', true) config_h.set('GTK_DISABLE_SINGLE_INCLUDES', true) config_h.set('GDK_PIXBUF_DISABLE_SINGLE_INCLUDES', true) -config_h.set('GLIB_VERSION_MAX_ALLOWED', 'GLIB_VERSION_2_36') -config_h.set('GLIB_VERSION_MIN_REQUIRED', 'GLIB_VERSION_2_36') # Detected features config_h.set('HAVE_MEMRCHR', cc.has_function('memrchr')) @@ -95,7 +92,10 @@ if host_machine.system() == 'windows' endif -global_cflags = [] +global_cflags = [ + '-DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_36', + '-DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_36', +] test_cflags = [ '-funsigned-char', '-Wno-conversion', diff --git a/plugins/fishlim/meson.build b/plugins/fishlim/meson.build index 1a2f1ffa..19715457 100644 --- a/plugins/fishlim/meson.build +++ b/plugins/fishlim/meson.build @@ -16,6 +16,7 @@ fishlim_sources = [ shared_module('fishlim', fishlim_sources, dependencies: [libgio_dep, zoitechat_plugin_dep, libssl_dep], + c_args: ['-DOPENSSL_API_COMPAT=0x10100000L'], install: true, install_dir: plugindir, name_prefix: '', diff --git a/plugins/perl/meson.build b/plugins/perl/meson.build index 3c1697f0..fb12466c 100644 --- a/plugins/perl/meson.build +++ b/plugins/perl/meson.build @@ -58,6 +58,8 @@ foreach flag : ret.stdout().strip().split(' ') endif endforeach +perl_cflags += ['-Wno-strict-prototypes'] + perl_cflags += [ # Perl has its own 'config.h' that we must override # TODO: Just rename ours to something more unique. diff --git a/plugins/sysinfo/meson.build b/plugins/sysinfo/meson.build index 530873df..a2e4ce68 100644 --- a/plugins/sysinfo/meson.build +++ b/plugins/sysinfo/meson.build @@ -19,10 +19,6 @@ if system == 'linux' or system == 'gnu' or system.startswith('gnu/') or system = 'shared/df.c' ] - if get_option('gtk-frontend') - sysinfo_cargs += '-DUSE_GTK_FRONTEND' - endif - if system == 'linux' or system == 'gnu' or system.startswith('gnu/') or system == 'freebsd' libpci = dependency('libpci', required: false, method: 'pkg-config') if libpci.found() diff --git a/src/common/dcc.h b/src/common/dcc.h index 8c0ded6a..c28f04d3 100644 --- a/src/common/dcc.h +++ b/src/common/dcc.h @@ -59,7 +59,9 @@ struct DCC int resume_error; int resume_errno; + G_GNUC_BEGIN_IGNORE_DEPRECATIONS GTimeVal lastcpstv, firstcpstv; + G_GNUC_END_IGNORE_DEPRECATIONS goffset lastcpspos; gint64 maxcps; diff --git a/src/common/gtk3-theme-service.c b/src/common/gtk3-theme-service.c index d15824e3..f4ffa2e7 100644 --- a/src/common/gtk3-theme-service.c +++ b/src/common/gtk3-theme-service.c @@ -22,8 +22,13 @@ #include #include #include +#include #include +#ifndef G_OS_WIN32 +extern char *realpath (const char *path, char *resolved_path); +#endif + #include "util.h" #include "cfgfiles.h" @@ -55,6 +60,7 @@ remove_tree (const char *path) g_rmdir (path); } +#ifdef G_OS_WIN32 static gboolean path_tree_has_entries (const char *path) { @@ -86,6 +92,7 @@ path_tree_has_entries (const char *path) g_dir_close (dir); return FALSE; } +#endif static gboolean gtk3_css_dir_parse_minor (const char *name, gint *minor) @@ -492,6 +499,49 @@ discover_dir (GPtrArray *themes, GHashTable *seen_theme_roots, const char *base_ } + +static char * +path_canonicalize_compat (const char *path) +{ + char *absolute_path; + char *cwd; + char *resolved; + + if (!path || path[0] == '\0') + return NULL; + + if (g_path_is_absolute (path)) + absolute_path = g_strdup (path); + else + { + cwd = g_get_current_dir (); + absolute_path = g_build_filename (cwd, path, NULL); + g_free (cwd); + } + +#ifdef G_OS_WIN32 + resolved = _fullpath (NULL, absolute_path, 0); + if (resolved) + { + char *copy = g_strdup (resolved); + free (resolved); + g_free (absolute_path); + return copy; + } +#else + resolved = realpath (absolute_path, NULL); + if (resolved) + { + char *copy = g_strdup (resolved); + free (resolved); + g_free (absolute_path); + return copy; + } +#endif + + return absolute_path; +} + static char * path_normalize_theme_root (const char *path) { @@ -501,7 +551,7 @@ path_normalize_theme_root (const char *path) if (!path || path[0] == '\0') return NULL; - canonical = g_canonicalize_filename (path, NULL); + canonical = path_canonicalize_compat (path); target = g_file_read_link (canonical, NULL); if (target && target[0]) { @@ -510,7 +560,7 @@ path_normalize_theme_root (const char *path) ? g_strdup (target) : g_build_filename (base, target, NULL); g_free (canonical); - canonical = g_canonicalize_filename (resolved, NULL); + canonical = path_canonicalize_compat (resolved); g_free (resolved); g_free (base); } @@ -534,7 +584,7 @@ add_theme_root (GPtrArray *roots, GHashTable *seen, const char *path) if (!path || path[0] == '\0') return; - normalized = g_canonicalize_filename (path, NULL); + normalized = path_canonicalize_compat (path); if (g_hash_table_contains (seen, normalized)) { g_free (normalized); @@ -739,6 +789,51 @@ select_theme_root (GPtrArray *roots, const char *input_root) return selected; } +static gboolean +copy_css_file (const char *src, const char *dest, GError **error) +{ + char *contents = NULL; + char *normalized; + gsize len = 0; + GRegex *regex; + + if (!g_file_get_contents (src, &contents, &len, error)) + return FALSE; + + if (!g_strstr_len (contents, len, ":insensitive")) + { + gboolean ok = g_file_set_contents (dest, contents, len, error); + g_free (contents); + return ok; + } + + regex = g_regex_new (":insensitive", 0, 0, error); + if (!regex) + { + g_free (contents); + return FALSE; + } + + normalized = g_regex_replace_literal (regex, contents, -1, 0, ":disabled", 0, error); + g_regex_unref (regex); + if (!normalized) + { + g_free (contents); + return FALSE; + } + + if (!g_file_set_contents (dest, normalized, -1, error)) + { + g_free (normalized); + g_free (contents); + return FALSE; + } + + g_free (normalized); + g_free (contents); + return TRUE; +} + static gboolean copy_tree (const char *src, const char *dest, GError **error) { @@ -768,19 +863,32 @@ copy_tree (const char *src, const char *dest, GError **error) } else { - GFile *sf = g_file_new_for_path (s); - GFile *df = g_file_new_for_path (d); - if (!g_file_copy (sf, df, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, error)) + if (g_str_has_suffix (name, ".css")) { + if (!copy_css_file (s, d, error)) + { + g_free (s); + g_free (d); + g_dir_close (dir); + return FALSE; + } + } + else + { + GFile *sf = g_file_new_for_path (s); + GFile *df = g_file_new_for_path (d); + if (!g_file_copy (sf, df, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, error)) + { + g_object_unref (sf); + g_object_unref (df); + g_free (s); + g_free (d); + g_dir_close (dir); + return FALSE; + } g_object_unref (sf); g_object_unref (df); - g_free (s); - g_free (d); - g_dir_close (dir); - return FALSE; } - g_object_unref (sf); - g_object_unref (df); } g_free (s); g_free (d); diff --git a/src/common/gtk3-theme-service.h b/src/common/gtk3-theme-service.h index 82b0172f..bbf98b0b 100644 --- a/src/common/gtk3-theme-service.h +++ b/src/common/gtk3-theme-service.h @@ -1,7 +1,7 @@ #ifndef ZOITECHAT_GTK3_THEME_SERVICE_H #define ZOITECHAT_GTK3_THEME_SERVICE_H -#include +#include "zoitechat.h" typedef enum { diff --git a/src/common/server.c b/src/common/server.c index df5f1bca..239f42de 100644 --- a/src/common/server.c +++ b/src/common/server.c @@ -694,17 +694,29 @@ conn_fail: } else { SSL_SESSION *session = SSL_get_session (serv->ssl); - if (session && SSL_SESSION_get_time (session) + SSLTMOUT < time (NULL)) + if (session) { - g_snprintf (buf, sizeof (buf), "SSL handshake timed out"); - EMIT_SIGNAL (XP_TE_CONNFAIL, serv->server_session, buf, NULL, + time_t session_time = 0; + gboolean handshake_timed_out = FALSE; + +#if OPENSSL_VERSION_NUMBER >= 0x30400000L + session_time = (time_t) SSL_SESSION_get_time_ex (session); +#else + session_time = SSL_SESSION_get_time (session); +#endif + handshake_timed_out = session_time + SSLTMOUT < time (NULL); + if (handshake_timed_out) + { + g_snprintf (buf, sizeof (buf), "SSL handshake timed out"); + EMIT_SIGNAL (XP_TE_CONNFAIL, serv->server_session, buf, NULL, NULL, NULL, 0); - server_cleanup (serv); /* ->connecting = FALSE */ + server_cleanup (serv); /* ->connecting = FALSE */ - if (prefs.hex_net_auto_reconnectonfail) - auto_reconnect (serv, FALSE, -1); + if (prefs.hex_net_auto_reconnectonfail) + auto_reconnect (serv, FALSE, -1); - return (0); /* remove it (0) */ + return (0); /* remove it (0) */ + } } return (1); /* call it more (1) */ diff --git a/src/common/sts.c b/src/common/sts.c index eef2a71b..4047f229 100644 --- a/src/common/sts.c +++ b/src/common/sts.c @@ -16,7 +16,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include +#include "zoitechat.h" + #include #include @@ -26,7 +27,6 @@ #include #endif -#include "zoitechat.h" #include "cfgfiles.h" #include "util.h" #include "text.h" diff --git a/src/common/tests/test-gtk3-theme-service.c b/src/common/tests/test-gtk3-theme-service.c index ac332a55..9a414375 100644 --- a/src/common/tests/test-gtk3-theme-service.c +++ b/src/common/tests/test-gtk3-theme-service.c @@ -1,9 +1,9 @@ -#include -#include - +#include "../zoitechat.h" #include "../gtk3-theme-service.h" #include "../cfgfiles.h" +#include + char *xdir = NULL; char * diff --git a/src/common/theme-service.c b/src/common/theme-service.c index f0e5aa5f..2e8f6d33 100644 --- a/src/common/theme-service.c +++ b/src/common/theme-service.c @@ -1,10 +1,11 @@ #include +#include "zoitechat.h" + #include #include #include "cfgfiles.h" -#include "zoitechat.h" #include "theme-service.h" static zoitechat_theme_post_apply_callback zoitechat_theme_post_apply_cb; diff --git a/src/common/theme-service.h b/src/common/theme-service.h index 21208cf2..7b3b3a4a 100644 --- a/src/common/theme-service.h +++ b/src/common/theme-service.h @@ -1,7 +1,7 @@ #ifndef ZOITECHAT_THEME_SERVICE_H #define ZOITECHAT_THEME_SERVICE_H -#include +#include "zoitechat.h" char *zoitechat_theme_service_get_themes_dir (void); GStrv zoitechat_theme_service_discover_themes (void); diff --git a/src/common/userlist.c b/src/common/userlist.c index 7c6c3e4f..f546d5e9 100644 --- a/src/common/userlist.c +++ b/src/common/userlist.c @@ -317,6 +317,7 @@ userlist_change (struct session *sess, char *oldname, char *newname) tree_insert (sess->usertree, user); fe_userlist_insert (sess, user, FALSE); + fe_userlist_rehash (sess, user); return 1; } diff --git a/src/fe-gtk/banlist.c b/src/fe-gtk/banlist.c index cc20a1e1..8462dabf 100644 --- a/src/fe-gtk/banlist.c +++ b/src/fe-gtk/banlist.c @@ -398,8 +398,7 @@ banlist_button_pressed (GtkWidget *wid, GdkEventButton *event, gpointer userdata gtk_menu_shell_append (GTK_MENU_SHELL(menu), allitem); gtk_widget_show_all (menu); - gtk_menu_popup (GTK_MENU(menu), NULL, NULL, NULL, NULL, - event->button, gtk_get_current_event_time ()); + gtk_menu_popup_at_pointer (GTK_MENU (menu), (GdkEvent *) event); } return TRUE; diff --git a/src/fe-gtk/chanlist.c b/src/fe-gtk/chanlist.c index ef7036e2..3fc1218e 100644 --- a/src/fe-gtk/chanlist.c +++ b/src/fe-gtk/chanlist.c @@ -535,7 +535,7 @@ chanlist_join (GtkWidget * wid, server *serv) g_snprintf (tbuf, sizeof (tbuf), "join %s", chan); handle_command (serv->server_session, tbuf, FALSE); } else - gdk_beep (); + gdk_display_beep (gdk_display_get_default ()); g_free (chan); } } @@ -595,10 +595,16 @@ chanlist_save (GtkWidget * wid, server *serv) static gboolean chanlist_flash (server *serv) { - if (gtk_widget_get_state (serv->gui->chanlist_refresh) != GTK_STATE_ACTIVE) - gtk_widget_set_state (serv->gui->chanlist_refresh, GTK_STATE_ACTIVE); + if (!(gtk_widget_get_state_flags (serv->gui->chanlist_refresh) & GTK_STATE_FLAG_ACTIVE)) + { + gtk_widget_unset_state_flags (serv->gui->chanlist_refresh, GTK_STATE_FLAG_PRELIGHT); + gtk_widget_set_state_flags (serv->gui->chanlist_refresh, GTK_STATE_FLAG_ACTIVE, FALSE); + } else - gtk_widget_set_state (serv->gui->chanlist_refresh, GTK_STATE_PRELIGHT); + { + gtk_widget_unset_state_flags (serv->gui->chanlist_refresh, GTK_STATE_FLAG_ACTIVE); + gtk_widget_set_state_flags (serv->gui->chanlist_refresh, GTK_STATE_FLAG_PRELIGHT, FALSE); + } return TRUE; } @@ -872,7 +878,7 @@ chanlist_opengui (server *serv, int do_refresh) chanlist_add_column (view, COL_CHANNEL, 96, _("Channel"), FALSE); chanlist_add_column (view, COL_USERS, 50, _("Users"), TRUE); chanlist_add_column (view, COL_TOPIC, 50, _("Topic"), FALSE); - gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE); + gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view), GTK_TREE_VIEW_GRID_LINES_HORIZONTAL); /* this is a speed up, but no horizontal scrollbar :( */ /*gtk_tree_view_set_fixed_height_mode (GTK_TREE_VIEW (view), TRUE);*/ gtk_widget_show (view); diff --git a/src/fe-gtk/chanview-tabs.c b/src/fe-gtk/chanview-tabs.c index b8e7cd0e..3d364ad4 100644 --- a/src/fe-gtk/chanview-tabs.c +++ b/src/fe-gtk/chanview-tabs.c @@ -75,20 +75,6 @@ cv_tabs_get_viewport_size (GdkWindow *parent_win, gboolean vertical) return viewport_size; } -/* - * GtkViewports request at least as much space as their children do. - * If we don't intervene here, the GtkViewport will be granted its - * request, even at the expense of resizing the top-level window. - */ -static void -cv_tabs_sizerequest (GtkWidget *viewport, GtkRequisition *requisition, chanview *cv) -{ - if (!cv->vertical) - requisition->width = 1; - else - requisition->height = 1; -} - static void cv_tabs_sizealloc (GtkWidget *widget, GtkAllocation *allocation, chanview *cv) { @@ -102,10 +88,10 @@ cv_tabs_sizealloc (GtkWidget *widget, GtkAllocation *allocation, chanview *cv) if (cv->vertical) { - adj = gtk_viewport_get_vadjustment (GTK_VIEWPORT (gtk_widget_get_parent (inner))); + adj = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (gtk_widget_get_parent (inner))); } else { - adj = gtk_viewport_get_hadjustment (GTK_VIEWPORT (gtk_widget_get_parent (inner))); + adj = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (gtk_widget_get_parent (inner))); } viewport_size = cv_tabs_get_viewport_size (parent_win, cv->vertical); @@ -264,10 +250,10 @@ tab_scroll_left_up_clicked (GtkWidget *widget, chanview *cv) if (cv->vertical) { - adj = gtk_viewport_get_vadjustment (GTK_VIEWPORT (gtk_widget_get_parent(inner))); + adj = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (gtk_widget_get_parent(inner))); } else { - adj = gtk_viewport_get_hadjustment (GTK_VIEWPORT (gtk_widget_get_parent(inner))); + adj = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (gtk_widget_get_parent(inner))); } viewport_size = cv_tabs_get_viewport_size (parent_win, cv->vertical); @@ -302,10 +288,10 @@ tab_scroll_right_down_clicked (GtkWidget *widget, chanview *cv) if (cv->vertical) { - adj = gtk_viewport_get_vadjustment (GTK_VIEWPORT (gtk_widget_get_parent(inner))); + adj = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (gtk_widget_get_parent(inner))); } else { - adj = gtk_viewport_get_hadjustment (GTK_VIEWPORT (gtk_widget_get_parent(inner))); + adj = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (gtk_widget_get_parent(inner))); } viewport_size = cv_tabs_get_viewport_size (parent_win, cv->vertical); @@ -415,8 +401,10 @@ cv_tabs_init (chanview *cv) viewport = gtk_viewport_new (0, 0); gtk_viewport_set_shadow_type (GTK_VIEWPORT (viewport), GTK_SHADOW_NONE); - g_signal_connect (G_OBJECT (viewport), "size_request", - G_CALLBACK (cv_tabs_sizerequest), cv); + if (cv->vertical) + gtk_widget_set_size_request (viewport, -1, 1); + else + gtk_widget_set_size_request (viewport, 1, -1); g_signal_connect (G_OBJECT (viewport), "scroll_event", G_CALLBACK (tab_scroll_cb), cv); gtk_box_pack_start (GTK_BOX (outer), viewport, 1, 1, 0); diff --git a/src/fe-gtk/dccgui.c b/src/fe-gtk/dccgui.c index 5c7e59b3..3be9fcd3 100644 --- a/src/fe-gtk/dccgui.c +++ b/src/fe-gtk/dccgui.c @@ -839,7 +839,7 @@ fe_dcc_open_recv_win (int passive) gtk_widget_set_vexpand (view_scrolled, TRUE); gtk_widget_set_hexpand (view, TRUE); gtk_widget_set_vexpand (view, TRUE); - gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE); + gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view), GTK_TREE_VIEW_GRID_LINES_HORIZONTAL); /* Up/Down Icon column */ gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), -1, NULL, gtk_cell_renderer_pixbuf_new (), @@ -1116,7 +1116,7 @@ fe_dcc_open_chat_win (int passive) dcc_add_column (view, CCOL_START, CCOL_COLOR, _("Start Time"), FALSE); gtk_tree_view_column_set_expand (gtk_tree_view_get_column (GTK_TREE_VIEW (view), 1), TRUE); - gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE); + gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view), GTK_TREE_VIEW_GRID_LINES_HORIZONTAL); dcccwin.list = view; dcccwin.store = store; diff --git a/src/fe-gtk/editlist.c b/src/fe-gtk/editlist.c index 8282dc16..27e8b3c0 100644 --- a/src/fe-gtk/editlist.c +++ b/src/fe-gtk/editlist.c @@ -293,7 +293,7 @@ editlist_treeview_new (GtkWidget *box, char *title1, char *title2) g_signal_connect (G_OBJECT (view), "key_press_event", G_CALLBACK (editlist_keypress), NULL); - gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE); + gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view), GTK_TREE_VIEW_GRID_LINES_HORIZONTAL); render = gtk_cell_renderer_text_new (); g_object_set (render, "editable", TRUE, NULL); diff --git a/src/fe-gtk/fe-gtk.c b/src/fe-gtk/fe-gtk.c index c91927ff..67f21209 100644 --- a/src/fe-gtk/fe-gtk.c +++ b/src/fe-gtk/fe-gtk.c @@ -922,7 +922,7 @@ fe_beep (session *sess) if (ca_context_play (ca_con, 0, CA_PROP_EVENT_ID, "message-new-instant", NULL) != 0) #endif - gdk_beep (); + gdk_display_beep (gdk_display_get_default ()); #endif } @@ -1308,7 +1308,7 @@ fe_open_url_inner (const char *url) g_clear_error (&error); } - if (!opened && gtk_show_uri (NULL, escaped_url, GDK_CURRENT_TIME, &error)) + if (!opened && gtk_show_uri_on_window (NULL, escaped_url, GDK_CURRENT_TIME, &error)) { opened = TRUE; } diff --git a/src/fe-gtk/gtkutil.c b/src/fe-gtk/gtkutil.c index f210dbe8..b1ed5e23 100644 --- a/src/fe-gtk/gtkutil.c +++ b/src/fe-gtk/gtkutil.c @@ -825,7 +825,6 @@ fe_get_int (char *msg, int def, void *callback, void *userdata) gtk_adjustment_set_lower (adj, 0); gtk_adjustment_set_upper (adj, 1024); gtk_adjustment_set_step_increment (adj, 1); - gtk_adjustment_changed (adj); gtk_spin_button_set_value ((GtkSpinButton*)spin, def); gtk_box_pack_end (GTK_BOX (hbox), spin, 0, 0, 0); @@ -1126,7 +1125,7 @@ gtkutil_tray_icon_supported (GtkWindow *window) GdkDisplay *display = gdk_screen_get_display (screen); if (!GDK_IS_X11_DISPLAY (display)) return FALSE; - int screen_number = gdk_screen_get_number (screen); + int screen_number = gdk_x11_screen_get_screen_number (screen); Display *xdisplay = gdk_x11_display_get_xdisplay (display); char *selection_name = g_strdup_printf ("_NET_SYSTEM_TRAY_S%d", screen_number); Atom selection_atom = XInternAtom (xdisplay, selection_name, False); diff --git a/src/fe-gtk/ignoregui.c b/src/fe-gtk/ignoregui.c index 8598221b..fbe7d2e2 100644 --- a/src/fe-gtk/ignoregui.c +++ b/src/fe-gtk/ignoregui.c @@ -170,7 +170,7 @@ ignore_treeview_new (GtkWidget *box) UNIGNORE_COLUMN, _("Unignore"), -1); - gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE); + gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view), GTK_TREE_VIEW_GRID_LINES_HORIZONTAL); gtk_tree_view_column_set_expand (gtk_tree_view_get_column (GTK_TREE_VIEW (view), 0), TRUE); /* attach to signals and customise columns */ diff --git a/src/fe-gtk/maingui.c b/src/fe-gtk/maingui.c index 7d37ac21..a5ba248d 100644 --- a/src/fe-gtk/maingui.c +++ b/src/fe-gtk/maingui.c @@ -21,6 +21,8 @@ #include #include +#include "fe-gtk.h" + #include #include #include @@ -40,7 +42,6 @@ #include "../common/chanopt.h" #include "../common/cfgfiles.h" -#include "fe-gtk.h" #include "theme/theme-manager.h" #include "theme/theme-css.h" #include "banlist.h" @@ -407,7 +408,7 @@ mg_attr_list_create (const XTextColor *col, int size) static void mg_create_tab_colors (void) { - XTextColor gui_palette[XTEXT_COLS]; + XTextColor gui_palette[THEME_TOKEN_COUNT]; if (plain_list) { @@ -2663,7 +2664,7 @@ mg_update_xtext (GtkWidget *wid) gtk_xtext_set_show_separator (xtext, prefs.hex_text_indent ? prefs.hex_text_show_sep : 0); gtk_xtext_set_indent (xtext, prefs.hex_text_indent); - font_name = (prefs.hex_text_font && *prefs.hex_text_font) + font_name = *prefs.hex_text_font ? prefs.hex_text_font : "Sans 10"; if (!gtk_xtext_set_font (xtext, (char *)font_name)) @@ -3321,7 +3322,7 @@ mg_apply_emoji_fallback_widget (GtkWidget *widget) { PangoFontDescription *desc; GtkStyleContext *context; - const PangoFontDescription *base_desc; + PangoFontDescription *base_desc = NULL; if (!widget) return; @@ -3330,16 +3331,19 @@ mg_apply_emoji_fallback_widget (GtkWidget *widget) if (!context) return; - base_desc = gtk_style_context_get_font (context, GTK_STATE_FLAG_NORMAL); + gtk_style_context_get (context, GTK_STATE_FLAG_NORMAL, + "font", &base_desc, + NULL); if (!base_desc) return; desc = mg_fontdesc_with_fallback (base_desc, FALSE); + pango_font_description_free (base_desc); if (!desc) return; - mg_apply_font_css (widget, desc, "zoitechat-emoji-font", - "zoitechat-emoji-font-provider"); + mg_apply_font_css (widget, desc, "zoitechat-emoji-font", + "zoitechat-emoji-font-provider"); pango_font_description_free (desc); } @@ -3733,7 +3737,7 @@ mg_create_topwindow (session *sess) prefs.hex_gui_win_height, 0); sess->gui->window = win; gtk_container_set_border_width (GTK_CONTAINER (win), GUI_BORDER); - gtk_window_set_opacity (GTK_WINDOW (win), (prefs.hex_gui_transparency / 255.)); + gtk_widget_set_opacity (win, (prefs.hex_gui_transparency / 255.)); g_signal_connect (G_OBJECT (win), "focus_in_event", G_CALLBACK (mg_topwin_focus_cb), sess); @@ -3922,7 +3926,7 @@ mg_create_tabwindow (session *sess) gtk_window_maximize (GTK_WINDOW (win)); if (prefs.hex_gui_win_fullscreen) gtk_window_fullscreen (GTK_WINDOW (win)); - gtk_window_set_opacity (GTK_WINDOW (win), (prefs.hex_gui_transparency / 255.)); + gtk_widget_set_opacity (win, (prefs.hex_gui_transparency / 255.)); gtk_container_set_border_width (GTK_CONTAINER (win), GUI_BORDER); g_signal_connect (G_OBJECT (win), "delete_event", @@ -4515,6 +4519,8 @@ mg_drag_motion_cb (GtkWidget *widget, GdkDragContext *context, int x, int y, gui { XTextColor col; cairo_t *cr; + GdkDrawingContext *draw_context; + cairo_region_t *region; int half, width, height; int ox, oy; GdkWindow *window; @@ -4545,7 +4551,11 @@ mg_drag_motion_cb (GtkWidget *widget, GdkDragContext *context, int x, int y, gui col.green = (double)rand () / (double)RAND_MAX; col.blue = (double)rand () / (double)RAND_MAX; col.alpha = 1.0; - cr = gdk_cairo_create (window); + region = cairo_region_create (); + cairo_region_union_rectangle (region, &(cairo_rectangle_int_t){ 0, 0, width, height }); + draw_context = gdk_window_begin_draw_frame (window, region); + cairo_region_destroy (region); + cr = gdk_drawing_context_get_cairo_context (draw_context); cairo_set_operator (cr, CAIRO_OPERATOR_XOR); mg_set_source_color (cr, &col); cairo_set_line_width (cr, 1.0); @@ -4587,7 +4597,7 @@ mg_drag_motion_cb (GtkWidget *widget, GdkDragContext *context, int x, int y, gui gtk_widget_queue_draw_area (widget, ox, oy, width, half); } - cairo_destroy (cr); + gdk_window_end_draw_frame (window, draw_context); return TRUE; } diff --git a/src/fe-gtk/menu.c b/src/fe-gtk/menu.c index 7faddc3e..2671ea4b 100644 --- a/src/fe-gtk/menu.c +++ b/src/fe-gtk/menu.c @@ -1860,16 +1860,6 @@ menu_about (GtkWidget *wid, gpointer sess) GtkAboutDialog *dialog = GTK_ABOUT_DIALOG(gtk_about_dialog_new()); theme_manager_attach_window (GTK_WIDGET (dialog)); char comment[512]; - char *license = "This program is free software; you can redistribute it and/or modify\n" \ - "it under the terms of the GNU General Public License as published by\n" \ - "the Free Software Foundation; version 2.\n\n" \ - "This program is distributed in the hope that it will be useful,\n" \ - "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" \ - "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" \ - "GNU General Public License for more details.\n\n" \ - "You should have received a copy of the GNU General Public License\n" \ - "along with this program. If not, see "; - g_snprintf (comment, sizeof(comment), "" #ifdef WIN32 "Portable Mode: %s\n" diff --git a/src/fe-gtk/plugin-tray.c b/src/fe-gtk/plugin-tray.c index 112c8983..7023ecd3 100644 --- a/src/fe-gtk/plugin-tray.c +++ b/src/fe-gtk/plugin-tray.c @@ -123,7 +123,7 @@ 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); #if HAVE_APPINDICATOR_BACKEND -static void tray_menu_show_cb (GtkWidget *menu, gpointer userdata); +static void tray_menu_show_cb (GtkWidget *menu, gpointer userdata) G_GNUC_UNUSED; #endif #if !HAVE_APPINDICATOR_BACKEND static void tray_menu_cb (GtkWidget *widget, guint button, guint time, gpointer userdata); @@ -414,8 +414,10 @@ tray_app_indicator_init (void) { GObjectClass *klass; + G_GNUC_BEGIN_IGNORE_DEPRECATIONS tray_indicator = app_indicator_new ("zoitechat", ICON_NORMAL_NAME, APP_INDICATOR_CATEGORY_COMMUNICATIONS); + G_GNUC_END_IGNORE_DEPRECATIONS if (!tray_indicator) return FALSE; @@ -578,8 +580,13 @@ tray_backend_cleanup (void) static WinStatus tray_get_window_status (void) { + GtkWindow *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; + st = zoitechat_get_info (ph, "win_status"); if (!st) @@ -998,6 +1005,7 @@ blink_item (unsigned int *setting, GtkWidget *menu, char *label) } #endif +#if !HAVE_APPINDICATOR_BACKEND static void tray_menu_destroy (GtkWidget *menu, gpointer userdata) { @@ -1009,6 +1017,7 @@ tray_menu_destroy (GtkWidget *menu, gpointer userdata) g_source_remove (tray_menu_timer); #endif } +#endif #ifdef WIN32 static gboolean @@ -1109,7 +1118,7 @@ tray_menu_clear (GtkWidget *menu) g_list_free (children); } -static void +static void G_GNUC_UNUSED tray_menu_show_cb (GtkWidget *menu, gpointer userdata) { (void)userdata; @@ -1125,7 +1134,9 @@ tray_menu_cb (GtkWidget *widget, guint button, guint time, gpointer userdata) { static GtkWidget *menu; - (void)widget; + (void)button; + (void)time; + (void)userdata; /* close any old menu */ if (G_IS_OBJECT (menu)) @@ -1151,8 +1162,15 @@ tray_menu_cb (GtkWidget *widget, guint button, guint time, gpointer userdata) tray_menu_timer = g_timeout_add (500, (GSourceFunc)tray_check_hide, menu); #endif - gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, - userdata, button, time); + if (widget && GTK_IS_WIDGET (widget)) + gtk_menu_popup_at_widget (GTK_MENU (menu), widget, GDK_GRAVITY_SOUTH_WEST, GDK_GRAVITY_NORTH_WEST, NULL); + else + { + GdkEvent *event = gtk_get_current_event (); + gtk_menu_popup_at_pointer (GTK_MENU (menu), event); + if (event) + gdk_event_free (event); + } } #endif diff --git a/src/fe-gtk/plugingui.c b/src/fe-gtk/plugingui.c index 32c4bc82..9d43ca15 100644 --- a/src/fe-gtk/plugingui.c +++ b/src/fe-gtk/plugingui.c @@ -105,7 +105,7 @@ plugingui_treeview_new (GtkWidget *box) FILE_COLUMN, _("File"), DESC_COLUMN, _("Description"), FILEPATH_COLUMN, NULL, -1); - gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE); + gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view), GTK_TREE_VIEW_GRID_LINES_HORIZONTAL); for (col_id=0; (col = gtk_tree_view_get_column (GTK_TREE_VIEW (view), col_id)); col_id++) gtk_tree_view_column_set_alignment (col, 0.5); diff --git a/src/fe-gtk/setup.c b/src/fe-gtk/setup.c index 9d015e80..ec5c3b3c 100644 --- a/src/fe-gtk/setup.c +++ b/src/fe-gtk/setup.c @@ -22,10 +22,10 @@ #include #include +#include "../common/zoitechat.h" + #include #include - -#include "../common/zoitechat.h" #include "../common/cfgfiles.h" #include "../common/fe.h" #include "../common/text.h" @@ -914,7 +914,7 @@ static gint setup_apply_trans (int *tag) { prefs.hex_gui_transparency = setup_prefs.hex_gui_transparency; - gtk_window_set_opacity (GTK_WINDOW (current_sess->gui->window), + gtk_widget_set_opacity (current_sess->gui->window, (prefs.hex_gui_transparency / 255.)); *tag = 0; @@ -956,7 +956,7 @@ setup_create_hscale (GtkWidget *table, int row, const setting *set) #ifndef WIN32 /* Windows always supports this */ /* Only used for transparency currently */ - if (!gtk_widget_is_composited (current_sess->gui->window)) + if (!gdk_screen_is_composited (gtk_widget_get_screen (current_sess->gui->window))) gtk_widget_set_sensitive (wid, FALSE); #endif } @@ -1732,7 +1732,7 @@ setup_create_sound_page (void) G_CALLBACK (setup_snd_row_cb), NULL); gtk_widget_show (sound_tree); gtk_container_add (GTK_CONTAINER (scrolledwindow1), sound_tree); - gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (sound_tree), TRUE); + gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (sound_tree), GTK_TREE_VIEW_GRID_LINES_HORIZONTAL); table1 = gtkutil_grid_new (2, 3, FALSE); gtk_widget_show (table1); @@ -1797,7 +1797,7 @@ setup_add_page (const char *title, GtkWidget *book, GtkWidget *tab) sw = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new (NULL, NULL)); gtk_scrolled_window_set_shadow_type (sw, GTK_SHADOW_IN); gtk_scrolled_window_set_policy (sw, GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_add_with_viewport (sw, vvbox); + gtk_container_add (GTK_CONTAINER (sw), vvbox); viewport = gtk_bin_get_child (GTK_BIN(sw)); gtk_viewport_set_shadow_type (GTK_VIEWPORT(viewport), GTK_SHADOW_NONE); diff --git a/src/fe-gtk/sexy-spell-entry.c b/src/fe-gtk/sexy-spell-entry.c index 5d57e496..aeff36ea 100644 --- a/src/fe-gtk/sexy-spell-entry.c +++ b/src/fe-gtk/sexy-spell-entry.c @@ -321,7 +321,6 @@ gtk_entry_find_position (GtkEntry *entry, gint x) PangoLayout *layout; PangoLayoutLine *line; const gchar *text; - gint cursor_index; gint index; gint pos; gboolean trailing; @@ -336,10 +335,6 @@ gtk_entry_find_position (GtkEntry *entry, gint x) layout = gtk_entry_get_layout(entry); text = pango_layout_get_text(layout); - cursor_index = g_utf8_offset_to_pointer( - text, - gtk_editable_get_position(GTK_EDITABLE(entry))) - text; - line = pango_layout_get_lines(layout)->data; pango_layout_line_x_to_index(line, x * PANGO_SCALE, &index, &trailing); diff --git a/src/fe-gtk/textgui.c b/src/fe-gtk/textgui.c index 9ca95040..a7378580 100644 --- a/src/fe-gtk/textgui.c +++ b/src/fe-gtk/textgui.c @@ -138,7 +138,7 @@ PrintTextRaw (void *xtbuf, unsigned char *text, int indent, time_t stamp) { beep_done = TRUE; if (!prefs.hex_input_filter_beep) - gdk_beep (); + gdk_display_beep (gdk_display_get_default ()); } default: text++; @@ -408,7 +408,7 @@ pevent_treeview_new (GtkWidget *box) view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store)); gtk_tree_view_set_fixed_height_mode (GTK_TREE_VIEW (view), TRUE); gtk_tree_view_set_enable_search (GTK_TREE_VIEW (view), TRUE); - gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE); + gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view), GTK_TREE_VIEW_GRID_LINES_HORIZONTAL); sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (view)); g_signal_connect (G_OBJECT (sel), "changed", diff --git a/src/fe-gtk/theme/tests/test-theme-access-routing.c b/src/fe-gtk/theme/tests/test-theme-access-routing.c index 9f87d150..0fc899b5 100644 --- a/src/fe-gtk/theme/tests/test-theme-access-routing.c +++ b/src/fe-gtk/theme/tests/test-theme-access-routing.c @@ -1,5 +1,6 @@ +#include "../../fe-gtk.h" + #include -#include #include "../theme-access.h" #include "../theme-manager.h" @@ -270,7 +271,7 @@ test_access_xtext_palette_widget_mapping_when_gtk3_active (void) if (!gtk_available) { - g_test_skip ("GTK display not available"); + g_test_message ("GTK display not available"); return; } diff --git a/src/fe-gtk/theme/tests/test-theme-application-input-style.c b/src/fe-gtk/theme/tests/test-theme-application-input-style.c index ccfe7255..1dd750ed 100644 --- a/src/fe-gtk/theme/tests/test-theme-application-input-style.c +++ b/src/fe-gtk/theme/tests/test-theme-application-input-style.c @@ -1,4 +1,4 @@ -#include +#include "../../fe-gtk.h" #include "../theme-application.h" #include "../../maingui.h" diff --git a/src/fe-gtk/theme/tests/test-theme-gtk3-settings.c b/src/fe-gtk/theme/tests/test-theme-gtk3-settings.c index 69694950..a621a58f 100644 --- a/src/fe-gtk/theme/tests/test-theme-gtk3-settings.c +++ b/src/fe-gtk/theme/tests/test-theme-gtk3-settings.c @@ -1,11 +1,12 @@ +#include "../../../common/zoitechat.h" +#include "../../../common/zoitechatc.h" + #include #include #include #include "../theme-gtk3.h" #include "../../../common/gtk3-theme-service.h" -#include "../../../common/zoitechat.h" -#include "../../../common/zoitechatc.h" struct session *current_sess; struct session *current_tab; @@ -246,7 +247,7 @@ test_settings_layer_precedence (void) if (!gtk_available) { - g_test_skip ("GTK display not available"); + g_test_message ("GTK display not available"); return; } @@ -269,7 +270,7 @@ test_settings_restored_on_disable_and_switch (void) if (!gtk_available) { - g_test_skip ("GTK display not available"); + g_test_message ("GTK display not available"); return; } diff --git a/src/fe-gtk/theme/tests/test-theme-manager-auto-refresh.c b/src/fe-gtk/theme/tests/test-theme-manager-auto-refresh.c index b49acd76..8331b311 100644 --- a/src/fe-gtk/theme/tests/test-theme-manager-auto-refresh.c +++ b/src/fe-gtk/theme/tests/test-theme-manager-auto-refresh.c @@ -1,8 +1,7 @@ -#include +#include "../../fe-gtk.h" #include "../theme-manager.h" #include "../theme-gtk3.h" -#include "../../fe-gtk.h" #include "../../../common/zoitechat.h" #include "../../../common/zoitechatc.h" diff --git a/src/fe-gtk/theme/tests/test-theme-manager-dispatch-routing.c b/src/fe-gtk/theme/tests/test-theme-manager-dispatch-routing.c index 6e6b492e..a3c34bc0 100644 --- a/src/fe-gtk/theme/tests/test-theme-manager-dispatch-routing.c +++ b/src/fe-gtk/theme/tests/test-theme-manager-dispatch-routing.c @@ -1,8 +1,8 @@ -#include +#include "../../fe-gtk.h" + #include #include "../theme-manager.h" -#include "../../fe-gtk.h" #include "../../../common/zoitechat.h" #include "../../../common/zoitechatc.h" diff --git a/src/fe-gtk/theme/tests/test-theme-manager-policy.c b/src/fe-gtk/theme/tests/test-theme-manager-policy.c index 717736c6..d5d2b60d 100644 --- a/src/fe-gtk/theme/tests/test-theme-manager-policy.c +++ b/src/fe-gtk/theme/tests/test-theme-manager-policy.c @@ -1,8 +1,7 @@ -#include +#include "../../fe-gtk.h" #include "../theme-palette.h" #include "../theme-manager.h" -#include "../../fe-gtk.h" #include "../../../common/zoitechat.h" #include "../../../common/zoitechatc.h" diff --git a/src/fe-gtk/theme/tests/test-theme-preferences-gtk3-populate.c b/src/fe-gtk/theme/tests/test-theme-preferences-gtk3-populate.c index 71540bc2..36863658 100644 --- a/src/fe-gtk/theme/tests/test-theme-preferences-gtk3-populate.c +++ b/src/fe-gtk/theme/tests/test-theme-preferences-gtk3-populate.c @@ -1,9 +1,8 @@ -#include +#include "../../fe-gtk.h" #include "../../../common/zoitechat.h" #include "../../../common/zoitechatc.h" #include "../../../common/gtk3-theme-service.h" -#include "../../fe-gtk.h" #include "../theme-gtk3.h" #include "../theme-manager.h" @@ -96,6 +95,7 @@ theme_manager_attach_window (GtkWidget *window) (void)window; } + char * zoitechat_gtk3_theme_service_get_user_themes_dir (void) { @@ -239,7 +239,7 @@ test_removed_selected_theme_commits_fallback_and_applies (void) if (!gtk_available) { - g_test_skip ("GTK display not available"); + g_test_message ("GTK display not available"); return; } @@ -269,6 +269,37 @@ test_removed_selected_theme_commits_fallback_and_applies (void) gtk_widget_destroy (page); } + +static void +test_unset_theme_keeps_system_default_without_apply (void) +{ + GtkWidget *page; + struct zoitechatprefs setup_prefs; + + if (!gtk_available) + { + g_test_message ("GTK display not available"); + return; + } + + memset (&setup_prefs, 0, sizeof (setup_prefs)); + memset (&prefs, 0, sizeof (prefs)); + removed_selected = FALSE; + apply_current_calls = 0; + applied_theme_id[0] = '\0'; + prefs.hex_gui_gtk3_variant = THEME_GTK3_VARIANT_FOLLOW_SYSTEM; + + page = theme_preferences_create_page (NULL, &setup_prefs, NULL); + + g_assert_cmpstr (prefs.hex_gui_gtk3_theme, ==, ""); + g_assert_cmpstr (setup_prefs.hex_gui_gtk3_theme, ==, ""); + g_assert_cmpint (prefs.hex_gui_gtk3_variant, ==, THEME_GTK3_VARIANT_FOLLOW_SYSTEM); + g_assert_cmpint (setup_prefs.hex_gui_gtk3_variant, ==, 0); + g_assert_cmpint (apply_current_calls, ==, 0); + + gtk_widget_destroy (page); +} + int main (int argc, char **argv) { @@ -276,5 +307,7 @@ main (int argc, char **argv) gtk_available = gtk_init_check (&argc, &argv); g_test_add_func ("/theme/preferences/gtk3_removed_selection_applies_fallback", test_removed_selected_theme_commits_fallback_and_applies); + g_test_add_func ("/theme/preferences/gtk3_unset_keeps_system_default", + test_unset_theme_keeps_system_default_without_apply); return g_test_run (); } diff --git a/src/fe-gtk/theme/tests/test-theme-runtime-persistence.c b/src/fe-gtk/theme/tests/test-theme-runtime-persistence.c index bfb8dff7..8b211125 100644 --- a/src/fe-gtk/theme/tests/test-theme-runtime-persistence.c +++ b/src/fe-gtk/theme/tests/test-theme-runtime-persistence.c @@ -1,3 +1,6 @@ +#include "../../../common/zoitechat.h" +#include "../../../common/zoitechatc.h" + #include #include #include @@ -8,8 +11,6 @@ #include #include "../theme-runtime.h" -#include "../../../common/zoitechat.h" -#include "../../../common/zoitechatc.h" struct session *current_sess; struct session *current_tab; diff --git a/src/fe-gtk/theme/theme-access.c b/src/fe-gtk/theme/theme-access.c index 517936a7..c093df58 100644 --- a/src/fe-gtk/theme/theme-access.c +++ b/src/fe-gtk/theme/theme-access.c @@ -40,9 +40,11 @@ theme_access_get_gtk_palette_map (GtkWidget *widget, ThemeGtkPaletteMap *out_map return FALSE; gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &out_map->text_foreground); + G_GNUC_BEGIN_IGNORE_DEPRECATIONS gtk_style_context_get_background_color (context, GTK_STATE_FLAG_NORMAL, &out_map->text_background); gtk_style_context_get_color (context, GTK_STATE_FLAG_SELECTED, &out_map->selection_foreground); gtk_style_context_get_background_color (context, GTK_STATE_FLAG_SELECTED, &out_map->selection_background); + G_GNUC_END_IGNORE_DEPRECATIONS gtk_style_context_get_color (context, GTK_STATE_FLAG_LINK, &accent); if (accent.alpha <= 0.0) accent = out_map->selection_background; diff --git a/src/fe-gtk/theme/theme-application.h b/src/fe-gtk/theme/theme-application.h index 99f770c9..46c7761d 100644 --- a/src/fe-gtk/theme/theme-application.h +++ b/src/fe-gtk/theme/theme-application.h @@ -1,7 +1,6 @@ #ifndef ZOITECHAT_THEME_APPLICATION_H #define ZOITECHAT_THEME_APPLICATION_H -#include #include "../fe-gtk.h" gboolean theme_application_apply_mode (unsigned int mode, gboolean *palette_changed); diff --git a/src/fe-gtk/theme/theme-gtk3.c b/src/fe-gtk/theme/theme-gtk3.c index 847e7ded..fea207f3 100644 --- a/src/fe-gtk/theme/theme-gtk3.c +++ b/src/fe-gtk/theme/theme-gtk3.c @@ -1,5 +1,8 @@ #include "theme-gtk3.h" +#include "../../common/zoitechat.h" +#include "../../common/zoitechatc.h" + #include #include #include @@ -7,8 +10,6 @@ #include "theme-policy.h" #include "../../common/gtk3-theme-service.h" -#include "../../common/zoitechat.h" -#include "../../common/zoitechatc.h" static GPtrArray *theme_gtk3_providers_base; static GPtrArray *theme_gtk3_providers_variant; @@ -183,7 +184,7 @@ settings_restore_icon_search_path (void) if (!icon_theme || !theme_gtk3_settings_state.icon_search_path_captured) return; - gtk_icon_theme_set_search_path (icon_theme, (const char * const *) theme_gtk3_settings_state.icon_search_path, theme_gtk3_settings_state.icon_search_path_count); + gtk_icon_theme_set_search_path (icon_theme, (const char **) theme_gtk3_settings_state.icon_search_path, theme_gtk3_settings_state.icon_search_path_count); gtk_icon_theme_rescan_if_needed (icon_theme); g_strfreev (theme_gtk3_settings_state.icon_search_path); theme_gtk3_settings_state.icon_search_path = NULL; diff --git a/src/fe-gtk/theme/theme-manager.c b/src/fe-gtk/theme/theme-manager.c index e5886a49..1885d626 100644 --- a/src/fe-gtk/theme/theme-manager.c +++ b/src/fe-gtk/theme/theme-manager.c @@ -102,6 +102,7 @@ theme_manager_synthesize_preference_reasons (const struct zoitechatprefs *old_pr reasons |= THEME_CHANGED_REASON_IDENTD; if (color_change || old_prefs->hex_gui_ulist_color != new_prefs->hex_gui_ulist_color || + old_prefs->hex_text_color_nicks != new_prefs->hex_text_color_nicks || old_prefs->hex_away_size_max != new_prefs->hex_away_size_max || old_prefs->hex_away_track != new_prefs->hex_away_track) reasons |= THEME_CHANGED_REASON_USERLIST; @@ -434,7 +435,9 @@ theme_manager_apply_wayland_kde_csd (GtkWidget *window) headerbar = gtk_header_bar_new (); gtk_header_bar_set_show_close_button (GTK_HEADER_BAR (headerbar), TRUE); gtk_header_bar_set_decoration_layout (GTK_HEADER_BAR (headerbar), "menu:minimize,maximize,close"); - icon_pixbuf = gdk_pixbuf_new_from_resource_at_scale ("/icons/zoitechat.png", 32, 32, TRUE, NULL); + icon_pixbuf = gdk_pixbuf_new_from_resource_at_scale ("/icons/zoitechat.svg", 32, 32, TRUE, NULL); + if (!icon_pixbuf) + icon_pixbuf = gdk_pixbuf_new_from_resource_at_scale ("/icons/zoitechat.png", 32, 32, TRUE, NULL); icon_image = icon_pixbuf ? gtk_image_new_from_pixbuf (icon_pixbuf) : gtk_image_new_from_resource ("/icons/zoitechat.png"); if (icon_pixbuf) g_object_unref (icon_pixbuf); @@ -576,7 +579,7 @@ theme_manager_get_userlist_palette_behavior (const PangoFontDescription *font_de behavior.font_desc = font_desc; behavior.apply_background = TRUE; - behavior.apply_foreground = TRUE; + behavior.apply_foreground = (prefs.hex_gui_ulist_color || prefs.hex_text_color_nicks) ? FALSE : TRUE; return behavior; } diff --git a/src/fe-gtk/theme/theme-policy.c b/src/fe-gtk/theme/theme-policy.c index 14df8bf9..05271be7 100644 --- a/src/fe-gtk/theme/theme-policy.c +++ b/src/fe-gtk/theme/theme-policy.c @@ -1,7 +1,5 @@ #include "theme-policy.h" -#include - #include "../fe-gtk.h" #include "../../common/zoitechat.h" #include "../../common/zoitechatc.h" diff --git a/src/fe-gtk/theme/theme-policy.h b/src/fe-gtk/theme/theme-policy.h index 8e40653e..5ce1d5f4 100644 --- a/src/fe-gtk/theme/theme-policy.h +++ b/src/fe-gtk/theme/theme-policy.h @@ -1,7 +1,7 @@ #ifndef ZOITECHAT_THEME_POLICY_H #define ZOITECHAT_THEME_POLICY_H -#include +#include "../fe-gtk.h" gboolean theme_policy_system_prefers_dark (void); gboolean theme_policy_is_dark_mode_active (unsigned int mode); diff --git a/src/fe-gtk/theme/theme-preferences.c b/src/fe-gtk/theme/theme-preferences.c index 8270404a..c5f41ba2 100644 --- a/src/fe-gtk/theme/theme-preferences.c +++ b/src/fe-gtk/theme/theme-preferences.c @@ -1,16 +1,16 @@ #include #include +#include "../../common/zoitechat.h" +#include "../../common/zoitechatc.h" + #include #include #include "../gtkutil.h" #include "../../common/fe.h" #include "../../common/util.h" -#include "../../common/cfgfiles.h" -#include "../../common/zoitechat.h" #include "../../common/gtk3-theme-service.h" -#include "../../common/zoitechatc.h" #include "theme-gtk3.h" #include "theme-manager.h" #include "theme-preferences.h" @@ -739,6 +739,186 @@ theme_preferences_manage_colors_cb (GtkWidget *button, gpointer user_data) theme_manager_save_preferences (); } +static void +theme_preferences_show_import_error (GtkWidget *button, const char *message) +{ + GtkWidget *dialog; + + dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (button)), + GTK_DIALOG_MODAL, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + "%s", + message); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); +} + +static gboolean +theme_preferences_parse_cfg_color (const char *cfg, + const char *key, + guint16 *red, + guint16 *green, + guint16 *blue) +{ + const char *line; + size_t key_len; + + if (!cfg || !key || !red || !green || !blue) + return FALSE; + + key_len = strlen (key); + line = cfg; + + while (*line) + { + const char *line_end; + const char *p; + + while (*line == '\n' || *line == '\r') + line++; + if (!*line) + break; + + line_end = strchr (line, '\n'); + if (!line_end) + line_end = line + strlen (line); + + p = line; + while (p < line_end && g_ascii_isspace (*p)) + p++; + + if ((size_t) (line_end - p) > key_len && + strncmp (p, key, key_len) == 0) + { + unsigned int r; + unsigned int g; + unsigned int b; + + p += key_len; + while (p < line_end && g_ascii_isspace (*p)) + p++; + if (p < line_end && *p == '=') + p++; + while (p < line_end && g_ascii_isspace (*p)) + p++; + + if (sscanf (p, "%x %x %x", &r, &g, &b) == 3) + { + *red = (guint16) CLAMP (r, 0, 0xffff); + *green = (guint16) CLAMP (g, 0, 0xffff); + *blue = (guint16) CLAMP (b, 0, 0xffff); + return TRUE; + } + } + + line = line_end; + } + + return FALSE; +} + +static gboolean +theme_preferences_read_import_color (const char *cfg, + ThemeSemanticToken token, + GdkRGBA *rgba) +{ + static const char *token_names[] = { + "mirc_0", "mirc_1", "mirc_2", "mirc_3", "mirc_4", "mirc_5", "mirc_6", "mirc_7", + "mirc_8", "mirc_9", "mirc_10", "mirc_11", "mirc_12", "mirc_13", "mirc_14", "mirc_15", + "mirc_16", "mirc_17", "mirc_18", "mirc_19", "mirc_20", "mirc_21", "mirc_22", "mirc_23", + "mirc_24", "mirc_25", "mirc_26", "mirc_27", "mirc_28", "mirc_29", "mirc_30", "mirc_31", + "selection_foreground", "selection_background", "text_foreground", "text_background", "marker", + "tab_new_data", "tab_highlight", "tab_new_message", "tab_away", "spell" + }; + char key[256]; + guint16 red; + guint16 green; + guint16 blue; + int legacy_key; + + if (token < 0 || token >= THEME_TOKEN_COUNT) + return FALSE; + + g_snprintf (key, sizeof key, "theme.mode.light.token.%s", token_names[token]); + if (!theme_preferences_parse_cfg_color (cfg, key, &red, &green, &blue)) + { + legacy_key = token < 32 ? token : (token - 32) + 256; + g_snprintf (key, sizeof key, "color_%d", legacy_key); + if (!theme_preferences_parse_cfg_color (cfg, key, &red, &green, &blue)) + return FALSE; + } + + rgba->red = red / 65535.0; + rgba->green = green / 65535.0; + rgba->blue = blue / 65535.0; + rgba->alpha = 1.0; + return TRUE; +} + +static void +theme_preferences_import_colors_conf_cb (GtkWidget *button, gpointer user_data) +{ + gboolean *color_change_flag = user_data; + GtkWidget *dialog; + char *path; + char *cfg; + GError *error = NULL; + gboolean any_imported = FALSE; + gboolean old_changed = FALSE; + ThemeSemanticToken token; + + if (color_change_flag) + old_changed = *color_change_flag; + + dialog = gtk_file_chooser_dialog_new (_("Import colors.conf colors"), + GTK_WINDOW (gtk_widget_get_toplevel (button)), + GTK_FILE_CHOOSER_ACTION_OPEN, + _("_Cancel"), GTK_RESPONSE_CANCEL, + _("_Import"), GTK_RESPONSE_ACCEPT, + NULL); + gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), TRUE); + gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), FALSE); + + if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_ACCEPT) + { + gtk_widget_destroy (dialog); + return; + } + + path = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); + gtk_widget_destroy (dialog); + if (!path) + return; + + if (!g_file_get_contents (path, &cfg, NULL, &error)) + { + theme_preferences_show_import_error (button, _("Failed to read colors.conf file.")); + g_clear_error (&error); + g_free (path); + return; + } + + for (token = THEME_TOKEN_MIRC_0; token < THEME_TOKEN_COUNT; token++) + { + GdkRGBA rgba; + + if (!theme_preferences_read_import_color (cfg, token, &rgba)) + continue; + + theme_manager_set_token_color (ZOITECHAT_DARK_MODE_LIGHT, token, &rgba, color_change_flag); + any_imported = TRUE; + } + + if (!any_imported) + theme_preferences_show_import_error (button, _("No importable colors were found in that colors.conf file.")); + else if (color_change_flag && *color_change_flag != old_changed) + theme_manager_save_preferences (); + + g_free (cfg); + g_free (path); +} + static void theme_preferences_create_color_button (GtkWidget *table, ThemeSemanticToken token, @@ -1102,6 +1282,40 @@ theme_preferences_load_thumbnail (const char *path) return scaled; } +static int +theme_preferences_gtk3_find_system_theme_index (GPtrArray *themes) +{ + GtkSettings *settings; + char *system_theme = NULL; + guint i; + int found = -1; + + settings = gtk_settings_get_default (); + if (!settings || !themes) + return -1; + + g_object_get (G_OBJECT (settings), "gtk-theme-name", &system_theme, NULL); + if (!system_theme || system_theme[0] == '\0') + { + g_free (system_theme); + return -1; + } + + for (i = 0; i < themes->len; i++) + { + ZoitechatGtk3Theme *theme = g_ptr_array_index (themes, i); + + if (theme && g_strcmp0 (theme->id, system_theme) == 0) + { + found = (int) i; + break; + } + } + + g_free (system_theme); + return found; +} + static void theme_preferences_populate_gtk3 (theme_preferences_ui *ui) { @@ -1111,6 +1325,7 @@ theme_preferences_populate_gtk3 (theme_preferences_ui *ui) GtkTreeIter iter; int active = -1; gboolean removed_selected_theme = FALSE; + gboolean using_system_default = prefs.hex_gui_gtk3_theme[0] == '\0'; gboolean should_apply = FALSE; char *final_id; ThemeGtk3Variant final_variant = THEME_GTK3_VARIANT_PREFER_LIGHT; @@ -1143,12 +1358,14 @@ theme_preferences_populate_gtk3 (theme_preferences_ui *ui) g_object_unref (thumbnail); g_free (label); } + if (active < 0 && using_system_default) + active = theme_preferences_gtk3_find_system_theme_index (themes); if (active >= 0) gtk_combo_box_set_active (GTK_COMBO_BOX (ui->gtk3_combo), active); else if (themes->len > 0) { gtk_combo_box_set_active (GTK_COMBO_BOX (ui->gtk3_combo), 0); - if (prefs.hex_gui_gtk3_theme[0] != '\0') + if (!using_system_default) removed_selected_theme = TRUE; } else if (prefs.hex_gui_gtk3_theme[0] != '\0') @@ -1161,19 +1378,22 @@ theme_preferences_populate_gtk3 (theme_preferences_ui *ui) if (final_id) { final_variant = theme_gtk3_variant_for_theme (final_id); - should_apply = g_strcmp0 (prefs.hex_gui_gtk3_theme, final_id) != 0 - || prefs.hex_gui_gtk3_variant != final_variant - || removed_selected_theme; - g_strlcpy (prefs.hex_gui_gtk3_theme, final_id, sizeof (prefs.hex_gui_gtk3_theme)); - if (ui->setup_prefs) - g_strlcpy (ui->setup_prefs->hex_gui_gtk3_theme, - final_id, - sizeof (ui->setup_prefs->hex_gui_gtk3_theme)); + if (!using_system_default || removed_selected_theme) + { + should_apply = g_strcmp0 (prefs.hex_gui_gtk3_theme, final_id) != 0 + || prefs.hex_gui_gtk3_variant != final_variant + || removed_selected_theme; + g_strlcpy (prefs.hex_gui_gtk3_theme, final_id, sizeof (prefs.hex_gui_gtk3_theme)); + if (ui->setup_prefs) + g_strlcpy (ui->setup_prefs->hex_gui_gtk3_theme, + final_id, + sizeof (ui->setup_prefs->hex_gui_gtk3_theme)); + prefs.hex_gui_gtk3_variant = final_variant; + if (ui->setup_prefs) + ui->setup_prefs->hex_gui_gtk3_variant = final_variant; + } g_free (final_id); } - prefs.hex_gui_gtk3_variant = final_variant; - if (ui->setup_prefs) - ui->setup_prefs->hex_gui_gtk3_variant = final_variant; if (should_apply && !theme_gtk3_apply_current (&error)) { @@ -1289,6 +1509,7 @@ theme_preferences_create_page (GtkWindow *parent, GtkWidget *colors_frame; GtkWidget *colors_box; GtkWidget *manage_colors_button; + GtkWidget *import_colors_button; GtkWidget *gtk3_frame; GtkWidget *gtk3_grid; GtkWidget *gtk3_button; @@ -1319,6 +1540,12 @@ theme_preferences_create_page (GtkWindow *parent, g_signal_connect (G_OBJECT (manage_colors_button), "clicked", G_CALLBACK (theme_preferences_manage_colors_cb), color_change_flag); + import_colors_button = gtk_button_new_with_label (_("Import colors.conf colors…")); + gtk_widget_set_halign (import_colors_button, GTK_ALIGN_START); + gtk_box_pack_start (GTK_BOX (colors_box), import_colors_button, FALSE, FALSE, 0); + g_signal_connect (G_OBJECT (import_colors_button), "clicked", + G_CALLBACK (theme_preferences_import_colors_conf_cb), color_change_flag); + gtk3_frame = gtk_frame_new (_("GTK3 Theme")); gtk_box_pack_start (GTK_BOX (box), gtk3_frame, FALSE, FALSE, 0); gtk3_grid = gtk_grid_new (); diff --git a/src/fe-gtk/theme/theme-preferences.h b/src/fe-gtk/theme/theme-preferences.h index 2ca3c3a8..d2d15a07 100644 --- a/src/fe-gtk/theme/theme-preferences.h +++ b/src/fe-gtk/theme/theme-preferences.h @@ -1,12 +1,11 @@ #ifndef ZOITECHAT_THEME_PREFERENCES_H #define ZOITECHAT_THEME_PREFERENCES_H -#include - -#include "theme-access.h" #include "../fe-gtk.h" #include "../../common/zoitechat.h" +#include "theme-access.h" + GtkWidget *theme_preferences_create_page (GtkWindow *parent, struct zoitechatprefs *setup_prefs, gboolean *color_change_flag); diff --git a/src/fe-gtk/userlistgui.c b/src/fe-gtk/userlistgui.c index d49512c0..445265a9 100644 --- a/src/fe-gtk/userlistgui.c +++ b/src/fe-gtk/userlistgui.c @@ -369,13 +369,13 @@ void userlist_set_value (GtkWidget *treeview, gfloat val) { gtk_adjustment_set_value ( - gtk_tree_view_get_vadjustment (GTK_TREE_VIEW (treeview)), val); + gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (treeview)), val); } gfloat userlist_get_value (GtkWidget *treeview) { - return gtk_adjustment_get_value (gtk_tree_view_get_vadjustment (GTK_TREE_VIEW (treeview))); + return gtk_adjustment_get_value (gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (treeview))); } int @@ -429,7 +429,7 @@ fe_userlist_rehash (session *sess, struct User *user) nick_token = THEME_TOKEN_TAB_AWAY; have_nick_token = TRUE; } - else if (prefs.hex_gui_ulist_color) + else if (prefs.hex_gui_ulist_color || prefs.hex_text_color_nicks) { int mirc_index = text_color_of (user->nick); @@ -461,7 +461,7 @@ fe_userlist_insert (session *sess, struct User *newuser, gboolean sel) nick_token = THEME_TOKEN_TAB_AWAY; have_nick_token = TRUE; } - else if (prefs.hex_gui_ulist_color) + else if (prefs.hex_gui_ulist_color || prefs.hex_text_color_nicks) { int mirc_index = text_color_of (newuser->nick); diff --git a/src/fe-gtk/xtext.c b/src/fe-gtk/xtext.c index 448e3ace..27f19452 100644 --- a/src/fe-gtk/xtext.c +++ b/src/fe-gtk/xtext.c @@ -318,12 +318,18 @@ xtext_surface_from_window (GdkWindow *window) static cairo_t * xtext_create_context (GtkXText *xtext) { + cairo_t *cr; + if (xtext->draw_surface) return cairo_create (xtext->draw_surface); if (xtext->draw_cr) return cairo_reference (xtext->draw_cr); - return gdk_cairo_create (xtext->draw_window); + G_GNUC_BEGIN_IGNORE_DEPRECATIONS + cr = gdk_cairo_create (xtext->draw_window); + G_GNUC_END_IGNORE_DEPRECATIONS + + return cr; } static inline void @@ -357,7 +363,7 @@ xtext_draw_line (GtkXText *xtext, cairo_t *cr, const XTextColor *color, int x1, cairo_restore (cr); } -static inline void +static void xtext_draw_bg_offset (GtkXText *xtext, int x, int y, int width, int height, int tile_x, int tile_y) { cairo_t *cr = xtext_create_context (xtext); @@ -1065,8 +1071,10 @@ static inline void gtk_xtext_clear_background (GtkWidget *widget) { GdkWindow *window = gtk_widget_get_window (widget); + G_GNUC_BEGIN_IGNORE_DEPRECATIONS if (window) gdk_window_set_background_pattern (window, NULL); + G_GNUC_END_IGNORE_DEPRECATIONS } static void