From 2d1d72c746f5d1aa0f80e50bb35ec4d199d5fcba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Tue, 9 Apr 2024 13:22:12 +0200 Subject: [PATCH] feedback-manager: Handle important hint This allows blessed apps to override the per-app as well as the global feedback level. This can e.g. be useful for alarm clocks. --- src/fbd-feedback-manager.c | 45 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/src/fbd-feedback-manager.c b/src/fbd-feedback-manager.c index c484312..0fa7f23 100644 --- a/src/fbd-feedback-manager.c +++ b/src/fbd-feedback-manager.c @@ -26,6 +26,7 @@ #define FEEDBACKD_SCHEMA_ID "org.sigxcpu.feedbackd" #define FEEDBACKD_KEY_PROFILE "profile" #define FEEDBACKD_KEY_THEME "theme" +#define FEEDBACKD_KEY_ALLOW_IMPORTANT "allow-important" #define APP_SCHEMA FEEDBACKD_SCHEMA_ID ".application" #define APP_PREFIX "/org/sigxcpu/feedbackd/application/" @@ -48,6 +49,7 @@ typedef struct _FbdFeedbackManager { FbdFeedbackProfileLevel level; FbdFeedbackTheme *theme; guint next_id; + GStrv allow_important; /* Key: event id, value: event */ GHashTable *events; @@ -225,6 +227,33 @@ on_feedbackd_setting_changed (FbdFeedbackManager *self, } } + +static gboolean +app_is_important (FbdFeedbackManager *self, const char *app_id) +{ + if (!self->allow_important) + return FALSE; + + if (g_strv_contains ((const char *const *)self->allow_important, app_id)) + return TRUE; + + return FALSE; +} + + +static void +on_feedbackd_allow_important_changed (FbdFeedbackManager *self, + const gchar *key, + GSettings *settings) +{ + g_return_if_fail (FBD_IS_FEEDBACK_MANAGER (self)); + g_return_if_fail (G_IS_SETTINGS (settings)); + + g_strfreev (self->allow_important); + self->allow_important = g_settings_get_strv(self->settings, FEEDBACKD_KEY_ALLOW_IMPORTANT); +} + + static void on_client_vanished (GDBusConnection *connection, const gchar *name, @@ -341,7 +370,7 @@ fbd_feedback_manager_handle_trigger_feedback (LfbGdbusFeedback *object, const gchar *sender; FbdFeedbackProfileLevel app_level, level, hint_level = FBD_FEEDBACK_PROFILE_LEVEL_FULL; gboolean found_fb = FALSE; - gboolean hint_important = FALSE; + gboolean hint_important = FALSE, can_important; sender = g_dbus_method_invocation_get_sender (invocation); g_debug ("Event '%s' for '%s' from %s", arg_event, arg_app_id, sender); @@ -381,7 +410,12 @@ fbd_feedback_manager_handle_trigger_feedback (LfbGdbusFeedback *object, g_hash_table_insert (self->events, GUINT_TO_POINTER (event_id), event); app_level = app_get_feedback_level (arg_app_id); - level = get_max_level (self->level, app_level, hint_level); + can_important = app_is_important (self, arg_app_id); + + if (hint_important && can_important) + level = hint_level; + else + level = get_max_level (self->level, app_level, hint_level); feedbacks = fbd_feedback_theme_lookup_feedback (self->theme, level, event); if (feedbacks) { @@ -461,8 +495,13 @@ fbd_feedback_manager_constructed (GObject *object) g_signal_connect_swapped (self->settings, "changed::" FEEDBACKD_KEY_PROFILE, G_CALLBACK (on_feedbackd_setting_changed), self); on_feedbackd_setting_changed (self, FEEDBACKD_KEY_PROFILE, self->settings); + + g_signal_connect_swapped (self->settings, "changed::" FEEDBACKD_KEY_ALLOW_IMPORTANT, + G_CALLBACK (on_feedbackd_allow_important_changed), self); + on_feedbackd_allow_important_changed (self, FEEDBACKD_KEY_ALLOW_IMPORTANT, self->settings); } + static void fbd_feedback_manager_dispose (GObject *object) { @@ -474,6 +513,8 @@ fbd_feedback_manager_dispose (GObject *object) g_clear_object (&self->vibra); g_clear_object (&self->leds); g_clear_object (&self->client); + + g_clear_pointer (&self->allow_important, g_strfreev); g_clear_pointer (&self->events, g_hash_table_destroy); g_clear_pointer (&self->clients, g_hash_table_destroy);