7 Commits

18 changed files with 238 additions and 181 deletions

View File

@@ -37,7 +37,11 @@ jobs:
libluajit-5.1-dev libpci-dev libperl-dev libssl-dev libayatana-appindicator3-dev \ libluajit-5.1-dev libpci-dev libperl-dev libssl-dev libayatana-appindicator3-dev \
perl python3 python3-minimal python3-dev python3-cffi mono-devel desktop-file-utils \ perl python3 python3-minimal python3-dev python3-cffi mono-devel desktop-file-utils \
fonts-noto-color-emoji breeze-gtk-theme \ fonts-noto-color-emoji breeze-gtk-theme \
patchelf file curl patchelf file curl imagemagick
if ! command -v magick >/dev/null 2>&1 && command -v convert >/dev/null 2>&1; then
printf '%s\n' '#!/bin/sh' 'exec convert "$@"' | sudo tee /usr/local/bin/magick >/dev/null
sudo chmod +x /usr/local/bin/magick
fi
- name: Configure - name: Configure
run: | run: |

View File

@@ -41,7 +41,12 @@ jobs:
perl \ perl \
python \ python \
python-cffi \ python-cffi \
pciutils pciutils \
imagemagick
if ! command -v magick >/dev/null 2>&1 && command -v convert >/dev/null 2>&1; then
printf '%s\n' '#!/bin/sh' 'exec convert "$@"' > /usr/local/bin/magick
chmod +x /usr/local/bin/magick
fi
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v5 uses: actions/checkout@v5

View File

@@ -39,6 +39,13 @@ jobs:
python -m pip install --upgrade pip python -m pip install --upgrade pip
python -m pip install cffi python -m pip install cffi
python -m pip install zstandard python -m pip install zstandard
choco install imagemagick -y --no-progress
if (-not (Get-Command magick -ErrorAction SilentlyContinue)) {
$magickDir = Get-ChildItem 'C:\Program Files\ImageMagick-*' -Directory -ErrorAction SilentlyContinue | Sort-Object LastWriteTime -Descending | Select-Object -First 1
if ($magickDir) {
$magickDir.FullName | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
}
}
$ProgressPreference = 'SilentlyContinue' $ProgressPreference = 'SilentlyContinue'
function Download-WithRetry { function Download-WithRetry {

View File

@@ -0,0 +1,120 @@
#!/usr/bin/env python3
import argparse
import contextlib
import pathlib
import shutil
import subprocess
import tempfile
SIZES = [16, 24, 32, 40, 48, 64, 96, 128, 256]
def run(cmd):
subprocess.run(cmd, check=True)
def try_run(cmd):
result = subprocess.run(cmd, text=True, capture_output=True)
return result.returncode == 0, result.stderr.strip()
def magick_cmd():
magick = shutil.which('magick')
if not magick:
raise RuntimeError('missing tool: install ImageMagick (magick)')
return magick
@contextlib.contextmanager
def magick_svg(svg):
text = pathlib.Path(svg).read_text(encoding='utf-8')
fixed = text.replace('href="image/', 'href="data:image/')
fixed = fixed.replace('xlink:href="image/', 'xlink:href="data:image/')
if fixed == text:
yield str(svg)
return
with tempfile.NamedTemporaryFile('w', suffix='.svg', delete=False, encoding='utf-8') as tmp:
tmp.write(fixed)
tmp_path = tmp.name
try:
yield tmp_path
finally:
pathlib.Path(tmp_path).unlink(missing_ok=True)
def render_png(svg, out_png, size):
errors = []
rsvg = shutil.which('rsvg-convert')
if rsvg:
ok, err = try_run([rsvg, '-w', str(size), '-h', str(size), '-o', str(out_png), str(svg)])
if ok:
return
errors.append(err)
inkscape = shutil.which('inkscape')
if inkscape:
ok, err = try_run([
inkscape,
str(svg),
'--export-type=png',
'--export-width',
str(size),
'--export-height',
str(size),
'--export-filename',
str(out_png),
])
if ok:
return
errors.append(err)
with magick_svg(svg) as svg_for_magick:
ok, err = try_run([
magick_cmd(),
svg_for_magick,
'-background',
'none',
'-resize',
f'{size}x{size}',
str(out_png),
])
if ok:
return
errors.append(err)
raise RuntimeError('failed to render png: ' + ' | '.join(e for e in errors if e))
def build_ico(svg, out_ico):
with magick_svg(svg) as svg_for_magick:
run([
magick_cmd(),
svg_for_magick,
'-background',
'none',
'-define',
'icon:auto-resize=' + ','.join(str(size) for size in SIZES),
str(out_ico),
])
def parse_args():
parser = argparse.ArgumentParser(prog='generate_icons.py')
parser.add_argument('input_svg')
parser.add_argument('output_png')
parser.add_argument('--ico', dest='output_ico')
parser.add_argument('--size', type=int, default=48)
return parser.parse_args()
def main():
args = parse_args()
svg = pathlib.Path(args.input_svg)
out_png = pathlib.Path(args.output_png)
out_png.parent.mkdir(parents=True, exist_ok=True)
render_png(svg, out_png, args.size)
if args.output_ico:
out_ico = pathlib.Path(args.output_ico)
out_ico.parent.mkdir(parents=True, exist_ok=True)
build_ico(svg, out_ico)
if __name__ == '__main__':
main()

View File

@@ -1,9 +1,24 @@
icon_gen = find_program('generate_icons.py')
find_program('magick', required: host_machine.system() == 'windows')
icondir = join_paths(get_option('datadir'), 'icons/hicolor') icondir = join_paths(get_option('datadir'), 'icons/hicolor')
install_data( custom_target('zoitechat_png',
'zoitechat.png', input: 'zoitechat.svg',
rename: 'net.zoite.Zoitechat.png', output: 'net.zoite.Zoitechat.png',
install_dir: join_paths(icondir, '48x48/apps') command: [icon_gen, '@INPUT@', '@OUTPUT@', '--size', '48'],
install: true,
install_dir: join_paths(icondir, '48x48/apps'),
) )
if host_machine.system() == 'windows'
custom_target('zoitechat_ico',
input: 'zoitechat.svg',
output: 'zoitechat.ico',
command: [icon_gen, '@INPUT@', '@PRIVATE_DIR@/zoitechat.png', '--size', '48', '--ico', '@OUTPUT@'],
build_by_default: true,
)
endif
install_data( install_data(
'zoitechat.svg', 'zoitechat.svg',
rename: 'net.zoite.Zoitechat.svg', rename: 'net.zoite.Zoitechat.svg',

View File

@@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
version="1.1"
width="0.213333in" height="0.213333in"
viewBox="0 0 64 64">
<defs>
</defs>
<image id="raster0"
x="0"
y="0"
width="64"
height="64"
opacity="1.000000"
href="data:image/png;base64,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" />
</svg>

Before

Width:  |  Height:  |  Size: 4.8 KiB

View File

@@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
version="1.1"
width="0.213333in" height="0.213333in"
viewBox="0 0 64 64">
<defs>
</defs>
<image id="raster0"
x="0"
y="0"
width="64"
height="64"
opacity="1.000000"
href="data:image/png;base64,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" />
</svg>

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/icons">
<file alias="zoitechat.png" preprocess="to-pixdata">@ZOITECHAT_PNG@</file>
<file alias="zoitechat.svg">icons/zoitechat.svg</file>
<file alias="book.png" preprocess="to-pixdata">icons/book.png</file>
<file alias="ulist_voice.png" preprocess="to-pixdata">icons/ulist_voice.png</file>
<file alias="ulist_halfop.png" preprocess="to-pixdata">icons/ulist_halfop.png</file>
<file alias="ulist_op.png" preprocess="to-pixdata">icons/ulist_op.png</file>
<file alias="ulist_owner.png" preprocess="to-pixdata">icons/ulist_owner.png</file>
<file alias="ulist_founder.png" preprocess="to-pixdata">icons/ulist_founder.png</file>
<file alias="ulist_netop.png" preprocess="to-pixdata">icons/ulist_netop.png</file>
<file alias="tray_normal.png" preprocess="to-pixdata">@ZOITECHAT_PNG@</file>
<file alias="tray_fileoffer.png" preprocess="to-pixdata">icons/tray_fileoffer.png</file>
<file alias="tray_highlight.png" preprocess="to-pixdata">icons/tray_highlight.png</file>
<file alias="tray_message.png" preprocess="to-pixdata">icons/tray_message.png</file>
<file alias="tree_channel.png" preprocess="to-pixdata">icons/tree_channel.png</file>
<file alias="tree_dialog.png" preprocess="to-pixdata">icons/tree_dialog.png</file>
<file alias="tree_server.png" preprocess="to-pixdata">icons/tree_server.png</file>
<file alias="tree_util.png" preprocess="to-pixdata">icons/tree_util.png</file>
</gresource>
</gresources>

View File

@@ -27,6 +27,8 @@ typedef struct
GtkWidget *b2; /* button2 */ GtkWidget *b2; /* button2 */
} tabview; } tabview;
#define ICON_CHANVIEW_CLOSE "gtk-close"
static void chanview_populate (chanview *cv); static void chanview_populate (chanview *cv);
/* ignore "toggled" signal? */ /* ignore "toggled" signal? */
@@ -332,6 +334,12 @@ tab_scroll_cb (GtkWidget *widget, GdkEventScroll *event, gpointer cv)
return FALSE; return FALSE;
} }
static void
cv_tabs_xclick_cb (GtkWidget *button, chanview *cv)
{
cv->cb_xbutton (cv, cv->focused, cv->focused->tag, cv->focused->userdata);
}
/* make a Scroll (arrow) button */ /* make a Scroll (arrow) button */
static GtkWidget * static GtkWidget *
@@ -376,6 +384,7 @@ cv_tabs_init (chanview *cv)
GtkWidget *box, *hbox = NULL; GtkWidget *box, *hbox = NULL;
GtkWidget *viewport; GtkWidget *viewport;
GtkWidget *outer; GtkWidget *outer;
GtkWidget *button;
if (cv->vertical) if (cv->vertical)
{ {
@@ -442,6 +451,11 @@ cv_tabs_init (chanview *cv)
gtk_box_pack_start (GTK_BOX (outer), ((tabview *)cv)->b1, 0, 0, 0); gtk_box_pack_start (GTK_BOX (outer), ((tabview *)cv)->b1, 0, 0, 0);
} }
button = gtkutil_button (outer, ICON_CHANVIEW_CLOSE, NULL, cv_tabs_xclick_cb,
cv, 0);
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
gtk_widget_set_can_focus (button, FALSE);
gtk_container_add (GTK_CONTAINER (cv->box), outer); gtk_container_add (GTK_CONTAINER (cv->box), outer);
} }
@@ -645,128 +659,20 @@ tab_toggled_cb (GtkToggleButton *tab, chan *ch)
static gboolean static gboolean
tab_click_cb (GtkWidget *wid, GdkEventButton *event, chan *ch) tab_click_cb (GtkWidget *wid, GdkEventButton *event, chan *ch)
{ {
GtkWidget *close_button;
gint close_x;
gint close_y;
GtkAllocation close_alloc;
if (event->button == 1 && event->type == GDK_BUTTON_PRESS)
{
close_button = g_object_get_data (G_OBJECT (wid), "tab-close-button");
if (close_button &&
gtk_widget_translate_coordinates (close_button, wid, 0, 0, &close_x, &close_y))
{
gtk_widget_get_allocation (close_button, &close_alloc);
if (event->x >= close_x && event->x < close_x + close_alloc.width &&
event->y >= close_y && event->y < close_y + close_alloc.height)
{
ch->cv->cb_xbutton (ch->cv, ch, ch->tag, ch->userdata);
return TRUE;
}
}
}
return ch->cv->cb_contextmenu (ch->cv, ch, ch->tag, ch->userdata, event); return ch->cv->cb_contextmenu (ch->cv, ch, ch->tag, ch->userdata, event);
} }
static gboolean
tab_close_motion_cb (GtkWidget *wid, GdkEventMotion *event, chan *ch)
{
GtkWidget *close_button;
gint close_x;
gint close_y;
GtkAllocation close_alloc;
gboolean hover = FALSE;
close_button = g_object_get_data (G_OBJECT (wid), "tab-close-button");
if (close_button &&
gtk_widget_translate_coordinates (close_button, wid, 0, 0, &close_x, &close_y))
{
gtk_widget_get_allocation (close_button, &close_alloc);
hover = event->x >= close_x && event->x < close_x + close_alloc.width &&
event->y >= close_y && event->y < close_y + close_alloc.height;
}
if (hover)
{
GdkCursor *cursor;
gtk_widget_set_state_flags (close_button, GTK_STATE_FLAG_PRELIGHT, TRUE);
if (gtk_widget_get_window (wid))
{
cursor = gdk_cursor_new_for_display (gtk_widget_get_display (wid), GDK_HAND2);
gdk_window_set_cursor (gtk_widget_get_window (wid), cursor);
g_object_unref (cursor);
}
}
else
{
gtk_widget_unset_state_flags (close_button, GTK_STATE_FLAG_PRELIGHT);
if (gtk_widget_get_window (wid))
gdk_window_set_cursor (gtk_widget_get_window (wid), NULL);
}
return FALSE;
}
static gboolean
tab_close_leave_cb (GtkWidget *wid, GdkEventCrossing *event, chan *ch)
{
GtkWidget *close_button;
close_button = g_object_get_data (G_OBJECT (wid), "tab-close-button");
if (close_button)
gtk_widget_unset_state_flags (close_button, GTK_STATE_FLAG_PRELIGHT);
if (gtk_widget_get_window (wid))
gdk_window_set_cursor (gtk_widget_get_window (wid), NULL);
return FALSE;
}
static GtkWidget *
tab_get_label (GtkWidget *tab)
{
GtkWidget *label;
label = g_object_get_data (G_OBJECT (tab), "tab-label");
if (label)
return label;
return gtk_bin_get_child (GTK_BIN (tab));
}
static void * static void *
cv_tabs_add (chanview *cv, chan *ch, char *name, GtkTreeIter *parent) cv_tabs_add (chanview *cv, chan *ch, char *name, GtkTreeIter *parent)
{ {
GtkWidget *but; GtkWidget *but;
GtkWidget *hbox;
GtkWidget *label;
GtkWidget *close_button;
GtkWidget *close_icon;
but = gtk_toggle_button_new (); but = gtk_toggle_button_new_with_label (name);
gtk_widget_set_name (but, "zoitechat-tab"); gtk_widget_set_name (but, "zoitechat-tab");
gtk_widget_add_events (but, GDK_POINTER_MOTION_MASK | GDK_LEAVE_NOTIFY_MASK);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
label = gtk_label_new (name);
close_button = gtk_button_new ();
gtk_style_context_add_class (gtk_widget_get_style_context (close_button), "flat");
close_icon = gtk_image_new_from_icon_name ("window-close-symbolic", GTK_ICON_SIZE_MENU);
gtk_image_set_pixel_size (GTK_IMAGE (close_icon), 8);
gtk_button_set_always_show_image (GTK_BUTTON (close_button), TRUE);
gtk_widget_set_can_focus (close_button, FALSE);
gtk_container_add (GTK_CONTAINER (close_button), close_icon);
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox), close_button, FALSE, FALSE, 0);
gtk_container_add (GTK_CONTAINER (but), hbox);
g_object_set_data (G_OBJECT (but), "tab-label", label);
g_object_set_data (G_OBJECT (but), "tab-close-button", close_button);
g_object_set_data (G_OBJECT (but), "c", ch); g_object_set_data (G_OBJECT (but), "c", ch);
/* used to trap right-clicks */ /* used to trap right-clicks */
g_signal_connect (G_OBJECT (but), "button-press-event", g_signal_connect (G_OBJECT (but), "button-press-event",
G_CALLBACK (tab_click_cb), ch); G_CALLBACK (tab_click_cb), ch);
g_signal_connect (G_OBJECT (but), "motion-notify-event",
G_CALLBACK (tab_close_motion_cb), ch);
g_signal_connect (G_OBJECT (but), "leave-notify-event",
G_CALLBACK (tab_close_leave_cb), ch);
/* avoid prelights */ /* avoid prelights */
g_signal_connect (G_OBJECT (but), "enter-notify-event", g_signal_connect (G_OBJECT (but), "enter-notify-event",
G_CALLBACK (tab_ignore_cb), NULL); G_CALLBACK (tab_ignore_cb), NULL);
@@ -778,7 +684,6 @@ cv_tabs_add (chanview *cv, chan *ch, char *name, GtkTreeIter *parent)
g_signal_connect (G_OBJECT (but), "toggled", g_signal_connect (G_OBJECT (but), "toggled",
G_CALLBACK (tab_toggled_cb), ch); G_CALLBACK (tab_toggled_cb), ch);
g_object_set_data (G_OBJECT (but), "u", ch->userdata); g_object_set_data (G_OBJECT (but), "u", ch->userdata);
gtk_widget_show_all (hbox);
tab_add_real (cv, but, ch); tab_add_real (cv, but, ch);
@@ -987,7 +892,7 @@ cv_tabs_cleanup (chanview *cv)
static void static void
cv_tabs_set_color (chan *ch, PangoAttrList *list) cv_tabs_set_color (chan *ch, PangoAttrList *list)
{ {
gtk_label_set_attributes (GTK_LABEL (tab_get_label (ch->impl)), list); gtk_label_set_attributes (GTK_LABEL (gtk_bin_get_child (GTK_BIN (ch->impl))), list);
} }
static void static void
@@ -996,16 +901,16 @@ cv_tabs_rename (chan *ch, char *name)
PangoAttrList *attr; PangoAttrList *attr;
GtkWidget *tab = ch->impl; GtkWidget *tab = ch->impl;
attr = gtk_label_get_attributes (GTK_LABEL (tab_get_label (tab))); attr = gtk_label_get_attributes (GTK_LABEL (gtk_bin_get_child (GTK_BIN (tab))));
if (attr) if (attr)
pango_attr_list_ref (attr); pango_attr_list_ref (attr);
gtk_label_set_text (GTK_LABEL (tab_get_label (tab)), name); gtk_button_set_label (GTK_BUTTON (tab), name);
gtk_widget_queue_resize (gtk_widget_get_parent(gtk_widget_get_parent(gtk_widget_get_parent(tab)))); gtk_widget_queue_resize (gtk_widget_get_parent(gtk_widget_get_parent(gtk_widget_get_parent(tab))));
if (attr) if (attr)
{ {
gtk_label_set_attributes (GTK_LABEL (tab_get_label (tab)), attr); gtk_label_set_attributes (GTK_LABEL (gtk_bin_get_child (GTK_BIN (tab))), attr);
pango_attr_list_unref (attr); pango_attr_list_unref (attr);
} }
} }

View File

@@ -42,6 +42,7 @@ SET SOLUTIONDIR=$(SolutionDir)..\
powershell -File "$(SolutionDir)..\win32\version-template.ps1" "$(SolutionDir)..\src\fe-gtk\zoitechat.rc.tt" "$(ZoiteChatLib)zoitechat.rc.utf8" powershell -File "$(SolutionDir)..\win32\version-template.ps1" "$(SolutionDir)..\src\fe-gtk\zoitechat.rc.tt" "$(ZoiteChatLib)zoitechat.rc.utf8"
REM zoitechat.rc needs to be in UCS-2 or Resource Compiler will complain REM zoitechat.rc needs to be in UCS-2 or Resource Compiler will complain
powershell "Get-Content -Encoding UTF8 '$(ZoiteChatLib)zoitechat.rc.utf8' | Out-File '$(ZoiteChatLib)zoitechat.rc'; Remove-Item '$(ZoiteChatLib)zoitechat.rc.utf8'" powershell "Get-Content -Encoding UTF8 '$(ZoiteChatLib)zoitechat.rc.utf8' | Out-File '$(ZoiteChatLib)zoitechat.rc'; Remove-Item '$(ZoiteChatLib)zoitechat.rc.utf8'"
"$(Python3Path)\python.exe" "$(SolutionDir)..\data\icons\generate_icons.py" "$(DataDir)icons\zoitechat.svg" "$(DataDir)icons\zoitechat.png" --size 256 --ico "$(DataDir)icons\zoitechat.ico"
"$(DepsRoot)\bin\glib-compile-resources.exe" --generate-header --manual-register --sourcedir "$(DataDir)" --target "$(ZoiteChatLib)resources.h" "$(DataDir)zoitechat.gresource.xml" "$(DepsRoot)\bin\glib-compile-resources.exe" --generate-header --manual-register --sourcedir "$(DataDir)" --target "$(ZoiteChatLib)resources.h" "$(DataDir)zoitechat.gresource.xml"
"$(DepsRoot)\bin\glib-compile-resources.exe" --generate-source --manual-register --sourcedir "$(DataDir)" --target "$(ZoiteChatLib)resources.c" "$(DataDir)zoitechat.gresource.xml" "$(DepsRoot)\bin\glib-compile-resources.exe" --generate-source --manual-register --sourcedir "$(DataDir)" --target "$(ZoiteChatLib)resources.c" "$(DataDir)zoitechat.gresource.xml"
]]></Command> ]]></Command>

View File

@@ -1915,7 +1915,17 @@ menu_about (GtkWidget *wid, gpointer sess)
gtk_about_dialog_set_website_label (dialog, NULL); gtk_about_dialog_set_website_label (dialog, NULL);
gtk_about_dialog_set_license (dialog, NULL); gtk_about_dialog_set_license (dialog, NULL);
gtk_about_dialog_set_wrap_license (dialog, FALSE); gtk_about_dialog_set_wrap_license (dialog, FALSE);
gtk_about_dialog_set_logo (dialog, pix_zoitechat); GdkPixbuf *about_logo;
about_logo = gdk_pixbuf_new_from_resource_at_scale ("/icons/zoitechat.svg", 48, 48, TRUE, NULL);
if (!about_logo && pix_zoitechat)
about_logo = gdk_pixbuf_scale_simple (pix_zoitechat, 48, 48, GDK_INTERP_BILINEAR);
if (about_logo || pix_zoitechat)
gtk_about_dialog_set_logo (dialog, about_logo ? about_logo : pix_zoitechat);
else
gtk_about_dialog_set_logo_icon_name (dialog, "zoitechat");
if (about_logo)
g_object_unref (about_logo);
gtk_about_dialog_set_copyright (dialog, "\302\251 1998-2010 Peter \305\275elezn\303\275\n\302\251 2009-2014 Berke Viktor\n\302\251 2015-2025 Patrick Griffis\n\302\251 2026 deepend"); gtk_about_dialog_set_copyright (dialog, "\302\251 1998-2010 Peter \305\275elezn\303\275\n\302\251 2009-2014 Berke Viktor\n\302\251 2015-2025 Patrick Griffis\n\302\251 2026 deepend");
gtk_about_dialog_set_comments (dialog, comment); gtk_about_dialog_set_comments (dialog, comment);
actions = gtk_dialog_get_action_area (GTK_DIALOG (dialog)); actions = gtk_dialog_get_action_area (GTK_DIALOG (dialog));

View File

@@ -117,9 +117,27 @@ if get_option('plugin')
zoitechat_gtk_sources += 'plugingui.c' zoitechat_gtk_sources += 'plugingui.c'
endif endif
zoitechat_png_generated = custom_target('zoitechat_resource_png',
input: '../../data/icons/zoitechat.svg',
output: 'zoitechat.png',
command: [find_program('../../data/icons/generate_icons.py'), '@INPUT@', '@OUTPUT@', '--size', '256'],
)
zoitechat_gresource_conf = configuration_data()
zoitechat_gresource_conf.set('ZOITECHAT_PNG', 'zoitechat.png')
zoitechat_gresource_xml = configure_file(
input: '../../data/zoitechat.gresource.xml.in',
output: 'zoitechat.gresource.xml',
configuration: zoitechat_gresource_conf,
)
resources = gnome.compile_resources('resources', resources = gnome.compile_resources('resources',
'../../data/zoitechat.gresource.xml', zoitechat_gresource_xml,
source_dir: '../../data', source_dir: [
meson.current_build_dir(),
'../../data',
],
dependencies: [zoitechat_png_generated],
c_name: 'zoitechat', c_name: 'zoitechat',
extra_args: ['--manual-register'] extra_args: ['--manual-register']
) )

View File

@@ -415,24 +415,6 @@ theme_manager_is_kde_wayland (void)
return is_kde; return is_kde;
} }
static gint
theme_manager_get_system_headerbar_height (void)
{
GtkWidget *probe;
gint minimum;
gint natural;
probe = gtk_header_bar_new ();
gtk_header_bar_set_show_close_button (GTK_HEADER_BAR (probe), TRUE);
gtk_header_bar_set_decoration_layout (GTK_HEADER_BAR (probe), "menu:minimize,maximize,close");
gtk_widget_show (probe);
gtk_widget_get_preferred_height (probe, &minimum, &natural);
gtk_widget_destroy (probe);
if (natural > 0)
return natural;
return minimum;
}
static void static void
theme_manager_apply_wayland_kde_csd (GtkWidget *window) theme_manager_apply_wayland_kde_csd (GtkWidget *window)
{ {
@@ -460,16 +442,10 @@ theme_manager_apply_wayland_kde_csd (GtkWidget *window)
headerbar = gtk_header_bar_new (); headerbar = gtk_header_bar_new ();
gtk_header_bar_set_show_close_button (GTK_HEADER_BAR (headerbar), TRUE); gtk_header_bar_set_show_close_button (GTK_HEADER_BAR (headerbar), TRUE);
gtk_header_bar_set_decoration_layout (GTK_HEADER_BAR (headerbar), "menu:minimize,maximize,close"); gtk_header_bar_set_decoration_layout (GTK_HEADER_BAR (headerbar), "menu:minimize,maximize,close");
g_object_set (G_OBJECT (headerbar), "spacing", 0, NULL); icon_pixbuf = gdk_pixbuf_new_from_resource_at_scale ("/icons/zoitechat.svg", 32, 32, TRUE, NULL);
gtk_widget_set_size_request (headerbar, -1, theme_manager_get_system_headerbar_height ());
icon_pixbuf = gdk_pixbuf_new_from_resource_at_scale ("/icons/zoitechat.svg", 24, 24, TRUE, NULL);
if (!icon_pixbuf) if (!icon_pixbuf)
icon_pixbuf = gdk_pixbuf_new_from_resource_at_scale ("/icons/zoitechat.png", 24, 24, TRUE, NULL); icon_pixbuf = gdk_pixbuf_new_from_resource_at_scale ("/icons/zoitechat.png", 32, 32, TRUE, NULL);
icon_image = icon_pixbuf ? gtk_image_new_from_pixbuf (icon_pixbuf) : gtk_image_new_from_resource ("/icons/zoitechat.png"); icon_image = icon_pixbuf ? gtk_image_new_from_pixbuf (icon_pixbuf) : gtk_image_new_from_resource ("/icons/zoitechat.png");
gtk_widget_set_margin_start (icon_image, 0);
gtk_widget_set_margin_end (icon_image, 0);
gtk_widget_set_margin_top (icon_image, 0);
gtk_widget_set_margin_bottom (icon_image, 0);
if (icon_pixbuf) if (icon_pixbuf)
g_object_unref (icon_pixbuf); g_object_unref (icon_pixbuf);
gtk_header_bar_pack_start (GTK_HEADER_BAR (headerbar), icon_image); gtk_header_bar_pack_start (GTK_HEADER_BAR (headerbar), icon_image);

View File

@@ -40,6 +40,7 @@
SET SOLUTIONDIR=$(SolutionDir)..\ SET SOLUTIONDIR=$(SolutionDir)..\
if not exist "$(ZoiteChatBin)" mkdir "$(ZoiteChatBin)" if not exist "$(ZoiteChatBin)" mkdir "$(ZoiteChatBin)"
powershell -File "$(SolutionDir)..\win32\version-template.ps1" "$(SolutionDir)..\win32\installer\zoitechat.iss.tt" "$(ZoiteChatBin)zoitechat.iss" powershell -File "$(SolutionDir)..\win32\version-template.ps1" "$(SolutionDir)..\win32\installer\zoitechat.iss.tt" "$(ZoiteChatBin)zoitechat.iss"
"$(Python3Path)\python.exe" "$(SolutionDir)..\data\icons\generate_icons.py" "$(DataDir)icons\zoitechat.svg" "$(DataDir)icons\zoitechat.png" --size 256 --ico "$(DataDir)icons\zoitechat.ico"
$(IsccPath) /dPROJECTDIR="$(ProjectDir)" /dAPPARCH="$(Platform)" "$(ZoiteChatBin)zoitechat.iss" $(IsccPath) /dPROJECTDIR="$(ProjectDir)" /dAPPARCH="$(Platform)" "$(ZoiteChatBin)zoitechat.iss"
]]> ]]>
</Command> </Command>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 201 KiB

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB