telegramdesktop / tdesktop

Telegram Desktop messaging app
https://desktop.telegram.org/
Other
26.19k stars 5.19k forks source link

Tray icon looks blurred/pixelated on KDE #2230

Closed z3ntu closed 4 years ago

z3ntu commented 8 years ago

As you can see in the screenshot, the Telegram Desktop icon looks very blurred in the system tray. I am using KDE 5.6.5 and the newest version of Telegram Desktop. tdesktop

It would also be good, if the Telegram Desktop tray icon would be monochrome for KDE but this is not important at all.

xuzhao9 commented 8 years ago

Hello, I am the packager of tdesktop on openSUSE and on my system this problem does not happen. Here is my spec file. Maybe it is useful to install Telegram icon into hicolor icon folder?

z3ntu commented 8 years ago

I am using Arch Linux, not openSUSE (if you meant that). I downloaded the Binary off the official website and ran it.

xuzhao9 commented 8 years ago

For Arch Users, AUR has a package that integrates into the system better. See: https://aur.archlinux.org/packages/telegram-desktop/

z3ntu commented 8 years ago

I have now installed the AUR package (compiled myself) and it looks even worse. spectacle t16379 EDIT: In /usr/share/icons/hicolor/512x512/apps/telegram-desktop.png there is a wonderful 512x512 icon. No idea why this isn't used.

xuzhao9 commented 8 years ago

Here is my screenshot: image

EDIT: When I make the system tray higher seems the icon also got blurred. Meanwhile, the taskbar icon looks just fine. Screenshot: screenshot_20160707_095302

Taskbar screenshot: image

So I think they should fix it by using higher resolution icon in system tray.

z3ntu commented 8 years ago

The taskbar is like that for me (and when I make the taskbar bigger it is still in good resolution): spectacle tj8842

gustawho commented 8 years ago

The thing is, Telegram use PNG files for its images, while most of the tray icons are SVG (or compressed SVG's, *.svgz, in the case of Plasma, I think).

alleehol commented 8 years ago

I see the same problem when I resize the panel higher than the default:

Kubuntu 16.04 default (Plasma 5.5.5, KF5 5.18) Desktop, Intel Gfx, 27" 2560x1440 (std res) Kubuntu 16.04 +ppa (Plasma 5.6.5, KF5 5.23) Laptop, Intel Gfx, 15" 1366x 768 (low res)

On the other hand I use the 'Icon-only' Taskmanger and there even a biiig Telegram Icon is crisp and sharp! The taskmanager use the icon from the desktop file and it's a 256x256 png.

$ grep Icon= ~/Telegram/Telegram.desktop Icon=~/.TelegramDesktop/tdata/icon.png $ file ~/.TelegramDesktop/tdata/icon.png /home/allee/.TelegramDesktop/tdata/icon.png: PNG image data, 256 x 256, 8-bit/color RGBA, non-interlaced

As I use plasmas default breeze theme, I've also /usr/share/icons/breeze/apps/48/telegram.svg on my system.

When I start Telegram in a konsole I get: $ Telegram/Telegram Fontconfig error: "/etc/fonts/conf.d/10-scale-bitmap-fonts.conf", line 72: non-double matrix element Fontconfig error: "/etc/fonts/conf.d/10-scale-bitmap-fonts.conf", line 72: non-double matrix element Fontconfig warning: "/etc/fonts/conf.d/10-scale-bitmap-fonts.conf", line 80: saw unknown, expected number Fontconfig error: "/etc/fonts/conf.d/10-scale-bitmap-fonts.conf", line 72: non-double matrix element Fontconfig error: "/etc/fonts/conf.d/10-scale-bitmap-fonts.conf", line 72: non-double matrix element Fontconfig warning: "/etc/fonts/conf.d/10-scale-bitmap-fonts.conf", line 80: saw unknown, expected number

maybe that's telegram 'fault', maybe it's a KDE systray panel bug for resize events? Has anymore Plasma 5.7 running? There the systray is rewritten.

z3ntu commented 8 years ago

@alleehol Yes, I have KDE 5.7.1 installed and it looks like on the attached screenshot

image

alleehol commented 8 years ago

@z3ntu look good! What happens when you make the panel higher (smaller). Telegram systray icon sharp and crisp for all vertical sizes?

z3ntu commented 8 years ago

The tray icon stays blurry as it is, but the taskbar icon looks very good (probably high-res png or svg).

Tynach commented 8 years ago

This didn't used to be the case. It used to be crisp; I remember the text indicating how many messages I missed also being crisp. But it's not crisp anymore :/

Tried disabling XEmbedSNIProxy, and there was no change.

z3ntu commented 8 years ago

I just found the line

Jul 29 12:18:25 hp-praktikum-luca xembedsniproxy[671]: kde.xembedsniproxy: Scaling pixmap of window 52428807 "telegram-desktop" from w*h 22 22

in my log. That's the problem probably.

alleehol commented 8 years ago

hmm, AFAIU xembed deprecated https://blog.martin-graesslin.com/blog/tag/systray/ There was a time KDE's plasma did not support it. If telegram supports both methods xembed and status notifier item, status notifier should be tried first, that should solve the problem (and would work with wayland too).

Achim

Tynach commented 8 years ago

@alleehol, @z3ntu, the problem persists when I disable Xembed. I also do not have lines like that in my Telegram log, so this is not the root of the problem.

I actually suspect that those of you having a blurry icon are perhaps using Xembed, while those of us who have a horribly pixelated icon are using libnotify.

But I don't know. All I know is that I'm not using Xembed, and the problem persists.

Tynach commented 8 years ago

It seems that Telegram/SourceFiles/platform/linux/main_window_linux.cpp is responsible for handling the system tray icon. It appears to create new icons for each time it's changed, which makes sense for supporting the message count feature.

In this file you can see that they support 3 different styles of system tray icons:

  1. QSystemTrayIcon
  2. AppIndicator
  3. GtkStatusIcon

Of those three, the only one that actually changes the value of the variable _trayIconSize is GtkStatusIcon. Neither AppIndicator nor QSystemTrayIcon change that variable, yet all of them use it for generating the icon size.

The starting value for that variable is 22, and indeed if I go to my ~/.TelegramDesktop/tdata/ticons/ folder I can see that the icons it generated are 22x22 pixels large.

Paging the author of this code, @john-preston. Perhaps he can give some insights and ideas.

john-preston commented 8 years ago

@Tynach Which size should it be? I was taking a size to look fine on the systems where I've tested the build.

Tynach commented 8 years ago

@john-preston, in KDE the panels can be dynamically resized at runtime, so ideally the code would use whatever size is requested. I don't know exactly what that size might be (and it will change depending on the user's preferences), but with the default panel (40px tall with fonts set to 96 DPI) the icons appear to be 32x32 pixels.

You do have a resize handler for GtkStatusIcon. Is it possible for you to write such a handler for AppIndicator or QSystemTrayIcon? Failing that, at least a function or method that detects what the requested icon size is?

It also seems that QSystemTrayIcon will use AppIndicator or XEmbed on Linux, choosing whichever one is available/works best. So perhaps you could just use that and not have separate code for AppIndicator (especially since Telegram has Qt and whatnot compiled statically).

It also apparently supports Windows and OS X, so you could potentially remove this from platform specific implementation and simply have it as the default code for all platforms. However, I don't know how well integrated it looks on other OSes.

I do see in the documentation that 22px is considered the standard size for Linux (X11) desktops. I suppose in this way that KDE is the oddball; though I swear this worked fine in a previous build. Weird.

At any rate, apparently QIcon has a lot of documentation too, including a way to choose which 'Icon Engine' you use; which might be a simpler way of choosing between XEmbed and AppIndicator.

I also see the QIcon::actualSize() method that tells you the dimensions of a pixmap given a certain size, which it claims will never be larger than the requested size but can be smaller. Perhaps you could put in a ridiculous size like '512', and then use the 'actual size' it returns as the size of the icon you generate with _trayIconImageGen().

I'd look around for more details (so far I've only dabbled with making little useless 'toy' programs using Qt, and kinda want to try implementing my own system tray icon in a program just to see how it all works), but I'm currently packing for a trip.

If I'd already dabbled in this corner of Qt, and wasn't about to leave for a week and a half, I'd offer to try writing the code myself and submit a pull request.

john-preston commented 8 years ago

@Tynach I have a resize handler for gtk status icon because it offers such a signal. I don't see anything like that for appindicator: http://people.canonical.com/~dpm/api/devel/GIR/C/AppIndicator-0.1.html

Tynach commented 8 years ago

@john-preston, it seems that QIcon has a method where you can add multiple of the same icon, but each a different size, and the system will use whichever one fits the best. This might be a better approach.

I talk about that and a few other things lower down in my post up there.

z3ntu commented 8 years ago

I also found

Jul 31 12:12:21 g550jk kdeinit5[1308]: Registering "org.kde.StatusNotifierItem-14215-1/StatusNotifierItem" to system tray Jul 31 12:12:21 g550jk plasmashell[1352]: Registering "org.kde.StatusNotifierItem-14215-1/StatusNotifierItem"

in my logs. This is in the normal systemd journal (journalctl)

davidedmundson commented 8 years ago

Plasma dev here.

hmm, AFAIU xembed deprecated https://blog.martin-graesslin.com/blog/tag/systray/ There was a time KDE's plasma did not support it.

That's not quite true, it is supported now, however you won't be using it as you have AppIndicator support.

It also seems that QSystemTrayIcon will use AppIndicator or XEmbed

That's correct from Qt5.7, and probably worth doing, but it won't help fix anything, as you can see below.

AppIndicator

There's no way to get the size the host is displaying at. It's not part of the spec, so whatever abstraction layer you use it simply won't work. (for one thing there may be N hosts). Even if you have a QIcon with multiple sizes, it can still only send one image as an IconPixmap field.

Rather than passing the icon as a pixmap over DBus, it's more typical to use the IconName + IconPath. It's faster, simpler, and it avoids the resolution problems as it's the client loading the icon. The iconPath supports the full XDG icon directory convention with the different folders per sizes, or SVG.

However, from what I can see you're deliberately doing it as a pixmap as you're manipulating the icon to display a badge with a number on it?

At which point your only option available is to just send a huge icon to begin with and let the indicator host scale it down.

Long term you might want to start a discussion about exanding the specification so that host side overlays are a thing. I think Unity has a specification for that(?) Or we expand the SNI spec to support arrays in IconPixmaps

john-preston commented 8 years ago

@davidedmundson Yes, I change the icon placing different badges. I thought about sending a large enough pixmap, though it will generate slowly (like 512x512), then scale back to small and will have worse quality (which is critical for small icons with very small counter of new messages — they're best displayed when prepared using the needed size from the beginning). Of course it doesn't work well, if they're then upscaled. Perhaps sending a large enough pixmap should be considered at some of the future versions.

alleehol commented 8 years ago

If supported: Maybe SVG is then the simpler solution? Substituting the Number in the SVG should be quick, and the scaling is done only once for earch systray instance (FWI I tried a inch high panel and at least the KDE systray impl. has a max size for the icons of ~ 25 px.)
screenshot-high-plasma-panel

If possible, this should also solve 2 or more Panel with systrays (1st small, 2nd much taller) because the SVG 'supports' several sizes.

davidedmundson commented 8 years ago

@alleehol Telegram doesn't control how Plasma renders it. and Plasma doesn't know it's meant to substitute things.

They're running in different processes, and the only communication between them expects a single pixmap or a text based icon name.

sl1pkn07 commented 8 years ago

why no use StatusNotifierItem instead of accient Xembed?

http://www.notmart.org/misc/statusnotifieritem/

AndydeCleyre commented 8 years ago

While I lose the mute signifier and the message count, and the icon is colored instead of mono as is more fitting for a plasma icon, I can get a non-pixelated icon up there as follows:

cd ~/.TelegramDesktop/tdata/ticons
rm -r *
cp /usr/share/pixmaps/telegram.png ./ico_22.png
cp ico_22.png icomute_22_0.png
cp icomute_22_0.png icomute_22_1.png
for f in {1..2000}; do ln -s ico_22.png ico_22_$f.png; done
for f in {2..2000}; do ln -s icomute_22_1.png icomute_22_$f.png; done

That's a 256x256 image.

EDIT: Maybe I'll do some simple color-changing operations on the images. For example, use a grayscale version for muted with zero messages, an orangered version for non-muted with one or more messages, and a darker value applied for muted with one or more messages.

AndydeCleyre commented 8 years ago

Alright, I'm finding this script works well for me. Just missing the message count.

#!/bin/bash
set -e

cd ~/.TelegramDesktop/tdata/ticons
rm -r *
cp /usr/share/pixmaps/telegram.png ./ico_22.png

# white center -> transparent center (base):
# convert ico_22.png -fuzz 40% -transparent white ico_22.png
# or not.

# blue -> orangered (unmuted, messages):
convert ico_22.png -modulate 100,120,0 ico_22_1.png

# blue -> dark blue (muted, no messages):
# convert ico_22.png -modulate 50,100,100 icomute_22_0.png
# or not:
cp ico_22.png icomute_22_0.png

# orangered -> dark orangered (muted, messages):
convert ico_22_1.png -modulate 50,100,100 icomute_22_1.png

for f in {2..2000}; do ln -s ico_22_1.png ico_22_$f.png; done
for f in {2..2000}; do ln -s icomute_22_1.png icomute_22_$f.png; done

EDIT: grey/blue style

AndydeCleyre commented 8 years ago

I just found that the source icon used for the above script is not included in the Ubuntu Telegram package available from http://ppa.launchpad.net/atareao/telegram/ubuntu . The source icon is available at https://raw.githubusercontent.com/telegramdesktop/tdesktop/master/Telegram/Resources/art/icon256.png .

sl1pkn07 commented 8 years ago

better

https://upload.wikimedia.org/wikipedia/commons/d/dd/Telegram_alternative_logo.svg

sl1pkn07 commented 8 years ago

why this issue is closed? still get a pixelated systray icon

EDIT: oh. nvermind

hesediel84 commented 8 years ago

what about other icons with the number of messages? i changed the ico22 and solved the problem of the main icon. But the icon with the number of messages in red still pixelated

sl1pkn07 commented 8 years ago

i think is possible change this Behavior from this code

https://github.com/telegramdesktop/tdesktop/blob/0d7af044e91452f7bd0db39c6eb9316e16d6071e/Telegram/SourceFiles/platform/linux/main_window_linux.cpp#L87

Getron commented 8 years ago

Even here, on 0.10.10 on Linux Manjaro 16.08 KDE 5.7 Rolling Arch Release, the icon is not fixed, and looks blury, ugly.

Please, fix this, maybe a bigger, or more detailed, more pixel icon, hi-resolution, and not integrated in the bin icon would be fix the problem on linux KDE. All other messengers have fixed the icons, just Telegram seems to be blured, pixelated.

mrzzzrm commented 8 years ago

Similar problem here, additionally the icon background has the wrong color

screenshot_20161009_203156

This is Kubuntu 16.04 on a 1440p screen (in case the latter matters)

z3ntu commented 8 years ago

@mrzzzrm For me it's pixelated the same way but it doesn't have that weird background color...

DaavisGit commented 7 years ago

@mrzzzrm Icon problems like yours solved when i installed nvidia driver 367.57 on kubuntu

z3ntu commented 7 years ago

I still noticed the issue with 375.10 so this can't be the problem/fix.

sl1pkn07 commented 7 years ago

nvidia (or video) drivers make nothing in this issue

DaavisGit commented 7 years ago

@sl1pkn07 well.. my tray icon fixed after the driver install. Maybe there is no direct connection to it, but there must be some kind of connection

sl1pkn07 commented 7 years ago

nope. if the image of the systray is small, if upscale, the image gets pixelated

set bigger image to the systray solve the issue

video drivers only apply filters to the image (antialiasing) displayed

DaavisGit commented 7 years ago

@sl1pkn07 all I did was install display drivers.. How would you explain icon fixing on itself?

sl1pkn07 commented 7 years ago

see my last statement

fliker09 commented 7 years ago

Same here, Kubuntu 16.04.1, badly pixelated :\ I don't want to lose notification badge. Is there a solution?

z3ntu commented 7 years ago

Did anyone else notice an improvement in 1.0.13? Also the right-click on the tray icon is much better than before... EDIT: Still not better when I set the iconSize default in /usr/share/plasma/plasmoids/org.kde.plasma.private.systemtray/contents/config/main.xml to 2.

AndydeCleyre commented 7 years ago

This is how I'm getting around it these days:

panel_icons="/usr/share/icons/Papirus-Dark/24x24/panel"
icon_size="512"
main_color="#c2b790"
accent_color="#a94d37"
main_color_old="#d3dae3"
accent_color_old="#5294e2"

# hardcode-tray -a -cc "${main_color_old} ${main_color}" -cc "${accent_color_old} ${accent_color}" --theme Papirus-Dark
# ^ This currently still makes the icons too small. So instead:

tg_tmp="/tmp/tg_svgs"
mkdir -p ${tg_tmp} ${tg_icons}
for i in '_22':'' '_22_1':'attention-' 'mute_22_0':'' 'mute_22_1':'mute-'; do
    ico=${i%:*}; name=${i#*:}
    sed "s/${main_color_old}/${main_color}/gi" ${panel_icons}/telegram-${name}panel.svg > ${tg_tmp}/telegram-${name}panel.svg
    sed -i "s/${accent_color_old}/${accent_color}/gi" ${tg_tmp}/telegram-${name}panel.svg
    inkscape -z -e ${tg_icons}/ico${ico}.png -w ${icon_size} -h ${icon_size} ${tg_tmp}/telegram-${name}panel.svg &>/dev/null
done
for f in {2..2000}; do
    ln -sf ${tg_icons}/ico_22_1.png ${tg_icons}/ico_22_${f}.png
    ln -sf ${tg_icons}/icomute_22_1.png ${tg_icons}/icomute_22_${f}.png
done
sl1pkn07 commented 7 years ago
#!/usr/bin/bash

## Variables ##
source="/usr/share/icons/breeze-dark/apps/48/telegram.svg" # icon source
font=Ubuntu-bold # see 'identify -list font' for obtain the name of the font
messages=9999 # number of the messages printed in the dot 
size=256 # size of the final image
dot_size=70 # meassure in % (smallest than the size)
font_size=89 # meassure in % (smallest than the dot size)
###############

# Some Math
max="$(echo "scale=1; $size*($dot_size/100)" | bc)"
mid="$(echo "scale=1; $max/2" | bc)"
psize="$(echo "scale=1; $mid*($font_size/100)" | bc)"

# dot image in SVG format
dot="<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${max}\" height=\"${max}\"><path d=\"M${max} ${mid}a${mid} ${mid} 0 1 1-${max} 0 ${mid} ${mid} 0 1 1 ${max} 0z\" style=\"fill:##\"/></svg>"

# Detect the display density
dpi="$(xrdb -q | awk 'match($0, /Xft.dpi:\t([^ ]*)/, a) {print a[1];}')"

# Create the base image ico_22_0.png and icomute_22_0.png
convert -density $((dpi*2)) -background transparent -resize ${size} -trim "${source}" ico_22_0.png
cp ico_22_0.png icomute_22_0.png

# Create the message counter images
for i in $(seq 1 $messages); do
  counter="\"##\""
  # Draw the number of the message number into the dot and compose the final image
  echo "${dot//##/#FF0000}" | convert -background transparent -gravity Center -font ${font} -pointsize ${psize}% -fill white -draw "text 0,0 ${counter//##/$i}" svg:- png:- | composite -density ${dpi} -gravity SouthEast png:- ico_22_0.png ico_22_${i}.png
  echo "${dot//##/#555555}" | convert -background transparent -gravity Center -font ${font} -pointsize ${psize}% -fill white -draw "text 0,0 ${counter//##/$i}" svg:- png:- | composite -density ${dpi} -gravity SouthEast png:- ico_22_0.png icomute_22_${i}.png
done

# Done

test.svg: https://cgit.kde.org/breeze-icons.git/tree/icons-dark/apps/48/telegram.svg result:

10 messages: normal ico_22_10 mute: icomute_22_10 999 messages: normal: ico_22_999 mute: icomute_22_999 1000 messages: normal: ico_22_1000 mute: icomute_22_1000 9999 messages: normal: ico_22_9999 mute: icomute_22_9999

more or less, like the original

anyone can test it?

i think 256x256 is a good resolution for the trayicon

what is the max number of messages count?

greetings

EDIT: script inprovement EDIT2: tested with 64x64px. same behavior like 256x256

ElvisPresly commented 7 years ago

I will just add the picture here) 2017-08-23 19-11-40 2017-08-23 19-12-43

SovRedBit commented 6 years ago

I have the same problem like @mrzzzrm has, telegram background color is pink on Kubuntu 16.04

alexey-khabulyak commented 5 years ago

have the same issue. kde neon. Kde 5.14.2 with autostart screenshot_1 with manual startup screenshot_2