[Xfce4-commits] [apps/xfce4-notifyd] 01/06: Add do-not-disturb mode and per-application settings

noreply at xfce.org noreply at xfce.org
Mon Oct 3 23:34:19 CEST 2016


This is an automated email from the git hooks/post-receive script.

ochosi pushed a commit to branch master
in repository apps/xfce4-notifyd.

commit 546b583dfc7e6677986f3c69c6605704ef05cf74
Author: Simon Steinbeiss <simon.steinbeiss at elfenbeinturm.at>
Date:   Wed Aug 24 20:31:15 2016 +0200

    Add do-not-disturb mode and per-application settings
---
 xfce4-notifyd-config/main.c                     | 171 +++++++++++-
 xfce4-notifyd-config/xfce4-notifyd-config.glade | 353 ++++++++++++++++--------
 xfce4-notifyd/xfce-notify-daemon.c              | 123 ++++++++-
 xfce4-notifyd/xfce-notify-window.c              |   2 +-
 4 files changed, 517 insertions(+), 132 deletions(-)

diff --git a/xfce4-notifyd-config/main.c b/xfce4-notifyd-config/main.c
index 38ad7e0..d9b3130 100644
--- a/xfce4-notifyd-config/main.c
+++ b/xfce4-notifyd-config/main.c
@@ -241,6 +241,110 @@ xfce_notifyd_config_preview_clicked(GtkButton *button,
     xfce_notifyd_config_show_notification_preview(GTK_WINDOW(dialog));
 }
 
+/* Shows a separator before each row. */
+static void
+display_header_func (GtkListBoxRow *row,
+                     GtkListBoxRow *before,
+                     gpointer       user_data)
+{
+  if (before != NULL)
+    {
+      GtkWidget *header = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
+      gtk_widget_show (header);
+
+      gtk_list_box_row_set_header (row, header);
+    }
+}
+
+static void
+xfce4_notifyd_mute_application (GtkListBox *known_applications_listbox,
+                                GtkListBoxRow *selected_application_row,
+                                XfconfChannel *channel)
+{
+
+    GtkWidget *application_box;
+    GtkWidget *application_label;
+    GtkWidget *mute_switch;
+    gboolean muted;
+    GPtrArray *muted_applications;
+    GPtrArray *new_array;
+    GValue *val;
+    guint i;
+    const gchar *application_name;
+    gchar *new_app_name;
+
+    muted_applications = xfconf_channel_get_arrayv (channel, "/applications/muted_applications");
+    if (muted_applications == NULL)
+        muted_applications = g_ptr_array_new ();
+
+    application_box = GTK_WIDGET (g_list_nth_data (gtk_container_get_children (GTK_CONTAINER (selected_application_row)), 0));
+    application_label = GTK_WIDGET (g_list_nth_data (gtk_container_get_children (GTK_CONTAINER (application_box)), 0));
+    application_name = gtk_label_get_text (GTK_LABEL(application_label));
+    mute_switch = GTK_WIDGET (g_list_nth_data (gtk_container_get_children (GTK_CONTAINER (application_box)), 1));
+    muted = gtk_switch_get_active (GTK_SWITCH (mute_switch));
+
+    val = g_new0 (GValue, 1);
+    g_value_init (val, G_TYPE_STRING);
+    new_app_name = g_strdup (application_name);
+    g_value_take_string (val, new_app_name);
+    if (muted == TRUE && muted_applications != NULL) {
+        for (i = 0; i < muted_applications->len; i++) {
+            GValue *muted_application;
+            muted_application = g_ptr_array_index (muted_applications, i);
+            if (g_str_match_string (g_value_get_string (val), g_value_get_string (muted_application), FALSE) == TRUE) {
+                g_ptr_array_remove_index (muted_applications, i);
+                break;
+            }
+            g_warning ("Could not remove %s from the list of muted applications.", new_app_name);
+        }
+
+    }
+    else
+        g_ptr_array_add (muted_applications, val);
+
+    if (!xfconf_channel_set_arrayv (channel, "/applications/muted_applications", muted_applications))
+        g_warning ("Could not add %s to the list of muted applications.", new_app_name);
+
+    xfconf_array_free (muted_applications);
+    /* FIXME: why does this cause a segfault? */
+    //g_free (new_app_name);
+}
+
+static void
+xfce4_notifyd_row_activated (GtkListBox *known_applications_listbox,
+                             GtkListBoxRow *selected_application_row,
+                             gpointer user_data)
+{
+    GtkWidget *application_box;
+    GtkWidget *mute_switch;
+    gboolean muted;
+
+    application_box = GTK_WIDGET (g_list_nth_data (gtk_container_get_children (GTK_CONTAINER (selected_application_row)), 0));
+    mute_switch = GTK_WIDGET (g_list_nth_data (gtk_container_get_children (GTK_CONTAINER (application_box)), 1));
+    muted = !gtk_switch_get_active (GTK_SWITCH (mute_switch));
+    gtk_switch_set_active (GTK_SWITCH (mute_switch), muted);
+}
+
+static void
+xfce4_notifyd_switch_activated (GtkSwitch *mute_switch,
+                                gboolean state,
+                                gpointer user_data)
+{
+    XfconfChannel *channel = user_data;
+    GtkWidget *row_box;
+    GtkWidget *selected_application_row;
+    GtkWidget *known_applications_listbox;
+
+    g_return_if_fail (XFCONF_IS_CHANNEL (channel));
+
+    row_box = gtk_widget_get_parent (GTK_WIDGET (mute_switch));
+    selected_application_row = gtk_widget_get_parent (GTK_WIDGET (row_box));
+    known_applications_listbox = gtk_widget_get_parent (GTK_WIDGET (selected_application_row));
+    xfce4_notifyd_mute_application (GTK_LIST_BOX (known_applications_listbox),
+                                    GTK_LIST_BOX_ROW (selected_application_row),
+                                    channel);
+}
+
 static void xfce4_notifyd_show_help(GtkButton *button,
                                     GtkWidget *dialog)
 {
@@ -251,10 +355,22 @@ static GtkWidget *
 xfce4_notifyd_config_setup_dialog(GtkBuilder *builder)
 {
     XfconfChannel *channel;
-    GtkWidget *dlg, *btn, *sbtn, *slider, *theme_combo, *position_combo, *help_button;
+    GtkWidget *dlg;
+    GtkWidget *btn;
+    GtkWidget *sbtn;
+    GtkWidget *slider;
+    GtkWidget *theme_combo;
+    GtkWidget *position_combo;
+    GtkWidget *help_button;
+    GtkWidget *known_applications_listbox;
+    GtkWidget *no_known_apps_label;
+    GtkWidget *do_not_disturb_switch;
     GtkAdjustment *adj;
     GError *error = NULL;
     gchar *current_theme;
+    GPtrArray *known_applications;
+    GPtrArray *muted_applications;
+    guint i, j;
 
     gtk_builder_connect_signals(builder, NULL);
 
@@ -311,6 +427,57 @@ xfce4_notifyd_config_setup_dialog(GtkBuilder *builder)
     if(gtk_combo_box_get_active(GTK_COMBO_BOX(position_combo)) == -1)
         gtk_combo_box_set_active(GTK_COMBO_BOX(position_combo), GTK_CORNER_TOP_RIGHT);
 
+    do_not_disturb_switch = GTK_WIDGET(gtk_builder_get_object(builder, "do_not_disturb"));
+    xfconf_g_property_bind(channel, "/do-not-disturb", G_TYPE_BOOLEAN,
+                           G_OBJECT(do_not_disturb_switch), "active");
+
+    known_applications_listbox = GTK_WIDGET (gtk_builder_get_object (builder, "known_applications_listbox"));
+    gtk_list_box_set_header_func (GTK_LIST_BOX (known_applications_listbox), display_header_func, NULL, NULL);
+    /* TODO: Make label nicer (markup)*/
+    /* TODO: Monitor xfconf for changes and update list */
+    no_known_apps_label = gtk_label_new ("Currently there are no known applications that send notifications.\nAs soon as an application sends a notification, it will appear in this list.");
+    gtk_list_box_set_placeholder (GTK_LIST_BOX (known_applications_listbox), no_known_apps_label);
+    /* FIXME: Handle non-existing channel for known apps */
+    known_applications = xfconf_channel_get_arrayv (channel, "/applications/known_applications");
+    muted_applications = xfconf_channel_get_arrayv (channel, "/applications/muted_applications");
+    if (known_applications != NULL) {
+        for (i = 0; i < known_applications->len; i++) {
+            GValue *known_application;
+            GtkWidget *hbox, *label, *mute_switch, *separator;
+            known_application = g_ptr_array_index(known_applications, i);
+            hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+            label = gtk_label_new (g_value_get_string (known_application));
+            gtk_label_set_xalign (GTK_LABEL (label), 0);
+            mute_switch = gtk_switch_new ();
+            gtk_switch_set_active (GTK_SWITCH (mute_switch), TRUE);
+            gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 3);
+            gtk_box_pack_end (GTK_BOX (hbox), mute_switch, FALSE, TRUE, 3);
+            gtk_list_box_prepend (GTK_LIST_BOX (known_applications_listbox), hbox);
+            /* Set correct initial value as to whether an application is muted */
+            if (muted_applications != NULL) {
+                for (j = 0; j < muted_applications->len; j++) {
+                    GValue *muted_application;
+                    muted_application = g_ptr_array_index (muted_applications, j);
+                    if (g_str_match_string (g_value_get_string (muted_application), g_value_get_string (known_application), FALSE) == TRUE) {
+                        gtk_switch_set_active (GTK_SWITCH (mute_switch), FALSE);
+                        break;
+                    }
+                    else
+                        continue;
+                }
+            }
+            /* TODO: Connect a callback to the state-set signal of the switch to toggle mute */
+            g_signal_connect (G_OBJECT (mute_switch), "state-set", G_CALLBACK (xfce4_notifyd_switch_activated), channel);
+        }
+    }
+    xfconf_array_free (known_applications);
+    xfconf_array_free (muted_applications);
+    gtk_widget_show (no_known_apps_label);
+    gtk_widget_show_all (known_applications_listbox);
+    g_signal_connect (G_OBJECT (known_applications_listbox), "row-activated",
+                      G_CALLBACK (xfce4_notifyd_row_activated),
+                      channel);
+
     help_button = GTK_WIDGET(gtk_builder_get_object(builder, "help_btn"));
     g_signal_connect(G_OBJECT(help_button), "clicked",
                      G_CALLBACK(xfce4_notifyd_show_help), dlg);
@@ -351,6 +518,8 @@ main(int argc,
         g_print("%s %s\n", G_LOG_DOMAIN, VERSION);
         g_print("Copyright (c) 2010 Brian Tarricone <bjt23 at cornell.edu>\n");
         g_print("Copyright (c) 2010 Jérôme Guelfucci <jeromeg at xfce.org>\n");
+        g_print("Copyright (c) 2016 Ali Abdallah <ali at xfce.org>\n");
+        g_print("Copyright (c) 2016 Simon Steinbeiß <simon at xfce.org>\n");
         g_print(_("Released under the terms of the GNU General Public License, version 2\n"));
         g_print(_("Please report bugs to %s.\n"), PACKAGE_BUGREPORT);
 
diff --git a/xfce4-notifyd-config/xfce4-notifyd-config.glade b/xfce4-notifyd-config/xfce4-notifyd-config.glade
index 7861973..44e3717 100644
--- a/xfce4-notifyd-config/xfce4-notifyd-config.glade
+++ b/xfce4-notifyd-config/xfce4-notifyd-config.glade
@@ -2,7 +2,6 @@
 <!-- Generated with glade 3.18.3 -->
 <interface>
   <requires lib="gtk+" version="3.14"/>
-  <requires lib="libxfce4ui" version="4.12"/>
   <requires lib="libxfce4ui-2" version="4.12"/>
   <object class="GtkAdjustment" id="adjustment1">
     <property name="lower">1</property>
@@ -101,173 +100,289 @@
             <property name="can_focus">False</property>
             <property name="border_width">6</property>
             <child>
-              <object class="GtkGrid" id="grid1">
+              <object class="GtkNotebook" id="notebook1">
                 <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="row_spacing">6</property>
-                <property name="column_spacing">12</property>
-                <property name="column_homogeneous">True</property>
-                <child>
-                  <object class="GtkScale" id="opacity_slider">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="adjustment">adjustment2</property>
-                    <property name="round_digits">2</property>
-                    <property name="digits">2</property>
-                    <property name="value_pos">right</property>
-                  </object>
-                  <packing>
-                    <property name="left_attach">1</property>
-                    <property name="top_attach">3</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkButton" id="preview_button">
-                    <property name="label" translatable="yes">_Preview</property>
-                    <property name="use_action_appearance">False</property>
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">True</property>
-                    <property name="use_underline">True</property>
-                  </object>
-                  <packing>
-                    <property name="left_attach">0</property>
-                    <property name="top_attach">4</property>
-                    <property name="width">2</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkLabel" id="label5">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="label" translatable="yes">_Theme:</property>
-                    <property name="use_underline">True</property>
-                    <property name="xalign">0</property>
-                  </object>
-                  <packing>
-                    <property name="left_attach">0</property>
-                    <property name="top_attach">0</property>
-                  </packing>
-                </child>
+                <property name="can_focus">True</property>
                 <child>
-                  <object class="GtkComboBox" id="theme_combo">
+                  <object class="GtkGrid" id="grid1">
                     <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="row_spacing">6</property>
+                    <property name="column_spacing">12</property>
+                    <property name="column_homogeneous">True</property>
                     <child>
-                      <object class="GtkCellRendererText" id="renderer2"/>
-                      <attributes>
-                        <attribute name="text">0</attribute>
-                      </attributes>
+                      <object class="GtkScale" id="opacity_slider">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="adjustment">adjustment2</property>
+                        <property name="round_digits">2</property>
+                        <property name="digits">2</property>
+                        <property name="value_pos">right</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="top_attach">3</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkButton" id="preview_button">
+                        <property name="label" translatable="yes">_Preview</property>
+                        <property name="use_action_appearance">False</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">True</property>
+                        <property name="use_underline">True</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">0</property>
+                        <property name="top_attach">4</property>
+                        <property name="width">2</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label5">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">_Theme:</property>
+                        <property name="use_underline">True</property>
+                        <property name="xalign">0</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">0</property>
+                        <property name="top_attach">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkComboBox" id="theme_combo">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <child>
+                          <object class="GtkCellRendererText" id="renderer2"/>
+                          <attributes>
+                            <attribute name="text">0</attribute>
+                          </attributes>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="top_attach">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label3">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">Default _position:</property>
+                        <property name="use_underline">True</property>
+                        <property name="xalign">0</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">0</property>
+                        <property name="top_attach">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkComboBox" id="position_combo">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="model">model1</property>
+                        <child>
+                          <object class="GtkCellRendererText" id="renderer1"/>
+                          <attributes>
+                            <attribute name="text">0</attribute>
+                          </attributes>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="top_attach">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkBox" id="hbox4">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="spacing">6</property>
+                        <child>
+                          <object class="GtkSpinButton" id="expire_timeout_sbtn">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="invisible_char">●</property>
+                            <property name="primary_icon_activatable">False</property>
+                            <property name="secondary_icon_activatable">False</property>
+                            <property name="adjustment">adjustment1</property>
+                            <property name="numeric">True</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label4">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="label" translatable="yes">seconds</property>
+                            <property name="xalign">0</property>
+                          </object>
+                          <packing>
+                            <property name="expand">True</property>
+                            <property name="fill">True</property>
+                            <property name="pack_type">end</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="top_attach">2</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label1">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">_Disappear after:</property>
+                        <property name="use_underline">True</property>
+                        <property name="mnemonic_widget">expire_timeout_sbtn</property>
+                        <property name="xalign">0</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">0</property>
+                        <property name="top_attach">2</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label2">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">_Opacity:</property>
+                        <property name="use_underline">True</property>
+                        <property name="xalign">0</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">0</property>
+                        <property name="top_attach">3</property>
+                      </packing>
                     </child>
                   </object>
-                  <packing>
-                    <property name="left_attach">1</property>
-                    <property name="top_attach">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkLabel" id="label3">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="label" translatable="yes">Default _position:</property>
-                    <property name="use_underline">True</property>
-                    <property name="xalign">0</property>
-                  </object>
-                  <packing>
-                    <property name="left_attach">0</property>
-                    <property name="top_attach">1</property>
-                  </packing>
                 </child>
-                <child>
-                  <object class="GtkComboBox" id="position_combo">
+                <child type="tab">
+                  <object class="GtkLabel" id="label6">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="model">model1</property>
-                    <child>
-                      <object class="GtkCellRendererText" id="renderer1"/>
-                      <attributes>
-                        <attribute name="text">0</attribute>
-                      </attributes>
-                    </child>
+                    <property name="label" translatable="yes">Appearance</property>
                   </object>
                   <packing>
-                    <property name="left_attach">1</property>
-                    <property name="top_attach">1</property>
+                    <property name="tab_fill">False</property>
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkBox" id="hbox4">
+                  <object class="GtkBox" id="box1">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="spacing">6</property>
+                    <property name="margin_left">6</property>
+                    <property name="margin_right">6</property>
+                    <property name="margin_top">6</property>
+                    <property name="margin_bottom">6</property>
+                    <property name="orientation">vertical</property>
                     <child>
-                      <object class="GtkSpinButton" id="expire_timeout_sbtn">
+                      <object class="GtkGrid" id="grid2">
                         <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="invisible_char">●</property>
-                        <property name="primary_icon_activatable">False</property>
-                        <property name="secondary_icon_activatable">False</property>
-                        <property name="adjustment">adjustment1</property>
-                        <property name="numeric">True</property>
+                        <property name="can_focus">False</property>
+                        <child>
+                          <object class="GtkSwitch" id="do_not_disturb">
+                            <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>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label8">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="hexpand">True</property>
+                            <property name="label" translatable="yes">Do not disturb</property>
+                            <property name="xalign">0</property>
+                          </object>
+                          <packing>
+                            <property name="left_attach">0</property>
+                            <property name="top_attach">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label9">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="margin_top">12</property>
+                            <property name="margin_bottom">6</property>
+                            <property name="hexpand">True</property>
+                            <property name="label" translatable="yes"><b>Show notifications:</b></property>
+                            <property name="use_markup">True</property>
+                            <property name="xalign">0</property>
+                          </object>
+                          <packing>
+                            <property name="left_attach">0</property>
+                            <property name="top_attach">1</property>
+                            <property name="width">2</property>
+                          </packing>
+                        </child>
                       </object>
                       <packing>
                         <property name="expand">False</property>
-                        <property name="fill">False</property>
+                        <property name="fill">True</property>
                         <property name="position">0</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkLabel" id="label4">
+                      <object class="GtkViewport" id="viewport1">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">seconds</property>
-                        <property name="xalign">0</property>
+                        <child>
+                          <object class="GtkListBox" id="known_applications_listbox">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                          </object>
+                        </child>
+                        <style>
+                          <class name="frame"/>
+                        </style>
                       </object>
                       <packing>
                         <property name="expand">True</property>
                         <property name="fill">True</property>
-                        <property name="pack_type">end</property>
                         <property name="position">1</property>
                       </packing>
                     </child>
                   </object>
                   <packing>
-                    <property name="left_attach">1</property>
-                    <property name="top_attach">2</property>
+                    <property name="position">1</property>
                   </packing>
                 </child>
-                <child>
-                  <object class="GtkLabel" id="label1">
+                <child type="tab">
+                  <object class="GtkLabel" id="label7">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="label" translatable="yes">_Disappear after:</property>
-                    <property name="use_underline">True</property>
-                    <property name="mnemonic_widget">expire_timeout_sbtn</property>
-                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">Applications</property>
                   </object>
                   <packing>
-                    <property name="left_attach">0</property>
-                    <property name="top_attach">2</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkLabel" id="label2">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="label" translatable="yes">_Opacity:</property>
-                    <property name="use_underline">True</property>
-                    <property name="xalign">0</property>
-                  </object>
-                  <packing>
-                    <property name="left_attach">0</property>
-                    <property name="top_attach">3</property>
+                    <property name="position">1</property>
+                    <property name="tab_fill">False</property>
                   </packing>
                 </child>
               </object>
               <packing>
                 <property name="expand">True</property>
                 <property name="fill">True</property>
-                <property name="position">1</property>
+                <property name="position">0</property>
               </packing>
             </child>
           </object>
diff --git a/xfce4-notifyd/xfce-notify-daemon.c b/xfce4-notifyd/xfce-notify-daemon.c
index c8bdafb..2ead409 100644
--- a/xfce4-notifyd/xfce-notify-daemon.c
+++ b/xfce4-notifyd/xfce-notify-daemon.c
@@ -59,6 +59,7 @@ struct _XfceNotifyDaemon
     GtkCornerType notify_location;
     gboolean do_fadeout;
     gboolean primary_monitor;
+    gboolean do_not_disturb;
 
     GtkCssProvider *css_provider;
     gboolean is_default_theme;
@@ -121,6 +122,11 @@ static gboolean notify_get_capabilities (XfceNotifyGBus *skeleton,
                                 		 GDBusMethodInvocation   *invocation,
                                          XfceNotifyDaemon *xndaemon);
 
+static void notify_update_known_applications (XfconfChannel *channel,
+                                              gchar *app_name);
+
+static gboolean notify_application_is_muted (XfconfChannel *channel,
+                                             gchar *new_app_name);
 
 static gboolean notify_notify (XfceNotifyGBus *skeleton,
                                GDBusMethodInvocation   *invocation,
@@ -1033,23 +1039,91 @@ notify_update_theme_foreach (gpointer key, gpointer value, gpointer data)
     return FALSE;
 }
 
-static gboolean notify_notify (XfceNotifyGBus *skeleton,
-                               GDBusMethodInvocation   *invocation,
-                               const gchar *app_name,
-                               guint replaces_id,
-                               const gchar *app_icon,
-                               const gchar *summary,
-                               const gchar *body,
-                               const gchar **actions,
-                               GVariant *hints,
-                               gint expire_timeout,
-                               XfceNotifyDaemon *xndaemon)
+static void
+notify_update_known_applications (XfconfChannel *channel, gchar *new_app_name)
+{
+    GPtrArray *known_applications;
+    GValue *val;
+
+    val = g_new0 (GValue, 1);
+    g_value_init (val, G_TYPE_STRING);
+    g_value_take_string (val, new_app_name);
+
+    known_applications = xfconf_channel_get_arrayv (channel, "/applications/known_applications");
+    /* No known applications, initialize the application log */
+    if (known_applications == NULL || known_applications->len < 1) {
+        GPtrArray *array;
+        array = g_ptr_array_sized_new (1);
+        g_ptr_array_add (array, val);
+        if (!xfconf_channel_set_arrayv (channel, "/applications/known_applications", array))
+            g_warning ("Could not initialize the application log: %s", new_app_name);
+        xfconf_array_free (array);
+    }
+    /* Add the new application to the list unless it's already known */
+    else {
+        guint i;
+        gboolean application_is_known = FALSE;
+        /* Check if the application is actually unknown */
+        for (i = 0; i < known_applications->len; i++) {
+            GValue *known_application;
+            known_application = g_ptr_array_index (known_applications, i);
+            if (g_str_match_string (new_app_name, g_value_get_string (known_application), FALSE) == TRUE) {
+                application_is_known = TRUE;
+                break;
+            }
+        }
+        if (application_is_known == FALSE) {
+            g_ptr_array_add (known_applications, val);
+            if (!xfconf_channel_set_arrayv (channel, "/applications/known_applications", known_applications))
+                g_warning ("Could not add a new application to the log: %s", new_app_name);
+        }
+    }
+    xfconf_array_free (known_applications);
+}
+
+static gboolean
+notify_application_is_muted (XfconfChannel *channel, gchar *new_app_name)
+{
+    GPtrArray *muted_applications;
+    guint i;
+
+    muted_applications = xfconf_channel_get_arrayv (channel, "/applications/muted_applications");
+
+    /* Check whether this application should be muted */
+    if (muted_applications != NULL) {
+        for (i = 0; i < muted_applications->len; i++) {
+            GValue *muted_application;
+            muted_application = g_ptr_array_index (muted_applications, i);
+            if (g_str_match_string (new_app_name, g_value_get_string (muted_application), FALSE) == TRUE) {
+                g_warning ("Muted application: %s", new_app_name);
+                return TRUE;
+            }
+        }
+    }
+    g_warning ("Found no match for %s", new_app_name);
+    xfconf_array_free (muted_applications);
+    return FALSE;
+}
+
+static gboolean
+notify_notify (XfceNotifyGBus *skeleton,
+               GDBusMethodInvocation   *invocation,
+               const gchar *app_name,
+               guint replaces_id,
+               const gchar *app_icon,
+               const gchar *summary,
+               const gchar *body,
+               const gchar **actions,
+               GVariant *hints,
+               gint expire_timeout,
+               XfceNotifyDaemon *xndaemon)
 {
     XfceNotifyWindow *window;
     GdkPixbuf *pix = NULL;
     GVariant *image_data = NULL;
     const gchar *image_path = NULL;
     const gchar *desktop_id = NULL;
+    gchar *new_app_name;
     gint value_hint = 0;
     gboolean value_hint_set = FALSE;
     gboolean x_canonical = FALSE;
@@ -1059,6 +1133,9 @@ static gboolean notify_notify (XfceNotifyGBus *skeleton,
 
     g_variant_iter_init (&iter, hints);
 
+    new_app_name = g_strdup (app_name);
+    notify_update_known_applications (xndaemon->settings, new_app_name);
+
     while ((item = g_variant_iter_next_value (&iter)))
     {
         const char *key;
@@ -1113,6 +1190,20 @@ static gboolean notify_notify (XfceNotifyGBus *skeleton,
     if(expire_timeout == -1)
         expire_timeout = xndaemon->expire_timeout;
 
+    /* Only suppress notifications which are not marked as urgent in the "Do not disturb" mode  */
+    if (xndaemon->do_not_disturb == TRUE || notify_application_is_muted (xndaemon->settings, new_app_name) == TRUE)
+    {
+        if(xndaemon->close_timeout)
+            g_source_remove(xndaemon->close_timeout);
+
+        xndaemon->close_timeout = 0;
+
+        xfce_notify_gbus_complete_notify(skeleton, invocation, OUT_id);
+        return TRUE;
+        g_warning ("DND");
+    }
+    g_free (new_app_name);
+
     if(replaces_id
        && (window = g_tree_lookup(xndaemon->active_notifications,
                                   GUINT_TO_POINTER(replaces_id))))
@@ -1418,6 +1509,10 @@ xfce_notify_daemon_settings_changed(XfconfChannel *channel,
         xndaemon->primary_monitor = G_VALUE_TYPE(value)
                                     ? g_value_get_boolean(value)
                                     : TRUE;
+    } else if(!strcmp(property, "/do-not-disturb")) {
+        xndaemon->do_not_disturb = G_VALUE_TYPE(value)
+                                 ? g_value_get_boolean(value)
+                                 : FALSE;
     }
 }
 
@@ -1454,6 +1549,12 @@ xfce_notify_daemon_load_config (XfceNotifyDaemon *xndaemon,
     xndaemon->primary_monitor = xfconf_channel_get_bool(xndaemon->settings,
                                                         "/primary-monitor", FALSE);
 
+    xndaemon->do_not_disturb = xfconf_channel_get_bool(xndaemon->settings,
+                                                       "/do-not-disturb",
+                                                       FALSE);
+    /* Clean up old notifications from the backlog */
+    xfconf_channel_reset_property (xndaemon->settings, "/backlog", TRUE);
+
     g_signal_connect(G_OBJECT(xndaemon->settings), "property-changed",
                      G_CALLBACK(xfce_notify_daemon_settings_changed),
                      xndaemon);
diff --git a/xfce4-notifyd/xfce-notify-window.c b/xfce4-notifyd/xfce-notify-window.c
index 7f81a29..fa54325 100644
--- a/xfce4-notifyd/xfce-notify-window.c
+++ b/xfce4-notifyd/xfce-notify-window.c
@@ -36,7 +36,7 @@
 
 #define DEFAULT_EXPIRE_TIMEOUT 10000
 #define DEFAULT_NORMAL_OPACITY 0.85
-#define DEFAULT_DO_FADEOUT        TRUE
+#define DEFAULT_DO_FADEOUT     TRUE
 #define FADE_TIME              800
 #define FADE_CHANGE_TIMEOUT    50
 #define DEFAULT_RADIUS         10

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Xfce4-commits mailing list