Add IdleRegister to deal with destruction while idle func is queued

This adds a little helper class to `guiutils.*` that unregisters
in-flight idle functions queued by `IdleRegister::add()`. It's best
to call `IdleRegister::destroy()` in the destructor of the class
owning the `IdleRegister` instance. Otherwise make sure, it is the
last member which will be deleted first.

`Resize` now makes use of this new facility in `setDimensions()`, which
also fixes #3673.
This commit is contained in:
Flössie
2017-02-09 20:25:58 +01:00
parent 281982f329
commit 824ecaed41
4 changed files with 155 additions and 78 deletions

View File

@@ -43,6 +43,53 @@ guint add_idle (GSourceFunc function, gpointer data)
//gtk_main_iteration_do(false);
}
IdleRegister::~IdleRegister()
{
destroy();
}
void IdleRegister::add(GSourceFunc function, gpointer data)
{
struct DataWrapper {
IdleRegister* const self;
GSourceFunc function;
gpointer data;
};
const auto dispatch = [](gpointer data) -> gboolean {
DataWrapper* const data_wrapper = static_cast<DataWrapper*>(data);
if (!data_wrapper->function(data_wrapper->data)) {
data_wrapper->self->mutex.lock();
data_wrapper->self->ids.erase(data_wrapper);
data_wrapper->self->mutex.unlock();
delete data_wrapper;
return FALSE;
}
return TRUE;
};
DataWrapper* const data_wrapper = new DataWrapper{
this,
function,
data
};
mutex.lock();
ids[data_wrapper] = add_idle(dispatch, data_wrapper);
mutex.unlock();
}
void IdleRegister::destroy()
{
mutex.lock();
for (const auto id : ids) {
g_source_remove(id.second);
}
mutex.unlock();
}
/*
gboolean giveMeAGo(void* data) {