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))