Merge lp:~philip.scott/gala/notifications-app-ids into lp:gala

Proposed by Felipe Escoto
Status: Merged
Merged at revision: 528
Proposed branch: lp:~philip.scott/gala/notifications-app-ids
Merge into: lp:gala
Diff against target: 208 lines (+104/-9)
3 files modified
data/Makefile.am (+3/-1)
data/gala-other.desktop.in (+7/-0)
plugins/notify/NotifyServer.vala (+94/-8)
To merge this branch: bzr merge lp:~philip.scott/gala/notifications-app-ids
Reviewer Review Type Date Requested Status
Gala developers Pending
Review via email: mp+298930@code.launchpad.net

Commit message

NotifyServer: use app_id as key for notification settings, with gala-other.desktop as the fallback

Description of the change

Re-proposal from https://code.launchpad.net/~philip.scott/gala/app_id-as-notifications-key/+merge/295975

Now including a .desktop file to use as a fallback, this .desktop will allow the switchboard plug to control all other notifications from apps that either don't have a .desktop file, or their desktop file does not contain "X-GNOME-UsesNotifications=true"

The only change the switchboard plug now needs is to push "Other" to the bottom since it's being sorted alphabetically atm

https://wiki.gnome.org/HowDoI/GNotification

To post a comment you must log in.
Revision history for this message
Felipe Escoto (philip.scott) wrote :
Revision history for this message
Corentin Noël (tintou) wrote :

NoDisplay=true makes the X-AppStream-Ignore key useless (https://wiki.debian.org/AppStream/Guidelines#line-84)

528. By Felipe Escoto

NotifyServer: use app_id as key for notification settings with gala-other as the fallback

The included .desktop file allows switchboard-plug-notifications to control notifications from applications using the outdated method for sending them

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'data/Makefile.am'
2--- data/Makefile.am 2015-07-15 22:55:10 +0000
3+++ data/Makefile.am 2016-07-14 20:05:17 +0000
4@@ -6,7 +6,7 @@
5 styles_DATA = gala.css texture.png close.png
6
7 applicationsdir = $(datadir)/applications
8-applications_DATA = gala.desktop gala-wayland.desktop gala-multitaskingview.desktop
9+applications_DATA = gala.desktop gala-wayland.desktop gala-other.desktop gala-multitaskingview.desktop
10
11 @INTLTOOL_DESKTOP_RULE@
12
13@@ -25,6 +25,7 @@
14 gala.css \
15 gala.desktop \
16 gala-wayland.desktop \
17+ gala-other.desktop.in \
18 gala-multitaskingview.desktop.in \
19 texture.png \
20 close.png \
21@@ -32,6 +33,7 @@
22 $(NULL)
23
24 CLEANFILES = \
25+ gala-other.desktop \
26 gala-multitaskingview.desktop \
27 gschemas.compiled \
28 org.pantheon.desktop.gala.gschema.xml \
29
30=== added file 'data/gala-other.desktop.in'
31--- data/gala-other.desktop.in 1970-01-01 00:00:00 +0000
32+++ data/gala-other.desktop.in 2016-07-14 20:05:17 +0000
33@@ -0,0 +1,7 @@
34+[Desktop Entry]
35+Type=Application
36+_Name=Other
37+_Comment=Fallback desktop file for notifications from outdated applications.
38+Icon=applications-other
39+NoDisplay=true
40+X-GNOME-UsesNotifications=true
41
42=== modified file 'plugins/notify/NotifyServer.vala'
43--- plugins/notify/NotifyServer.vala 2015-11-16 19:48:30 +0000
44+++ plugins/notify/NotifyServer.vala 2016-07-14 20:05:17 +0000
45@@ -49,6 +49,7 @@
46 {
47 const int DEFAULT_TMEOUT = 4000;
48 const string FALLBACK_ICON = "dialog-information";
49+ const string FALLBACK_APP_ID = "gala-other";
50
51 static Gdk.RGBA? icon_fg_color = null;
52
53@@ -66,6 +67,7 @@
54 DBus? bus_proxy = null;
55 unowned Canberra.Context? ca_context = null;
56 Gee.HashMap<string, Settings> app_settings_cache;
57+ Gee.HashMap<string, AppInfo> app_info_cache;
58
59 public NotifyServer (NotificationStack stack)
60 {
61@@ -91,6 +93,7 @@
62 ca_context.open ();
63
64 app_settings_cache = new Gee.HashMap<string, Settings> ();
65+ app_info_cache = new Gee.HashMap<string, AppInfo> ();
66 }
67
68 public string [] get_capabilities ()
69@@ -115,7 +118,7 @@
70 name = "pantheon-notify";
71 vendor = "elementaryOS";
72 version = "0.1";
73- spec_version = "1.1";
74+ spec_version = "1.2";
75 }
76
77 /**
78@@ -142,13 +145,30 @@
79 throw new DBusError.FAILED ("");
80 }
81
82- public new uint32 notify (string app_name, uint32 replaces_id, string app_icon, string summary,
83+ public new uint32 notify (string app_name, uint32 replaces_id, string app_icon, string summary,
84 string body, string[] actions, HashTable<string, Variant> hints, int32 expire_timeout, BusName sender)
85 {
86- unowned Variant? variant;
87+ unowned Variant? variant = null;
88+
89+ AppInfo? app_info = null;
90+
91+ if ((variant = hints.lookup ("desktop-entry")) != null) {
92+ string desktop_id = variant.get_string ();
93+ if (!desktop_id.has_suffix (".desktop"))
94+ desktop_id += ".desktop";
95+
96+ app_info = new DesktopAppInfo (desktop_id);
97+ } else {
98+ app_info = get_appinfo_from_app_name (app_name);
99+ }
100+
101+ // Get app icon from .desktop as fallback
102+ string icon = app_icon;
103+ if (app_icon == "" && app_info != null)
104+ icon = app_info.get_icon ().to_string ();
105
106 var id = (replaces_id != 0 ? replaces_id : ++id_counter);
107- var pixbuf = get_pixbuf (app_name, app_icon, hints);
108+ var pixbuf = get_pixbuf (app_name, icon, hints);
109 var timeout = (expire_timeout == uint32.MAX ? DEFAULT_TMEOUT : expire_timeout);
110
111 var urgency = NotificationUrgency.NORMAL;
112@@ -169,13 +189,24 @@
113 if (notify_settings.do_not_disturb) {
114 allow_bubble = allow_sound = false;
115 } else {
116- Settings? app_settings = app_settings_cache.get (app_name);
117-
118+ string app_id = "";
119+ bool has_notifications_key = false;
120+
121+ if (app_info != null) {
122+ app_id = app_info.get_id ().replace (".desktop", "");
123+ if (app_info is DesktopAppInfo)
124+ has_notifications_key = ((DesktopAppInfo) app_info).get_boolean ("X-GNOME-UsesNotifications");
125+ }
126+
127+ if (!has_notifications_key)
128+ app_id = FALLBACK_APP_ID;
129+
130+ Settings? app_settings = app_settings_cache.get (app_id);
131 if (app_settings == null) {
132 var schema = SettingsSchemaSource.get_default ().lookup ("org.pantheon.desktop.gala.notifications.application", false);
133 if (schema != null) {
134- app_settings = new Settings.full (schema, null, "/org/pantheon/desktop/gala/notifications/applications/%s/".printf (app_name));
135- app_settings_cache.set (app_name, app_settings);
136+ app_settings = new Settings.full (schema, null, "/org/pantheon/desktop/gala/notifications/applications/%s/".printf (app_id));
137+ app_settings_cache.set (app_id, app_settings);
138 }
139 }
140
141@@ -258,6 +289,8 @@
142 notification.action_invoked.connect (notification_action_invoked_callback);
143 notification.closed.connect (notification_closed_callback);
144 stack.show_notification (notification);
145+ } else {
146+ notification_closed (id, NotificationClosedReason.EXPIRED);
147 }
148
149 #if !VALA_0_26
150@@ -553,5 +586,58 @@
151 {
152 action_invoked (id, action);
153 }
154+
155+ AppInfo? get_appinfo_from_app_name (string app_name)
156+ {
157+ if (app_name.strip () == "")
158+ return null;
159+
160+ AppInfo? app_info = app_info_cache.get (app_name);
161+ if (app_info != null)
162+ return app_info;
163+
164+ foreach (unowned AppInfo info in AppInfo.get_all ()) {
165+ if (info == null || !validate (info, app_name))
166+ continue;
167+
168+ app_info = info;
169+ break;
170+ }
171+
172+ app_info_cache.set (app_name, app_info);
173+
174+ return app_info;
175+ }
176+
177+ static bool validate (AppInfo appinfo, string name)
178+ {
179+ string? app_executable = appinfo.get_executable ();
180+ string? app_name = appinfo.get_name ();
181+ string? app_display_name = appinfo.get_display_name ();
182+
183+ if (app_name == null || app_executable == null || app_display_name == null)
184+ return false;
185+
186+ string token = name.down ().strip ();
187+ string? token_executable = token;
188+ if (!token_executable.has_prefix (Path.DIR_SEPARATOR_S))
189+ token_executable = Environment.find_program_in_path (token_executable);
190+
191+ if (!app_executable.has_prefix (Path.DIR_SEPARATOR_S))
192+ app_executable = Environment.find_program_in_path (app_executable);
193+
194+ string[] args;
195+
196+ try {
197+ Shell.parse_argv (appinfo.get_commandline (), out args);
198+ } catch (ShellError e) {
199+ warning ("%s", e.message);
200+ }
201+
202+ return (app_name.down () == token
203+ || token_executable == app_executable
204+ || args[0] == token
205+ || app_display_name.down ().contains (token));
206+ }
207 }
208 }

Subscribers

People subscribed via source and target branches