aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjakob.stendahl <jakob.stendahl@infomedia.dk>2024-07-13 15:05:11 +0200
committerjakob.stendahl <jakob.stendahl@infomedia.dk>2024-07-13 15:05:11 +0200
commit7c52e13134c29dbde4f7678be1be431b62afe91f (patch)
tree3d49cd3b64af9a3c0e6aae2871f2cd5526425535
parented74ab2d27460ec11a29f6d005a003d69104d7c5 (diff)
downloadsimple-notification-daemon-7c52e13134c29dbde4f7678be1be431b62afe91f.tar.gz
simple-notification-daemon-7c52e13134c29dbde4f7678be1be431b62afe91f.zip
Add systemd service, add clear method call, add paging to snotifc
-rw-r--r--Makefile9
-rw-r--r--snotif.c15
-rw-r--r--snotif.h2
-rw-r--r--snotifc.c119
-rw-r--r--snotifd.c15
-rw-r--r--snotifd.service13
6 files changed, 162 insertions, 11 deletions
diff --git a/Makefile b/Makefile
index 38c3773..e77241b 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@ CFLAGS = -g -Wall -O ${CFLAGS_DBUS}
DEST =
-.PHONY: clean
+.PHONY: install clean
all: snotifd snotifc
o_files := $(patsubst %.c,%.o,$(wildcard *.c))
@@ -19,8 +19,11 @@ snotifc: ${o_files}
${GCC} -o $@ $@.o snotif.o ${CFLAGS} -lncursesw
install: snotifc snotifd
- install snotifd ${DEST}/usr/local/bin/snotifd
- install snotifc ${DEST}/usr/local/bin/snotifc
+ install snotifd ${HOME}/bin/snotifd
+ install snotifc ${HOME}/bin/snotifc
+ mkdir -p ${XDG_CONFIG_HOME}/systemd/user/
+ install snotifd.service ${XDG_CONFIG_HOME}/systemd/user/
+ systemctl --user daemon-reload
clean:
rm -f *.o
diff --git a/snotif.c b/snotif.c
index 8d914e5..5d8b387 100644
--- a/snotif.c
+++ b/snotif.c
@@ -72,3 +72,18 @@ void notifs_list_free(struct NotifsList* list) {
free(list->list);
free(list);
}
+
+void notifs_list_clear(struct NotifsList* list) {
+ for (unsigned int i = 0; i < list->element_count; i++) {
+ if (list->list[i]->app_name)
+ free(list->list[i]->app_name);
+ if (list->list[i]->app_icon)
+ free(list->list[i]->app_icon);
+ if (list->list[i]->summary)
+ free(list->list[i]->summary);
+ if (list->list[i]->body)
+ free(list->list[i]->body);
+ free(list->list[i]);
+ }
+ list->element_count = 0;
+}
diff --git a/snotif.h b/snotif.h
index dd52ac4..16c8667 100644
--- a/snotif.h
+++ b/snotif.h
@@ -12,6 +12,7 @@
#define DBUS_METHOD_GETLIST "GetNotifications"
#define DBUS_METHOD_GETUNSEENCOUNT "GetUnseenCount"
#define DBUS_METHOD_SETSEEN "SetSeen"
+#define DBUS_METHOD_CLEAR "ClearAll"
// Curses related constants
#define CPAIR_SEL 132
@@ -44,5 +45,6 @@ void notifs_list_init(struct NotifsList** list);
void notifs_list_set(struct NotifsList* list, struct NotifyParams* notif);
void notifs_list_free(struct NotifsList* list);
int notifs_list_set_seen(struct NotifsList* list, unsigned int id, bool read);
+void notifs_list_clear(struct NotifsList* list);
#endif
diff --git a/snotifc.c b/snotifc.c
index ebda38a..265e2ed 100644
--- a/snotifc.c
+++ b/snotifc.c
@@ -91,6 +91,37 @@ void set_notif_seen(DBusConnection* conn, uint id, bool seen) {
dbus_message_unref(msg);
}
+void clear_all(DBusConnection* conn) {
+ DBusMessage* msg;
+ DBusMessageIter args;
+ DBusPendingCall* pending;
+
+ msg = dbus_message_new_method_call(
+ DBUS_CLIENT_INTERFACE,
+ DBUS_CLIENT_OBJECT,
+ DBUS_CLIENT_INTERFACE,
+ DBUS_METHOD_CLEAR
+ );
+
+ dbus_message_iter_init_append(msg, &args);
+
+ if (!dbus_connection_send_with_reply(conn, msg, &pending, -1)) {
+ fprintf(stderr, "Out Of Memory!\n");
+ exit(1);
+ }
+ dbus_connection_flush(conn);
+ dbus_message_unref(msg);
+
+ dbus_pending_call_block(pending);
+ msg = dbus_pending_call_steal_reply(pending);
+ if (msg == NULL) {
+ fprintf(stderr, "Reply Null\n"); exit(1);
+ }
+ dbus_pending_call_unref(pending);
+
+ dbus_message_unref(msg);
+}
+
void print_notification_list(DBusConnection* conn) {
DBusMessage* msg;
DBusMessageIter args;
@@ -144,7 +175,6 @@ void print_notification_list(DBusConnection* conn) {
dbus_message_iter_get_basic(&struct_iter, &body);
dbus_message_iter_next(&struct_iter);
- //printf("Received Struct: { id: %d, app_name: %s, summary: %s, body: %s }\n", id, app_name, summary, body);
printf(KITAL"%10s"KNRM" ┃ "KMAG"%s"KNRM"\n", app_name, summary);
dbus_message_iter_next(&array_iter);
@@ -269,7 +299,12 @@ void curses_init() {
}
void curses_display_menu(int c_id) {
- mvprintw(LINES - 1, 0, " F7");
+ mvprintw(LINES - 1, 0, " F2");
+ attron(COLOR_PAIR(2));
+ printw("Show notification");
+ attroff(COLOR_PAIR(2));
+
+ printw(" F7");
attron(COLOR_PAIR(2));
printw("Toogle read");
attroff(COLOR_PAIR(2));
@@ -279,6 +314,11 @@ void curses_display_menu(int c_id) {
printw("Mark all read");
attroff(COLOR_PAIR(2));
+ printw(" F9");
+ attron(COLOR_PAIR(2));
+ printw("Clear");
+ attroff(COLOR_PAIR(2));
+
printw("F10");
attron(COLOR_PAIR(2));
printw("Quit");
@@ -309,7 +349,7 @@ void curses_display_notifs(struct NotifsList* notifs, int start, int selected) {
size_t ri;
struct NotifyParams* notif;
- for (size_t i = 0; i < items; i++) {
+ for (size_t i = start; i < items+start; i++) {
ri = notifs->element_count - i - 1;
if (!notifs->list[ri])
continue;
@@ -324,11 +364,11 @@ void curses_display_notifs(struct NotifsList* notifs, int start, int selected) {
if (notif->seen) {
attron(COLOR_PAIR((CPAIR_B + 3) | extra_bits));
attron(A_ITALIC);
- mvprintw(i, 0, " %s", time);
+ mvprintw(i-start, 0, " %s", time);
attroff(A_ITALIC);
printw(" │ ");
attron(A_ITALIC);
- printw("%*s ", w_app_name, notif->app_name);
+ printw("%*s", w_app_name, notif->app_name);
attroff(A_ITALIC);
printw(" │ ");
attron(A_ITALIC);
@@ -336,7 +376,7 @@ void curses_display_notifs(struct NotifsList* notifs, int start, int selected) {
attroff(A_ITALIC);
} else {
attron(A_ITALIC);
- mvprintw(i, 0, " %s", time);
+ mvprintw(i-start, 0, " %s", time);
attroff(A_ITALIC);
printw(" │ ");
attron(COLOR_PAIR((CPAIR_B + 2) | extra_bits));
@@ -410,17 +450,27 @@ void show_full_notif(int id, struct NotifsList* notifs) {
void curses_handle_input(DBusConnection* conn, int ch, int* start, int* selected, struct NotifsList* notifs) {
unsigned int id = notifs->element_count - (*selected) - 1;
+ WINDOW* win;
+ WINDOW* progress;
switch (ch) {
case KEY_DOWN:
case 'j':
if ((*selected) < notifs->element_count-1) {
(*selected)++;
+ if ((*selected) + (*start) > LINES-2) {
+ (*start)++;
+ clear();
+ }
}
break;
case KEY_UP:
case 'k':
if ((*selected) > 0) {
(*selected)--;
+ if ((*selected) < (*start)) {
+ (*start)--;
+ clear();
+ }
}
break;
case KEY_ENTER:
@@ -433,11 +483,45 @@ void curses_handle_input(DBusConnection* conn, int ch, int* start, int* selected
set_notif_seen(conn, id, !(notifs->list[id]->seen));
break;
case KEY_F(8):
+ win = newwin(8, 30, (LINES/2)-5, (COLS/2)-15);
+ box(win, 0, 0);
+ wattron(win, COLOR_PAIR(2));
+ mvwprintw(win, 0, 1, "%s", "Working");
+ wattroff(win, COLOR_PAIR(2));
+ mvwprintw(win, 2, 5, "%s", "Marking all as read");
+
+ progress = newwin(3, 28, (LINES/2)-1, (COLS/2)-14);
+ box(progress, 0, 0);
+ mvwprintw(progress, 0, 1, "%s", "Progress");
+
+ wrefresh(win);
+ wrefresh(progress);
+ refresh();
+
+ unsigned int n = notifs->element_count / 25;
for (size_t i = 0; i < notifs->element_count; i++) {
- if (notifs->list[id] || !notifs->list[id]->seen) {
+ if (notifs->list[i] && !notifs->list[i]->seen) {
set_notif_seen(conn, i, true);
}
+ if (i > 0) {
+ for (unsigned int o = 0; o < i/n; o++) {
+ wattron(progress, A_REVERSE);
+ mvwprintw(progress, 1, o + 1, " ");
+ wattroff(progress, A_REVERSE);
+ }
+ wrefresh(progress);
+ refresh();
+ }
}
+ werase(progress);
+ wrefresh(progress);
+ delwin(progress);
+ werase(win);
+ wrefresh(win);
+ delwin(win);
+ break;
+ case KEY_F(9):
+ clear_all(conn);
break;
}
}
@@ -466,6 +550,10 @@ void run_tui_client(DBusConnection* conn) {
setlocale(LC_ALL, "");
curses_init();
+ int last_lines = LINES;
+ int last_cols = COLS;
+ int last_notifs = 0;
+
struct NotifsList* notifs = NULL;
notifs_list_init(&notifs);
@@ -479,6 +567,23 @@ void run_tui_client(DBusConnection* conn) {
curses_handle_input(conn, ch, &start, &selected, notifs);
update_notif_list(conn, &notifs, &unread_count);
+
+ bool major_change = 0;
+ if (LINES != last_lines) {
+ last_lines = LINES;
+ major_change = true;
+ }
+ if (COLS != last_cols) {
+ last_cols = COLS;
+ major_change = true;
+ }
+ if (notifs->element_count != last_notifs) {
+ last_notifs = notifs->element_count;
+ major_change = true;
+ }
+ if (major_change)
+ clear();
+
curses_display_notifs(notifs, start, selected);
curses_display_menu(unread_count);
refresh();
diff --git a/snotifd.c b/snotifd.c
index d60f9f4..d7ad47e 100644
--- a/snotifd.c
+++ b/snotifd.c
@@ -192,7 +192,8 @@ void reply_to_get_notification_list(DBusMessage* msg, DBusConnection* conn) {
dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &notifs->list[i]->summary);
dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &notifs->list[i]->body);
dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_UINT32, &notifs->list[i]->time);
- dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_BOOLEAN, &notifs->list[i]->seen);
+ unsigned int _seen = notifs->list[i]->seen; // Workaround for broken implementation
+ dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_BOOLEAN, &_seen);
dbus_message_iter_close_container(&array_iter, &struct_iter);
}
}
@@ -269,6 +270,16 @@ void reply_to_set_seen(DBusMessage* msg, DBusConnection* conn) {
dbus_message_unref(reply);
}
+void reply_to_clear_all(DBusMessage* msg, DBusConnection* conn) {
+ DBusMessage* reply;
+ DBusMessageIter args;
+ notifs_list_clear(notifs);
+ reply = dbus_message_new_method_return(msg);
+ dbus_message_iter_init_append(reply, &args);
+ dbus_connection_send(conn, reply, NULL);
+ dbus_message_unref(reply);
+}
+
void init_dbus(DBusConnection** conn) {
DBusError err;
@@ -325,6 +336,8 @@ void handle_dbus_message(DBusConnection* conn, DBusMessage* msg) {
reply_to_get_unseen_count(msg, conn);
} else if (dbus_message_is_method_call(msg, DBUS_CLIENT_INTERFACE, DBUS_METHOD_SETSEEN)) {
reply_to_set_seen(msg, conn);
+ } else if (dbus_message_is_method_call(msg, DBUS_CLIENT_INTERFACE, DBUS_METHOD_CLEAR)) {
+ reply_to_clear_all(msg, conn);
}
dbus_message_unref(msg);
diff --git a/snotifd.service b/snotifd.service
new file mode 100644
index 0000000..fc1feb4
--- /dev/null
+++ b/snotifd.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=Simple notification daemon
+After=default.target
+
+[Service]
+ExecStart=%h/bin/snotifd
+Restart=on-failure
+StandardOutput=journal
+StandardError=journal
+
+[Install]
+WantedBy=default.target
+