Use different icon for a sync folder on Windows depending on zoom level.

Signed-off-by: alex-z <blackslayer4@gmail.com>
This commit is contained in:
alex-z 2021-11-24 16:09:41 +02:00 committed by Matthieu Gallien (Rebase PR Action)
parent 7e41cf07d4
commit 77bf892809
6 changed files with 401 additions and 19 deletions

1
.gitignore vendored
View File

@ -184,6 +184,7 @@ compile_commands.json
convert.exe
.dir-locals.el
*-icon.png
*-icon-win-folder.png
*-sidebar.png
*-w10startmenu.png
theme.qrc

View File

@ -41,7 +41,7 @@
# target does not have the ``WIN32_EXECUTABLE`` property set.
# * One of the tools png2ico (See :find-module:`FindPng2Ico`) or
# icotool (see :find-module:`FindIcoTool`) is required.
# * Supported sizes: 16, 24, 32, 48, 64, 128, 256, 512 and 1024.
# * Supported sizes: 16, 20, 24, 32, 40, 48, 64, 128, 256, 512 and 1024.
#
# Mac OS X notes
# * The executable target must have the ``MACOSX_BUNDLE`` property set.
@ -102,9 +102,12 @@ include(CMakeParseArguments)
function(ecm_add_app_icon appsources)
set(options)
set(oneValueArgs OUTFILE_BASENAME)
set(multiValueArgs ICONS SIDEBAR_ICONS)
set(oneValueArgs OUTFILE_BASENAME ICON_INDEX)
set(multiValueArgs ICONS SIDEBAR_ICONS RC_DEPENDENCIES)
cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if (NOT ARG_ICON_INDEX)
set(ARG_ICON_INDEX 1)
endif()
if(NOT ARG_ICONS)
message(FATAL_ERROR "No ICONS argument given to ecm_add_app_icon")
@ -138,8 +141,11 @@ function(ecm_add_app_icon appsources)
endforeach()
endif()
_ecm_add_app_icon_categorize_icons("${ARG_ICONS}" "icons" "16;24;32;48;64;128;256;512;1024")
if (WIN32)
_ecm_add_app_icon_categorize_icons("${ARG_ICONS}" "icons" "16;20;24;32;40;48;64;128;256;512;1024")
else()
_ecm_add_app_icon_categorize_icons("${ARG_ICONS}" "icons" "16;24;32;48;64;128;256;512;1024")
endif()
if(ARG_SIDEBAR_ICONS)
_ecm_add_app_icon_categorize_icons("${ARG_SIDEBAR_ICONS}" "sidebar_icons" "16;32;64;128;256")
endif()
@ -168,8 +174,10 @@ function(ecm_add_app_icon appsources)
set(windows_icons ${icons_at_16px}
${icons_at_20px}
${icons_at_24px}
${icons_at_32px}
${icons_at_40px}
${icons_at_48px}
${icons_at_64px}
${icons_at_128px}
@ -204,12 +212,12 @@ function(ecm_add_app_icon appsources)
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
)
# this bit's a little hacky to make the dependency stuff work
file(WRITE "${_outfilename}.rc.in" "IDI_ICON1 ICON DISCARDABLE \"${_outfilename}.ico\"\n")
file(WRITE "${_outfilename}.rc.in" "IDI_ICON${ARG_ICON_INDEX} ICON DISCARDABLE \"${_outfilename}.ico\"\n")
add_custom_command(
OUTPUT "${_outfilename}.rc"
COMMAND ${CMAKE_COMMAND}
ARGS -E copy "${_outfilename}.rc.in" "${_outfilename}.rc"
DEPENDS "${_outfilename}.ico"
DEPENDS ${ARG_RC_DEPENDENCIES} "${_outfilename}.ico"
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
)
endfunction()
@ -226,7 +234,7 @@ function(ecm_add_app_icon appsources)
endif()
endforeach()
foreach(size 16 24 32 48 64 128 ${maxSize})
foreach(size 16 20 24 32 40 48 64 128 ${maxSize})
if(NOT icons_at_${size}px)
continue()
endif()

View File

@ -18,6 +18,7 @@
#include "asserts.h"
#include "utility.h"
#include "gui/configgui.h"
#include <comdef.h>
#include <Lmcons.h>
@ -48,7 +49,14 @@ static void setupFavLink_private(const QString &folder)
desktopIni.open(QFile::WriteOnly);
desktopIni.write("[.ShellClassInfo]\r\nIconResource=");
desktopIni.write(QDir::toNativeSeparators(qApp->applicationFilePath()).toUtf8());
desktopIni.write(",0\r\n");
#ifdef APPLICATION_FOLDER_ICON_INDEX
const auto iconIndex = APPLICATION_FOLDER_ICON_INDEX;
#else
const auto iconIndex = "0";
#endif
desktopIni.write(",");
desktopIni.write(iconIndex);
desktopIni.write("\r\n");
desktopIni.close();
// Set the folder as system and Desktop.ini as hidden+system for explorer to pick it.

View File

@ -258,6 +258,10 @@ if (NOT DEFINED APPLICATION_ICON_NAME)
set(APPLICATION_ICON_NAME ${APPLICATION_SHORTNAME})
endif()
if(NOT DEFINED APPLICATION_FOLDER_ICON_INDEX)
set(APPLICATION_FOLDER_ICON_INDEX 0)
endif()
# Generate png icons from svg
find_program(SVG_CONVERTER
NAMES inkscape inkscape.exe rsvg-convert
@ -269,9 +273,24 @@ if (NOT SVG_CONVERTER)
endif()
function(generate_sized_png_from_svg icon_path size)
set(options)
set(oneValueArgs OUTPUT_ICON_NAME OUTPUT_ICON_PATH)
set(multiValueArgs)
cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
get_filename_component(icon_name_dir ${icon_path} DIRECTORY)
get_filename_component(icon_name_wle ${icon_path} NAME_WLE)
if (ARG_OUTPUT_ICON_NAME)
set(icon_name_wle ${ARG_OUTPUT_ICON_NAME})
endif ()
if (ARG_OUTPUT_ICON_PATH)
set(icon_name_dir ${ARG_OUTPUT_ICON_PATH})
endif ()
if (EXISTS "${icon_name_dir}/${size}-${icon_name_wle}.png")
return()
endif()
@ -317,22 +336,84 @@ if(WIN32)
endif()
set(APP_ICON_SVG "${theme_dir}/colored/${APPLICATION_ICON_NAME}-icon.svg")
generate_sized_png_from_svg(${APP_ICON_SVG} 16)
generate_sized_png_from_svg(${APP_ICON_SVG} 24)
generate_sized_png_from_svg(${APP_ICON_SVG} 32)
generate_sized_png_from_svg(${APP_ICON_SVG} 48)
generate_sized_png_from_svg(${APP_ICON_SVG} 64)
generate_sized_png_from_svg(${APP_ICON_SVG} 128)
generate_sized_png_from_svg(${APP_ICON_SVG} 256)
generate_sized_png_from_svg(${APP_ICON_SVG} 512)
generate_sized_png_from_svg(${APP_ICON_SVG} 1024)
# generate secondary icon if available (currently for Windows only)--------------------------------------
set(APP_SECONDARY_ICONS "${theme_dir}/colored/icons")
set(APP_ICON_WIN_FOLDER_SVG "${APP_SECONDARY_ICONS}/${APPLICATION_ICON_NAME}-icon-win-folder.svg")
set(RC_DEPENDENCIES "")
if (EXISTS ${APP_ICON_WIN_FOLDER_SVG})
get_filename_component(output_icon_name_win ${APP_ICON_WIN_FOLDER_SVG} NAME_WLE)
# Product icon (for smallest size)
foreach(size IN ITEMS 16;20)
generate_sized_png_from_svg(${APP_ICON_SVG} ${size} OUTPUT_ICON_NAME ${output_icon_name_win} OUTPUT_ICON_PATH "${APP_SECONDARY_ICONS}/")
endforeach()
# Product icon with Windows folder (for sizes larger than 20)
foreach(size IN ITEMS 24;32;40;48;64;128;256;512;1024)
generate_sized_png_from_svg(${APP_ICON_WIN_FOLDER_SVG} ${size} OUTPUT_ICON_NAME ${output_icon_name_win} OUTPUT_ICON_PATH "${APP_SECONDARY_ICONS}/")
endforeach()
file(GLOB_RECURSE OWNCLOUD_ICONS_WIN_FOLDER "${APP_SECONDARY_ICONS}/*-${APPLICATION_ICON_NAME}-icon*")
set(APP_ICON_WIN_FOLDER_ICO_NAME "${APPLICATION_ICON_NAME}-win-folder")
set(RC_DEPENDENCIES "${RC_DEPENDENCIES} ${APP_ICON_WIN_FOLDER_ICO_NAME}.ico")
ecm_add_app_icon(APP_ICON_WIN_FOLDER ICONS "${OWNCLOUD_ICONS_WIN_FOLDER}" SIDEBAR_ICONS "${OWNCLOUD_SIDEBAR_ICONS}" OUTFILE_BASENAME "${APP_ICON_WIN_FOLDER_ICO_NAME}" ICON_INDEX 2)
endif()
# --------------------------------------
if (NOT ${RC_DEPENDENCIES} STREQUAL "")
string(STRIP ${RC_DEPENDENCIES} RC_DEPENDENCIES)
endif()
# generate primary icon from SVG (due to Win .ico vs .rc dependency issues, primary icon must always be generated last)--------------------------------------
if(WIN32)
foreach(size IN ITEMS 16;20;24;32;40;48;64;128;256;512;1024)
generate_sized_png_from_svg(${APP_ICON_SVG} ${size})
endforeach()
else()
foreach(size IN ITEMS 16;24;32;48;64;128;256;512;1024)
generate_sized_png_from_svg(${APP_ICON_SVG} ${size})
endforeach()
endif()
file(GLOB_RECURSE OWNCLOUD_ICONS "${theme_dir}/colored/*-${APPLICATION_ICON_NAME}-icon*")
if(APPLE)
file(GLOB_RECURSE OWNCLOUD_SIDEBAR_ICONS "${theme_dir}/colored/*-${APPLICATION_ICON_NAME}-sidebar*")
MESSAGE(STATUS "OWNCLOUD_SIDEBAR_ICONS: ${APPLICATION_ICON_NAME}: ${OWNCLOUD_SIDEBAR_ICONS}")
endif()
ecm_add_app_icon(APP_ICON ICONS "${OWNCLOUD_ICONS}" SIDEBAR_ICONS "${OWNCLOUD_SIDEBAR_ICONS}" OUTFILE_BASENAME "${APPLICATION_ICON_NAME}")
ecm_add_app_icon(APP_ICON RC_DEPENDENCIES ${RC_DEPENDENCIES} ICONS "${OWNCLOUD_ICONS}" SIDEBAR_ICONS "${OWNCLOUD_SIDEBAR_ICONS}" OUTFILE_BASENAME "${APPLICATION_ICON_NAME}" ICON_INDEX 1)
# --------------------------------------
if(WIN32)
# merge *.rc.in files for Windows (multiple ICON resources must be placed in a single file, otherwise, this won't work de to a bug in Windows compiler https://developercommunity.visualstudio.com/t/visual-studio-2017-prof-1557-cvt1100-duplicate-res/363156)
function(merge_files IN_FILE OUT_FILE)
file(READ ${IN_FILE} CONTENTS)
message("Merging ${IN_FILE} into ${OUT_FILE}")
file(APPEND ${OUT_FILE} "${CONTENTS}")
endfunction()
message("APP_ICON is: ${APP_ICON}")
if(APP_ICON)
get_filename_component(RC_IN_FOLDER ${APP_ICON}} DIRECTORY)
file(GLOB_RECURSE RC_IN_FILES "${RC_IN_FOLDER}/*rc.in")
foreach(rc_in_file IN ITEMS ${RC_IN_FILES})
get_filename_component(rc_in_file_name ${rc_in_file} NAME)
get_filename_component(app_icon_name "${APP_ICON}.in" NAME)
if(NOT "${rc_in_file_name}" STREQUAL "${app_icon_name}")
merge_files(${rc_in_file} "${APP_ICON}.in")
if (DEFINED APPLICATION_FOLDER_ICON_INDEX)
MATH(EXPR APPLICATION_FOLDER_ICON_INDEX "${APPLICATION_FOLDER_ICON_INDEX}+1")
message("APPLICATION_FOLDER_ICON_INDEX is now set to: ${APPLICATION_FOLDER_ICON_INDEX}")
endif()
endif()
endforeach()
endif()
endif()
# --------------------------------------
if(UNIX AND NOT APPLE)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIE")
@ -545,3 +626,5 @@ if(NOT BUILD_OWNCLOUD_OSX_BUNDLE AND NOT WIN32)
update_xdg_mimetypes( ${CMAKE_INSTALL_DATADIR}/mime/packages )
endif(SharedMimeInfo_FOUND)
endif()
configure_file(configgui.h.in ${CMAKE_CURRENT_BINARY_DIR}/configgui.h)

4
src/gui/configgui.h.in Normal file
View File

@ -0,0 +1,4 @@
#ifndef CONFIG_GUI_H
#define CONFIG_GUI_H
#cmakedefine APPLICATION_FOLDER_ICON_INDEX "@APPLICATION_FOLDER_ICON_INDEX@"
#endif

View File

@ -0,0 +1,278 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 26.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
version="1.1"
id="Ebene_1"
x="0px"
y="0px"
viewBox="0 0 300 300"
style="enable-background:new 0 0 300 300;"
xml:space="preserve"
sodipodi:docname="Windows_Folder.svg"
inkscape:version="1.1.1 (1:1.1+202109281949+c3084ef5ed)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs74">
<linearGradient
id="Pfad_499_00000161620552563728473090000003454445015337385602_"
gradientUnits="userSpaceOnUse"
x1="3.5778999"
y1="299.08331"
x2="3.5778999"
y2="297.29568"
gradientTransform="matrix(72,0,0,-72,49,21673)">
<stop
offset="0"
style="stop-color:#FE319A"
id="stop59" />
<stop
offset="1"
style="stop-color:#E20074"
id="stop61" />
</linearGradient>
<linearGradient
gradientTransform="matrix(0.9909162,0,0,0.99091623,283.08824,126.10294)"
inkscape:collect="always"
xlink:href="#linearGradient857"
id="linearGradient1192"
gradientUnits="userSpaceOnUse"
x1="18.230097"
y1="150"
x2="150.00002"
y2="-7.6293945e-06" /><linearGradient
inkscape:collect="always"
id="linearGradient857"><stop
style="stop-color:#0082c9;stop-opacity:1;"
offset="0"
id="stop853" /><stop
style="stop-color:#1cafff;stop-opacity:1"
offset="1"
id="stop855" /></linearGradient></defs><sodipodi:namedview
id="namedview72"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="1.9233304"
inkscape:cx="123.48372"
inkscape:cy="174.17704"
inkscape:window-width="1920"
inkscape:window-height="1046"
inkscape:window-x="0"
inkscape:window-y="34"
inkscape:window-maximized="1"
inkscape:current-layer="Ebene_1" />
<style
type="text/css"
id="style2">
.st0{fill:url(#SVGID_1_);}
.st1{fill:url(#SVGID_00000073698049827524260440000006626317865822427277_);}
.st2{fill:url(#SVGID_00000058549202148666045310000006535695705354523308_);}
.st3{fill:url(#SVGID_00000135661076229880923210000014324535628046543800_);}
.st4{fill:url(#SVGID_00000090993352524005697930000005123350809455339168_);}
.st5{fill:#FDE07F;}
.st6{fill:#FFEEB6;}
.st7{clip-path:url(#SVGID_00000027581996385575992730000014613207578918336175_);}
.st8{fill:url(#Pfad_499_00000154407742523961947240000000935762443450757262_);}
.st9{fill:#FFFFFF;}
.st10{fill:#F2F2F2;}
</style>
<g
id="g51">
<linearGradient
id="SVGID_1_"
gradientUnits="userSpaceOnUse"
x1="224.238"
y1="251.2621"
x2="235.5521"
y2="229.8477">
<stop
offset="0"
style="stop-color:#E5E5E5"
id="stop4" />
<stop
offset="1"
style="stop-color:#F2F2F2;stop-opacity:0"
id="stop6" />
</linearGradient>
<polygon
class="st0"
points="221,245 251,236 221,222 "
id="polygon9" />
<linearGradient
id="SVGID_00000168800218275837730680000003462325949068373151_"
gradientUnits="userSpaceOnUse"
x1="108.238"
y1="292.2621"
x2="119.5521"
y2="270.8477">
<stop
offset="0"
style="stop-color:#E5E5E5"
id="stop11" />
<stop
offset="1"
style="stop-color:#F2F2F2;stop-opacity:0"
id="stop13" />
</linearGradient>
<polygon
style="fill:url(#SVGID_00000168800218275837730680000003462325949068373151_);"
points="105,286 135,277 105,263 "
id="polygon16" />
<linearGradient
id="SVGID_00000003802560936691988940000016049607085827979708_"
gradientUnits="userSpaceOnUse"
x1="51.9582"
y1="185.0925"
x2="200.6586"
y2="104.7857">
<stop
offset="0.3193"
style="stop-color:#EBC863"
id="stop18" />
<stop
offset="1"
style="stop-color:#FEE182"
id="stop20" />
</linearGradient>
<path
style="fill:url(#SVGID_00000003802560936691988940000016049607085827979708_);"
d="M219,246H56c-1.7,0-3-1.3-3-3V33h151 c1.7,0,3,1.3,3,3v125.2c0,0.8,0.3,1.5,0.9,2.1l13.3,13.6c0.5,0.6,0.9,1.3,0.9,2.1V243C222,244.7,220.7,246,219,246z"
id="path23" />
<g
id="g39">
<linearGradient
id="SVGID_00000088830071281327557650000012927193665735863469_"
gradientUnits="userSpaceOnUse"
x1="81.921"
y1="116.6131"
x2="83.1607"
y2="222.7924">
<stop
offset="0"
style="stop-color:#FFEFBC"
id="stop25" />
<stop
offset="1"
style="stop-color:#FFE495"
id="stop27" />
</linearGradient>
<path
style="fill:url(#SVGID_00000088830071281327557650000012927193665735863469_);"
d="M103.5,286L54,246V33l55.9,44.1 c0.7,0.6,1.1,1.4,1.1,2.4V211l-5,7v66.9C106,286.1,104.5,286.8,103.5,286z"
id="path30" />
<linearGradient
id="SVGID_00000075125985038499810010000013334681634146325900_"
gradientUnits="userSpaceOnUse"
x1="58.9558"
y1="126.3097"
x2="117.1869"
y2="218.9498">
<stop
offset="0"
style="stop-color:#FFEAA5"
id="stop32" />
<stop
offset="1"
style="stop-color:#FFE086"
id="stop34" />
</linearGradient>
<path
style="fill:url(#SVGID_00000075125985038499810010000013334681634146325900_);"
d="M102.5,285.7l-49.5-40V33l55.8,44 c0.7,0.6,1.1,1.4,1.1,2.4v131.4l-5,7v66.8C104.9,285.8,103.5,286.5,102.5,285.7z"
id="path37" />
</g>
<g
id="g49">
<rect
x="60"
y="46"
class="st5"
width="1"
height="200"
id="rect41" />
<rect
x="56.5"
y="46"
class="st5"
width="1"
height="200"
id="rect43" />
<rect
x="57.5"
y="46"
class="st6"
width="1"
height="200"
id="rect45" />
<rect
x="61"
y="46"
class="st6"
width="1"
height="200"
id="rect47" />
</g>
</g>
<g
id="g69"
transform="translate(0,-100)">
<defs
id="defs54">
<rect
id="SVGID_00000093176395783954265780000012512996052019405743_"
x="122.3"
y="139"
width="128.7"
height="128.7" />
</defs>
<clipPath
id="SVGID_00000106127748250350940740000017471206982484828042_">
<use
xlink:href="#SVGID_00000093176395783954265780000012512996052019405743_"
style="overflow:visible"
id="use56"
x="0"
y="0"
width="100%"
height="100%" />
</clipPath>
<g
id="g925"
transform="matrix(0.81518987,0,0,0.81518987,-44.170655,200.60216)"><circle
r="79"
cy="126.10294"
cx="283.08823"
id="circle1050"
style="fill:url(#linearGradient1192);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.0990916;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
inkscape:export-filename="nextcloud-icon.png"
inkscape:export-xdpi="300"
inkscape:export-ydpi="300" /><path
inkscape:connector-curvature="0"
id="path1052"
d="m 283.18965,95.813064 c -13.79313,0 -25.48394,9.350826 -29.10731,22.020146 -3.14909,-6.72 -9.97328,-11.42792 -17.83356,-11.42792 -10.80973,0 -19.69562,8.88589 -19.69562,19.69562 0,10.80972 8.88589,19.69967 19.69562,19.69967 7.86028,0 14.68447,-4.7108 17.83356,-11.43198 3.62337,12.67028 15.31418,22.02422 29.10731,22.02422 13.69111,0 25.32232,-9.21286 29.03837,-21.74023 3.20726,6.56859 9.94698,11.14799 17.69562,11.14799 10.80974,0 19.69967,-8.88995 19.69967,-19.69967 0,-10.80973 -8.88993,-19.69562 -19.69967,-19.69562 -7.74864,0 -14.48836,4.57653 -17.69562,11.14395 -3.71605,-12.5264 -15.34726,-21.736176 -29.03837,-21.736176 z m 0,11.561796 c 10.41225,0 18.73011,8.31383 18.73011,18.72605 0,10.41221 -8.31786,18.73011 -18.73011,18.73011 -10.41219,0 -18.72603,-8.3179 -18.72603,-18.73011 0,-10.41222 8.31384,-18.72605 18.72603,-18.72605 z m -46.94087,10.59222 c 4.56183,0 8.13788,3.57198 8.13788,8.13383 0,4.56184 -3.57605,8.13787 -8.13788,8.13787 -4.56183,0 -8.13385,-3.57603 -8.13385,-8.13787 0,-4.56185 3.57202,-8.13383 8.13385,-8.13383 z m 93.67486,0 c 4.56187,0 8.1379,3.57198 8.1379,8.13383 0,4.56184 -3.57605,8.13787 -8.1379,8.13787 -4.56181,0 -8.13381,-3.57603 -8.13381,-8.13787 0,-4.56185 3.57201,-8.13383 8.13381,-8.13383 z"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:6.50314;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
inkscape:export-filename="Nextcloud Hub logo variants.png"
inkscape:export-xdpi="300"
inkscape:export-ydpi="300" /></g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.1 KiB