diff --git a/qubesmanager/qube_manager.py b/qubesmanager/qube_manager.py index feb388d..024a3d5 100644 --- a/qubesmanager/qube_manager.py +++ b/qubesmanager/qube_manager.py @@ -506,14 +506,15 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtWidgets.QMainWindow): dispatcher.add_handler('property-load', self.on_domain_changed) + dispatcher.add_handler('domain-feature-set:updates-available', + self.on_domain_updates_available) + dispatcher.add_handler('domain-feature-delete:updates-available', + self.on_domain_updates_available) + # It needs to store threads until they finish self.threads_list = [] self.progress = None - # Check Updates Timer - timer = QtCore.QTimer(self) - timer.timeout.connect(self.check_updates) - timer.start(1000 * 30) # 30s self.check_updates() # select the first row of the table to make sure menu actions are @@ -524,7 +525,6 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtWidgets.QMainWindow): self.qt_app.setApplicationName(self.tr("Qube Manager")) self.qt_app.setWindowIcon(QtGui.QIcon.fromTheme("qubes-manager")) - def keyPressEvent(self, event): # pylint: disable=invalid-name if event.key() == QtCore.Qt.Key_Escape: self.searchbox.clear() @@ -561,15 +561,19 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtWidgets.QMainWindow): self.manager_settings.setValue("window_size", self.size()) event.accept() - def check_updates(self): - for vm in self.qubes_app.domains: - if vm.klass in {'TemplateVM', 'StandaloneVM'}: - try: - self.vms_in_table[vm.qid].info_widget.update_vm_state() - except (exc.QubesException, KeyError): - # the VM might have vanished in the meantime or - # the signal might have been handled in the wrong order - pass + def check_updates(self, vm=None): + if vm is None: + for vm_iter in self.qubes_app.domains: + self.check_updates(vm_iter) + return + + if vm.klass in {'TemplateVM', 'StandaloneVM'}: + try: + self.vms_in_table[vm.qid].info_widget.update_vm_state() + except (exc.QubesException, KeyError): + # the VM might have vanished in the meantime or + # the signal might have been handled in the wrong order + pass def on_domain_added(self, _submitter, _event, vm, **_kwargs): row_no = 0 @@ -615,6 +619,9 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtWidgets.QMainWindow): if getattr(row.vm, 'template', None) == vm: row.info_widget.update_vm_state() + def on_domain_updates_available(self, vm, _event, **_kwargs): + self.check_updates(vm) + def on_domain_changed(self, vm, event, **_kwargs): if not vm: # change of global properties occured if event.endswith(':default_netvm'): diff --git a/qubesmanager/tests/test_qube_manager.py b/qubesmanager/tests/test_qube_manager.py index 720b5f1..4f1ebf8 100644 --- a/qubesmanager/tests/test_qube_manager.py +++ b/qubesmanager/tests/test_qube_manager.py @@ -1084,9 +1084,9 @@ class QubeManagerTest(unittest.TestCase): self.addCleanup( subprocess.call, - ["qvm-shutdown", target_vm_name]) + ["qvm-shutdown", "--wait", target_vm_name]) self._run_command_and_process_events( - ["qvm-start", target_vm_name], timeout=20) + ["qvm-start", target_vm_name], timeout=60) status_item = self._get_table_item(vm_row, "State") @@ -1096,7 +1096,7 @@ class QubeManagerTest(unittest.TestCase): "Power state failed to update on start") self._run_command_and_process_events( - ["qvm-shutdown", target_vm_name], timeout=20) + ["qvm-shutdown", "--wait", target_vm_name], timeout=30) displayed_power_state = status_item.on_icon.status @@ -1122,9 +1122,9 @@ class QubeManagerTest(unittest.TestCase): self.addCleanup( subprocess.call, - ["qvm-shutdown", target_vm_name]) + ["qvm-shutdown", "--wait", target_vm_name]) self._run_command_and_process_events( - ["qvm-start", target_vm_name], timeout=20) + ["qvm-start", target_vm_name], timeout=60) for i in range(self.dialog.table.rowCount()): call_count = self._get_table_item( @@ -1149,7 +1149,7 @@ class QubeManagerTest(unittest.TestCase): self.assertIn("hypervisor", c.text(), "Log for dom0 does not contain 'hypervisor'") - selected_vm = self._select_non_admin_vm().name + selected_vm = self._select_non_admin_vm(running=True).name self.assertTrue(self.dialog.logs_menu.isEnabled()) diff --git a/ui/settingsdlg.ui b/ui/settingsdlg.ui index 5a7da54..e5f7563 100644 --- a/ui/settingsdlg.ui +++ b/ui/settingsdlg.ui @@ -1321,6 +1321,9 @@ The qube must be running to disable seamless mode; this setting is not persisten This qube has direct network access and Qubes Firewall settings will not be used. Configure other qubes' network access in their network settings or in a dedicated firewall qube. + + true +