From dfa174a82854b214b7eeaa62ad8b7567c4c1a949 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Feb 2016 18:05:45 -0600 Subject: don't show calendar event notifications if com.ubuntu.calendar's notifications are blacklisted --- src/snap.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'src/snap.cpp') diff --git a/src/snap.cpp b/src/snap.cpp index f0300af..934ad19 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -84,6 +84,12 @@ public: appointment_func snooze, appointment_func ok) { + // If calendar notifications are muted, don't show them + if (!appointment.is_ubuntu_alarm() && calendar_events_are_muted()) { + g_debug("Skipping muted calendar event '%s' notification", appointment.summary.c_str()); + return; + } + /* Alarms and calendar events are treated differently. Alarms should require manual intervention to dismiss. Calendar events are less urgent and shouldn't require manual @@ -159,6 +165,17 @@ public: private: + bool calendar_events_are_muted() const + { + for(const auto& app : m_settings->muted_apps.get()) { + if (app.first == "com.ubuntu.calendar") { + return true; + } + } + + return false; + } + static void on_sound_proxy_ready(GObject* /*source_object*/, GAsyncResult* res, gpointer gself) { GError * error; -- cgit v1.2.3 From 7357c8fbeafece1a31a57c7483e47fc3964ecd68 Mon Sep 17 00:00:00 2001 From: David Barth Date: Wed, 3 Feb 2016 15:47:29 +0100 Subject: adjust title and notification icon according to the event type --- src/snap.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'src/snap.cpp') diff --git a/src/snap.cpp b/src/snap.cpp index 934ad19..9c2b4b6 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -122,7 +122,7 @@ public: const auto minutes = std::chrono::minutes(m_settings->alarm_duration.get()); ain::Builder b; b.set_body (appointment.summary); - b.set_icon_name ("alarm-clock"); + b.set_icon_name (appointment.is_ubuntu_alarm() ? "alarm-clock" : "reminder"); b.add_hint (ain::Builder::HINT_NONSHAPED_ICON); const char * timefmt; @@ -136,7 +136,14 @@ public: timefmt = _("%a, %H:%M"); } const auto timestr = appointment.begin.format(timefmt); - auto title = g_strdup_printf(_("Alarm %s"), timestr.c_str()); + + const char * titlefmt; + if (appointment.is_ubuntu_alarm()) { + titlefmt = _("Alarm %s"); + } else { + titlefmt = _("Event %s"); + } + auto title = g_strdup_printf(titlefmt, timestr.c_str()); b.set_title (title); g_free (title); b.set_timeout (std::chrono::duration_cast(minutes)); -- cgit v1.2.3 From dd4265f22ee05aab8dbe6d60f9c7a13f85818466 Mon Sep 17 00:00:00 2001 From: Renato Araujo Oliveira Filho Date: Wed, 30 Mar 2016 16:52:02 -0300 Subject: Only play a sound alert if the event contains a SOUND reminder. --- include/datetime/appointment.h | 6 ++++++ src/engine-eds.cpp | 24 +++++++++++++++--------- src/snap.cpp | 4 ++++ tests/manual-test-snap.cpp | 2 +- 4 files changed, 26 insertions(+), 10 deletions(-) (limited to 'src/snap.cpp') diff --git a/include/datetime/appointment.h b/include/datetime/appointment.h index 950f4bb..5b4c27e 100644 --- a/include/datetime/appointment.h +++ b/include/datetime/appointment.h @@ -34,9 +34,15 @@ namespace datetime { */ struct Alarm { + enum Type { + EMAIL = 0x001, + SOUND = 0x010, + TEXT = 0x100 + }; std::string text; std::string audio_url; DateTime time; + int type; bool operator== (const Alarm& that) const; bool has_sound() const; diff --git a/src/engine-eds.cpp b/src/engine-eds.cpp index becd40f..f3b08cd 100644 --- a/src/engine-eds.cpp +++ b/src/engine-eds.cpp @@ -604,13 +604,14 @@ private: } }; - static std::string get_alarm_text(ECalComponentAlarm * alarm) + static std::string get_alarm_text(ECalComponentAlarm * alarm, bool * hasText) { std::string ret; auto action = e_cal_component_alarm_get_action(alarm); if (action == E_CAL_COMPONENT_ALARM_DISPLAY) { + *hasText = true; auto text = e_cal_component_alarm_get_description(alarm); if (text != nullptr) @@ -627,13 +628,14 @@ private: return ret; } - static std::string get_alarm_sound_url(ECalComponentAlarm * alarm, const std::string & default_sound) + static std::string get_alarm_sound_url(ECalComponentAlarm * alarm, bool * hasSound) { std::string ret; auto action = e_cal_component_alarm_get_action(alarm); if (action == E_CAL_COMPONENT_ALARM_AUDIO) { + *hasSound = true; ICalAttach *attach = nullptr; auto attachments = e_cal_component_alarm_get_attachments(alarm); @@ -649,8 +651,6 @@ private: ret = url; } } - if (ret.empty()) - ret = default_sound; } return ret; @@ -1138,17 +1138,23 @@ private: DateTime{gtz, e_cal_component_alarm_instance_get_occur_end(ai)}); auto trigger_time = DateTime{gtz, e_cal_component_alarm_instance_get_time(ai)}; auto& alarm = alarms[instance_time][trigger_time]; + bool hasText = false; + bool hasSound = false; + if (alarm.text.empty()) - alarm.text = get_alarm_text(a); + alarm.text = get_alarm_text(a, &hasText); if (alarm.audio_url.empty()) - alarm.audio_url = get_alarm_sound_url(a, (baseline.is_ubuntu_alarm() ? - "file://" ALARM_DEFAULT_SOUND : - "file://" CALENDAR_DEFAULT_SOUND)); + alarm.audio_url = get_alarm_sound_url(a, &hasSound); if (!alarm.time.is_set()) alarm.time = trigger_time; + if (hasText) + alarm.type = alarm.type | Alarm::TEXT; + if (hasSound) + alarm.type = alarm.type | Alarm::SOUND; + e_cal_component_alarm_free(a); } @@ -1160,7 +1166,7 @@ private: appointment.alarms.reserve(i.second.size()); for (auto& j : i.second) { - if (j.second.has_text() || j.second.has_sound()) + if ((j.second.type & Alarm::TEXT) || (j.second.type & Alarm::SOUND)) appointment.alarms.push_back(j.second); } subtask->task->appointments.push_back(appointment); diff --git a/src/snap.cpp b/src/snap.cpp index 9c2b4b6..72d68a2 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -227,6 +227,10 @@ private: std::string uri; + // does not play any sound if alarm is not set as sound + if (!is_alarm && !(alarm.type & Alarm::SOUND)) + return uri; + for(const auto& candidate : candidates) { if (gst_uri_is_valid (candidate.c_str())) diff --git a/tests/manual-test-snap.cpp b/tests/manual-test-snap.cpp index a0f80f2..5aa49a7 100644 --- a/tests/manual-test-snap.cpp +++ b/tests/manual-test-snap.cpp @@ -71,7 +71,7 @@ int main(int argc, const char* argv[]) a.type = Appointment::UBUNTU_ALARM; a.begin = DateTime::Local(2014, 12, 25, 0, 0, 0); a.end = a.begin.end_of_day(); - a.alarms.push_back(Alarm{"Alarm Text", "", a.begin}); + a.alarms.push_back(Alarm{"Alarm Text", "", a.begin, Alarm::SOUND}); auto loop = g_main_loop_new(nullptr, false); auto on_snooze = [loop](const Appointment& appt, const Alarm&){ -- cgit v1.2.3 From 87d2694ceeadee723573b3866a8bc2e3fb49de58 Mon Sep 17 00:00:00 2001 From: Renato Araujo Oliveira Filho Date: Thu, 31 Mar 2016 15:51:29 -0300 Subject: Remove type property from Alarm. --- include/datetime/appointment.h | 11 ++--------- src/appointment.cpp | 17 ++++++++--------- src/engine-eds.cpp | 22 +++++++--------------- src/snap.cpp | 5 ----- tests/manual-test-snap.cpp | 2 +- tests/notification-fixture.h | 4 ++-- tests/test-alarm-queue.cpp | 4 ++-- tests/test-eds-ics-missing-trigger.cpp | 1 - tests/test-eds-ics-nonrepeating-events.cpp | 2 +- tests/test-eds-ics-repeating-events.cpp | 16 ++++++++-------- tests/test-eds-ics-repeating-valarms.cpp | 16 ++++++++-------- tests/test-eds-ics-tzids-2.cpp | 2 +- 12 files changed, 40 insertions(+), 62 deletions(-) (limited to 'src/snap.cpp') diff --git a/include/datetime/appointment.h b/include/datetime/appointment.h index ae9e8ff..faf8a18 100644 --- a/include/datetime/appointment.h +++ b/include/datetime/appointment.h @@ -34,20 +34,13 @@ namespace datetime { */ struct Alarm { - enum Type { - None = 0, - EMAIL = 0x001, - SOUND = 0x010, - TEXT = 0x100 - }; - int type; std::string text; std::string audio_url; DateTime time; bool operator== (const Alarm& that) const; - Alarm(); - Alarm(int type_, const std::string &text_, const std::string& audio_url_, const DateTime &time_); + bool has_sound() const; + bool has_text() const; }; /** diff --git a/src/appointment.cpp b/src/appointment.cpp index e014a85..ebd5a47 100644 --- a/src/appointment.cpp +++ b/src/appointment.cpp @@ -27,22 +27,21 @@ namespace datetime { ***** ****/ -Alarm::Alarm() - : type(Alarm::None) +bool Alarm::operator==(const Alarm& that) const { + return (text==that.text) + && (audio_url==that.audio_url) + && (this->time==that.time); } -Alarm::Alarm(int type_, const std::string &text_, const std::string& audio_url_, const DateTime &time_) - : type(type_), text(text_), audio_url(audio_url_), time(time_) +bool Alarm::has_sound() const { + return !audio_url.empty(); } -bool Alarm::operator==(const Alarm& that) const +bool Alarm::has_text() const { - return (type==that.type) - && (text==that.text) - && (audio_url==that.audio_url) - && (this->time==that.time); + return !text.empty(); } bool Appointment::operator==(const Appointment& that) const diff --git a/src/engine-eds.cpp b/src/engine-eds.cpp index bd94251..68e2bdd 100644 --- a/src/engine-eds.cpp +++ b/src/engine-eds.cpp @@ -604,14 +604,13 @@ private: } }; - static std::string get_alarm_text(ECalComponentAlarm * alarm, bool * hasText) + static std::string get_alarm_text(ECalComponentAlarm * alarm) { std::string ret; auto action = e_cal_component_alarm_get_action(alarm); if (action == E_CAL_COMPONENT_ALARM_DISPLAY) { - *hasText = true; auto text = e_cal_component_alarm_get_description(alarm); if (text != nullptr) @@ -628,14 +627,14 @@ private: return ret; } - static std::string get_alarm_sound_url(ECalComponentAlarm * alarm, bool * hasSound) + static std::string get_alarm_sound_url(ECalComponentAlarm * alarm, const std::string & default_sound) { std::string ret; auto action = e_cal_component_alarm_get_action(alarm); if (action == E_CAL_COMPONENT_ALARM_AUDIO) { - *hasSound = true; + ret = default_sound; ICalAttach *attach = nullptr; auto attachments = e_cal_component_alarm_get_attachments(alarm); @@ -1138,23 +1137,16 @@ private: DateTime{gtz, e_cal_component_alarm_instance_get_occur_end(ai)}); auto trigger_time = DateTime{gtz, e_cal_component_alarm_instance_get_time(ai)}; auto& alarm = alarms[instance_time][trigger_time]; - bool hasText = false; - bool hasSound = false; - if (alarm.text.empty()) - alarm.text = get_alarm_text(a, &hasText); + alarm.text = get_alarm_text(a); if (alarm.audio_url.empty()) - alarm.audio_url = get_alarm_sound_url(a, &hasSound); + alarm.audio_url = get_alarm_sound_url(a, baseline.is_ubuntu_alarm() ? + ALARM_DEFAULT_SOUND : CALENDAR_DEFAULT_SOUND); if (!alarm.time.is_set()) alarm.time = trigger_time; - if (hasText) - alarm.type = alarm.type | Alarm::TEXT; - if (hasSound) - alarm.type = alarm.type | Alarm::SOUND; - e_cal_component_alarm_free(a); } @@ -1166,7 +1158,7 @@ private: appointment.alarms.reserve(i.second.size()); for (auto& j : i.second) { - if ((j.second.type & Alarm::TEXT) || (j.second.type & Alarm::SOUND)) + if (j.second.has_text() || (j.second.has_sound())) appointment.alarms.push_back(j.second); } subtask->task->appointments.push_back(appointment); diff --git a/src/snap.cpp b/src/snap.cpp index 72d68a2..97fcbab 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -226,11 +226,6 @@ private: }; std::string uri; - - // does not play any sound if alarm is not set as sound - if (!is_alarm && !(alarm.type & Alarm::SOUND)) - return uri; - for(const auto& candidate : candidates) { if (gst_uri_is_valid (candidate.c_str())) diff --git a/tests/manual-test-snap.cpp b/tests/manual-test-snap.cpp index 1479ef9..a0f80f2 100644 --- a/tests/manual-test-snap.cpp +++ b/tests/manual-test-snap.cpp @@ -71,7 +71,7 @@ int main(int argc, const char* argv[]) a.type = Appointment::UBUNTU_ALARM; a.begin = DateTime::Local(2014, 12, 25, 0, 0, 0); a.end = a.begin.end_of_day(); - a.alarms.push_back(Alarm{Alarm::SOUND, "Alarm Text", "", a.begin}); + a.alarms.push_back(Alarm{"Alarm Text", "", a.begin}); auto loop = g_main_loop_new(nullptr, false); auto on_snooze = [loop](const Appointment& appt, const Alarm&){ diff --git a/tests/notification-fixture.h b/tests/notification-fixture.h index 40f7cee..29066c0 100644 --- a/tests/notification-fixture.h +++ b/tests/notification-fixture.h @@ -111,7 +111,7 @@ protected: const auto christmas = ayatana::indicator::datetime::DateTime::Local(2015,12,25,0,0,0); appt.begin = christmas.start_of_day(); appt.end = christmas.end_of_day(); - appt.alarms.push_back(ayatana::indicator::datetime::Alarm{ayatana::indicator::datetime::Alarm::SOUND, "Ho Ho Ho!", "", appt.begin }); + appt.alarms.push_back(ayatana::indicator::datetime::Alarm{"Ho Ho Ho!", "", appt.begin }); // init a Lomiri Alarm ualarm.color = "red"; @@ -121,7 +121,7 @@ protected: const auto tomorrow = ayatana::indicator::datetime::DateTime::NowLocal().add_days(1); ualarm.begin = tomorrow; ualarm.end = tomorrow; - ualarm.alarms.push_back(ayatana::indicator::datetime::Alarm{ayatana::indicator::datetime::Alarm::SOUND, "It's Tomorrow!", "", appt.begin}); + ualarm.alarms.push_back(ayatana::indicator::datetime::Alarm{"It's Tomorrow!", "", appt.begin}); /// /// Add the AccountsService mock diff --git a/tests/test-alarm-queue.cpp b/tests/test-alarm-queue.cpp index 49bd933..42edf74 100644 --- a/tests/test-alarm-queue.cpp +++ b/tests/test-alarm-queue.cpp @@ -79,7 +79,7 @@ protected: a1.type = Appointment::UBUNTU_ALARM; a1.begin = tomorrow_begin; a1.end = tomorrow_end; - a1.alarms.push_back(Alarm{Alarm::SOUND, "Alarm Text", "", a1.begin}); + a1.alarms.push_back(Alarm{"Alarm Text", "", a1.begin}); const auto ubermorgen_begin = now.add_days(2).start_of_day(); const auto ubermorgen_end = ubermorgen_begin.end_of_day(); @@ -92,7 +92,7 @@ protected: a2.type = Appointment::EVENT; a2.begin = ubermorgen_begin; a2.end = ubermorgen_end; - a2.alarms.push_back(Alarm{Alarm::SOUND, "Alarm Text", "", a2.begin}); + a2.alarms.push_back(Alarm{"Alarm Text", "", a2.begin}); return std::vector({a1, a2}); } diff --git a/tests/test-eds-ics-missing-trigger.cpp b/tests/test-eds-ics-missing-trigger.cpp index 3894569..0aa00c6 100644 --- a/tests/test-eds-ics-missing-trigger.cpp +++ b/tests/test-eds-ics-missing-trigger.cpp @@ -91,7 +91,6 @@ TEST_F(VAlarmFixture, MissingTriggers) a.alarms[0].audio_url = "file://" ALARM_DEFAULT_SOUND; a.alarms[0].time = a.begin; a.alarms[0].text = a.summary; - a.alarms[0].type = Alarm::SOUND | Alarm::TEXT; expected.push_back(a); // build expected: recurring alarm diff --git a/tests/test-eds-ics-nonrepeating-events.cpp b/tests/test-eds-ics-nonrepeating-events.cpp index fe0d851..ff0ef3f 100644 --- a/tests/test-eds-ics-nonrepeating-events.cpp +++ b/tests/test-eds-ics-nonrepeating-events.cpp @@ -84,7 +84,7 @@ TEST_F(VAlarmFixture, MultipleAppointments) expected_appt.color = "#becedd"; expected_appt.summary = "Alarm"; std::array expected_alarms = { - Alarm({Alarm::SOUND | Alarm::TEXT, "Alarm", "file://" ALARM_DEFAULT_SOUND, DateTime(gtz,2015,5,20,20,00,0)}) + Alarm({"Alarm", "file://" ALARM_DEFAULT_SOUND, DateTime(gtz,2015,5,20,20,00,0)}) }; // compare it to what we actually loaded... diff --git a/tests/test-eds-ics-repeating-events.cpp b/tests/test-eds-ics-repeating-events.cpp index cdc0bbc..5d2a2ee 100644 --- a/tests/test-eds-ics-repeating-events.cpp +++ b/tests/test-eds-ics-repeating-events.cpp @@ -84,14 +84,14 @@ TEST_F(VAlarmFixture, MultipleAppointments) expected_appt.color = "#becedd"; expected_appt.summary = "Alarm"; std::array expected_alarms = { - Alarm({Alarm::SOUND | Alarm::TEXT, "Alarm", "file://" ALARM_DEFAULT_SOUND, DateTime(gtz,2015,5, 8,16,40,0)}), - Alarm({Alarm::SOUND | Alarm::TEXT, "Alarm", "file://" ALARM_DEFAULT_SOUND, DateTime(gtz,2015,5,15,16,40,0)}), - Alarm({Alarm::SOUND | Alarm::TEXT, "Alarm", "file://" ALARM_DEFAULT_SOUND, DateTime(gtz,2015,5,22,16,40,0)}), - Alarm({Alarm::SOUND | Alarm::TEXT, "Alarm", "file://" ALARM_DEFAULT_SOUND, DateTime(gtz,2015,5,29,16,40,0)}), - Alarm({Alarm::SOUND | Alarm::TEXT, "Alarm", "file://" ALARM_DEFAULT_SOUND, DateTime(gtz,2015,6, 5,16,40,0)}), - Alarm({Alarm::SOUND | Alarm::TEXT, "Alarm", "file://" ALARM_DEFAULT_SOUND, DateTime(gtz,2015,6,12,16,40,0)}), - Alarm({Alarm::SOUND | Alarm::TEXT, "Alarm", "file://" ALARM_DEFAULT_SOUND, DateTime(gtz,2015,6,19,16,40,0)}), - Alarm({Alarm::SOUND | Alarm::TEXT, "Alarm", "file://" ALARM_DEFAULT_SOUND, DateTime(gtz,2015,6,26,16,40,0)}) + Alarm({"Alarm", "file://" ALARM_DEFAULT_SOUND, DateTime(gtz,2015,5, 8,16,40,0)}), + Alarm({"Alarm", "file://" ALARM_DEFAULT_SOUND, DateTime(gtz,2015,5,15,16,40,0)}), + Alarm({"Alarm", "file://" ALARM_DEFAULT_SOUND, DateTime(gtz,2015,5,22,16,40,0)}), + Alarm({"Alarm", "file://" ALARM_DEFAULT_SOUND, DateTime(gtz,2015,5,29,16,40,0)}), + Alarm({"Alarm", "file://" ALARM_DEFAULT_SOUND, DateTime(gtz,2015,6, 5,16,40,0)}), + Alarm({"Alarm", "file://" ALARM_DEFAULT_SOUND, DateTime(gtz,2015,6,12,16,40,0)}), + Alarm({"Alarm", "file://" ALARM_DEFAULT_SOUND, DateTime(gtz,2015,6,19,16,40,0)}), + Alarm({"Alarm", "file://" ALARM_DEFAULT_SOUND, DateTime(gtz,2015,6,26,16,40,0)}) }; // compare it to what we actually loaded... diff --git a/tests/test-eds-ics-repeating-valarms.cpp b/tests/test-eds-ics-repeating-valarms.cpp index 49ec41b..4f53e68 100644 --- a/tests/test-eds-ics-repeating-valarms.cpp +++ b/tests/test-eds-ics-repeating-valarms.cpp @@ -83,14 +83,14 @@ TEST_F(VAlarmFixture, MultipleAppointments) ASSERT_EQ(1, appts.size()); const auto& appt = appts.front(); ASSERT_EQ(8, appt.alarms.size()); - EXPECT_EQ(Alarm({Alarm::SOUND | Alarm::TEXT, "Time to pack!", "", DateTime(gtz,2015,4,23,13,35,0)}), appt.alarms[0]); - EXPECT_EQ(Alarm({Alarm::SOUND | Alarm::TEXT, "Time to pack!", "", DateTime(gtz,2015,4,23,13,37,0)}), appt.alarms[1]); - EXPECT_EQ(Alarm({Alarm::SOUND | Alarm::TEXT, "Time to pack!", "", DateTime(gtz,2015,4,23,13,39,0)}), appt.alarms[2]); - EXPECT_EQ(Alarm({Alarm::SOUND | Alarm::TEXT, "Time to pack!", "", DateTime(gtz,2015,4,23,13,41,0)}), appt.alarms[3]); - EXPECT_EQ(Alarm({Alarm::SOUND | Alarm::TEXT, "Go to the airport!", "", DateTime(gtz,2015,4,24,10,35,0)}), appt.alarms[4]); - EXPECT_EQ(Alarm({Alarm::SOUND | Alarm::TEXT, "Go to the airport!", "", DateTime(gtz,2015,4,24,10,37,0)}), appt.alarms[5]); - EXPECT_EQ(Alarm({Alarm::SOUND | Alarm::TEXT, "Go to the airport!", "", DateTime(gtz,2015,4,24,10,39,0)}), appt.alarms[6]); - EXPECT_EQ(Alarm({Alarm::SOUND | Alarm::TEXT, "Go to the airport!", "", DateTime(gtz,2015,4,24,10,41,0)}), appt.alarms[7]); + EXPECT_EQ(Alarm({"Time to pack!", "", DateTime(gtz,2015,4,23,13,35,0)}), appt.alarms[0]); + EXPECT_EQ(Alarm({"Time to pack!", "", DateTime(gtz,2015,4,23,13,37,0)}), appt.alarms[1]); + EXPECT_EQ(Alarm({"Time to pack!", "", DateTime(gtz,2015,4,23,13,39,0)}), appt.alarms[2]); + EXPECT_EQ(Alarm({"Time to pack!", "", DateTime(gtz,2015,4,23,13,41,0)}), appt.alarms[3]); + EXPECT_EQ(Alarm({"Go to the airport!", "", DateTime(gtz,2015,4,24,10,35,0)}), appt.alarms[4]); + EXPECT_EQ(Alarm({"Go to the airport!", "", DateTime(gtz,2015,4,24,10,37,0)}), appt.alarms[5]); + EXPECT_EQ(Alarm({"Go to the airport!", "", DateTime(gtz,2015,4,24,10,39,0)}), appt.alarms[6]); + EXPECT_EQ(Alarm({"Go to the airport!", "", DateTime(gtz,2015,4,24,10,41,0)}), appt.alarms[7]); // now let's try this out with AlarmQueue... // hook the planner up to a SimpleAlarmQueue and confirm that it triggers for each of the reminders diff --git a/tests/test-eds-ics-tzids-2.cpp b/tests/test-eds-ics-tzids-2.cpp index b1a344a..c8b0370 100644 --- a/tests/test-eds-ics-tzids-2.cpp +++ b/tests/test-eds-ics-tzids-2.cpp @@ -86,7 +86,7 @@ TEST_F(VAlarmFixture, MultipleAppointments) appt->summary = "National Incubator Initiative for Clean Energy (NIICE) FOA: Pre-Concept Paper Informational Webinar"; appt->begin = DateTime{gtz,2014,1,21,11,0,0}; appt->end = DateTime{gtz,2014,1,21,13,0,0}; - appt->alarms = std::vector{ Alarm({Alarm::TEXT, "Reminder", "", DateTime(gtz,2014,1,21,10,45,0)}) }; + appt->alarms = std::vector{ Alarm({"Reminder", "", DateTime(gtz,2014,1,21,10,45,0)}) }; // compare it to what we actually loaded... const auto appts = planner->appointments().get(); -- cgit v1.2.3 From b7e9673460d55d07020728bd981eb61e956336f0 Mon Sep 17 00:00:00 2001 From: Renato Araujo Oliveira Filho Date: Fri, 1 Apr 2016 10:05:52 -0300 Subject: Does not play sound for events without a sound set. --- src/snap.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/snap.cpp') diff --git a/src/snap.cpp b/src/snap.cpp index 97fcbab..ca89851 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -226,6 +226,9 @@ private: }; std::string uri; + if (!alarm.has_sound() && !is_alarm) + return uri; + for(const auto& candidate : candidates) { if (gst_uri_is_valid (candidate.c_str())) -- cgit v1.2.3 From 274ac6aa8898fb6621dbba8161a08ca41f451952 Mon Sep 17 00:00:00 2001 From: Renato Araujo Oliveira Filho Date: Fri, 1 Apr 2016 10:13:49 -0300 Subject: better code. --- src/snap.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/snap.cpp') diff --git a/src/snap.cpp b/src/snap.cpp index ca89851..259592e 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -101,7 +101,7 @@ public: // calendar events are muted in silent mode; alarm clocks never are std::shared_ptr sound; - if (appointment.is_ubuntu_alarm() || !silent_mode()) { + if (appointment.is_ubuntu_alarm() || (alarm.has_sound() && !silent_mode())) { // create the sound. const auto role = appointment.is_ubuntu_alarm() ? "alarm" : "alert"; const auto uri = get_alarm_uri(appointment, alarm, m_settings); @@ -226,8 +226,6 @@ private: }; std::string uri; - if (!alarm.has_sound() && !is_alarm) - return uri; for(const auto& candidate : candidates) { -- cgit v1.2.3 From 6d9cae0de3d127c5b757fc6af482c047a1d81ab9 Mon Sep 17 00:00:00 2001 From: Renato Araujo Oliveira Filho Date: Thu, 14 Apr 2016 18:23:44 -0300 Subject: Play event sound even if the event has only text reminders. --- src/snap.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/snap.cpp') diff --git a/src/snap.cpp b/src/snap.cpp index 259592e..a1caf62 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -101,7 +101,10 @@ public: // calendar events are muted in silent mode; alarm clocks never are std::shared_ptr sound; - if (appointment.is_ubuntu_alarm() || (alarm.has_sound() && !silent_mode())) { + // play reminder sound even if the event is only a text reminder. + // we choose that because events synced from google only get text reminders + bool play_sound = (alarm.has_sound() || alarm.has_text()); + if (appointment.is_ubuntu_alarm() || (play_sound && !silent_mode())) { // create the sound. const auto role = appointment.is_ubuntu_alarm() ? "alarm" : "alert"; const auto uri = get_alarm_uri(appointment, alarm, m_settings); -- cgit v1.2.3 From d80df1bbd068f97457575fcd20f9664f2a5d11c4 Mon Sep 17 00:00:00 2001 From: Renato Araujo Oliveira Filho Date: Fri, 15 Apr 2016 14:23:40 -0300 Subject: revert last change. --- src/snap.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/snap.cpp') diff --git a/src/snap.cpp b/src/snap.cpp index a1caf62..259592e 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -101,10 +101,7 @@ public: // calendar events are muted in silent mode; alarm clocks never are std::shared_ptr sound; - // play reminder sound even if the event is only a text reminder. - // we choose that because events synced from google only get text reminders - bool play_sound = (alarm.has_sound() || alarm.has_text()); - if (appointment.is_ubuntu_alarm() || (play_sound && !silent_mode())) { + if (appointment.is_ubuntu_alarm() || (alarm.has_sound() && !silent_mode())) { // create the sound. const auto role = appointment.is_ubuntu_alarm() ? "alarm" : "alert"; const auto uri = get_alarm_uri(appointment, alarm, m_settings); -- cgit v1.2.3 From bb7b522ef52b240718f33f37b577bacc4fea2db6 Mon Sep 17 00:00:00 2001 From: Renato Araujo Oliveira Filho Date: Mon, 18 Apr 2016 23:42:53 -0300 Subject: Post message on messaging menu if the notification get timeout. --- data/CMakeLists.txt | 7 +- data/ayatana-indicator-datetime.desktop.in | 1 + include/notifications/notifications.h | 11 ++- src/main.cpp | 5 +- src/notifications.cpp | 127 +++++++++++++++++++++++++++-- src/snap.cpp | 12 ++- tests/test-notification.cpp | 2 +- tests/test-sound.cpp | 2 +- 8 files changed, 154 insertions(+), 13 deletions(-) (limited to 'src/snap.cpp') diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt index c460586..14d36b8 100644 --- a/data/CMakeLists.txt +++ b/data/CMakeLists.txt @@ -32,6 +32,7 @@ if (${SYSTEMD_FOUND}) # build it set (pkglibexecdir "${CMAKE_INSTALL_FULL_PKGLIBEXECDIR}") + set (messaging_menu_icon "${CMAKE_INSTALL_FULL_DATAROOTDIR}/icons/suru/actions/scalable/appointment.svg") configure_file ("${SYSTEMD_USER_FILE_IN}" "${SYSTEMD_USER_FILE}") # install it @@ -55,7 +56,11 @@ set (XDG_AUTOSTART_FILE_IN "${CMAKE_CURRENT_SOURCE_DIR}/${XDG_AUTOSTART_NAME}.in set (pkglibexecdir "${CMAKE_INSTALL_FULL_PKGLIBEXECDIR}") configure_file ("${XDG_AUTOSTART_FILE_IN}" "${XDG_AUTOSTART_FILE}") -# install it +# install desktop file used by messaging-menu +install (FILES "${XDG_AUTOSTART_FILE}" + DESTINATION "${CMAKE_INSTALL_FULL_DATAROOTDIR}/applications/") + +# install XDG autostart install (FILES "${XDG_AUTOSTART_FILE}" DESTINATION "${XDG_AUTOSTART_DIR}") diff --git a/data/ayatana-indicator-datetime.desktop.in b/data/ayatana-indicator-datetime.desktop.in index 70df0d7..6d27166 100644 --- a/data/ayatana-indicator-datetime.desktop.in +++ b/data/ayatana-indicator-datetime.desktop.in @@ -6,3 +6,4 @@ OnlyShowIn=MATE;Unity;XFCE;Pantheon; NoDisplay=true StartupNotify=false Terminal=false +Icon=@messaging_menu_icon@ diff --git a/include/notifications/notifications.h b/include/notifications/notifications.h index 0de1e23..2bb6694 100644 --- a/include/notifications/notifications.h +++ b/include/notifications/notifications.h @@ -50,6 +50,8 @@ public: void set_icon_name (const std::string& icon_name); + void set_start_time(uint64_t time); + /* Set an interval, after which the notification will automatically be closed. If not set, the notification server's default timeout is used. */ @@ -62,19 +64,24 @@ public: static constexpr char const * HINT_NONSHAPED_ICON {"x-canonical-non-shaped-icon"}; static constexpr char const * HINT_AFFIRMATIVE_HINT {"x-canonical-private-affirmative-tint"}; static constexpr char const * HINT_REJECTION_TINT {"x-canonical-private-rejection-tint"}; + static constexpr char const * HINT_INTERACTIVE {"x-canonical-switch-to-application"}; /* Add an action button. This may fail if the Engine doesn't support actions. @see Engine::supports_actions() */ void add_action (const std::string& action, const std::string& label); - /** Sets the closed callback. This will be called exactly once. */ + /** Sets the closed callback. This will be called exactly once. After notification dissapear */ void set_closed_callback (std::function); + /** Sets the time-out callback. This will be called exactly once. */ + void set_missed_click_callback (std::function); + + private: friend class Engine; class Impl; - std::unique_ptr impl; + std::shared_ptr impl; }; /** diff --git a/src/main.cpp b/src/main.cpp index bb77c0e..f9a934a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -156,7 +156,10 @@ main(int /*argc*/, char** /*argv*/) auto on_snooze = [snooze_planner](const Appointment& appointment, const Alarm& alarm) { snooze_planner->add(appointment, alarm); }; - auto on_ok = [](const Appointment&, const Alarm&){}; + auto on_ok = [actions](const Appointment& app, const Alarm&){ + //TODO: add support for desktop + actions->phone_open_appointment(app, app.begin); + }; auto on_alarm_reached = [&engine, &snap, &on_snooze, &on_ok](const Appointment& appointment, const Alarm& alarm) { (*snap)(appointment, alarm, on_snooze, on_ok); engine->disable_ubuntu_alarm(appointment); diff --git a/src/notifications.cpp b/src/notifications.cpp index 051653d..2d22087 100644 --- a/src/notifications.cpp +++ b/src/notifications.cpp @@ -21,10 +21,18 @@ #include +#include +#include + + +#include + #include #include #include #include +#include + namespace ayatana { namespace indicator { @@ -45,9 +53,11 @@ public: std::string m_body; std::string m_icon_name; std::chrono::seconds m_duration; + gint64 m_start_time; std::set m_string_hints; std::vector> m_actions; std::function m_closed_callback; + std::function m_missed_click_callback; }; Builder::Builder(): @@ -101,6 +111,18 @@ Builder::set_closed_callback (std::function cb) impl->m_closed_callback.swap (cb); } +void +Builder::set_missed_click_callback (std::function cb) +{ + impl->m_missed_click_callback.swap (cb); +} + +void +Builder::set_start_time (uint64_t time) +{ + impl->m_start_time = time; +} + /*** **** ***/ @@ -110,23 +132,39 @@ class Engine::Impl struct notification_data { std::shared_ptr nn; - std::function closed_callback; + Builder::Impl data; + }; + + struct messaging_menu_data + { + std::shared_ptr mm; + std::function callback; }; public: Impl(const std::string& app_name): + m_messaging_app(messaging_menu_app_new(DATETIME_INDICATOR_DESKTOP_FILE), g_object_unref), m_app_name(app_name) { if (!notify_init(app_name.c_str())) g_critical("Unable to initialize libnotify!"); + + // messaging menu + GIcon *icon = g_themed_icon_new("calendar-app"); + + messaging_menu_app_register(m_messaging_app.get()); + messaging_menu_app_append_source(m_messaging_app.get(), m_app_name.c_str(), icon, "Calendar"); + g_object_unref(icon); } ~Impl() { close_all (); + remove_all (); notify_uninit (); + messaging_menu_app_unregister (m_messaging_app.get()); } const std::string& app_name() const @@ -217,7 +255,7 @@ public: notification_key_quark(), GINT_TO_POINTER(key)); - m_notifications[key] = { nn, info.m_closed_callback }; + m_notifications[key] = { nn, info }; g_signal_connect (nn.get(), "closed", G_CALLBACK(on_notification_closed), this); @@ -238,6 +276,59 @@ public: return ret; } + std::string post(const Builder::Impl& data) + { + uuid_t message_uuid; + uuid_generate(message_uuid); + + char message_id[37]; + uuid_unparse(message_uuid, message_id); + + GIcon *icon = g_themed_icon_new(data.m_icon_name.c_str()); + std::shared_ptr msg (messaging_menu_message_new(message_id, + icon, + data.m_title.c_str(), + nullptr, + data.m_body.c_str(), + data.m_start_time * 1000000), // secs -> microsecs + g_object_ref); + g_object_unref(icon); + if (msg) + { + m_messaging_messages[std::string(message_id)] = { msg, data.m_missed_click_callback }; + g_signal_connect(msg.get(), "activate", + G_CALLBACK(on_message_activated), this); + messaging_menu_app_append_message(m_messaging_app.get(), msg.get(), m_app_name.c_str(), false); + return message_id; + } else { + g_warning("Fail to create messaging menu message"); + } + return ""; + } + + void remove (const std::string &key) + { + auto it = m_messaging_messages.find(key); + if (it != m_messaging_messages.end()) + { + // tell the server to remove message + messaging_menu_app_remove_message(m_messaging_app.get(), it->second.mm.get()); + m_messaging_messages.erase(it); + } + } + + void remove_all () + { + // call remove() on all our keys + + std::set keys; + for (const auto& it : m_messaging_messages) + keys.insert (it.first); + + for (const std::string &key : keys) + remove (key); + } + private: const std::set& server_caps() const @@ -279,6 +370,22 @@ private: static_cast(gself)->remove_closed_notification(GPOINTER_TO_INT(gkey)); } + static void on_message_activated (MessagingMenuMessage *, + const char *actionId, + GVariant *, + gpointer gself) + { + auto self = static_cast(gself); + auto it = self->m_messaging_messages.find(actionId); + g_return_if_fail (it != self->m_messaging_messages.end()); + const auto& ndata = it->second; + + if (ndata.callback) + ndata.callback(); + + self->m_messaging_messages.erase(it); + } + void remove_closed_notification (int key) { auto it = m_notifications.find(key); @@ -286,16 +393,20 @@ private: const auto& ndata = it->second; auto nn = ndata.nn.get(); - if (ndata.closed_callback) + + if (ndata.data.m_closed_callback) { std::string action; - const GQuark q = notification_action_quark(); const gpointer p = g_object_get_qdata(G_OBJECT(nn), q); if (p != nullptr) action = static_cast(p); - ndata.closed_callback (action); + ndata.data.m_closed_callback (action); + // empty action means that the notification got timeout + // post a message on messaging menu + if (action.empty()) + post(ndata.data); } m_notifications.erase(it); @@ -305,6 +416,10 @@ private: **** ***/ + // messaging menu + std::shared_ptr m_messaging_app; + std::map m_messaging_messages; + const std::string m_app_name; // key-to-data @@ -315,6 +430,8 @@ private: mutable std::set m_lazy_caps; static constexpr char const * HINT_TIMEOUT {"x-canonical-snap-decisions-timeout"}; + static constexpr char const * DATETIME_INDICATOR_DESKTOP_FILE {"indicator-datetime.desktop"}; + static constexpr char const * DATETIME_INDICATOR_SOURCE_ID {"indicator-datetime"}; }; /*** diff --git a/src/snap.cpp b/src/snap.cpp index 259592e..5c530be 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -122,8 +122,9 @@ public: const auto minutes = std::chrono::minutes(m_settings->alarm_duration.get()); ain::Builder b; b.set_body (appointment.summary); - b.set_icon_name (appointment.is_ubuntu_alarm() ? "alarm-clock" : "reminder"); + b.set_icon_name (appointment.is_ubuntu_alarm() ? "alarm-clock" : "appointment"); b.add_hint (ain::Builder::HINT_NONSHAPED_ICON); + b.set_start_time (appointment.begin.to_unix()); const char * timefmt; if (is_locale_12h()) { @@ -152,6 +153,9 @@ public: b.add_hint (ain::Builder::HINT_AFFIRMATIVE_HINT); b.add_action ("ok", _("OK")); b.add_action ("snooze", _("Snooze")); + } else { + b.add_hint (ain::Builder::HINT_INTERACTIVE); + b.add_action ("ok", _("OK")); } // add 'sound', 'haptic', and 'awake' objects to the capture so @@ -161,10 +165,14 @@ public: (const std::string& action){ if (action == "snooze") snooze(appointment, alarm); - else + else if (action == "ok") ok(appointment, alarm); }); + b.set_missed_click_callback([appointment, alarm, ok](){ + ok(appointment, alarm); + }); + const auto key = m_engine->show(b); if (key) m_notifications.insert (key); diff --git a/tests/test-notification.cpp b/tests/test-notification.cpp index 4c11dca..b951cee 100644 --- a/tests/test-notification.cpp +++ b/tests/test-notification.cpp @@ -63,7 +63,7 @@ TEST_F(NotificationFixture,Notification) bool expected_notify_called; bool expected_vibrate_called; } test_appts[] = { - { appt, "reminder", "Event", true, true }, + { appt, "appointment", "Event", true, true }, { ualarm, "alarm-clock", "Alarm", true, true } }; diff --git a/tests/test-sound.cpp b/tests/test-sound.cpp index a222f39..59c1a28 100644 --- a/tests/test-sound.cpp +++ b/tests/test-sound.cpp @@ -85,7 +85,7 @@ TEST_F(NotificationFixture, InteractiveDuration) // confirm that the icon passed to Notify was "alarm-clock" g_variant_get_child (params, 2, "&s", &str); - ASSERT_STREQ("reminder", str); + ASSERT_STREQ("appointment", str); // confirm that the hints passed to Notify included a timeout matching duration_minutes int32_t i32; -- cgit v1.2.3 From 1ace19e7b28a5e817114a47e25d540f8c48f1cec Mon Sep 17 00:00:00 2001 From: Renato Araujo Oliveira Filho Date: Tue, 19 Apr 2016 13:12:54 -0300 Subject: Only play sounds for alarms. --- src/snap.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/snap.cpp') diff --git a/src/snap.cpp b/src/snap.cpp index 5c530be..4736498 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -101,7 +101,9 @@ public: // calendar events are muted in silent mode; alarm clocks never are std::shared_ptr sound; - if (appointment.is_ubuntu_alarm() || (alarm.has_sound() && !silent_mode())) { + // FIXME: only play sounds for alarms for now, we should itegrate it with + // system settings to decide if we should play sounds for calendar notification or not + if (appointment.is_ubuntu_alarm()) { // create the sound. const auto role = appointment.is_ubuntu_alarm() ? "alarm" : "alert"; const auto uri = get_alarm_uri(appointment, alarm, m_settings); -- cgit v1.2.3 From 6a6cca286f8dca9a41fb13d51f991dd88eec5791 Mon Sep 17 00:00:00 2001 From: Renato Araujo Oliveira Filho Date: Wed, 20 Apr 2016 17:59:25 -0300 Subject: Vibrate only once when notification about calendar events. --- include/notifications/haptic.h | 2 +- src/haptic.cpp | 20 +++++++++++++------- src/snap.cpp | 2 +- 3 files changed, 15 insertions(+), 9 deletions(-) (limited to 'src/snap.cpp') diff --git a/include/notifications/haptic.h b/include/notifications/haptic.h index 535074d..2f4008a 100644 --- a/include/notifications/haptic.h +++ b/include/notifications/haptic.h @@ -41,7 +41,7 @@ public: MODE_PULSE }; - explicit Haptic(const Mode& mode = MODE_PULSE); + explicit Haptic(const Mode& mode = MODE_PULSE, bool repeat = false); ~Haptic(); private: diff --git a/src/haptic.cpp b/src/haptic.cpp index 7430c04..dc2cb82 100644 --- a/src/haptic.cpp +++ b/src/haptic.cpp @@ -37,9 +37,10 @@ class Haptic::Impl { public: - Impl(const Mode& mode): + Impl(const Mode& mode, bool repeat): m_mode(mode), - m_cancellable(g_cancellable_new()) + m_cancellable(g_cancellable_new()), + m_repeat(repeat) { g_bus_get (G_BUS_TYPE_SESSION, m_cancellable, on_bus_ready, this); } @@ -93,11 +94,15 @@ private: // one second on, one second off. m_pattern = std::vector({1000u, 1000u}); break; + } - // Set up a loop to keep repeating the pattern - auto msec = std::accumulate(m_pattern.begin(), m_pattern.end(), 0u); - m_tag = g_timeout_add(msec, call_vibrate_pattern_static, this); + if (m_repeat) + { + // Set up a loop to keep repeating the pattern + auto msec = std::accumulate(m_pattern.begin(), m_pattern.end(), 0u); + m_tag = g_timeout_add(msec, call_vibrate_pattern_static, this); + } call_vibrate_pattern(); } @@ -146,14 +151,15 @@ private: GDBusConnection * m_bus = nullptr; std::vector m_pattern; guint m_tag = 0; + bool m_repeat = false; }; /*** **** ***/ -Haptic::Haptic(const Mode& mode): - impl(new Impl (mode)) +Haptic::Haptic(const Mode& mode, bool repeat): + impl(new Impl (mode, repeat)) { } diff --git a/src/snap.cpp b/src/snap.cpp index 4736498..217b6df 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -117,7 +117,7 @@ public: if (should_vibrate()) { const auto haptic_mode = m_settings->alarm_haptic.get(); if (haptic_mode == "pulse") - haptic = std::make_shared(ain::Haptic::MODE_PULSE); + haptic = std::make_shared(ain::Haptic::MODE_PULSE, appointment.is_ubuntu_alarm()); } // show a notification... -- cgit v1.2.3 From 04588f8bff4156dae76d8ef03d1bbd58fca9fdb7 Mon Sep 17 00:00:00 2001 From: Renato Araujo Oliveira Filho Date: Tue, 26 Apr 2016 21:43:03 -0300 Subject: Update notifications to use the new calendar icon. --- data/CMakeLists.txt | 2 +- src/snap.cpp | 2 +- tests/test-notification.cpp | 2 +- tests/test-sound.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/snap.cpp') diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt index 14d36b8..6bbc246 100644 --- a/data/CMakeLists.txt +++ b/data/CMakeLists.txt @@ -32,7 +32,7 @@ if (${SYSTEMD_FOUND}) # build it set (pkglibexecdir "${CMAKE_INSTALL_FULL_PKGLIBEXECDIR}") - set (messaging_menu_icon "${CMAKE_INSTALL_FULL_DATAROOTDIR}/icons/suru/actions/scalable/appointment.svg") + set (messaging_menu_icon "${CMAKE_INSTALL_FULL_DATAROOTDIR}/icons/suru/actions/scalable/calendar.svg") configure_file ("${SYSTEMD_USER_FILE_IN}" "${SYSTEMD_USER_FILE}") # install it diff --git a/src/snap.cpp b/src/snap.cpp index 217b6df..1e7dd5e 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -124,7 +124,7 @@ public: const auto minutes = std::chrono::minutes(m_settings->alarm_duration.get()); ain::Builder b; b.set_body (appointment.summary); - b.set_icon_name (appointment.is_ubuntu_alarm() ? "alarm-clock" : "appointment"); + b.set_icon_name (appointment.is_ubuntu_alarm() ? "alarm-clock" : "calendar"); b.add_hint (ain::Builder::HINT_NONSHAPED_ICON); b.set_start_time (appointment.begin.to_unix()); diff --git a/tests/test-notification.cpp b/tests/test-notification.cpp index b951cee..d660982 100644 --- a/tests/test-notification.cpp +++ b/tests/test-notification.cpp @@ -63,7 +63,7 @@ TEST_F(NotificationFixture,Notification) bool expected_notify_called; bool expected_vibrate_called; } test_appts[] = { - { appt, "appointment", "Event", true, true }, + { appt, "calendar", "Event", true, true }, { ualarm, "alarm-clock", "Alarm", true, true } }; diff --git a/tests/test-sound.cpp b/tests/test-sound.cpp index 469b085..013c388 100644 --- a/tests/test-sound.cpp +++ b/tests/test-sound.cpp @@ -85,7 +85,7 @@ TEST_F(NotificationFixture, InteractiveDuration) // confirm that the icon passed to Notify was "alarm-clock" g_variant_get_child (params, 2, "&s", &str); - ASSERT_STREQ("appointment", str); + ASSERT_STREQ("calendar", str); // confirm that the hints passed to Notify included a timeout matching duration_minutes int32_t i32; -- cgit v1.2.3 From 02ea97a63928c5da4ca1882d34ae61076b06c945 Mon Sep 17 00:00:00 2001 From: Renato Araujo Oliveira Filho Date: Wed, 27 Apr 2016 14:01:28 -0300 Subject: Use calendar app icon. --- CMakeLists.txt | 9 +++++++++ data/CMakeLists.txt | 5 ----- src/notifications.cpp | 41 +++++++++++++++++++++++++++++++++++++---- src/snap.cpp | 11 +++++++---- 4 files changed, 53 insertions(+), 13 deletions(-) (limited to 'src/snap.cpp') diff --git a/CMakeLists.txt b/CMakeLists.txt index 33781a0..5dbc921 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,6 +80,15 @@ if(URLDISPATCHER_FOUND) add_definitions( -DHAS_URLDISPATCHER ) endif() +# lomiri-app-launch + +pkg_check_modules(LOMIRIAPPLAUNCH lomiri-app-launch>=0) +include_directories(${LOMIRIAPPLAUNCH_INCLUDE_DIRS}) + +if(LOMIRIAPPLAUNCH_FOUND) + add_definitions( -DHAS_LOMIRIAPPLAUNCH ) +endif() + if(EXISTS "/usr/share/accountsservice/interfaces/com.ubuntu.touch.AccountsService.Sound.xml") set (HAVE_UT_ACCTSERVICE_SYSTEMSOUND_SETTINGS ON) add_definitions ( -DHAS_UT_ACCTSERVICE_SYSTEMSOUND_SETTINGS ) diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt index 6bbc246..d7ab10f 100644 --- a/data/CMakeLists.txt +++ b/data/CMakeLists.txt @@ -32,7 +32,6 @@ if (${SYSTEMD_FOUND}) # build it set (pkglibexecdir "${CMAKE_INSTALL_FULL_PKGLIBEXECDIR}") - set (messaging_menu_icon "${CMAKE_INSTALL_FULL_DATAROOTDIR}/icons/suru/actions/scalable/calendar.svg") configure_file ("${SYSTEMD_USER_FILE_IN}" "${SYSTEMD_USER_FILE}") # install it @@ -56,10 +55,6 @@ set (XDG_AUTOSTART_FILE_IN "${CMAKE_CURRENT_SOURCE_DIR}/${XDG_AUTOSTART_NAME}.in set (pkglibexecdir "${CMAKE_INSTALL_FULL_PKGLIBEXECDIR}") configure_file ("${XDG_AUTOSTART_FILE_IN}" "${XDG_AUTOSTART_FILE}") -# install desktop file used by messaging-menu -install (FILES "${XDG_AUTOSTART_FILE}" - DESTINATION "${CMAKE_INSTALL_FULL_DATAROOTDIR}/applications/") - # install XDG autostart install (FILES "${XDG_AUTOSTART_FILE}" DESTINATION "${XDG_AUTOSTART_DIR}") diff --git a/src/notifications.cpp b/src/notifications.cpp index f59a421..dc42534 100644 --- a/src/notifications.cpp +++ b/src/notifications.cpp @@ -24,9 +24,14 @@ #include #include +#ifdef HAS_LOMIRIAPPLAUNCH +#include +#endif #include +#include + #include #include #include @@ -145,7 +150,7 @@ class Engine::Impl public: Impl(const std::string& app_name): - m_messaging_app(messaging_menu_app_new(DATETIME_INDICATOR_DESKTOP_FILE), g_object_unref), + m_messaging_app(messaging_menu_app_new(calendar_app_id().c_str()), g_object_unref), m_app_name(app_name) { if (!notify_init(app_name.c_str())) @@ -282,11 +287,15 @@ public: uuid_unparse(message_uuid, uuid_buf); const std::string message_id(uuid_buf); - GIcon *icon = g_themed_icon_new(data.m_icon_name.c_str()); + // use full icon path name, "calendar-app" does not work with themed icons + auto icon_file = g_file_new_for_path(calendar_app_icon().c_str()); + // messaging_menu_message_new: will take control of icon object + GIcon *icon = g_file_icon_new(icon_file); + g_object_unref(icon_file); // check if source exists if (!messaging_menu_app_has_source(m_messaging_app.get(), m_app_name.c_str())) - messaging_menu_app_append_source(m_messaging_app.get(), m_app_name.c_str(), icon, "Calendar"); + messaging_menu_app_append_source(m_messaging_app.get(), m_app_name.c_str(), nullptr, "Calendar"); auto msg = messaging_menu_message_new(message_id.c_str(), icon, @@ -294,7 +303,6 @@ public: nullptr, data.m_body.c_str(), data.m_start_time * G_USEC_PER_SEC); // secs -> microsecs - g_object_unref(icon); if (msg) { std::shared_ptr msg_data(new messaging_menu_data{message_id, data.m_missed_click_callback, this}); @@ -427,6 +435,31 @@ private: m_notifications.erase(it); } + static std::string calendar_app_id() + { + #ifdef HAS_LOMIRIAPPLAUNCH + auto app_id = lomiri::app_launch::AppID::discover("com.lomiri.calendar"); + return std::string(app_id) + ".desktop"; + #else + return ""; + #endif + } + + static std::string calendar_app_icon() + { + auto app_desktop = g_desktop_app_info_new(calendar_app_id().c_str()); + if (app_desktop != nullptr) { + auto icon_name = g_desktop_app_info_get_string(app_desktop, "Icon"); + g_object_unref(app_desktop); + std::string result(icon_name); + g_free(icon_name); + return result; + } else { + g_warning("Fail to get calendar icon"); + return std::string(); + } + } + /*** **** ***/ diff --git a/src/snap.cpp b/src/snap.cpp index 1e7dd5e..60005f3 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -124,7 +124,7 @@ public: const auto minutes = std::chrono::minutes(m_settings->alarm_duration.get()); ain::Builder b; b.set_body (appointment.summary); - b.set_icon_name (appointment.is_ubuntu_alarm() ? "alarm-clock" : "calendar"); + b.set_icon_name (appointment.is_ubuntu_alarm() ? "alarm-clock" : "calendar-app"); b.add_hint (ain::Builder::HINT_NONSHAPED_ICON); b.set_start_time (appointment.begin.to_unix()); @@ -171,9 +171,12 @@ public: ok(appointment, alarm); }); - b.set_missed_click_callback([appointment, alarm, ok](){ - ok(appointment, alarm); - }); + //TODO: we need to extend it to support alarms appoitments + if (!appointment.is_ubuntu_alarm()) { + b.set_missed_click_callback([appointment, alarm, ok](){ + ok(appointment, alarm); + }); + } const auto key = m_engine->show(b); if (key) -- cgit v1.2.3 From 0fb4679e9043ba2591055f46445294cf508be0fb Mon Sep 17 00:00:00 2001 From: Renato Araujo Oliveira Filho Date: Thu, 28 Apr 2016 09:35:05 -0300 Subject: Small fixes requeted by charles during the review. --- include/notifications/notifications.h | 2 +- src/main.cpp | 1 - src/notifications.cpp | 39 +++++++++++++++-------------------- src/snap.cpp | 2 +- 4 files changed, 19 insertions(+), 25 deletions(-) (limited to 'src/snap.cpp') diff --git a/include/notifications/notifications.h b/include/notifications/notifications.h index 4b66800..450c45b 100644 --- a/include/notifications/notifications.h +++ b/include/notifications/notifications.h @@ -75,7 +75,7 @@ public: void set_closed_callback (std::function); /** Sets the time-out callback. This will be called exactly once. */ - void set_missed_click_callback (std::function); + void set_timeout_callback (std::function); private: diff --git a/src/main.cpp b/src/main.cpp index f9a934a..729f0e5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -157,7 +157,6 @@ main(int /*argc*/, char** /*argv*/) snooze_planner->add(appointment, alarm); }; auto on_ok = [actions](const Appointment& app, const Alarm&){ - //TODO: add support for desktop actions->phone_open_appointment(app, app.begin); }; auto on_alarm_reached = [&engine, &snap, &on_snooze, &on_ok](const Appointment& appointment, const Alarm& alarm) { diff --git a/src/notifications.cpp b/src/notifications.cpp index 9817686..3c90e57 100644 --- a/src/notifications.cpp +++ b/src/notifications.cpp @@ -58,11 +58,11 @@ public: std::string m_body; std::string m_icon_name; std::chrono::seconds m_duration; - gint64 m_start_time; + gint64 m_start_time {}; std::set m_string_hints; std::vector> m_actions; std::function m_closed_callback; - std::function m_missed_click_callback; + std::function m_timeout_callback; }; Builder::Builder(): @@ -117,9 +117,9 @@ Builder::set_closed_callback (std::function cb) } void -Builder::set_missed_click_callback (std::function cb) +Builder::set_timeout_callback (std::function cb) { - impl->m_missed_click_callback.swap (cb); + impl->m_timeout_callback.swap (cb); } void @@ -312,7 +312,7 @@ public: data.m_start_time * G_USEC_PER_SEC); // secs -> microsecs if (msg) { - std::shared_ptr msg_data(new messaging_menu_data{message_id, data.m_missed_click_callback, this}); + std::shared_ptr msg_data(new messaging_menu_data{message_id, data.m_timeout_callback, this}); m_messaging_messages[message_id] = msg_data; g_signal_connect(G_OBJECT(msg), "activate", G_CALLBACK(on_message_activated), msg_data.get()); @@ -344,13 +344,8 @@ public: void remove_all () { // call remove() on all our keys - - std::set keys; - for (const auto& it : m_messaging_messages) - keys.insert (it.first); - - for (const std::string &key : keys) - remove (key); + while (!m_messaging_messages.empty()) + remove(m_messaging_messages.begin()->first); } private: @@ -400,7 +395,7 @@ private: gpointer data) { auto msg_data = static_cast(data); - auto it = msg_data->self->m_messaging_messages.find(msg_data->msg_id.c_str()); + auto it = msg_data->self->m_messaging_messages.find(msg_data->msg_id); g_return_if_fail (it != msg_data->self->m_messaging_messages.end()); const auto& ndata = it->second; @@ -411,7 +406,7 @@ private: static void on_message_destroyed(gpointer data) { auto msg_data = static_cast(data); - auto it = msg_data->self->m_messaging_messages.find(msg_data->msg_id.c_str()); + auto it = msg_data->self->m_messaging_messages.find(msg_data->msg_id); if (it != msg_data->self->m_messaging_messages.end()) msg_data->self->m_messaging_messages.erase(it); } @@ -448,6 +443,7 @@ private: auto app_id = lomiri::app_launch::AppID::discover("com.lomiri.calendar"); if (!app_id.empty()) + // Due the use of old API by messaging_menu we need append a extra ".desktop" to the app_id. return std::string(app_id) + ".desktop"; else return std::string(); @@ -463,13 +459,14 @@ private: if (app_desktop != nullptr) { auto icon_name = g_desktop_app_info_get_string(app_desktop, "Icon"); g_object_unref(app_desktop); - std::string result(icon_name); - g_free(icon_name); - return result; - } else { - g_warning("Fail to get calendar icon"); - return std::string(); + if (icon_name) { + std::string result(icon_name); + g_free(icon_name); + return result; + } } + g_warning("Fail to get calendar icon"); + return std::string(); } /*** @@ -490,8 +487,6 @@ private: mutable std::set m_lazy_caps; static constexpr char const * HINT_TIMEOUT {"x-canonical-snap-decisions-timeout"}; - static constexpr char const * DATETIME_INDICATOR_DESKTOP_FILE {"indicator-datetime.desktop"}; - static constexpr char const * DATETIME_INDICATOR_SOURCE_ID {"indicator-datetime"}; }; /*** diff --git a/src/snap.cpp b/src/snap.cpp index 60005f3..4078dd7 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -173,7 +173,7 @@ public: //TODO: we need to extend it to support alarms appoitments if (!appointment.is_ubuntu_alarm()) { - b.set_missed_click_callback([appointment, alarm, ok](){ + b.set_timeout_callback([appointment, alarm, ok](){ ok(appointment, alarm); }); } -- cgit v1.2.3 From b639e39dc4a2aa82a40f0a6922577b65ff3dd35f Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sat, 14 May 2016 12:18:45 -0500 Subject: add a new Snap::Response enum for more flexible handling of snap decisions --- include/datetime/snap.h | 6 +++--- src/main.cpp | 21 ++++++++++++++------- src/snap.cpp | 39 +++++++++++++++++++++++---------------- 3 files changed, 40 insertions(+), 26 deletions(-) (limited to 'src/snap.cpp') diff --git a/include/datetime/snap.h b/include/datetime/snap.h index a295d9f..099426b 100644 --- a/include/datetime/snap.h +++ b/include/datetime/snap.h @@ -42,11 +42,11 @@ public: const std::shared_ptr& settings); virtual ~Snap(); - typedef std::function appointment_func; + enum class Response { None, Snooze, ShowApp }; + typedef std::function response_func; void operator()(const Appointment& appointment, const Alarm& alarm, - appointment_func snooze, - appointment_func ok); + response_func on_response); private: class Impl; diff --git a/src/main.cpp b/src/main.cpp index 034a5ef..9defed0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -153,14 +153,21 @@ main(int /*argc*/, char** /*argv*/) auto notification_engine = std::make_shared("ayatana-indicator-datetime-service"); std::unique_ptr snap (new Snap(notification_engine, state->settings)); auto alarm_queue = create_simple_alarm_queue(state->clock, snooze_planner, engine, timezone_); - auto on_snooze = [snooze_planner](const Appointment& appointment, const Alarm& alarm) { - snooze_planner->add(appointment, alarm); + auto sound_builder = std::make_shared(); + auto on_response = [snooze_planner, actions](const Appointment& appointment, const Alarm& alarm, const Snap::Response& response) { + switch(response) { + case Snap::Response::Snooze: + snooze_planner->add(appointment, alarm); + break; + case Snap::Response::ShowApp: + actions->open_appointment(appointment, appointment.begin); + break; + case Snap::Response::None: + break; + } }; - auto on_ok = [actions](const Appointment& app, const Alarm&){ - actions->open_appointment(app, app.begin); - }; - auto on_alarm_reached = [&engine, &snap, &on_snooze, &on_ok](const Appointment& appointment, const Alarm& alarm) { - (*snap)(appointment, alarm, on_snooze, on_ok); + auto on_alarm_reached = [&engine, &snap, &on_response](const Appointment& appointment, const Alarm& alarm) { + (*snap)(appointment, alarm, on_response); engine->disable_ubuntu_alarm(appointment); }; alarm_queue->alarm_reached().connect(on_alarm_reached); diff --git a/src/snap.cpp b/src/snap.cpp index 4078dd7..51d04ae 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -81,8 +81,7 @@ public: void operator()(const Appointment& appointment, const Alarm& alarm, - appointment_func snooze, - appointment_func ok) + response_func on_response) { // If calendar notifications are muted, don't show them if (!appointment.is_ubuntu_alarm() && calendar_events_are_muted()) { @@ -153,28 +152,33 @@ public: if (interactive) { b.add_hint (ain::Builder::HINT_SNAP); b.add_hint (ain::Builder::HINT_AFFIRMATIVE_HINT); - b.add_action ("ok", _("OK")); - b.add_action ("snooze", _("Snooze")); + b.add_action (ACTION_NONE, _("OK")); + b.add_action (ACTION_SNOOZE, _("Snooze")); } else { b.add_hint (ain::Builder::HINT_INTERACTIVE); - b.add_action ("ok", _("OK")); + b.add_action (ACTION_SHOW_APP, _("OK")); } // add 'sound', 'haptic', and 'awake' objects to the capture so // they stay alive until the closed callback is called; i.e., // for the lifespan of the notficiation - b.set_closed_callback([appointment, alarm, snooze, ok, sound, awake, haptic] + b.set_closed_callback([appointment, alarm, on_response, sound, awake, haptic] (const std::string& action){ - if (action == "snooze") - snooze(appointment, alarm); - else if (action == "ok") - ok(appointment, alarm); + Snap::Response response; + if (action == ACTION_SNOOZE) + response = Snap::Response::Snooze; + else if (action == ACTION_SHOW_APP) + response = Snap::Response::ShowApp; + else + response = Snap::Response::None; + + on_response(appointment, alarm, response); }); - //TODO: we need to extend it to support alarms appoitments + //TODO: we need to extend it to support alarms appointments if (!appointment.is_ubuntu_alarm()) { - b.set_timeout_callback([appointment, alarm, ok](){ - ok(appointment, alarm); + b.set_timeout_callback([appointment, alarm, on_response](){ + on_response(appointment, alarm, Snap::Response::ShowApp); }); } @@ -267,6 +271,10 @@ private: std::set m_notifications; GCancellable * m_cancellable {nullptr}; AccountsServiceSound * m_accounts_service_sound_proxy {nullptr}; + + static constexpr char const * ACTION_NONE {"none"}; + static constexpr char const * ACTION_SNOOZE {"snooze"}; + static constexpr char const * ACTION_SHOW_APP {"show-app"}; }; /*** @@ -286,10 +294,9 @@ Snap::~Snap() void Snap::operator()(const Appointment& appointment, const Alarm& alarm, - appointment_func show, - appointment_func ok) + response_func on_response) { - (*impl)(appointment, alarm, show, ok); + (*impl)(appointment, alarm, on_response); } /*** -- cgit v1.2.3 From 525a38eb600292ffb764f6b5de058f9ba6ddd2b8 Mon Sep 17 00:00:00 2001 From: Arthur Mello Date: Wed, 22 Jun 2016 15:37:55 -0300 Subject: Update indicator-datetime to work with the new notification settings --- include/datetime/settings-live.h | 12 ++-- include/datetime/settings-shared.h | 9 ++- include/datetime/settings.h | 6 +- src/settings-live.cpp | 115 ++++++++++++++++++++++--------------- src/snap.cpp | 45 ++++++++++----- tests/test-notification.cpp | 26 ++++----- tests/test-settings.cpp | 111 ++++++++++++++--------------------- 7 files changed, 173 insertions(+), 151 deletions(-) (limited to 'src/snap.cpp') diff --git a/include/datetime/settings-live.h b/include/datetime/settings-live.h index 330b8e8..4aeaa9b 100644 --- a/include/datetime/settings-live.h +++ b/include/datetime/settings-live.h @@ -39,9 +39,9 @@ public: private: static void on_changed_ccid(GSettings*, gchar*, gpointer); - static void on_changed_cunh(GSettings*, gchar*, gpointer); + static void on_changed_cal_notification(GSettings*, gchar*, gpointer); void update_key_ccid(const std::string& key); - void update_key_cunh(const std::string& key); + void update_key_cal_notification(const std::string& key); void update_custom_time_format(); void update_locations(); @@ -62,10 +62,14 @@ private: void update_alarm_duration(); void update_alarm_haptic(); void update_snooze_duration(); - void update_muted_apps(); + void update_cal_notification_enabled(); + void update_cal_notification_sounds(); + void update_cal_notification_vibrations(); + void update_cal_notification_bubbles(); + void update_cal_notification_list(); GSettings* m_settings; - GSettings* m_settings_cunh; + GSettings* m_settings_cal_notification; // we've got a raw pointer here, so disable copying LiveSettings(const LiveSettings&) =delete; diff --git a/include/datetime/settings-shared.h b/include/datetime/settings-shared.h index f385e7a..236b8f1 100644 --- a/include/datetime/settings-shared.h +++ b/include/datetime/settings-shared.h @@ -51,7 +51,12 @@ TimeFormatMode; #define SETTINGS_ALARM_HAPTIC_S "alarm-haptic-feedback" #define SETTINGS_SNOOZE_DURATION_S "snooze-duration-minutes" -#define SETTINGS_CUNH_SCHEMA_ID "com.lomiri.notifications.hub" -#define SETTINGS_CUNH_BLACKLIST_S "blacklist" +#define SETTINGS_NOTIFY_SCHEMA_ID "com.lomiri.notifications.settings" +#define SETTINGS_NOTIFY_CALENDAR_PATH "/com/lomiri/NotificationSettings/com.lomiri.calendar/calendar/" +#define SETTINGS_NOTIFY_ENABLED_KEY "enable-notifications" +#define SETTINGS_NOTIFY_SOUNDS_KEY "use-sounds-notifications" +#define SETTINGS_NOTIFY_VIBRATIONS_KEY "use-vibrations-notifications" +#define SETTINGS_NOTIFY_BUBBLES_KEY "use-bubbles-notifications" +#define SETTINGS_NOTIFY_LIST_KEY "use-list-notifications" #endif // INDICATOR_DATETIME_SETTINGS_SHARED diff --git a/include/datetime/settings.h b/include/datetime/settings.h index d5e81c6..5ae00f6 100644 --- a/include/datetime/settings.h +++ b/include/datetime/settings.h @@ -61,7 +61,11 @@ public: core::Property alarm_volume; core::Property alarm_duration; core::Property snooze_duration; - core::Property>> muted_apps; + core::Property cal_notification_enabled; + core::Property cal_notification_sounds; + core::Property cal_notification_vibrations; + core::Property cal_notification_bubbles; + core::Property cal_notification_list; }; } // namespace datetime diff --git a/src/settings-live.cpp b/src/settings-live.cpp index 6504d7d..f908c05 100644 --- a/src/settings-live.cpp +++ b/src/settings-live.cpp @@ -34,7 +34,7 @@ namespace datetime { LiveSettings::~LiveSettings() { - g_clear_object(&m_settings_cunh); + g_clear_object(&m_settings_cal_notification); g_clear_object(&m_settings); } @@ -44,8 +44,8 @@ LiveSettings::LiveSettings(): m_settings(g_settings_new(SETTINGS_INTERFACE)) if (ayatana_common_utils_is_lomiri()) { - m_settings_cunh = g_settings_new(SETTINGS_CUNH_SCHEMA_ID); - g_signal_connect (m_settings_cunh, "changed", G_CALLBACK(on_changed_cunh), this); + m_settings_cal_notification = g_settings_new_with_path(SETTINGS_NOTIFY_SCHEMA_ID, SETTINGS_NOTIFY_CALENDAR_PATH); + g_signal_connect (m_settings_cal_notification, "changed", G_CALLBACK(on_changed_cal_notification), this); } // init the Properties from the GSettings backend @@ -68,7 +68,11 @@ LiveSettings::LiveSettings(): m_settings(g_settings_new(SETTINGS_INTERFACE)) update_alarm_duration(); update_alarm_haptic(); update_snooze_duration(); - update_muted_apps(); + update_cal_notification_enabled(); + update_cal_notification_sounds(); + update_cal_notification_vibrations(); + update_cal_notification_bubbles(); + update_cal_notification_list(); // now listen for clients to change the properties s.t. we can sync update GSettings @@ -76,20 +80,6 @@ LiveSettings::LiveSettings(): m_settings(g_settings_new(SETTINGS_INTERFACE)) g_settings_set_string(m_settings, SETTINGS_CUSTOM_TIME_FORMAT_S, value.c_str()); }); - if (ayatana_common_utils_is_lomiri()) - { - muted_apps.changed().connect([this](const std::set>& value){ - GVariantBuilder builder; - g_variant_builder_init(&builder, G_VARIANT_TYPE("a(ss)")); - for(const auto& app : value){ - const std::string& pkgname {app.first}; - const std::string& appname {app.second}; - g_variant_builder_add(&builder, "(ss)", pkgname.c_str(), appname.c_str()); - } - g_settings_set_value(m_settings_cunh, SETTINGS_CUNH_BLACKLIST_S, g_variant_builder_end(&builder)); - }); - } - locations.changed().connect([this](const std::vector& value){ const int n = value.size(); gchar** strv = g_new0(gchar*, n+1); @@ -166,6 +156,26 @@ LiveSettings::LiveSettings(): m_settings(g_settings_new(SETTINGS_INTERFACE)) snooze_duration.changed().connect([this](unsigned int value){ g_settings_set_uint(m_settings, SETTINGS_SNOOZE_DURATION_S, value); }); + + cal_notification_enabled.changed().connect([this](bool value){ + g_settings_set_boolean(m_settings_cal_notification, SETTINGS_NOTIFY_ENABLED_KEY, value); + }); + + cal_notification_sounds.changed().connect([this](bool value){ + g_settings_set_boolean(m_settings_cal_notification, SETTINGS_NOTIFY_SOUNDS_KEY, value); + }); + + cal_notification_vibrations.changed().connect([this](bool value){ + g_settings_set_boolean(m_settings_cal_notification, SETTINGS_NOTIFY_VIBRATIONS_KEY, value); + }); + + cal_notification_bubbles.changed().connect([this](bool value){ + g_settings_set_boolean(m_settings_cal_notification, SETTINGS_NOTIFY_BUBBLES_KEY, value); + }); + + cal_notification_list.changed().connect([this](bool value){ + g_settings_set_boolean(m_settings_cal_notification, SETTINGS_NOTIFY_LIST_KEY, value); + }); } /*** @@ -189,27 +199,6 @@ void LiveSettings::update_locations() locations.set(l); } -void LiveSettings::update_muted_apps() -{ - if (ayatana_common_utils_is_lomiri()) - { - std::set> apps; - - auto blacklist = g_settings_get_value(m_settings_cunh, SETTINGS_CUNH_BLACKLIST_S); - GVariantIter* iter {nullptr}; - g_variant_get (blacklist, "a(ss)", &iter); - gchar* pkgname; - gchar* appname; - while (g_variant_iter_loop (iter, "(ss)", &pkgname, &appname)) { - apps.insert(std::make_pair(pkgname,appname)); - } - g_variant_iter_free (iter); - g_clear_pointer(&blacklist, g_variant_unref); - - muted_apps.set(apps); - } -} - void LiveSettings::update_show_calendar() { const auto val = g_settings_get_boolean(m_settings, SETTINGS_SHOW_CALENDAR_S); @@ -308,21 +297,55 @@ void LiveSettings::update_snooze_duration() snooze_duration.set(g_settings_get_uint(m_settings, SETTINGS_SNOOZE_DURATION_S)); } +void LiveSettings::update_cal_notification_enabled() +{ + cal_notification_enabled.set(g_settings_get_boolean(m_settings_cal_notification, SETTINGS_NOTIFY_ENABLED_KEY)); +} + +void LiveSettings::update_cal_notification_sounds() +{ + cal_notification_sounds.set(g_settings_get_boolean(m_settings_cal_notification, SETTINGS_NOTIFY_SOUNDS_KEY)); +} + +void LiveSettings::update_cal_notification_vibrations() +{ + cal_notification_vibrations.set(g_settings_get_boolean(m_settings_cal_notification, SETTINGS_NOTIFY_VIBRATIONS_KEY)); +} + +void LiveSettings::update_cal_notification_bubbles() +{ + cal_notification_bubbles.set(g_settings_get_boolean(m_settings_cal_notification, SETTINGS_NOTIFY_BUBBLES_KEY)); +} + +void LiveSettings::update_cal_notification_list() +{ + cal_notification_list.set(g_settings_get_boolean(m_settings_cal_notification, SETTINGS_NOTIFY_LIST_KEY)); +} + /*** **** ***/ -void LiveSettings::on_changed_cunh(GSettings* /*settings*/, - gchar* key, - gpointer gself) +void LiveSettings::on_changed_cal_notification(GSettings* /*settings*/, + gchar* key, + gpointer gself) { - static_cast(gself)->update_key_cunh(key); + static_cast(gself)->update_key_cal_notification(key); } -void LiveSettings::update_key_cunh(const std::string& key) + +void LiveSettings::update_key_cal_notification(const std::string& key) { - if (key == SETTINGS_CUNH_BLACKLIST_S) - update_muted_apps(); + if (key == SETTINGS_NOTIFY_ENABLED_KEY) + update_cal_notification_enabled(); + else if (key == SETTINGS_NOTIFY_SOUNDS_KEY) + update_cal_notification_sounds(); + else if (key == SETTINGS_NOTIFY_VIBRATIONS_KEY) + update_cal_notification_vibrations(); + else if (key == SETTINGS_NOTIFY_BUBBLES_KEY) + update_cal_notification_bubbles(); + else if (key == SETTINGS_NOTIFY_LIST_KEY) + update_cal_notification_list(); } /*** diff --git a/src/snap.cpp b/src/snap.cpp index 51d04ae..1e71e7b 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -83,9 +83,9 @@ public: const Alarm& alarm, response_func on_response) { - // If calendar notifications are muted, don't show them - if (!appointment.is_ubuntu_alarm() && calendar_events_are_muted()) { - g_debug("Skipping muted calendar event '%s' notification", appointment.summary.c_str()); + // If calendar notifications are disabled, don't show them + if (!appointment.is_ubuntu_alarm() && !calendar_notifications_are_enabled()) { + g_debug("Skipping disabled calendar event '%s' notification", appointment.summary.c_str()); return; } @@ -96,13 +96,14 @@ public: const bool interactive = appointment.is_ubuntu_alarm() && m_engine->supports_actions(); // force the system to stay awake - auto awake = std::make_shared(m_engine->app_name()); + std::shared_ptr awake; + if (calendar_bubbles_enabled()) { + awake = std::make_shared(m_engine->app_name()); + } // calendar events are muted in silent mode; alarm clocks never are std::shared_ptr sound; - // FIXME: only play sounds for alarms for now, we should itegrate it with - // system settings to decide if we should play sounds for calendar notification or not - if (appointment.is_ubuntu_alarm()) { + if (appointment.is_ubuntu_alarm() || calendar_sounds_enabled()) { // create the sound. const auto role = appointment.is_ubuntu_alarm() ? "alarm" : "alert"; const auto uri = get_alarm_uri(appointment, alarm, m_settings); @@ -113,7 +114,7 @@ public: // create the haptic feedback... std::shared_ptr haptic; - if (should_vibrate()) { + if (should_vibrate() && calendar_vibrations_enabled()) { const auto haptic_mode = m_settings->alarm_haptic.get(); if (haptic_mode == "pulse") haptic = std::make_shared(ain::Haptic::MODE_PULSE, appointment.is_ubuntu_alarm()); @@ -189,15 +190,29 @@ public: private: - bool calendar_events_are_muted() const + bool calendar_notifications_are_enabled() const { - for(const auto& app : m_settings->muted_apps.get()) { - if (app.first == "com.ubuntu.calendar") { - return true; - } - } + return m_settings->cal_notification_enabled.get(); + } + + bool calendar_sounds_enabled() const + { + return m_settings->cal_notification_sounds.get(); + } - return false; + bool calendar_vibrations_enabled() const + { + return m_settings->cal_notification_vibrations.get(); + } + + bool calendar_bubbles_enabled() const + { + return m_settings->cal_notification_bubbles.get(); + } + + bool calendar_list_enabled() const + { + return m_settings->cal_notification_list.get(); } static void on_sound_proxy_ready(GObject* /*source_object*/, GAsyncResult* res, gpointer gself) diff --git a/tests/test-notification.cpp b/tests/test-notification.cpp index 50d7b57..b84c6f8 100644 --- a/tests/test-notification.cpp +++ b/tests/test-notification.cpp @@ -87,18 +87,16 @@ TEST_F(NotificationFixture,Notification) { false, true, false } }; - // combinatorial factor #4: system settings' notifications app blacklist - const std::set> blacklist_calendar { std::make_pair(std::string{"com.lomiri.calendar"}, std::string{"calendar-app"}) }; - const std::set> blacklist_empty; + // combinatorial factor #4: system settings' notifications disabled struct { - std::set> muted_apps; // apps that should not trigger notifications + bool cal_notification_enabled; // calendar app can trigger notifications std::set expected_notify_called; // do we expect the notification to show? std::set expected_vibrate_called; // do we expect the phone to vibrate? - } test_muted_apps[] = { - { blacklist_empty, std::set{ Appointment::Type::UBUNTU_ALARM, Appointment::Type::EVENT }, - std::set{ Appointment::Type::UBUNTU_ALARM, Appointment::Type::EVENT } }, - { blacklist_calendar, std::set{ Appointment::Type::UBUNTU_ALARM }, - std::set{ Appointment::Type::UBUNTU_ALARM } } + } test_cal_disabled[] = { + { true, std::set{ Appointment::Type::UBUNTU_ALARM, Appointment::Type::EVENT }, + std::set{ Appointment::Type::UBUNTU_ALARM, Appointment::Type::EVENT } }, + { false, std::set{ Appointment::Type::UBUNTU_ALARM }, + std::set{ Appointment::Type::UBUNTU_ALARM } } }; for (const auto& test_appt : test_appts) @@ -107,20 +105,20 @@ TEST_F(NotificationFixture,Notification) { for (const auto& test_vibes : test_other_vibrations) { - for (const auto& test_muted : test_muted_apps) + for (const auto& test_disabled : test_cal_disabled) { const bool expected_notify_called = test_appt.expected_notify_called && test_vibes.expected_notify_called - && (test_muted.expected_notify_called.count(test_appt.appt.type) > 0) + && (test_disabled.expected_notify_called.count(test_appt.appt.type) > 0) && test_haptic.expected_notify_called; const bool expected_vibrate_called = test_appt.expected_vibrate_called && test_vibes.expected_vibrate_called - && (test_muted.expected_vibrate_called.count(test_appt.appt.type) > 0) + && (test_disabled.expected_vibrate_called.count(test_appt.appt.type) > 0) && test_haptic.expected_vibrate_called; - // set test case properties: blacklist - settings->muted_apps.set(test_muted.muted_apps); + // set test case properties: cal_notification_enabled + settings->cal_notification_enabled.set(test_disabled.cal_notification_enabled); // set test case properties: haptic mode settings->alarm_haptic.set(test_haptic.haptic_mode); diff --git a/tests/test-settings.cpp b/tests/test-settings.cpp index d18b58a..d0ee369 100644 --- a/tests/test-settings.cpp +++ b/tests/test-settings.cpp @@ -43,7 +43,7 @@ protected: std::shared_ptr m_live; std::shared_ptr m_settings; GSettings * m_gsettings; - GSettings * m_gsettings_cunh; + GSettings * m_gsettings_cal_notification; void SetUp() override { @@ -53,7 +53,7 @@ protected: if (ayatana_common_utils_is_lomiri()) { - m_gsettings_cunh = g_settings_new(SETTINGS_CUNH_SCHEMA_ID); + m_gsettings_cal_notification = g_settings_new_with_path(SETTINGS_NOTIFY_SCHEMA_ID, SETTINGS_NOTIFY_CALENDAR_PATH); } m_live.reset(new LiveSettings); @@ -62,7 +62,7 @@ protected: void TearDown() override { - g_clear_object(&m_gsettings_cunh); + g_clear_object(&m_gsettings_cal_notification); g_clear_object(&m_gsettings); m_settings.reset(); m_live.reset(); @@ -70,62 +70,62 @@ protected: super::TearDown(); } - void TestBoolProperty(core::Property& property, const gchar* key) + void TestBoolProperty(GSettings* gsettings, core::Property& property, const gchar* key) { - EXPECT_EQ(g_settings_get_boolean(m_gsettings, key), property.get()); - g_settings_set_boolean(m_gsettings, key, false); + EXPECT_EQ(g_settings_get_boolean(gsettings, key), property.get()); + g_settings_set_boolean(gsettings, key, false); EXPECT_FALSE(property.get()); - g_settings_set_boolean(m_gsettings, key, true); + g_settings_set_boolean(gsettings, key, true); EXPECT_TRUE(property.get()); property.set(false); - EXPECT_FALSE(g_settings_get_boolean(m_gsettings, key)); + EXPECT_FALSE(g_settings_get_boolean(gsettings, key)); property.set(true); - EXPECT_TRUE(g_settings_get_boolean(m_gsettings, key)); + EXPECT_TRUE(g_settings_get_boolean(gsettings, key)); } - void TestStringProperty(core::Property& property, const gchar* key) + void TestStringProperty(GSettings* gsettings, core::Property& property, const gchar* key) { gchar* tmp; std::string str; - tmp = g_settings_get_string(m_gsettings, key); + tmp = g_settings_get_string(gsettings, key); EXPECT_EQ(tmp, property.get()); g_clear_pointer(&tmp, g_free); str = "a"; - g_settings_set_string(m_gsettings, key, str.c_str()); + g_settings_set_string(gsettings, key, str.c_str()); EXPECT_EQ(str, property.get()); str = "b"; - g_settings_set_string(m_gsettings, key, str.c_str()); + g_settings_set_string(gsettings, key, str.c_str()); EXPECT_EQ(str, property.get()); str = "a"; property.set(str); - tmp = g_settings_get_string(m_gsettings, key); + tmp = g_settings_get_string(gsettings, key); EXPECT_EQ(str, tmp); g_clear_pointer(&tmp, g_free); str = "b"; property.set(str); - tmp = g_settings_get_string(m_gsettings, key); + tmp = g_settings_get_string(gsettings, key); EXPECT_EQ(str, tmp); g_clear_pointer(&tmp, g_free); } - void TestUIntProperty(core::Property& property, const gchar* key) + void TestUIntProperty(GSettings* gsettings, core::Property& property, const gchar* key) { - EXPECT_EQ(g_settings_get_uint(m_gsettings, key), property.get()); + EXPECT_EQ(g_settings_get_uint(gsettings, key), property.get()); unsigned int expected_values[] = { 1, 2, 3 }; // modify GSettings and confirm that the new value is propagated for(const auto& expected_value : expected_values) { - g_settings_set_uint(m_gsettings, key, expected_value); + g_settings_set_uint(gsettings, key, expected_value); EXPECT_EQ(expected_value, property.get()); - EXPECT_EQ(expected_value, g_settings_get_uint(m_gsettings, key)); + EXPECT_EQ(expected_value, g_settings_get_uint(gsettings, key)); } // modify the property and confirm that the new value is propagated @@ -133,7 +133,7 @@ protected: { property.set(expected_value); EXPECT_EQ(expected_value, property.get()); - EXPECT_EQ(expected_value, g_settings_get_uint(m_gsettings, key)); + EXPECT_EQ(expected_value, g_settings_get_uint(gsettings, key)); } } }; @@ -149,31 +149,31 @@ TEST_F(SettingsFixture, HelloWorld) TEST_F(SettingsFixture, BoolProperties) { - TestBoolProperty(m_settings->show_seconds, SETTINGS_SHOW_SECONDS_S); - TestBoolProperty(m_settings->show_calendar, SETTINGS_SHOW_CALENDAR_S); - TestBoolProperty(m_settings->show_date, SETTINGS_SHOW_DATE_S); - TestBoolProperty(m_settings->show_day, SETTINGS_SHOW_DAY_S); - TestBoolProperty(m_settings->show_detected_location, SETTINGS_SHOW_DETECTED_S); - TestBoolProperty(m_settings->show_events, SETTINGS_SHOW_EVENTS_S); - TestBoolProperty(m_settings->show_locations, SETTINGS_SHOW_LOCATIONS_S); - TestBoolProperty(m_settings->show_week_numbers, SETTINGS_SHOW_WEEK_NUMBERS_S); - TestBoolProperty(m_settings->show_year, SETTINGS_SHOW_YEAR_S); + TestBoolProperty(m_gsettings, m_settings->show_seconds, SETTINGS_SHOW_SECONDS_S); + TestBoolProperty(m_gsettings, m_settings->show_calendar, SETTINGS_SHOW_CALENDAR_S); + TestBoolProperty(m_gsettings, m_settings->show_date, SETTINGS_SHOW_DATE_S); + TestBoolProperty(m_gsettings, m_settings->show_day, SETTINGS_SHOW_DAY_S); + TestBoolProperty(m_gsettings, m_settings->show_detected_location, SETTINGS_SHOW_DETECTED_S); + TestBoolProperty(m_gsettings, m_settings->show_events, SETTINGS_SHOW_EVENTS_S); + TestBoolProperty(m_gsettings, m_settings->show_locations, SETTINGS_SHOW_LOCATIONS_S); + TestBoolProperty(m_gsettings, m_settings->show_week_numbers, SETTINGS_SHOW_WEEK_NUMBERS_S); + TestBoolProperty(m_gsettings, m_settings->show_year, SETTINGS_SHOW_YEAR_S); } TEST_F(SettingsFixture, UIntProperties) { - TestUIntProperty(m_settings->alarm_duration, SETTINGS_ALARM_DURATION_S); - TestUIntProperty(m_settings->alarm_volume, SETTINGS_ALARM_VOLUME_S); - TestUIntProperty(m_settings->snooze_duration, SETTINGS_SNOOZE_DURATION_S); + TestUIntProperty(m_gsettings, m_settings->alarm_duration, SETTINGS_ALARM_DURATION_S); + TestUIntProperty(m_gsettings, m_settings->alarm_volume, SETTINGS_ALARM_VOLUME_S); + TestUIntProperty(m_gsettings, m_settings->snooze_duration, SETTINGS_SNOOZE_DURATION_S); } TEST_F(SettingsFixture, StringProperties) { - TestStringProperty(m_settings->custom_time_format, SETTINGS_CUSTOM_TIME_FORMAT_S); - TestStringProperty(m_settings->timezone_name, SETTINGS_TIMEZONE_NAME_S); - TestStringProperty(m_settings->alarm_sound, SETTINGS_ALARM_SOUND_S); - TestStringProperty(m_settings->calendar_sound, SETTINGS_CALENDAR_SOUND_S); - TestStringProperty(m_settings->alarm_haptic, SETTINGS_ALARM_HAPTIC_S); + TestStringProperty(m_gsettings, m_settings->custom_time_format, SETTINGS_CUSTOM_TIME_FORMAT_S); + TestStringProperty(m_gsettings, m_settings->timezone_name, SETTINGS_TIMEZONE_NAME_S); + TestStringProperty(m_gsettings, m_settings->alarm_sound, SETTINGS_ALARM_SOUND_S); + TestStringProperty(m_gsettings, m_settings->calendar_sound, SETTINGS_CALENDAR_SOUND_S); + TestStringProperty(m_gsettings, m_settings->alarm_haptic, SETTINGS_ALARM_HAPTIC_S); } TEST_F(SettingsFixture, TimeFormatMode) @@ -237,36 +237,9 @@ TEST_F(SettingsFixture, Locations) TEST_F(SettingsFixture, MutedApps) { - const auto key = SETTINGS_CUNH_BLACKLIST_S; - - struct { - std::string pkgname; - std::string appname; - } apps[] = { - { "", "lomiri-system-settings" }, - { "com.lomiri.calendar", "calendar" }, - { "com.lomiri.developer.webapps.webapp-facebook", "webapp-facebook" }, - { "com.lomiri.reminders", "reminders" } - }; - std::set> apps_set; - for (const auto& app : apps) - apps_set.insert(std::make_pair(app.pkgname, app.appname)); - - // test that changing Settings is reflected in the schema - m_settings->muted_apps.set(apps_set); - auto v = g_settings_get_value(m_gsettings_cunh, key); - auto str = g_variant_print(v, true); - EXPECT_STREQ("[('', 'lomiri-system-settings'), ('com.lomiri.calendar', 'calendar'), ('com.lomiri.developer.webapps.webapp-facebook', 'webapp-facebook'), ('com.lomiri.reminders', 'reminders')]", str); - g_clear_pointer(&str, g_free); - - // test that clearing the schema clears the settings - g_settings_reset(m_gsettings_cunh, key); - EXPECT_EQ(0, m_settings->muted_apps.get().size()); - - // test thst setting the schema updates the settings - g_settings_set_value(m_gsettings_cunh, key, v); - EXPECT_EQ(apps_set, m_settings->muted_apps.get()); - - // cleanup - g_clear_pointer(&v, g_variant_unref); + TestBoolProperty(m_gsettings_cal_notification, m_settings->cal_notification_enabled, SETTINGS_NOTIFY_ENABLED_KEY); + TestBoolProperty(m_gsettings_cal_notification, m_settings->cal_notification_sounds, SETTINGS_NOTIFY_SOUNDS_KEY); + TestBoolProperty(m_gsettings_cal_notification, m_settings->cal_notification_vibrations, SETTINGS_NOTIFY_VIBRATIONS_KEY); + TestBoolProperty(m_gsettings_cal_notification, m_settings->cal_notification_bubbles, SETTINGS_NOTIFY_BUBBLES_KEY); + TestBoolProperty(m_gsettings_cal_notification, m_settings->cal_notification_list, SETTINGS_NOTIFY_LIST_KEY); } -- cgit v1.2.3 From 686579f67c368512ac36267dd5bd13eff2a0abb5 Mon Sep 17 00:00:00 2001 From: Arthur Mello Date: Fri, 24 Jun 2016 09:26:06 -0300 Subject: Make sure that calendar settings do not affect alarm notifications --- src/snap.cpp | 6 +++--- tests/test-notification.cpp | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'src/snap.cpp') diff --git a/src/snap.cpp b/src/snap.cpp index 1e71e7b..273f125 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -97,8 +97,8 @@ public: // force the system to stay awake std::shared_ptr awake; - if (calendar_bubbles_enabled()) { - awake = std::make_shared(m_engine->app_name()); + if (appointment.is_ubuntu_alarm() || calendar_bubbles_enabled()) { + awake = std::make_shared(m_engine->app_name()); } // calendar events are muted in silent mode; alarm clocks never are @@ -114,7 +114,7 @@ public: // create the haptic feedback... std::shared_ptr haptic; - if (should_vibrate() && calendar_vibrations_enabled()) { + if (should_vibrate() && (appointment.is_ubuntu_alarm() || calendar_vibrations_enabled())) { const auto haptic_mode = m_settings->alarm_haptic.get(); if (haptic_mode == "pulse") haptic = std::make_shared(ain::Haptic::MODE_PULSE, appointment.is_ubuntu_alarm()); diff --git a/tests/test-notification.cpp b/tests/test-notification.cpp index 58c0760..0db6ab9 100644 --- a/tests/test-notification.cpp +++ b/tests/test-notification.cpp @@ -230,6 +230,12 @@ TEST_F(NotificationFixture,Response) }; + settings->cal_notification_enabled.set(true); + settings->cal_notification_sounds.set(true); + settings->cal_notification_vibrations.set(true); + settings->cal_notification_bubbles.set(true); + settings->cal_notification_list.set(true); + // walk through the tests for (const auto& test : tests) { -- cgit v1.2.3 From f42d0a01dcbd66920f65d1e5bd784914a797d773 Mon Sep 17 00:00:00 2001 From: Arthur Mello Date: Wed, 29 Jun 2016 21:37:56 -0300 Subject: Fix notifications so it respects if it should or not show bubbles or add to notification list --- include/notifications/notifications.h | 6 ++++++ src/notifications.cpp | 23 +++++++++++++++++++++++ src/snap.cpp | 8 ++++---- 3 files changed, 33 insertions(+), 4 deletions(-) (limited to 'src/snap.cpp') diff --git a/include/notifications/notifications.h b/include/notifications/notifications.h index 450c45b..a76ec45 100644 --- a/include/notifications/notifications.h +++ b/include/notifications/notifications.h @@ -77,6 +77,12 @@ public: /** Sets the time-out callback. This will be called exactly once. */ void set_timeout_callback (std::function); + /** Sets if a notification bubble should be displayed. */ + void set_show_notification_bubble (bool show); + + /** Sets if notification should be posted to messaging menu after it is closed. */ + void set_post_to_messaging_menu (bool post); + private: friend class Engine; diff --git a/src/notifications.cpp b/src/notifications.cpp index 3c90e57..4a2c846 100644 --- a/src/notifications.cpp +++ b/src/notifications.cpp @@ -63,6 +63,8 @@ public: std::vector> m_actions; std::function m_closed_callback; std::function m_timeout_callback; + bool m_show_notification_bubble; + bool m_post_to_messaging_menu; }; Builder::Builder(): @@ -128,6 +130,18 @@ Builder::set_start_time (uint64_t time) impl->m_start_time = time; } +void +Builder::set_show_notification_bubble (bool show) +{ + impl->m_show_notification_bubble = show; +} + +void +Builder::set_post_to_messaging_menu (bool post) +{ + impl->m_post_to_messaging_menu = post; +} + /*** **** ***/ @@ -265,6 +279,11 @@ public: g_signal_connect (nn.get(), "closed", G_CALLBACK(on_notification_closed), this); + if (!info.m_show_notification_bubble) { + post(info); + return ret; + } + GError * error = nullptr; if (notify_notification_show(nn.get(), &error)) { @@ -284,6 +303,10 @@ public: std::string post(const Builder::Impl& data) { + if (!data.m_post_to_messaging_menu) { + return ""; + } + if (!m_messaging_app) { return std::string(); } diff --git a/src/snap.cpp b/src/snap.cpp index 273f125..1b7c183 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -96,10 +96,7 @@ public: const bool interactive = appointment.is_ubuntu_alarm() && m_engine->supports_actions(); // force the system to stay awake - std::shared_ptr awake; - if (appointment.is_ubuntu_alarm() || calendar_bubbles_enabled()) { - awake = std::make_shared(m_engine->app_name()); - } + std::shared_ptr awake = std::make_shared(m_engine->app_name()); // calendar events are muted in silent mode; alarm clocks never are std::shared_ptr sound; @@ -183,6 +180,9 @@ public: }); } + b.set_show_notification_bubble(appointment.is_ubuntu_alarm() || calendar_bubbles_enabled()); + b.set_post_to_messaging_menu(appointment.is_ubuntu_alarm() || calendar_list_enabled()); + const auto key = m_engine->show(b); if (key) m_notifications.insert (key); -- cgit v1.2.3 From 94af77abe22cf5fe8845d3d0cd4a9bc2ca5ab38a Mon Sep 17 00:00:00 2001 From: Arthur Mello Date: Fri, 1 Jul 2016 18:26:46 -0300 Subject: Only wake device if bubbles notifications are enabled --- src/snap.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/snap.cpp') diff --git a/src/snap.cpp b/src/snap.cpp index 1b7c183..d0c12a0 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -96,7 +96,10 @@ public: const bool interactive = appointment.is_ubuntu_alarm() && m_engine->supports_actions(); // force the system to stay awake - std::shared_ptr awake = std::make_shared(m_engine->app_name()); + std::shared_ptr awake; + if (appointment.is_ubuntu_alarm() || calendar_bubbles_enabled()) { + awake = std::make_shared(m_engine->app_name()); + } // calendar events are muted in silent mode; alarm clocks never are std::shared_ptr sound; -- cgit v1.2.3 From cd03321181ba64c66a93c60d444dfea59f293fa1 Mon Sep 17 00:00:00 2001 From: Arthur Mello Date: Mon, 4 Jul 2016 16:30:18 -0300 Subject: If in silent mode should only vibrate if the settings say so --- include/datetime/settings-live.h | 4 ++++ include/datetime/settings-shared.h | 2 ++ include/datetime/settings.h | 1 + src/settings-live.cpp | 38 +++++++++++++++++++++++++++++++++++--- src/snap.cpp | 20 ++++++++++++++------ 5 files changed, 56 insertions(+), 9 deletions(-) (limited to 'src/snap.cpp') diff --git a/include/datetime/settings-live.h b/include/datetime/settings-live.h index 4aeaa9b..85071ce 100644 --- a/include/datetime/settings-live.h +++ b/include/datetime/settings-live.h @@ -40,8 +40,10 @@ public: private: static void on_changed_ccid(GSettings*, gchar*, gpointer); static void on_changed_cal_notification(GSettings*, gchar*, gpointer); + static void on_changed_general_notification(GSettings*, gchar*, gpointer); void update_key_ccid(const std::string& key); void update_key_cal_notification(const std::string& key); + void update_key_general_notification(const std::string& key); void update_custom_time_format(); void update_locations(); @@ -67,9 +69,11 @@ private: void update_cal_notification_vibrations(); void update_cal_notification_bubbles(); void update_cal_notification_list(); + void update_vibrate_silent_mode(); GSettings* m_settings; GSettings* m_settings_cal_notification; + GSettings* m_settings_general_notification; // we've got a raw pointer here, so disable copying LiveSettings(const LiveSettings&) =delete; diff --git a/include/datetime/settings-shared.h b/include/datetime/settings-shared.h index 236b8f1..7280c16 100644 --- a/include/datetime/settings-shared.h +++ b/include/datetime/settings-shared.h @@ -51,6 +51,8 @@ TimeFormatMode; #define SETTINGS_ALARM_HAPTIC_S "alarm-haptic-feedback" #define SETTINGS_SNOOZE_DURATION_S "snooze-duration-minutes" +#define SETTINGS_NOTIFY_APPS_SCHEMA_ID "com.lomiri.notifications.settings.applications" +#define SETTINGS_VIBRATE_SILENT_KEY "vibrate-silent-mode" #define SETTINGS_NOTIFY_SCHEMA_ID "com.lomiri.notifications.settings" #define SETTINGS_NOTIFY_CALENDAR_PATH "/com/lomiri/NotificationSettings/com.lomiri.calendar/calendar/" #define SETTINGS_NOTIFY_ENABLED_KEY "enable-notifications" diff --git a/include/datetime/settings.h b/include/datetime/settings.h index 5ae00f6..af9227d 100644 --- a/include/datetime/settings.h +++ b/include/datetime/settings.h @@ -66,6 +66,7 @@ public: core::Property cal_notification_vibrations; core::Property cal_notification_bubbles; core::Property cal_notification_list; + core::Property vibrate_silent_mode; }; } // namespace datetime diff --git a/src/settings-live.cpp b/src/settings-live.cpp index 01de7b8..66590e0 100644 --- a/src/settings-live.cpp +++ b/src/settings-live.cpp @@ -34,14 +34,19 @@ namespace datetime { LiveSettings::~LiveSettings() { + g_clear_object(&m_settings_general_notification); g_clear_object(&m_settings_cal_notification); g_clear_object(&m_settings); } -LiveSettings::LiveSettings(): m_settings(g_settings_new(SETTINGS_INTERFACE)), m_settings_cal_notification(g_settings_new_with_path(SETTINGS_NOTIFY_SCHEMA_ID, SETTINGS_NOTIFY_CALENDAR_PATH)) +LiveSettings::LiveSettings(): + m_settings(g_settings_new(SETTINGS_INTERFACE)), + m_settings_cal_notification(g_settings_new_with_path(SETTINGS_NOTIFY_SCHEMA_ID, SETTINGS_NOTIFY_CALENDAR_PATH)), + m_settings_general_notification(g_settings_new(SETTINGS_NOTIFY_APPS_SCHEMA_ID)) { - g_signal_connect (m_settings, "changed", G_CALLBACK(on_changed_ccid), this); - g_signal_connect (m_settings_cal_notification, "changed", G_CALLBACK(on_changed_cal_notification), this); + g_signal_connect (m_settings, "changed", G_CALLBACK(on_changed_ccid), this); + g_signal_connect (m_settings_cal_notification, "changed", G_CALLBACK(on_changed_cal_notification), this); + g_signal_connect (m_settings_general_notification, "changed", G_CALLBACK(on_changed_general_notification), this); // init the Properties from the GSettings backend update_custom_time_format(); @@ -68,6 +73,7 @@ LiveSettings::LiveSettings(): m_settings(g_settings_new(SETTINGS_INTERFACE)), m_ update_cal_notification_vibrations(); update_cal_notification_bubbles(); update_cal_notification_list(); + update_vibrate_silent_mode(); // now listen for clients to change the properties s.t. we can sync update GSettings @@ -171,6 +177,10 @@ LiveSettings::LiveSettings(): m_settings(g_settings_new(SETTINGS_INTERFACE)), m_ cal_notification_list.changed().connect([this](bool value){ g_settings_set_boolean(m_settings_cal_notification, SETTINGS_NOTIFY_LIST_KEY, value); }); + + vibrate_silent_mode.changed().connect([this](bool value){ + g_settings_set_boolean(m_settings_general_notification, SETTINGS_VIBRATE_SILENT_KEY, value); + }); } /*** @@ -317,6 +327,11 @@ void LiveSettings::update_cal_notification_list() cal_notification_list.set(g_settings_get_boolean(m_settings_cal_notification, SETTINGS_NOTIFY_LIST_KEY)); } +void LiveSettings::update_vibrate_silent_mode() +{ + vibrate_silent_mode.set(g_settings_get_boolean(m_settings_general_notification, SETTINGS_VIBRATE_SILENT_KEY)); +} + /*** **** ***/ @@ -347,6 +362,23 @@ void LiveSettings::update_key_cal_notification(const std::string& key) **** ***/ +void LiveSettings::on_changed_general_notification(GSettings* /*settings*/, + gchar* key, + gpointer gself) +{ + static_cast(gself)->update_key_general_notification(key); +} + +void LiveSettings::update_key_general_notification(const std::string& key) +{ + if (key == SETTINGS_VIBRATE_SILENT_KEY) + update_vibrate_silent_mode(); +} + +/*** +**** +***/ + void LiveSettings::on_changed_ccid(GSettings* /*settings*/, gchar* key, gpointer gself) diff --git a/src/snap.cpp b/src/snap.cpp index d0c12a0..363e0df 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -97,9 +97,9 @@ public: // force the system to stay awake std::shared_ptr awake; - if (appointment.is_ubuntu_alarm() || calendar_bubbles_enabled()) { - awake = std::make_shared(m_engine->app_name()); - } + if (appointment.is_ubuntu_alarm() || calendar_bubbles_enabled() || calendar_list_enabled()) { + awake = std::make_shared(m_engine->app_name()); + } // calendar events are muted in silent mode; alarm clocks never are std::shared_ptr sound; @@ -115,9 +115,12 @@ public: // create the haptic feedback... std::shared_ptr haptic; if (should_vibrate() && (appointment.is_ubuntu_alarm() || calendar_vibrations_enabled())) { - const auto haptic_mode = m_settings->alarm_haptic.get(); - if (haptic_mode == "pulse") - haptic = std::make_shared(ain::Haptic::MODE_PULSE, appointment.is_ubuntu_alarm()); + // when in silent mode should only vibrate if user defined so + if (!silent_mode() || vibrate_in_silent_mode_enabled()) { + const auto haptic_mode = m_settings->alarm_haptic.get(); + if (haptic_mode == "pulse") + haptic = std::make_shared(ain::Haptic::MODE_PULSE, appointment.is_ubuntu_alarm()); + } } // show a notification... @@ -218,6 +221,11 @@ private: return m_settings->cal_notification_list.get(); } + bool vibrate_in_silent_mode_enabled() const + { + return m_settings->vibrate_silent_mode.get(); + } + static void on_sound_proxy_ready(GObject* /*source_object*/, GAsyncResult* res, gpointer gself) { GError * error; -- cgit v1.2.3 From 2467a3c607ce561bd364500d9c41d547787c5c5e Mon Sep 17 00:00:00 2001 From: Arthur Mello Date: Mon, 4 Jul 2016 20:44:47 -0300 Subject: Should not use sounds notifications for calendar in silent mode --- src/snap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/snap.cpp') diff --git a/src/snap.cpp b/src/snap.cpp index 363e0df..c834f72 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -103,7 +103,7 @@ public: // calendar events are muted in silent mode; alarm clocks never are std::shared_ptr sound; - if (appointment.is_ubuntu_alarm() || calendar_sounds_enabled()) { + if (appointment.is_ubuntu_alarm() || (calendar_sounds_enabled() && !silent_mode())) { // create the sound. const auto role = appointment.is_ubuntu_alarm() ? "alarm" : "alert"; const auto uri = get_alarm_uri(appointment, alarm, m_settings); -- cgit v1.2.3 From 6863282c60b01752ecd53ea329a74940ee8380e4 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 6 Oct 2016 12:08:29 -0500 Subject: in Snap, add a constructor arg for the system bus because we need it when instantiating Awake objects --- include/datetime/snap.h | 7 ++++++- src/snap.cpp | 36 +++++++++++++++++++++++------------- 2 files changed, 29 insertions(+), 14 deletions(-) (limited to 'src/snap.cpp') diff --git a/include/datetime/snap.h b/include/datetime/snap.h index 099426b..baa765b 100644 --- a/include/datetime/snap.h +++ b/include/datetime/snap.h @@ -24,6 +24,9 @@ #include #include +#include + +#include // GDBusConnection #include #include @@ -39,7 +42,9 @@ class Snap { public: Snap(const std::shared_ptr& engine, - const std::shared_ptr& settings); + const std::shared_ptr& sound_builder, + const std::shared_ptr& settings, + GDBusConnection* system_bus); virtual ~Snap(); enum class Response { None, Snooze, ShowApp }; diff --git a/src/snap.cpp b/src/snap.cpp index c834f72..a55f760 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -53,19 +53,25 @@ class Snap::Impl public: Impl(const std::shared_ptr& engine, - const std::shared_ptr& settings): + const std::shared_ptr& sound_builder, + const std::shared_ptr& settings, + GDBusConnection* system_bus): m_engine(engine), + m_sound_builder(sound_builder), m_settings(settings), - m_cancellable(g_cancellable_new()) + m_cancellable(g_cancellable_new()), + m_system_bus{G_DBUS_CONNECTION(g_object_ref(system_bus))} { auto object_path = g_strdup_printf("/org/freedesktop/Accounts/User%lu", (gulong)getuid()); - accounts_service_sound_proxy_new_for_bus(G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, - "org.freedesktop.Accounts", - object_path, - m_cancellable, - on_sound_proxy_ready, - this); + + + accounts_service_sound_proxy_new(m_system_bus, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.Accounts", + object_path, + m_cancellable, + on_sound_proxy_ready, + this); g_free(object_path); } @@ -74,6 +80,7 @@ public: g_cancellable_cancel(m_cancellable); g_clear_object(&m_cancellable); g_clear_object(&m_accounts_service_sound_proxy); + g_clear_object(&m_system_bus); for (const auto& key : m_notifications) m_engine->close (key); @@ -98,7 +105,7 @@ public: // force the system to stay awake std::shared_ptr awake; if (appointment.is_ubuntu_alarm() || calendar_bubbles_enabled() || calendar_list_enabled()) { - awake = std::make_shared(m_engine->app_name()); + awake = std::make_shared(m_system_bus, m_engine->app_name()); } // calendar events are muted in silent mode; alarm clocks never are @@ -231,7 +238,7 @@ private: GError * error; error = nullptr; - auto proxy = accounts_service_sound_proxy_new_for_bus_finish (res, &error); + auto proxy = accounts_service_sound_proxy_new_finish (res, &error); if (error != nullptr) { if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) @@ -297,6 +304,7 @@ private: std::set m_notifications; GCancellable * m_cancellable {nullptr}; AccountsServiceSound * m_accounts_service_sound_proxy {nullptr}; + GDBusConnection * m_system_bus {nullptr}; static constexpr char const * ACTION_NONE {"none"}; static constexpr char const * ACTION_SNOOZE {"snooze"}; @@ -308,8 +316,10 @@ private: ***/ Snap::Snap(const std::shared_ptr& engine, - const std::shared_ptr& settings): - impl(new Impl(engine, settings)) + const std::shared_ptr& sound_builder, + const std::shared_ptr& settings, + GDBusConnection* system_bus): + impl(new Impl(engine, sound_builder, settings, system_bus)) { } -- cgit v1.2.3 From 0898d70491061913fcadfe65d7cf1bf016d6d241 Mon Sep 17 00:00:00 2001 From: farkasdvd <30418389+farkasdvd@users.noreply.github.com> Date: Wed, 26 May 2021 00:07:13 +0200 Subject: Alarm snoozes after timeout (#29) Changes the default behavior for an alarm timeout from "no action" to "snooze". --- src/snap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/snap.cpp') diff --git a/src/snap.cpp b/src/snap.cpp index a55f760..00c4743 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -176,7 +176,7 @@ public: b.set_closed_callback([appointment, alarm, on_response, sound, awake, haptic] (const std::string& action){ Snap::Response response; - if (action == ACTION_SNOOZE) + if ((action == ACTION_SNOOZE) || (appointment.is_ubuntu_alarm() && action.empty())) response = Snap::Response::Snooze; else if (action == ACTION_SHOW_APP) response = Snap::Response::ShowApp; -- cgit v1.2.3