]> granicus.if.org Git - neomutt/commitdiff
notify: drop old Context notifications
authorRichard Russon <rich@flatcap.org>
Wed, 10 Jul 2019 16:09:21 +0000 (17:09 +0100)
committerRichard Russon <rich@flatcap.org>
Sat, 13 Jul 2019 23:25:45 +0000 (00:25 +0100)
context.c
context.h
mailbox.c
mailbox.h
mutt/notify.c
mutt/notify_type.h
mx.c

index baf24024f1746978f10f5d7493f98648fb5be3da..65aa7ad09dbde1cac29b07eda1f078c30a5b1ec8 100644 (file)
--- a/context.c
+++ b/context.c
  * ctx_free - Free a Context
  * @param[out] ctx Context to free
  */
-void ctx_free(struct Context **ctx)
+void ctx_free(struct Context **ptr)
 {
-  if (!ctx || !*ctx)
+  if (!ptr || !*ptr)
     return;
 
-  FREE(ctx);
+  struct Context *ctx = *ptr;
+  if (ctx->mailbox)
+    notify_observer_remove(ctx->mailbox->notify, ctx_mailbox_observer);
+
+  FREE(ptr);
 }
 
 /**
@@ -60,6 +64,8 @@ void ctx_cleanup(struct Context *ctx)
 {
   FREE(&ctx->pattern);
   mutt_pattern_free(&ctx->limit_pattern);
+  if (ctx->mailbox)
+    notify_observer_remove(ctx->mailbox->notify, ctx_mailbox_observer);
   memset(ctx, 0, sizeof(struct Context));
 }
 
@@ -250,18 +256,19 @@ void ctx_update_tables(struct Context *ctx, bool committing)
 }
 
 /**
- * ctx_mailbox_changed - Act on a Mailbox change notification
- * @param m      Mailbox
- * @param action Event occurring
+ * ctx_mailbox_observer - Watch for changes affecting the Context - Implements ::observer_t
  */
-void ctx_mailbox_changed(struct Mailbox *m, enum MailboxNotification action)
+int ctx_mailbox_observer(struct NotifyCallback *nc)
 {
-  if (!m || !m->ndata)
-    return;
-
-  struct Context *ctx = m->ndata;
+  if (!nc)
+    return -1;
+  if ((nc->obj_type != NT_MAILBOX) || (nc->event_type != NT_MAILBOX))
+    return 0;
+  struct Context *ctx = (struct Context *) nc->data;
+  if (!ctx)
+    return -1;
 
-  switch (action)
+  switch (nc->event_subtype)
   {
     case MBN_CLOSED:
       mutt_clear_threads(ctx);
@@ -281,6 +288,8 @@ void ctx_mailbox_changed(struct Mailbox *m, enum MailboxNotification action)
         ctx->last_tag = NULL;
       break;
   }
+
+  return 0;
 }
 
 /**
index 6be1bec25556a70f750d3926a25cd12fad740324..ffe6eb53cdb3e9902e0dce4025f9c3c4b7ef5f54 100644 (file)
--- a/context.h
+++ b/context.h
@@ -31,6 +31,7 @@
 #include "pattern.h"
 
 struct EmailList;
+struct NotifyCallback;
 
 /**
  * struct Context - The "current" mailbox
@@ -52,8 +53,8 @@ struct Context
   struct Mailbox *mailbox;
 };
 
-void ctx_free(struct Context **ctx);
-void ctx_mailbox_changed(struct Mailbox *m, enum MailboxNotification action);
+void ctx_free(struct Context **ptr);
+int  ctx_mailbox_observer(struct NotifyCallback *nc);
 void ctx_update(struct Context *ctx);
 void ctx_update_tables(struct Context *ctx, bool committing);
 
index 1254e2effd01c60b5d940ba86f4cda0b6690620c..d0505ee05f8f3d5cdb600037cd23864327f20139 100644 (file)
--- a/mailbox.c
+++ b/mailbox.c
@@ -46,6 +46,7 @@ struct Mailbox *mailbox_new(void)
   struct Mailbox *m = mutt_mem_calloc(1, sizeof(struct Mailbox));
 
   m->pathbuf = mutt_buffer_new();
+  m->notify = notify_new(m, NT_MAILBOX);
 
   return m;
 }
@@ -61,6 +62,7 @@ void mailbox_free(struct Mailbox **ptr)
 
   struct Mailbox *m = *ptr;
   mutt_mailbox_changed(m, MBN_CLOSED);
+  notify_free(&m->notify);
 
   mutt_buffer_free(&m->pathbuf);
   FREE(&m->desc);
@@ -208,10 +210,10 @@ void mutt_mailbox_update(struct Mailbox *m)
  */
 void mutt_mailbox_changed(struct Mailbox *m, enum MailboxNotification action)
 {
-  if (!m || !m->notify2)
+  if (!m)
     return;
 
-  m->notify2(m, action);
+  notify_send(m->notify, NT_MAILBOX, action, 0);
 }
 
 /**
index 234f476530b7b94077acda3d4715a61be12ac1c9..684acdc3754846c79695e4e75fb0fb2fca1cc233 100644 (file)
--- a/mailbox.h
+++ b/mailbox.h
@@ -147,8 +147,6 @@ struct Mailbox
   void (*free_mdata)(void **); /**< driver-specific data free function */
 
   struct Notify *notify;        ///< Notifications handler
-  void (*notify2)(struct Mailbox *m, enum MailboxNotification action); ///< Notification callback
-  void *ndata; ///< Notification callback private data
 };
 
 /**
index 4f369a1e7b7ffe5408a55dc9164ffb60ae527b7d..0c7a2950e75b0f03cdf8aecc0a6cc4b4ba102f21 100644 (file)
@@ -116,7 +116,9 @@ static bool send(struct Notify *source, struct Notify *current, int type,
 
   // mutt_debug(LL_NOTIFY, "send: %d, %ld\n", type, data);
   struct ObserverNode *np = NULL;
-  STAILQ_FOREACH(np, &current->observers, entries)
+  struct ObserverNode *tmp = NULL;
+  // We use the `_SAFE` version in case an event causes an observer to be deleted
+  STAILQ_FOREACH_SAFE(np, &current->observers, entries, tmp)
   {
     struct Observer *o = np->observer;
 
index 982a12b76b34b9c798eff737c8c4da6f00a3ae70..846ab819284d2c6e05940e273ae26928bf7abf3d 100644 (file)
@@ -35,6 +35,7 @@ enum NotifyType
   NT_MAILBOX, ///< Mailbox has changed
   NT_EMAIL,   ///< Email has changed
   NT_WINDOW,  ///< Window has changed
+  NT_CONTEXT, ///< Context has changed
 };
 
 #endif /* MUTT_LIB_NOTIFY_TYPE_H */
diff --git a/mx.c b/mx.c
index 4e85a21e2e4fbd9426ef6c7014bb7a27c6ca7b49..d853c7f8cc5631604a647dfc94dbf35fba7b3139 100644 (file)
--- a/mx.c
+++ b/mx.c
@@ -270,6 +270,7 @@ struct Context *mx_mbox_open(struct Mailbox *m, OpenMailboxFlags flags)
 
   struct Context *ctx = mutt_mem_calloc(1, sizeof(*ctx));
   ctx->mailbox = m;
+  notify_observer_add(m->notify, NT_MAILBOX, 0, ctx_mailbox_observer, IP ctx);
 
   if ((m->magic == MUTT_UNKNOWN) && (flags & (MUTT_NEWFOLDER | MUTT_APPEND)))
   {
@@ -385,8 +386,6 @@ struct Context *mx_mbox_open(struct Mailbox *m, OpenMailboxFlags flags)
   }
 
   OptForceRefresh = false;
-  m->notify2 = ctx_mailbox_changed;
-  m->ndata = ctx;
 
   return ctx;
 }
@@ -413,7 +412,6 @@ void mx_fastclose_mailbox(struct Mailbox *m)
     m->mx_ops->mbox_close(m);
 
   mutt_mailbox_changed(m, MBN_CLOSED);
-  m->notify2 = NULL;
 
   mutt_hash_free(&m->subj_hash);
   mutt_hash_free(&m->id_hash);
@@ -741,7 +739,7 @@ int mx_mbox_close(struct Context **ptr)
     if ((m->magic == MUTT_MBOX) || (m->magic == MUTT_MMDF))
       mbox_reset_atime(m, NULL);
     mx_fastclose_mailbox(m);
-    FREE(ptr);
+    ctx_free(ptr);
     return 0;
   }