notifications: Add panel
Show applications using the message tray, and allow configuring in what way the shell presents them. The set of applications shown include all applications that ever showed a notification in gnome-shell and all applications that have a boolean X-GNOME-UsesNotifications key set to true in their desktop file. https://bugzilla.gnome.org/show_bug.cgi?id=685928
This commit is contained in:
parent
1af3a03ca3
commit
e8cd35edce
12 changed files with 812 additions and 0 deletions
|
@ -137,6 +137,7 @@ PKG_CHECK_MODULES(MEDIA_PANEL, $COMMON_MODULES)
|
|||
PKG_CHECK_MODULES(MOUSE_PANEL, $COMMON_MODULES xi >= 1.2
|
||||
gnome-settings-daemon >= $GSD_REQUIRED_VERSION x11)
|
||||
PKG_CHECK_MODULES(NETWORK_PANEL, $COMMON_MODULES)
|
||||
PKG_CHECK_MODULES(NOTIFICATIONS_PANEL, $COMMON_MODULES libgnome-menu-3.0)
|
||||
PKG_CHECK_MODULES(ONLINE_ACCOUNTS_PANEL, $COMMON_MODULES goa-1.0 goa-backend-1.0 >= $GOA_REQUIRED_VERSION)
|
||||
PKG_CHECK_MODULES(POWER_PANEL, $COMMON_MODULES upower-glib >= 0.9.1
|
||||
gnome-settings-daemon >= $GSD_REQUIRED_VERSION)
|
||||
|
@ -488,6 +489,8 @@ panels/privacy/Makefile
|
|||
panels/privacy/gnome-privacy-panel.desktop.in
|
||||
panels/network/Makefile
|
||||
panels/network/gnome-network-panel.desktop.in
|
||||
panels/notifications/Makefile
|
||||
panels/notifications/gnome-notifications-panel.desktop.in
|
||||
panels/universal-access/Makefile
|
||||
panels/universal-access/gnome-universal-access-panel.desktop.in
|
||||
panels/user-accounts/Makefile
|
||||
|
|
|
@ -6,6 +6,7 @@ SUBDIRS= \
|
|||
color \
|
||||
display \
|
||||
mouse \
|
||||
notifications \
|
||||
online-accounts \
|
||||
region \
|
||||
info \
|
||||
|
|
32
panels/notifications/Makefile.am
Normal file
32
panels/notifications/Makefile.am
Normal file
|
@ -0,0 +1,32 @@
|
|||
cappletname = notifications
|
||||
|
||||
INCLUDES = \
|
||||
$(PANEL_CFLAGS) \
|
||||
$(NOTIFICATIONS_PANEL_CFLAGS) \
|
||||
-DGNOMECC_UI_DIR="\"$(uidir)\"" \
|
||||
-DGNOMELOCALEDIR="\"$(datadir)/locale\"" \
|
||||
-DGNOMECC_DATA_DIR="\"$(pkgdatadir)\"" \
|
||||
$(NULL)
|
||||
|
||||
noinst_LTLIBRARIES = libnotifications.la
|
||||
|
||||
libnotifications_la_SOURCES = \
|
||||
cc-edit-dialog.c \
|
||||
cc-edit-dialog.h \
|
||||
cc-notifications-panel.c \
|
||||
cc-notifications-panel.h
|
||||
|
||||
libnotifications_la_LIBADD = $(NOTIFICATIONS_PANEL_LIBS) $(PANEL_LIBS)
|
||||
|
||||
uidir = $(pkgdatadir)/ui
|
||||
dist_ui_DATA = notifications.ui
|
||||
|
||||
@INTLTOOL_DESKTOP_RULE@
|
||||
|
||||
desktopdir = $(datadir)/applications
|
||||
desktop_in_files = gnome-notifications-panel.desktop.in
|
||||
desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
|
||||
|
||||
CLEANFILES = $(desktop_in_files) $(desktop_DATA)
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
119
panels/notifications/cc-edit-dialog.c
Normal file
119
panels/notifications/cc-edit-dialog.c
Normal file
|
@ -0,0 +1,119 @@
|
|||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
/*
|
||||
* Copyright (C) 2012 Giovanni Campagna <scampa.giovanni@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <glib/gi18n-lib.h>
|
||||
#include <glib.h>
|
||||
#include <gio/gio.h>
|
||||
#include <gio/gdesktopappinfo.h>
|
||||
|
||||
#include "cc-notifications-panel.h"
|
||||
|
||||
static struct {
|
||||
const char *setting_key;
|
||||
const char *label;
|
||||
gboolean bold;
|
||||
} policy_settings[] = {
|
||||
/* TRANSLATORS: this is the per application switch for message tray usage. */
|
||||
{ "enable", NC_("notifications", "Notifications"), TRUE },
|
||||
/* TRANSLATORS: this is the setting to configure sounds associated with notifications */
|
||||
{ "enable-sound-alerts", NC_("notifications", "Sound Alerts"), FALSE },
|
||||
{ "show-banners", NC_("notifications", "Show Popup Banners"), FALSE },
|
||||
/* TRANSLATORS: banners here refers to message tray notifications in the middle of the screen */
|
||||
{ "force-expanded", NC_("notifications", "Show Details in Banners"), FALSE },
|
||||
{ "show-in-lock-screen", NC_("notifications", "View in Lock Screen"), FALSE },
|
||||
{ "resident-in-lock-screen", NC_("notifications", "Show Details in Lock Screen"), FALSE }
|
||||
};
|
||||
|
||||
void
|
||||
cc_build_edit_dialog (CcNotificationsPanel *panel,
|
||||
GAppInfo *app,
|
||||
GSettings *settings)
|
||||
{
|
||||
GtkWindow *shell;
|
||||
GtkDialog *win;
|
||||
GtkWidget *content_area;
|
||||
GtkGrid *content_grid;
|
||||
int i;
|
||||
|
||||
shell = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (panel)));
|
||||
|
||||
win = GTK_DIALOG (gtk_dialog_new ());
|
||||
g_object_set (win,
|
||||
"modal", TRUE,
|
||||
"title", g_app_info_get_name (app),
|
||||
"width-request", 450,
|
||||
"transient-for", shell,
|
||||
NULL);
|
||||
gtk_dialog_add_button (win, "gtk-close", GTK_RESPONSE_CLOSE);
|
||||
gtk_dialog_set_default_response (win, GTK_RESPONSE_CLOSE);
|
||||
|
||||
content_area = gtk_dialog_get_content_area (win);
|
||||
content_grid = GTK_GRID (gtk_grid_new ());
|
||||
g_object_set (content_grid,
|
||||
"row-spacing", 10,
|
||||
"margin-left", 15,
|
||||
"margin-right", 5,
|
||||
NULL);
|
||||
gtk_container_add (GTK_CONTAINER (content_area), GTK_WIDGET (content_grid));
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (policy_settings); i++)
|
||||
{
|
||||
GtkWidget *label;
|
||||
GtkWidget *_switch;
|
||||
|
||||
label = gtk_label_new (g_dpgettext2 (GETTEXT_PACKAGE,
|
||||
"notifications",
|
||||
policy_settings[i].label));
|
||||
g_object_set (label,
|
||||
"xalign", 0.0,
|
||||
"hexpand", TRUE,
|
||||
NULL);
|
||||
|
||||
if (policy_settings[i].bold)
|
||||
{
|
||||
PangoAttrList *list;
|
||||
PangoAttribute *weight;
|
||||
list = pango_attr_list_new ();
|
||||
weight = pango_attr_weight_new (PANGO_WEIGHT_BOLD);
|
||||
|
||||
pango_attr_list_insert (list, weight);
|
||||
gtk_label_set_attributes (GTK_LABEL (label), list);
|
||||
|
||||
pango_attr_list_unref (list);
|
||||
}
|
||||
|
||||
_switch = gtk_switch_new ();
|
||||
g_settings_bind (settings, policy_settings[i].setting_key,
|
||||
_switch, "active",
|
||||
G_SETTINGS_BIND_DEFAULT);
|
||||
|
||||
gtk_grid_attach (content_grid, GTK_WIDGET (label),
|
||||
0, i, 1, 1);
|
||||
gtk_grid_attach (content_grid, _switch,
|
||||
1, i, 1, 1);
|
||||
}
|
||||
|
||||
g_signal_connect (win, "response", G_CALLBACK (gtk_widget_destroy), NULL);
|
||||
gtk_widget_show_all (GTK_WIDGET (win));
|
||||
}
|
33
panels/notifications/cc-edit-dialog.h
Normal file
33
panels/notifications/cc-edit-dialog.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
/*
|
||||
* Copyright (C) 2012 Giovanni Campagna <scampa.giovanni@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _CC_EDIT_DIALOG_H_
|
||||
#define _CC_EDIT_DIALOG_H_
|
||||
|
||||
#include "cc-notifications-panel.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void cc_build_edit_dialog (CcNotificationsPanel *panel, GAppInfo *app, GSettings *settings);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* _CC_EDIT_DIALOG_H_ */
|
467
panels/notifications/cc-notifications-panel.c
Normal file
467
panels/notifications/cc-notifications-panel.c
Normal file
|
@ -0,0 +1,467 @@
|
|||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
/*
|
||||
* Copyright (C) 2012 Giovanni Campagna <scampa.giovanni@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <glib/gi18n-lib.h>
|
||||
#include <glib.h>
|
||||
#include <gio/gio.h>
|
||||
#include <gio/gdesktopappinfo.h>
|
||||
|
||||
#include <egg-list-box/egg-list-box.h>
|
||||
#include "cc-notifications-panel.h"
|
||||
|
||||
#define MASTER_SCHEMA "org.gnome.desktop.notifications"
|
||||
#define APP_SCHEMA MASTER_SCHEMA ".application"
|
||||
#define APP_PREFIX "/org/gnome/desktop/notifications/application/"
|
||||
|
||||
struct _CcNotificationsPanel {
|
||||
CcPanel parent_instance;
|
||||
|
||||
GSettings *master_settings;
|
||||
GtkBuilder *builder;
|
||||
EggListBox *list_box;
|
||||
|
||||
GCancellable *apps_load_cancellable;
|
||||
|
||||
GHashTable *known_applications;
|
||||
};
|
||||
|
||||
struct _CcNotificationsPanelClass {
|
||||
CcPanelClass parent;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
char *canonical_app_id;
|
||||
GAppInfo *app_info;
|
||||
GSettings *settings;
|
||||
|
||||
/* Temporary pointer, to pass from the loading thread
|
||||
to the app */
|
||||
CcNotificationsPanel *panel;
|
||||
} Application;
|
||||
|
||||
static void application_free (Application *app);
|
||||
static void build_app_store (CcNotificationsPanel *panel);
|
||||
static void select_app (EggListBox *box, GtkWidget *child, CcNotificationsPanel *panel);
|
||||
static int sort_apps (gconstpointer one, gconstpointer two, gpointer user_data);
|
||||
|
||||
CC_PANEL_REGISTER (CcNotificationsPanel, cc_notifications_panel);
|
||||
|
||||
static void
|
||||
cc_notifications_panel_dispose (GObject *object)
|
||||
{
|
||||
CcNotificationsPanel *panel = CC_NOTIFICATIONS_PANEL (object);
|
||||
|
||||
g_clear_object (&panel->builder);
|
||||
g_clear_object (&panel->master_settings);
|
||||
g_clear_pointer (&panel->known_applications, g_hash_table_unref);
|
||||
|
||||
g_cancellable_cancel (panel->apps_load_cancellable);
|
||||
|
||||
G_OBJECT_CLASS (cc_notifications_panel_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_notifications_panel_finalize (GObject *object)
|
||||
{
|
||||
CcNotificationsPanel *panel = CC_NOTIFICATIONS_PANEL (object);
|
||||
|
||||
g_clear_object (&panel->apps_load_cancellable);
|
||||
|
||||
G_OBJECT_CLASS (cc_notifications_panel_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
update_separator_func (GtkWidget **separator,
|
||||
GtkWidget *child,
|
||||
GtkWidget *before,
|
||||
gpointer user_data)
|
||||
{
|
||||
if (*separator == NULL && before != NULL)
|
||||
{
|
||||
*separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
|
||||
|
||||
/* https://bugzilla.gnome.org/show_bug.cgi?id=690545 */
|
||||
g_object_ref_sink (*separator);
|
||||
gtk_widget_show (*separator);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cc_notifications_panel_init (CcNotificationsPanel *panel)
|
||||
{
|
||||
GtkWidget *w;
|
||||
GError *error = NULL;
|
||||
|
||||
panel->known_applications = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
NULL, g_free);
|
||||
|
||||
panel->builder = gtk_builder_new ();
|
||||
if (gtk_builder_add_from_file (panel->builder,
|
||||
GNOMECC_UI_DIR "/notifications.ui",
|
||||
&error) == 0)
|
||||
{
|
||||
g_error ("Error loading UI file: %s", error->message);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
panel->master_settings = g_settings_new (MASTER_SCHEMA);
|
||||
|
||||
g_settings_bind (panel->master_settings, "show-banners",
|
||||
gtk_builder_get_object (panel->builder, "ccnotify-switch-banners"),
|
||||
"active", G_SETTINGS_BIND_DEFAULT);
|
||||
g_settings_bind (panel->master_settings, "show-in-lock-screen",
|
||||
gtk_builder_get_object (panel->builder, "ccnotify-switch-lock-screen"),
|
||||
"active", G_SETTINGS_BIND_DEFAULT);
|
||||
|
||||
panel->list_box = egg_list_box_new ();
|
||||
w = GTK_WIDGET (gtk_builder_get_object (panel->builder,
|
||||
"ccnotify-app-scrolledwindow"));
|
||||
|
||||
egg_list_box_add_to_scrolled (panel->list_box, GTK_SCROLLED_WINDOW (w));
|
||||
egg_list_box_set_selection_mode (panel->list_box, GTK_SELECTION_NONE);
|
||||
egg_list_box_set_sort_func (panel->list_box, sort_apps, NULL, NULL);
|
||||
egg_list_box_set_separator_funcs (panel->list_box,
|
||||
update_separator_func,
|
||||
NULL, NULL);
|
||||
|
||||
g_signal_connect (panel->list_box, "child-activated",
|
||||
G_CALLBACK (select_app), panel);
|
||||
|
||||
gtk_widget_set_visible (GTK_WIDGET (panel->list_box), TRUE);
|
||||
|
||||
build_app_store (panel);
|
||||
|
||||
w = GTK_WIDGET (gtk_builder_get_object (panel->builder,
|
||||
"ccnotify-main-grid"));
|
||||
gtk_widget_reparent (w, GTK_WIDGET (panel));
|
||||
gtk_widget_show (w);
|
||||
}
|
||||
|
||||
static const char *
|
||||
cc_notifications_panel_get_help_uri (CcPanel *panel)
|
||||
{
|
||||
/* TODO */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
cc_notifications_panel_class_init (CcNotificationsPanelClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
CcPanelClass *panel_class = CC_PANEL_CLASS (klass);
|
||||
|
||||
panel_class->get_help_uri = cc_notifications_panel_get_help_uri;
|
||||
|
||||
/* Separate dispose() and finalize() functions are necessary
|
||||
* to make sure we cancel the running thread before the panel
|
||||
* gets finalized */
|
||||
object_class->dispose = cc_notifications_panel_dispose;
|
||||
object_class->finalize = cc_notifications_panel_finalize;
|
||||
}
|
||||
|
||||
static inline GQuark
|
||||
application_quark (void)
|
||||
{
|
||||
static GQuark quark;
|
||||
|
||||
if (G_UNLIKELY (quark == 0))
|
||||
quark = g_quark_from_static_string ("cc-application");
|
||||
|
||||
return quark;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_off_label_mapping_get (GValue *value,
|
||||
GVariant *variant,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_value_set_string (value, g_variant_get_boolean (variant) ? _("On") : _("Off"));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
add_application (CcNotificationsPanel *panel,
|
||||
Application *app)
|
||||
{
|
||||
GtkWidget *box, *w;
|
||||
GIcon *icon;
|
||||
|
||||
icon = g_app_info_get_icon (app->app_info);
|
||||
if (icon == NULL)
|
||||
icon = g_themed_icon_new ("application-x-executable");
|
||||
else
|
||||
g_object_ref (icon);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
|
||||
g_object_set_qdata_full (G_OBJECT (box), application_quark (),
|
||||
app, (GDestroyNotify) application_free);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (panel->list_box), box);
|
||||
|
||||
w = gtk_image_new_from_gicon (icon, GTK_ICON_SIZE_DIALOG);
|
||||
gtk_container_add (GTK_CONTAINER (box), w);
|
||||
g_object_unref (icon);
|
||||
|
||||
w = gtk_label_new (g_app_info_get_name (app->app_info));
|
||||
gtk_container_add (GTK_CONTAINER (box), w);
|
||||
|
||||
w = gtk_label_new ("");
|
||||
g_settings_bind_with_mapping (app->settings, "enable",
|
||||
w, "label",
|
||||
G_SETTINGS_BIND_GET |
|
||||
G_SETTINGS_BIND_NO_SENSITIVITY,
|
||||
on_off_label_mapping_get,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
gtk_widget_set_margin_right (w, 24);
|
||||
gtk_widget_set_valign (w, GTK_ALIGN_CENTER);
|
||||
gtk_box_pack_end (GTK_BOX (box), w, FALSE, FALSE, 0);
|
||||
|
||||
gtk_widget_show_all (box);
|
||||
|
||||
g_hash_table_add (panel->known_applications, g_strdup (app->canonical_app_id));
|
||||
}
|
||||
|
||||
static void
|
||||
maybe_add_app_id (CcNotificationsPanel *panel,
|
||||
const char *canonical_app_id)
|
||||
{
|
||||
Application *app;
|
||||
gchar *path;
|
||||
gchar *full_app_id;
|
||||
GSettings *settings;
|
||||
GAppInfo *app_info;
|
||||
|
||||
if (g_hash_table_contains (panel->known_applications,
|
||||
canonical_app_id))
|
||||
return;
|
||||
|
||||
path = g_strconcat (APP_PREFIX, canonical_app_id, "/", NULL);
|
||||
settings = g_settings_new_with_path (APP_SCHEMA, path);
|
||||
|
||||
full_app_id = g_settings_get_string (settings, "application-id");
|
||||
app_info = G_APP_INFO (g_desktop_app_info_new (full_app_id));
|
||||
|
||||
app = g_slice_new (Application);
|
||||
app->canonical_app_id = g_strdup (canonical_app_id);
|
||||
app->settings = settings;
|
||||
app->app_info = app_info;
|
||||
|
||||
add_application (panel, app);
|
||||
g_free (path);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
queued_app_info (gpointer data)
|
||||
{
|
||||
Application *app;
|
||||
CcNotificationsPanel *panel;
|
||||
|
||||
app = data;
|
||||
panel = app->panel;
|
||||
app->panel = NULL;
|
||||
|
||||
if (g_cancellable_is_cancelled (panel->apps_load_cancellable) ||
|
||||
g_hash_table_contains (panel->known_applications,
|
||||
app->canonical_app_id))
|
||||
{
|
||||
application_free (app);
|
||||
g_object_unref (panel);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_debug ("Processing queued application %s", app->canonical_app_id);
|
||||
|
||||
add_application (panel, app);
|
||||
g_object_unref (panel);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static char *
|
||||
app_info_get_id (GAppInfo *app_info)
|
||||
{
|
||||
const char *desktop_id;
|
||||
char *ret;
|
||||
const char *filename;
|
||||
int l;
|
||||
|
||||
desktop_id = g_app_info_get_id (app_info);
|
||||
if (desktop_id != NULL)
|
||||
{
|
||||
ret = g_strdup (desktop_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
filename = g_desktop_app_info_get_filename (G_DESKTOP_APP_INFO (app_info));
|
||||
ret = g_path_get_basename (filename);
|
||||
}
|
||||
|
||||
if (G_UNLIKELY (g_str_has_suffix (ret, ".desktop") == FALSE))
|
||||
{
|
||||
g_free (ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
l = strlen (desktop_id);
|
||||
*(ret + l - strlen(".desktop")) = '\0';
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
process_app_info (CcNotificationsPanel *panel,
|
||||
GTask *task,
|
||||
GAppInfo *app_info)
|
||||
{
|
||||
Application *app;
|
||||
char *app_id;
|
||||
char *canonical_app_id;
|
||||
char *path;
|
||||
GSettings *settings;
|
||||
GSource *source;
|
||||
|
||||
app_id = app_info_get_id (app_info);
|
||||
canonical_app_id = g_strcanon (app_id,
|
||||
"0123456789"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"-",
|
||||
'-');
|
||||
|
||||
path = g_strconcat (APP_PREFIX, canonical_app_id, "/", NULL);
|
||||
settings = g_settings_new_with_path (APP_SCHEMA, path);
|
||||
|
||||
app = g_slice_new (Application);
|
||||
app->canonical_app_id = canonical_app_id;
|
||||
app->settings = settings;
|
||||
app->app_info = g_object_ref (app_info);
|
||||
app->panel = g_object_ref (panel);
|
||||
|
||||
source = g_idle_source_new ();
|
||||
g_source_set_callback (source, queued_app_info, app, NULL);
|
||||
g_source_attach (source, g_task_get_context (task));
|
||||
|
||||
g_free (path);
|
||||
}
|
||||
|
||||
static void
|
||||
load_apps_thread (GTask *task,
|
||||
gpointer panel,
|
||||
gpointer task_data,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
GList *iter, *apps;
|
||||
|
||||
apps = g_app_info_get_all ();
|
||||
|
||||
for (iter = apps; iter && !g_cancellable_is_cancelled (cancellable); iter = iter->next)
|
||||
{
|
||||
GDesktopAppInfo *app;
|
||||
|
||||
app = iter->data;
|
||||
if (g_desktop_app_info_get_boolean (app, "X-GNOME-UsesNotifications"))
|
||||
process_app_info (panel, task, G_APP_INFO (app));
|
||||
}
|
||||
|
||||
g_list_free_full (apps, g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
load_apps_async (CcNotificationsPanel *panel)
|
||||
{
|
||||
GTask *task;
|
||||
|
||||
panel->apps_load_cancellable = g_cancellable_new ();
|
||||
task = g_task_new (panel, panel->apps_load_cancellable, NULL, NULL);
|
||||
g_task_run_in_thread (task, load_apps_thread);
|
||||
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void
|
||||
children_changed (GSettings *settings,
|
||||
const char *key,
|
||||
CcNotificationsPanel *panel)
|
||||
{
|
||||
int i;
|
||||
const gchar **new_app_ids;
|
||||
|
||||
g_settings_get (panel->master_settings,
|
||||
"application-children",
|
||||
"^a&s", &new_app_ids);
|
||||
for (i = 0; new_app_ids[i]; i++)
|
||||
maybe_add_app_id (panel, new_app_ids[i]);
|
||||
|
||||
g_free (new_app_ids);
|
||||
}
|
||||
|
||||
static void
|
||||
build_app_store (CcNotificationsPanel *panel)
|
||||
{
|
||||
/* Build application entries for known applications */
|
||||
children_changed (panel->master_settings, NULL, panel);
|
||||
g_signal_connect (panel->master_settings, "changed::application-children",
|
||||
G_CALLBACK (children_changed), panel);
|
||||
|
||||
/* Scan applications that statically declare to show notifications */
|
||||
load_apps_async (panel);
|
||||
}
|
||||
|
||||
static void
|
||||
select_app (EggListBox *list_box,
|
||||
GtkWidget *child,
|
||||
CcNotificationsPanel *panel)
|
||||
{
|
||||
Application *app;
|
||||
|
||||
app = g_object_get_qdata (G_OBJECT (child), application_quark ());
|
||||
cc_build_edit_dialog (panel, app->app_info, app->settings);
|
||||
}
|
||||
|
||||
static void
|
||||
application_free (Application *app)
|
||||
{
|
||||
g_free (app->canonical_app_id);
|
||||
g_object_unref (app->app_info);
|
||||
g_object_unref (app->settings);
|
||||
|
||||
g_slice_free (Application, app);
|
||||
}
|
||||
|
||||
static int
|
||||
sort_apps (gconstpointer one,
|
||||
gconstpointer two,
|
||||
gpointer user_data)
|
||||
{
|
||||
Application *a1, *a2;
|
||||
|
||||
a1 = g_object_get_qdata (G_OBJECT (one), application_quark ());
|
||||
a2 = g_object_get_qdata (G_OBJECT (two), application_quark ());
|
||||
|
||||
return g_utf8_collate (g_app_info_get_name (a1->app_info),
|
||||
g_app_info_get_name (a2->app_info));
|
||||
}
|
41
panels/notifications/cc-notifications-panel.h
Normal file
41
panels/notifications/cc-notifications-panel.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
/*
|
||||
* Copyright (C) 2012 Giovanni Campagna <scampa.giovanni@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _CC_NOTIFICATIONS_PANEL_H_
|
||||
#define _CC_NOTIFICATIONS_PANEL_H_
|
||||
|
||||
#include <gio/gio.h>
|
||||
#include <shell/cc-panel.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CC_TYPE_NOTIFICATIONS_PANEL (cc_notifications_panel_get_type ())
|
||||
#define CC_NOTIFICATIONS_PANEL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CC_TYPE_NOTIFICATIONS_PANEL, CcNotificationsPanel))
|
||||
#define GC_IS_NOTIFICATIONS_PANEL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CC_TYPE_NOTIFICATIONS_PANEL))
|
||||
|
||||
typedef struct _CcNotificationsPanel CcNotificationsPanel;
|
||||
typedef struct _CcNotificationsPanelClass CcNotificationsPanelClass;
|
||||
|
||||
GType cc_notifications_panel_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* _CC_EDIT_DIALOG_H_ */
|
17
panels/notifications/gnome-notifications-panel.desktop.in.in
Normal file
17
panels/notifications/gnome-notifications-panel.desktop.in.in
Normal file
|
@ -0,0 +1,17 @@
|
|||
[Desktop Entry]
|
||||
_Name=Notifications
|
||||
_Comment=Manage notifications
|
||||
Exec=gnome-control-center notifications
|
||||
Icon=preferences-system-notifications
|
||||
Terminal=false
|
||||
Type=Application
|
||||
StartupNotify=true
|
||||
Categories=GNOME;GTK;Settings;DesktopSettings;X-GNOME-Settings-Panel;X-GNOME-PersonalSettings;
|
||||
OnlyShowIn=GNOME;Unity;
|
||||
X-GNOME-Bugzilla-Bugzilla=GNOME
|
||||
X-GNOME-Bugzilla-Product=gnome-control-center
|
||||
X-GNOME-Bugzilla-Component=Notifications
|
||||
X-GNOME-Bugzilla-Version=@VERSION@
|
||||
X-GNOME-Settings-Panel=notifications
|
||||
# Translators: those are keywords for the notifications control-center panel
|
||||
_Keywords=Notifications;Banner;Message;Tray;Popup;
|
92
panels/notifications/notifications.ui
Normal file
92
panels/notifications/notifications.ui
Normal file
|
@ -0,0 +1,92 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkWindow" id="ccnotify-main-window">
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkGrid" id="ccnotify-main-grid">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">12</property>
|
||||
<property name="margin_right">12</property>
|
||||
<property name="margin_top">12</property>
|
||||
<property name="margin_bottom">12</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="row_spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="ccnotify-label-banners">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Show Pop Up Banners</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="ccnotify-label-lock-screen">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Show in Lock Screen</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="ccnotify-switch-banners">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="ccnotify-switch-lock-screen">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="ccnotify-app-scrolledwindow">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<property name="hscrollbar_policy">never</property>
|
||||
<property name="height-request">250</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="width">2</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
|
@ -58,6 +58,10 @@ panels/network/net-vpn.c
|
|||
[type: gettext/glade]panels/network/network-vpn.ui
|
||||
[type: gettext/glade]panels/network/network-wifi.ui
|
||||
panels/network/panel-common.c
|
||||
panels/notifications/cc-edit-dialog.c
|
||||
panels/notifications/cc-notifications-panel.c
|
||||
panels/notifications/gnome-notifications-panel.desktop.in.in
|
||||
[type: gettext/glade] panels/notifications/notifications.ui
|
||||
panels/online-accounts/cc-online-accounts-add-account-dialog.c
|
||||
panels/online-accounts/cc-online-accounts-panel.c
|
||||
panels/online-accounts/gnome-online-accounts-panel.desktop.in.in
|
||||
|
|
|
@ -39,6 +39,7 @@ gnome_control_center_LDADD = \
|
|||
$(top_builddir)/panels/info/libinfo.la \
|
||||
$(top_builddir)/panels/keyboard/libkeyboard.la \
|
||||
$(top_builddir)/panels/mouse/libmouse-properties.la \
|
||||
$(top_builddir)/panels/notifications/libnotifications.la \
|
||||
$(top_builddir)/panels/online-accounts/libonline-accounts.la \
|
||||
$(top_builddir)/panels/power/libpower.la \
|
||||
$(top_builddir)/panels/privacy/libprivacy.la \
|
||||
|
|
|
@ -40,6 +40,7 @@ extern GType cc_mouse_panel_get_type (void);
|
|||
#ifdef BUILD_NETWORK
|
||||
extern GType cc_network_panel_get_type (void);
|
||||
#endif /* BUILD_NETWORK */
|
||||
extern GType cc_notifications_panel_get_type (void);
|
||||
extern GType cc_goa_panel_get_type (void);
|
||||
extern GType cc_power_panel_get_type (void);
|
||||
#ifdef BUILD_PRINTERS
|
||||
|
@ -73,6 +74,7 @@ static struct {
|
|||
#ifdef BUILD_NETWORK
|
||||
{ "network", cc_network_panel_get_type },
|
||||
#endif
|
||||
{ "notifications", cc_notifications_panel_get_type },
|
||||
{ "online-accounts", cc_goa_panel_get_type },
|
||||
{ "power", cc_power_panel_get_type },
|
||||
#ifdef BUILD_PRINTERS
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue