From 673d5df9fd343140e6700f7547ac951487fb0a65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Tue, 9 Apr 2024 13:22:06 +0200 Subject: [PATCH 01/12] packaging: Add libgirepository1.0-dev --- debian/control | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/debian/control b/debian/control index 100e5ad..6bb67a4 100644 --- a/debian/control +++ b/debian/control @@ -8,8 +8,9 @@ Build-Depends: dh-sequence-gir, gsettings-desktop-schemas , gi-docgen , + gir1.2-gio-2.0-dev , json-glib-tools, - libgirepository1.0-dev, + libgirepository1.0-dev , libglib2.0-dev, libgudev-1.0-dev, libgsound-dev, From bf52369e68a72df6ffdaab5b66800f0dff566099 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Tue, 9 Apr 2024 13:22:06 +0200 Subject: [PATCH 02/12] README: Note what's the preferred way to specify a theme --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6b915e8..83912f8 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,8 @@ You can add your own themes in multiple ways: gsettings reset org.sigxcpu.feedbackd theme Note that you can name your theme as you wish but avoid theme names - starting with `__` or `$` as this namespace is reserved. + starting with `__` or `$` as this namespace is reserved. This is the + preferred way to specify a custom theme. 4. By adding your theme file to one of the folders in the `XDG_DATA_DIRS` environment variable, appended with `feedbackd/themes/`. This folder isn't From d73677dfffc3eb2c0ea82a3e15f671871bf48057 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Tue, 9 Apr 2024 13:22:07 +0200 Subject: [PATCH 03/12] build: Validate schema file --- data/meson.build | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/data/meson.build b/data/meson.build index 762b0e6..0c8590f 100644 --- a/data/meson.build +++ b/data/meson.build @@ -24,6 +24,12 @@ compiled = gnome.compile_schemas( build_by_default: true ) +compile_schemas = find_program('glib-compile-schemas', required: false) +if compile_schemas.found() + test('Validate schema file', compile_schemas, + args: ['--strict', '--dry-run', meson.current_source_dir()]) +endif + install_data( schemas, install_dir: 'share/glib-2.0/schemas' From 106663e41cbafe77eef033a278bf069b072b6c19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Tue, 9 Apr 2024 13:22:08 +0200 Subject: [PATCH 04/12] data/dbus: Document current flags --- data/org.sigxcpu.Feedback.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/data/org.sigxcpu.Feedback.xml b/data/org.sigxcpu.Feedback.xml index 652f175..84c2cef 100644 --- a/data/org.sigxcpu.Feedback.xml +++ b/data/org.sigxcpu.Feedback.xml @@ -20,7 +20,8 @@ TriggerFeedback: @app_id: The application id usually in "reverse DNS" format @event: The event name from the Event naming spec - @hints: Additional hints (e.g. to prefer haptic feedback over audio feedback on button press events) + @hints: Additional hints. Currently known hints + - profile: Override the profile used for this event with the given profile name @timeout: When the feedbacks for this event should end latest in seconds. The special values '-1' (just run each feedback once) and '0' (endless loop) are also supported. @id: Event id for future reference From f71ece5d8b8b953e0e0955315b7148ff4836452d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Tue, 9 Apr 2024 13:22:08 +0200 Subject: [PATCH 05/12] data/dbus: Document important hint The important hint can be used by apps to override the current per app or system wide feedback level (if the feedback server allows it). --- data/org.sigxcpu.Feedback.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/data/org.sigxcpu.Feedback.xml b/data/org.sigxcpu.Feedback.xml index 84c2cef..987ffde 100644 --- a/data/org.sigxcpu.Feedback.xml +++ b/data/org.sigxcpu.Feedback.xml @@ -22,6 +22,10 @@ @event: The event name from the Event naming spec @hints: Additional hints. Currently known hints - profile: Override the profile used for this event with the given profile name + - important: Override the current global feedback level. + Together with the 'profile' hint this allows to trigger feedback for events + that would otherwise be disabled. A typical use case is an alarm clock. Note + that the feedback daemon (depending on it's configuration) might ignore this flag. @timeout: When the feedbacks for this event should end latest in seconds. The special values '-1' (just run each feedback once) and '0' (endless loop) are also supported. @id: Event id for future reference From 7640a73e82de621eb4dd283f18dac1469bcaa2a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Tue, 9 Apr 2024 13:22:09 +0200 Subject: [PATCH 06/12] data/schema: Add 'allow-override' gsetting This allows to list apps that can override the currently effective feedback level by setting the 'impotant' hint in the event. --- data/org.sigxcpu.feedbackd.gschema.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/data/org.sigxcpu.feedbackd.gschema.xml b/data/org.sigxcpu.feedbackd.gschema.xml index 723f8c1..462e6c7 100644 --- a/data/org.sigxcpu.feedbackd.gschema.xml +++ b/data/org.sigxcpu.feedbackd.gschema.xml @@ -23,6 +23,15 @@ feedbackd receives an event. + + + [] + List of apps that can override the feedback level + + Apps listed here can override the configured feedack level by + setting the 'important' hint on the submitted event. + + From 6a5d558a837c4a147a090e16c585f9fb6a3fd61c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Tue, 9 Apr 2024 13:22:09 +0200 Subject: [PATCH 07/12] fbcli: Allow to override app-id Useful for testing --- cli/fbcli.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/cli/fbcli.c b/cli/fbcli.c index 89571e5..a6dc3f8 100644 --- a/cli/fbcli.c +++ b/cli/fbcli.c @@ -130,7 +130,8 @@ main (int argc, char *argv[0]) { g_autoptr(GOptionContext) opt_context = NULL; g_autoptr(GError) err = NULL; - g_autofree gchar *profile = NULL; + g_autofree char *profile = NULL; + g_autofree char *app_id = NULL; const char *name = NULL; gboolean success; int watch = 30; @@ -144,6 +145,8 @@ main (int argc, char *argv[0]) "Profile name to set", NULL}, {"watch", 'w', 0, G_OPTION_ARG_INT, &watch, "How long to watch for feedback longest", NULL}, + {"app-id", 'A', 0, G_OPTION_ARG_STRING, &app_id, + "Override used application id"}, { NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL } }; @@ -155,7 +158,10 @@ main (int argc, char *argv[0]) return 1; } - if (!lfb_init ("org.sigxcpu.fbcli", &err)) { + if (!app_id) + app_id = g_strdup ("org.sigxcpu.fbcli"); + + if (!lfb_init (app_id, &err)) { g_print ("Failed to init libfeedback: %s\n", err->message); return 1; } From e6845a52d3ad1bcedca34ea05fbf64ae1c0e625b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Tue, 9 Apr 2024 13:22:10 +0200 Subject: [PATCH 08/12] feedback-manager: Use MIN() A bit easier to read --- src/fbd-feedback-manager.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/fbd-feedback-manager.c b/src/fbd-feedback-manager.c index b6681e2..0866751 100644 --- a/src/fbd-feedback-manager.c +++ b/src/fbd-feedback-manager.c @@ -298,9 +298,11 @@ get_max_level (FbdFeedbackProfileLevel global_level, { FbdFeedbackProfileLevel level; - /* Individual events and apps can select lower levels than the global level but not higher ones */ - level = global_level > app_level ? app_level : global_level; - level = level > event_level ? event_level : level; + /* Per app configuration can only select a *lower* feedback level */ + level = MIN (global_level, app_level); + /* A hint in an event can only select a *lower* feedback level */ + level = MIN (level, event_level); + return level; } From 14ffd9722dd73f6d7ee9d68ffbe6c412f77c42e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Tue, 9 Apr 2024 13:22:11 +0200 Subject: [PATCH 09/12] libfeedback: Allow to set important hint --- debian/libfeedback-0.0-0.symbols | 2 ++ libfeedback/lfb-event.c | 62 ++++++++++++++++++++++++++++++++ libfeedback/lfb-event.h | 3 ++ tests/test-lfb-event.c | 3 ++ tests/test-lfb-integration.c | 1 + 5 files changed, 71 insertions(+) diff --git a/debian/libfeedback-0.0-0.symbols b/debian/libfeedback-0.0-0.symbols index 114ab85..d67a7af 100644 --- a/debian/libfeedback-0.0-0.symbols +++ b/debian/libfeedback-0.0-0.symbols @@ -9,12 +9,14 @@ libfeedback-0.0.so.0 libfeedback-0.0-0 #MINVER# lfb_event_get_end_reason@LIBFEEDBACK_0_0_0 0.1.1 lfb_event_get_event@LIBFEEDBACK_0_0_0 0.1.1 lfb_event_get_feedback_profile@LIBFEEDBACK_0_0_0 0.1.1 + lfb_event_get_important@LIBFEEDBACK_0_0_0 0.2.1 lfb_event_get_state@LIBFEEDBACK_0_0_0 0.1.1 lfb_event_get_timeout@LIBFEEDBACK_0_0_0 0.1.1 lfb_event_get_type@LIBFEEDBACK_0_0_0 0.1.1 lfb_event_new@LIBFEEDBACK_0_0_0 0.1.1 lfb_event_set_app_id@LIBFEEDBACK_0_0_0 0.2.0 lfb_event_set_feedback_profile@LIBFEEDBACK_0_0_0 0.1.1 + lfb_event_set_important@LIBFEEDBACK_0_0_0 0.2.1 lfb_event_set_timeout@LIBFEEDBACK_0_0_0 0.1.1 lfb_event_state_get_type@LIBFEEDBACK_0_0_0 0.1.1 lfb_event_trigger_feedback@LIBFEEDBACK_0_0_0 0.1.1 diff --git a/libfeedback/lfb-event.c b/libfeedback/lfb-event.c index 3fdf78a..20a6556 100644 --- a/libfeedback/lfb-event.c +++ b/libfeedback/lfb-event.c @@ -79,6 +79,7 @@ enum { PROP_STATE, PROP_END_REASON, PROP_FEEDBACK_PROFILE, + PROP_IMPORTANT, PROP_APP_ID, PROP_LAST_PROP, }; @@ -96,6 +97,7 @@ typedef struct _LfbEvent { char *event; gint timeout; gchar *profile; + gboolean important; char *app_id; guint id; @@ -139,6 +141,8 @@ build_hints (LfbEvent *self) g_variant_builder_init (&hints_builder, G_VARIANT_TYPE ("a{sv}")); if (self->profile) g_variant_builder_add (&hints_builder, "{sv}", "profile", g_variant_new_string (self->profile)); + if (self->important) + g_variant_builder_add (&hints_builder, "{sv}", "important", g_variant_new_boolean (self->important)); return g_variant_builder_end (&hints_builder); } @@ -223,6 +227,9 @@ lfb_event_set_property (GObject *object, case PROP_FEEDBACK_PROFILE: lfb_event_set_feedback_profile (self, g_value_get_string (value)); break; + case PROP_IMPORTANT: + lfb_event_set_important (self, g_value_get_boolean (value)); + break; case PROP_APP_ID: lfb_event_set_app_id (self, g_value_get_string (value)); break; @@ -251,6 +258,9 @@ lfb_event_get_property (GObject *object, case PROP_FEEDBACK_PROFILE: g_value_set_string (value, lfb_event_get_feedback_profile (self)); break; + case PROP_IMPORTANT: + g_value_set_boolean (value, lfb_event_get_important (self)); + break; case PROP_APP_ID: g_value_set_string (value, lfb_event_get_app_id (self)); break; @@ -345,6 +355,20 @@ lfb_event_class_init (LfbEventClass *klass) NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY); + /** + * LfbEvent:important: + * + * Whether to flag this event as important. + * [method@LfbEvent.set_imporant] for details. + */ + props[PROP_IMPORTANT] = + g_param_spec_boolean ( + "important", + "Important", + "Whether to flags this event as important", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY); + /** * LfbEvent:app-id: * @@ -757,6 +781,44 @@ lfb_event_get_feedback_profile (LfbEvent *self) return self->profile; } +/** + * lfb_event_set_important: + * @self: The event + * @important: Whether to flag this event as important + * + * Tells the feedback server that the sender deems this to be an + * important event. A feedback server might allow the sender to + * override the current feedback level when this is set. + */ +void +lfb_event_set_important (LfbEvent *self, gboolean important) +{ + g_return_if_fail (LFB_IS_EVENT (self)); + + if (self->important == important) + return; + + self->important = important; + g_object_notify_by_pspec (G_OBJECT (self), props[PROP_IMPORTANT]); +} + +/** + * lfb_event_get_important: + * @self: The event + * + * Gets the set feedback profile. If no profile was set it returns + * %NULL. The event uses the system wide profile in this case. + * + * Returns: The set feedback profile to use for this event or %NULL. + */ +gboolean +lfb_event_get_important (LfbEvent *self) +{ + g_return_val_if_fail (LFB_IS_EVENT (self), FALSE); + + return self->important; +} + /** * lfb_event_set_app_id: * @self: The event diff --git a/libfeedback/lfb-event.h b/libfeedback/lfb-event.h index 6437c60..c4c66cf 100644 --- a/libfeedback/lfb-event.h +++ b/libfeedback/lfb-event.h @@ -75,9 +75,12 @@ void lfb_event_set_timeout (LfbEvent *self, gint timeout); gint lfb_event_get_timeout (LfbEvent *self); void lfb_event_set_feedback_profile (LfbEvent *self, const char *profile); const char *lfb_event_get_feedback_profile (LfbEvent *self); +void lfb_event_set_important (LfbEvent *self, gboolean important); +gboolean lfb_event_get_important (LfbEvent *self); void lfb_event_set_app_id (LfbEvent *self, const char *app_id); const char *lfb_event_get_app_id (LfbEvent *self); const char *lfb_event_get_event (LfbEvent *self); + LfbEventState lfb_event_get_state (LfbEvent *self); LfbEventEndReason lfb_event_get_end_reason (LfbEvent *self); diff --git a/tests/test-lfb-event.c b/tests/test-lfb-event.c index d52b9fb..f59237f 100644 --- a/tests/test-lfb-event.c +++ b/tests/test-lfb-event.c @@ -15,6 +15,7 @@ test_lfb_event_props (void) g_autofree gchar *evname = NULL; g_autofree gchar *profile = NULL; g_autofree gchar *app_id = NULL; + gboolean important; gint timeout; g_assert_true (lfb_init (TEST_APP_ID, NULL)); @@ -27,10 +28,12 @@ test_lfb_event_props (void) "timeout", &timeout, "feedback-profile", &profile, "app-id", &app_id, + "important", &important, NULL); g_assert_cmpstr (evname, ==, "window-close"); g_assert_cmpint (timeout, ==, -1); g_assert_null (profile); + g_assert_false (important); g_assert_null (app_id); g_assert_cmpint (lfb_event_get_end_reason (event), ==, LFB_EVENT_END_REASON_NATURAL); diff --git a/tests/test-lfb-integration.c b/tests/test-lfb-integration.c index 48b39b3..74ebcf7 100644 --- a/tests/test-lfb-integration.c +++ b/tests/test-lfb-integration.c @@ -238,6 +238,7 @@ test_lfb_integration_event_async (void) lfb_event_set_timeout (event10, 1); g_assert_cmpint (lfb_event_get_timeout (event10), ==, 1); lfb_event_set_feedback_profile (event10, "quiet"); + lfb_event_set_important (event10, FALSE); g_signal_connect (event10, "feedback-ended", (GCallback)on_feedback_ended, &cmp1); /* The async callback ends the main loop */ From 716f296ab88b0e00da3cda0b82ae701dc5bd5fc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Tue, 9 Apr 2024 13:22:11 +0200 Subject: [PATCH 10/12] feedback-manager: Parse important hint --- src/fbd-feedback-manager.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/fbd-feedback-manager.c b/src/fbd-feedback-manager.c index 0866751..c484312 100644 --- a/src/fbd-feedback-manager.c +++ b/src/fbd-feedback-manager.c @@ -307,17 +307,22 @@ get_max_level (FbdFeedbackProfileLevel global_level, } static gboolean -parse_hints (GVariant *hints, FbdFeedbackProfileLevel *level) +parse_hints (GVariant *hints, FbdFeedbackProfileLevel *level, gboolean *hint_important) { const gchar *profile; - gboolean found; + gboolean found, important; g_auto (GVariantDict) dict = G_VARIANT_DICT_INIT (NULL); g_variant_dict_init (&dict, hints); - found = g_variant_dict_lookup (&dict, "profile", "&s", &profile); + found = g_variant_dict_lookup (&dict, "profile", "&s", &profile); if (level && found) *level = fbd_feedback_profile_level (profile); + + found = g_variant_dict_lookup (&dict, "important", "b", &important); + if (hint_important && found) + *hint_important = important; + return TRUE; } @@ -336,6 +341,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; sender = g_dbus_method_invocation_get_sender (invocation); g_debug ("Event '%s' for '%s' from %s", arg_event, arg_app_id, sender); @@ -359,7 +365,7 @@ fbd_feedback_manager_handle_trigger_feedback (LfbGdbusFeedback *object, return TRUE; } - if (!parse_hints (arg_hints, &hint_level)) { + if (!parse_hints (arg_hints, &hint_level, &hint_important)) { g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "Invalid hints"); From f575d326515472e03a594501388ba066be7b62e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Mon, 15 Apr 2024 12:28:57 +0200 Subject: [PATCH 11/12] cli: Allow to set important hint --- cli/fbcli.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/cli/fbcli.c b/cli/fbcli.c index a6dc3f8..ca7cf79 100644 --- a/cli/fbcli.c +++ b/cli/fbcli.c @@ -1,5 +1,7 @@ /* * Copyright (C) 2020 Purism SPC + * 2023-2024 The Phosh Developers + * * SPDX-License-Identifier: GPL-3.0+ * Author: Guido Günther */ @@ -58,7 +60,7 @@ on_user_input (GIOChannel *channel, GIOCondition cond, LfbEvent *event) } static gboolean -trigger_event (const char *name, const gchar *profile, gint timeout) +trigger_event (const char *name, const gchar *profile, gboolean important, gint timeout) { g_autoptr(GError) err = NULL; g_autoptr(LfbEvent) event = NULL; @@ -74,6 +76,9 @@ trigger_event (const char *name, const gchar *profile, gint timeout) if (profile) lfb_event_set_feedback_profile (event, profile); + if (important) + lfb_event_set_important (event, TRUE); + g_signal_connect (event, "feedback-ended", (GCallback)on_feedback_ended, &success); if (!lfb_event_trigger_feedback (event, &err)) { g_print ("Failed to report event: %s\n", err->message); @@ -133,12 +138,14 @@ main (int argc, char *argv[0]) g_autofree char *profile = NULL; g_autofree char *app_id = NULL; const char *name = NULL; - gboolean success; + gboolean success, important = FALSE; int watch = 30; int timeout = -1; const GOptionEntry options [] = { {"event", 'E', 0, G_OPTION_ARG_STRING, &name, "Event name. (default: " DEFAULT_EVENT ").", NULL}, + {"important", 'I', 0, G_OPTION_ARG_NONE, &important, + "Whether to set the important hint", NULL}, {"timeout", 't', 0, G_OPTION_ARG_INT, &timeout, "Run feedback for timeout seconds", NULL}, {"profile", 'P', 0, G_OPTION_ARG_STRING, &profile, @@ -173,7 +180,7 @@ main (int argc, char *argv[0]) name = g_strdup (DEFAULT_EVENT); g_timeout_add_seconds (watch, (GSourceFunc)on_watch_expired, NULL); - success = trigger_event (name, profile, timeout); + success = trigger_event (name, profile, important, timeout); } lfb_uninit (); 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 12/12] 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);