From 8f67dbd120dcf963227a5347119e0261d65e5e70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Thu, 13 Jun 2024 15:29:13 +0200 Subject: [PATCH] feedback-led: Allow to prefer flash LEDs over notification LEDs --- data/org.sigxcpu.feedbackd.gschema.xml | 8 ++++ src/fbd-dev-leds.c | 2 +- src/fbd-feedback-led.c | 61 +++++++++++++++++++++----- tests/test-fbd-feedback-led.c | 11 +++-- 4 files changed, 66 insertions(+), 16 deletions(-) diff --git a/data/org.sigxcpu.feedbackd.gschema.xml b/data/org.sigxcpu.feedbackd.gschema.xml index 462e6c7..c70da2a 100644 --- a/data/org.sigxcpu.feedbackd.gschema.xml +++ b/data/org.sigxcpu.feedbackd.gschema.xml @@ -24,6 +24,14 @@ + + false + Prefer camera flash LED over notification LED + + Prefer the (camera) flash LED over other notifiction LEDs. + + + [] List of apps that can override the feedback level diff --git a/src/fbd-dev-leds.c b/src/fbd-dev-leds.c index 0d856e8..467d1f9 100644 --- a/src/fbd-dev-leds.c +++ b/src/fbd-dev-leds.c @@ -28,7 +28,7 @@ * * LED device interface * - * #FbdDevLeds is used to interface with LEDS via sysfs + * #FbdDevLeds is used to interface with all LEDs detected in sysfs * It currently only supports one pattern per led at a time. */ typedef struct _FbdDevLeds { diff --git a/src/fbd-feedback-led.c b/src/fbd-feedback-led.c index f9fd408..b713690 100644 --- a/src/fbd-feedback-led.c +++ b/src/fbd-feedback-led.c @@ -8,6 +8,7 @@ #define G_LOG_DOMAIN "fbd-feedback-led" +#include "fbd.h" #include "fbd-enums.h" #include "fbd-dev-leds.h" #include "fbd-feedback-led.h" @@ -39,6 +40,9 @@ typedef struct _FbdFeedbackLed { guint priority; guint max_brightness; char *color; + gboolean prefer_flash; + + GSettings *settings; } FbdFeedbackLed; G_DEFINE_TYPE (FbdFeedbackLed, fbd_feedback_led, FBD_TYPE_FEEDBACK_BASE) @@ -120,34 +124,52 @@ parse_hex_color (const char *color, FbdLedRgbColor *rgb) static FbdFeedbackLedColor -color_string_to_color (const char *color, FbdLedRgbColor *rgb) +color_string_to_color (const char *color, gboolean prefer_flash, FbdLedRgbColor *rgb) { + FbdFeedbackLedColor type; + g_return_val_if_fail (!gm_str_is_null_or_empty (color), FBD_FEEDBACK_LED_COLOR_WHITE); if (g_strcmp0 (color, "red") == 0) { if (rgb) rgb->r = 255; - return FBD_FEEDBACK_LED_COLOR_RED; + type = FBD_FEEDBACK_LED_COLOR_RED; } else if (g_strcmp0 (color, "green") == 0) { if (rgb) rgb->g = 255; - return FBD_FEEDBACK_LED_COLOR_GREEN; + type = FBD_FEEDBACK_LED_COLOR_GREEN; } else if (g_strcmp0 (color, "blue") == 0) { if (rgb) rgb->b = 255; - return FBD_FEEDBACK_LED_COLOR_BLUE; + type = FBD_FEEDBACK_LED_COLOR_BLUE; } else if (g_strcmp0 (color, "white") == 0) { if (rgb) rgb->r = rgb->g = rgb->b = 255; - return FBD_FEEDBACK_LED_COLOR_WHITE; + type = FBD_FEEDBACK_LED_COLOR_WHITE; } else if (parse_hex_color (color, rgb)) { - return FBD_FEEDBACK_LED_COLOR_RGB; + type = FBD_FEEDBACK_LED_COLOR_RGB; + } else { + g_warning_once ("Can't parse color '%s' using white", color); + if (rgb) + rgb->r = rgb->g = rgb->b = 255; + type = FBD_FEEDBACK_LED_COLOR_WHITE; } - g_warning_once ("Can't parse color '%s' using white", color); - if (rgb) - rgb->r = rgb->g = rgb->b = 255; - return FBD_FEEDBACK_LED_COLOR_WHITE; + /* Override the LED color type at the very end as we want rgb filled + * in so it can be used in case we need to fall back to non flash + * LED */ + if (prefer_flash) + type = FBD_FEEDBACK_LED_COLOR_FLASH; + + return type; +} + + +static void +on_prefer_flash_changed (FbdFeedbackLed *self) +{ + self->prefer_flash = g_settings_get_boolean (self->settings, "prefer-flash"); + g_debug ("Prefer flash: %d", self->prefer_flash); } @@ -219,7 +241,7 @@ fbd_feedback_led_run (FbdFeedbackBase *base) g_return_if_fail (FBD_IS_DEV_LEDS (dev)); g_debug ("Periodic led feedback: max brightness: %d, freq: %d", self->max_brightness, self->frequency); - color = color_string_to_color (self->color, &rgb); + color = color_string_to_color (self->color, self->prefer_flash, &rgb); /* FIXME: handle priority */ fbd_dev_leds_start_periodic (dev, color, @@ -237,7 +259,7 @@ fbd_feedback_led_end (FbdFeedbackBase *base) FbdDevLeds *dev = fbd_feedback_manager_get_dev_leds (manager); FbdFeedbackLedColor color; - color = color_string_to_color (self->color, NULL); + color = color_string_to_color (self->color, self->prefer_flash, NULL); if (dev) fbd_dev_leds_stop (dev, color); fbd_feedback_base_done (FBD_FEEDBACK_BASE (self)); @@ -247,12 +269,18 @@ fbd_feedback_led_end (FbdFeedbackBase *base) static gboolean fbd_feedback_led_is_available (FbdFeedbackBase *base) { + FbdFeedbackLed *self = FBD_FEEDBACK_LED (base); FbdFeedbackManager *manager = fbd_feedback_manager_get_default (); FbdDevLeds *dev = fbd_feedback_manager_get_dev_leds (manager); if (!FBD_IS_DEV_LEDS (dev)) return FALSE; + if (self->prefer_flash && + fbd_dev_leds_has_led (dev, FBD_FEEDBACK_LED_COLOR_FLASH)) { + return TRUE; + } + return fbd_dev_leds_has_led (dev, FBD_FEEDBACK_LED_COLOR_WHITE); } @@ -262,6 +290,7 @@ fbd_feedback_led_finalize (GObject *object) { FbdFeedbackLed *self = FBD_FEEDBACK_LED (object); + g_clear_object (&self->settings); g_clear_pointer (&self->color, g_free); G_OBJECT_CLASS (fbd_feedback_led_parent_class)->finalize (object); @@ -331,4 +360,12 @@ static void fbd_feedback_led_init (FbdFeedbackLed *self) { self->max_brightness = 100; + self->settings = g_settings_new (FEEDBACKD_SCHEMA_ID); + + g_signal_connect_object (self->settings, + "changed::prefer-flash", + G_CALLBACK (on_prefer_flash_changed), + self, + G_CONNECT_SWAPPED); + on_prefer_flash_changed (self); } diff --git a/tests/test-fbd-feedback-led.c b/tests/test-fbd-feedback-led.c index 2b7bb0e..8be5853 100644 --- a/tests/test-fbd-feedback-led.c +++ b/tests/test-fbd-feedback-led.c @@ -38,14 +38,19 @@ test_fbd_feedback_led_color_string_to_color (void) { FbdLedRgbColor rgb = { 0 }; - g_assert_cmpint (color_string_to_color ("red", NULL), ==, FBD_FEEDBACK_LED_COLOR_RED); + g_assert_cmpint (color_string_to_color ("red", FALSE, NULL), ==, FBD_FEEDBACK_LED_COLOR_RED); - g_assert_cmpint (color_string_to_color ("#11aaBB", &rgb), ==, FBD_FEEDBACK_LED_COLOR_RGB); + g_assert_cmpint (color_string_to_color ("#11aaBB", FALSE, &rgb), ==, FBD_FEEDBACK_LED_COLOR_RGB); g_assert_cmpint (rgb.r, ==, 0x11); g_assert_cmpint (rgb.g, ==, 0xaa); g_assert_cmpint (rgb.b, ==, 0xbb); - g_assert_cmpint (color_string_to_color ("#00FF00", &rgb), ==, FBD_FEEDBACK_LED_COLOR_RGB); + g_assert_cmpint (color_string_to_color ("#00FF00", FALSE, &rgb), ==, FBD_FEEDBACK_LED_COLOR_RGB); + g_assert_cmpint (rgb.r, ==, 0x00); + g_assert_cmpint (rgb.g, ==, 0xFF); + g_assert_cmpint (rgb.b, ==, 0x00); + + g_assert_cmpint (color_string_to_color ("#00FF00", TRUE, &rgb), ==, FBD_FEEDBACK_LED_COLOR_FLASH); g_assert_cmpint (rgb.r, ==, 0x00); g_assert_cmpint (rgb.g, ==, 0xFF); g_assert_cmpint (rgb.b, ==, 0x00);