83 Commits

Author SHA1 Message Date
deepend-tildeclub
f676aa56e6 Merge pull request #103 from ZoiteChat/theme-features-fixes
Theme update
2026-03-09 10:50:12 -06:00
a53802cfef fix(win): tolerate tar/PS nonzero if files extracted; add path_tree_has_entries() to verify real output 2026-03-08 10:40:20 -06:00
b47c45d4cc feat: merge GTK3 Theme into Appearance (new Advanced section); fix+scale chat bg image + use FileChooserNative picker 2026-03-08 10:10:59 -06:00
f2354a7fa2 refactor: unify tree/xtext/input colors via ThemeWidgetStyleValues (canonical widget-style path) 2026-03-07 22:11:09 -07:00
ca043be197 fix: KDE Wayland alert flash—detect Plasma+Wayland, present() before urgency hint 2026-03-07 19:21:37 -07:00
50346683a1 feat: GTK3-only theming overhaul—new theme service (discover/import/inherits), layered CSS+settings.ini apply w/ safe rollback + caching; widget/xtext palette mapping + all-colors editor; lots of win32/CI libarchive plumbing + installer assets; 2026-03-04 23:28:01 -07:00
deepend-tildeclub
43374f4fae Merge pull request #4 from deepend-tildeclub/theme-module
feat: centralize theming in theme-manager (palette/tokens, CSS, dark-…
2026-03-02 20:44:49 -07:00
deepend-tildeclub
5e86f363ed Merge pull request #100 from ZoiteChat/theme-module
Theme module
2026-03-02 19:59:43 -07:00
d9be0a7b1c feat: centralize theming in theme-manager (palette/tokens, CSS, dark-mode, setup UI), add tests + win32/meson wiring 2026-03-02 19:42:48 -07:00
deepend-tildeclub
f3086fa389 Merge pull request #2 from deepend-tildeclub/consistent-icons
gtk: centralize icon lookup (new icon-resolver), move mappings out of…
2026-03-01 15:01:19 -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
1a32bff274 win32 icons: actually copy hicolor subdirs. 2026-03-01 13:16:52 -07:00
349d7f4c55 win32: install hicolor icons + CI now pulls real hicolor-icon-theme 2026-03-01 11:09:19 -07:00
734d194cb0 win32: stage hicolor icon theme into rel share/icons 2026-03-01 10:58:17 -07:00
5983befd5b icons: add system_icon_name API, make gtkutil fall back via resolver registry 2026-03-01 10:14:41 -07:00
e63e68dfde icons: dedupe resolver tables, add unified menu-action API, route gtkutil/pixmaps through one registry + fallback chain 2026-03-01 09:58:04 -07:00
1ef81951b7 win32: wire icon-resolver into VS build, kill old menu icon payload (copy + installer) 2026-02-28 23:39:08 -07:00
395ccb0706 gtk: centralize icon lookup (new icon-resolver), move mappings out of gtkutil/pixmaps, add sane fallback chain + meson hookup 2026-02-28 23:17:27 -07:00
deepend-tildeclub
b3f692f00c Update server addresses for Zoite 2026-02-28 23:02:02 -07:00
deepend-tildeclub
64c2fd4e51 Merge pull request #96 from ZoiteChat/win-dependencies-cleanup
Win dependencies cleanup
2026-02-28 10:44:44 -07:00
deepend-tildeclub
dd698ecab4 Merge pull request #95 from ZoiteChat/userlist-highlight
userlist highlight: focusable treeview
2026-02-28 10:23:23 -07:00
b93bad9859 windows x64-only purge: kill Win32 configs, simplify installer. 2026-02-28 09:53:37 -07:00
733f932b78 squash: win32 packaging detox (no comsupp/VC2013, trim payload, gate lua/python) 2026-02-28 09:36:50 -07:00
50d99e1314 userlist highlight: focusable treeview + palette CSS gets real :selected theme colors 2026-02-27 09:28:44 -07:00
deepend-tildeclub
90b7d7c5a1 Delete packaging/solus directory
Removing Solus build.  Will bring this back in future when I have more time.
2026-02-26 12:51:51 -07:00
deepend-tildeclub
7e422e10a6 Delete .github/workflows/solus-eopkg-build.yml
Removing Solus Build.  Will possibly bring this back when I have more time.
2026-02-26 12:51:11 -07:00
deepend-tildeclub
2bf32fc770 Merge pull request #90 from ZoiteChat/code-cleanup
Code cleanup
2026-02-25 18:16:54 -07:00
3e095c3c33 Removed two redundant inline comments in the file dialog response/done handlers, leaving the behavior unchanged and the control flow cleaner.
Removed an old commented-out helper function block (gtkutil_treeview_get_selected_iter) that was dead/commented code.
2026-02-25 18:07:26 -07:00
3445d946bc Removed a redundant inline comment in icon loading/scaling logic, leaving behavior unchanged.
Removed a redundant inline comment in the Windows sysinfo volume-name guard path, with no functional impact.
Removed a redundant inline comment in WinRT toast setup while keeping the same notification/audio attribute behavior.
2026-02-25 18:05:21 -07:00
7578928199 Cleaned up redundant/outdated inline comments in the text frontend argument/config and GUI control paths while leaving behavior unchanged (comment-only cleanup). 2026-02-25 16:22:46 -07:00
deepend-tildeclub
428127ef40 Merge pull request #91 from ZoiteChat/fix-application-focus
Added a Windows-only helper (mg_win32_allow_autohide_taskbar) that ge…
2026-02-25 16:20:47 -07:00
e3f932aa6b Updated the Win32 window-state handling to include shellapi.h and query taskbar auto-hide/taskbar edge state via SHAppBarMessage, so maximized windows can leave a 1px reveal edge for the auto-hidden taskbar.
Added monitor-aware work-area adjustment when maximized (MonitorFromWindow + GetMonitorInfo) and shrink by 1px on the detected taskbar edge (including bottom edge), then apply that rectangle with SetWindowPos. This addresses the “mouse at bottom edge should unhide taskbar” behavior.
Kept the existing HWND_NOTOPMOST safeguard in place after the adjustment, preserving prior not-topmost behavior.
2026-02-25 14:48:18 -07:00
7cfa3b3513 Added a Windows-only helper (mg_win32_allow_autohide_taskbar) that gets the native HWND and calls SetWindowPos(..., HWND_NOTOPMOST, ...) for non-fullscreen window-state transitions, so a maximized ZoiteChat window no longer blocks the taskbar auto-hide reveal edge.
Hooked that helper into mg_windowstate_cb so it runs whenever the main window state changes (while preserving existing maximize/fullscreen preference handling).
2026-02-25 14:18:23 -07:00
81c691491c Removed three redundant inline comments in joind_ok_cb that duplicated obvious control flow, leaving behavior unchanged and improving readability. 2026-02-25 13:55:44 -07:00
c361602b1a Removed four unneeded section comments in src/common/notify.h (WATCH/MONITOR/general/old ISON labels), leaving only the function declarations for a cleaner header interface. 2026-02-25 13:51:22 -07:00
99b969067e Removed one stale, commented-out debug/error line in the PCI device-name lookup path (pci_find_fullname), leaving behavior unchanged and making the function cleaner. 2026-02-25 13:29:20 -07:00
6e8b750c68 Removed an obsolete commented-out hdiutil line from the macOS bundling script, leaving only the active packaging path (zip) to keep the script cleaner and easier to scan. 2026-02-25 13:04:05 -07:00
df37b44cc8 Cleaned up unneeded comment noise in the Solus eopkg workflow by replacing an 11-line explanatory block with a concise 2-line comment while preserving the key rationale for --ignore-file-conflicts and required Meson tooling install. 2026-02-25 13:01:21 -07:00
9548be0cec Removed redundant inline comments in the Winamp plugin by simplifying the plugin handle declaration and cleanup comments around initialization/return values, while keeping functional comments intact.
Removed the redundant return 1 inline comment in the Exec plugin init function.
2026-02-25 12:57:42 -07:00
deepend-tildeclub
588e27b456 Remove Debian Build badge from README
Removed Debian Build badge from README.
2026-02-25 10:32:21 -07:00
deepend-tildeclub
7032d0c6b7 Update contact email in appdata XML file 2026-02-25 10:23:59 -07:00
deepend-tildeclub
72e9a99315 Update developer information and homepage URL 2026-02-25 10:17:14 -07:00
3cff6742f5 Removed unneeded inline comments around the Win32 error-formatting fallback in errorstring() and simplified matching block-closing lines, without changing behavior. 2026-02-25 02:37:08 -07:00
6a02f578b6 Removed obsolete commented-out lines from fe_cleanup() so the function no longer contains dead commented code.
Removed an unnecessary explanatory comment above the unconditional early return in log_handler(), leaving only the active behavior.

Removed an unneeded section marker comment before fe_idle() to keep surrounding code cleaner.
2026-02-25 02:34:50 -07:00
e62769b361 Cleaned up unneeded comments in DCC receive/connect code by removing:
a stale commented-out ACK block in the DCC receive error path,

    an unnecessary speculative note before the quoted filename handling,

    and an editorial inline comment on a static variable declaration.
2026-02-25 02:30:46 -07:00
9df9776238 Removed a stale multi-line # TODO note block from the common Meson build file to clean up unneeded comments without changing build logic.
Removed an old commented-out /* FIXME ... */ prototype block from servlist.h, leaving only active declarations.
2026-02-25 02:28:10 -07:00
4beabb6bf5 Removed a stale commented-out debug function block from the fishlim plugin source to reduce dead/commented code.
Removed the corresponding commented-out RAW LINE hook entry so only active handlers remain in plugin initialization.
2026-02-25 02:24:11 -07:00
10d5bb91ab Cleaned up unneeded, commented-out debug logging lines in Perl plugin callback handlers (server_cb, command_cb, and print_cb) without changing runtime behavior. 2026-02-25 02:14:38 -07:00
7c9c615aed Removed redundant inline comments from the fishlim IRC parsing helpers where the comments only repeated obvious code behavior, while preserving all function docblocks and logic. 2026-02-25 02:12:10 -07:00
fd48c97209 Removed four redundant inline comments in src/fe-gtk/urlgrab.c to clean up readability without changing behavior (treeview enum declaration area, right-click selection block, headers visibility call, and URL list overflow trimming block). 2026-02-25 02:09:35 -07:00
e58bf2be22 Cleaned up redundant comments in dcc_listen_init by removing obvious/explanatory noise and an obsolete commented-out debug printf, while leaving logic unchanged. 2026-02-25 02:07:38 -07:00
dc6453e230 Removed redundant inline comments in lastact_update and lastact_getfirst where the code was already self-explanatory, without changing behavior.
Simplified away_check by removing comment clutter and keeping only the logic flow, including the WHO batching behavior.
Removed unneeded commentary around lag-check helpers and timer reinitialization to keep the core timer code cleaner and easier to scan.
2026-02-25 02:04:31 -07:00
b3a0288fd9 Cleaned up stale inline comments in the tab scrolling handlers by removing outdated explanatory text while keeping behavior unchanged (tab_left_is_moving / tab_right_is_moving reset paths).
Removed an old commented-out gtk_container_set_border_width(...) line that was dead/commented code in cv_tabs_init.
Simplified the tab-switch condition by removing a legacy commented expression from if (is_switching).
2026-02-25 02:01:11 -07:00
9c86f18982 Cleaned up unneeded inline comments in plugins/python/python.py while keeping runtime behavior unchanged (comment-only cleanup around version declaration, compile helpers, wordlist/timer handling, and autoload path handling). 2026-02-25 01:58:19 -07:00
1bf0140652 Cleaned up redundant inline comments in the SCRAM implementation so the file is less noisy while preserving behavior exactly as-is (no logic changes). 2026-02-25 01:54:34 -07:00
bb72f8afab Removed redundant inline comments from the common header includes/platform guards in src/common/zoitechat.h (e.g., comments like “need time_t”, “for win32”, “for unix”), while preserving meaningful explanatory comments. 2026-02-25 01:50:00 -07:00
bb11c4676b Cleaned up src/fe-gtk/meson.build by removing an outdated commented-out WinRT build block in the Windows section, leaving only active build logic.
Removed an inline TODO comment from the gnome.compile_resources call to keep the Meson configuration concise and focused on current settings.
2026-02-25 01:47:32 -07:00
32fe3e54f1 Removed redundant section-divider comments in the Windows spellcheck provider to reduce clutter without changing behavior.
Removed non-essential inline comments that restated obvious return values and assignment intent (return -1/1/0, add_to_exclude alias), keeping logic identical.
2026-02-25 01:45:20 -07:00
9d2187ca4d Cleaned up unneeded inline comments in src/fe-text/fe-text.c where control-character switch cases were already self-explanatory, while keeping behavior unchanged.
Removed a redundant comment from the done global flag declaration for a cleaner declaration section.
2026-02-25 01:43:01 -07:00
0e94432c24 Removed four redundant comments in plugins/sysinfo/sysinfo.c while keeping behavior unchanged (the command parsing, channel checks, and menu add/remove calls are intact). 2026-02-25 01:40:34 -07:00
c4890d157a Cleaned up redundant inline comments in the exec plugin’s command execution path (pipe creation, buffer termination, per-line announce handling, sleep loop, and trailing newline output) without changing behavior. 2026-02-25 01:38:06 -07:00
ef2befa698 Cleaned up redundant comments in src/fe-gtk/fkeys.c by removing section-divider noise and a stale XXX line near key-action helpers, while keeping useful function-level documentation.
Removed repetitive inline comments from return 2; statements in tab-move/history key actions, since behavior is already clear from the surrounding code.
Removed an unnecessary separator comment before replace_handle() for a cleaner transition between functions.
2026-02-25 01:35:30 -07:00
5f9ce549f8 Removed redundant inline comments in the timer plugin that did not add useful context (plugin handle declaration and return value comment), keeping behavior unchanged.
Removed an obsolete visual alignment guide comment above the timer list header print call to clean up the function body.
2026-02-25 01:32:27 -07:00
cb435f0d15 Cleaned up unneeded comments in default config initialization by removing:
a stale commented-out assignment line,

    an outdated inline TODO/FIXME note on hex_irc_who_join,

    and an inline /*FIXME*/ marker on hex_flood_msg_time.
2026-02-25 01:29:05 -07:00
105e259f2c Removed redundant inline /* plugin handle */ comments from the ph declarations in three plugin source files, keeping behavior unchanged and making the declarations cleaner. 2026-02-25 01:06:13 -07:00
51bf0c3fe0 Removed redundant explanatory comments in chanopt_command so the control flow reads cleanly without inline narration, while keeping behavior unchanged.
Simplified the chanopt_in_memory struct and helper routines by removing comments that repeated obvious intent (allocation/default initialization/loading notes), with no logic changes.
2026-02-25 01:02:37 -07:00
e6311a5fe7 Removed two stale, commented-out lines in ignore_showlist() (an unused EMIT_SIGNAL call and its note), cleaning up unneeded comments without changing runtime behavior. 2026-02-25 00:59:53 -07:00
2c90c14d72 Removed an unneeded comment above the $(CONFIG_STAMP) target in Makefile, leaving behavior unchanged and just cleaning up the file. 2026-02-25 00:57:30 -07:00
6c9aeac36f Cleaned up unneeded inline comments in swtype by removing index/reserved annotations that didn’t add value, while keeping the data unchanged.
Removed a stale commented-out ST_HEADER line from tabs_settings so the settings table only contains active entries.
Removed a dead commented-out call from setup_apply_trans to reduce noise in the function body.
Removed redundant trailing declaration comments from proxy_user and proxy_pass since the types are already explicit.
2026-02-25 00:55:37 -07:00
48f7693eac Removed redundant comments in the notification plugin implementation to clean up the code without changing behavior (including comments around color stripping, alert gating logic, and special-event hook registration). 2026-02-25 00:53:10 -07:00
71d3ba576f Removed an outdated TODO comment in plugins/python/python.py above the module-level state variables, keeping behavior unchanged while reducing noise.
Removed two stale TODO comments in plugins/python/_zoitechat.py above command() and hook_command(), with no functional changes to those APIs.
2026-02-25 00:49:54 -07:00
067670bd01 Removed three redundant inline comments in the server helper code to clean up readability without changing any behavior:
Deleted comment above the serv->network check in server_get_network.
 Deleted comment above the server_session->channel check in server_get_network.
 Deleted comment above the name != serv->servername guard in server_set_name.
2026-02-25 00:46:18 -07:00
610d6fa1c0 Removed stale, commented-out SSL debug code in ssl_cb_info, leaving the function behavior unchanged while cleaning dead comments.
Removed an old commented-out rsa_tmp_bits certificate logging block in the SSL certificate info path.
Removed commented-out “Verify OK” signal lines in the SSL verification switch for cleaner control-flow comments.
2026-02-25 00:43:03 -07:00
5d6fa503c9 Cleaned up redundant CI workflow comments in AppImage workflow sections where the commands are already self-explanatory, including plugin listing and environment export blocks.
Replaced a long explanatory Solus packaging comment block with a concise single-line comment that preserves the key intent for --ignore-file-conflicts and toolchain installation.
Removed unneeded inline comments in the Windows build workflow around Python root resolution and junction creation while keeping behavior unchanged.
2026-02-25 00:40:36 -07:00
375e747014 Removed four redundant section-label comments from plugins/python/generate_plugin.py to clean up non-essential commentary while keeping behavior unchanged (# zoitechat-plugin.h, # This is very specific..., # python.py, # python.c). 2026-02-25 00:38:03 -07:00
5cab7be8a9 Removed redundant inline comments in notify network filtering and server-entry lookup paths to clean up noise without changing behavior.
Simplified notify list preparation in notify_save into a single reverse-copy expression and normalized GLib call spacing for consistency.
2026-02-25 00:34:59 -07:00
4808d83b26 Cleaned up unneeded inline comments in IRC inbound handling by removing redundant // comments around session selection and SCRAM auth status branches, with no logic changes. 2026-02-25 00:32:23 -07:00
c4951a06f3 Cleaned up unneeded commented-out debug lines in maingui.c (old printf/puts and an obsolete commented call), without changing behavior or logic flow.
Committed the cleanup on the current branch with commit message: Remove stale debug comments from maingui.
2026-02-25 00:29:52 -07:00
bd418160e1 Removed four redundant inline comments in print_sha256_result so the function is cleaner without changing behavior or control flow. 2026-02-25 00:26:56 -07:00
90a3d6d839 Removed redundant comments in url_save_node() and url_add() so the function bodies are cleaner without changing logic.
Removed an outdated performance note comment before the cached match state variables and a redundant comment in match_nick(); behavior remains unchanged.
2026-02-25 00:23:42 -07:00
deepend-tildeclub
e2511e8be1 Delete .github/workflows/debian-build.yml 2026-02-24 22:41:00 -07:00
deepend-tildeclub
33e1403b98 Delete debian directory 2026-02-24 22:40:49 -07:00
deepend-tildeclub
596a134ef3 Add Manjaro Package Build badge to README 2026-02-24 22:11:51 -07:00
156 changed files with 11887 additions and 4559 deletions

View File

@@ -29,6 +29,7 @@ jobs:
build-essential pkg-config meson ninja-build cmake \
gettext \
libcanberra-dev libdbus-glib-1-dev libglib2.0-dev \
libarchive-dev \
libgtk-3-dev \
libwayland-client0 libwayland-cursor0 libwayland-egl1 \
libxkbcommon0 \

View File

@@ -1,48 +0,0 @@
name: Debian Build
on:
push:
branches: [master]
pull_request:
branches: [master]
jobs:
debian_build:
runs-on: ubuntu-24.04
container:
image: debian:bookworm
steps:
- name: Install packaging tooling and build dependencies
run: |
set -eux
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install -y --no-install-recommends \
git ca-certificates \
build-essential dpkg-dev debhelper fakeroot \
pkg-config meson ninja-build \
gettext iso-codes \
libcanberra-dev libdbus-glib-1-dev libglib2.0-dev libgtk-3-dev libayatana-appindicator3-dev \
liblua5.3-dev libpci-dev libperl-dev libssl-dev \
python3-dev python3-cffi desktop-file-utils
- uses: actions/checkout@v4
with:
submodules: true
- name: Build Debian packages
run: |
set -eux
dpkg-buildpackage -us -uc -b
- name: Collect Debian artifacts
run: |
set -eux
mkdir -p artifacts
cp -v ../*.deb ../*.changes ../*.buildinfo artifacts/
- name: Upload Debian artifacts
uses: actions/upload-artifact@v4
with:
name: zoitechat-debian-packages
path: artifacts/*

View File

@@ -1,88 +0,0 @@
name: Solus eopkg build
on:
workflow_dispatch:
inputs:
package_yml:
description: "Path to Solus package.yml for ypkg build"
required: false
default: "packaging/solus/package.yml"
solus_image:
description: "Solus container image"
required: false
default: "docker.io/silkeh/solus:latest"
push:
branches:
- main
- master
permissions:
contents: read
packages: read
jobs:
build-eopkg:
runs-on: ubuntu-latest
env:
SOLUS_IMAGE: ${{ inputs.solus_image || 'docker.io/silkeh/solus:latest' }}
PACKAGE_YML: ${{ inputs.package_yml || 'packaging/solus/package.yml' }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Log in to GHCR (for ghcr.io images)
if: startsWith(env.SOLUS_IMAGE, 'ghcr.io/')
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ github.token }}
- name: Build eopkg package in Solus container
run: |
if [ ! -f "$PACKAGE_YML" ]; then
echo "Expected Solus packaging file at $PACKAGE_YML" >&2
echo "Available package.yml files:" >&2
find . -name "package.yml" -print >&2 || true
echo "Add a package.yml (ypkg) file or update the workflow input PACKAGE_YML." >&2
exit 1
fi
if ! docker pull "$SOLUS_IMAGE"; then
echo "Failed to pull SOLUS_IMAGE=$SOLUS_IMAGE" >&2
echo "Set workflow input 'solus_image' to a valid image that provides eopkg/ypkg." >&2
exit 1
fi
docker run --rm \
-v "$PWD":/workspace \
-w /workspace \
-e PACKAGE_YML="$PACKAGE_YML" \
"$SOLUS_IMAGE" \
sh -lc '
set -euo pipefail
eopkg update-repo -y
# Do not remove openssl-11 here: it can trigger a very large
# dependency cascade (including python3/eopkg itself), which
# breaks the build environment before package build starts.
# Some Solus base images still contain openssl-11 files that
# conflict with openssl 3.x when the package set is refreshed.
# Allowing file-conflict resolution keeps the CI image usable
# long enough to install ypkg and complete the package build.
# The base image does not guarantee Meson toolchain packages,
# while our package.yml setup phase calls meson directly.
# Install the essential build tools up front to avoid
# `/tmp/ypkg-setup*: meson: command not found` failures.
eopkg install -y --ignore-file-conflicts \
ypkg git meson ninja pkgconf gcc gettext
ypkg build "$PACKAGE_YML"
mkdir -p /workspace/artifacts
find . -maxdepth 3 -name "*.eopkg" -type f -exec cp -v {} /workspace/artifacts/ \;
'
- name: Upload eopkg artifacts
uses: actions/upload-artifact@v4
with:
name: solus-eopkg
path: artifacts/*.eopkg
if-no-files-found: error

View File

@@ -36,29 +36,79 @@ jobs:
run: |
New-Item -Name "deps" -ItemType "Directory" -Force | Out-Null
Invoke-WebRequest https://files.jrsoftware.org/is/6/innosetup-6.7.0.exe -OutFile deps\innosetup-unicode.exe
python -m pip install --upgrade pip
python -m pip install cffi
python -m pip install zstandard
$ProgressPreference = 'SilentlyContinue'
function Download-WithRetry {
param(
[string]$Url,
[string]$OutFile,
[int]$MaxAttempts = 5,
[int]$InitialDelaySeconds = 2
)
for ($attempt = 1; $attempt -le $MaxAttempts; $attempt++) {
try {
Invoke-WebRequest -Uri $Url -OutFile $OutFile -ErrorAction Stop
return
}
catch {
if ($attempt -eq $MaxAttempts) {
throw
}
Start-Sleep -Seconds ($InitialDelaySeconds * [math]::Pow(2, $attempt - 1))
}
}
}
Download-WithRetry -Url https://files.jrsoftware.org/is/6/innosetup-6.7.0.exe -OutFile deps\innosetup-unicode.exe
& deps\innosetup-unicode.exe /VERYSILENT | Out-Null
Invoke-WebRequest https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/idpsetup-1.5.1.exe -OutFile deps\idpsetup.exe
Download-WithRetry -Url https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/idpsetup-1.5.1.exe -OutFile deps\idpsetup.exe
& deps\idpsetup.exe /VERYSILENT
Invoke-WebRequest https://github.com/ZoiteChat/gvsbuild/releases/download/zoitechat-2.18.0-pre1/GTK3_Gvsbuild_zoitechat-2.18.0-pre1_${{ matrix.platform }}.7z -OutFile deps\gtk-${{ matrix.arch }}.7z
Download-WithRetry -Url https://github.com/ZoiteChat/gvsbuild/releases/download/zoitechat-2.18.0-pre1/GTK3_Gvsbuild_zoitechat-2.18.0-pre1_${{ matrix.platform }}.7z -OutFile deps\gtk-${{ matrix.arch }}.7z
& 7z.exe x deps\gtk-${{ matrix.arch }}.7z -oC:\gtk-build\gtk\x64\release
Invoke-WebRequest https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/gendef-20111031.7z -OutFile deps\gendef.7z
Download-WithRetry -Url https://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-hicolor-icon-theme-0.18-1-any.pkg.tar.zst -OutFile deps\hicolor-icon-theme.pkg.tar.zst
python -c "import tarfile,zstandard,pathlib;archive=pathlib.Path(r'deps\\hicolor-icon-theme.pkg.tar.zst');target=pathlib.Path(r'C:\\gtk-build\\gtk\\x64\\release');dctx=zstandard.ZstdDecompressor();f=archive.open('rb');reader=dctx.stream_reader(f);tf=tarfile.open(fileobj=reader,mode='r|');[tf.extract(m,path=target) for m in tf if m.name.startswith('mingw64/share/icons/hicolor/')];tf.close();reader.close();f.close()"
Download-WithRetry -Url https://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-libarchive-3.8.1-1-any.pkg.tar.zst -OutFile deps\libarchive.pkg.tar.zst
python -c "import tarfile,zstandard,pathlib;archive=pathlib.Path(r'deps\\libarchive.pkg.tar.zst');target=pathlib.Path(r'C:\\gtk-build\\gtk\\x64\\release');dctx=zstandard.ZstdDecompressor();f=archive.open('rb');reader=dctx.stream_reader(f);tf=tarfile.open(fileobj=reader,mode='r|');[tf.extract(m,path=target) for m in tf if m.name.startswith(('mingw64/include/archive','mingw64/lib/libarchive','mingw64/bin/libarchive'))];tf.close();reader.close();f.close()"
if (Test-Path C:\gtk-build\gtk\x64\release\mingw64\share\icons\hicolor) {
New-Item -Path C:\gtk-build\gtk\x64\release\share\icons -ItemType Directory -Force | Out-Null
Copy-Item -Path C:\gtk-build\gtk\x64\release\mingw64\share\icons\hicolor -Destination C:\gtk-build\gtk\x64\release\share\icons\hicolor -Recurse -Force
}
if (Test-Path C:\gtk-build\gtk\x64\release\mingw64\include) {
New-Item -Path C:\gtk-build\gtk\x64\release\include -ItemType Directory -Force | Out-Null
Copy-Item -Path C:\gtk-build\gtk\x64\release\mingw64\include\archive* -Destination C:\gtk-build\gtk\x64\release\include -Recurse -Force
}
if (Test-Path C:\gtk-build\gtk\x64\release\mingw64\lib) {
New-Item -Path C:\gtk-build\gtk\x64\release\lib -ItemType Directory -Force | Out-Null
Copy-Item -Path C:\gtk-build\gtk\x64\release\mingw64\lib\libarchive* -Destination C:\gtk-build\gtk\x64\release\lib -Force
}
if (Test-Path C:\gtk-build\gtk\x64\release\mingw64\bin) {
New-Item -Path C:\gtk-build\gtk\x64\release\bin -ItemType Directory -Force | Out-Null
Copy-Item -Path C:\gtk-build\gtk\x64\release\mingw64\bin\libarchive*.dll -Destination C:\gtk-build\gtk\x64\release\bin -Force
}
if (Test-Path C:\gtk-build\gtk\x64\release\mingw64) {
Remove-Item -Path C:\gtk-build\gtk\x64\release\mingw64 -Recurse -Force
}
Download-WithRetry -Url https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/gendef-20111031.7z -OutFile deps\gendef.7z
& 7z.exe x deps\gendef.7z -oC:\gtk-build
Invoke-WebRequest https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/WinSparkle-20151011.7z -OutFile deps\WinSparkle.7z
Download-WithRetry -Url https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/WinSparkle-20151011.7z -OutFile deps\WinSparkle.7z
& 7z.exe x deps\WinSparkle.7z -oC:\gtk-build\WinSparkle
Invoke-WebRequest https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/perl-5.20.0-${{ matrix.arch }}.7z -OutFile deps\perl-${{ matrix.arch }}.7z
Download-WithRetry -Url https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/perl-5.20.0-${{ matrix.arch }}.7z -OutFile deps\perl-${{ matrix.arch }}.7z
& 7z.exe x deps\perl-${{ matrix.arch }}.7z -oC:\gtk-build\perl-5.20\${{ matrix.platform }}
# Resolve python root from setup-python
$pyRoot = $env:pythonLocation
if (-not $pyRoot) { $pyRoot = & python -c "import sys; print(sys.prefix)" }
# Create BOTH paths because the .vcxproj hard-codes python-3.14\...
foreach ($pyDir in @("C:\gtk-build\python-3.14.2", "C:\gtk-build\python-3.14")) {
New-Item -Path $pyDir -ItemType Directory -Force | Out-Null
$target = Join-Path $pyDir "${{ matrix.platform }}"
@@ -66,9 +116,6 @@ jobs:
New-Item -Path $pyDir -Name "${{ matrix.platform }}" -ItemType Junction -Value $pyRoot | Out-Null
}
python -m pip install --upgrade pip
python -m pip install cffi
- name: Build
run: |
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsDevCmd.bat"
@@ -83,6 +130,8 @@ jobs:
set "LIB=%PYTHON_DIR%\libs;%LIB%"
set "INCLUDE=%PYTHON_DIR%\include;%INCLUDE%"
powershell -NoProfile -ExecutionPolicy Bypass -Command "$archiveLib='C:\gtk-build\gtk\x64\release\lib\libarchive.lib'; if (-not (Test-Path $archiveLib)) { $archiveDll = Get-ChildItem 'C:\gtk-build\gtk\x64\release\bin\libarchive*.dll' | Select-Object -First 1; if ($archiveDll) { Push-Location 'C:\gtk-build\gtk\x64\release\lib'; & 'C:\gtk-build\gendef\gendef.exe' $archiveDll.FullName | Out-Null; $archiveDef = Get-ChildItem 'libarchive*.def' | Select-Object -First 1; if ($archiveDef) { & lib /def:$archiveDef.Name /machine:${{ matrix.platform }} /out:libarchive.lib | Out-Null }; Pop-Location } }"
msbuild win32\zoitechat.sln /m /verbosity:minimal /p:Configuration=Release /p:Platform=${{ matrix.platform }}
shell: cmd

View File

@@ -14,7 +14,6 @@ CONFIG_STAMP := $(BUILD_DIR)/build.ninja
all: build
# Only run initial meson setup if we don't have a configured build dir yet.
$(CONFIG_STAMP):
@mkdir -p $(BUILD_DIR)
@env NINJA=$(NINJA) $(MESON) setup $(BUILD_DIR) --prefix=$(PREFIX) $(MESON_SETUP_ARGS)

View File

@@ -43,10 +43,6 @@ if get_option('gtk-frontend')
install_dir: appdir
)
install_data('net.zoite.Zoitechat.mime.xml',
install_dir: mimedir
)
if desktop_utils.found()
test('Validate net.zoite.Zoitechat.desktop', desktop_utils,
args: [zoitechat_desktop]

View File

@@ -3,7 +3,11 @@
<id>net.zoite.Zoitechat</id>
<name>ZoiteChat</name>
<launchable type="desktop-id">net.zoite.Zoitechat.desktop</launchable>
<developer_name>ZoiteChat</developer_name>
<developer id="net.zoite">
<name translate="no">ZoiteChat</name>
</developer>
<metadata_license>CC0-1.0</metadata_license>
<project_license>GPL-2.0+</project_license>
<translation type="gettext">zoitechat</translation>
@@ -12,7 +16,7 @@
<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">http://zoitechat.zoite.net</url>
<url type="homepage">https://zoitechat.zoite.net</url>
<url type="bugtracker">https://github.com/zoitechat/zoitechat</url>
<url type="help">https://docs.zoitechat.zoite.net/en/latest/</url>
<screenshots>
@@ -36,7 +40,7 @@
</ul>
</description>
</release>
<release date="2026-02-16" version="2.18.0-pre1">
<release date="2026-02-16" version="2.18.0~pre1">
<description>
<p>Packaging and GTK3 improvements:</p>
<ul>
@@ -234,5 +238,5 @@
<content_rating type="oars-1.1">
<content_attribute id="social-chat">intense</content_attribute>
</content_rating>
<update_contact>tingping_at_fedoraproject.org</update_contact>
<update_contact>deepend_at_zoite.net</update_contact>
</component>

View File

@@ -11,7 +11,7 @@ Categories=GTK;Network;IRCClient;
StartupNotify=true
StartupWMClass=net.zoite.Zoitechat
X-GNOME-UsesNotifications=true
MimeType=x-scheme-handler/irc;x-scheme-handler/ircs;application/x-zoitechat-theme;application/x-hexchat-theme;
MimeType=x-scheme-handler/irc;x-scheme-handler/ircs;
Actions=SafeMode;
[Desktop Action SafeMode]

View File

@@ -1,11 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
<mime-type type="application/x-zoitechat-theme">
<comment>ZoiteChat Theme</comment>
<glob pattern="*.zct"/>
</mime-type>
<mime-type type="application/x-hexchat-theme">
<comment>HexChat Theme</comment>
<glob pattern="*.hct"/>
</mime-type>
</mime-info>

521
debian/changelog vendored
View File

@@ -1,521 +0,0 @@
zoitechat (2.18.0~pre2-1) unstable; urgency=medium
* New upstream pre-release 2.18.0~pre2.
* Added HexChat plugin compatibility improvements.
* Fixed user info right-click menu refresh behavior.
* Added support for emoji characters in alert highlight matching.
* Removed remaining unused GTK2 code paths.
-- ZoiteChat Maintainers <zoitechat@users.noreply.github.com> Wed, 25 Feb 2026 02:16:43 +0000
zoitechat (2.18.0~pre1-1) unstable; urgency=medium
* New upstream pre-release 2.18.0~pre1.
* Debian packaging updates in this branch:
- switch package builds to GTK 3 and pass -Dgtk3=true to Meson.
- add/install split-package manifests for generated binary packages.
- include manpage and MIME package XML in package installs.
- adjust CI artifact staging/upload paths for actions/upload-artifact@v4.
-- ZoiteChat Maintainers <zoitechat@users.noreply.github.com> Sun, 16 Feb 2026 00:00:00 +0000
zoitechat (2.17.0-1) unstable; urgency=medium
* Switch Debian build to GTK 3 packaging:
- replace libgtk2.0-dev with libgtk-3-dev in Build-Depends.
- pass -Dgtk3=true to Meson during package builds.
- update package description to explicitly reference GTK 3.
-- ZoiteChat Maintainers <zoitechat@users.noreply.github.com> Sun, 16 Feb 2026 00:00:00 +0000
zoitechat (2.17.0-0) stable; urgency=medium
* Initial ZoiteChat packaging (forked from HexChat's Debian packaging).
* Rename packages/binaries to zoitechat.
* Move Python plugin package to Suggests (known to be unstable in Flatpak builds).
-- ZoiteChat Maintainers <zoitechat@users.noreply.github.com> Wed, 07 Jan 2026 00:00:00 +0000
hexchat (2.16.2-1) unstable; urgency=medium
* Update watch file for new github tarball location
* New upstream version 2.16.2
* Update copyright file
* Update copyright years also for Debian packaging
* Drop patch 0001-Be-even-more-picky-about-invalid-URLs.patch: upstream
* Add three patches from <pabs>:
- Add-channel-context-menu-item-to-close-the-channel,
- Automatically-reconnect-when-there-is-a-TLS-error,
- Do-not-insert-an-extra-space-on-all-lines-when-loading-scrollback-with-colours
-- Gianfranco Costamagna <locutusofborg@debian.org> Sat, 09 Mar 2024 11:51:16 +0100
hexchat (2.16.1-2) unstable; urgency=medium
[ Gianfranco Costamagna ]
* Team upload
[ Debian Janitor ]
* Drop versioned constraint on python3-dev.
[ Sudip Mukherjee ]
* Fix hexchat crash for specific links. (LP: #2029314)
+ This is an upstream cherry-pick
-- Gianfranco Costamagna <locutusofborg@debian.org> Wed, 06 Mar 2024 07:30:56 +0100
hexchat (2.16.1-1) unstable; urgency=medium
* New upstream version 2.16.1.
* Drop all patches, applied upstream.
-- Mattia Rizzolo <mattia@debian.org> Fri, 22 Apr 2022 21:52:27 +0200
hexchat (2.16.0-4) unstable; urgency=medium
* d/copyright: bump copyright year
* Add some patches from upstream, while waiting for the new release:
+ Fix build with OpenSSL 3.
+ Improve the fishlim tests.
+ Fix the URL opening to not double-encode already encoded URLs.
-- Mattia Rizzolo <mattia@debian.org> Mon, 17 Jan 2022 13:26:58 +0100
hexchat (2.16.0-3) unstable; urgency=medium
* Increase the tests timeout even more.
-- Mattia Rizzolo <mattia@debian.org> Sun, 31 Oct 2021 17:45:43 +0100
hexchat (2.16.0-2) unstable; urgency=medium
* Add patch to increase the tests timeout.
* Update our copy of the upstream changelog.
* Recommends:hexchat-lua from hexchat. Closes: #996172
Thanks to Jesse Rhodes <jesse@sney.ca> for the patch!
-- Mattia Rizzolo <mattia@debian.org> Fri, 15 Oct 2021 14:20:31 +0200
hexchat (2.16.0-1) unstable; urgency=medium
[ Mattia Rizzolo ]
* New upstream version 2.16.0.
+ Drop all patches applied upstream.
+ Refresh the patches tweaking the default channels/networks.
* Refresh the upstream signing key.
* Update copyright.
* Drop our patch renaming the Python plugin into Python3.
There doesn't seem to be any transition needed.
* d/control:
+ Drop Build-Depends on libnotify-dev and libproxy-dev,
not used anymore starting with v2.16.
+ Have hexchat-python3 Depend on python3-cffi-backend;
seems like I missed this dependency since v2.14.3-4.
+ Bump Standards-Version to 4.6.0, no changes needed.
[ Debian Janitor ]
* Remove constraints unnecessary since buster:
* Build-Depends: Drop versioned constraint on meson.
-- Mattia Rizzolo <mattia@debian.org> Mon, 04 Oct 2021 17:12:52 +0200
hexchat (2.14.3-6) unstable; urgency=medium
* Add Recommends:ca-certificates.
* Add patches from upstream to add Libera.Chat to the network list.
* Adapt default servers patches for the upstream changes.
* Ubuntu default server: LP: #1933681
+ Change from Freenode to Libera.Chat.
+ Pre-select the "join channel" button, like we do in Debian.
-- Mattia Rizzolo <mattia@debian.org> Wed, 26 May 2021 14:55:10 +0200
hexchat (2.14.3-5) unstable; urgency=medium
* Bump copyright for 2021.
* Apply patch from upstream to fix font height calculation with Pango>=1.44.
LP: #1920974
-- Mattia Rizzolo <mattia@debian.org> Sat, 02 Jan 2021 16:31:39 +0100
hexchat (2.14.3-4) unstable; urgency=medium
[ Debian Janitor ]
* Set upstream metadata fields: Bug-Submit.
[ Mattia Rizzolo ]
* Bump Standards-Version to 4.5.1, no changes needed.
* Bump debhelper compat version to 13.
+ Drop dh_missing override, now that --fail-missing is the default.
* Add a patch series from upstream to refactor the whole Python plugin,
using CFFI. This fixes support for Python 3.9. Closes: #975393
+ Replace my naive patch to fix the build with Python 3.8, using instead
the fix that comes from upstream.
+ Install the new files produced by cffi.
+ Add new Build-Depends python3-cffi.
-- Mattia Rizzolo <mattia@debian.org> Wed, 16 Dec 2020 22:03:57 +0100
hexchat (2.14.3-3) unstable; urgency=medium
* Add patch to use the new -embed variant of python3.pc.
Fix linking with Python 3.8. LP: #1866081
* Swap the Recommends:hwdata with Recommends:pci.ids. Closes: #953300
* Bump Standards-Version to 4.5.0, no changes needed.
-- Mattia Rizzolo <mattia@debian.org> Wed, 11 Mar 2020 17:08:25 +0100
hexchat (2.14.3-2) unstable; urgency=medium
[ Gianfranco Costamagna ]
* Refresh the Ubuntu servlist patch.
[ Mattia Rizzolo ]
* Import patch from upstream (from James Clarke) to properly prioritize
MODE commands, that were delaying PINGs in some cases.
[ Debian Janitor ]
* Set upstream metadata fields: Bug-Database, Repository,
Repository-Browse.
-- Mattia Rizzolo <mattia@debian.org> Thu, 02 Jan 2020 09:46:24 +0100
hexchat (2.14.3-1) unstable; urgency=medium
* New upstream version 2.14.3.
+ Drop patches applied upstream.
* d/control:
+ Bump build-dependency on meson to >= 0.40.
+ Bump Standards-Version to 4.4.1, no changes needed.
* Update the boundled upstream docs.
-- Mattia Rizzolo <mattia@debian.org> Tue, 31 Dec 2019 15:24:45 +0100
hexchat (2.14.2-5) unstable; urgency=medium
* Stop building the Python2 plugin. Closes: #936697
Simplify the patch used to build py2 and py3; we need to keep it because
we used to rename the 'python' plugin to 'python3'. We should check if
some kind of transition should be done to go back to the upstream
defaults.
* d/control:
+ Drop a bunch of old Breaks/Replaces that shouldn't be needed anymore.
+ Bump Standards-Version to 4.4.0, no changes needed.
+ Bump debhelper compat level to 12, no changes needed.
-- Mattia Rizzolo <mattia@debian.org> Sat, 31 Aug 2019 11:57:51 +0200
hexchat (2.14.2-4) unstable; urgency=medium
* Add a patch to fix a probable crash while unloading the Python plugin
when using Python 3.7. LP: #1830246; Closes: #921208
-- Mattia Rizzolo <mattia@debian.org> Sat, 25 May 2019 11:48:26 +0200
hexchat (2.14.2-3) unstable; urgency=medium
[ Ondřej Nový ]
* d/copyright: Change Format URL to correct one.
[ Mattia Rizzolo ]
* Move the patches tweaking the default servers out of d/patches, and inject
them through d/rules. The ctte decided that vendored series files are not
allowed in the Debian archive, see #904302. Closes: #915350
-- Mattia Rizzolo <mattia@debian.org> Mon, 03 Dec 2018 14:17:35 +0100
hexchat (2.14.2-2) unstable; urgency=medium
* Add patch to fix FTBFS on !linux.
* d/control: Use the new debhelper-compat(=11) build-dep and drop d/compat.
-- Mattia Rizzolo <mattia@debian.org> Sun, 23 Sep 2018 20:38:39 +0200
hexchat (2.14.2-1) unstable; urgency=medium
* New upstream version 2.14.2.
* d/patches:
+ Drop patches applied upstream.
+ Refresh remaining patches.
* d/control: Bump Standards-Version to 4.2.1, no changes needed.
-- Mattia Rizzolo <mattia@debian.org> Sat, 01 Sep 2018 22:28:20 +0200
hexchat (2.14.1-2) unstable; urgency=medium
* Add some patches from upstream:
+ upstream/0003-Remove-shift-click-to-close-tab-binding.patch
- LP: #1756402
+ upstream/0004-build-Add-metainfo-files-for-addons.patch
+ upstream/0005-build-Fix-id-in-plugin-metainfo-files.patch
+ upstream/0006-build-Correctly-set-plugin-licenses.patch
+ upstream/0007-build-Re-add-support-for-the-legacy-perl-api.patch
+ upstream/0008-Deiconify-window-on-tray-click.-Closes-2136.patch
* Fixup our py2+py3 patch after the above patches have been applied.
* Install the new metainfo files representing the various plugins.
-- Mattia Rizzolo <mattia@debian.org> Tue, 20 Mar 2018 16:10:27 +0100
hexchat (2.14.1-1) unstable; urgency=medium
* New upstream version 2.14.1.
* Drop all patches applied upstream.
-- Mattia Rizzolo <mattia@debian.org> Wed, 14 Mar 2018 03:35:41 +0100
hexchat (2.14.0-1) unstable; urgency=medium
* New upstream version 2.14.0. Closes: #892085
* Refresh patches:
+ drop 4c178782a779f013fafab476506f7d4dae372b8a.patch, applied upstream.
+ Rewrite the local patch used to build for both python2 and python3 after
the change of build system upstream.
+ Add all the commits from upstream after the release:
- 0003-build-Remove-pie-from-global-ldflags.patch
- 0004-Fix-fscanf-usage-without-size-limit.patch
- 0005-fix-typo-in-comment.patch
- 0006-Revert-xtext-Always-use-Pango-to-get-correct-glyph-w.patch
* d/control:
+ Update build dependencies for the new upstream:
- New build-deps: gettext, iso-codes, liblua5.3-dev, meson (>= 0.38).
- Drop build-deps: dh-lua, intltool, libtool.
- Drop version restriction from libgtk2.0-dev (>= 2.10.0).
+ Set Rules-Requires-Root:no.
* d/changelog.txt: Update from upstream.
* d/hexchat.install: Slightly update the paths.
* d/rules:
+ Drop override_dh_install not needed anymore with meson.
+ Explicitly build with lua 5.3. The new build system defaults on luajit
only now.
* d/copyright: Update.
-- Mattia Rizzolo <mattia@debian.org> Wed, 14 Mar 2018 02:36:37 +0100
hexchat (2.12.4-6) unstable; urgency=medium
* d/control:
+ Move packaging to salsa.debian.org.
+ Replace recomendency on gvfs-bin to libglib2.0-bin. Closes: #877746
+ Bump Standards-Version to 4.1.3, no changes needed.
* d/copyright: Bump copyright years for debian/*.
* d/rules: Replace dh_install --fail-missing by dh_missing.
* d/watch: Use HTTPS.
* Bump debhelper compat level to 11.
-- Mattia Rizzolo <mattia@debian.org> Sat, 24 Feb 2018 18:26:41 +0100
hexchat (2.12.4-5) unstable; urgency=medium
* Add a short description to the previous changelog entry on how to manually
preserve the scrollback that would otherwise get lost.
* Remove the patch also for Ubuntu (fixing FTBFS there).
* d/control:
+ Add a bunch of Multi-Arch:same notation, suggested by the M-A hinter.
+ Remove the transitional package hexchat-python.
-- Mattia Rizzolo <mattia@debian.org> Sat, 15 Jul 2017 18:34:27 +0200
hexchat (2.12.4-4) unstable; urgency=medium
* Stop reverting upstream commit 15600f405f2d5bda6ccf0dd73957395716e0d4d3.
This means users will lose their scrollback right after updating, but
that's what upstream did and we have no real reasons to undefinitely
diverge from them just to wait for a nicer fix.
Closes: #852275; CVE-2016-2087
For users who care about their scrollback, it's enough to manually rename
the directories in ~/.config/hexchat/scrollback to all-lowercase characters
before restarting hexchat after the update.
* d/control: Bump Standards-Version to 4.0.0, no changes needed
* d/copyright: bump my copyright year for debian/ to cover 2017
-- Mattia Rizzolo <mattia@debian.org> Fri, 14 Jul 2017 16:12:32 +0200
hexchat (2.12.4-3) unstable; urgency=medium
* Demote hexchat-otr from Recommends to Suggests.
It reportely causes noise and problems for unexperienced users, and it's
a mostly unmaintained plugin, so don't install it by default.
-- Mattia Rizzolo <mattia@debian.org> Tue, 30 May 2017 21:50:09 +0200
hexchat (2.12.4-2) unstable; urgency=medium
* Also apply patch 4c178782a779f013fafab476506f7d4dae372b8a.patch on ubuntu.
* d/p/0001-Debian-server-defaults.patch: Add missing braces around the `if`.
Thanks to Lauri Alanko <la@iki.fi> for the patch. Closes: #779892
-- Mattia Rizzolo <mattia@debian.org> Thu, 26 Jan 2017 09:54:41 +0100
hexchat (2.12.4-1) unstable; urgency=medium
* New upstream version 2.12.4.
* d/copyright: update (removal of the doat plugin).
* d/watch: improve:
+ Bump version to 4.
+ Use substitution strings @ANY_VERSION@ and @ARCHIVE_EXT@.
+ Ignore version 2.12.4-repack by mangling it into 2.12.4.
* d/control: mark hexchat-dev and hexchat-lua as Multi-Arch:same.
* d/patches/:
+ openssl/*: drop, applied upstream.
+ clean.patch: drop, applied upstream.
+ 4c178782a779f013fafab476506f7d4dae372b8a.patch: include from upstream to
work around a gdk-pixbuf bug which would prevent the hexchat icon from
being displayed in panels/systrays. Closes: #848615
* d/rules: add a 'udoc' target to update the bundled copy of upstream doc.
* Update upstream documentation.
* d/hexchat-plugins.install: upstream converted the 'doat' plugin into an
internal command, so stop trying to install the plugin.
-- Mattia Rizzolo <mattia@debian.org> Mon, 26 Dec 2016 01:16:19 +0100
hexchat (2.12.3-4) unstable; urgency=medium
* Re-enable Lua support everywhere now that #845929 is fixed.
-- Mattia Rizzolo <mattia@debian.org> Mon, 19 Dec 2016 12:47:31 +0100
hexchat (2.12.3-3) unstable; urgency=medium
* Actually disable Lua support when building.
-- Mattia Rizzolo <mattia@debian.org> Mon, 05 Dec 2016 16:03:26 +0100
hexchat (2.12.3-2) unstable; urgency=medium
* Temporary restrict the build of hexchat-lua to the architectures where lua
is usable right now (see #845929).
-- Mattia Rizzolo <mattia@debian.org> Mon, 05 Dec 2016 14:02:40 +0100
hexchat (2.12.3-1) unstable; urgency=medium
[ Jesse Rhodes ]
* Add hexchat-dev package for .pc and .h files.
* Include dbus service file in hexchat-common.
[ Mattia Rizzolo ]
* Take over maintenance from Jasse Rhodes.
Thank you for all your work these years! Closes: #844574
* debian/control:
+ wrap-and-sort -ast.
+ Bump Standards-Version to 3.9.8, no changes needed.
+ Add proper Breaks/Replaces for the hexchat-dev addition-
+ Have hexchat-plugins recommend hwdata for the sysinfo plugin.
Closes: #845940
+ Have hexchat recommend the hexchat-otr plugin.
Thanks to Petter Reinholdtsen <pere@hungry.com> for the suggestion
+ Bump the Breaks/Replaces of hexchat-plugins against hexchat;
hexchat-plugin.pc has been moved from hexchat to hexchat-plugins
in 2.12.0-1. LP: #1586239
+ Set appropriate Breaks/Replaces to cope with the Ubuntu delta and
make the package syncable.
+ Mark hexchat-common as Multi-Arch:foreign (from the m-a hinter).
* debian/rules:
+ Remove huge override_dh_auto_clean: if anything of that is needed,
it should be done on the upstream side.
+ Remove *.la files before running dh_install.
+ Use dh_install --fail-missing.
* Package the Lua plugin. Closes: #834491
* Update upstream changelog for 2.13.2.
* Use dh_installchangelogs to install the upstream changelog, instead of
manually compressing in rules and the install with d/*.docs.
* Let the upstream build system put the manpage in place, instead of copying
it of our own.
* Add patch to properly clean the upstream sources and make possible to build
the package twice in a row.
* Bump debhelper compat level to 10.
+ --with autoreconf is now default.
* debian/copyright:
+ Make it DEP-5 compliant.
+ Update.
* Drop nearly all lintian overrides; they are either fixed or unused.
-- Mattia Rizzolo <mattia@debian.org> Thu, 01 Dec 2016 18:30:03 +0100
hexchat (2.12.3-0.1) unstable; urgency=medium
* Non-maintainer upload, with maintainer ACK.
[ Jesse Rhodes ]
* Fixed vcs-git url.
[ Mattia Rizzolo ]
* Imported Upstream version 2.12.3. Closes: #836809
* Refresh patches
* d/rules: disable LUA bindings, as they would require a new binary package.
* Add several patches from upstream to add support to OpenSSL 1.1.0.
Closes: #828339
* Revert upstream commit 15600f405f2d5bda6ccf0dd73957395716e0d4d3, which
would cause users to lose their scrollback.
-- Mattia Rizzolo <mattia@debian.org> Sun, 27 Nov 2016 13:41:25 +0100
hexchat (2.12.0-2) unstable; urgency=medium
* Removed patch correcting for missing translations,
as translations are no longer missing
* Removed patch correcting spelling error that would break
some scripts and themes
* Updated ubuntu server/channel defaults
-- Jesse Rhodes <drubo@drubo.net> Wed, 30 Mar 2016 11:44:04 -0600
hexchat (2.12.0-1) unstable; urgency=medium
* New upstream release
* Iceweasel no longer called Firefox in url dialog
* Building both python2 and python3 plugins
* Including hexchat-plugin.pc (Closes: 801767)
-- Jesse Rhodes <drubo@drubo.net> Fri, 25 Mar 2016 10:54:57 -0600
hexchat (2.10.2-1) unstable; urgency=medium
* New upstream release
* Includes upstream fixes for POODLE vulnerability
(CVE-2014-3566)
* Split plugins into modular packages rather than having all
binaries in the main hexchat package
-- Jesse Rhodes <drubo@drubo.net> Fri, 28 Nov 2014 18:35:39 -0700
hexchat (2.10.1-2) unstable; urgency=medium
* Fix ubuntu_defaults.patch (LP: #1390851)
* Disable SSLv3
-- Jesse Rhodes <drubo@drubo.net> Sun, 16 Nov 2014 11:47:12 -0700
hexchat (2.10.1-1) unstable; urgency=medium
* New upstream release
* No longer build-depend on libsexy-dev
* URL handler dialog now labeled Iceweasel rather than Firefox
-- Jesse Rhodes <drubo@drubo.net> Mon, 18 Aug 2014 21:18:55 -0600
hexchat (2.10.0-1) unstable; urgency=medium
* New upstream release
* Removed patches for issues fixed by upstream
* Added default servers and recommended channels for debian
and ubuntu (LP: #1294415)
* Upstream commit fa955a0f fixes xdcc segfault (Closes: #745764)
-- Jesse Rhodes <drubo@drubo.net> Sun, 01 Jun 2014 16:45:22 -0600
hexchat (2.9.6.1-2) unstable; urgency=low
* Now using dh-autoreconf instead of autotools-dev (Closes: #739630)
* Added gvfs-bin as Recommends so default url handlers work
(Closes: #740006)
* Added unifont as Suggests for unicode symbol support
* Included png,svg icons in package
-- Jesse Rhodes <drubo@drubo.net> Tue, 25 Feb 2014 16:45:42 -0700
hexchat (2.9.6.1-1) unstable; urgency=low
* Initial release (Closes: #702075)
-- Jesse Rhodes <drubo@drubo.net> Mon, 03 Feb 2014 19:09:17 -0700

126
debian/control vendored
View File

@@ -1,126 +0,0 @@
Source: zoitechat
Section: net
Priority: optional
Maintainer: ZoiteChat Maintainers <zoitechat@users.noreply.github.com>
Build-Depends:
debhelper-compat (= 13),
gettext,
iso-codes,
libcanberra-dev,
libdbus-glib-1-dev,
libglib2.0-dev,
libgtk-3-dev,
liblua5.3-dev,
libpci-dev,
libperl-dev,
libssl-dev,
meson,
python3-cffi,
python3-dev
Standards-Version: 4.6.0
Rules-Requires-Root: no
Vcs-Git: https://github.com/zoitechat/zoitechat.git
Vcs-Browser: https://github.com/zoitechat/zoitechat
Homepage: https://zoitechat.zoite.net
Package: zoitechat
Architecture: any
Depends:
zoitechat-common (= ${binary:Version}),
${misc:Depends},
${shlibs:Depends}
Recommends:
ca-certificates,
zoitechat-lua,
zoitechat-perl,
zoitechat-plugins,
libglib2.0-bin
Suggests:
zoitechat-python3,
zoitechat-otr,
unifont
Description: IRC client for GNOME (fork of HexChat 2.18.0~pre2 base)
ZoiteChat is a graphical IRC client with a GTK 3 GUI. Features include Python,
Perl and Lua scripting support, a plugin API, multiple server/channel
windows, spell checking, multiple authentication methods including SASL, and
customizable notifications. For more information on IRC, see
http://irchelp.org/.
Package: zoitechat-common
Architecture: all
Multi-Arch: foreign
Provides: irc-client
Depends: ${misc:Depends}
Recommends:
ca-certificates,
zoitechat-lua,
zoitechat-perl,
zoitechat-plugins,
libglib2.0-bin
Suggests:
zoitechat,
zoitechat-python3,
zoitechat-otr,
unifont
Description: Common data files for ZoiteChat
This package includes architecture-independent files for ZoiteChat, such as
translations, desktop integration, and shared data.
Package: zoitechat-perl
Architecture: any
Multi-Arch: same
Depends:
zoitechat (= ${binary:Version}),
${misc:Depends},
${shlibs:Depends}
Description: Perl plugin for ZoiteChat
This package contains the Perl plugin for ZoiteChat. It is split out from the
main package because it is optional.
Package: zoitechat-python3
Architecture: any
Multi-Arch: same
Depends:
zoitechat (= ${binary:Version}),
python3-cffi-backend,
${misc:Depends},
${shlibs:Depends}
Description: Python 3 plugin for ZoiteChat
This package contains the Python 3 plugin for ZoiteChat. It is split out from
the main package because it is optional.
.
Known issue: the Python plugin may freeze the client in some builds.
Package: zoitechat-lua
Architecture: any
Multi-Arch: same
Depends:
zoitechat (= ${binary:Version}),
${misc:Depends},
${shlibs:Depends}
Description: Lua plugin for ZoiteChat
This package contains the Lua plugin for ZoiteChat. It is split out from the
main package because it is optional.
Package: zoitechat-plugins
Architecture: any
Multi-Arch: same
Depends:
zoitechat (= ${binary:Version}),
${misc:Depends},
${shlibs:Depends}
Suggests: pciutils
Description: Extra plugins for ZoiteChat
This package contains optional plugins (e.g. FiSHLiM, Sysinfo, Do At and
Checksum). These are split out from the main package because they are not
required for core functionality.
Package: zoitechat-dev
Architecture: any
Multi-Arch: same
Depends:
zoitechat-common (= ${binary:Version}),
${misc:Depends}
Description: Development files for ZoiteChat plugins
This package contains zoitechat-plugin.h and zoitechat-plugin.pc, which
facilitate building binary plugins for ZoiteChat.

188
debian/copyright vendored
View File

@@ -1,188 +0,0 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: zoitechat
Source: https://zoitechat.zoite.net
Files: *
Copyright: 1998-2010 Peter Zelezny
2009-2013 Berke Viktor
2015-2021 Patrick Griffis
License: GPL-2+ with OpenSSL exception
Files: debian/*
Copyright: 2014 Jesse Rhodes <drubo@drubo.net>
2016-2022 Mattia Rizzolo <mattia@debian.org>
2020-2024 Gianfranco Costamagna <locutusofborg@debian.org>
License: GPL-2+
Files: data/man/zoitechat.1.in
Copyright: Davide Puricelli <evo@debian.org>
License: GPL-2+
Files: osx/gtkrc
Copyright: 2012 Xamarin Inc.
License: GPL-2+
Files: plugins/checksum/* plugins/exec/*
Copyright: 2010-2012 Berke Viktor
License: Expat
Files: plugins/fishlim/*
Copyright: 2010 Samuel Lidén Borell <samuel@kodafritt.se>
2015 <the.cypher@gmail.com>
2019-2020 <bakasura@protonmail.ch>
License: Expat
Files: plugins/lua/*
Copyright: 2015-2016 mniip
License: Expat
Files: plugins/perl/*
Copyright: 1998-2002 Peter Zelezny
License: GPL-2+
Files: plugins/python/*
Copyright: 2002-2003 Gustavo Niemeyer <niemeyer@conectiva.com>
License: GPL-2+
Files: plugins/sysinfo/*
Copyright: 2003-2005 Michael Shoup
2005-2007 Tony Vroon
2012 Berke Viktor
2015 Patrick Griffis
License: GPL-2+
Files: plugins/winamp/*
Copyright: Leo <leo.nard@free.fr>
Silverex <SilvereX@karklas.mif.vu.lt>
Derek Buitenhuis <daemon404@gmail.com>
Berke Viktor <berkeviktor@aol.com>
License: GPL-1.0
Files: src/common/dbus/*
Copyright: 2006 Claessens Xavier
License: GPL-2+
Files: src/common/dbus/example.py
Copyright: 1998-2010 Peter Zelezny
2009-2013 Berke Viktor
License: GPL-2+
Files: src/common/scram.*
Copyright: 2023 Patrick Okraku
License: GPL-2+
Files: src/common/ssl.c
Copyright: 2000 DaP <profeta@freemail.c3.hu>
License: GPL-2+ with OpenSSL exception
Files: src/dirent/dirent-win32.h
Copyright: 2006-2012 Toni Ronkko
License: Expat
Files: src/fe-gtk/sexy-iso-codes.c src/fe-gtk/sexy-iso-codes.h
Copyright: 2008 Novell, Inc.
2013 Sandro Mani
License: GPL-2+
Files: src/fe-gtk/sexy-spell-entry.c src/fe-gtk/sexy-spell-entry.h
Copyright: 2002 Evan Martin
2004-2006 Christian Hammond
License: LGPL-2.1+
License: GPL-2+ with OpenSSL exception
This package is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
.
This package is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License
along with this package; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
.
On Debian systems, the complete text of the GNU General
Public License can be found in `/usr/share/common-licenses/GPL-2'.
.
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
You must obey the GNU General Public License in all respects for all of
the code used other than OpenSSL. If you modify file(s) with this
exception, you may extend this exception to your version of the file(s),
but you are not obligated to do so. If you do not wish to do so, delete
this exception statement from your version. If you delete this exception
statement from all source files in the program, then also delete it here.
License: Expat
.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
.
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
License: GPL-2+
This package is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
.
This package is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License
along with this package; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
.
On Debian systems, the complete text of the GNU General
Public License can be found in `/usr/share/common-licenses/GPL-2'.
License: GPL-1.0
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
02110-1301, USA.
License: LGPL-2.1+
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA

View File

@@ -1,40 +0,0 @@
Description: Changed default network to OFTC,
suggests to join #debian on OFTC and Freenode
diff --git a/src/common/servlist.c b/src/common/servlist.c
index a203e702..22fcd92b 100644
--- a/src/common/servlist.c
+++ b/src/common/servlist.c
@@ -902,7 +902,7 @@ servlist_load_defaults (void)
{
int i = 0, j = 0;
ircnet *net = NULL;
- guint def_hash = g_str_hash ("Libera.Chat");
+ guint def_hash = g_str_hash ("OFTC");
while (1)
{
diff --git a/src/fe-gtk/joind.c b/src/fe-gtk/joind.c
index ce3cbcae..7f6b1116 100644
--- a/src/fe-gtk/joind.c
+++ b/src/fe-gtk/joind.c
@@ -247,10 +247,18 @@ joind_show_dialog (server *serv)
G_CALLBACK (joind_ok_cb), serv);
if (serv->network)
+ {
+ if (g_ascii_strcasecmp(((ircnet*)serv->network)->name, "OFTC") == 0)
+ {
+ gtk_entry_set_text (GTK_ENTRY (entry1), "#debian");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(radiobutton2), TRUE);
+ }
if (g_ascii_strcasecmp(((ircnet*)serv->network)->name, "Libera.Chat") == 0)
{
- gtk_entry_set_text (GTK_ENTRY (entry1), "#hexchat");
+ gtk_entry_set_text (GTK_ENTRY (entry1), "#debian");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(radiobutton2), TRUE);
}
+ }
gtk_widget_grab_focus (okbutton1);
gtk_widget_show_all (dialog1);

View File

@@ -1,43 +0,0 @@
Description: Changed default channel to join from #hexchat to #ubuntu
Also adds a "Ubuntu servers" entry, same as connecting to libera.chat.
diff --git a/src/common/servlist.c b/src/common/servlist.c
index a203e702..18a6c4b3 100644
--- a/src/common/servlist.c
+++ b/src/common/servlist.c
@@ -206,6 +206,9 @@ static const struct defaultserver def[] =
{"Libera.Chat", 0, 0, 0, LOGIN_SASL, 0, TRUE},
{0, "irc.libera.chat"},
+ {"Ubuntu Servers (Libera.Chat)", 0, 0, 0, LOGIN_SASL, 0, TRUE},
+ {0, "irc.libera.chat"},
+
#ifdef USE_OPENSSL
{"LibertaCasa", 0, 0, 0, LOGIN_SASL, 0, TRUE},
{0, "irc.liberta.casa"},
@@ -902,7 +905,7 @@ servlist_load_defaults (void)
{
int i = 0, j = 0;
ircnet *net = NULL;
- guint def_hash = g_str_hash ("Libera.Chat");
+ guint def_hash = g_str_hash ("Ubuntu Servers (Libera.Chat)");
while (1)
{
diff --git a/src/fe-gtk/joind.c b/src/fe-gtk/joind.c
index ce3cbcae..e94e562a 100644
--- a/src/fe-gtk/joind.c
+++ b/src/fe-gtk/joind.c
@@ -247,9 +247,10 @@ joind_show_dialog (server *serv)
G_CALLBACK (joind_ok_cb), serv);
if (serv->network)
- if (g_ascii_strcasecmp(((ircnet*)serv->network)->name, "Libera.Chat") == 0)
+ if (g_ascii_strcasecmp(((ircnet*)serv->network)->name, "Ubuntu Servers (Libera.Chat)") == 0)
{
- gtk_entry_set_text (GTK_ENTRY (entry1), "#hexchat");
+ gtk_entry_set_text (GTK_ENTRY (entry1), "#ubuntu");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(radiobutton2), TRUE);
}
gtk_widget_grab_focus (okbutton1);

View File

@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop-application">
<id>net.zoite.Zoitechat</id>
<name>ZoiteChat</name>
<summary>IRC client for GNOME</summary>
<metadata_license>CC0-1.0</metadata_license>
<project_license>GPL-2.0-or-later</project_license>
<description>
<p>ZoiteChat is a graphical IRC client based on HexChat.</p>
<p>Current Flatpak builds have a known issue where the Python plugin can freeze the client.</p>
</description>
<launchable type="desktop-id">net.zoite.Zoitechat.desktop</launchable>
<provides>
<binary>zoitechat</binary>
</provides>
<url type="homepage">https://zoitechat.zoite.net/</url>
</component>

View File

@@ -1 +0,0 @@
readmechanges.patch

22
debian/rules vendored
View File

@@ -1,22 +0,0 @@
#!/usr/bin/make -f
export DH_VERBOSE=1
%:
dh $@ --buildsystem=meson
override_dh_auto_configure:
dh_auto_configure -- \
-Dinstall-plugin-metainfo=false \
-Dwith-lua=lua53
override_dh_installchangelogs:
install -m0755 -d \
debian/zoitechat/usr/share/doc/zoitechat \
debian/zoitechat-common/usr/share/doc/zoitechat-common \
debian/zoitechat-perl/usr/share/doc/zoitechat-perl \
debian/zoitechat-python3/usr/share/doc/zoitechat-python3 \
debian/zoitechat-lua/usr/share/doc/zoitechat-lua \
debian/zoitechat-plugins/usr/share/doc/zoitechat-plugins \
debian/zoitechat-dev/usr/share/doc/zoitechat-dev
dh_installchangelogs changelog.rst

View File

@@ -1 +0,0 @@
3.0 (quilt)

View File

@@ -1,2 +0,0 @@
# the upstream maintainer says that he doesn't have time to go fish out his GPG key for now
orig-tarball-missing-upstream-signature

View File

@@ -1,4 +0,0 @@
Bug-Database: https://github.com/zoitechat/zoitechat/issues
Bug-Submit: https://github.com/zoitechat/zoitechat/issues/new
Repository: https://github.com/zoitechat/zoitechat.git
Repository-Browse: https://github.com/zoitechat/zoitechat

View File

@@ -1,72 +0,0 @@
pub rsa4096 2014-02-13 [SC] [expires: 2024-02-08]
108BF2212A051F4A72B18448B3C7CE210DE76DFC
uid [ unknown] Patrick Griffis <tingping@tingping.se>
uid [ unknown] TingPing <tingping@fedoraproject.org>
sub rsa4096 2014-02-13 [E] [expires: 2024-02-08]
C6CAF2A624B9C2ECBF83ACBF488A9319DABACE61
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBFL9JHIBEADDKL+vc3MHctXCWxG0IcuLPm4i+WO9jH6MdF8p2bokaL5lilcJ
o2i0RHImP83FpqCDj/hE7AeB3Ix3Oq3tIe6lpCz468OVbLivErX/yL8rYUhC+yba
zlSJcBipTIezD3pZI/vpFyCIC8mSEI4PJGiLotioNJWQBStQuuPqMKo4cd6cRWx6
WovQMKa85rQPvv+wYCseBqU6xBx1xSgpkjDJnAH7We5G6T8TYVM2gqXtii/JYyUC
8E7Z2BBdSGkq1Dma1W6paOw7VOtLu6YbAH9v/VUVx0UdzwiyXHQ8qLKbxeXkex9d
zoe+oy8wt3bvVHirxU42IlJJVLY4NcUYhr/xOq/YqT+3sWAqgdVM/WnzY3bPiMnQ
XqQ3UZ0LKXXsF2+9u2qM6FTiAHIMLtH95IlOQo1qXmDl1HRJTNq3B41UduLDRUhP
uGBaXbOtb6ql4nV3/BTxcHumisMh5ALhqXHRNOdn+mEjvT2HT6pp07ZfVhFwM4U0
K78f52S+NppiS0cWtn9ibq+UmqZyvw9HMOHYt51lSUOueg/sOvsxrG1gjvcUMlJw
nCgS3b+QUmZYo+pl/l13fiWPQpteVGZqKPMBBaQ4MCrwHgvikN8uppKDw8fFGs44
LgbCsDoQA8wKxNzMEMTvuhFFgCiOxMCzR0XKxlcKr8CiHZjYwovJLFfLvwARAQAB
tCVUaW5nUGluZyA8dGluZ3BpbmdAZmVkb3JhcHJvamVjdC5vcmc+iQJVBBMBAgA/
AhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgBYhBBCL8iEqBR9KcrGESLPHziEN
5238BQJcXuBtBQkSx717AAoJELPHziEN5238pfAP/331a2PASeS1toBRNbMVyXcB
8zEb5Q4MFiTmgy7aOOo2MDzV4VBiYEUa93pmWrozWudqZl1u+Cm7XC0Kxv7b6HRC
/2UBDKY0FUk7xALFQN+XycNDweflT9SlJ+4IcgfHX3/FcF0Obl0fnNfr8DXXqdsj
hxWqlXRkyvRC8VuJJkkufi4CxUBQPSSG+dGgskACP6e210rogPq7LyUIMKkKqKSV
69RUHDJZOsObNA6q1gTNcb8G/lIGaqbVTJ/d+6X/iDkgMrxRi++OyAUa7aXMHGBn
5PnFjqPKBP7qrEEl1nA0LcXhr1hCEVVXGosuqR1WjbbyOTOq50oGvk8zbTy/1mOc
UwkJYbaMv20wAYXx9QSbYoTDMx+DXrB3NCtBHeM7o9igoom8n9khoVmC1SPMOsQM
1xLAk22RuyeDw3C3K3xoar4tcrwXKRmTyUxDBvkR7gtySiAKWFZOEPbeeRzprpG+
Fg48Zh7buqh3Rdk5rmXOeATbyRq9+D0p6WhtO6UdEbi9yNCGo/eTTs2a9CcxfW6E
7gGrX/wP6eKrP7KiT5NqcM01R961IxRpNLM0Uy15Jf5paP9VoJBtR0hO+94Vc9ZJ
jS9yv5iJ62FIqSkqXZ7v+59XFZjm84pI7ywHuzjv9poBi3W19jM1eyYeryLj8362
w2z5UgLfllZv1o2NTLx6tCZQYXRyaWNrIEdyaWZmaXMgPHRpbmdwaW5nQHRpbmdw
aW5nLnNlPokCVAQTAQgAPgIbAwULCQgHAgYVCAkKCwIEFgIDAQIeAQIXgBYhBBCL
8iEqBR9KcrGESLPHziEN5238BQJcXuBtBQkSx717AAoJELPHziEN5238J9cP/3SX
UCZBFKf79LUfKVOxZYgAMKzL2CQdglNKrtE0aqMJwga6AUrSLEBWUqKHOFrcWYDi
qKldpWGWv52lSlZL4YCIcgymOyYMbjQXkHUUaAH4tCzjT0yhFKKAAokJKBSinaO4
cA6i3p3XdyUWbvjqnc8/2Mn31cyxiqj58EN5r7naS/5DaD+0q2dxhLW5/A+IKukk
l12NhMpDbTkQ18brttBMCW5h5LPR7HDN5hVPCztj4BN5JqPeMyspemvGMT6G12vA
5N+S83rAushIyu8Y88iKhPsNLbLgi3PCOZJDKeNlqdPoXJX7mau41U08/8NiORUP
R4Dj9942c6rdHHXDyZ3puvsVK0YjwcmG5uSdG2tpyhNOBiyNQXgpPVHU5YKTob75
vGs4uuxKYxNns/UULiC4fp/gGOIRh9f0veJG2DbMnEHXhnpQzIbsYSo1yeJ+8vFM
FhbkHlylrkTUtOzQwFqybhgYGbfDvT4weMvCc9jEQXfIfI39/Tjx/JD0VVKu577X
oZhtsb4rX2qEmiEnMrWAMM97LGyCNEi6DJipHse4Z5cc54/VswGF8Ze4VYF5hF8o
DaIQfGXmuceMS3l4FXK0x6CYKpr7e0pY3zrsGIJ8Zwd11T9ubilAvK68Ix7j1puJ
x8/ZD9NYP/NUNpriRVyFNiPlfKRqauDBnSKjiTiguQINBFL9JHIBEACx1FJWBK1R
ORu+rHa52Uc0+Jkcr791A10Itwyv6fsA0RT6moob6s8Rvet8NQH6SZVRqiGy3d8g
lxnedT32ZxHWRoLC8Pc6PnQhVXB3RSZoE9VVm9z+7nHOGXXCj0a0OsgyGSHLerE9
7MvlMlkf2EsOTj6irZZDvJH4Eblbk1WzC4K5EC5r7FL/4sdHLbDWEUR3wemC7s0n
9IusHwNBiTSSxpag/dq9+6eVyoA3opsqSU3wlSqfm3U/0G3MG4JkwDmS3nK4hmmq
nCakdXZaqKZDGZjfaztTuO5RP73KfNHSNfsreOXY3ldX7Jy1qdHp/hBp6CFXhHul
d4ZyWL+O6uMRcNQdfd/b8VBDe3z2LYw3AHnhjAnmwJqjfnhH3r7ibM2+HAtrj8J5
Qwe/28QJOR3UfT1+tYW8I0bpnBesfzgm9Vp2t3IzkaGdXQOsB9KdcKRV4viiq4VP
S1HdtvpLAxxrNxFguIlYAkLMJwwuaaK8X+K/kgAm3q5+txsxR/jDmDaFqqj0YnfT
7s+czbSkkvXDG68sTVr1c2u71i8Q0XXSSrL30/j/+//CN9mP6oI6dYRDK5wCFaYw
cQe5Td/biJDWXsXolOC0CHny1TTfNvaK+b0Yksas7aLypHOc5xfVJI1eovwkBpXA
QQDFJoWlZudXXUvjPFsEyt9jd2LUl5fZcQARAQABiQI8BBgBAgAmAhsMFiEEEIvy
ISoFH0pysYRIs8fOIQ3nbfwFAlxe4JAFCRLHvZ4ACgkQs8fOIQ3nbfwvsQ//QE7v
neqZdFBq9PxIgu6S95PTchBI3BsCH6M3uv/hIpLgZwGzymHjCQlwYzjPYRAycphk
VjsWP5T6hFPDfFhtAkdPuDd6LW+asUky1B8t802jGrVSmEA81s9jkjKBpdNR5JJr
a8fAhUvZz9HW2SUwJyvVaO+q4GZep7VrNMKoCvC0K123V442wOYOLC3cldRgVRKY
tXs4KHEjYaR0+zvX2zJvn/CIHWaxw2/qgArXIbTqwiqOWeXAkQWwcArZzkughGIb
iv1DgkttTBLOZbiEUerwoMlGERlSTurhahoNInXD8vPPOrYMl7RSV8XUmgTKCJeN
Xv/Jdg7ejfmPH9zABh8kh+eiL/yINwh2mmRK2aM+u8wghU7i0g72GSKBNgPHzw7X
FDIN4diVX8MB93yeMOMzXGuyHzy3mQhj5LcqMKtTSOeqREAUTHoC0KvQ8kTeZ4N3
czHndwBNEVxluR4ljQeqMdJHWoy6GxFGdrcAHqLZZyxbBQq2cYMwAdbscnQqIhhC
luJgu4vA+7b8RQIZ725Ij+05J5vpHbPtEGACD09YChQL0OtLIZfS8RKP1lKLrmXC
cnJzweMcISPi5PxPXlqXNFzwspK2PLHpmwZ1zSoARXB3BzzCYTE4Mw8UxsCqpbDG
cBfbvGaxikGVOqMEoNo/umEhsyleb0gqXIoZJrc=
=kssP
-----END PGP PUBLIC KEY BLOCK-----

5
debian/watch vendored
View File

@@ -1,5 +0,0 @@
version=4
opts="searchmode=plain,\
filenamemangle=s%.*/v?@ANY_VERSION@%@PACKAGE@-$1.tar.xz%" \
https://api.github.com/repos/zoitechat/zoitechat/releases?per_page=50 \
https://api.github.com/repos/[^/]+/[^/]+/tarball/v?@ANY_VERSION@

View File

@@ -1,7 +0,0 @@
usr/share/applications/net.zoite.Zoitechat.desktop
usr/share/dbus-1/services/org.zoitechat.service.service
usr/share/icons/hicolor/48x48/apps/net.zoite.Zoitechat.png
usr/share/icons/hicolor/scalable/apps/net.zoite.Zoitechat.svg
usr/share/locale/*/LC_MESSAGES/zoitechat.mo
usr/share/metainfo/net.zoite.Zoitechat.appdata.xml
usr/share/mime/packages/net.zoite.Zoitechat.mime.xml

View File

@@ -1,2 +0,0 @@
usr/include/zoitechat-plugin.h
usr/lib/*/pkgconfig/zoitechat-plugin.pc

View File

@@ -1 +0,0 @@
usr/lib/*/zoitechat/plugins/lua.so

View File

@@ -1 +0,0 @@
usr/lib/*/zoitechat/plugins/perl.so

View File

@@ -1,3 +0,0 @@
usr/lib/*/zoitechat/plugins/checksum.so
usr/lib/*/zoitechat/plugins/fishlim.so
usr/lib/*/zoitechat/plugins/sysinfo.so

View File

@@ -1,5 +0,0 @@
usr/lib/*/zoitechat/plugins/python.so
usr/lib/*/zoitechat/python/_zoitechat.py
usr/lib/*/zoitechat/python/hexchat.py
usr/lib/*/zoitechat/python/xchat.py
usr/lib/*/zoitechat/python/zoitechat.py

View File

@@ -1 +0,0 @@
dh_installchangelogs

View File

@@ -1,2 +0,0 @@
usr/bin/zoitechat
usr/share/man/man1/zoitechat.1

View File

@@ -1,6 +0,0 @@
# intentional typo as example for autoreplace function
zoitechat: spelling-error-in-binary usr/bin/zoitechat teh the
# upstream will not correct misspelled variable names
zoitechat: spelling-error-in-binary usr/bin/zoitechat hilight highlight
# fixing this spelling error would break scripting/theming
zoitechat: spelling-error-in-binary usr/bin/zoitechat Conection Connection

View File

@@ -6,6 +6,4 @@ rm -f *.app.zip
python $HOME/.local/bin/gtk-mac-bundler zoitechat.bundle
echo "Compressing bundle"
#hdiutil create -format UDBZ -srcdir ZoiteChat.app -quiet ZoiteChat-2.9.6.1-$(git rev-parse --short master).dmg
zip -9rXq ./ZoiteChat-$(git describe --tags).app.zip ./ZoiteChat.app

View File

@@ -1,33 +0,0 @@
name : zoitechat
version : 2.18.0~pre2
release : 2
source :
- https://github.com/ZoiteChat/zoitechat/archive/e060d57baee1be22bee1f9c3b047be3fa71c6d35.tar.gz : ed315a0b1c46e798912fd830d3845427972857c43ccaa16284969c6f542add38
homepage : https://zoitechat.zoite.net/
license : GPL-2.0-only
component : network.irc
summary : HexChat-based IRC client
description: |
ZoiteChat is a HexChat-based IRC client for Windows and UNIX-like systems.
builddeps :
- pkgconfig(glib-2.0)
- pkgconfig(gmodule-2.0)
- pkgconfig(gtk+-3.0)
- pkgconfig(ayatana-appindicator3-0.1)
- pkgconfig(dbus-glib-1)
- pkgconfig(libcanberra)
- pkgconfig(openssl)
- pkgconfig(iso-codes)
- meson
- ninja
- pkgconf
- gcc
- gettext
setup : |
%meson_configure \
-Dgtk-frontend=true \
-Dinstall-appdata=true
build : |
%ninja_build
install : |
%ninja_install

View File

@@ -26,7 +26,7 @@
#include "zoitechat-plugin.h"
static zoitechat_plugin *ph; /* plugin handle */
static zoitechat_plugin *ph;
static char name[] = "Checksum";
static char desc[] = "Calculate checksum for DCC file transfers";
static char version[] = "4.0";
@@ -42,18 +42,14 @@ typedef struct {
static void
print_sha256_result (ChecksumCallbackInfo *info, const char *checksum, const char *filename, GError *error)
{
// So then we get the next best available channel, since we always want to print at least somewhere, it's fine
zoitechat_context *ctx = zoitechat_find_context(ph, info->servername, info->channel);
if (!ctx) {
// before we print a private message to the wrong channel, we exit early
if (info->send_message) {
return;
}
// if the context isn't found the first time, we search in the server
ctx = zoitechat_find_context(ph, info->servername, NULL);
if (!ctx) {
// The second time we exit early, since printing in another server isn't desireable
return;
}
}

View File

@@ -5,10 +5,6 @@
<ConfigurationType>DynamicLibrary</ConfigurationType>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
@@ -27,21 +23,10 @@
<TargetName>hcchecksum</TargetName>
<OutDir>$(ZoiteChatRel)plugins\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CHECKSUM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(DepsRoot)\include;$(OpenSslInclude);$(Glib);..\..\src\common;$(ZoiteChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<ModuleDefinitionFile>checksum.def</ModuleDefinitionFile>
<AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;CHECKSUM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(DepsRoot)\include;$(OpenSslInclude);$(Glib);..\..\src\common;$(ZoiteChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(DepsRoot)\include;$(OpenSslInclude);$(Glib);..\..\src\common;$(ZoiteChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<ModuleDefinitionFile>checksum.def</ModuleDefinitionFile>

View File

@@ -25,7 +25,7 @@
#include "zoitechat-plugin.h"
static zoitechat_plugin *ph; /* plugin handle */
static zoitechat_plugin *ph;
static char name[] = "Exec";
static char desc[] = "Execute commands inside ZoiteChat";
static char version[] = "1.2";
@@ -71,7 +71,7 @@ run_command (char *word[], char *word_eol[], void *userdata)
strcat (commandLine, word_eol[2]);
}
CreatePipe (&readPipe, &writePipe, &secattr, 0); /* might be replaced with MyCreatePipeEx */
CreatePipe (&readPipe, &writePipe, &secattr, 0);
ZeroMemory (&sInfo, sizeof (sInfo));
ZeroMemory (&pInfo, sizeof (pInfo));
@@ -91,12 +91,10 @@ run_command (char *word[], char *word_eol[], void *userdata)
{
if (ReadFile (readPipe, buffer, sizeof (buffer) - 1, &dwRead, NULL) && dwRead != 0 )
{
/* avoid garbage */
buffer[dwRead] = '\0';
if (announce)
{
/* Say each line seperately, TODO: improve... */
token = strtok_s (buffer, "\n", &context);
while (token != NULL)
{
@@ -110,13 +108,11 @@ run_command (char *word[], char *word_eol[], void *userdata)
}
else
{
/* this way we'll more likely get full lines */
SleepEx (100, TRUE);
}
timeElapsed = difftime (time (0), start);
}
/* display a newline to separate things */
if (!announce)
zoitechat_printf (ph, "\n");
@@ -149,7 +145,7 @@ zoitechat_plugin_init (zoitechat_plugin *plugin_handle, char **plugin_name, char
zoitechat_hook_command (ph, "EXEC", ZOITECHAT_PRI_NORM, run_command, "Usage: /EXEC [-O] - execute commands inside ZoiteChat", 0);
zoitechat_printf (ph, "%s plugin loaded\n", name);
return 1; /* return 1 for success */
return 1;
}
int

View File

@@ -5,10 +5,6 @@
<ConfigurationType>DynamicLibrary</ConfigurationType>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
@@ -27,15 +23,6 @@
<TargetName>hcexec</TargetName>
<OutDir>$(ZoiteChatRel)plugins\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;EXEC_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<ModuleDefinitionFile>exec.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;EXEC_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>

View File

@@ -5,10 +5,6 @@
<ConfigurationType>DynamicLibrary</ConfigurationType>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
@@ -27,21 +23,10 @@
<TargetName>hcfishlim</TargetName>
<OutDir>$(ZoiteChatRel)plugins\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;FISHLIM_EXPORTS;HAVE_DH_SET0_PQG;HAVE_DH_GET0_KEY;HAVE_DH_SET0_KEY;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(DepsRoot)\include;$(OpenSslInclude);$(Glib);..\..\src\common;$(ZoiteChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<ModuleDefinitionFile>fishlim.def</ModuleDefinitionFile>
<AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;FISHLIM_EXPORTS;HAVE_DH_SET0_PQG;HAVE_DH_GET0_KEY;HAVE_DH_SET0_KEY;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(DepsRoot)\include;$(OpenSslInclude);$(Glib);..\..\src\common;$(ZoiteChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(DepsRoot)\include;$(OpenSslInclude);$(Glib);..\..\src\common;$(ZoiteChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<ModuleDefinitionFile>fishlim.def</ModuleDefinitionFile>

View File

@@ -39,13 +39,11 @@ gboolean irc_parse_message(const char *words[],
if (prefix) *prefix = NULL;
if (command) *command = NULL;
/* See if the message starts with a prefix (sender user) */
if (words[w][0] == ':') {
if (prefix) *prefix = &words[w][1];
w++;
}
/* Check command */
if (words[w][0] == '\0') return FALSE;
if (command) *command = words[w];
w++;
@@ -72,11 +70,9 @@ char *irc_prefix_get_nick(const char *prefix) {
if (!prefix) return NULL;
/* Find end of nick */
end = prefix;
while (*end != '\0' && *end != '!' && *end != '@') end++;
/* Allocate string */
length = end - prefix;
return g_strndup (prefix, length);
}

View File

@@ -277,15 +277,6 @@ char *decrypt_raw_message(const char *message, const char *key) {
return NULL;
}
/*static int handle_debug(char *word[], char *word_eol[], void *userdata) {
zoitechat_printf(ph, "debug incoming: ");
for (size_t i = 1; word[i] != NULL && word[i][0] != '\0'; i++) {
zoitechat_printf(ph, ">%s< ", word[i]);
}
zoitechat_printf(ph, "\n");
return ZOITECHAT_EAT_NONE;
}*/
/**
* Called when a message is to be sent.
*/
@@ -811,7 +802,6 @@ int zoitechat_plugin_init(zoitechat_plugin *plugin_handle,
zoitechat_hook_server(ph, "NOTICE", ZOITECHAT_PRI_HIGHEST, handle_keyx_notice, NULL);
zoitechat_hook_server_attrs(ph, "NOTICE", ZOITECHAT_PRI_NORM, handle_incoming, NULL);
zoitechat_hook_server_attrs(ph, "PRIVMSG", ZOITECHAT_PRI_NORM, handle_incoming, NULL);
/* zoitechat_hook_server(ph, "RAW LINE", ZOITECHAT_PRI_NORM, handle_debug, NULL); */
zoitechat_hook_server_attrs(ph, "TOPIC", ZOITECHAT_PRI_NORM, handle_incoming, NULL);
zoitechat_hook_server_attrs(ph, "332", ZOITECHAT_PRI_NORM, handle_incoming, NULL);
@@ -836,4 +826,3 @@ int zoitechat_plugin_deinit(void) {
zoitechat_printf(ph, "%s plugin unloaded\n", plugin_name);
return 1;
}

View File

@@ -5,10 +5,6 @@
<ConfigurationType>DynamicLibrary</ConfigurationType>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
@@ -27,16 +23,6 @@
<TargetName>$(LuaOutput)</TargetName>
<OutDir>$(ZoiteChatRel)plugins\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(Glib);$(LuaInclude);..\..\src\common;$(ZoiteChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>"$(LuaLib).lib";$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions>

View File

@@ -440,8 +440,6 @@ server_cb (char *word[], char *word_eol[], void *userdata)
if (data->depth)
return ZOITECHAT_EAT_NONE;
/* zoitechat_printf (ph, */
/* "Received %d words in server callback", av_len (wd)); */
PUSHMARK (SP);
XPUSHs (newRV_noinc ((SV *) array2av (word)));
XPUSHs (newRV_noinc ((SV *) array2av (word_eol)));
@@ -489,8 +487,6 @@ command_cb (char *word[], char *word_eol[], void *userdata)
if (data->depth)
return ZOITECHAT_EAT_NONE;
/* zoitechat_printf (ph, "Received %d words in command callback", */
/* av_len (wd)); */
PUSHMARK (SP);
XPUSHs (newRV_noinc ((SV *) array2av (word)));
XPUSHs (newRV_noinc ((SV *) array2av (word_eol)));
@@ -567,7 +563,6 @@ print_cb (char *word[], void *userdata)
}
}
/*zoitechat_printf (ph, "Received %d words in print callback", av_len (wd)+1); */
PUSHMARK (SP);
XPUSHs (newRV_noinc ((SV *) wd));
XPUSHs (data->userdata);

View File

@@ -5,10 +5,6 @@
<ConfigurationType>DynamicLibrary</ConfigurationType>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
@@ -27,26 +23,6 @@
<TargetName>hcperl</TargetName>
<OutDir>$(ZoiteChatRel)plugins\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;PERL520_EXPORTS;HAS_BOOL;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(IntDir);..\..\src\common;$(ZoiteChatLib);$(PerlPath)\lib\CORE;$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>$(IntDir);$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>$(PerlLib).lib;$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>perl.def</ModuleDefinitionFile>
<DelayLoadDLLs>$(PerlLib).dll;%(DelayLoadDLLs)</DelayLoadDLLs>
</Link>
<PreBuildEvent>
<Command>"$(GendefPath)\gendef" "$(PerlPath)\bin\$(PerlLib).dll"
move $(PerlLib).def "$(IntDir)"
lib /nologo /machine:x86 "/def:$(IntDir)$(PerlLib).def" "/out:$(IntDir)\$(PerlLib).lib"
"$(PerlPath)\bin\perl.exe" generate_header
move irc.pm.h "$(IntDir)"
move zoitechat.pm.h "$(IntDir)"</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;PERL520_EXPORTS;HAS_BOOL;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions>

View File

@@ -79,7 +79,6 @@ def emit_print(event_name, *args, **kwargs):
return ret
# TODO: this shadows itself. command should be changed to cmd
def command(command):
lib.zoitechat_command(lib.ph, command.encode())
@@ -221,7 +220,6 @@ def get_list(name):
return ret
# TODO: 'command' here shadows command above, and should be renamed to cmd
def hook_command(command, callback, userdata=None, priority=PRI_NORM, help=None):
plugin = __get_current_plugin()
hook = plugin.add_hook(callback, userdata)

View File

@@ -5,11 +5,9 @@ import cffi
builder = cffi.FFI()
# zoitechat-plugin.h
with open(sys.argv[1]) as f:
output = []
eat_until_endif = 0
# This is very specific to zoitechat-plugin.h, it is not a cpp
for line in f:
if line.startswith('#define'):
continue
@@ -81,9 +79,7 @@ int zoitechat_plugin_deinit(void)
}
''')
# python.py
with open(sys.argv[2]) as f:
builder.embedding_init_code(f.read())
# python.c
builder.emit_c_code(sys.argv[3])

View File

@@ -19,12 +19,11 @@ else:
if not hasattr(sys, 'argv'):
sys.argv = ['<zoitechat>']
VERSION = b'2.18.0~pre2' # Sync with zoitechat.__version__
VERSION = b'2.18.0~pre2'
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)
# TODO: Constants should be screaming snake case
zoitechat = None
local_interp = None
zoitechat_stdout = None
@@ -106,8 +105,6 @@ if sys.version_info[0] == 2:
return compile(string, '<string>', 'eval', dont_inherit=True)
except SyntaxError:
# For some reason `print` is invalid for eval
# This will hide any return value though
return compile(string, '<string>', 'exec', dont_inherit=True)
else:
def compile_file(data, filename):
@@ -115,7 +112,6 @@ else:
def compile_line(string):
# newline appended to solve unexpected EOF issues
return compile(string + '\n', '<string>', 'single', optimize=2, dont_inherit=True)
@@ -200,8 +196,6 @@ else:
return string.decode()
# There can be empty entries between non-empty ones so find the actual last value
def _cstr(ptr):
"""Safely convert a C char* (possibly NULL) to bytes."""
if ptr == ffi.NULL:
@@ -212,7 +206,6 @@ def _cstr(ptr):
return b''
def wordlist_len(words):
# ZoiteChat passes a fixed-size array (typically 32) where unused entries may be NULL.
for i in range(31, 0, -1):
if _cstr(words[i]):
return i
@@ -299,12 +292,8 @@ def _on_timer_hook(userdata):
return 1
try:
# Avoid calling zoitechat_unhook twice if unnecessary
hook.is_unload = True
except ReferenceError:
# hook is a weak reference, it might have been destroyed by the callback
# in which case it has already been removed from hook.plugin.hooks and
# we wouldn't be able to test it with h == hook anyway.
return 0
for h in hook.plugin.hooks:
@@ -338,11 +327,9 @@ def _on_say_command(word, word_eol, userdata):
if not python:
return 1
# Dont let exceptions here swallow core commands or wedge the UI.
try:
exec_in_interp(python)
except Exception:
# Best effort: surface the traceback in the python tab.
exc = traceback.format_exc().encode('utf-8', errors='replace')
lib.zoitechat_print(lib.ph, exc)
return 1
@@ -397,11 +384,10 @@ def autoload():
configdir = __decode(_cstr(lib.zoitechat_get_info(lib.ph, b'configdir')))
addondir = os.path.join(configdir, 'addons')
try:
with change_cwd(addondir): # Maintaining old behavior
with change_cwd(addondir):
for f in os.listdir(addondir):
if f.endswith('.py'):
log('Autoloading', f)
# TODO: Set cwd
load_filename(os.path.join(addondir, f))
except FileNotFoundError as e:

View File

@@ -27,23 +27,6 @@
<TargetName>$(Python3Output)</TargetName>
<OutDir>$(ZoiteChatRel)plugins\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;PYTHON_EXPORTS;Py_NO_LINK_LIB;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions>
<UndefinePreprocessorDefinitions>_DEBUG;Py_DEBUG;Py_REF_DEBUG;Py_TRACE_REFS;%(UndefinePreprocessorDefinitions)</UndefinePreprocessorDefinitions>
<AdditionalOptions>/U_DEBUG /UPy_DEBUG /UPy_REF_DEBUG /UPy_TRACE_REFS %(AdditionalOptions)</AdditionalOptions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<AdditionalIncludeDirectories>$(Glib);$(Python3Path)\include;..\..\src\common;$(ZoiteChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<ModuleDefinitionFile>python.def</ModuleDefinitionFile>
<AdditionalDependencies>"$(Python3Lib).lib";$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(DepsRoot)\lib;$(Python3Path)\libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PreBuildEvent>
<Command>"$(Python3Path)\python.exe" generate_plugin.py ..\..\src\common\zoitechat-plugin.h python.py "$(IntDir)python.c"</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;PYTHON_EXPORTS;Py_NO_LINK_LIB;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions>

View File

@@ -208,7 +208,6 @@ sysinfo_cb (char *word[], char *word_eol[], void *userdata)
int offset = 0, channel_type;
char *cmd;
/* Allow overriding global announce setting */
if (!strcmp ("-e", word[2]))
{
announce = FALSE;
@@ -220,7 +219,6 @@ sysinfo_cb (char *word[], char *word_eol[], void *userdata)
offset++;
}
/* Cannot send to server tab */
channel_type = zoitechat_list_int (ph, NULL, "type");
if (channel_type != 2 /* SESS_CHANNEL */ && channel_type != 3 /* SESS_DIALOG */)
announce = FALSE;
@@ -246,7 +244,6 @@ zoitechat_plugin_init (zoitechat_plugin *plugin_handle, char **plugin_name, char
zoitechat_hook_command (ph, "SYSINFO", ZOITECHAT_PRI_NORM, sysinfo_cb, sysinfo_help, NULL);
/* Match the classic label from HexChat so people can actually find it. */
zoitechat_command (ph, "MENU ADD \"Window/Display System Info\" \"SYSINFO\"");
zoitechat_printf (ph, _("%s plugin loaded\n"), name);
return 1;
@@ -255,7 +252,6 @@ zoitechat_plugin_init (zoitechat_plugin *plugin_handle, char **plugin_name, char
int
zoitechat_plugin_deinit (void)
{
/* Keep both in case older builds used a different label. */
zoitechat_command (ph, "MENU DEL \"Window/Send System Info\"");
zoitechat_command (ph, "MENU DEL \"Window/Display System Info\"");
zoitechat_printf (ph, _("%s plugin unloaded\n"), name);

View File

@@ -28,29 +28,15 @@
<TargetName>hcsysinfo</TargetName>
<OutDir>$(ZoiteChatRel)plugins\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SYSINFO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\src\common;$(DepsRoot)\include;$(OpenSslInclude);$(Glib);$(ZoiteChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>$(ZoiteChatLib)common.lib;wbemuuid.lib;comsupp.lib;$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
<IgnoreSpecificDefaultLibraries>comsupp.lib</IgnoreSpecificDefaultLibraries>
<ModuleDefinitionFile>sysinfo.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;SYSINFO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\src\common;$(DepsRoot)\include;$(OpenSslInclude);$(Glib);$(ZoiteChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\..\src\common;$(DepsRoot)\include;$(OpenSslInclude);$(Glib);$(ZoiteChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>$(ZoiteChatLib)common.lib;wbemuuid.lib;comsupp.lib;$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
<IgnoreSpecificDefaultLibraries>comsupp.lib</IgnoreSpecificDefaultLibraries>
<AdditionalDependencies>$(ZoiteChatLib)common.lib;wbemuuid.lib;$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>sysinfo.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
@@ -68,4 +54,4 @@
<ClInclude Include="sysinfo.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
</Project>

View File

@@ -132,7 +132,6 @@ void pci_find_fullname(char *fullname, char *vendor, char *device)
if(fp == NULL)
{
g_snprintf(fullname, bsize, "%s:%s", vendor, device);
//sysinfo_print_error ("pci.ids file not found! You might want to adjust your pciids setting with /SYSINFO SET pciids (you can query its current value with /SYSINFO LIST).\n");
return;
}

View File

@@ -26,7 +26,7 @@
#define APPCAST_URL "https://zoitechat.zoite.net/appcast.xml"
static zoitechat_plugin *ph; /* plugin handle */
static zoitechat_plugin *ph;
static char name[] = "Update Checker";
static char desc[] = "Check for ZoiteChat updates automatically";
static char version[] = "5.0";

View File

@@ -27,17 +27,6 @@
<TargetName>hcupd</TargetName>
<OutDir>$(ZoiteChatRel)plugins\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;UPD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\src\common;$(WinSparklePath);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<ModuleDefinitionFile>upd.def</ModuleDefinitionFile>
<AdditionalDependencies>$(DepLibs);WinSparkle.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(DepsRoot)\lib;$(WinSparklePath);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;UPD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>

View File

@@ -20,7 +20,7 @@
#define PLAYING 1
#define PAUSED 3
static zoitechat_plugin *ph; /* plugin handle */
static zoitechat_plugin *ph;
static int
winamp(char *word[], char *word_eol[], void *userdata)
@@ -130,7 +130,6 @@ zoitechat_plugin_init(zoitechat_plugin *plugin_handle,
char **plugin_version,
char *arg)
{
/* we need to save this for use with any zoitechat_* functions */
ph = plugin_handle;
*plugin_name = "Winamp";
@@ -142,7 +141,7 @@ zoitechat_plugin_init(zoitechat_plugin *plugin_handle,
zoitechat_print (ph, "Winamp plugin loaded\n");
return 1; /* return 1 for success */
return 1;
}
int

View File

@@ -5,10 +5,6 @@
<ConfigurationType>DynamicLibrary</ConfigurationType>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
@@ -27,11 +23,6 @@
<TargetName>hcwinamp</TargetName>
<OutDir>$(ZoiteChatRel)plugins\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WINAMP_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;WINAMP_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
@@ -39,7 +30,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(DepsRoot)\include;$(OpenSslInclude);$(Glib);..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(DepsRoot)\include;$(OpenSslInclude);$(Glib);..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<ModuleDefinitionFile>winamp.def</ModuleDefinitionFile>

View File

@@ -1,10 +1,10 @@
<div align="center">
<img src="data/icons/zoitechat.svg" height="230">
[![Debian Build](https://github.com/ZoiteChat/zoitechat/actions/workflows/debian-build.yml/badge.svg)](https://github.com/ZoiteChat/zoitechat/actions/workflows/debian-build.yml)
[![Flatpak Build](https://github.com/ZoiteChat/zoitechat/actions/workflows/flatpak-build.yml/badge.svg)](https://github.com/ZoiteChat/zoitechat/actions/workflows/flatpak-build.yml)
[![AppImage Build](https://github.com/ZoiteChat/zoitechat/actions/workflows/appimage-build.yml/badge.svg)](https://github.com/ZoiteChat/zoitechat/actions/workflows/appimage-build.yml)
[![Windows Build](https://github.com/ZoiteChat/zoitechat/actions/workflows/windows-build.yml/badge.svg)](https://github.com/ZoiteChat/zoitechat/actions/workflows/windows-build.yml)
[![Manjaro Package Build](https://github.com/ZoiteChat/zoitechat/actions/workflows/manjaro-package-build.yml/badge.svg)](https://github.com/ZoiteChat/zoitechat/actions/workflows/manjaro-package-build.yml)
[![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 File

@@ -258,12 +258,13 @@ int
cfg_get_color (char *cfg, char *var, guint16 *r, guint16 *g, guint16 *b)
{
char str[128];
int matched;
if (!cfg_get_str (cfg, var, str, sizeof (str)))
return 0;
sscanf (str, "%04hx %04hx %04hx", r, g, b);
return 1;
matched = sscanf (str, "%04hx %04hx %04hx", r, g, b);
return matched == 3;
}
int
@@ -438,6 +439,7 @@ const struct prefs vars[] =
{"gui_tab_dots", P_OFFINT (hex_gui_tab_dots), TYPE_BOOL},
{"gui_tab_icons", P_OFFINT (hex_gui_tab_icons), TYPE_BOOL},
{"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_middleclose", P_OFFINT (hex_gui_tab_middleclose), TYPE_BOOL},
{"gui_tab_newtofront", P_OFFINT (hex_gui_tab_newtofront), TYPE_INT},
@@ -567,6 +569,7 @@ const struct prefs vars[] =
{"text_font", P_OFFSET (hex_text_font), TYPE_STR},
{"text_font_main", P_OFFSET (hex_text_font_main), TYPE_STR},
{"text_font_alternative", P_OFFSET (hex_text_font_alternative), TYPE_STR},
{"gui_gtk3_theme", P_OFFSET (hex_gui_gtk3_theme), TYPE_STR},
{"text_indent", P_OFFINT (hex_text_indent), TYPE_BOOL},
{"text_max_indent", P_OFFINT (hex_text_max_indent), TYPE_INT},
{"text_max_lines", P_OFFINT (hex_text_max_lines), TYPE_INT},
@@ -764,7 +767,6 @@ load_default_config(void)
prefs.hex_gui_input_style = 1;
prefs.hex_gui_join_dialog = 1;
prefs.hex_gui_quit_dialog = 1;
/* prefs.hex_gui_slist_skip = 1; */
prefs.hex_gui_tab_chans = 1;
prefs.hex_gui_tab_dialogs = 1;
prefs.hex_gui_tab_icons = 1;
@@ -788,7 +790,7 @@ load_default_config(void)
prefs.hex_irc_reconnect_rejoin = 1;
prefs.hex_irc_cap_server_time = 1;
prefs.hex_irc_logging = 1;
prefs.hex_irc_who_join = 1; /* Can kick with inordinate amount of channels, required for some of our features though, TODO: add cap like away check? */
prefs.hex_irc_who_join = 1;
prefs.hex_irc_whois_front = 1;
prefs.hex_net_auto_reconnect = 1;
prefs.hex_net_throttle = 1;
@@ -819,7 +821,7 @@ load_default_config(void)
prefs.hex_flood_ctcp_num = 5;
prefs.hex_flood_ctcp_time = 30;
prefs.hex_flood_msg_num = 5;
/*FIXME*/ prefs.hex_flood_msg_time = 30;
prefs.hex_flood_msg_time = 30;
prefs.hex_gui_chanlist_maxusers = 9999;
prefs.hex_gui_chanlist_minusers = 5;
prefs.hex_gui_dialog_height = 256;

View File

@@ -99,8 +99,6 @@ str_to_chanopt (const char *str)
return SET_DEFAULT;
}
/* handle the /CHANOPT command */
int
chanopt_command (session *sess, char *tbuf, char *word[], char *word_eol[])
{
@@ -135,13 +133,13 @@ chanopt_command (session *sess, char *tbuf, char *word[], char *word_eol[])
{
if (find[0] == 0 || match (find, chanopt[i].name) || (chanopt[i].alias && match (find, chanopt[i].alias)))
{
if (newval != -1) /* set new value */
if (newval != -1)
{
*(guint8 *)G_STRUCT_MEMBER_P(sess, chanopt[i].offset) = newval;
chanopt_changed = TRUE;
}
if (!quiet) /* print value */
if (!quiet)
{
strcpy (tbuf, chanopt[i].name);
p = strlen (tbuf);
@@ -177,18 +175,13 @@ chanopt_is_set (unsigned int global, guint8 per_chan_setting)
return global;
}
/* === below is LOADING/SAVING stuff only === */
typedef struct
{
/* Per-Channel Alerts */
/* use a byte, because we need a pointer to each element */
guint8 alert_balloon;
guint8 alert_beep;
guint8 alert_taskbar;
guint8 alert_tray;
/* Per-Channel Settings */
guint8 text_hidejoinpart;
guint8 text_logging;
guint8 text_scrollback;
@@ -218,12 +211,10 @@ chanopt_find (char *network, char *channel, gboolean add_new)
if (!add_new)
return NULL;
/* allocate a new one */
co = g_new0 (chanopt_in_memory, 1);
co->channel = g_strdup (channel);
co->network = g_strdup (network);
/* set all values to SET_DEFAULT */
i = 0;
while (i < sizeof (chanopt) / sizeof (channel_options))
{
@@ -254,8 +245,6 @@ chanopt_add_opt (chanopt_in_memory *co, char *var, int new_value)
}
}
/* load chanopt.conf from disk into our chanopt_list GSList */
static void
chanopt_load_all (void)
{
@@ -265,7 +254,6 @@ chanopt_load_all (void)
char *network = NULL;
chanopt_in_memory *current = NULL;
/* 1. load the old file into our GSList */
fh = zoitechat_open_file ("chanopt.conf", O_RDONLY, 0, 0);
if (fh != -1)
{
@@ -326,7 +314,6 @@ chanopt_load (session *sess)
if (!co)
return;
/* fill in all the sess->xxxxx fields */
i = 0;
while (i < sizeof (chanopt) / sizeof (channel_options))
{
@@ -352,8 +339,6 @@ chanopt_save (session *sess)
if (!network)
return;
/* 2. reconcile sess with what we loaded from disk */
co = chanopt_find (network, sess->session_name, TRUE);
i = 0;

View File

@@ -5,10 +5,6 @@
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
@@ -49,6 +45,8 @@
<ClInclude Include="zoitechat-plugin.h" />
<ClInclude Include="zoitechat.h" />
<ClInclude Include="zoitechatc.h" />
<ClInclude Include="theme-service.h" />
<ClInclude Include="gtk3-theme-service.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="cfgfiles.c" />
@@ -79,6 +77,8 @@
<ClCompile Include="userlist.c" />
<ClCompile Include="util.c" />
<ClCompile Include="zoitechat.c" />
<ClCompile Include="theme-service.c" />
<ClCompile Include="gtk3-theme-service.c" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\win32\config.h.tt" />
@@ -96,16 +96,10 @@
<PropertyGroup>
<OutDir>$(ZoiteChatLib)</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ZoiteChatLib);$(DepsRoot)\include;$(OpenSslInclude);$(Glib);$(Gtk);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_LIB;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ZoiteChatLib);$(DepsRoot)\include;$(OpenSslInclude);$(Glib);$(Gtk);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ZoiteChatLib);$(DepsRoot)\include;$(ArchiveInclude);$(OpenSslInclude);$(Glib);$(Gtk);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>

View File

@@ -119,6 +119,12 @@
<ClInclude Include="sysinfo\sysinfo.h">
<Filter>Source Files\sysinfo</Filter>
</ClInclude>
<ClInclude Include="theme-service.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="gtk3-theme-service.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="cfgfiles.c">
@@ -202,6 +208,12 @@
<ClCompile Include="sysinfo\win32\backend.c">
<Filter>Source Files\sysinfo\win32</Filter>
</ClCompile>
<ClCompile Include="theme-service.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="gtk3-theme-service.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\..\win32\config.h.tt" />

View File

@@ -743,9 +743,6 @@ dcc_read (GIOChannel *source, GIOCondition condition, struct DCC *dcc)
EMIT_SIGNAL (XP_TE_DCCRECVERR, dcc->serv->front_session, dcc->file,
dcc->destfile, dcc->nick,
errorstring ((n < 0) ? sock_error () : 0), 0);
/* send ack here? but the socket is dead */
/*if (need_ack)
dcc_send_ack (dcc);*/
dcc_close (dcc, STAT_FAILED, FALSE);
return TRUE;
}
@@ -1383,7 +1380,6 @@ dcc_connect (struct DCC *dcc)
dcc_close (dcc, STAT_FAILED, FALSE);
return;
}
/* possible problems with filenames containing spaces? */
if (dcc->type == TYPE_RECV)
g_snprintf (tbuf, sizeof (tbuf), strchr (dcc->file, ' ') ?
"DCC SEND \"%s\" %u %d %" G_GUINT64_FORMAT " %d" :
@@ -1660,17 +1656,14 @@ dcc_listen_init (struct DCC *dcc, session *sess)
SAddr.sin_family = AF_INET;
/*if local_ip is specified use that*/
if (prefs.local_ip != 0xffffffff)
{
my_addr = prefs.local_ip;
SAddr.sin_addr.s_addr = prefs.local_ip;
}
/*otherwise use the default*/
else
my_addr = SAddr.sin_addr.s_addr;
/*if we have a valid portrange try to use that*/
if (prefs.hex_dcc_port_first > 0)
{
SAddr.sin_port = 0;
@@ -1680,7 +1673,6 @@ dcc_listen_init (struct DCC *dcc, session *sess)
{
SAddr.sin_port = htons (prefs.hex_dcc_port_first + i);
i++;
/*printf("Trying to bind against port: %d\n",ntohs(SAddr.sin_port));*/
bindretval = bind (dcc->sok, (struct sockaddr *) &SAddr, sizeof (SAddr));
}
@@ -1707,12 +1699,8 @@ dcc_listen_init (struct DCC *dcc, session *sess)
dcc->port = ntohs (SAddr.sin_port);
/*if we have a dcc_ip, we use that, so the remote client can connect*/
/*else we try to take an address from hex_dcc_ip*/
/*if something goes wrong we tell the client to connect to our LAN ip*/
dcc->addr = dcc_get_my_address (sess);
/*if nothing else worked we use the address we bound to*/
if (dcc->addr == 0)
dcc->addr = my_addr;
@@ -1728,7 +1716,7 @@ dcc_listen_init (struct DCC *dcc, session *sess)
}
static struct session *dccsess;
static char *dccto; /* lame!! */
static char *dccto;
static gint64 dccmaxcps;
static int recursive = FALSE;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,32 @@
#ifndef ZOITECHAT_GTK3_THEME_SERVICE_H
#define ZOITECHAT_GTK3_THEME_SERVICE_H
#include <glib.h>
typedef enum
{
ZOITECHAT_GTK3_THEME_SOURCE_SYSTEM = 0,
ZOITECHAT_GTK3_THEME_SOURCE_USER = 1
} ZoitechatGtk3ThemeSource;
typedef struct
{
char *id;
char *display_name;
char *path;
gboolean has_dark_variant;
char *thumbnail_path;
ZoitechatGtk3ThemeSource source;
} ZoitechatGtk3Theme;
char *zoitechat_gtk3_theme_service_get_user_themes_dir (void);
GPtrArray *zoitechat_gtk3_theme_service_discover (void);
void zoitechat_gtk3_theme_free (ZoitechatGtk3Theme *theme);
ZoitechatGtk3Theme *zoitechat_gtk3_theme_find_by_id (const char *theme_id);
gboolean zoitechat_gtk3_theme_service_import (const char *source_path, char **imported_id, GError **error);
gboolean zoitechat_gtk3_theme_service_remove_user_theme (const char *theme_id, GError **error);
char *zoitechat_gtk3_theme_pick_css_dir_for_minor (const char *theme_root, int preferred_minor);
char *zoitechat_gtk3_theme_pick_css_dir (const char *theme_root);
GPtrArray *zoitechat_gtk3_theme_build_inheritance_chain (const char *theme_root);
#endif

View File

@@ -153,8 +153,6 @@ ignore_showlist (session *sess)
strcat (tbuf, _("NO "));
strcat (tbuf, "\n");
PrintText (sess, tbuf);
/*EMIT_SIGNAL (XP_TE_IGNORELIST, sess, ig->mask, 0, 0, 0, 0); */
/* use this later, when TE's support 7 args */
list = list->next;
}
@@ -413,4 +411,3 @@ flood_check (char *nick, char *ip, server *serv, session *sess, int what) /*0=ct
}
return 1;
}

View File

@@ -108,7 +108,6 @@ find_session_from_nick (char *nick, server *serv)
if (serv->front_session)
{
// If we are here for ChanServ, then it is usually a reply for the user
if (!g_ascii_strcasecmp(nick, "ChanServ") || userlist_find (serv->front_session, nick))
return serv->front_session;
}
@@ -2121,7 +2120,6 @@ scram_authenticate (server *serv, const char *data, const char *digest,
if (status == SCRAM_IN_PROGRESS)
{
// Authentication is still in progress
encoded = g_base64_encode ((guchar *) output, output_len);
tcp_sendf (serv, "AUTHENTICATE %s\r\n", encoded);
g_free (encoded);
@@ -2129,13 +2127,11 @@ scram_authenticate (server *serv, const char *data, const char *digest,
}
else if (status == SCRAM_SUCCESS)
{
// Authentication succeeded
tcp_sendf (serv, "AUTHENTICATE +\r\n");
g_clear_pointer (&serv->scram_session, scram_session_free);
}
else if (status == SCRAM_ERROR)
{
// Authentication failed
tcp_sendf (serv, "AUTHENTICATE *\r\n");
if (serv->scram_session->error != NULL)

View File

@@ -3,6 +3,7 @@ common_sources = [
'chanopt.c',
'ctcp.c',
'dcc.c',
'gtk3-theme-service.c',
'zoitechat.c',
'history.c',
'ignore.c',
@@ -27,12 +28,17 @@ common_sources = [
]
common_sysinfo_deps = []
libarchive_dep = dependency('libarchive', required: host_machine.system() != 'windows')
common_deps = [
libgio_dep,
libcanberra_dep,
] + global_deps
if libarchive_dep.found()
common_deps += libarchive_dep
endif
common_includes = [
config_h_include,
include_directories('.')
@@ -96,11 +102,6 @@ textevents = custom_target('textevents',
command: [make_te, '@INPUT@', '@OUTPUT0@', '@OUTPUT1@']
)
# TODO:
# LOOKUPD
# SIGACTION
# HAVE_GTK_MAC
if libssl_dep.found()
common_sources += 'ssl.c'
common_deps += libssl_dep
@@ -138,3 +139,18 @@ zoitechat_plugin_dep = declare_dependency(
compile_args: common_cflags,
dependencies: global_deps,
)
gtk3_theme_service_tests = executable('gtk3_theme_service_tests',
[
'tests/test-gtk3-theme-service.c',
'gtk3-theme-service.c',
],
include_directories: [config_h_include, include_directories('.')],
dependencies: [libgio_dep] + (libarchive_dep.found() ? [libarchive_dep] : []),
)
test('GTK3 Theme Service Tests', gtk3_theme_service_tests,
protocol: 'tap',
timeout: 120,
)

View File

@@ -87,7 +87,7 @@ notify_do_network (struct notify *notify, server *serv)
return TRUE;
if (token_foreach (notify->networks, ',', notify_netcmp, serv))
return FALSE; /* network list doesn't contain this one */
return FALSE;
return TRUE;
}
@@ -106,8 +106,6 @@ notify_find_server_entry (struct notify *notify, struct server *serv)
list = list->next;
}
/* not found, should we add it, or is this not a network where
we're monitoring this nick? */
if (!notify_do_network (notify, serv))
return NULL;
@@ -123,11 +121,7 @@ notify_save (void)
{
int fh;
struct notify *notify;
// while reading the notify.conf file, elements are added by prepending to the
// list. reverse the list before writing to disk to keep the original
// order of the list
GSList *list = g_slist_copy(notify_list);
list = g_slist_reverse(list);
GSList *list = g_slist_reverse (g_slist_copy (notify_list));
fh = zoitechat_open_file ("notify.conf", O_TRUNC | O_WRONLY | O_CREAT, 0600, XOF_DOMODE);
if (fh != -1)
@@ -146,7 +140,7 @@ notify_save (void)
}
close (fh);
}
g_slist_free(list);
g_slist_free (list);
}
void

View File

@@ -42,19 +42,16 @@ struct notify_per_server
extern GSList *notify_list;
extern int notify_tag;
/* the WATCH stuff */
void notify_set_online (server * serv, char *nick,
const message_tags_data *tags_data);
void notify_set_offline (server * serv, char *nick, int quiet,
const message_tags_data *tags_data);
/* the MONITOR stuff */
const message_tags_data *tags_data);
void notify_set_online_list (server * serv, char *users,
const message_tags_data *tags_data);
void notify_set_offline_list (server * serv, char *users, int quiet,
const message_tags_data *tags_data);
const message_tags_data *tags_data);
void notify_send_watches (server * serv);
/* the general stuff */
void notify_adduser (char *name, char *networks);
int notify_deluser (char *name);
void notify_cleanup (void);
@@ -65,7 +62,6 @@ gboolean notify_is_in_list (server *serv, char *name);
int notify_isnotify (session *sess, char *name);
struct notify_per_server *notify_find_server_entry (struct notify *notify, struct server *serv);
/* the old ISON stuff - remove me? */
void notify_markonline (server *serv, char *word[],
const message_tags_data *tags_data);
int notify_checklist (void);

View File

@@ -3770,45 +3770,6 @@ cmd_url (struct session *sess, char *tbuf, char *word[], char *word_eol[])
{
if (word[2][0])
{
char *theme_path = NULL;
if (zoitechat_theme_path_from_arg (word[2], &theme_path))
{
GError *error = NULL;
char *basename = g_path_get_basename (theme_path);
char *dot = strrchr (basename, '.');
char *message;
if (dot)
*dot = '\0';
if (zoitechat_import_theme (theme_path, &error))
{
if (zoitechat_apply_theme (basename, &error))
{
message = g_strdup_printf (_("Theme \"%s\" imported and applied."), basename);
fe_message (message, FE_MSG_INFO);
handle_command (sess, "gui apply", FALSE);
g_free (message);
}
else
{
fe_message (error ? error->message : _("Theme imported, but failed to apply."),
FE_MSG_ERROR);
g_clear_error (&error);
}
}
else
{
fe_message (error ? error->message : _("Failed to import theme."),
FE_MSG_ERROR);
g_clear_error (&error);
}
g_free (basename);
g_free (theme_path);
return TRUE;
}
char *server_name = NULL;
char *port = NULL;
char *channel = NULL;

View File

@@ -30,7 +30,7 @@
#define _(x) zoitechat_gettext(ph,x)
static zoitechat_plugin *ph; /* plugin handle */
static zoitechat_plugin *ph;
static GSList *timer_list = NULL;
#define STATIC
@@ -146,7 +146,6 @@ timer_showlist (void)
zoitechat_print (ph, _(HELP));
return;
}
/* 00000 00000000 0000000 abc */
zoitechat_print (ph, _("\026 Ref# Seconds Repeat Command \026\n"));
list = timer_list;
while (list)
@@ -218,7 +217,6 @@ zoitechat_plugin_init
(zoitechat_plugin *plugin_handle, char **plugin_name,
char **plugin_desc, char **plugin_version, char *arg)
{
/* we need to save this for use with any zoitechat_* functions */
ph = plugin_handle;
*plugin_name = "Timer";
@@ -227,5 +225,5 @@ zoitechat_plugin_init
zoitechat_hook_command (ph, "TIMER", ZOITECHAT_PRI_NORM, timer_cb, _(HELP), 0);
return 1; /* return 1 for success */
return 1;
}

View File

@@ -28,7 +28,6 @@
#define CLIENT_KEY "Client Key"
#define SERVER_KEY "Server Key"
// EVP_MD_CTX_create() and EVP_MD_CTX_destroy() were renamed in OpenSSL 1.1.0
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
#define EVP_MD_CTX_new(ctx) EVP_MD_CTX_create(ctx)
#define EVP_MD_CTX_free(ctx) EVP_MD_CTX_destroy(ctx)
@@ -46,7 +45,6 @@ scram_session
if (md == NULL)
{
// Unknown message digest
return NULL;
}
@@ -189,7 +187,6 @@ process_server_first (scram_session *session, const char *data, char **output,
client_nonce_len = strlen (session->client_nonce_b64);
// The server can append his nonce to the client's nonce
if (strlen (server_nonce_b64) < client_nonce_len ||
strncmp (server_nonce_b64, session->client_nonce_b64, client_nonce_len))
{
@@ -199,28 +196,22 @@ process_server_first (scram_session *session, const char *data, char **output,
g_base64_decode_inplace ((gchar *) salt, &salt_len);
// SaltedPassword := Hi(Normalize(password), salt, i)
session->salted_password = g_malloc (session->digest_size);
PKCS5_PBKDF2_HMAC (session->password, strlen (session->password), (unsigned char *) salt,
salt_len, iteration_count, session->digest, session->digest_size,
session->salted_password);
// AuthMessage := client-first-message-bare + "," +
// server-first-message + "," +
// client-final-message-without-proof
client_final_message_without_proof = g_strdup_printf ("c=biws,r=%s", server_nonce_b64);
session->auth_message = g_strdup_printf ("%s,%s,%s", session->client_first_message_bare,
data, client_final_message_without_proof);
// ClientKey := HMAC(SaltedPassword, "Client Key")
client_key = g_malloc0 (session->digest_size);
HMAC (session->digest, session->salted_password, session->digest_size,
(unsigned char *) CLIENT_KEY, strlen (CLIENT_KEY), client_key, &client_key_len);
// StoredKey := H(ClientKey)
if (!create_SHA (session, client_key, session->digest_size, stored_key, &stored_key_len))
{
g_free (client_final_message_without_proof);
@@ -230,12 +221,10 @@ process_server_first (scram_session *session, const char *data, char **output,
return SCRAM_ERROR;
}
// ClientSignature := HMAC(StoredKey, AuthMessage)
client_signature = g_malloc0 (session->digest_size);
HMAC (session->digest, stored_key, stored_key_len, (unsigned char *) session->auth_message,
strlen ((char *) session->auth_message), client_signature, NULL);
// ClientProof := ClientKey XOR ClientSignature
client_proof = g_malloc0 (client_key_len);
for (i = 0; i < client_key_len; i++)
@@ -276,12 +265,10 @@ process_server_final (scram_session *session, const char *data)
verifier = g_strdup (data + 2);
g_base64_decode_inplace (verifier, &verifier_len);
// ServerKey := HMAC(SaltedPassword, "Server Key")
server_key = g_malloc0 (session->digest_size);
HMAC (session->digest, session->salted_password, session->digest_size,
(unsigned char *) SERVER_KEY, strlen (SERVER_KEY), server_key, &server_key_len);
// ServerSignature := HMAC(ServerKey, AuthMessage)
server_signature = g_malloc0 (session->digest_size);
HMAC (session->digest, server_key, session->digest_size,
(unsigned char *) session->auth_message, strlen ((char *) session->auth_message),
@@ -330,4 +317,4 @@ scram_process (scram_session *session, const char *input, char **output, size_t
return status;
}
#endif
#endif

View File

@@ -510,16 +510,7 @@ server_stopconnecting (server * serv)
static void
ssl_cb_info (SSL * s, int where, int ret)
{
/* char buf[128];*/
return; /* FIXME: make debug level adjustable in serverlist or settings */
/* g_snprintf (buf, sizeof (buf), "%s (%d)", SSL_state_string_long (s), where);
if (g_sess)
EMIT_SIGNAL (XP_TE_SSLMESSAGE, g_sess, buf, NULL, NULL, NULL, 0);
else
fprintf (stderr, "%s\n", buf);*/
}
static int
@@ -625,14 +616,6 @@ ssl_do_connect (server * serv)
cert_info.algorithm, cert_info.algorithm_bits);
EMIT_SIGNAL (XP_TE_SSLMESSAGE, serv->server_session, buf, NULL, NULL,
NULL, 0);
/*if (cert_info.rsa_tmp_bits)
{
g_snprintf (buf, sizeof (buf),
" Public key algorithm uses ephemeral key with %d bits",
cert_info.rsa_tmp_bits);
EMIT_SIGNAL (XP_TE_SSLMESSAGE, serv->server_session, buf, NULL, NULL,
NULL, 0);
}*/
g_snprintf (buf, sizeof (buf), " Sign algorithm %s",
cert_info.sign_algorithm/*, cert_info.sign_algorithm_bits*/);
EMIT_SIGNAL (XP_TE_SSLMESSAGE, serv->server_session, buf, NULL, NULL,
@@ -675,8 +658,6 @@ ssl_do_connect (server * serv)
}
break;
}
/* g_snprintf (buf, sizeof (buf), "* Verify OK (?)"); */
/* EMIT_SIGNAL (XP_TE_SSLMESSAGE, serv->server_session, buf, NULL, NULL, NULL, 0); */
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
@@ -1870,11 +1851,9 @@ server_set_defaults (server *serv)
char *
server_get_network (server *serv, gboolean fallback)
{
/* check the network list */
if (serv->network)
return ((ircnet *)serv->network)->name;
/* check the network name given in 005 NETWORK=... */
if (serv->server_session && *serv->server_session->channel)
return serv->server_session->channel;
@@ -1893,7 +1872,6 @@ server_set_name (server *serv, char *name)
if (name[0] == 0)
name = serv->hostname;
/* strncpy parameters must NOT overlap */
if (name != serv->servername)
{
safe_strcpy (serv->servername, name, sizeof (serv->servername));

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}
};
@@ -1065,7 +1065,7 @@ servlist_load (void)
}
}
if (buf[0] == 'N')
net = servlist_net_add (buf + 2, /* comment */ NULL, FALSE);
net = servlist_net_add (buf + 2, NULL, FALSE);
}
fclose (fp);

View File

@@ -125,8 +125,4 @@ GSList *servlist_favchan_listadd (GSList *chanlist, char *channel, char *key);
gboolean joinlist_is_in_list (server *serv, char *channel);
/* FIXME
void joinlist_split (char *autojoin, GSList **channels, GSList **keys);
void joinlist_free (GSList *channels, GSList *keys);
*/
#endif

View File

@@ -465,7 +465,6 @@ static char *read_hdd_info (IWbemClassObject *object)
if (name_len >= 4 && name_bstr[0] == L'\\' && name_bstr[1] == L'\\' && name_bstr[2] == L'?' && name_bstr[3] == L'\\')
{
// This is not a named volume. Skip it.
VariantClear (&name_variant);
return NULL;

View File

@@ -0,0 +1,684 @@
#include <glib.h>
#include <glib/gstdio.h>
#include "../gtk3-theme-service.h"
#include "../cfgfiles.h"
char *xdir = NULL;
char *
get_xdir (void)
{
return xdir;
}
static void
write_text_file (const char *path, const char *contents)
{
g_file_set_contents (path, contents, -1, NULL);
}
static char *
make_theme_dir (const char *base, const char *name, gboolean dark, gboolean with_index)
{
char *root = g_build_filename (base, name, NULL);
char *gtk_dir = g_build_filename (root, "gtk-3.0", NULL);
char *css = g_build_filename (gtk_dir, "gtk.css", NULL);
g_mkdir_with_parents (gtk_dir, 0700);
write_text_file (css, "button { background-image: url(\"../assets/a.png\"); }");
if (dark)
{
char *dark_css = g_build_filename (gtk_dir, "gtk-dark.css", NULL);
write_text_file (dark_css, "button { color: #eee; }");
g_free (dark_css);
}
if (with_index)
{
char *index = g_build_filename (root, "index.theme", NULL);
write_text_file (index, "[Desktop Entry]\nName=Indexed Theme\n");
g_free (index);
}
g_free (css);
g_free (gtk_dir);
return root;
}
static void
setup_test_xdir (char **tmp_root)
{
char *root = g_dir_make_tmp ("zoitechat-gtk3-service-test-XXXXXX", NULL);
xdir = g_build_filename (root, "config", NULL);
g_mkdir_with_parents (xdir, 0700);
*tmp_root = root;
}
static void
teardown_test_xdir (char *tmp_root)
{
char *cmd;
cmd = g_strdup_printf ("rm -rf %s", tmp_root);
g_spawn_command_line_sync (cmd, NULL, NULL, NULL, NULL);
g_free (cmd);
g_free (xdir);
xdir = NULL;
g_free (tmp_root);
}
static guint
count_extract_temp_dirs (void)
{
GDir *dir;
const char *name;
guint count = 0;
const char *tmp_dir = g_get_tmp_dir ();
dir = g_dir_open (tmp_dir, 0, NULL);
if (!dir)
return 0;
while ((name = g_dir_read_name (dir)) != NULL)
{
if (g_str_has_prefix (name, "zoitechat-gtk3-theme-"))
count++;
}
g_dir_close (dir);
return count;
}
static char *
make_theme_dir_with_inherits (const char *base, const char *name, const char *inherits)
{
char *root = make_theme_dir (base, name, FALSE, FALSE);
char *index = g_build_filename (root, "index.theme", NULL);
char *contents;
if (inherits && inherits[0])
contents = g_strdup_printf ("[Desktop Entry]\nName=%s\nInherits=%s\n", name, inherits);
else
contents = g_strdup_printf ("[Desktop Entry]\nName=%s\n", name);
write_text_file (index, contents);
g_free (contents);
g_free (index);
return root;
}
static void
test_inheritance_chain_single_parent (void)
{
char *tmp_root;
char *themes_root;
char *adwaita;
char *child;
GPtrArray *chain;
setup_test_xdir (&tmp_root);
themes_root = g_build_filename (tmp_root, "themes", NULL);
g_mkdir_with_parents (themes_root, 0700);
adwaita = make_theme_dir_with_inherits (themes_root, "Adwaita", NULL);
child = make_theme_dir_with_inherits (themes_root, "Child", "Adwaita");
chain = zoitechat_gtk3_theme_build_inheritance_chain (child);
g_assert_nonnull (chain);
g_assert_cmpuint (chain->len, ==, 2);
g_assert_cmpstr (g_ptr_array_index (chain, 0), ==, adwaita);
g_assert_cmpstr (g_ptr_array_index (chain, 1), ==, child);
g_ptr_array_unref (chain);
g_free (child);
g_free (adwaita);
g_free (themes_root);
teardown_test_xdir (tmp_root);
}
static void
test_inheritance_chain_multi_level (void)
{
char *tmp_root;
char *themes_root;
char *base;
char *middle;
char *child;
GPtrArray *chain;
setup_test_xdir (&tmp_root);
themes_root = g_build_filename (tmp_root, "themes", NULL);
g_mkdir_with_parents (themes_root, 0700);
base = make_theme_dir_with_inherits (themes_root, "Base", NULL);
middle = make_theme_dir_with_inherits (themes_root, "Middle", "Base");
child = make_theme_dir_with_inherits (themes_root, "Child", "Middle");
chain = zoitechat_gtk3_theme_build_inheritance_chain (child);
g_assert_nonnull (chain);
g_assert_cmpuint (chain->len, ==, 3);
g_assert_cmpstr (g_ptr_array_index (chain, 0), ==, base);
g_assert_cmpstr (g_ptr_array_index (chain, 1), ==, middle);
g_assert_cmpstr (g_ptr_array_index (chain, 2), ==, child);
g_ptr_array_unref (chain);
g_free (child);
g_free (middle);
g_free (base);
g_free (themes_root);
teardown_test_xdir (tmp_root);
}
static void
test_inheritance_chain_missing_parent (void)
{
char *tmp_root;
char *themes_root;
char *child;
GPtrArray *chain;
setup_test_xdir (&tmp_root);
themes_root = g_build_filename (tmp_root, "themes", NULL);
g_mkdir_with_parents (themes_root, 0700);
child = make_theme_dir_with_inherits (themes_root, "Child", "MissingParent");
chain = zoitechat_gtk3_theme_build_inheritance_chain (child);
g_assert_nonnull (chain);
g_assert_cmpuint (chain->len, ==, 1);
g_assert_cmpstr (g_ptr_array_index (chain, 0), ==, child);
g_ptr_array_unref (chain);
g_free (child);
g_free (themes_root);
teardown_test_xdir (tmp_root);
}
static void
test_inheritance_chain_parent_from_xdg_data_home (void)
{
char *tmp_root;
char *child_root;
char *home_dir;
char *user_data_dir;
char *saved_home;
char *saved_xdg_data_home;
char *parent;
char *child;
GPtrArray *chain;
setup_test_xdir (&tmp_root);
child_root = g_build_filename (tmp_root, "themes", NULL);
home_dir = g_build_filename (tmp_root, "home", NULL);
user_data_dir = g_build_filename (tmp_root, "xdg-data-home", NULL);
g_mkdir_with_parents (child_root, 0700);
g_mkdir_with_parents (home_dir, 0700);
g_mkdir_with_parents (user_data_dir, 0700);
saved_home = g_strdup (g_getenv ("HOME"));
saved_xdg_data_home = g_strdup (g_getenv ("XDG_DATA_HOME"));
g_setenv ("HOME", home_dir, TRUE);
g_setenv ("XDG_DATA_HOME", user_data_dir, TRUE);
{
char *user_themes = g_build_filename (user_data_dir, "themes", NULL);
g_mkdir_with_parents (user_themes, 0700);
parent = make_theme_dir_with_inherits (user_themes, "ParentFromDataHome", NULL);
g_free (user_themes);
}
child = make_theme_dir_with_inherits (child_root, "Child", "ParentFromDataHome");
chain = zoitechat_gtk3_theme_build_inheritance_chain (child);
g_assert_nonnull (chain);
g_assert_cmpuint (chain->len, ==, 2);
g_assert_cmpstr (g_ptr_array_index (chain, 0), ==, parent);
g_assert_cmpstr (g_ptr_array_index (chain, 1), ==, child);
g_ptr_array_unref (chain);
if (saved_home)
g_setenv ("HOME", saved_home, TRUE);
else
g_unsetenv ("HOME");
if (saved_xdg_data_home)
g_setenv ("XDG_DATA_HOME", saved_xdg_data_home, TRUE);
else
g_unsetenv ("XDG_DATA_HOME");
g_free (child);
g_free (parent);
g_free (saved_xdg_data_home);
g_free (saved_home);
g_free (user_data_dir);
g_free (home_dir);
g_free (child_root);
teardown_test_xdir (tmp_root);
}
static void
test_inheritance_chain_parent_from_xdg_data_dirs (void)
{
char *tmp_root;
char *child_root;
char *home_dir;
char *system_data_dir;
char *system_data_dirs;
char *saved_home;
char *saved_xdg_data_dirs;
char *parent;
char *child;
GPtrArray *chain;
setup_test_xdir (&tmp_root);
child_root = g_build_filename (tmp_root, "themes", NULL);
home_dir = g_build_filename (tmp_root, "home", NULL);
system_data_dir = g_build_filename (tmp_root, "xdg-data-system", NULL);
system_data_dirs = g_strdup_printf ("%s:/usr/share", system_data_dir);
g_mkdir_with_parents (child_root, 0700);
g_mkdir_with_parents (home_dir, 0700);
g_mkdir_with_parents (system_data_dir, 0700);
saved_home = g_strdup (g_getenv ("HOME"));
saved_xdg_data_dirs = g_strdup (g_getenv ("XDG_DATA_DIRS"));
g_setenv ("HOME", home_dir, TRUE);
g_setenv ("XDG_DATA_DIRS", system_data_dirs, TRUE);
{
char *system_themes = g_build_filename (system_data_dir, "themes", NULL);
g_mkdir_with_parents (system_themes, 0700);
parent = make_theme_dir_with_inherits (system_themes, "ParentFromDataDirs", NULL);
g_free (system_themes);
}
child = make_theme_dir_with_inherits (child_root, "Child", "ParentFromDataDirs");
chain = zoitechat_gtk3_theme_build_inheritance_chain (child);
g_assert_nonnull (chain);
g_assert_cmpuint (chain->len, ==, 2);
g_assert_cmpstr (g_ptr_array_index (chain, 0), ==, parent);
g_assert_cmpstr (g_ptr_array_index (chain, 1), ==, child);
g_ptr_array_unref (chain);
if (saved_home)
g_setenv ("HOME", saved_home, TRUE);
else
g_unsetenv ("HOME");
if (saved_xdg_data_dirs)
g_setenv ("XDG_DATA_DIRS", saved_xdg_data_dirs, TRUE);
else
g_unsetenv ("XDG_DATA_DIRS");
g_free (child);
g_free (parent);
g_free (saved_xdg_data_dirs);
g_free (saved_home);
g_free (system_data_dirs);
g_free (system_data_dir);
g_free (home_dir);
g_free (child_root);
teardown_test_xdir (tmp_root);
}
static void
test_invalid_archive_reports_extract_error (void)
{
char *tmp_root;
char *bad_archive;
char *imported_id = NULL;
GError *error = NULL;
guint before_count;
guint after_count;
setup_test_xdir (&tmp_root);
bad_archive = g_build_filename (tmp_root, "bad-theme.tar.xz", NULL);
write_text_file (bad_archive, "this is not a real archive");
before_count = count_extract_temp_dirs ();
g_assert_false (zoitechat_gtk3_theme_service_import (bad_archive, &imported_id, &error));
g_assert_null (imported_id);
g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED);
g_assert_cmpstr (error->message, ==, "Failed to extract theme archive.");
g_error_free (error);
after_count = count_extract_temp_dirs ();
g_assert_cmpuint (after_count, ==, before_count);
g_free (bad_archive);
teardown_test_xdir (tmp_root);
}
static void
test_archive_without_theme_reports_css_error (void)
{
char *tmp_root;
char *archive_root;
char *archive_path;
char *command;
char *imported_id = NULL;
GError *error = NULL;
setup_test_xdir (&tmp_root);
archive_root = g_build_filename (tmp_root, "invalid-theme-root", NULL);
g_mkdir_with_parents (archive_root, 0700);
{
char *readme = g_build_filename (archive_root, "README.txt", NULL);
write_text_file (readme, "not a gtk theme");
g_free (readme);
}
archive_path = g_build_filename (tmp_root, "invalid-theme.zip", NULL);
command = g_strdup_printf ("cd %s && zip -qr %s .", archive_root, archive_path);
g_assert_true (g_spawn_command_line_sync (command, NULL, NULL, NULL, NULL));
g_free (command);
g_assert_false (zoitechat_gtk3_theme_service_import (archive_path, &imported_id, &error));
g_assert_null (imported_id);
g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL);
g_assert_cmpstr (error->message, ==, "No GTK3 gtk.css file found in the selected theme.");
g_error_free (error);
g_free (archive_path);
g_free (archive_root);
teardown_test_xdir (tmp_root);
}
static void
test_import_rejects_theme_missing_index_theme (void)
{
char *tmp_root;
char *src_root;
char *theme_root;
char *imported_id = NULL;
GError *error = NULL;
setup_test_xdir (&tmp_root);
src_root = g_build_filename (tmp_root, "src", NULL);
g_mkdir_with_parents (src_root, 0700);
theme_root = make_theme_dir (src_root, "NoIndex", FALSE, FALSE);
g_assert_false (zoitechat_gtk3_theme_service_import (theme_root, &imported_id, &error));
g_assert_null (imported_id);
g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL);
g_assert_nonnull (g_strstr_len (error->message, -1, "missing required index.theme"));
g_assert_nonnull (g_strstr_len (error->message, -1, "NoIndex"));
g_error_free (error);
g_free (theme_root);
g_free (src_root);
teardown_test_xdir (tmp_root);
}
static void
test_import_rejects_index_without_desktop_entry (void)
{
char *tmp_root;
char *src_root;
char *theme_root;
char *index_path;
char *imported_id = NULL;
GError *error = NULL;
setup_test_xdir (&tmp_root);
src_root = g_build_filename (tmp_root, "src", NULL);
g_mkdir_with_parents (src_root, 0700);
theme_root = make_theme_dir (src_root, "NoDesktopEntry", FALSE, FALSE);
index_path = g_build_filename (theme_root, "index.theme", NULL);
write_text_file (index_path, "[X-GNOME-Metatheme]\nName=Broken\n");
g_assert_false (zoitechat_gtk3_theme_service_import (theme_root, &imported_id, &error));
g_assert_null (imported_id);
g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL);
g_assert_nonnull (g_strstr_len (error->message, -1, "missing the [Desktop Entry] section"));
g_assert_nonnull (g_strstr_len (error->message, -1, "index.theme"));
g_error_free (error);
g_free (index_path);
g_free (theme_root);
g_free (src_root);
teardown_test_xdir (tmp_root);
}
static void
test_import_rejects_unresolved_inherits (void)
{
char *tmp_root;
char *src_root;
char *theme_root;
char *imported_id = NULL;
GError *error = NULL;
setup_test_xdir (&tmp_root);
src_root = g_build_filename (tmp_root, "src", NULL);
g_mkdir_with_parents (src_root, 0700);
theme_root = make_theme_dir_with_inherits (src_root, "ChildTheme", "MissingParent");
g_assert_false (zoitechat_gtk3_theme_service_import (theme_root, &imported_id, &error));
g_assert_null (imported_id);
g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL);
g_assert_nonnull (g_strstr_len (error->message, -1, "MissingParent"));
g_assert_nonnull (g_strstr_len (error->message, -1, "could not be resolved"));
g_error_free (error);
g_free (theme_root);
g_free (src_root);
teardown_test_xdir (tmp_root);
}
static void
test_import_collision_and_dark_detection (void)
{
char *tmp_root;
char *src_root;
char *theme_one;
char *id_one = NULL;
char *id_two = NULL;
ZoitechatGtk3Theme *found;
setup_test_xdir (&tmp_root);
src_root = g_build_filename (tmp_root, "src", NULL);
g_mkdir_with_parents (src_root, 0700);
theme_one = make_theme_dir (src_root, "Ocean", TRUE, FALSE);
g_assert_true (zoitechat_gtk3_theme_service_import (theme_one, &id_one, NULL));
g_assert_true (zoitechat_gtk3_theme_service_import (theme_one, &id_two, NULL));
g_assert_nonnull (id_one);
g_assert_nonnull (id_two);
g_assert_cmpstr (id_one, !=, id_two);
found = zoitechat_gtk3_theme_find_by_id (id_two);
g_assert_nonnull (found);
g_assert_true (found->has_dark_variant);
g_assert_true (g_str_has_suffix (found->path, "Ocean-1"));
zoitechat_gtk3_theme_free (found);
g_free (id_one);
g_free (id_two);
g_free (theme_one);
g_free (src_root);
teardown_test_xdir (tmp_root);
}
static void
test_discover_includes_user_and_system_data_dirs (void)
{
char *tmp_root;
char *home_dir;
char *user_data_dir;
char *system_data_dir;
char *system_data_dirs;
char *saved_home;
char *saved_xdg_data_home;
char *saved_xdg_data_dirs;
char *user_themes_dir;
char *system_themes_dir;
char *user_theme;
char *system_theme;
GPtrArray *themes;
guint i;
gboolean found_user = FALSE;
gboolean found_system = FALSE;
setup_test_xdir (&tmp_root);
home_dir = g_build_filename (tmp_root, "home", NULL);
user_data_dir = g_build_filename (tmp_root, "xdg-data-home", NULL);
system_data_dir = g_build_filename (tmp_root, "xdg-data-system", NULL);
system_data_dirs = g_strdup_printf ("%s:/usr/share", system_data_dir);
user_themes_dir = g_build_filename (user_data_dir, "themes", NULL);
system_themes_dir = g_build_filename (system_data_dir, "themes", NULL);
g_mkdir_with_parents (home_dir, 0700);
g_mkdir_with_parents (user_themes_dir, 0700);
g_mkdir_with_parents (system_themes_dir, 0700);
user_theme = make_theme_dir (user_themes_dir, "UserDataTheme", FALSE, FALSE);
system_theme = make_theme_dir (system_themes_dir, "SystemDataTheme", FALSE, FALSE);
saved_home = g_strdup (g_getenv ("HOME"));
saved_xdg_data_home = g_strdup (g_getenv ("XDG_DATA_HOME"));
saved_xdg_data_dirs = g_strdup (g_getenv ("XDG_DATA_DIRS"));
g_setenv ("HOME", home_dir, TRUE);
g_setenv ("XDG_DATA_HOME", user_data_dir, TRUE);
g_setenv ("XDG_DATA_DIRS", system_data_dirs, TRUE);
themes = zoitechat_gtk3_theme_service_discover ();
g_assert_nonnull (themes);
for (i = 0; i < themes->len; i++)
{
ZoitechatGtk3Theme *theme = g_ptr_array_index (themes, i);
if (g_strcmp0 (theme->path, user_theme) == 0)
{
found_user = TRUE;
g_assert_cmpint (theme->source, ==, ZOITECHAT_GTK3_THEME_SOURCE_USER);
}
if (g_strcmp0 (theme->path, system_theme) == 0)
{
found_system = TRUE;
g_assert_cmpint (theme->source, ==, ZOITECHAT_GTK3_THEME_SOURCE_SYSTEM);
}
}
g_assert_true (found_user);
g_assert_true (found_system);
g_ptr_array_unref (themes);
if (saved_home)
g_setenv ("HOME", saved_home, TRUE);
else
g_unsetenv ("HOME");
if (saved_xdg_data_home)
g_setenv ("XDG_DATA_HOME", saved_xdg_data_home, TRUE);
else
g_unsetenv ("XDG_DATA_HOME");
if (saved_xdg_data_dirs)
g_setenv ("XDG_DATA_DIRS", saved_xdg_data_dirs, TRUE);
else
g_unsetenv ("XDG_DATA_DIRS");
g_free (saved_xdg_data_dirs);
g_free (saved_xdg_data_home);
g_free (saved_home);
g_free (system_theme);
g_free (user_theme);
g_free (system_themes_dir);
g_free (user_themes_dir);
g_free (system_data_dirs);
g_free (system_data_dir);
g_free (user_data_dir);
g_free (home_dir);
teardown_test_xdir (tmp_root);
}
static void
test_archive_root_detection_prefers_index (void)
{
char *tmp_root;
char *archive_root;
char *theme_a;
char *theme_b_parent;
char *theme_b;
char *archive_path;
char *command;
char *imported_id = NULL;
ZoitechatGtk3Theme *found;
setup_test_xdir (&tmp_root);
archive_root = g_build_filename (tmp_root, "archive-root", NULL);
g_mkdir_with_parents (archive_root, 0700);
theme_a = make_theme_dir (archive_root, "Flat", FALSE, FALSE);
theme_b_parent = g_build_filename (archive_root, "nested", NULL);
g_mkdir_with_parents (theme_b_parent, 0700);
theme_b = make_theme_dir (theme_b_parent, "Indexed", FALSE, TRUE);
archive_path = g_build_filename (tmp_root, "themes.tar.xz", NULL);
command = g_strdup_printf ("tar -cJf %s -C %s .", archive_path, archive_root);
g_assert_true (g_spawn_command_line_sync (command, NULL, NULL, NULL, NULL));
g_free (command);
g_assert_true (zoitechat_gtk3_theme_service_import (archive_path, &imported_id, NULL));
found = zoitechat_gtk3_theme_find_by_id (imported_id);
g_assert_nonnull (found);
g_assert_true (g_str_has_suffix (found->path, "Indexed"));
zoitechat_gtk3_theme_free (found);
g_free (imported_id);
g_free (archive_path);
g_free (theme_b);
g_free (theme_b_parent);
g_free (theme_a);
g_free (archive_root);
teardown_test_xdir (tmp_root);
}
static void
test_zip_import_nested_root (void)
{
char *tmp_root;
char *zip_root;
char *nested;
char *theme;
char *archive_path;
char *command;
char *imported_id = NULL;
ZoitechatGtk3Theme *found;
setup_test_xdir (&tmp_root);
zip_root = g_build_filename (tmp_root, "zip-root", NULL);
nested = g_build_filename (zip_root, "bundle", "themes", NULL);
g_mkdir_with_parents (nested, 0700);
theme = make_theme_dir (nested, "Juno-ocean", TRUE, FALSE);
archive_path = g_build_filename (tmp_root, "themes.zip", NULL);
command = g_strdup_printf ("cd %s && zip -qr %s .", zip_root, archive_path);
g_assert_true (g_spawn_command_line_sync (command, NULL, NULL, NULL, NULL));
g_free (command);
g_assert_true (zoitechat_gtk3_theme_service_import (archive_path, &imported_id, NULL));
found = zoitechat_gtk3_theme_find_by_id (imported_id);
g_assert_nonnull (found);
g_assert_true (found->has_dark_variant);
g_assert_true (g_str_has_suffix (found->path, "Juno-ocean"));
zoitechat_gtk3_theme_free (found);
g_free (imported_id);
g_free (archive_path);
g_free (theme);
g_free (nested);
g_free (zip_root);
teardown_test_xdir (tmp_root);
}
int
main (int argc, char **argv)
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/gtk3-theme-service/inheritance-single-parent", test_inheritance_chain_single_parent);
g_test_add_func ("/gtk3-theme-service/inheritance-multi-level", test_inheritance_chain_multi_level);
g_test_add_func ("/gtk3-theme-service/inheritance-missing-parent", test_inheritance_chain_missing_parent);
g_test_add_func ("/gtk3-theme-service/inheritance-parent-from-xdg-data-home", test_inheritance_chain_parent_from_xdg_data_home);
g_test_add_func ("/gtk3-theme-service/inheritance-parent-from-xdg-data-dirs", test_inheritance_chain_parent_from_xdg_data_dirs);
g_test_add_func ("/gtk3-theme-service/import-collision-dark", test_import_collision_and_dark_detection);
g_test_add_func ("/gtk3-theme-service/discover-user-and-system-data-dirs", test_discover_includes_user_and_system_data_dirs);
g_test_add_func ("/gtk3-theme-service/archive-root-detection", test_archive_root_detection_prefers_index);
g_test_add_func ("/gtk3-theme-service/zip-import-nested-root", test_zip_import_nested_root);
g_test_add_func ("/gtk3-theme-service/invalid-archive-extract-error", test_invalid_archive_reports_extract_error);
g_test_add_func ("/gtk3-theme-service/archive-without-theme-css-error", test_archive_without_theme_reports_css_error);
g_test_add_func ("/gtk3-theme-service/import-missing-index-theme", test_import_rejects_theme_missing_index_theme);
g_test_add_func ("/gtk3-theme-service/import-missing-desktop-entry", test_import_rejects_index_without_desktop_entry);
g_test_add_func ("/gtk3-theme-service/import-unresolved-inherits", test_import_rejects_unresolved_inherits);
return g_test_run ();
}

176
src/common/theme-service.c Normal file
View File

@@ -0,0 +1,176 @@
#include <errno.h>
#include <gio/gio.h>
#include <glib/gstdio.h>
#include "cfgfiles.h"
#include "zoitechat.h"
#include "theme-service.h"
static zoitechat_theme_post_apply_callback zoitechat_theme_post_apply_cb;
static gboolean
zoitechat_theme_service_copy_file (const char *src, const char *dest, GError **error)
{
char *data = NULL;
gsize len = 0;
if (!g_file_get_contents (src, &data, &len, error))
return FALSE;
if (!g_file_set_contents (dest, data, len, error))
{
g_free (data);
return FALSE;
}
g_free (data);
return TRUE;
}
char *
zoitechat_theme_service_get_themes_dir (void)
{
return g_build_filename (get_xdir (), "themes", NULL);
}
static gboolean
zoitechat_theme_service_validate (const char *theme_name,
char **colors_src,
char **events_src,
GError **error)
{
char *themes_dir;
char *theme_dir;
if (!theme_name || !*theme_name)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
_("No theme name specified."));
return FALSE;
}
themes_dir = zoitechat_theme_service_get_themes_dir ();
theme_dir = g_build_filename (themes_dir, theme_name, NULL);
g_free (themes_dir);
*colors_src = g_build_filename (theme_dir, "colors.conf", NULL);
*events_src = g_build_filename (theme_dir, "pevents.conf", NULL);
if (!g_file_test (*colors_src, G_FILE_TEST_IS_REGULAR))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
_("This theme is missing a colors.conf file."));
g_free (*events_src);
g_free (*colors_src);
*events_src = NULL;
*colors_src = NULL;
g_free (theme_dir);
return FALSE;
}
g_free (theme_dir);
return TRUE;
}
gboolean
zoitechat_theme_service_apply (const char *theme_name, GError **error)
{
char *colors_src = NULL;
char *colors_dest = NULL;
char *events_src = NULL;
char *events_dest = NULL;
gboolean ok = FALSE;
if (!zoitechat_theme_service_validate (theme_name, &colors_src, &events_src, error))
return FALSE;
colors_dest = g_build_filename (get_xdir (), "colors.conf", NULL);
events_dest = g_build_filename (get_xdir (), "pevents.conf", NULL);
if (!zoitechat_theme_service_copy_file (colors_src, colors_dest, error))
goto cleanup;
if (g_file_test (events_src, G_FILE_TEST_IS_REGULAR))
{
if (!zoitechat_theme_service_copy_file (events_src, events_dest, error))
goto cleanup;
}
else if (g_file_test (events_dest, G_FILE_TEST_EXISTS))
{
if (g_unlink (events_dest) != 0)
{
g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
_("Failed to remove existing event settings."));
goto cleanup;
}
}
zoitechat_theme_service_run_post_apply_callback ();
ok = TRUE;
cleanup:
g_free (events_dest);
g_free (events_src);
g_free (colors_dest);
g_free (colors_src);
return ok;
}
GStrv
zoitechat_theme_service_discover_themes (void)
{
char *themes_dir;
GDir *dir;
const char *name;
GPtrArray *themes;
GStrv result;
themes_dir = zoitechat_theme_service_get_themes_dir ();
if (!g_file_test (themes_dir, G_FILE_TEST_IS_DIR))
g_mkdir_with_parents (themes_dir, 0700);
themes = g_ptr_array_new_with_free_func (g_free);
dir = g_dir_open (themes_dir, 0, NULL);
if (dir)
{
while ((name = g_dir_read_name (dir)))
{
char *theme_dir = g_build_filename (themes_dir, name, NULL);
char *colors_path;
if (!g_file_test (theme_dir, G_FILE_TEST_IS_DIR))
{
g_free (theme_dir);
continue;
}
colors_path = g_build_filename (theme_dir, "colors.conf", NULL);
if (g_file_test (colors_path, G_FILE_TEST_IS_REGULAR))
g_ptr_array_add (themes, g_strdup (name));
g_free (colors_path);
g_free (theme_dir);
}
g_dir_close (dir);
}
g_ptr_array_sort (themes, (GCompareFunc) g_strcmp0);
g_ptr_array_add (themes, NULL);
result = (GStrv) g_ptr_array_free (themes, FALSE);
g_free (themes_dir);
return result;
}
void
zoitechat_theme_service_set_post_apply_callback (zoitechat_theme_post_apply_callback callback)
{
zoitechat_theme_post_apply_cb = callback;
}
void
zoitechat_theme_service_run_post_apply_callback (void)
{
if (zoitechat_theme_post_apply_cb)
zoitechat_theme_post_apply_cb ();
}

View File

@@ -0,0 +1,12 @@
#ifndef ZOITECHAT_THEME_SERVICE_H
#define ZOITECHAT_THEME_SERVICE_H
#include <glib.h>
char *zoitechat_theme_service_get_themes_dir (void);
GStrv zoitechat_theme_service_discover_themes (void);
gboolean zoitechat_theme_service_apply (const char *theme_name, GError **error);
void zoitechat_theme_service_set_post_apply_callback (void (*callback) (void));
void zoitechat_theme_service_run_post_apply_callback (void);
#endif

View File

@@ -95,7 +95,6 @@ url_save_node (char* url)
{
FILE *fd;
/* open <config>/url.log in append mode */
fd = zoitechat_fopen_file ("url.log", "a", 0);
if (fd == NULL)
{
@@ -118,7 +117,6 @@ url_add (char *urltext, int len)
char *data;
int size;
/* we don't need any URLs if we have neither URL grabbing nor URL logging enabled */
if (!prefs.hex_url_grabber && !prefs.hex_url_logging)
{
return;
@@ -126,12 +124,11 @@ url_add (char *urltext, int len)
data = g_strndup (urltext, len);
if (data[len - 1] == '.') /* chop trailing dot */
if (data[len - 1] == '.')
{
len--;
data[len] = 0;
}
/* chop trailing ) but only if there's no counterpart */
if (data[len - 1] == ')' && strchr (data, '(') == NULL)
{
data[len - 1] = 0;
@@ -142,7 +139,6 @@ url_add (char *urltext, int len)
url_save_node (data);
}
/* the URL is saved already, only continue if we need the URL grabber too */
if (!prefs.hex_url_grabber)
{
g_free (data);
@@ -162,11 +158,8 @@ url_add (char *urltext, int len)
}
size = tree_size (url_tree);
/* 0 is unlimited */
if (prefs.hex_url_grabber_limit > 0 && size >= prefs.hex_url_grabber_limit)
{
/* the loop is necessary to handle having the limit lowered while
ZoiteChat is running */
size -= prefs.hex_url_grabber_limit;
for(; size > 0; size--)
{
@@ -183,10 +176,6 @@ url_add (char *urltext, int len)
fe_url_add (data);
}
/* check if a word is clickable. This is called on mouse motion events, so
keep it FAST! This new version was found to be almost 3x faster than
2.4.4 release. */
static int laststart = 0;
static int lastend = 0;
static int lasttype = 0;
@@ -234,7 +223,6 @@ match_nick (const char *word, int *start, int *end)
if (!regex_match (re_nick (), word, start, end))
return FALSE;
/* ignore matches with prefixes that the server doesn't use */
if (strchr (NICKPRE, word[*start])
&& !strchr (nick_prefixes, word[*start]))
return FALSE;

View File

@@ -169,13 +169,12 @@ errorstring (int err)
return tbuf;
}
}
} /* ! if (osvi.dwMajorVersion >= 5) */
}
/* fallback to error number */
sprintf (tbuf, "%s %d", _("Error"), err);
return tbuf;
} /* ! if (err >= WSABASEERR) */
#endif /* ! WIN32 */
}
#endif
return strerror (err);
}

View File

@@ -112,36 +112,9 @@ struct zoitechatprefs prefs;
gboolean
zoitechat_theme_path_from_arg (const char *arg, char **path_out)
{
char *path = NULL;
const char *ext;
if (!arg)
return FALSE;
if (g_str_has_prefix (arg, "file://"))
path = g_filename_from_uri (arg, NULL, NULL);
else
path = g_strdup (arg);
if (!path)
return FALSE;
ext = strrchr (path, '.');
if (!g_file_test (path, G_FILE_TEST_IS_REGULAR) ||
!ext ||
(g_ascii_strcasecmp (ext, ".zct") != 0 &&
g_ascii_strcasecmp (ext, ".hct") != 0))
{
g_free (path);
return FALSE;
}
if (path_out)
*path_out = path;
else
g_free (path);
return TRUE;
(void) arg;
(void) path_out;
return FALSE;
}
#ifdef WIN32
@@ -251,237 +224,19 @@ zoitechat_remote_win32 (void)
}
#endif
static zoitechat_theme_post_apply_callback zoitechat_theme_post_apply_cb;
static gboolean
zoitechat_copy_theme_file (const char *src, const char *dest, GError **error)
void
zoitechat_set_theme_post_apply_callback (zoitechat_theme_post_apply_callback callback)
{
char *data = NULL;
gsize len = 0;
if (!g_file_get_contents (src, &data, &len, error))
return FALSE;
if (!g_file_set_contents (dest, data, len, error))
{
g_free (data);
return FALSE;
}
g_free (data);
return TRUE;
zoitechat_theme_post_apply_cb = callback;
}
gboolean
zoitechat_apply_theme (const char *theme_name, GError **error)
void
zoitechat_run_theme_post_apply_callback (void)
{
char *theme_dir;
char *colors_src;
char *colors_dest;
char *events_src;
char *events_dest;
gboolean ok = FALSE;
if (!theme_name || !*theme_name)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
_("No theme name specified."));
return FALSE;
}
theme_dir = g_build_filename (get_xdir (), "themes", theme_name, NULL);
colors_src = g_build_filename (theme_dir, "colors.conf", NULL);
colors_dest = g_build_filename (get_xdir (), "colors.conf", NULL);
events_src = g_build_filename (theme_dir, "pevents.conf", NULL);
events_dest = g_build_filename (get_xdir (), "pevents.conf", NULL);
if (!g_file_test (colors_src, G_FILE_TEST_IS_REGULAR))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
_("This theme is missing a colors.conf file."));
goto cleanup;
}
if (!zoitechat_copy_theme_file (colors_src, colors_dest, error))
goto cleanup;
if (g_file_test (events_src, G_FILE_TEST_IS_REGULAR))
{
if (!zoitechat_copy_theme_file (events_src, events_dest, error))
goto cleanup;
}
else if (g_file_test (events_dest, G_FILE_TEST_EXISTS))
{
if (g_unlink (events_dest) != 0)
{
g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
_("Failed to remove existing event settings."));
goto cleanup;
}
}
ok = TRUE;
cleanup:
g_free (events_dest);
g_free (events_src);
g_free (colors_dest);
g_free (colors_src);
g_free (theme_dir);
return ok;
}
gboolean
zoitechat_import_theme (const char *path, GError **error)
{
char *themes_dir;
char *basename;
char *dot;
char *theme_dir;
char *argv[] = {"unzip", "-o", (char *)path, "-d", NULL, NULL};
int status = 0;
gboolean ok;
#ifdef WIN32
char *command = NULL;
char *powershell = NULL;
#endif
if (!path)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
_("No theme file specified."));
return FALSE;
}
themes_dir = g_build_filename (get_xdir (), "themes", NULL);
basename = g_path_get_basename (path);
if (!basename || basename[0] == '\0')
{
g_free (themes_dir);
g_free (basename);
g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
_("Failed to determine theme name."));
return FALSE;
}
dot = strrchr (basename, '.');
if (dot)
*dot = '\0';
theme_dir = g_build_filename (themes_dir, basename, NULL);
if (g_mkdir_with_parents (theme_dir, 0700) != 0)
{
g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
_("Failed to create theme directory."));
g_free (theme_dir);
g_free (basename);
g_free (themes_dir);
return FALSE;
}
#ifdef WIN32
powershell = g_find_program_in_path ("powershell.exe");
if (!powershell)
powershell = g_find_program_in_path ("powershell");
if (!powershell)
{
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_NOENT,
_("No archive extractor was found."));
ok = FALSE;
}
else
{
GString *escaped_path = g_string_new ("'");
GString *escaped_dir = g_string_new ("'");
const char *cursor;
for (cursor = path; *cursor != '\0'; cursor++)
{
if (*cursor == '\'')
g_string_append (escaped_path, "''");
else
g_string_append_c (escaped_path, *cursor);
}
g_string_append_c (escaped_path, '\'');
for (cursor = theme_dir; *cursor != '\0'; cursor++)
{
if (*cursor == '\'')
g_string_append (escaped_dir, "''");
else
g_string_append_c (escaped_dir, *cursor);
}
g_string_append_c (escaped_dir, '\'');
command = g_strdup_printf (
"Add-Type -AssemblyName WindowsBase; "
"$ErrorActionPreference='Stop'; "
"$package=[System.IO.Packaging.Package]::Open(%s); "
"try { "
"foreach ($part in $package.GetParts()) { "
"$relative=$part.Uri.OriginalString.TrimStart('/'); "
"if ([string]::IsNullOrEmpty($relative)) { continue }; "
"$destPath=[System.IO.Path]::Combine(%s, $relative); "
"$destDir=[System.IO.Path]::GetDirectoryName($destPath); "
"if ($destDir -and -not (Test-Path -LiteralPath $destDir)) { "
"[System.IO.Directory]::CreateDirectory($destDir) | Out-Null "
"}; "
"$partStream=$part.GetStream(); "
"$fileStream=[System.IO.File]::Open($destPath,[System.IO.FileMode]::Create,[System.IO.FileAccess]::Write); "
"$partStream.CopyTo($fileStream); "
"$fileStream.Dispose(); "
"$partStream.Dispose(); "
"} "
"} finally { $package.Close(); }",
escaped_path->str,
escaped_dir->str);
g_string_free (escaped_path, TRUE);
g_string_free (escaped_dir, TRUE);
{
char *ps_argv[] = {powershell, "-NoProfile", "-NonInteractive", "-Command", command, NULL};
ok = g_spawn_sync (NULL, ps_argv, NULL, 0, NULL, NULL,
NULL, NULL, &status, error);
}
}
#else
argv[4] = theme_dir;
ok = g_spawn_sync (NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL,
NULL, NULL, &status, error);
#endif
if (!ok)
{
#ifdef WIN32
g_free (command);
g_free (powershell);
#endif
g_free (theme_dir);
g_free (basename);
g_free (themes_dir);
return FALSE;
}
if (!g_spawn_check_exit_status (status, error))
{
#ifdef WIN32
g_free (command);
g_free (powershell);
#endif
g_free (theme_dir);
g_free (basename);
g_free (themes_dir);
return FALSE;
}
#ifdef WIN32
g_free (command);
g_free (powershell);
#endif
g_free (theme_dir);
g_free (basename);
g_free (themes_dir);
return TRUE;
if (zoitechat_theme_post_apply_cb)
zoitechat_theme_post_apply_cb ();
}
/*
@@ -502,16 +257,13 @@ lastact_update(session *sess)
else if (sess->tab_state & TAB_STATE_NEW_DATA)
newidx = dia? LACT_QUERY: LACT_CHAN_DATA;
/* If already first at the right position, just return */
if (oldidx == newidx &&
(newidx == LACT_NONE || g_list_index(sess_list_by_lastact[newidx], sess) == 0))
return;
/* Remove from the old position */
if (oldidx != LACT_NONE)
sess_list_by_lastact[oldidx] = g_list_remove(sess_list_by_lastact[oldidx], sess);
/* Add at the new position */
sess->lastact_idx = newidx;
if (newidx != LACT_NONE)
sess_list_by_lastact[newidx] = g_list_prepend(sess_list_by_lastact[newidx], sess);
@@ -533,7 +285,6 @@ lastact_getfirst(int (*filter) (session *sess))
session *sess = NULL;
GList *curitem;
/* 5 is the number of priority classes LACT_ */
for (i = 0; i < 5 && !sess; i++)
{
curitem = sess_list_by_lastact[i];
@@ -672,9 +423,8 @@ away_check (void)
return 1;
doover:
/* request an update of AWAY status of 1 channel every 30 seconds */
full = TRUE;
sent = 0; /* number of WHOs (users) requested */
sent = 0;
list = sess_list;
while (list)
{
@@ -689,12 +439,10 @@ doover:
{
full = FALSE;
/* if we're under 31 WHOs, send another channels worth */
if (sent < 31 && !sess->doing_who)
{
sess->done_away_check = TRUE;
sess->doing_who = TRUE;
/* this'll send a WHO #channel */
sess->server->p_away_status (sess->server, sess->channel);
sent += sess->total;
}
@@ -704,7 +452,6 @@ doover:
list = list->next;
}
/* done them all, reset done_away_check to FALSE and start over unless we have away-notify */
if (full)
{
list = sess_list;
@@ -723,22 +470,20 @@ doover:
return 1;
}
/* these are only run if the lagometer is enabled */
static int
zoitechat_lag_check (void) /* this gets called every 30 seconds */
zoitechat_lag_check (void)
{
lag_check ();
return 1;
}
static int
zoitechat_lag_check_update (void) /* this gets called every 0.5 seconds */
zoitechat_lag_check_update (void)
{
lagcheck_update ();
return 1;
}
/* call whenever timeout intervals change */
void
zoitechat_reinit_timers (void)
{
@@ -746,7 +491,6 @@ zoitechat_reinit_timers (void)
static int lag_check_tag = 0;
static int away_tag = 0;
/* notify timeout */
if (prefs.hex_notify_timeout && notify_tag == 0)
{
notify_tag = fe_timeout_add_seconds (prefs.hex_notify_timeout,
@@ -758,7 +502,6 @@ zoitechat_reinit_timers (void)
notify_tag = 0;
}
/* away status tracking */
if (prefs.hex_away_track && away_tag == 0)
{
away_tag = fe_timeout_add_seconds (prefs.hex_away_timeout, away_check, NULL);
@@ -769,7 +512,6 @@ zoitechat_reinit_timers (void)
away_tag = 0;
}
/* lag-o-meter */
if (prefs.hex_gui_lagometer && lag_check_update_tag == 0)
{
lag_check_update_tag = fe_timeout_add (500, zoitechat_lag_check_update, NULL);
@@ -780,7 +522,6 @@ zoitechat_reinit_timers (void)
lag_check_update_tag = 0;
}
/* network timeouts and lag-o-meter */
if ((prefs.hex_net_ping_timeout != 0 || prefs.hex_gui_lagometer)
&& lag_check_tag == 0)
{
@@ -794,14 +535,11 @@ zoitechat_reinit_timers (void)
}
}
/* executed when the first irc window opens */
static void
irc_init (session *sess)
{
static int done_init = FALSE;
char *buf;
char *theme_path;
if (done_init)
return;
@@ -824,51 +562,10 @@ irc_init (session *sess)
if (arg_url != NULL)
{
theme_path = NULL;
if (zoitechat_theme_path_from_arg (arg_url, &theme_path))
{
GError *error = NULL;
char *basename = g_path_get_basename (theme_path);
char *dot = strrchr (basename, '.');
char *message;
if (dot)
*dot = '\0';
if (zoitechat_import_theme (theme_path, &error))
{
if (zoitechat_apply_theme (basename, &error))
{
message = g_strdup_printf (_("Theme \"%s\" imported and applied."), basename);
fe_message (message, FE_MSG_INFO);
handle_command (sess, "gui apply", FALSE);
g_free (message);
}
else
{
fe_message (error ? error->message : _("Theme imported, but failed to apply."),
FE_MSG_ERROR);
g_clear_error (&error);
}
}
else
{
fe_message (error ? error->message : _("Failed to import theme."),
FE_MSG_ERROR);
g_clear_error (&error);
}
g_free (basename);
}
else
{
buf = g_strdup_printf ("server %s", arg_url);
handle_command (sess, buf, FALSE);
g_free (buf);
}
g_free (theme_path);
g_free (arg_url); /* from GOption */
buf = g_strdup_printf ("server %s", arg_url);
handle_command (sess, buf, FALSE);
g_free (buf);
g_free (arg_url);
}
if (arg_urls != NULL)
@@ -876,50 +573,9 @@ irc_init (session *sess)
guint i;
for (i = 0; i < g_strv_length (arg_urls); i++)
{
theme_path = NULL;
if (zoitechat_theme_path_from_arg (arg_urls[i], &theme_path))
{
GError *error = NULL;
char *basename = g_path_get_basename (theme_path);
char *dot = strrchr (basename, '.');
char *message;
if (dot)
*dot = '\0';
if (zoitechat_import_theme (theme_path, &error))
{
if (zoitechat_apply_theme (basename, &error))
{
message = g_strdup_printf (_("Theme \"%s\" imported and applied."), basename);
fe_message (message, FE_MSG_INFO);
handle_command (sess, "gui apply", FALSE);
g_free (message);
}
else
{
fe_message (error ? error->message : _("Theme imported, but failed to apply."),
FE_MSG_ERROR);
g_clear_error (&error);
}
}
else
{
fe_message (error ? error->message : _("Failed to import theme."),
FE_MSG_ERROR);
g_clear_error (&error);
}
g_free (basename);
}
else
{
buf = g_strdup_printf ("%s %s", i==0? "server" : "newserver", arg_urls[i]);
handle_command (sess, buf, FALSE);
g_free (buf);
}
g_free (theme_path);
buf = g_strdup_printf ("%s %s", i == 0 ? "server" : "newserver", arg_urls[i]);
handle_command (sess, buf, FALSE);
g_free (buf);
}
g_strfreev (arg_urls);
}

View File

@@ -24,14 +24,15 @@
#include <glib/gi18n.h>
#include <gio/gio.h>
#include <time.h> /* need time_t */
#include <time.h>
#ifndef ZOITECHAT_H
#define ZOITECHAT_H
gboolean zoitechat_theme_path_from_arg (const char *arg, char **path_out);
gboolean zoitechat_import_theme (const char *path, GError **error);
gboolean zoitechat_apply_theme (const char *theme_name, GError **error);
typedef void (*zoitechat_theme_post_apply_callback) (void);
void zoitechat_set_theme_post_apply_callback (zoitechat_theme_post_apply_callback callback);
void zoitechat_run_theme_post_apply_callback (void);
#ifdef USE_OPENSSL
#ifdef __APPLE__
@@ -44,11 +45,11 @@ gboolean zoitechat_apply_theme (const char *theme_name, GError **error);
#include "tree.h"
#ifdef USE_OPENSSL
#include <openssl/ssl.h> /* SSL_() */
#include <openssl/ssl.h>
#include "scram.h"
#endif
#ifdef __EMX__ /* for o/s 2 */
#ifdef __EMX__
#define OFLAGS O_BINARY
#define g_ascii_strcasecmp stricmp
#define g_ascii_strncasecmp strnicmp
@@ -59,7 +60,7 @@ gboolean zoitechat_apply_theme (const char *theme_name, GError **error);
/* force a 32bit CMP.L */
#define WORDL(c0, c1, c2, c3) (guint32)(c0 | (c1 << 8) | (c2 << 16) | (c3 << 24))
#ifdef WIN32 /* for win32 */
#ifdef WIN32
#define OFLAGS O_BINARY
#define sleep(t) Sleep(t*1000)
#include <direct.h>
@@ -71,7 +72,7 @@ gboolean zoitechat_apply_theme (const char *theme_name, GError **error);
#define S_ISDIR(m) ((m) & _S_IFDIR)
#endif
#define NETWORK_PRIVATE
#else /* for unix */
#else
#define OFLAGS 0
#endif
@@ -140,6 +141,7 @@ struct zoitechatprefs
unsigned int hex_gui_tab_dots;
unsigned int hex_gui_tab_icons;
unsigned int hex_gui_dark_mode;
unsigned int hex_gui_gtk3_variant;
unsigned int hex_gui_tab_scrollchans;
unsigned int hex_gui_tab_server;
unsigned int hex_gui_tab_sort;
@@ -320,6 +322,7 @@ struct zoitechatprefs
char hex_text_font[4 * FONTNAMELEN + 1];
char hex_text_font_main[FONTNAMELEN + 1];
char hex_text_font_alternative[3 * FONTNAMELEN + 1];
char hex_gui_gtk3_theme[256];
char hex_text_spell_langs[64];
/* these are the private variables */

View File

@@ -27,6 +27,7 @@
#endif
#include "fe-gtk.h"
#include "theme/theme-manager.h"
#include "../common/zoitechat.h"
#include "../common/fe.h"
@@ -563,6 +564,7 @@ banlist_clear (GtkWidget * wid, banlist_info *banl)
dialog = gtk_message_dialog_new (NULL, 0,
GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL,
_("Are you sure you want to remove all listed items in %s?"), banl->sess->channel);
theme_manager_attach_window (dialog);
g_signal_connect (G_OBJECT (dialog), "response",
G_CALLBACK (banlist_clear_cb), banl);

View File

@@ -36,6 +36,21 @@ static int ignore_toggle = FALSE;
static int tab_left_is_moving = 0;
static int tab_right_is_moving = 0;
typedef struct
{
GtkAdjustment *adj;
gdouble current_value;
gdouble target_value;
gint direction;
gdouble step_size;
guint source_id;
int *moving_flag;
gboolean is_left;
} tab_scroll_animation;
static tab_scroll_animation *tab_left_animation;
static tab_scroll_animation *tab_right_animation;
/* userdata for gobjects used here:
*
* tab (togglebuttons inside boxes):
@@ -149,6 +164,92 @@ tab_search_offset (GtkWidget *inner, gint start_offset,
return 0;
}
static gboolean
tab_scroll_animation_tick (gpointer userdata)
{
tab_scroll_animation *animation = userdata;
gboolean reached_target;
animation->current_value += animation->step_size * animation->direction;
if (animation->direction < 0)
reached_target = animation->current_value <= animation->target_value;
else
reached_target = animation->current_value >= animation->target_value;
if (reached_target)
animation->current_value = animation->target_value;
gtk_adjustment_set_value (animation->adj, animation->current_value);
if (!reached_target)
return G_SOURCE_CONTINUE;
*animation->moving_flag = 0;
animation->source_id = 0;
if (animation->is_left)
tab_left_animation = NULL;
else
tab_right_animation = NULL;
g_object_unref (animation->adj);
g_free (animation);
return G_SOURCE_REMOVE;
}
static void
tab_scroll_animation_cancel (tab_scroll_animation **animation)
{
if (*animation == NULL)
return;
if ((*animation)->source_id != 0)
g_source_remove ((*animation)->source_id);
*(*animation)->moving_flag = 0;
g_object_unref ((*animation)->adj);
g_free (*animation);
*animation = NULL;
}
static void
tab_scroll_animation_start (tab_scroll_animation **slot, GtkAdjustment *adj,
gdouble current_value, gdouble target_value,
gint direction, int *moving_flag,
gboolean is_left)
{
tab_scroll_animation *animation;
gdouble distance;
gdouble frames;
distance = target_value - current_value;
if (distance < 0.0)
distance = -distance;
if (distance <= 0.0)
{
gtk_adjustment_set_value (adj, target_value);
*moving_flag = 0;
return;
}
animation = g_new0 (tab_scroll_animation, 1);
animation->adj = g_object_ref (adj);
animation->current_value = current_value;
animation->target_value = target_value;
animation->direction = direction;
frames = 12.0;
animation->step_size = distance / MAX (1.0, frames);
animation->moving_flag = moving_flag;
animation->is_left = is_left;
*moving_flag = 1;
animation->source_id = g_timeout_add (16, tab_scroll_animation_tick, animation);
*slot = animation;
}
static void
tab_scroll_left_up_clicked (GtkWidget *widget, chanview *cv)
{
@@ -157,7 +258,6 @@ tab_scroll_left_up_clicked (GtkWidget *widget, chanview *cv)
gfloat new_value;
GtkWidget *inner;
GdkWindow *parent_win;
gdouble i;
inner = ((tabview *)cv)->inner;
parent_win = gtk_widget_get_window (gtk_widget_get_parent (inner));
@@ -177,25 +277,15 @@ tab_scroll_left_up_clicked (GtkWidget *widget, chanview *cv)
if (new_value + viewport_size > gtk_adjustment_get_upper (adj))
new_value = gtk_adjustment_get_upper (adj) - viewport_size;
if (!tab_left_is_moving)
if (tab_left_is_moving)
{
tab_left_is_moving = 1;
for (i = gtk_adjustment_get_value (adj); ((i > new_value) && (tab_left_is_moving)); i -= 0.1)
{
gtk_adjustment_set_value (adj, i);
while (g_main_context_pending (NULL))
g_main_context_iteration (NULL, TRUE);
}
gtk_adjustment_set_value (adj, new_value);
tab_left_is_moving = 0; /* hSP: set to false in case we didnt get stopped (the normal case) */
}
else
{
tab_left_is_moving = 0; /* hSP: jump directly to next element if user is clicking faster than we can scroll.. */
tab_scroll_animation_cancel (&tab_left_animation);
return;
}
tab_scroll_animation_start (&tab_left_animation, adj,
gtk_adjustment_get_value (adj), new_value,
-1, &tab_left_is_moving, TRUE);
}
static void
@@ -206,7 +296,6 @@ tab_scroll_right_down_clicked (GtkWidget *widget, chanview *cv)
gfloat new_value;
GtkWidget *inner;
GdkWindow *parent_win;
gdouble i;
inner = ((tabview *)cv)->inner;
parent_win = gtk_widget_get_window (gtk_widget_get_parent (inner));
@@ -226,25 +315,15 @@ tab_scroll_right_down_clicked (GtkWidget *widget, chanview *cv)
if (new_value == 0 || new_value + viewport_size > gtk_adjustment_get_upper (adj))
new_value = gtk_adjustment_get_upper (adj) - viewport_size;
if (!tab_right_is_moving)
if (tab_right_is_moving)
{
tab_right_is_moving = 1;
for (i = gtk_adjustment_get_value (adj); ((i < new_value) && (tab_right_is_moving)); i += 0.1)
{
gtk_adjustment_set_value (adj, i);
while (g_main_context_pending (NULL))
g_main_context_iteration (NULL, TRUE);
}
gtk_adjustment_set_value (adj, new_value);
tab_right_is_moving = 0; /* hSP: set to false in case we didnt get stopped (the normal case) */
}
else
{
tab_right_is_moving = 0; /* hSP: jump directly to next element if user is clicking faster than we can scroll.. */
tab_scroll_animation_cancel (&tab_right_animation);
return;
}
tab_scroll_animation_start (&tab_right_animation, adj,
gtk_adjustment_get_value (adj), new_value,
1, &tab_right_is_moving, FALSE);
}
static gboolean
@@ -332,7 +411,6 @@ cv_tabs_init (chanview *cv)
((tabview *)cv)->outer = outer;
g_signal_connect (G_OBJECT (outer), "size_allocate",
G_CALLBACK (cv_tabs_sizealloc), cv);
/* gtk_container_set_border_width (GTK_CONTAINER (outer), 2);*/
gtk_widget_show (outer);
viewport = gtk_viewport_new (0, 0);
@@ -574,7 +652,7 @@ tab_pressed_cb (GtkToggleButton *tab, chan *ch)
ignore_toggle = FALSE;
cv->focused = ch;
if (/*tab->active*/is_switching)
if (is_switching)
/* call the focus callback */
cv->cb_focus (cv, ch, ch->tag, ch->userdata);
}

View File

@@ -27,6 +27,8 @@ typedef struct
#include <gdk/gdk.h>
#include "theme/theme-access.h"
static void /* row-activated, when a row is double clicked */
cv_tree_activated_cb (GtkTreeView *view, GtkTreePath *path,
GtkTreeViewColumn *column, gpointer data)
@@ -136,14 +138,14 @@ cv_tree_init (chanview *cv)
gtk_widget_set_hexpand (view, TRUE);
gtk_widget_set_vexpand (view, TRUE);
gtk_widget_set_name (view, "zoitechat-tree");
if (
cv->font_desc
)
{
gtkutil_apply_palette (view, &colors[COL_BG], &colors[COL_FG],
ThemeWidgetStyleValues style_values;
theme_get_widget_style_values_for_widget (view, &style_values);
gtkutil_apply_palette (view, &style_values.background, &style_values.foreground,
cv->font_desc);
}
/*gtk_widget_modify_base (view, GTK_STATE_NORMAL, &colors[COL_BG]);*/
/*gtk_widget_modify_base (view, GTK_STATE_NORMAL, &colors[THEME_LEGACY_TEXT_BACKGROUND]);*/
gtk_widget_set_can_focus (view, FALSE);
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (view), FALSE);

View File

@@ -28,7 +28,8 @@
#include "maingui.h"
#include "gtkutil.h"
#include "chanview.h"
#include "palette.h"
#include "theme/theme-manager.h"
#include "theme/theme-access.h"
/* treeStore columns */
#define COL_NAME 0 /* (char *) */
@@ -75,6 +76,7 @@ struct _chanview
unsigned int sorted:1;
unsigned int vertical:1;
unsigned int use_icons:1;
guint theme_listener_id;
};
struct _chan
@@ -91,6 +93,7 @@ struct _chan
static chan *cv_find_chan_by_number (chanview *cv, int num);
static int cv_find_number_of_chan (chanview *cv, chan *find_ch);
static void cv_find_neighbors_for_removal (chanview *cv, chan *find_ch, chan **left_ch, chan **first_ch);
/* ======= TABS ======= */
@@ -127,15 +130,17 @@ chanview_apply_theme (chanview *cv)
if (input_style)
font = input_style->font_desc;
if (fe_dark_mode_is_enabled () || prefs.hex_gui_dark_mode == ZOITECHAT_DARK_MODE_LIGHT)
{
gtkutil_apply_palette (w, &colors[COL_BG], &colors[COL_FG], font);
}
else
{
/* Keep list font in sync while reverting colors to theme defaults. */
gtkutil_apply_palette (w, NULL, NULL, font);
}
theme_manager_apply_channel_tree_style (w,
theme_manager_get_channel_tree_palette_behavior (font));
}
static void
chanview_theme_changed (const ThemeChangedEvent *event, gpointer userdata)
{
chanview *cv = userdata;
(void) event;
chanview_apply_theme (cv);
}
static char *
@@ -278,6 +283,12 @@ chanview_destroy_store (chanview *cv) /* free every (chan *) in the store */
static void
chanview_destroy (chanview *cv)
{
if (cv->theme_listener_id)
{
theme_listener_unregister (cv->theme_listener_id);
cv->theme_listener_id = 0;
}
if (cv->func_cleanup)
cv->func_cleanup (cv);
@@ -312,6 +323,7 @@ chanview_new (int type, int trunc_len, gboolean sort, gboolean use_icons,
cv->use_icons = use_icons;
gtk_widget_show (cv->box);
chanview_set_impl (cv, type);
cv->theme_listener_id = theme_listener_register ("chanview", chanview_theme_changed, cv);
g_signal_connect (G_OBJECT (cv->box), "destroy",
G_CALLBACK (chanview_box_destroy_cb), cv);
@@ -608,6 +620,45 @@ cv_find_chan_by_number (chanview *cv, int num)
return NULL;
}
static void
cv_find_neighbors_for_removal (chanview *cv, chan *find_ch, chan **left_ch, chan **first_ch)
{
GtkTreeIter iter, inner;
chan *ch;
chan *prev = NULL;
*left_ch = NULL;
*first_ch = NULL;
if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (cv->store), &iter))
{
do
{
gtk_tree_model_get (GTK_TREE_MODEL (cv->store), &iter, COL_CHAN, &ch, -1);
if (ch == find_ch)
*left_ch = prev;
else if (*first_ch == NULL)
*first_ch = ch;
prev = ch;
if (gtk_tree_model_iter_children (GTK_TREE_MODEL (cv->store), &inner, &iter))
{
do
{
gtk_tree_model_get (GTK_TREE_MODEL (cv->store), &inner, COL_CHAN, &ch, -1);
if (ch == find_ch)
*left_ch = prev;
else if (*first_ch == NULL)
*first_ch = ch;
prev = ch;
}
while (gtk_tree_model_iter_next (GTK_TREE_MODEL (cv->store), &inner));
}
}
while (gtk_tree_model_iter_next (GTK_TREE_MODEL (cv->store), &iter));
}
}
static void
chan_emancipate_children (chan *ch)
{
@@ -638,7 +689,7 @@ gboolean
chan_remove (chan *ch, gboolean force)
{
chan *new_ch;
int i, num;
chan *first_ch;
extern int zoitechat_is_quitting;
if (zoitechat_is_quitting) /* avoid lots of looping on exit */
@@ -658,25 +709,14 @@ chan_remove (chan *ch, gboolean force)
{
ch->cv->focused = NULL;
/* try to move the focus to some other valid channel */
num = cv_find_number_of_chan (ch->cv, ch);
/* move to the one left of the closing tab */
new_ch = cv_find_chan_by_number (ch->cv, num - 1);
cv_find_neighbors_for_removal (ch->cv, ch, &new_ch, &first_ch);
if (new_ch && new_ch != ch)
{
chan_focus (new_ch); /* this'll will set ch->cv->focused for us too */
} else
chan_focus (new_ch);
}
else if (first_ch && first_ch != ch)
{
/* if it fails, try focus from tab 0 and up */
for (i = 0; i < ch->cv->size; i++)
{
new_ch = cv_find_chan_by_number (ch->cv, i);
if (new_ch && new_ch != ch)
{
chan_focus (new_ch); /* this'll will set ch->cv->focused for us too */
break;
}
}
chan_focus (first_ch);
}
}

View File

@@ -34,8 +34,9 @@
#include "../common/util.h"
#include "../common/network.h"
#include "gtkutil.h"
#include "palette.h"
#include "theme/theme-gtk.h"
#include "maingui.h"
#include "theme/theme-access.h"
#define ICON_DCC_CANCEL "dialog-cancel"
#define ICON_DCC_ACCEPT "dialog-apply"
@@ -55,7 +56,7 @@ enum /* DCC SEND/RECV */
COL_ETA,
COL_NICK,
COL_DCC, /* struct DCC * */
COL_COLOR, /* PaletteColor */
COL_COLOR, /* GdkRGBA */
N_COLUMNS
};
@@ -67,7 +68,7 @@ enum /* DCC CHAT */
CCOL_SENT,
CCOL_START,
CCOL_DCC, /* struct DCC * */
CCOL_COLOR, /* PaletteColor * */
CCOL_COLOR, /* GdkRGBA * */
CN_COLUMNS
};
@@ -177,15 +178,15 @@ fe_dcc_send_filereq (struct session *sess, char *nick, int maxcps, int passive)
static void
dcc_store_color (GtkListStore *store, GtkTreeIter *iter, int column, int color_index)
{
const PaletteColor *color = NULL;
GdkRGBA rgba;
const GdkRGBA *color = NULL;
if (color_index != 1)
color = &colors[color_index];
if (color_index != 1 && theme_get_mirc_color ((unsigned int) color_index, &rgba))
color = &rgba;
if (color)
{
GdkRGBA rgba = *color;
gtk_list_store_set (store, iter, column, &rgba, -1);
gtk_list_store_set (store, iter, column, color, -1);
}
else
{
@@ -623,15 +624,7 @@ clear_completed (GtkWidget * wid, gpointer none)
static void
browse_folder (char *dir)
{
#ifdef WIN32
/* no need for file:// in ShellExecute() */
fe_open_url (dir);
#else
char buf[512];
g_snprintf (buf, sizeof (buf), "file://%s", dir);
fe_open_url (buf);
#endif
}
static void
@@ -753,7 +746,7 @@ dcc_add_column (GtkWidget *tree, int textcol, int colorcol, char *title, gboolea
if (right_justified)
g_object_set (G_OBJECT (renderer), "xalign", (float) 1.0, NULL);
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree), -1, title, renderer,
"text", textcol, PALETTE_FOREGROUND_PROPERTY, colorcol,
"text", textcol, THEME_GTK_FOREGROUND_PROPERTY, colorcol,
NULL);
gtk_cell_renderer_text_set_fixed_height_from_font (GTK_CELL_RENDERER_TEXT (renderer), 1);
}
@@ -839,7 +832,7 @@ fe_dcc_open_recv_win (int passive)
store = gtk_list_store_new (N_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING,
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_STRING, G_TYPE_POINTER, PALETTE_GDK_TYPE);
G_TYPE_STRING, G_TYPE_POINTER, THEME_GTK_COLOR_TYPE);
view = gtkutil_treeview_new (vbox, GTK_TREE_MODEL (store), NULL, -1);
view_scrolled = gtk_widget_get_parent (view);
gtk_widget_set_hexpand (view_scrolled, TRUE);
@@ -1111,7 +1104,7 @@ fe_dcc_open_chat_win (int passive)
store = gtk_list_store_new (CN_COLUMNS, G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_POINTER, PALETTE_GDK_TYPE);
G_TYPE_POINTER, THEME_GTK_COLOR_TYPE);
view = gtkutil_treeview_new (vbox, GTK_TREE_MODEL (store), NULL, -1);
scroll = gtk_widget_get_parent (view);
gtk_box_set_child_packing (GTK_BOX (vbox), scroll, TRUE, TRUE, 0, GTK_PACK_START);

View File

@@ -48,7 +48,7 @@
#include "chanlist.h"
#include "joind.h"
#include "xtext.h"
#include "palette.h"
#include "theme/theme-gtk.h"
#include "menu.h"
#include "notifygui.h"
#include "textgui.h"
@@ -57,6 +57,8 @@
#include "urlgrab.h"
#include "setup.h"
#include "plugin-notification.h"
#include "theme/theme-manager.h"
#include "theme/theme-application.h"
#ifdef USE_LIBCANBERRA
#include <canberra.h>
@@ -105,6 +107,7 @@ create_msg_dialog (gchar *title, gchar *message)
GtkWidget *dialog;
dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, "%s", message);
theme_manager_attach_window (dialog);
gtk_window_set_title (GTK_WINDOW (dialog), title);
/* On Win32 we automatically have the icon. If we try to load it explicitly, it will look ugly for some reason. */
@@ -429,37 +432,12 @@ fe_args (int argc, char *argv[])
return -1;
}
const char cursor_color_rc[] =
"style \"xc-ib-st\""
"{"
"GtkEntry::cursor-color=\"#%02x%02x%02x\""
"}"
"widget \"*.zoitechat-inputbox\" style : application \"xc-ib-st\"";
InputStyle *create_input_style (InputStyle *style);
static const char adwaita_workaround_rc[] =
"style \"zoitechat-input-workaround\""
"{"
"engine \"pixmap\" {"
"image {"
"function = FLAT_BOX\n"
"state = NORMAL\n"
"}"
"image {"
"function = FLAT_BOX\n"
"state = ACTIVE\n"
"}"
"}"
"}"
"widget \"*.zoitechat-inputbox\" style \"zoitechat-input-workaround\"";
#ifdef G_OS_WIN32
#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE
#define DWMWA_USE_IMMERSIVE_DARK_MODE 20
#endif
static gboolean
gboolean
fe_win32_high_contrast_is_enabled (void)
{
HIGHCONTRASTW hc;
@@ -472,7 +450,7 @@ fe_win32_high_contrast_is_enabled (void)
return (hc.dwFlags & HCF_HIGHCONTRASTON) != 0;
}
static gboolean
gboolean
fe_win32_try_get_system_dark (gboolean *prefer_dark)
{
DWORD value = 1;
@@ -502,7 +480,7 @@ fe_win32_try_get_system_dark (gboolean *prefer_dark)
return TRUE;
}
static void
void
fe_win32_apply_native_titlebar (GtkWidget *window, gboolean dark_mode)
{
HWND hwnd;
@@ -525,7 +503,7 @@ fe_win32_apply_native_titlebar (GtkWidget *window, gboolean dark_mode)
sizeof (use_dark));
}
#else
static void
void
fe_win32_apply_native_titlebar (GtkWidget *window, gboolean dark_mode)
{
(void) window;
@@ -533,163 +511,14 @@ fe_win32_apply_native_titlebar (GtkWidget *window, gboolean dark_mode)
}
#endif
static gboolean
fe_system_prefers_dark (void)
{
GtkSettings *settings = gtk_settings_get_default ();
gboolean prefer_dark = FALSE;
char *theme_name = NULL;
#ifdef G_OS_WIN32
gboolean have_win_pref = FALSE;
if (fe_win32_high_contrast_is_enabled ())
return FALSE;
#endif
if (!settings)
return FALSE;
#ifdef G_OS_WIN32
have_win_pref = fe_win32_try_get_system_dark (&prefer_dark);
if (!have_win_pref)
#endif
if (g_object_class_find_property (G_OBJECT_GET_CLASS (settings),
"gtk-application-prefer-dark-theme"))
{
g_object_get (settings, "gtk-application-prefer-dark-theme", &prefer_dark, NULL);
}
if (!prefer_dark)
{
g_object_get (settings, "gtk-theme-name", &theme_name, NULL);
if (theme_name)
{
char *lower = g_ascii_strdown (theme_name, -1);
if (g_str_has_suffix (lower, "-dark") || g_strrstr (lower, "dark"))
prefer_dark = TRUE;
g_free (lower);
g_free (theme_name);
}
}
return prefer_dark;
}
static gboolean auto_dark_mode_enabled = FALSE;
#ifdef G_OS_WIN32
static void
fe_apply_windows_theme (gboolean dark)
{
GtkSettings *settings = gtk_settings_get_default ();
if (settings && g_object_class_find_property (G_OBJECT_GET_CLASS (settings),
"gtk-application-prefer-dark-theme"))
{
g_object_set (settings, "gtk-application-prefer-dark-theme", dark, NULL);
}
{
static GtkCssProvider *win_theme_provider = NULL;
GdkScreen *screen = gdk_screen_get_default ();
const char *css =
"window.zoitechat-dark, .zoitechat-dark {"
"background-color: #202020;"
"color: #f0f0f0;"
"}"
"window.zoitechat-light, .zoitechat-light {"
"background-color: #f6f6f6;"
"color: #101010;"
"}";
if (!win_theme_provider)
win_theme_provider = gtk_css_provider_new ();
gtk_css_provider_load_from_data (win_theme_provider, css, -1, NULL);
if (screen)
gtk_style_context_add_provider_for_screen (
screen,
GTK_STYLE_PROVIDER (win_theme_provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
}
}
#endif
static void
fe_auto_dark_mode_changed (GtkSettings *settings, GParamSpec *pspec, gpointer data)
{
gboolean enabled;
(void) settings;
(void) pspec;
(void) data;
if (prefs.hex_gui_dark_mode != ZOITECHAT_DARK_MODE_AUTO)
return;
enabled = fe_system_prefers_dark ();
if (enabled == auto_dark_mode_enabled)
return;
auto_dark_mode_enabled = enabled;
fe_apply_theme_for_mode (ZOITECHAT_DARK_MODE_AUTO, NULL);
setup_apply_real (0, TRUE, FALSE, FALSE);
}
void
fe_set_auto_dark_mode_state (gboolean enabled)
{
auto_dark_mode_enabled = enabled;
}
void
fe_refresh_auto_dark_mode (void)
{
fe_auto_dark_mode_changed (NULL, NULL, NULL);
}
gboolean
fe_apply_theme_for_mode (unsigned int mode, gboolean *palette_changed)
{
gboolean enabled = fe_dark_mode_is_enabled_for (mode);
gboolean changed = palette_apply_dark_mode (enabled);
#ifdef G_OS_WIN32
fe_apply_windows_theme (enabled);
#endif
if (palette_changed)
*palette_changed = changed;
if (input_style)
create_input_style (input_style);
return enabled;
}
void
fe_apply_theme_to_toplevel (GtkWidget *window)
{
if (!window)
return;
#ifdef G_OS_WIN32
{
GtkStyleContext *context = gtk_widget_get_style_context (window);
gboolean dark = fe_dark_mode_is_enabled ();
if (context)
{
gtk_style_context_remove_class (context, "zoitechat-dark");
gtk_style_context_remove_class (context, "zoitechat-light");
gtk_style_context_add_class (context, dark ? "zoitechat-dark" : "zoitechat-light");
}
}
#endif
fe_win32_apply_native_titlebar (window, fe_dark_mode_is_enabled ());
}
gboolean
fe_dark_mode_is_enabled_for (unsigned int mode)
{
@@ -711,174 +540,10 @@ fe_dark_mode_is_enabled (void)
return fe_dark_mode_is_enabled_for (prefs.hex_gui_dark_mode);
}
InputStyle *
create_input_style (InputStyle *style)
{
char buf[256];
static int done_rc = FALSE;
static GtkCssProvider *input_css_provider = NULL;
static char *last_theme_name = NULL;
static gboolean last_dark_mode = FALSE;
static gboolean last_input_style = FALSE;
static gboolean last_colors_set = FALSE;
static guint16 last_fg_red;
static guint16 last_fg_green;
static guint16 last_fg_blue;
static guint16 last_bg_red;
static guint16 last_bg_green;
static guint16 last_bg_blue;
if (!style)
style = g_new0 (InputStyle, 1);
if (style->font_desc)
pango_font_description_free (style->font_desc);
style->font_desc = pango_font_description_from_string (prefs.hex_text_font);
/* fall back */
if (pango_font_description_get_size (style->font_desc) == 0)
{
g_snprintf (buf, sizeof (buf), _("Failed to open font:\n\n%s"), prefs.hex_text_font);
fe_message (buf, FE_MSG_ERROR);
pango_font_description_free (style->font_desc);
style->font_desc = pango_font_description_from_string ("sans 11");
}
if (prefs.hex_gui_input_style)
{
GtkSettings *settings = gtk_settings_get_default ();
GdkScreen *screen = gdk_screen_get_default ();
char *theme_name;
char cursor_rc[sizeof (cursor_color_rc)];
char cursor_color[8];
const char *cursor_color_start = NULL;
guint16 fg_red;
guint16 fg_green;
guint16 fg_blue;
guint16 bg_red;
guint16 bg_green;
guint16 bg_blue;
gboolean dark_mode = fe_dark_mode_is_enabled ();
gboolean needs_reload;
g_object_get (settings, "gtk-theme-name", &theme_name, NULL);
palette_color_get_rgb16 (&colors[COL_FG], &fg_red, &fg_green, &fg_blue);
palette_color_get_rgb16 (&colors[COL_BG], &bg_red, &bg_green, &bg_blue);
needs_reload = !done_rc
|| !last_input_style
|| last_dark_mode != dark_mode
|| g_strcmp0 (last_theme_name, theme_name) != 0
|| !last_colors_set
|| last_fg_red != fg_red
|| last_fg_green != fg_green
|| last_fg_blue != fg_blue
|| last_bg_red != bg_red
|| last_bg_green != bg_green
|| last_bg_blue != bg_blue;
if (needs_reload)
{
if (!input_css_provider)
input_css_provider = gtk_css_provider_new ();
g_snprintf (buf, sizeof (buf), "#%02x%02x%02x",
(fg_red >> 8), (fg_green >> 8), (fg_blue >> 8));
g_snprintf (cursor_rc, sizeof (cursor_rc), cursor_color_rc,
(fg_red >> 8), (fg_green >> 8), (fg_blue >> 8));
cursor_color_start = g_strstr_len (cursor_rc, -1, "cursor-color=\"");
if (cursor_color_start)
{
cursor_color_start += strlen ("cursor-color=\"");
g_strlcpy (cursor_color, cursor_color_start, sizeof (cursor_color));
cursor_color[7] = '\0';
}
else
{
g_strlcpy (cursor_color, buf, sizeof (cursor_color));
}
{
GString *css = g_string_new ("#zoitechat-inputbox {");
/* GTK3 equivalents for adwaita_workaround_rc/cursor_color_rc. */
if (adwaita_workaround_rc[0] != '\0'
&& (g_str_has_prefix (theme_name, "Adwaita")
|| g_str_has_prefix (theme_name, "Yaru")))
g_string_append (css, "background-image: none;");
g_string_append_printf (
css,
"background-color: #%02x%02x%02x;"
"color: #%02x%02x%02x;"
"caret-color: %s;"
"}"
"#zoitechat-inputbox text {"
"color: #%02x%02x%02x;"
"caret-color: %s;"
"}",
(bg_red >> 8), (bg_green >> 8), (bg_blue >> 8),
(fg_red >> 8), (fg_green >> 8), (fg_blue >> 8),
cursor_color,
(fg_red >> 8), (fg_green >> 8), (fg_blue >> 8),
cursor_color);
gtk_css_provider_load_from_data (input_css_provider, css->str, -1, NULL);
g_string_free (css, TRUE);
}
if (screen)
gtk_style_context_add_provider_for_screen (
screen,
GTK_STYLE_PROVIDER (input_css_provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
done_rc = TRUE;
last_input_style = TRUE;
last_dark_mode = dark_mode;
last_colors_set = TRUE;
last_fg_red = fg_red;
last_fg_green = fg_green;
last_fg_blue = fg_blue;
last_bg_red = bg_red;
last_bg_green = bg_green;
last_bg_blue = bg_blue;
g_free (last_theme_name);
last_theme_name = g_strdup (theme_name);
}
g_free (theme_name);
}
else
{
GdkScreen *screen = gdk_screen_get_default ();
if (input_css_provider && screen)
{
gtk_style_context_remove_provider_for_screen (
screen,
GTK_STYLE_PROVIDER (input_css_provider));
}
g_clear_object (&input_css_provider);
g_clear_pointer (&last_theme_name, g_free);
done_rc = FALSE;
last_input_style = FALSE;
last_colors_set = FALSE;
}
return style;
}
void
fe_init (void)
{
GtkSettings *settings;
palette_load ();
settings = gtk_settings_get_default ();
if (settings)
auto_dark_mode_enabled = fe_system_prefers_dark ();
fe_apply_theme_for_mode (prefs.hex_gui_dark_mode, NULL);
theme_manager_init ();
key_init ();
pixmaps_init ();
@@ -886,15 +551,8 @@ fe_init (void)
gtkosx_application_set_dock_icon_pixbuf (osx_app, pix_zoitechat);
#endif
channelwin_pix = pixmap_load_from_file (prefs.hex_text_background);
input_style = create_input_style (input_style);
theme_application_reload_input_style ();
if (settings)
{
g_signal_connect (settings, "notify::gtk-application-prefer-dark-theme",
G_CALLBACK (fe_auto_dark_mode_changed), NULL);
g_signal_connect (settings, "notify::gtk-theme-name",
G_CALLBACK (fe_auto_dark_mode_changed), NULL);
}
}
#ifdef HAVE_GTK_MAC
@@ -925,8 +583,6 @@ fe_main (void)
void
fe_cleanup (void)
{
/* it's saved when pressing OK in setup.c */
/*palette_save ();*/
}
void
@@ -963,8 +619,7 @@ log_handler (const gchar *log_domain,
{
session *sess;
/* if (getenv ("ZOITECHAT_WARNING_IGNORE")) this gets ignored sometimes, so simply just disable all warnings */
return;
return;
sess = find_dialog (serv_list->data, "(warnings)");
if (!sess)
@@ -977,8 +632,6 @@ log_handler (const gchar *log_domain,
#endif
/* install tray stuff */
static int
fe_idle (gpointer data)
{
@@ -1045,6 +698,7 @@ fe_message (char *msg, int flags)
dialog = gtk_message_dialog_new (GTK_WINDOW (parent_window), 0, type,
GTK_BUTTONS_OK, "%s", msg);
theme_manager_attach_window (dialog);
if (flags & FE_MSG_MARKUP)
gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog), msg);
g_signal_connect (G_OBJECT (dialog), "response",
@@ -1445,7 +1099,7 @@ fe_ctrl_gui (session *sess, fe_gui_action action, int arg)
mg_detach (sess, arg); /* arg: 0=toggle 1=detach 2=attach */
break;
case FE_GUI_APPLY:
setup_apply_real (TRUE, TRUE, TRUE, FALSE);
theme_manager_dispatch_changed (THEME_CHANGED_REASON_PIXMAP | THEME_CHANGED_REASON_USERLIST | THEME_CHANGED_REASON_LAYOUT | THEME_CHANGED_REASON_WIDGET_STYLE);
}
}
@@ -1569,61 +1223,6 @@ fe_set_inputbox_contents (session *sess, char *text)
}
}
#ifdef __APPLE__
static char *
url_escape_hostname (const char *url)
{
char *host_start, *host_end, *ret, *hostname;
host_start = strstr (url, "://");
if (host_start != NULL)
{
*host_start = '\0';
host_start += 3;
host_end = strchr (host_start, '/');
if (host_end != NULL)
{
*host_end = '\0';
host_end++;
}
hostname = g_hostname_to_ascii (host_start);
if (host_end != NULL)
ret = g_strdup_printf ("%s://%s/%s", url, hostname, host_end);
else
ret = g_strdup_printf ("%s://%s", url, hostname);
g_free (hostname);
return ret;
}
return g_strdup (url);
}
static void
osx_show_uri (const char *url)
{
char *escaped_url, *encoded_url, *open, *cmd;
escaped_url = url_escape_hostname (url);
encoded_url = g_filename_from_utf8 (escaped_url, -1, NULL, NULL, NULL);
if (encoded_url)
{
open = g_find_program_in_path ("open");
cmd = g_strjoin (" ", open, encoded_url, NULL);
zoitechat_exec (cmd);
g_free (encoded_url);
g_free (cmd);
}
g_free (escaped_url);
}
#endif
static inline char *
escape_uri (const char *uri)
{
@@ -1635,7 +1234,7 @@ uri_contains_forbidden_characters (const char *uri)
{
while (*uri)
{
if (!g_ascii_isalnum (*uri) && !strchr ("-._~:/?#[]@!$&'()*+,;=", *uri))
if (!g_ascii_isalnum (*uri) && !strchr ("-._~%:/?#[]@!$&'()*+,;=", *uri))
return TRUE;
uri++;
}
@@ -1666,48 +1265,39 @@ maybe_escape_uri (const char *uri)
static void
fe_open_url_inner (const char *url)
{
#ifdef WIN32
gunichar2 *url_utf16 = g_utf8_to_utf16 (url, -1, NULL, NULL, NULL);
if (url_utf16 == NULL)
{
return;
}
ShellExecuteW (0, L"open", url_utf16, NULL, NULL, SW_SHOWNORMAL);
g_free (url_utf16);
#elif defined(__APPLE__)
osx_show_uri (url);
#else
GError *error = NULL;
char *escaped_url = maybe_escape_uri (url);
gchar *xdg_open_argv[] = {(gchar *) "xdg-open", escaped_url, NULL};
gchar **spawn_env = NULL;
gboolean opened = FALSE;
g_debug ("Opening URL \"%s\" (%s)", escaped_url, url);
gboolean opened = g_app_info_launch_default_for_uri (escaped_url, NULL, &error);
/* AppImage runtime variables can point host binaries like /bin/sh at
* bundled libraries, which may not be ABI-compatible with system tools. */
spawn_env = g_get_environ ();
if (!opened)
{
gchar **tmp_env = spawn_env;
spawn_env = g_environ_unsetenv (tmp_env, "LD_LIBRARY_PATH");
if (spawn_env != tmp_env)
g_strfreev (tmp_env);
g_clear_error (&error);
#ifdef WIN32
gunichar2 *url_utf16 = g_utf8_to_utf16 (escaped_url, -1, NULL, NULL, NULL);
tmp_env = spawn_env;
spawn_env = g_environ_unsetenv (tmp_env, "LD_PRELOAD");
if (spawn_env != tmp_env)
g_strfreev (tmp_env);
}
if (url_utf16 != NULL)
{
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;
/* Prefer xdg-open when available because gtk_show_uri can inherit
* AppImage runtime state and fail before we can control the environment. */
{
gchar *xdg_open_path = g_find_program_in_path ("xdg-open");
if (xdg_open_path &&
g_spawn_async (NULL, xdg_open_argv, spawn_env,
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);
}
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,
NULL, NULL, NULL, &error))
{
@@ -1717,27 +1307,26 @@ fe_open_url_inner (const char *url)
{
g_clear_error (&error);
}
g_free (xdg_open_path);
}
if (!opened && gtk_show_uri (NULL, escaped_url, GDK_CURRENT_TIME, &error))
{
opened = TRUE;
}
else if (!opened)
{
g_warning ("gtk_show_uri failed for '%s': %s", escaped_url, error ? error->message : "unknown error");
g_clear_error (&error);
if (!opened && gtk_show_uri (NULL, escaped_url, GDK_CURRENT_TIME, &error))
{
opened = TRUE;
}
else if (!opened)
{
g_clear_error (&error);
}
g_strfreev (spawn_env);
#endif
}
if (!opened)
{
g_warning ("Unable to open URL '%s' via xdg-open or gtk_show_uri", escaped_url);
g_warning ("Unable to open URL '%s' using system default application", escaped_url);
}
g_strfreev (spawn_env);
g_free (escaped_url);
#endif
}
void

View File

@@ -114,6 +114,7 @@ typedef struct restore_gui
/* information stored when this tab isn't front-most */
GtkListStore *user_model; /* for filling the GtkTreeView */
GHashTable *user_row_refs;
void *buffer; /* xtext_Buffer */
char *input_text; /* input text buffer (while not-front tab) */
char *topic_text; /* topic GtkEntry buffer */
@@ -178,6 +179,8 @@ typedef struct session_gui
int pane_left_size; /*last position of the pane*/
int pane_right_size;
guint theme_window_listener_id;
guint theme_userlist_listener_id;
guint16 is_tab; /* is tab or toplevel? */
guint16 ul_hidden; /* userlist hidden? */
@@ -190,9 +193,12 @@ extern cairo_surface_t *dialogwin_pix;
gboolean fe_dark_mode_is_enabled (void);
gboolean fe_dark_mode_is_enabled_for (unsigned int mode);
void fe_set_auto_dark_mode_state (gboolean enabled);
void fe_refresh_auto_dark_mode (void);
gboolean fe_apply_theme_for_mode (unsigned int mode, gboolean *palette_changed);
void fe_apply_theme_to_toplevel (GtkWidget *window);
#ifdef G_OS_WIN32
gboolean fe_win32_high_contrast_is_enabled (void);
gboolean fe_win32_try_get_system_dark (gboolean *prefer_dark);
#endif
void fe_win32_apply_native_titlebar (GtkWidget *window, gboolean dark_mode);
#define SPELL_ENTRY_GET_TEXT(e) ((char *)(gtk_entry_get_text (GTK_ENTRY(e))))
#define SPELL_ENTRY_SET_TEXT(e,txt) gtk_entry_set_text(GTK_ENTRY(e),txt)

View File

@@ -5,10 +5,6 @@
<ConfigurationType>Application</ConfigurationType>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
@@ -27,18 +23,6 @@
<TargetName>zoitechat</TargetName>
<OutDir>$(ZoiteChatRel)</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\common;$(ZoiteChatLib);$(DepsRoot)\include;$(OpenSslInclude);$(Glib);$(Gtk);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4244;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>$(DepLibs);$(ZoiteChatLib)common.lib;wbemuuid.lib;comsupp.lib;dwmapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<EntryPointSymbol>mainCRTStartup</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions>
@@ -46,8 +30,8 @@
<DisableSpecificWarnings>4244;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>$(DepLibs);$(ZoiteChatLib)common.lib;wbemuuid.lib;comsupp.lib;dwmapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ArchiveLibDir);$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>$(DepLibs);$(ZoiteChatLib)common.lib;wbemuuid.lib;dwmapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<EntryPointSymbol>mainCRTStartup</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
@@ -74,6 +58,7 @@ powershell "Get-Content -Encoding UTF8 '$(ZoiteChatLib)zoitechat.rc.utf8' | Out-
<ClInclude Include="fe-gtk.h" />
<ClInclude Include="fkeys.h" />
<ClInclude Include="gtkutil.h" />
<ClInclude Include="icon-resolver.h" />
<ClInclude Include="joind.h" />
<ClInclude Include="maingui.h" />
<ClInclude Include="menu.h" />
@@ -92,6 +77,16 @@ powershell "Get-Content -Encoding UTF8 '$(ZoiteChatLib)zoitechat.rc.utf8' | Out-
<ClInclude Include="urlgrab.h" />
<ClInclude Include="userlistgui.h" />
<ClInclude Include="xtext.h" />
<ClInclude Include="theme\theme-manager.h" />
<ClInclude Include="theme\theme-palette.h" />
<ClInclude Include="theme\theme-application.h" />
<ClInclude Include="theme\theme-policy.h" />
<ClInclude Include="theme\theme-css.h" />
<ClInclude Include="theme\theme-runtime.h" />
<ClInclude Include="theme\theme-access.h" />
<ClInclude Include="theme\theme-gtk.h" />
<ClInclude Include="theme\theme-gtk3.h" />
<ClInclude Include="theme\theme-preferences.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="ascii.c" />
@@ -104,13 +99,13 @@ powershell "Get-Content -Encoding UTF8 '$(ZoiteChatLib)zoitechat.rc.utf8' | Out-
<ClCompile Include="fe-gtk.c" />
<ClCompile Include="fkeys.c" />
<ClCompile Include="gtkutil.c" />
<ClCompile Include="icon-resolver.c" />
<ClCompile Include="ignoregui.c" />
<ClCompile Include="joind.c" />
<ClCompile Include="maingui.c" />
<ClCompile Include="menu.c" />
<ClCompile Include="notifications\notification-windows.c" />
<ClCompile Include="notifygui.c" />
<ClCompile Include="palette.c" />
<ClCompile Include="pixmaps.c" />
<ClCompile Include="plugin-notification.c" />
<ClCompile Include="plugin-tray.c" />
@@ -125,6 +120,15 @@ powershell "Get-Content -Encoding UTF8 '$(ZoiteChatLib)zoitechat.rc.utf8' | Out-
<ClCompile Include="urlgrab.c" />
<ClCompile Include="userlistgui.c" />
<ClCompile Include="xtext.c" />
<ClCompile Include="theme\theme-manager.c" />
<ClCompile Include="theme\theme-palette.c" />
<ClCompile Include="theme\theme-application.c" />
<ClCompile Include="theme\theme-policy.c" />
<ClCompile Include="theme\theme-css.c" />
<ClCompile Include="theme\theme-runtime.c" />
<ClCompile Include="theme\theme-access.c" />
<ClCompile Include="theme\theme-gtk3.c" />
<ClCompile Include="theme\theme-preferences.c" />
</ItemGroup>
<ItemGroup>
<Manifest Include="..\..\win32\zoitechat.exe.manifest" />
@@ -135,6 +139,12 @@ powershell "Get-Content -Encoding UTF8 '$(ZoiteChatLib)zoitechat.rc.utf8' | Out-
</ItemGroup>
<ItemGroup>
<None Include="..\..\data\icons\zoitechat.ico" />
<None Include="theme\tests\test-theme-manager-policy.c" />
<None Include="theme\tests\test-theme-runtime-persistence.c" />
<None Include="theme\tests\test-theme-access-routing.c" />
<None Include="theme\tests\src/fe-gtk/theme/tests/test-theme-manager-auto-refresh.c" />
<None Include="theme\tests\src/fe-gtk/theme/tests/test-theme-manager-dispatch-routing.c" />
<None Include="theme\tests\src/fe-gtk/theme/tests/test-theme-application-input-style.c" />
</ItemGroup>
<ItemGroup>
<Xml Include="..\..\data\zoitechat.gresource.xml" />

View File

@@ -42,6 +42,9 @@
<ClInclude Include="gtkutil.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="icon-resolver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="joind.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -96,6 +99,36 @@
<ClInclude Include="notifications\notification-backend.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="theme\theme-manager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="theme\theme-palette.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="theme\theme-application.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="theme\theme-policy.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="theme\theme-css.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="theme\theme-runtime.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="theme\theme-access.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="theme\theme-gtk.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="theme\theme-gtk3.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="theme\theme-preferences.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="ascii.c">
@@ -128,6 +161,9 @@
<ClCompile Include="gtkutil.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="icon-resolver.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ignoregui.c">
<Filter>Source Files</Filter>
</ClCompile>
@@ -143,9 +179,6 @@
<ClCompile Include="notifygui.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="palette.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="pixmaps.c">
<Filter>Source Files</Filter>
</ClCompile>
@@ -191,6 +224,33 @@
<ClCompile Include="notifications\notification-windows.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="theme\theme-manager.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="theme\theme-palette.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="theme\theme-application.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="theme\theme-policy.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="theme\theme-css.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="theme\theme-runtime.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="theme\theme-access.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="theme\theme-gtk3.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="theme\theme-preferences.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Manifest Include="..\..\win32\zoitechat.exe.manifest">
@@ -206,9 +266,27 @@
<None Include="..\..\data\icons\zoitechat.ico">
<Filter>Resource Files</Filter>
</None>
<None Include="theme\tests\test-theme-manager-policy.c">
<Filter>Source Files</Filter>
</None>
<None Include="theme\tests\test-theme-runtime-persistence.c">
<Filter>Source Files</Filter>
</None>
<None Include="\theme\tests\test-theme-access-routing.c">
<Filter>Source Files</Filter>
</None>
<None Include="\theme\tests\test-theme-manager-dispatch-routing.c">
<Filter>Source Files</Filter>
</None>
<None Include="\theme\tests\test-theme-manager-auto-refresh.c">
<Filter>Source Files</Filter>
</None>
<None Include="\theme\tests\test-theme-application-input-style.c">
<Filter>Source Files</Filter>
</None>
<None Include="zoitechat.rc.tt" />
</ItemGroup>
<ItemGroup>
<Xml Include="..\..\data\zoitechat.gresource.xml" />
</ItemGroup>
</Project>
</Project>

View File

@@ -48,7 +48,10 @@
#include "gtkutil.h"
#include "menu.h"
#include "xtext.h"
#include "palette.h"
#include "theme/theme-access.h"
#include "theme/theme-manager.h"
#include "theme/theme-css.h"
#include "theme/theme-gtk3.h"
#include "maingui.h"
#include "textgui.h"
#include "fkeys.h"
@@ -142,6 +145,53 @@ static int key_action_put_history (GtkWidget * wid, GdkEventKey * evt,
static GSList *keybind_list = NULL;
#define KEY_DIALOG_THEME_LISTENER_ID_KEY "fkeys.theme-listener-id"
static void
key_dialog_theme_apply (GtkWidget *window)
{
GtkWidget *xtext;
XTextColor xtext_palette[XTEXT_COLS];
if (!window)
return;
xtext = g_object_get_data (G_OBJECT (window), "xtext");
if (!xtext)
return;
theme_get_xtext_colors (xtext_palette, XTEXT_COLS);
gtk_xtext_set_palette (GTK_XTEXT (xtext), xtext_palette);
}
static void
key_dialog_theme_changed (const ThemeChangedEvent *event, gpointer userdata)
{
GtkWidget *window = userdata;
if (!theme_changed_event_has_reason (event, THEME_CHANGED_REASON_PALETTE) &&
!theme_changed_event_has_reason (event, THEME_CHANGED_REASON_THEME_PACK) &&
!theme_changed_event_has_reason (event, THEME_CHANGED_REASON_MODE))
return;
key_dialog_theme_apply (window);
}
static void
key_dialog_theme_destroy_cb (GtkWidget *widget, gpointer userdata)
{
guint listener_id;
(void) userdata;
listener_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (widget), KEY_DIALOG_THEME_LISTENER_ID_KEY));
if (listener_id)
{
theme_listener_unregister (listener_id);
g_object_set_data (G_OBJECT (widget), KEY_DIALOG_THEME_LISTENER_ID_KEY, NULL);
}
}
static gsize
key_action_decode_escapes (const char *input, char *output)
{
@@ -746,9 +796,9 @@ key_dialog_treeview_new (GtkWidget *box)
"changed", G_CALLBACK (key_dialog_selection_changed), NULL);
gtk_widget_set_name (view, "fkeys-treeview");
if (!theme_gtk3_is_active ())
{
GtkCssProvider *provider = gtk_css_provider_new ();
GtkStyleContext *context = gtk_widget_get_style_context (view);
gtk_css_provider_load_from_data (
provider,
@@ -760,8 +810,7 @@ key_dialog_treeview_new (GtkWidget *box)
"}",
-1,
NULL);
gtk_style_context_add_provider (context, GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
theme_css_apply_widget_provider (view, GTK_STYLE_PROVIDER (provider));
g_object_unref (provider);
}
@@ -904,13 +953,16 @@ key_dialog_show ()
NULL, 600, 360, &vbox, 0);
view = key_dialog_treeview_new (vbox);
palette_get_xtext_colors (xtext_palette, XTEXT_COLS);
theme_get_xtext_colors (xtext_palette, XTEXT_COLS);
xtext = gtk_xtext_new (xtext_palette, 0);
gtk_box_pack_start (GTK_BOX (vbox), xtext, FALSE, TRUE, 2);
gtk_xtext_set_font (GTK_XTEXT (xtext), prefs.hex_text_font);
g_object_set_data (G_OBJECT (key_dialog), "view", view);
g_object_set_data (G_OBJECT (key_dialog), "xtext", xtext);
g_object_set_data (G_OBJECT (key_dialog), KEY_DIALOG_THEME_LISTENER_ID_KEY,
GUINT_TO_POINTER (theme_listener_register ("fkeys.window", key_dialog_theme_changed, key_dialog)));
g_signal_connect (G_OBJECT (key_dialog), "destroy", G_CALLBACK (key_dialog_theme_destroy_cb), NULL);
box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
gtk_button_box_set_layout (GTK_BUTTON_BOX (box), GTK_BUTTONBOX_SPREAD);
@@ -1199,11 +1251,6 @@ corrupt_file:
return 5;
}
/* ***** Key actions start here *********** */
/* See the NOTES above --AGL */
/* "Run command" */
static int
key_action_handle_command (GtkWidget * wid, GdkEventKey * evt, char *d1,
char *d2, struct session *sess)
@@ -1224,7 +1271,6 @@ key_action_handle_command (GtkWidget * wid, GdkEventKey * evt, char *d1,
/*
* Check if the given session is inside the main window. This predicate
* is passed to lastact_getfirst() as a way to filter out detached sessions.
* XXX: Consider moving this in a different file?
*/
static int
session_check_is_tab(session *sess)
@@ -1806,7 +1852,7 @@ key_action_move_tab_left (GtkWidget * wid, GdkEventKey * ent, char *d1,
char *d2, struct session *sess)
{
mg_move_tab (sess, +1);
return 2; /* don't allow default action */
return 2;
}
static int
@@ -1814,7 +1860,7 @@ key_action_move_tab_right (GtkWidget * wid, GdkEventKey * ent, char *d1,
char *d2, struct session *sess)
{
mg_move_tab (sess, -1);
return 2; /* -''- */
return 2;
}
static int
@@ -1822,7 +1868,7 @@ key_action_move_tab_family_left (GtkWidget * wid, GdkEventKey * ent, char *d1,
char *d2, struct session *sess)
{
mg_move_tab_family (sess, +1);
return 2; /* don't allow default action */
return 2;
}
static int
@@ -1830,7 +1876,7 @@ key_action_move_tab_family_right (GtkWidget * wid, GdkEventKey * ent, char *d1,
char *d2, struct session *sess)
{
mg_move_tab_family (sess, -1);
return 2; /* -''- */
return 2;
}
static int
@@ -1839,12 +1885,9 @@ key_action_put_history (GtkWidget * wid, GdkEventKey * ent, char *d1,
{
history_add (&sess->history, SPELL_ENTRY_GET_TEXT (wid));
SPELL_ENTRY_SET_TEXT (wid, "");
return 2; /* -''- */
return 2;
}
/* -------- */
static void
replace_handle (GtkWidget *t)
{

View File

@@ -42,7 +42,9 @@
#include "../common/zoitechatc.h"
#include "../common/typedef.h"
#include "gtkutil.h"
#include "icon-resolver.h"
#include "pixmaps.h"
#include "theme/theme-manager.h"
#ifdef WIN32
#include <io.h>
@@ -62,124 +64,28 @@ struct file_req
int flags; /* FRF_* flags */
};
static const char *
gtkutil_menu_custom_icon_from_stock (const char *stock_name)
{
static const struct
{
const char *stock;
const char *custom_icon;
} icon_map[] = {
{ "gtk-new", "zc-menu-new" },
{ "gtk-index", "zc-menu-network-list" },
{ "gtk-revert-to-saved", "zc-menu-load-plugin" },
{ "gtk-redo", "zc-menu-detach" },
{ "gtk-close", "zc-menu-close" },
{ "gtk-quit", "zc-menu-quit" },
{ "gtk-disconnect", "zc-menu-disconnect" },
{ "gtk-connect", "zc-menu-connect" },
{ "gtk-jump-to", "zc-menu-join" },
{ "gtk-preferences", "zc-menu-preferences" },
{ "gtk-clear", "zc-menu-clear" },
{ "gtk-copy", "zc-menu-copy" },
{ "gtk-delete", "zc-menu-delete" },
{ "gtk-add", "zc-menu-add" },
{ "gtk-remove", "zc-menu-remove" },
{ "gtk-spell-check", "zc-menu-spell-check" },
{ "gtk-save", "zc-menu-save" },
{ "gtk-save-as", "zc-menu-save-as" },
{ "gtk-refresh", "zc-menu-refresh" },
{ "gtk-justify-left", "zc-menu-search" },
{ "gtk-find", "zc-menu-find" },
{ "gtk-go-back", "zc-menu-previous" },
{ "gtk-go-forward", "zc-menu-next" },
{ "gtk-help", "zc-menu-help" },
{ "gtk-about", "zc-menu-about" },
{ "gtk-convert", "zc-menu-emoji" },
};
size_t i;
if (!stock_name)
return NULL;
for (i = 0; i < G_N_ELEMENTS (icon_map); i++)
{
if (strcmp (stock_name, icon_map[i].stock) == 0)
return icon_map[i].custom_icon;
}
return NULL;
}
static const char *
gtkutil_menu_custom_icon_from_icon_name (const char *icon_name)
{
static const struct
{
const char *icon;
const char *custom_icon;
} icon_map[] = {
{ "document-new", "zc-menu-new" },
{ "view-list", "zc-menu-network-list" },
{ "document-open", "zc-menu-load-plugin" },
{ "edit-redo", "zc-menu-detach" },
{ "window-close", "zc-menu-close" },
{ "application-exit", "zc-menu-quit" },
{ "network-disconnect", "zc-menu-disconnect" },
{ "network-connect", "zc-menu-connect" },
{ "go-jump", "zc-menu-join" },
{ "preferences-system", "zc-menu-preferences" },
{ "edit-clear", "zc-menu-clear" },
{ "edit-copy", "zc-menu-copy" },
{ "edit-delete", "zc-menu-delete" },
{ "list-add", "zc-menu-add" },
{ "list-remove", "zc-menu-remove" },
{ "tools-check-spelling", "zc-menu-spell-check" },
{ "document-save", "zc-menu-save" },
{ "document-save-as", "zc-menu-save-as" },
{ "view-refresh", "zc-menu-refresh" },
{ "edit-find", "zc-menu-find" },
{ "go-previous", "zc-menu-previous" },
{ "go-next", "zc-menu-next" },
{ "help-browser", "zc-menu-help" },
{ "help-about", "zc-menu-about" },
{ "face-smile", "zc-menu-emoji" },
{ "insert-emoticon", "zc-menu-emoji" },
{ "software-update-available", "zc-menu-update" },
{ "network-workgroup", "zc-menu-chanlist" },
};
size_t i;
if (!icon_name)
return NULL;
for (i = 0; i < G_N_ELEMENTS (icon_map); i++)
{
if (strcmp (icon_name, icon_map[i].icon) == 0)
return icon_map[i].custom_icon;
}
return NULL;
}
static GdkPixbuf *
gtkutil_menu_icon_pixbuf_new (const char *icon_name)
{
GdkPixbuf *pixbuf = NULL;
char *resource_path;
const char *system_icon_name = NULL;
int action;
if (!icon_name || !g_str_has_prefix (icon_name, "zc-menu-"))
if (!icon_name || !icon_resolver_menu_action_from_name (icon_name, &action))
return NULL;
resource_path = g_strdup_printf ("/icons/menu/light/%s.png", icon_name + strlen ("zc-menu-"));
pixbuf = gdk_pixbuf_new_from_resource (resource_path, NULL);
if (!pixbuf)
{
g_free (resource_path);
resource_path = g_strdup_printf ("/icons/menu/light/%s.svg", icon_name + strlen ("zc-menu-"));
resource_path = icon_resolver_resolve_path (ICON_RESOLVER_ROLE_MENU_ACTION, action,
GTK_ICON_SIZE_MENU, "menu",
ICON_RESOLVER_THEME_SYSTEM,
&system_icon_name);
if (!resource_path)
return NULL;
if (g_str_has_prefix (resource_path, "/icons/"))
pixbuf = gdk_pixbuf_new_from_resource (resource_path, NULL);
}
else
pixbuf = gdk_pixbuf_new_from_file (resource_path, NULL);
g_free (resource_path);
return pixbuf;
@@ -188,136 +94,26 @@ gtkutil_menu_icon_pixbuf_new (const char *icon_name)
const char *
gtkutil_icon_name_from_stock (const char *stock_name)
{
static const struct
{
const char *stock;
const char *icon;
} icon_map[] = {
{ "gtk-new", "document-new" },
{ "gtk-open", "document-open" },
{ "gtk-revert-to-saved", "document-open" },
{ "gtk-save", "document-save" },
{ "gtk-save-as", "document-save-as" },
{ "gtk-add", "list-add" },
{ "gtk-cancel", "dialog-cancel" },
{ "gtk-ok", "dialog-ok" },
{ "gtk-no", "dialog-cancel" },
{ "gtk-yes", "dialog-ok" },
{ "gtk-apply", "dialog-apply" },
{ "gtk-dialog-error", "dialog-error" },
{ "gtk-copy", "edit-copy" },
{ "gtk-delete", "edit-delete" },
{ "gtk-remove", "list-remove" },
{ "gtk-clear", "edit-clear" },
{ "gtk-redo", "edit-redo" },
{ "gtk-find", "edit-find" },
{ "gtk-justify-left", "edit-find" },
{ "gtk-refresh", "view-refresh" },
{ "gtk-go-back", "go-previous" },
{ "gtk-go-forward", "go-next" },
{ "gtk-index", "view-list" },
{ "gtk-jump-to", "go-jump" },
{ "gtk-media-play", "media-playback-start" },
{ "gtk-preferences", "preferences-system" },
{ "gtk-help", "help-browser" },
{ "gtk-about", "help-about" },
{ "gtk-close", "window-close" },
{ "gtk-quit", "application-exit" },
{ "gtk-connect", "network-connect" },
{ "gtk-disconnect", "network-disconnect" },
{ "gtk-network", "network-workgroup" },
{ "gtk-spell-check", "tools-check-spelling" },
};
size_t i;
if (!stock_name)
return NULL;
for (i = 0; i < G_N_ELEMENTS (icon_map); i++)
{
if (strcmp (stock_name, icon_map[i].stock) == 0)
return icon_map[i].icon;
}
return stock_name;
}
static const char *
gtkutil_menu_icon_theme_variant (void)
{
GtkSettings *settings;
gboolean prefer_dark = FALSE;
char *theme_name = NULL;
char *theme_name_lower = NULL;
const char *theme_variant = "light";
settings = gtk_settings_get_default ();
if (settings)
{
g_object_get (G_OBJECT (settings), "gtk-application-prefer-dark-theme", &prefer_dark, NULL);
g_object_get (G_OBJECT (settings), "gtk-theme-name", &theme_name, NULL);
}
if (theme_name)
theme_name_lower = g_ascii_strdown (theme_name, -1);
if (prefer_dark || (theme_name_lower && g_strrstr (theme_name_lower, "dark")))
theme_variant = "dark";
g_free (theme_name_lower);
g_free (theme_name);
return theme_variant;
return icon_resolver_icon_name_from_stock (stock_name);
}
static GtkWidget *
gtkutil_menu_icon_image_new (const char *icon_name, GtkIconSize size)
{
GtkWidget *image = NULL;
GdkPixbuf *pixbuf = NULL;
char *resource_path;
const char *variant;
GdkPixbuf *pixbuf;
gint width;
gint height;
if (!icon_name || !g_str_has_prefix (icon_name, "zc-menu-"))
pixbuf = gtkutil_menu_icon_pixbuf_new (icon_name);
if (!pixbuf)
return NULL;
variant = gtkutil_menu_icon_theme_variant ();
resource_path = g_strdup_printf ("/icons/menu/%s/%s.png", variant, icon_name + strlen ("zc-menu-"));
if (!g_resources_get_info (resource_path, G_RESOURCE_LOOKUP_FLAGS_NONE, NULL, NULL, NULL))
{
g_free (resource_path);
resource_path = g_strdup_printf ("/icons/menu/light/%s.png", icon_name + strlen ("zc-menu-"));
}
image = gtk_image_new_from_pixbuf (pixbuf);
g_object_unref (pixbuf);
pixbuf = gdk_pixbuf_new_from_resource (resource_path, NULL);
if (!pixbuf)
{
g_free (resource_path);
resource_path = g_strdup_printf ("/icons/menu/%s/%s.svg", variant, icon_name + strlen ("zc-menu-"));
if (!g_resources_get_info (resource_path, G_RESOURCE_LOOKUP_FLAGS_NONE, NULL, NULL, NULL))
{
g_free (resource_path);
resource_path = g_strdup_printf ("/icons/menu/light/%s.svg", icon_name + strlen ("zc-menu-"));
}
pixbuf = gdk_pixbuf_new_from_resource (resource_path, NULL);
}
if (pixbuf)
{
image = gtk_image_new_from_pixbuf (pixbuf);
g_object_unref (pixbuf);
}
g_free (resource_path);
if (image)
{
GtkIconSize tmp_size;
gint width;
gint height;
tmp_size = size;
if (gtk_icon_size_lookup (tmp_size, &width, &height))
gtk_image_set_pixel_size (GTK_IMAGE (image), MAX (width, height));
}
if (gtk_icon_size_lookup (size, &width, &height))
gtk_image_set_pixel_size (GTK_IMAGE (image), MAX (width, height));
return image;
}
@@ -327,26 +123,24 @@ gtkutil_image_new_from_stock (const char *stock, GtkIconSize size)
{
GtkWidget *image;
const char *icon_name;
const char *resolved_icon_name = NULL;
int action;
icon_name = gtkutil_icon_name_from_stock (stock);
if (!icon_name && stock && g_str_has_prefix (stock, "zc-menu-"))
icon_name = stock;
if (size == GTK_ICON_SIZE_MENU)
{
const char *menu_icon_name = gtkutil_menu_custom_icon_from_stock (stock);
if (!menu_icon_name)
menu_icon_name = gtkutil_menu_custom_icon_from_icon_name (icon_name);
if (menu_icon_name)
icon_name = menu_icon_name;
}
image = gtkutil_menu_icon_image_new (icon_name, size);
if (image)
return image;
return gtk_image_new_from_icon_name (icon_name, size);
if (icon_resolver_menu_action_from_name (icon_name, &action))
resolved_icon_name = icon_resolver_system_icon_name (ICON_RESOLVER_ROLE_MENU_ACTION, action);
if (!resolved_icon_name)
resolved_icon_name = icon_name;
return gtk_image_new_from_icon_name (resolved_icon_name, size);
}
GtkWidget *
@@ -484,66 +278,7 @@ void
gtkutil_apply_palette (GtkWidget *widget, const GdkRGBA *bg, const GdkRGBA *fg,
const PangoFontDescription *font_desc)
{
if (!widget)
return;
{
static const char *class_name = "zoitechat-palette";
GtkStyleContext *context = gtk_widget_get_style_context (widget);
GtkCssProvider *provider = g_object_get_data (G_OBJECT (widget),
"zoitechat-palette-provider");
gboolean new_provider = FALSE;
GString *css;
gchar *bg_color = NULL;
gchar *fg_color = NULL;
if (!bg && !fg && !font_desc)
{
gtk_style_context_remove_class (context, class_name);
if (provider)
{
gtk_style_context_remove_provider (context, GTK_STYLE_PROVIDER (provider));
g_object_set_data (G_OBJECT (widget), "zoitechat-palette-provider", NULL);
}
return;
}
if (!provider)
{
provider = gtk_css_provider_new ();
g_object_set_data_full (G_OBJECT (widget), "zoitechat-palette-provider",
provider, g_object_unref);
new_provider = TRUE;
}
css = g_string_new (".");
g_string_append (css, class_name);
g_string_append (css, " {");
if (bg)
{
bg_color = gdk_rgba_to_string (bg);
g_string_append_printf (css, " background-color: %s;", bg_color);
}
if (fg)
{
fg_color = gdk_rgba_to_string (fg);
g_string_append_printf (css, " color: %s;", fg_color);
}
gtkutil_append_font_css (css, font_desc);
g_string_append (css, " }");
gtk_css_provider_load_from_data (provider, css->str, -1, NULL);
if (new_provider)
{
gtk_style_context_add_provider (context, GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
}
gtk_style_context_add_class (context, class_name);
g_string_free (css, TRUE);
g_free (bg_color);
g_free (fg_color);
}
theme_manager_apply_palette_widget (widget, bg, fg, font_desc);
}
static void
@@ -668,8 +403,6 @@ static void
gtkutil_file_req_done (GtkWidget * wid, struct file_req *freq)
{
gtkutil_file_req_done_chooser (GTK_FILE_CHOOSER (freq->dialog), freq);
/* this should call the "destroy" cb, where we free(freq) */
gtk_widget_destroy (freq->dialog);
}
@@ -682,7 +415,6 @@ gtkutil_file_req_response (GtkWidget *dialog, gint res, struct file_req *freq)
return;
}
/* this should call the "destroy" cb, where we free(freq) */
gtk_widget_destroy (dialog);
}
@@ -822,6 +554,8 @@ gtkutil_file_req (GtkWindow *parent, const char *title, void *callback, void *us
_("_Open"), GTK_RESPONSE_ACCEPT,
NULL);
theme_manager_attach_window (dialog);
if (filter && filter[0] && (flags & FRF_FILTERISINITIAL))
{
if (flags & FRF_WRITE)
@@ -980,6 +714,7 @@ fe_get_str (char *msg, char *def, void *callback, void *userdata)
_("_Cancel"), GTK_RESPONSE_REJECT,
_("_OK"), GTK_RESPONSE_ACCEPT,
NULL);
theme_manager_attach_window (dialog);
gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (parent_window));
gtk_box_set_homogeneous (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), TRUE);
@@ -1075,6 +810,7 @@ fe_get_int (char *msg, int def, void *callback, void *userdata)
_("_Cancel"), GTK_RESPONSE_REJECT,
_("_OK"), GTK_RESPONSE_ACCEPT,
NULL);
theme_manager_attach_window (dialog);
gtk_box_set_homogeneous (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), TRUE);
gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (parent_window));
@@ -1115,6 +851,7 @@ fe_get_bool (char *title, char *prompt, void *callback, void *userdata)
_("_No"), GTK_RESPONSE_REJECT,
_("_Yes"), GTK_RESPONSE_ACCEPT,
NULL);
theme_manager_attach_window (dialog);
gtk_box_set_homogeneous (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), TRUE);
gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (parent_window));
@@ -1231,6 +968,7 @@ gtkutil_window_new (char *title, char *role, int width, int height, int flags)
GtkWidget *win;
win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
theme_manager_attach_window (win);
gtkutil_set_icon (win);
#ifdef WIN32
gtk_window_set_wmclass (GTK_WINDOW (win), "ZoiteChat", "zoitechat");
@@ -1360,16 +1098,6 @@ gtkutil_treemodel_string_to_iter (GtkTreeModel *model, gchar *pathstr, GtkTreeIt
return success;
}
/*gboolean
gtkutil_treeview_get_selected_iter (GtkTreeView *view, GtkTreeIter *iter_ret)
{
GtkTreeModel *store;
GtkTreeSelection *select;
select = gtk_tree_view_get_selection (view);
return gtk_tree_selection_get_selected (select, &store, iter_ret);
}*/
gboolean
gtkutil_treeview_get_selected (GtkTreeView *view, GtkTreeIter *iter_ret, ...)
{

View File

@@ -22,7 +22,7 @@
#include <gtk/gtk.h>
#include "../common/fe.h"
#include "palette.h"
#include "theme/theme-gtk.h"
typedef void (*filereqcallback) (void *, char *file);

380
src/fe-gtk/icon-resolver.c Normal file
View File

@@ -0,0 +1,380 @@
#include <string.h>
#include "fe-gtk.h"
#include "icon-resolver.h"
#include "theme/theme-policy.h"
#include "../common/cfgfiles.h"
typedef struct
{
IconResolverRole role;
int item;
const char *custom_icon_name;
const char *system_icon_name;
const char *resource_name;
} IconRegistryEntry;
typedef struct
{
const char *stock_name;
const char *system_icon_name;
} StockIconMap;
static const IconRegistryEntry icon_registry[] = {
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_NEW, "zc-menu-new", "document-new", "new" },
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_NETWORK_LIST, "zc-menu-network-list", "view-list", "network-list" },
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_LOAD_PLUGIN, "zc-menu-load-plugin", "document-open", "load-plugin" },
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_DETACH, "zc-menu-detach", "edit-redo", "detach" },
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_CLOSE, "zc-menu-close", "window-close", "close" },
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_QUIT, "zc-menu-quit", "application-exit", "quit" },
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_DISCONNECT, "zc-menu-disconnect", "network-disconnect", "disconnect" },
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_CONNECT, "zc-menu-connect", "network-connect", "connect" },
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_JOIN, "zc-menu-join", "go-jump", "join" },
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_PREFERENCES, "zc-menu-preferences", "preferences-system", "preferences" },
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_CLEAR, "zc-menu-clear", "edit-clear", "clear" },
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_COPY, "zc-menu-copy", "edit-copy", "copy" },
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_DELETE, "zc-menu-delete", "edit-delete", "delete" },
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_ADD, "zc-menu-add", "list-add", "add" },
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_REMOVE, "zc-menu-remove", "list-remove", "remove" },
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_SPELL_CHECK, "zc-menu-spell-check", "tools-check-spelling", "spell-check" },
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_SAVE, "zc-menu-save", "document-save", "save" },
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_SAVE_AS, "zc-menu-save-as", "document-save-as", "save-as" },
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_REFRESH, "zc-menu-refresh", "view-refresh", "refresh" },
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_SEARCH, "zc-menu-search", "edit-find", "search" },
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_FIND, "zc-menu-find", "edit-find", "find" },
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_PREVIOUS, "zc-menu-previous", "go-previous", "previous" },
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_NEXT, "zc-menu-next", "go-next", "next" },
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_HELP, "zc-menu-help", "help-browser", "help" },
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_ABOUT, "zc-menu-about", "help-about", "about" },
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_EMOJI, "zc-menu-emoji", "face-smile", "emoji" },
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_UPDATE, "zc-menu-update", "software-update-available", "update" },
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_CHANLIST, "zc-menu-chanlist", "network-workgroup", "chanlist" },
{ ICON_RESOLVER_ROLE_TRAY_STATE, ICON_RESOLVER_TRAY_STATE_NORMAL, NULL, "zoitechat", "tray_normal" },
{ ICON_RESOLVER_ROLE_TRAY_STATE, ICON_RESOLVER_TRAY_STATE_FILEOFFER, NULL, "mail-attachment", "tray_fileoffer" },
{ ICON_RESOLVER_ROLE_TRAY_STATE, ICON_RESOLVER_TRAY_STATE_HIGHLIGHT, NULL, "dialog-warning", "tray_highlight" },
{ ICON_RESOLVER_ROLE_TRAY_STATE, ICON_RESOLVER_TRAY_STATE_MESSAGE, NULL, "mail-unread", "tray_message" },
{ ICON_RESOLVER_ROLE_TREE_TYPE, ICON_RESOLVER_TREE_TYPE_CHANNEL, NULL, "folder", "tree_channel" },
{ ICON_RESOLVER_ROLE_TREE_TYPE, ICON_RESOLVER_TREE_TYPE_DIALOG, NULL, "mail-message-new", "tree_dialog" },
{ ICON_RESOLVER_ROLE_TREE_TYPE, ICON_RESOLVER_TREE_TYPE_SERVER, NULL, "network-server", "tree_server" },
{ ICON_RESOLVER_ROLE_TREE_TYPE, ICON_RESOLVER_TREE_TYPE_UTIL, NULL, "applications-utilities", "tree_util" },
{ ICON_RESOLVER_ROLE_USERLIST_RANK, ICON_RESOLVER_USERLIST_RANK_VOICE, NULL, "emblem-ok", "ulist_voice" },
{ ICON_RESOLVER_ROLE_USERLIST_RANK, ICON_RESOLVER_USERLIST_RANK_HALFOP, NULL, "emblem-shared", "ulist_halfop" },
{ ICON_RESOLVER_ROLE_USERLIST_RANK, ICON_RESOLVER_USERLIST_RANK_OP, NULL, "emblem-default", "ulist_op" },
{ ICON_RESOLVER_ROLE_USERLIST_RANK, ICON_RESOLVER_USERLIST_RANK_OWNER, NULL, "emblem-favorite", "ulist_owner" },
{ ICON_RESOLVER_ROLE_USERLIST_RANK, ICON_RESOLVER_USERLIST_RANK_FOUNDER, NULL, "emblem-favorite", "ulist_founder" },
{ ICON_RESOLVER_ROLE_USERLIST_RANK, ICON_RESOLVER_USERLIST_RANK_NETOP, NULL, "emblem-system", "ulist_netop" }
};
static const StockIconMap stock_icon_map[] = {
{ "gtk-new", "document-new" },
{ "gtk-open", "document-open" },
{ "gtk-revert-to-saved", "document-open" },
{ "gtk-save", "document-save" },
{ "gtk-save-as", "document-save-as" },
{ "gtk-add", "list-add" },
{ "gtk-cancel", "dialog-cancel" },
{ "gtk-ok", "dialog-ok" },
{ "gtk-no", "dialog-cancel" },
{ "gtk-yes", "dialog-ok" },
{ "gtk-apply", "dialog-apply" },
{ "gtk-dialog-error", "dialog-error" },
{ "gtk-copy", "edit-copy" },
{ "gtk-delete", "edit-delete" },
{ "gtk-remove", "list-remove" },
{ "gtk-clear", "edit-clear" },
{ "gtk-redo", "edit-redo" },
{ "gtk-find", "edit-find" },
{ "gtk-justify-left", "edit-find" },
{ "gtk-refresh", "view-refresh" },
{ "gtk-go-back", "go-previous" },
{ "gtk-go-forward", "go-next" },
{ "gtk-index", "view-list" },
{ "gtk-jump-to", "go-jump" },
{ "gtk-media-play", "media-playback-start" },
{ "gtk-preferences", "preferences-system" },
{ "gtk-help", "help-browser" },
{ "gtk-about", "help-about" },
{ "gtk-close", "window-close" },
{ "gtk-quit", "application-exit" },
{ "gtk-connect", "network-connect" },
{ "gtk-disconnect", "network-disconnect" },
{ "gtk-network", "network-workgroup" },
{ "gtk-spell-check", "tools-check-spelling" }
};
static int
menu_action_from_icon_name (const char *icon_name)
{
size_t i;
if (!icon_name)
return -1;
for (i = 0; i < G_N_ELEMENTS (icon_registry); i++)
{
if (icon_registry[i].role != ICON_RESOLVER_ROLE_MENU_ACTION)
continue;
if (icon_registry[i].system_icon_name && strcmp (icon_name, icon_registry[i].system_icon_name) == 0)
return icon_registry[i].item;
}
return -1;
}
static const IconRegistryEntry *
icon_registry_find (IconResolverRole role, int item)
{
size_t i;
for (i = 0; i < G_N_ELEMENTS (icon_registry); i++)
{
if (icon_registry[i].role == role && icon_registry[i].item == item)
return &icon_registry[i];
}
return NULL;
}
static const IconRegistryEntry *
icon_registry_find_custom (const char *custom_icon_name)
{
size_t i;
if (!custom_icon_name)
return NULL;
for (i = 0; i < G_N_ELEMENTS (icon_registry); i++)
{
if (icon_registry[i].custom_icon_name && strcmp (icon_registry[i].custom_icon_name, custom_icon_name) == 0)
return &icon_registry[i];
}
return NULL;
}
const char *
icon_resolver_icon_name_from_stock (const char *stock_name)
{
size_t i;
if (!stock_name)
return NULL;
for (i = 0; i < G_N_ELEMENTS (stock_icon_map); i++)
{
if (strcmp (stock_name, stock_icon_map[i].stock_name) == 0)
return stock_icon_map[i].system_icon_name;
}
return stock_name;
}
gboolean
icon_resolver_menu_action_from_name (const char *name, int *action_out)
{
size_t i;
if (!name)
return FALSE;
for (i = 0; i < G_N_ELEMENTS (icon_registry); i++)
{
if (icon_registry[i].role != ICON_RESOLVER_ROLE_MENU_ACTION)
continue;
if ((icon_registry[i].custom_icon_name && strcmp (name, icon_registry[i].custom_icon_name) == 0) ||
(icon_registry[i].system_icon_name && strcmp (name, icon_registry[i].system_icon_name) == 0))
{
if (action_out)
*action_out = icon_registry[i].item;
return TRUE;
}
}
for (i = 0; i < G_N_ELEMENTS (stock_icon_map); i++)
{
if (strcmp (name, stock_icon_map[i].stock_name) == 0)
{
int action = menu_action_from_icon_name (stock_icon_map[i].system_icon_name);
if (action >= 0)
{
if (action_out)
*action_out = action;
return TRUE;
}
}
}
return FALSE;
}
const char *
icon_resolver_icon_name_for_menu_custom (const char *custom_icon_name)
{
const IconRegistryEntry *entry = icon_registry_find_custom (custom_icon_name);
if (!entry)
return NULL;
return entry->system_icon_name;
}
gboolean
icon_resolver_menu_action_from_custom (const char *custom_icon_name, int *action_out)
{
const IconRegistryEntry *entry = icon_registry_find_custom (custom_icon_name);
if (!entry || entry->role != ICON_RESOLVER_ROLE_MENU_ACTION)
return FALSE;
if (action_out)
*action_out = entry->item;
return TRUE;
}
const char *
icon_resolver_system_icon_name (IconResolverRole role, int item)
{
const IconRegistryEntry *entry = icon_registry_find (role, item);
if (!entry)
return NULL;
return entry->system_icon_name;
}
IconResolverThemeVariant
icon_resolver_detect_theme_variant (void)
{
if (theme_policy_is_app_dark_mode_active ())
return ICON_RESOLVER_THEME_DARK;
return ICON_RESOLVER_THEME_LIGHT;
}
static gboolean
resource_exists (const char *resource_path)
{
return g_resources_get_info (resource_path, G_RESOURCE_LOOKUP_FLAGS_NONE, NULL, NULL, NULL);
}
static char *
resolve_user_override (const IconRegistryEntry *entry, IconResolverThemeVariant variant)
{
const char *variant_name = variant == ICON_RESOLVER_THEME_DARK ? "dark" : "light";
char *path;
path = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "icons" G_DIR_SEPARATOR_S "%s" G_DIR_SEPARATOR_S "%s.png",
get_xdir (), variant_name, entry->resource_name);
if (g_file_test (path, G_FILE_TEST_EXISTS))
return path;
g_free (path);
path = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "icons" G_DIR_SEPARATOR_S "%s-%s.png",
get_xdir (), entry->resource_name, variant_name);
if (g_file_test (path, G_FILE_TEST_EXISTS))
return path;
g_free (path);
path = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "icons" G_DIR_SEPARATOR_S "%s.png",
get_xdir (), entry->resource_name);
if (g_file_test (path, G_FILE_TEST_EXISTS))
return path;
g_free (path);
return NULL;
}
static char *
resolve_bundled_variant (const IconRegistryEntry *entry, IconResolverThemeVariant variant)
{
const char *variant_name = variant == ICON_RESOLVER_THEME_DARK ? "dark" : "light";
char *path;
if (entry->role == ICON_RESOLVER_ROLE_MENU_ACTION)
{
path = g_strdup_printf ("/icons/menu/%s/%s.png", variant_name, entry->resource_name);
if (resource_exists (path))
return path;
g_free (path);
path = g_strdup_printf ("/icons/menu/%s/%s.svg", variant_name, entry->resource_name);
if (resource_exists (path))
return path;
g_free (path);
}
else
{
path = g_strdup_printf ("/icons/%s-%s.png", entry->resource_name, variant_name);
if (resource_exists (path))
return path;
g_free (path);
}
return NULL;
}
static char *
resolve_bundled_neutral (const IconRegistryEntry *entry)
{
char *path;
if (entry->role == ICON_RESOLVER_ROLE_MENU_ACTION)
{
path = g_strdup_printf ("/icons/menu/light/%s.png", entry->resource_name);
if (resource_exists (path))
return path;
g_free (path);
path = g_strdup_printf ("/icons/menu/light/%s.svg", entry->resource_name);
if (resource_exists (path))
return path;
g_free (path);
}
else
{
path = g_strdup_printf ("/icons/%s.png", entry->resource_name);
if (resource_exists (path))
return path;
g_free (path);
}
return NULL;
}
char *
icon_resolver_resolve_path (IconResolverRole role, int item, GtkIconSize size,
const char *context, IconResolverThemeVariant variant,
const char **system_icon_name)
{
const IconRegistryEntry *entry;
IconResolverThemeVariant effective_variant = variant;
char *path;
(void)size;
(void)context;
entry = icon_registry_find (role, item);
if (!entry)
return NULL;
if (system_icon_name)
*system_icon_name = entry->system_icon_name;
if (effective_variant == ICON_RESOLVER_THEME_SYSTEM)
effective_variant = icon_resolver_detect_theme_variant ();
path = resolve_user_override (entry, effective_variant);
if (path)
return path;
path = resolve_bundled_variant (entry, effective_variant);
if (path)
return path;
return resolve_bundled_neutral (entry);
}

View File

@@ -0,0 +1,89 @@
#ifndef ZOITECHAT_ICON_RESOLVER_H
#define ZOITECHAT_ICON_RESOLVER_H
#include <gtk/gtk.h>
typedef enum
{
ICON_RESOLVER_ROLE_MENU_ACTION,
ICON_RESOLVER_ROLE_TRAY_STATE,
ICON_RESOLVER_ROLE_TREE_TYPE,
ICON_RESOLVER_ROLE_USERLIST_RANK
} IconResolverRole;
typedef enum
{
ICON_RESOLVER_THEME_SYSTEM,
ICON_RESOLVER_THEME_LIGHT,
ICON_RESOLVER_THEME_DARK
} IconResolverThemeVariant;
typedef enum
{
ICON_RESOLVER_MENU_ACTION_NEW,
ICON_RESOLVER_MENU_ACTION_NETWORK_LIST,
ICON_RESOLVER_MENU_ACTION_LOAD_PLUGIN,
ICON_RESOLVER_MENU_ACTION_DETACH,
ICON_RESOLVER_MENU_ACTION_CLOSE,
ICON_RESOLVER_MENU_ACTION_QUIT,
ICON_RESOLVER_MENU_ACTION_DISCONNECT,
ICON_RESOLVER_MENU_ACTION_CONNECT,
ICON_RESOLVER_MENU_ACTION_JOIN,
ICON_RESOLVER_MENU_ACTION_PREFERENCES,
ICON_RESOLVER_MENU_ACTION_CLEAR,
ICON_RESOLVER_MENU_ACTION_COPY,
ICON_RESOLVER_MENU_ACTION_DELETE,
ICON_RESOLVER_MENU_ACTION_ADD,
ICON_RESOLVER_MENU_ACTION_REMOVE,
ICON_RESOLVER_MENU_ACTION_SPELL_CHECK,
ICON_RESOLVER_MENU_ACTION_SAVE,
ICON_RESOLVER_MENU_ACTION_SAVE_AS,
ICON_RESOLVER_MENU_ACTION_REFRESH,
ICON_RESOLVER_MENU_ACTION_SEARCH,
ICON_RESOLVER_MENU_ACTION_FIND,
ICON_RESOLVER_MENU_ACTION_PREVIOUS,
ICON_RESOLVER_MENU_ACTION_NEXT,
ICON_RESOLVER_MENU_ACTION_HELP,
ICON_RESOLVER_MENU_ACTION_ABOUT,
ICON_RESOLVER_MENU_ACTION_EMOJI,
ICON_RESOLVER_MENU_ACTION_UPDATE,
ICON_RESOLVER_MENU_ACTION_CHANLIST
} IconResolverMenuAction;
typedef enum
{
ICON_RESOLVER_TRAY_STATE_NORMAL,
ICON_RESOLVER_TRAY_STATE_FILEOFFER,
ICON_RESOLVER_TRAY_STATE_HIGHLIGHT,
ICON_RESOLVER_TRAY_STATE_MESSAGE
} IconResolverTrayState;
typedef enum
{
ICON_RESOLVER_TREE_TYPE_CHANNEL,
ICON_RESOLVER_TREE_TYPE_DIALOG,
ICON_RESOLVER_TREE_TYPE_SERVER,
ICON_RESOLVER_TREE_TYPE_UTIL
} IconResolverTreeType;
typedef enum
{
ICON_RESOLVER_USERLIST_RANK_VOICE,
ICON_RESOLVER_USERLIST_RANK_HALFOP,
ICON_RESOLVER_USERLIST_RANK_OP,
ICON_RESOLVER_USERLIST_RANK_OWNER,
ICON_RESOLVER_USERLIST_RANK_FOUNDER,
ICON_RESOLVER_USERLIST_RANK_NETOP
} IconResolverUserlistRank;
const char *icon_resolver_icon_name_from_stock (const char *stock_name);
const char *icon_resolver_icon_name_for_menu_custom (const char *custom_icon_name);
gboolean icon_resolver_menu_action_from_custom (const char *custom_icon_name, int *action_out);
gboolean icon_resolver_menu_action_from_name (const char *name, int *action_out);
const char *icon_resolver_system_icon_name (IconResolverRole role, int item);
IconResolverThemeVariant icon_resolver_detect_theme_variant (void);
char *icon_resolver_resolve_path (IconResolverRole role, int item, GtkIconSize size,
const char *context, IconResolverThemeVariant variant,
const char **system_icon_name);
#endif

View File

@@ -23,6 +23,7 @@
#include <sys/stat.h>
#include <fcntl.h>
#include "fe-gtk.h"
#include "theme/theme-manager.h"
#include "../common/zoitechat.h"
#include "../common/ignore.h"
@@ -295,6 +296,7 @@ ignore_clear_entry_clicked (GtkWidget * wid)
dialog = gtk_message_dialog_new (NULL, 0,
GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL,
_("Are you sure you want to remove all ignores?"));
theme_manager_attach_window (dialog);
g_signal_connect (G_OBJECT (dialog), "response",
G_CALLBACK (ignore_clear_cb), NULL);
gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);

View File

@@ -39,6 +39,7 @@
#include "fe-gtk.h"
#include "chanlist.h"
#include "gtkutil.h"
#include "theme/theme-manager.h"
#define ICON_JOIND_NETWORK "network-workgroup"
@@ -81,11 +82,9 @@ joind_ok_cb (GtkWidget *ok, server *serv)
return;
}
/* do nothing */
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (serv->gui->joind_radio1)))
goto xit;
/* join specific channel */
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (serv->gui->joind_radio2)))
{
char *text = (char *)gtk_entry_get_text (GTK_ENTRY (serv->gui->joind_entry));
@@ -98,7 +97,6 @@ joind_ok_cb (GtkWidget *ok, server *serv)
goto xit;
}
/* channel list */
chanlist_opengui (serv, TRUE);
xit:
@@ -132,6 +130,7 @@ joind_show_dialog (server *serv)
char buf2[256];
serv->gui->joind_win = dialog1 = gtk_dialog_new ();
theme_manager_attach_window (dialog1);
g_snprintf(buf, sizeof(buf), _("Connection Complete - %s"), _(DISPLAY_NAME));
gtk_window_set_title (GTK_WINDOW (dialog1), buf);
gtk_window_set_type_hint (GTK_WINDOW (dialog1), GDK_WINDOW_TYPE_HINT_DIALOG);

View File

@@ -41,10 +41,13 @@
#include "../common/cfgfiles.h"
#include "fe-gtk.h"
#include "theme/theme-manager.h"
#include "theme/theme-css.h"
#include "banlist.h"
#include "gtkutil.h"
#include "joind.h"
#include "palette.h"
#include "theme/theme-access.h"
#include "theme/theme-palette.h"
#include "maingui.h"
#include "menu.h"
#include "fkeys.h"
@@ -58,6 +61,87 @@
#ifdef G_OS_WIN32
#include <windows.h>
#include <shellapi.h>
#include <gdk/gdkwin32.h>
static void
mg_win32_allow_autohide_taskbar (GtkWindow *window, GdkEventWindowState *event)
{
GdkWindow *gdk_window;
HWND hwnd;
if (!window || !event)
return;
if ((event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN) != 0)
return;
gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
if (!gdk_window)
return;
hwnd = gdk_win32_window_get_handle (gdk_window);
if (!hwnd)
return;
if (event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED)
{
APPBARDATA appbar_data;
RECT work_area;
ZeroMemory (&appbar_data, sizeof (APPBARDATA));
appbar_data.cbSize = sizeof (APPBARDATA);
if ((SHAppBarMessage (ABM_GETSTATE, &appbar_data) & ABS_AUTOHIDE) != 0 &&
SHAppBarMessage (ABM_GETTASKBARPOS, &appbar_data) != 0)
{
HMONITOR monitor;
MONITORINFO monitor_info;
monitor = MonitorFromWindow (hwnd, MONITOR_DEFAULTTONEAREST);
ZeroMemory (&monitor_info, sizeof (MONITORINFO));
monitor_info.cbSize = sizeof (MONITORINFO);
if (monitor && GetMonitorInfo (monitor, &monitor_info))
{
work_area = monitor_info.rcMonitor;
switch (appbar_data.uEdge)
{
case ABE_LEFT:
work_area.left += 1;
break;
case ABE_TOP:
work_area.top += 1;
break;
case ABE_RIGHT:
work_area.right -= 1;
break;
case ABE_BOTTOM:
default:
work_area.bottom -= 1;
break;
}
SetWindowPos (hwnd,
NULL,
work_area.left,
work_area.top,
work_area.right - work_area.left,
work_area.bottom - work_area.top,
SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER);
}
}
}
SetWindowPos (hwnd,
HWND_NOTOPMOST,
0,
0,
0,
0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
}
#endif
#define ICON_TAB_DETACH "zc-menu-detach"
@@ -135,8 +219,7 @@ mg_apply_font_css (GtkWidget *widget, const PangoFontDescription *desc,
g_string_free (css, TRUE);
gtk_style_context_add_class (context, class_name);
gtk_style_context_add_provider (context, GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
theme_css_apply_widget_provider (widget, GTK_STYLE_PROVIDER (provider));
}
static void
@@ -324,7 +407,7 @@ mg_attr_list_create (const XTextColor *col, int size)
static void
mg_create_tab_colors (void)
{
XTextColor gui_palette[MAX_COL + 1];
XTextColor gui_palette[XTEXT_COLS];
if (plain_list)
{
@@ -335,12 +418,12 @@ mg_create_tab_colors (void)
pango_attr_list_unref (away_list);
}
palette_get_xtext_colors (gui_palette, G_N_ELEMENTS (gui_palette));
theme_get_xtext_colors (gui_palette, G_N_ELEMENTS (gui_palette));
plain_list = mg_attr_list_create (NULL, prefs.hex_gui_tab_small);
newdata_list = mg_attr_list_create (&gui_palette[COL_NEW_DATA], prefs.hex_gui_tab_small);
nickseen_list = mg_attr_list_create (&gui_palette[COL_HILIGHT], prefs.hex_gui_tab_small);
newmsg_list = mg_attr_list_create (&gui_palette[COL_NEW_MSG], prefs.hex_gui_tab_small);
away_list = mg_attr_list_create (&gui_palette[COL_AWAY], FALSE);
newdata_list = mg_attr_list_create (&gui_palette[THEME_TOKEN_TAB_NEW_DATA], prefs.hex_gui_tab_small);
nickseen_list = mg_attr_list_create (&gui_palette[THEME_TOKEN_TAB_HIGHLIGHT], prefs.hex_gui_tab_small);
newmsg_list = mg_attr_list_create (&gui_palette[THEME_TOKEN_TAB_NEW_MESSAGE], prefs.hex_gui_tab_small);
away_list = mg_attr_list_create (&gui_palette[THEME_TOKEN_TAB_AWAY], FALSE);
}
static void
@@ -349,12 +432,47 @@ set_window_urgency (GtkWidget *win, gboolean set)
gtk_window_set_urgency_hint (GTK_WINDOW (win), set);
}
static gboolean
is_wayland_display (void)
{
GdkDisplay *display = gdk_display_get_default ();
const char *name;
if (!display)
return FALSE;
name = gdk_display_get_name (display);
if (!name)
return FALSE;
return g_str_has_prefix (name, "wayland");
}
static gboolean
is_kde_desktop (void)
{
const char *desktop = g_getenv ("XDG_CURRENT_DESKTOP");
if (desktop && strstr (desktop, "KDE"))
return TRUE;
return g_getenv ("KDE_FULL_SESSION") != NULL;
}
static gboolean
is_kde_wayland (void)
{
return is_wayland_display () && is_kde_desktop ();
}
static void
flash_window (GtkWidget *win)
{
#ifdef HAVE_GTK_MAC
gtkosx_application_attention_request (osx_app, INFO_REQUEST);
#endif
if (is_kde_wayland ())
gtk_window_present (GTK_WINDOW (win));
set_window_urgency (win, TRUE);
}
@@ -659,6 +777,10 @@ mg_windowstate_cb (GtkWindow *wid, GdkEventWindowState *event, gpointer userdata
menu_set_fullscreen (current_sess->gui, prefs.hex_gui_win_fullscreen);
#ifdef G_OS_WIN32
mg_win32_allow_autohide_taskbar (wid, event);
#endif
return FALSE;
}
@@ -1193,7 +1315,6 @@ mg_switch_page (int relative, int num)
static void
mg_topdestroy_cb (GtkWidget *win, session *sess)
{
/* printf("enter mg_topdestroy. sess %p was destroyed\n", sess);*/
session_free (sess); /* tell zoitechat.c about it */
}
@@ -1208,7 +1329,6 @@ mg_ircdestroy (session *sess)
if (mg_gui == NULL)
{
/* puts("-> mg_gui is already NULL");*/
return;
}
@@ -1218,13 +1338,11 @@ mg_ircdestroy (session *sess)
sess = list->data;
if (sess->gui->is_tab)
{
/* puts("-> some tabs still remain");*/
return;
}
list = list->next;
}
/* puts("-> no tabs left, killing main tabwindow");*/
gtk_widget_destroy (mg_gui->window);
active_tab = NULL;
mg_gui = NULL;
@@ -1281,6 +1399,7 @@ mg_tab_close (session *sess)
GTK_MESSAGE_WARNING, GTK_BUTTONS_OK_CANCEL,
_("This server still has %d channels or dialogs associated with it. "
"Close them all?"), i);
theme_manager_attach_window (dialog);
g_signal_connect (G_OBJECT (dialog), "response",
G_CALLBACK (mg_tab_close_cb), sess);
if (prefs.hex_gui_tab_layout)
@@ -1378,6 +1497,7 @@ mg_open_quit_dialog (gboolean minimize_button)
}
dialog = gtk_dialog_new ();
theme_manager_attach_window (dialog);
gtk_container_set_border_width (GTK_CONTAINER (dialog), 6);
gtk_window_set_title (GTK_WINDOW (dialog), _("Quit ZoiteChat?"));
gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (parent_window));
@@ -1670,7 +1790,13 @@ mg_create_color_menu (GtkWidget *menu, session *sess)
guint16 green;
guint16 blue;
palette_color_get_rgb16 (&colors[i], &red, &green, &blue);
GdkRGBA color;
if (!theme_get_mirc_color ((unsigned int) i, &color))
continue;
red = (guint16) CLAMP (color.red * 65535.0 + 0.5, 0.0, 65535.0);
green = (guint16) CLAMP (color.green * 65535.0 + 0.5, 0.0, 65535.0);
blue = (guint16) CLAMP (color.blue * 65535.0 + 0.5, 0.0, 65535.0);
sprintf (buf, "<tt><sup>%02d</sup> <span background=\"#%02x%02x%02x\">"
" </span></tt>",
i, red >> 8, green >> 8, blue >> 8);
@@ -1685,7 +1811,13 @@ mg_create_color_menu (GtkWidget *menu, session *sess)
guint16 green;
guint16 blue;
palette_color_get_rgb16 (&colors[i], &red, &green, &blue);
GdkRGBA color;
if (!theme_get_mirc_color ((unsigned int) i, &color))
continue;
red = (guint16) CLAMP (color.red * 65535.0 + 0.5, 0.0, 65535.0);
green = (guint16) CLAMP (color.green * 65535.0 + 0.5, 0.0, 65535.0);
blue = (guint16) CLAMP (color.blue * 65535.0 + 0.5, 0.0, 65535.0);
sprintf (buf, "<tt><sup>%02d</sup> <span background=\"#%02x%02x%02x\">"
" </span></tt>",
i, red >> 8, green >> 8, blue >> 8);
@@ -2004,7 +2136,6 @@ mg_tabwindow_kill_cb (GtkWidget *win, gpointer userdata)
GSList *list, *next;
session *sess;
/* puts("enter mg_tabwindow_kill_cb");*/
zoitechat_is_quitting = TRUE;
/* see if there's any non-tab windows left */
@@ -2016,7 +2147,6 @@ mg_tabwindow_kill_cb (GtkWidget *win, gpointer userdata)
if (!sess->gui->is_tab)
{
zoitechat_is_quitting = FALSE;
/* puts("-> will not exit, some toplevel windows left");*/
} else
{
mg_ircdestroy (sess);
@@ -2050,7 +2180,6 @@ mg_changui_destroy (session *sess)
/* avoid calling the "destroy" callback */
g_signal_handlers_disconnect_by_func (G_OBJECT (sess->gui->window),
mg_topdestroy_cb, sess);
/*gtk_widget_destroy (sess->gui->window);*/
/* don't destroy until the new one is created. Not sure why, but */
/* it fixes: Gdk-CRITICAL **: gdk_colormap_get_screen: */
/* assertion `GDK_IS_COLORMAP (cmap)' failed */
@@ -2281,8 +2410,7 @@ mg_limit_entry_cb (GtkWidget * igad, gpointer userdata)
static void
mg_apply_entry_style (GtkWidget *entry)
{
gtkutil_apply_palette (entry, &colors[COL_BG], &colors[COL_FG],
input_style->font_desc);
theme_manager_apply_entry_palette (entry, input_style->font_desc);
}
static void
@@ -2526,7 +2654,7 @@ mg_update_xtext (GtkWidget *wid)
const gchar *font_name;
XTextColor xtext_palette[XTEXT_COLS];
palette_get_xtext_colors (xtext_palette, XTEXT_COLS);
theme_get_xtext_colors_for_widget (wid, xtext_palette, XTEXT_COLS);
gtk_xtext_set_palette (xtext, xtext_palette);
gtk_xtext_set_max_lines (xtext, prefs.hex_text_max_lines);
gtk_xtext_set_background (xtext, channelwin_pix);
@@ -2573,7 +2701,7 @@ mg_create_textarea (session *sess, GtkWidget *box)
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
gtk_box_pack_start (GTK_BOX (inbox), frame, TRUE, TRUE, 0);
palette_get_xtext_colors (xtext_palette, XTEXT_COLS);
theme_get_xtext_colors_for_widget (frame, xtext_palette, XTEXT_COLS);
gui->xtext = gtk_xtext_new (xtext_palette, TRUE);
xtext = GTK_XTEXT (gui->xtext);
gtk_xtext_set_max_indent (xtext, prefs.hex_text_max_indent);
@@ -2692,6 +2820,81 @@ mg_update_meters (session_gui *gui)
gtk_widget_show_all (gui->meter_box);
}
static void
mg_theme_apply_userlist_style (session_gui *gui)
{
const PangoFontDescription *font = NULL;
if (!gui || !gui->user_tree)
return;
if (input_style)
font = input_style->font_desc;
theme_manager_apply_userlist_style (gui->user_tree,
theme_manager_get_userlist_palette_behavior (font));
}
static void
mg_theme_userlist_changed (const ThemeChangedEvent *event, gpointer userdata)
{
session_gui *gui = userdata;
if (!theme_changed_event_has_reason (event, THEME_CHANGED_REASON_USERLIST) &&
!theme_changed_event_has_reason (event, THEME_CHANGED_REASON_PALETTE) &&
!theme_changed_event_has_reason (event, THEME_CHANGED_REASON_WIDGET_STYLE) &&
!theme_changed_event_has_reason (event, THEME_CHANGED_REASON_MODE) &&
!theme_changed_event_has_reason (event, THEME_CHANGED_REASON_THEME_PACK))
return;
mg_theme_apply_userlist_style (gui);
}
static void
mg_theme_window_changed (const ThemeChangedEvent *event, gpointer userdata)
{
session_gui *gui = userdata;
if (!theme_changed_event_has_reason (event, THEME_CHANGED_REASON_MODE) &&
!theme_changed_event_has_reason (event, THEME_CHANGED_REASON_THEME_PACK) &&
!theme_changed_event_has_reason (event, THEME_CHANGED_REASON_WIDGET_STYLE))
return;
if (gui)
theme_manager_apply_to_window (gui->window);
}
static void
mg_theme_userlist_destroy_cb (GtkWidget *widget, gpointer userdata)
{
session_gui *gui = userdata;
(void) widget;
if (!gui)
return;
if (gui->theme_userlist_listener_id)
{
theme_listener_unregister (gui->theme_userlist_listener_id);
gui->theme_userlist_listener_id = 0;
}
}
static void
mg_theme_window_destroy_cb (GtkWidget *widget, gpointer userdata)
{
session_gui *gui = userdata;
(void) widget;
if (!gui)
return;
theme_manager_detach_window (gui->window);
if (gui->theme_window_listener_id)
{
theme_listener_unregister (gui->theme_window_listener_id);
gui->theme_window_listener_id = 0;
}
}
static void
mg_create_userlist (session_gui *gui, GtkWidget *box)
{
@@ -2709,19 +2912,10 @@ mg_create_userlist (session_gui *gui, GtkWidget *box)
gui->user_tree = ulist = userlist_create (vbox);
/*
* Keep the user list in sync with the chat palette.
*
* - When "Use the text box font and colors" is enabled, we already want the
* palette background.
* - When "Dark mode" is enabled, we also force the user list to use the
* palette colors so it doesn't stay blindingly white on dark themes.
*/
if (prefs.hex_gui_ulist_style || fe_dark_mode_is_enabled ())
{
gtkutil_apply_palette (ulist, &colors[COL_BG], &colors[COL_FG],
input_style ? input_style->font_desc : NULL);
}
if (!gui->theme_userlist_listener_id)
gui->theme_userlist_listener_id = theme_listener_register ("maingui.userlist", mg_theme_userlist_changed, gui);
g_signal_connect (G_OBJECT (ulist), "destroy", G_CALLBACK (mg_theme_userlist_destroy_cb), gui);
mg_theme_apply_userlist_style (gui);
mg_create_meters (gui, vbox);
@@ -3548,7 +3742,6 @@ mg_create_topwindow (session *sess)
g_signal_connect (G_OBJECT (win), "configure_event",
G_CALLBACK (mg_configure_cb), sess);
palette_alloc (win);
table = gtk_grid_new ();
/* spacing under the menubar */
@@ -3603,7 +3796,10 @@ mg_create_topwindow (session *sess)
mg_place_userlist_and_chanview (sess->gui);
gtk_widget_show (win);
fe_apply_theme_to_toplevel (win);
if (!sess->gui->theme_window_listener_id)
sess->gui->theme_window_listener_id = theme_listener_register ("maingui.window", mg_theme_window_changed, sess->gui);
g_signal_connect (G_OBJECT (win), "destroy", G_CALLBACK (mg_theme_window_destroy_cb), sess->gui);
theme_manager_attach_window (win);
#ifdef G_OS_WIN32
parent_win = gtk_widget_get_window (win);
@@ -3652,7 +3848,7 @@ mg_win32_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data)
if (msg->message == WM_SETTINGCHANGE || msg->message == WM_THEMECHANGED)
{
fe_refresh_auto_dark_mode ();
theme_manager_refresh_auto_mode ();
return GDK_FILTER_CONTINUE;
}
@@ -3740,7 +3936,6 @@ mg_create_tabwindow (session *sess)
g_signal_connect (G_OBJECT (win), "window_state_event",
G_CALLBACK (mg_windowstate_cb), NULL);
palette_alloc (win);
sess->gui->main_table = table = gtk_grid_new ();
/* spacing under the menubar */
@@ -3779,7 +3974,10 @@ mg_create_tabwindow (session *sess)
mg_place_userlist_and_chanview (sess->gui);
gtk_widget_show (win);
fe_apply_theme_to_toplevel (win);
if (!sess->gui->theme_window_listener_id)
sess->gui->theme_window_listener_id = theme_listener_register ("maingui.window", mg_theme_window_changed, sess->gui);
g_signal_connect (G_OBJECT (win), "destroy", G_CALLBACK (mg_theme_window_destroy_cb), sess->gui);
theme_manager_attach_window (win);
#ifdef G_OS_WIN32
parent_win = gtk_widget_get_window (win);
@@ -3803,8 +4001,6 @@ mg_apply_setup (void)
((xtext_buffer *)sess->res->buffer)->needs_recalc = TRUE;
if (!sess->gui->is_tab || !done_main)
mg_place_userlist_and_chanview (sess->gui);
if (sess->gui->window)
fe_apply_theme_to_toplevel (sess->gui->window);
if (sess->gui->is_tab)
done_main = TRUE;
list = list->next;
@@ -4140,6 +4336,8 @@ fe_session_callback (session *sess)
{
gtk_xtext_buffer_free (sess->res->buffer);
g_object_unref (G_OBJECT (sess->res->user_model));
if (sess->res->user_row_refs)
g_hash_table_destroy (sess->res->user_row_refs);
if (sess->res->banlist && sess->res->banlist->window)
mg_close_gen (NULL, sess->res->banlist->window);

View File

@@ -54,7 +54,8 @@
#include "notifygui.h"
#include "pixmaps.h"
#include "rawlog.h"
#include "palette.h"
#include "theme/theme-gtk.h"
#include "theme/theme-manager.h"
#include "plugingui.h"
#include "search.h"
#include "textgui.h"
@@ -1520,6 +1521,7 @@ menu_join (GtkWidget * wid, gpointer none)
_("_Cancel"), GTK_RESPONSE_REJECT,
_("_OK"), GTK_RESPONSE_ACCEPT,
NULL);
theme_manager_attach_window (dialog);
{
GtkWidget *button;
@@ -1856,6 +1858,7 @@ static void
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" \
@@ -2483,6 +2486,7 @@ menu_create_main (void *accel_group, int bar, int away, int toplevel,
if (bar)
{
menu_bar = gtk_menu_bar_new ();
gtk_style_context_add_class (gtk_widget_get_style_context (menu_bar), GTK_STYLE_CLASS_MENUBAR);
#ifdef HAVE_GTK_MAC
gtkosx_application_set_menu_bar (osx_app, GTK_MENU_SHELL (menu_bar));
#endif

View File

@@ -1,3 +1,15 @@
zoitechat_theme_sources = [
'theme/theme-access.c',
'theme/theme-application.c',
'theme/theme-css.c',
'theme/theme-gtk3.c',
'theme/theme-manager.c',
'theme/theme-palette.c',
'theme/theme-preferences.c',
'theme/theme-policy.c',
'theme/theme-runtime.c',
]
zoitechat_gtk_sources = [
'ascii.c',
'banlist.c',
@@ -9,12 +21,12 @@ zoitechat_gtk_sources = [
'fe-gtk.c',
'fkeys.c',
'gtkutil.c',
'icon-resolver.c',
'ignoregui.c',
'joind.c',
'menu.c',
'maingui.c',
'notifygui.c',
'palette.c',
'pixmaps.c',
'plugin-tray.c',
'plugin-notification.c',
@@ -37,6 +49,8 @@ zoitechat_gtk_deps = [
gtk_dep = dependency('gtk+-3.0', version: '>= 3.22')
zoitechat_theme_deps = [gtk_dep]
if host_machine.system() != 'windows'
appindicator_opt = get_option('appindicator')
@@ -76,17 +90,19 @@ zoitechat_gtk_ldflags = []
if host_machine.system() == 'windows'
zoitechat_gtk_sources += 'notifications/notification-windows.c'
zoitechat_gtk_deps += cc.find_library('dwmapi', required: true)
# TODO: mingw doesn't have these headers or libs
# add_languages('cpp')
# shared_module('hcnotifications-winrt',
# sources: 'notifications/notification-winrt.cpp'
#)
zoitechat_theme_deps += cc.find_library('dwmapi', required: true)
else
zoitechat_gtk_sources += 'notifications/notification-freedesktop.c'
endif
zoitechat_theme_lib = static_library('zoitechat_theme',
sources: zoitechat_theme_sources,
include_directories: [config_h_include],
dependencies: zoitechat_theme_deps,
install: false,
)
iso_codes = dependency('iso-codes', required: false)
if iso_codes.found()
zoitechat_gtk_sources += 'sexy-iso-codes.c'
@@ -102,7 +118,7 @@ endif
resources = gnome.compile_resources('resources',
'../../data/zoitechat.gresource.xml',
source_dir: '../../data', # TODO: Fix upstream
source_dir: '../../data',
c_name: 'zoitechat',
extra_args: ['--manual-register']
)
@@ -114,9 +130,124 @@ endif
executable('zoitechat',
sources: resources + zoitechat_gtk_sources,
dependencies: zoitechat_gtk_deps,
link_with: zoitechat_theme_lib,
c_args: zoitechat_gtk_cflags,
link_args: zoitechat_gtk_ldflags,
pie: true,
install: true,
gui_app: true,
)
theme_manager_policy_tests = executable('theme_manager_policy_tests',
[
'theme/tests/test-theme-manager-policy.c',
'theme/theme-manager.c',
'theme/theme-palette.c',
'theme/tests/test-theme-gtk3-stub.c',
],
include_directories: [config_h_include],
dependencies: [gtk_dep],
)
test('Theme Manager/Policy Tests', theme_manager_policy_tests,
protocol: 'tap',
timeout: 120,
)
theme_manager_dispatch_tests = executable('theme_manager_dispatch_routing_tests',
[
'theme/tests/test-theme-manager-dispatch-routing.c',
'theme/theme-manager.c',
'theme/theme-palette.c',
'theme/tests/test-theme-gtk3-stub.c',
],
include_directories: [config_h_include],
dependencies: [gtk_dep],
)
test('Theme Manager Dispatch Routing Tests', theme_manager_dispatch_tests,
protocol: 'tap',
timeout: 120,
)
theme_manager_auto_refresh_tests = executable('theme_manager_auto_refresh_tests',
[
'theme/tests/test-theme-manager-auto-refresh.c',
'theme/theme-manager.c',
'theme/theme-palette.c',
'theme/tests/test-theme-gtk3-stub.c',
],
include_directories: [config_h_include],
dependencies: [gtk_dep],
)
test('Theme Manager Auto Refresh Tests', theme_manager_auto_refresh_tests,
protocol: 'tap',
timeout: 120,
)
theme_application_input_style_tests = executable('theme_application_input_style_tests',
[
'theme/tests/test-theme-application-input-style.c',
'theme/theme-application.c',
'theme/tests/test-theme-gtk3-stub.c',
],
include_directories: [config_h_include],
dependencies: [gtk_dep],
)
test('Theme Application Input Style Tests', theme_application_input_style_tests,
protocol: 'tap',
timeout: 120,
)
theme_runtime_tests = executable('theme_runtime_persistence_tests',
'theme/tests/test-theme-runtime-persistence.c',
include_directories: [config_h_include],
dependencies: [gtk_dep],
link_with: zoitechat_theme_lib,
)
test('Theme Runtime Persistence Tests', theme_runtime_tests,
protocol: 'tap',
timeout: 120,
)
theme_access_tests = executable('theme_access_routing_tests',
'theme/tests/test-theme-access-routing.c',
include_directories: [config_h_include],
dependencies: [gtk_dep],
link_with: zoitechat_theme_lib,
)
test('Theme Access Routing Tests', theme_access_tests,
protocol: 'tap',
timeout: 120,
)
theme_gtk3_settings_tests = executable('theme_gtk3_settings_tests',
[
'theme/tests/test-theme-gtk3-settings.c',
'theme/theme-gtk3.c',
],
include_directories: [config_h_include],
dependencies: [gtk_dep],
)
test('Theme GTK3 Settings Tests', theme_gtk3_settings_tests,
protocol: 'tap',
timeout: 120,
)
theme_preferences_gtk3_populate_tests = executable('theme_preferences_gtk3_populate_tests',
'theme/tests/test-theme-preferences-gtk3-populate.c',
include_directories: [config_h_include],
dependencies: [gtk_dep],
)
test('Theme Preferences GTK3 Populate Tests', theme_preferences_gtk3_populate_tests,
protocol: 'tap',
timeout: 120,
)

Some files were not shown because too many files have changed in this diff Show More