From 1fcef5c966af523a24369d0897e01d8349e9a36e Mon Sep 17 00:00:00 2001 From: Erik Reider <35975961+ErikReider@users.noreply.github.com> Date: Fri, 15 Dec 2023 16:15:48 +0100 Subject: [PATCH] Add app icon above the regular icon (#354) * Add app icon above the regular icon * Fixed linting issues * Tweaked the CSS --- data/style/style.scss | 14 +++++--- src/configSchema.json | 4 +-- src/functions.vala | 24 +++++++------- src/notification/notification.ui | 34 +++++++++++++++---- src/notification/notification.vala | 52 ++++++++++++++++++++++-------- 5 files changed, 91 insertions(+), 37 deletions(-) diff --git a/data/style/style.scss b/data/style/style.scss index 97b409c..f5d9bd1 100644 --- a/data/style/style.scss +++ b/data/style/style.scss @@ -109,19 +109,25 @@ $notification-shadow: 0 0 0 1px rgba(0, 0, 0, 0.3), .notification-content { background: transparent; - $padding: 6px; - padding: $padding; border-radius: $border-radius; + $margin: 8px; .image { /* Notification Primary Image */ -gtk-icon-effect: none; border-radius: 100px; /* Size in px */ - margin: 4px; + margin: $margin; + } + .app-icon { + /* Notification app icon (only visible when the primary image is set) */ + -gtk-icon-effect: none; + -gtk-icon-shadow: 0 1px 4px black; + margin: 6px; } .text-box { - margin: 0 8px; + margin: $margin; + .summary { /* Notification summary/title */ font-size: $font-size-summary; diff --git a/src/configSchema.json b/src/configSchema.json index f5e962a..db5cc52 100644 --- a/src/configSchema.json +++ b/src/configSchema.json @@ -92,7 +92,7 @@ }, "notification-icon-size": { "type": "integer", - "description": "The notification icon size (in pixels)", + "description": "The notification icon size (in pixels). The app icon size is 1/3", "default": 64, "minimum": 16 }, @@ -157,7 +157,7 @@ }, "image-visibility": { "type": "string", - "description": "An explanation about the purpose of this instance.", + "description": "The notification image visibility when no icon is available.", "default": "when-available", "enum": ["always", "when-available", "never"] }, diff --git a/src/functions.vala b/src/functions.vala index bc176cc..c263e4e 100644 --- a/src/functions.vala +++ b/src/functions.vala @@ -14,30 +14,30 @@ namespace SwayNotificationCenter { theme.add_resource_path ("/org/erikreider/swaync/icons"); } - public static void set_image_path (owned string path, - Gtk.Image img, - int icon_size, - int radius, - bool file_exists) { - if ((path.length > 6 && path.slice (0, 7) == "file://") || file_exists) { + public static void set_image_uri (owned string uri, + Gtk.Image img, + int icon_size, + int radius, + bool file_exists) { + const string URI_PREFIX = "file://"; + const uint PREFIX_SIZE = 7; + bool is_uri = (uri.length >= PREFIX_SIZE + && uri.slice (0, PREFIX_SIZE) == URI_PREFIX); + if (is_uri || file_exists) { // Try as a URI (file:// is the only URI schema supported right now) try { - if (!file_exists) path = path.slice (7, path.length); + if (is_uri) uri = uri.slice (PREFIX_SIZE, uri.length); - var pixbuf = new Gdk.Pixbuf.from_file (path); + var pixbuf = new Gdk.Pixbuf.from_file (uri); var surface = scale_round_pixbuf (pixbuf, icon_size, icon_size, img.scale_factor, radius); img.set_from_surface (surface); - return; } catch (Error e) { stderr.printf (e.message + "\n"); } - } else if (Gtk.IconTheme.get_default ().has_icon (path)) { - // Try as a freedesktop.org-compliant icon theme - img.set_from_icon_name (path, Notification.icon_size); } } diff --git a/src/notification/notification.ui b/src/notification/notification.ui index af0e92c..b948f48 100644 --- a/src/notification/notification.ui +++ b/src/notification/notification.ui @@ -60,15 +60,37 @@ True False - + True False + center center - 12 - 6 - + + + True + False + center + 6 + + + + -1 + + + + + True + False + end + end + 6 + + + False diff --git a/src/notification/notification.vala b/src/notification/notification.vala index 87a582e..b4d864c 100644 --- a/src/notification/notification.vala +++ b/src/notification/notification.vala @@ -41,6 +41,8 @@ namespace SwayNotificationCenter { [GtkChild] unowned Gtk.Image img; [GtkChild] + unowned Gtk.Image img_app_icon; + [GtkChild] unowned Gtk.Image body_image; // Inline Reply @@ -652,21 +654,36 @@ namespace SwayNotificationCenter { private void set_icon () { img.clear (); + img.set_visible (true); + img_app_icon.clear (); + img_app_icon.set_visible (true); + + Icon ? app_icon_name = null; + string ? app_icon_uri = null; + if (param.desktop_app_info != null) { + app_icon_name = param.desktop_app_info.get_icon (); + } + if (param.app_icon != null && param.app_icon != "") { + app_icon_uri = param.app_icon; + } var image_visibility = ConfigModel.instance.image_visibility; if (image_visibility == ImageVisibility.NEVER) { img.set_visible (false); + img_app_icon.set_visible (false); return; } img.set_pixel_size (notification_icon_size); img.height_request = notification_icon_size; img.width_request = notification_icon_size; + int app_icon_size = notification_icon_size / 3; + img_app_icon.set_pixel_size (app_icon_size); - var img_path_exists = File.new_for_path ( + var img_path_exists = File.new_for_uri ( param.image_path ?? "").query_exists (); - var app_icon_exists = File.new_for_path ( - param.app_icon ?? "").query_exists (); + var app_icon_exists = File.new_for_uri ( + app_icon_uri ?? "").query_exists (); // Get the image CSS corner radius in pixels int radius = 0; @@ -677,21 +694,17 @@ namespace SwayNotificationCenter { radius = value.get_int (); } + // Set the main image to the provided image if (param.image_data.is_initialized) { Functions.set_image_data (param.image_data, img, notification_icon_size, radius); } else if (param.image_path != null && param.image_path != "" && img_path_exists) { - Functions.set_image_path (param.image_path, img, + Functions.set_image_uri (param.image_path, img, notification_icon_size, radius, img_path_exists); - } else if (param.app_icon != null && param.app_icon != "") { - Functions.set_image_path (param.app_icon, img, - notification_icon_size, - radius, - app_icon_exists); } else if (param.icon_data.is_initialized) { Functions.set_image_data (param.icon_data, img, notification_icon_size, radius); @@ -699,16 +712,29 @@ namespace SwayNotificationCenter { if (img.storage_type == Gtk.ImageType.EMPTY) { // Get the app icon - Icon ? icon = null; - if (param.desktop_app_info != null - && (icon = param.desktop_app_info.get_icon ()) != null) { - img.set_from_gicon (icon, icon_size); + if (app_icon_uri != null) { + Functions.set_image_uri (app_icon_uri, img, + notification_icon_size, + radius, + app_icon_exists); + } else if (app_icon_name != null) { + img.set_from_gicon (app_icon_name, icon_size); } else if (image_visibility == ImageVisibility.ALWAYS) { // Default icon img.set_from_icon_name ("image-missing", icon_size); } else { img.set_visible (false); } + } else { + // We only set the app icon if the main image is set + if (app_icon_uri != null) { + Functions.set_image_uri (app_icon_uri, img_app_icon, + app_icon_size, + 0, + app_icon_exists); + } else if (app_icon_name != null) { + img_app_icon.set_from_gicon (app_icon_name, Gtk.IconSize.INVALID); + } } }