From f05f214f6cf109e792dcac4141269dd465932950 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Tue, 28 Apr 2015 12:45:29 +0200 Subject: [PATCH] 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). --- appmenus-scripts/qubes-core-appmenus.py | 22 +++++++++++-- appmenus-scripts/qubes-receive-appmenus | 43 +++++++++++++++---------- 2 files changed, 45 insertions(+), 20 deletions(-) diff --git a/appmenus-scripts/qubes-core-appmenus.py b/appmenus-scripts/qubes-core-appmenus.py index 75ed1b0..84d658d 100644 --- a/appmenus-scripts/qubes-core-appmenus.py +++ b/appmenus-scripts/qubes-core-appmenus.py @@ -133,9 +133,11 @@ def QubesVm_appicons_create(self, srcdir=None): if whitelist and desktop not in whitelist: continue - qubes.imgconverter.tint(os.path.join(srcdir, icon), - os.path.join(self.appmenus_icons_dir, icon), - self.label.color) + src_icon = os.path.join(srcdir, icon) + dst_icon = os.path.join(self.appmenus_icons_dir, icon) + 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): if not os.path.exists(self.appmenus_icons_dir): return @@ -246,11 +248,24 @@ def QubesVm_label_setter(self, _): self.appmenus_create() def QubesVm_appmenus_recreate(self): + """ + Force recreation of all appmenus and icons. For example when VM label + color was changed + """ self.appmenus_remove() self.appicons_remove() self.appicons_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): if name == 'internal': 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_remove = QubesVm_appmenus_remove QubesVm.appmenus_recreate = QubesVm_appmenus_recreate +QubesVm.appmenus_update = QubesVm_appmenus_update QubesVm.appicons_create = QubesVm_appicons_create QubesVm.appicons_remove = QubesVm_appicons_remove diff --git a/appmenus-scripts/qubes-receive-appmenus b/appmenus-scripts/qubes-receive-appmenus index 2e1f819..1110c52 100755 --- a/appmenus-scripts/qubes-receive-appmenus +++ b/appmenus-scripts/qubes-receive-appmenus @@ -186,31 +186,34 @@ def create_template(path, values): print >>sys.stderr, "Warning: not creating/updating '%s' because of missing '%s' key" % (path, key) return - desktop_file = open(path, "w") - desktop_file.write("[Desktop Entry]\n") - desktop_file.write("Version=1.0\n") - desktop_file.write("Type=Application\n") - desktop_file.write("Terminal=false\n") - desktop_file.write("X-Qubes-VmName=%VMNAME%\n") + desktop_entry = "" + desktop_entry += "[Desktop Entry]\n" + desktop_entry += "Version=1.0\n" + desktop_entry += "Type=Application\n" + desktop_entry += "Terminal=false\n" + desktop_entry += "X-Qubes-VmName=%VMNAME%\n" if 'Icon' in values: icon_file = os.path.splitext(os.path.split(path)[1])[0] + '.png' - desktop_file.write("Icon={0}\n".format(os.path.join( - '%VMDIR%', vm_files['appmenus_icons_subdir'], icon_file))) + desktop_entry += "Icon={0}\n".format(os.path.join( + '%VMDIR%', vm_files['appmenus_icons_subdir'], icon_file)) else: - desktop_file.write("Icon=%XDGICON%\n") + desktop_entry += "Icon=%XDGICON%\n" for key in ["Name", "GenericName" ]: 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" ]: if values.has_key(key): - desktop_file.write("{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 += "{0}={1}\n".format(key, values[key]) + 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(): env_vmname = os.environ.get("QREXEC_REMOTE_DOMAIN") @@ -294,8 +297,14 @@ def main(): os.path.splitext(appmenu_file)[0] + '.png') try: - qubes.imgconverter.Image.get_xdg_icon_from_vm(vm, - new_appmenus[appmenu_file]['Icon']).save(icondest) + icon = qubes.imgconverter.Image.get_xdg_icon_from_vm(vm, + 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: 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') for child_vm in vm.appvms.values(): try: - child_vm.appmenus_recreate() + child_vm.appmenus_update() except Exception, e: print >> sys.stderr, "---> Failed to recreate appmenus for " \ "'{0}': {1}".format(child_vm.name, str(e))