Skip to content

Commit

Permalink
ui: allow to configure refresh interval
Browse files Browse the repository at this point in the history
Up until now, the GUI was refreshed if:
 - it was not minimized or hidden.
 - if there were new events (even if we received events from the daemon,
   they were filtered out if they were duplicated).

But still, there were scenarios where refreshing the views every second
(more or less) was too much, like when monitoring multiple machines.

Now it's possible to configure the views' refresh interval, regardless
of what the daemon sends.

Asked here: #1073

(cherry picked from commit 6006717)
  • Loading branch information
gustavo-iniguez-goya committed Jan 8, 2024
1 parent f16b27a commit 435dffc
Show file tree
Hide file tree
Showing 4 changed files with 219 additions and 29 deletions.
1 change: 1 addition & 0 deletions ui/opensnitch/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ class Config:
NOTIFICATION_TYPE_SYSTEM = 0
NOTIFICATION_TYPE_QT = 1

STATS_UPDATE_INTERVAL = "statsDialog/update_interval"
STATS_GEOMETRY = "statsDialog/geometry"
STATS_LAST_TAB = "statsDialog/last_tab"
STATS_FILTER_TEXT = "statsDialog/general_filter_text"
Expand Down
8 changes: 8 additions & 0 deletions ui/opensnitch/dialogs/preferences.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ def __init__(self, parent=None, appicon=None):
self.comboUITheme.currentIndexChanged.connect(self._cb_combo_themes_changed)
self.cmdTimeoutUp.clicked.connect(lambda: self._cb_cmd_spin_clicked(self.spinUITimeout, self.SUM))
self.cmdTimeoutDown.clicked.connect(lambda: self._cb_cmd_spin_clicked(self.spinUITimeout, self.REST))
self.cmdRefreshUIUp.clicked.connect(lambda: self._cb_cmd_spin_clicked(self.spinUIRefresh, self.SUM))
self.cmdRefreshUIDown.clicked.connect(lambda: self._cb_cmd_spin_clicked(self.spinUIRefresh, self.REST))
self.cmdDBMaxDaysUp.clicked.connect(lambda: self._cb_cmd_spin_clicked(self.spinDBMaxDays, self.SUM))
self.cmdDBMaxDaysDown.clicked.connect(lambda: self._cb_cmd_spin_clicked(self.spinDBMaxDays, self.REST))
self.cmdDBPurgesUp.clicked.connect(lambda: self._cb_cmd_spin_clicked(self.spinDBPurgeInterval, self.SUM))
Expand Down Expand Up @@ -133,6 +135,8 @@ def __init__(self, parent=None, appicon=None):

self.cmdTimeoutUp.setIcon(addIcon)
self.cmdTimeoutDown.setIcon(delIcon)
self.cmdRefreshUIUp.setIcon(addIcon)
self.cmdRefreshUIDown.setIcon(delIcon)
self.cmdDBMaxDaysUp.setIcon(addIcon)
self.cmdDBMaxDaysDown.setIcon(delIcon)
self.cmdDBPurgesUp.setIcon(addIcon)
Expand Down Expand Up @@ -260,6 +264,9 @@ def _load_settings(self):
self.comboUIDuration.setCurrentIndex(self._default_duration)
self.comboUIDialogPos.setCurrentIndex(self._cfg.getInt(self._cfg.DEFAULT_POPUP_POSITION))

self._ui_refresh_interval = self._cfg.getInt(self._cfg.STATS_REFRESH_INTERVAL, 0)
self.spinUIRefresh.setValue(self._ui_refresh_interval)

self.checkAutostart.setChecked(self._autostart.isEnabled())

maxmsgsize = self._cfg.getSettings(Config.DEFAULT_SERVER_MAX_MESSAGE_LENGTH)
Expand Down Expand Up @@ -581,6 +588,7 @@ def _save_ui_config(self):
if self.checkUIRules.isChecked():
self._nodes.delete_rule_by_field(Config.DURATION_FIELD, Config.RULES_DURATION_FILTER)

self._cfg.setSettings(self._cfg.STATS_REFRESH_INTERVAL, int(self.spinUIRefresh.value()))
self._cfg.setSettings(self._cfg.DEFAULT_ACTION_KEY, self.comboUIAction.currentIndex())
self._cfg.setSettings(self._cfg.DEFAULT_DURATION_KEY, int(self.comboUIDuration.currentIndex()))
self._cfg.setSettings(self._cfg.DEFAULT_TARGET_KEY, self.comboUITarget.currentIndex())
Expand Down
13 changes: 12 additions & 1 deletion ui/opensnitch/dialogs/stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ def __init__(self, parent=None, address=None, db=None, dbname="db", appicon=None
self._rules.updated.connect(self._cb_app_rules_updated)
self._actions = Actions().instance()
self._actions.loadAll()
self._last_update = datetime.datetime.now()

# TODO: allow to display multiples dialogs
self._proc_details_dialog = ProcessDetailsDialog(appicon=appicon)
Expand Down Expand Up @@ -718,6 +719,7 @@ def _configure_buttons_icons(self):
self.TABLES[idx]['cmdCleanStats'].setIcon(clearIcon)

def _load_settings(self):
self._ui_refresh_interval = self._cfg.getInt(Config.STATS_REFRESH_INTERVAL, 0)
dialog_geometry = self._cfg.getSettings(Config.STATS_GEOMETRY)
dialog_last_tab = self._cfg.getSettings(Config.STATS_LAST_TAB)
dialog_general_filter_text = self._cfg.getSettings(Config.STATS_FILTER_TEXT)
Expand Down Expand Up @@ -2517,6 +2519,7 @@ def _get_indetail_filter_query(self, lastQuery, text):

@QtCore.pyqtSlot()
def _on_settings_saved(self):
self._ui_refresh_interval = self._cfg.getInt(Config.STATS_REFRESH_INTERVAL, 0)
self._show_columns()
self.settings_saved.emit()

Expand Down Expand Up @@ -2699,15 +2702,23 @@ def update_interception_status(self, enabled):
else:
self._update_status_label(running=False, text=self.FIREWALL_DISABLED)

def _needs_refresh(self):
diff = datetime.datetime.now() - self._last_update
if diff.seconds < self._ui_refresh_interval:
return False

return True

# launched from a thread
def update(self, is_local=True, stats=None, need_query_update=True):
# lock mandatory when there're multiple clients
with self._lock:
if stats is not None:
self._stats = stats
# do not update any tab if the window is not visible
if self.isVisible() and self.isMinimized() == False:
if self.isVisible() and self.isMinimized() == False and self._needs_refresh():
self._trigger.emit(is_local, need_query_update)
self._last_update = datetime.datetime.now()

def update_status(self):
self.startButton.setDown(self.daemon_connected)
Expand Down
Loading

0 comments on commit 435dffc

Please sign in to comment.