* 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);
}
/**
{
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));
}
}
/**
- * 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);
ctx->last_tag = NULL;
break;
}
+
+ return 0;
}
/**
#include "pattern.h"
struct EmailList;
+struct NotifyCallback;
/**
* struct Context - The "current" mailbox
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);
struct Mailbox *m = mutt_mem_calloc(1, sizeof(struct Mailbox));
m->pathbuf = mutt_buffer_new();
+ m->notify = notify_new(m, NT_MAILBOX);
return m;
}
struct Mailbox *m = *ptr;
mutt_mailbox_changed(m, MBN_CLOSED);
+ notify_free(&m->notify);
mutt_buffer_free(&m->pathbuf);
FREE(&m->desc);
*/
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);
}
/**
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
};
/**
// mutt_debug(LL_NOTIFY, "send: %d, %ld\n", type, data);
struct ObserverNode *np = NULL;
- STAILQ_FOREACH(np, ¤t->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, ¤t->observers, entries, tmp)
{
struct Observer *o = np->observer;
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 */
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)))
{
}
OptForceRefresh = false;
- m->notify2 = ctx_mailbox_changed;
- m->ndata = ctx;
return ctx;
}
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);
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;
}