Skip to content

Conversation

@SebastianKrupinski
Copy link
Contributor

@SebastianKrupinski SebastianKrupinski commented Sep 15, 2025

  • Resolves: # client ticket

Summary

Before

Custom favourite icon was only generate when imagick svg support was turned on

After

Custom favourite is generate even when imagick svg support is not present, as long a a supported image format is used

image

Testing

  1. Make sure Imagick is installed
  2. In Administrative settings -> Themes -> Update the logo and favicon use PNG to start (this should reset the image cache)
  3. Log out then log back in (This should generate new favicon visible in the browser tab by the tab headeing)
  4. Repeat test with SVG enable and svg logo and favicon

TODO

  • Tests

Checklist

@SebastianKrupinski SebastianKrupinski self-assigned this Sep 15, 2025
@SebastianKrupinski SebastianKrupinski added the 2. developing Work in progress label Sep 15, 2025
@SebastianKrupinski SebastianKrupinski force-pushed the fix/favourite-icon-without-imagick-svg-support branch 2 times, most recently from e08e5d4 to 23ab2ba Compare September 16, 2025 16:19
@SebastianKrupinski SebastianKrupinski force-pushed the fix/favourite-icon-without-imagick-svg-support branch from 941959d to aa1d4ef Compare October 8, 2025 11:58
@SebastianKrupinski SebastianKrupinski marked this pull request as ready for review October 8, 2025 12:59
@SebastianKrupinski SebastianKrupinski requested review from come-nc and salmart-dev and removed request for a team October 8, 2025 12:59
@ChristophWurst

This comment was marked as resolved.

@szaimen
Copy link
Contributor

szaimen commented Nov 4, 2025

@SebastianKrupinski does this address #36607?

@SebastianKrupinski SebastianKrupinski added 3. to review Waiting for reviews and removed 2. developing Work in progress labels Nov 4, 2025
@SebastianKrupinski SebastianKrupinski force-pushed the fix/favourite-icon-without-imagick-svg-support branch from aa1d4ef to 08869d2 Compare November 4, 2025 10:32
@SebastianKrupinski

This comment was marked as resolved.

@SebastianKrupinski
Copy link
Contributor Author

SebastianKrupinski commented Nov 4, 2025

@SebastianKrupinski does this address #36607?

No, it still uses imagick, but it no longer requires imagick svg support, to generate icons, the icons where generated as png's anyway, it only requires imagick png support and a png logo. But it will generate themed svg icons also

If we want to generate themed icons, we have to either limit the input formats to png, and we can use another library like php-gd, or stick with imagick as its the only one that supports svg.

Unless we drop the whole themed icons idea then we can drop imagick

@szaimen
Copy link
Contributor

szaimen commented Nov 4, 2025

@SebastianKrupinski does this address #36607?

No, it still uses imagick, but it no longer requires imagick svg support, to generate icons, the icons where generated as png's anyway, it only requires imagick png support and a png logo. But it will generate themed svg icons also

If we want to generate themed icons, we have to either limit the input formats to png, and we can use another library like php-gd, or stick with imagick as its the only one that supports svg.

Unless we drop the whole themed icons idea then we can drop imagick

It seems like svg favicons are supported by all major browsers nowadays. I was wondering if it would be possible to have svgs stacked on top of each other by using masks or something for which we dont need to use imagick?

@SebastianKrupinski
Copy link
Contributor Author

It seems like svg favicons are supported by all major browsers nowadays. I was wondering if it would be possible to have svgs stacked on top of each other by using masks or something for which we dont need to use imagick?

It's possible, but we would need to find a pure php library or someone would have to write one, then you also need to consider that the input image (logo) would have to be a svg also.

@ChristophWurst
Copy link
Member

@szaimen are you fine with the current approach?

@szaimen
Copy link
Contributor

szaimen commented Nov 26, 2025

@szaimen are you fine with the current approach?

Yes

@ChristophWurst
Copy link
Member

@kesselb @come-nc @provokateurin @salmart-dev 🏓 for review. Thank you 🙏


$response = null;
$iconFile = null;
// retrieve instance favorite icon
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code already shows that we retrieve the icon. A comment would be more useful if it explained the reasoning or any non-obvious behavior.

Copy link
Contributor Author

@SebastianKrupinski SebastianKrupinski Dec 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does explain what we are doing? We are retrieving the user instance configured favorite icon.


$response = null;
$iconFile = null;
// retrieve instance favorite icon
Copy link
Contributor

@kesselb kesselb Dec 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// retrieve instance favorite icon
// retrieve instance favicon

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure

} catch (NotFoundException $e) {
}
if ($iconFile === null && $this->imageManager->shouldReplaceIcons()) {
// retrieve or generate app specific favorite icon
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// retrieve or generate app specific favorite icon
// retrieve or generate app specific favicon

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest removing this comment unless there's additional context we should know. Right now it's just echoing the code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to keep these in, they break up the code into specific logical section and tell us which icon is being worked with. User Instance icon, App specific icon or Generic core icon.

}
$response = new FileDisplayResponse($iconFile, Http::STATUS_OK, ['Content-Type' => 'image/x-icon']);
}
// fallback to core favorite icon
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// fallback to core favorite icon
// fallback to core favicon

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure

@ChristophWurst ChristophWurst force-pushed the fix/favourite-icon-without-imagick-svg-support branch from 08869d2 to 69057a5 Compare December 3, 2025 16:00
Comment on lines 214 to 232
if ($useSvg) {
$icon = $appPath . '/img/' . $app . '.svg';
if (file_exists($icon)) {
return $icon;
}
$icon = $appPath . '/img/app.svg';
if (file_exists($icon)) {
return $icon;
}
} else {
$icon = $appPath . '/img/' . $app . '.png';
if (file_exists($icon)) {
return $icon;
}
$icon = $appPath . '/img/app.png';
if (file_exists($icon)) {
return $icon;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if ($useSvg) {
$icon = $appPath . '/img/' . $app . '.svg';
if (file_exists($icon)) {
return $icon;
}
$icon = $appPath . '/img/app.svg';
if (file_exists($icon)) {
return $icon;
}
} else {
$icon = $appPath . '/img/' . $app . '.png';
if (file_exists($icon)) {
return $icon;
}
$icon = $appPath . '/img/app.png';
if (file_exists($icon)) {
return $icon;
}
}
$extension = ($useSvg ? '.svg' : '.png');
$icon = $appPath . '/img/' . $app . $extension;
if (file_exists($icon)) {
return $icon;
}
$icon = $appPath . '/img/app' . $extension;
if (file_exists($icon)) {
return $icon;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure


$appIconFile->destroy();
return $finalIconFile;
return false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you forgot the catch block for the exception?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, this is just a default return, this should never get triggered but I did not want to change the function signature. The original code did not throw a error, so just matching that.

Copy link
Contributor

@kesselb kesselb Dec 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The try-catch-finally block does not catch any exceptions. That means if an error occurs, the variable is unset and the exception still bubbles up. If no exception occurs, the function returns earlier. This makes the final return block unreachable. It is not documented that the functions throw and the previous try-catch block does catch the ImagickException, so I wanted to check whether the catch block is missing.

@SebastianKrupinski
Copy link
Contributor Author

@kesselb you good with the latest code?

@kesselb
Copy link
Contributor

kesselb commented Dec 4, 2025

Hey, thanks for picking it up.

Themed icon is definitely a rabbit hole ;)

I briefly talked about the PR with Christoph. I'm probably not the right person to review or approve this since I don't have enough knowledge about icon generation. I strongly recommend looping in Julius, Barth, or Ferdinand so someone with more expertise can take a look.

After reading the code and going through the customer ticket I have a few questions. Some things don't fully add up for me.

  1. The customer says the branded favicon on the login page worked some time ago but is now broken. They also say it still works for logged-in users. As far as I remember, we always required imagick with SVG support for this to work. I suggest clarifying with the customer whether they actually have imagick with SVG support enabled.

  2. How is that feature supposed to work in general? I'm uploading a custom icon and changing the primary colors. In my tests, with SVG support, the favicon becomes the logo with the primary color as background. Is that the expected outcome, and should this PR now produce the same outcome even without SVG support?

  3. I patched my dev instance 1 (this PR) and instance 2 (master) to always return false for SVG support. On instance 1 I'm getting the themed instance icon for the Contacts app. On instance 2 I'm getting the default Contacts icon with the default color. So it seems this only works if the app itself also ships a PNG version of the icon (like the mail app does). If not, we fall back to the instance logo. I'm not sure if this was an intentional change. It looks like a nice enhancement, but most apps don't bundle such a file today. I wonder if they should. We've required imagick with SVG support for themed icons for years. If we can achieve the same result today without imagick and without SVG support, great, but we should have a proper discussion about it.

This PR (without SVG support) Main (without SVG support)
Contacts favIcon-contacts#b6469d favicon
Mail favIcon-mail#b6469d favicon
Talk favIcon-spreed#b6469d favicon

@SebastianKrupinski
Copy link
Contributor Author

SebastianKrupinski commented Dec 4, 2025

Themed icon is definitely a rabbit hole ;)

LOL. Oh, I know, I had to decipher the original code to figure what, when and why

  1. The customer says the branded favicon on the login page worked some time ago but is now broken. They also say it still works for logged-in users. As far as I remember, we always required imagick with SVG support for this to work. I suggest clarifying with the customer whether they actually have imagick with SVG support enabled.

For me this did not work at all, weather this was a logged in user or a non logged in user, so I based my work of that.

  1. How is that feature supposed to work in general? I'm uploading a custom icon and changing the primary colors. In my tests, with SVG support, the favicon becomes the logo with the primary color as background. Is that the expected outcome, and should this PR now produce the same outcome even without SVG support?

The original code, did the same thing, it tried to find the "app specific icon" then the "instance icon" from themes and then as a last resort "stock (shipped) icon".

  1. If not, we fall back to the instance logo. I'm not sure if this was an intentional change.

This was the original logic.

I wonder if they should. We've required imagick with SVG support for themed icons for years. If we can achieve the same result today without imagick and without SVG support, great, but we should have a proper discussion about it.

Well the apps should ship both svg and png, I was going to update our apps with both once this was in and working again.

Yes we required "imagick with SVG" mainly I think because the original code was using an embedded svg string to generate the background. Also not sure why we forced SVG support when all the icons generated where PNG... the original code always generated PNGs from what I saw, so if the client used a PNG logo and we generated a PNG themed logo why did we need SVG support?

On a side note, in my personal opinion, SVG are not safe, they are nice because they are small and scale nicely, but the fact they can contain "links" makes them super scary.

@kesselb
Copy link
Contributor

kesselb commented Dec 4, 2025

For me this did not work at all

With SVG support, it does for me 🎨

This was the original logic

With the original logic, that path was never executed and went right away to favicon.ico.

Well the apps should ship both svg and png, I was going to update our apps with both once this was in and working again.

Some apps also ship a favicon.png file. Not sure though if we would pick them up somewhere.

Yes we required "imagick with SVG" mainly I think because the original code was using an embedded svg string to generate the background. Also not sure why we forced SVG support when all the icons generated where PNG... the original code always generated PNGs from what I saw, so if the client used a PNG logo and we generated a PNG themed logo why did we need SVG support?

cc @juliusknorr @skjnldsv @susnux wdyt?

@kesselb kesselb added the bug label Dec 4, 2025
@susnux
Copy link
Contributor

susnux commented Dec 4, 2025

Well the apps should ship both svg and png, I was going to update our apps with both once this was in and working again.

No on the long run non-vector SVGs are deprecated.
This is also a design requirement we lately see to make it properly work in Nextcloud.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

3. to review Waiting for reviews bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants