appmenus: update icons only when changed

Do not regenerate all the icons when the source is unchanged.

Also add preliminary code to support the same improvement for .desktop
files, but it requires some more work, especially because KDE does a lot
of caching and we need to force update sometimes (for example when VM
label color has changed).
This commit is contained in:
Marek Marczykowski-Górecki 2015-04-28 12:45:29 +02:00
parent d6f0cfcbad
commit f05f214f6c
2 changed files with 45 additions and 20 deletions

View File

@ -133,9 +133,11 @@ def QubesVm_appicons_create(self, srcdir=None):
if whitelist and desktop not in whitelist: if whitelist and desktop not in whitelist:
continue continue
qubes.imgconverter.tint(os.path.join(srcdir, icon), src_icon = os.path.join(srcdir, icon)
os.path.join(self.appmenus_icons_dir, icon), dst_icon = os.path.join(self.appmenus_icons_dir, icon)
self.label.color) if not os.path.exists(dst_icon) or \
os.path.getmtime(src_icon) > os.path.getmtime(dst_icon):
qubes.imgconverter.tint(src_icon, dst_icon, self.label.color)
def QubesVm_appicons_remove(self): def QubesVm_appicons_remove(self):
if not os.path.exists(self.appmenus_icons_dir): return if not os.path.exists(self.appmenus_icons_dir): return
@ -246,11 +248,24 @@ def QubesVm_label_setter(self, _):
self.appmenus_create() self.appmenus_create()
def QubesVm_appmenus_recreate(self): def QubesVm_appmenus_recreate(self):
"""
Force recreation of all appmenus and icons. For example when VM label
color was changed
"""
self.appmenus_remove() self.appmenus_remove()
self.appicons_remove() self.appicons_remove()
self.appicons_create() self.appicons_create()
self.appmenus_create() self.appmenus_create()
def QubesVm_appmenus_update(self):
"""
Similar to appmenus_recreate, but do not touch unchanged files
"""
self.appmenus_remove()
self.appicons_create()
self.appicons_cleanup()
self.appmenus_create()
def QubesVm_set_attr(self, name, newvalue, oldvalue): def QubesVm_set_attr(self, name, newvalue, oldvalue):
if name == 'internal': if name == 'internal':
if newvalue and not oldvalue: if newvalue and not oldvalue:
@ -262,6 +277,7 @@ def QubesVm_set_attr(self, name, newvalue, oldvalue):
QubesVm.appmenus_create = QubesVm_appmenus_create QubesVm.appmenus_create = QubesVm_appmenus_create
QubesVm.appmenus_remove = QubesVm_appmenus_remove QubesVm.appmenus_remove = QubesVm_appmenus_remove
QubesVm.appmenus_recreate = QubesVm_appmenus_recreate QubesVm.appmenus_recreate = QubesVm_appmenus_recreate
QubesVm.appmenus_update = QubesVm_appmenus_update
QubesVm.appicons_create = QubesVm_appicons_create QubesVm.appicons_create = QubesVm_appicons_create
QubesVm.appicons_remove = QubesVm_appicons_remove QubesVm.appicons_remove = QubesVm_appicons_remove

View File

@ -186,31 +186,34 @@ def create_template(path, values):
print >>sys.stderr, "Warning: not creating/updating '%s' because of missing '%s' key" % (path, key) print >>sys.stderr, "Warning: not creating/updating '%s' because of missing '%s' key" % (path, key)
return return
desktop_file = open(path, "w") desktop_entry = ""
desktop_file.write("[Desktop Entry]\n") desktop_entry += "[Desktop Entry]\n"
desktop_file.write("Version=1.0\n") desktop_entry += "Version=1.0\n"
desktop_file.write("Type=Application\n") desktop_entry += "Type=Application\n"
desktop_file.write("Terminal=false\n") desktop_entry += "Terminal=false\n"
desktop_file.write("X-Qubes-VmName=%VMNAME%\n") desktop_entry += "X-Qubes-VmName=%VMNAME%\n"
if 'Icon' in values: if 'Icon' in values:
icon_file = os.path.splitext(os.path.split(path)[1])[0] + '.png' icon_file = os.path.splitext(os.path.split(path)[1])[0] + '.png'
desktop_file.write("Icon={0}\n".format(os.path.join( desktop_entry += "Icon={0}\n".format(os.path.join(
'%VMDIR%', vm_files['appmenus_icons_subdir'], icon_file))) '%VMDIR%', vm_files['appmenus_icons_subdir'], icon_file))
else: else:
desktop_file.write("Icon=%XDGICON%\n") desktop_entry += "Icon=%XDGICON%\n"
for key in ["Name", "GenericName" ]: for key in ["Name", "GenericName" ]:
if values.has_key(key): if values.has_key(key):
desktop_file.write("{0}=%VMNAME%: {1}\n".format(key, values[key])) desktop_entry += "{0}=%VMNAME%: {1}\n".format(key, values[key])
for key in [ "Comment", "Categories" ]: for key in [ "Comment", "Categories" ]:
if values.has_key(key): if values.has_key(key):
desktop_file.write("{0}={1}\n".format(key, values[key])) desktop_entry += "{0}={1}\n".format(key, values[key])
desktop_file.write("Exec=qvm-run -q --tray -a %VMNAME% -- {0}\n".format(pipes.quote(values['Exec'])))
desktop_file.close()
desktop_entry += "Exec=qvm-run -q --tray -a %VMNAME% -- {0}\n".format(
pipes.quote(values['Exec']))
if not os.path.exists(path) or desktop_entry != open(path, "r").read():
desktop_file = open(path, "w")
desktop_file.write(desktop_entry)
desktop_file.close()
def main(): def main():
env_vmname = os.environ.get("QREXEC_REMOTE_DOMAIN") env_vmname = os.environ.get("QREXEC_REMOTE_DOMAIN")
@ -294,8 +297,14 @@ def main():
os.path.splitext(appmenu_file)[0] + '.png') os.path.splitext(appmenu_file)[0] + '.png')
try: try:
qubes.imgconverter.Image.get_xdg_icon_from_vm(vm, icon = qubes.imgconverter.Image.get_xdg_icon_from_vm(vm,
new_appmenus[appmenu_file]['Icon']).save(icondest) new_appmenus[appmenu_file]['Icon'])
if os.path.exists(icondest):
old_icon = qubes.imgconverter.Image.load_from_file(icondest)
else:
old_icon = None
if old_icon is None or icon != old_icon:
icon.save(icondest)
except Exception, e: except Exception, e:
print >> sys.stderr, '----> Failed to get icon for {0}: {1!s}'.format(appmenu_file, e) print >> sys.stderr, '----> Failed to get icon for {0}: {1!s}'.format(appmenu_file, e)
@ -329,7 +338,7 @@ def main():
os.putenv('SKIP_CACHE_REBUILD', '1') os.putenv('SKIP_CACHE_REBUILD', '1')
for child_vm in vm.appvms.values(): for child_vm in vm.appvms.values():
try: try:
child_vm.appmenus_recreate() child_vm.appmenus_update()
except Exception, e: except Exception, e:
print >> sys.stderr, "---> Failed to recreate appmenus for " \ print >> sys.stderr, "---> Failed to recreate appmenus for " \
"'{0}': {1}".format(child_vm.name, str(e)) "'{0}': {1}".format(child_vm.name, str(e))