From 91b44dbd086185f29830eadb3dc91d6dfd019082 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=B6ssie?= Date: Sun, 26 Mar 2017 22:03:33 +0200 Subject: [PATCH 1/3] Replace all `g_idle_add`s with `IdleRegister` (#3767) --- rtgui/batchqueue.cc | 34 ++++--- rtgui/dirbrowser.cc | 17 ++-- rtgui/dirbrowser.h | 5 + rtgui/editorpanel.cc | 119 ++++++++++++----------- rtgui/filebrowser.cc | 81 ++++++++-------- rtgui/filebrowser.h | 6 +- rtgui/filecatalog.cc | 47 +++++----- rtgui/filecatalog.h | 2 + rtgui/histogrampanel.cc | 100 ++++++++++---------- rtgui/histogrampanel.h | 10 +- rtgui/lensgeom.cc | 33 ++++--- rtgui/lensgeom.h | 3 +- rtgui/mycurve.cc | 1 - rtgui/mycurve.h | 1 - rtgui/mydiagonalcurve.cc | 51 +++++----- rtgui/mydiagonalcurve.h | 2 + rtgui/previewhandler.cc | 193 +++++++++++++++++++------------------- rtgui/previewhandler.h | 14 ++- rtgui/progressconnector.h | 32 ++++--- rtgui/retinex.cc | 22 ++--- rtgui/retinex.h | 2 + rtgui/tonecurve.cc | 18 ++-- rtgui/tonecurve.h | 3 +- rtgui/wavelet.cc | 22 +++-- rtgui/wavelet.h | 4 +- 25 files changed, 419 insertions(+), 403 deletions(-) diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index 7bd53c444..fc5636b1a 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -385,16 +385,6 @@ Glib::ustring BatchQueue::getTempFilenameForParams( const Glib::ustring &filenam return savedParamPath; } -int cancelItemUI (void* data) -{ - const auto bqe = static_cast(data); - - g_remove (bqe->savedParamsFile.c_str ()); - delete bqe; - - return 0; -} - void BatchQueue::cancelItems (const std::vector& items) { { @@ -419,7 +409,16 @@ void BatchQueue::cancelItems (const std::vector& items) if (entry->thumbnail) entry->thumbnail->imageRemovedFromQueue (); - g_idle_add (cancelItemUI, entry); + const auto func = [](gpointer data) -> gboolean { + const BatchQueueEntry* const bqe = static_cast(data); + + ::g_remove(bqe->savedParamsFile.c_str()); + delete bqe; + + return FALSE; + }; + + idle_register.add(func, entry); } for (const auto entry : fd) @@ -879,12 +878,6 @@ Glib::ustring BatchQueue::autoCompleteFileName (const Glib::ustring& fileName, c return ""; } -int setProgressUI (void* p) -{ - (static_cast(p))->redraw(); - return 0; -} - void BatchQueue::setProgress (double p) { @@ -893,7 +886,12 @@ void BatchQueue::setProgress (double p) } // No need to acquire the GUI, setProgressUI will do it - g_idle_add (setProgressUI, this); + const auto func = [](gpointer data) -> gboolean { + static_cast(data)->redraw(); + return FALSE; + }; + + idle_register.add(func, this); } void BatchQueue::buttonPressed (LWButton* button, int actionCode, void* actionData) diff --git a/rtgui/dirbrowser.cc b/rtgui/dirbrowser.cc index 7b5adade2..654748dd0 100644 --- a/rtgui/dirbrowser.cc +++ b/rtgui/dirbrowser.cc @@ -100,6 +100,11 @@ DirBrowser::DirBrowser () : dirTreeModel(), scrolledwindow4->show (); } +DirBrowser::~DirBrowser() +{ + idle_register.destroy(); +} + void DirBrowser::fillDirTree () { @@ -227,16 +232,16 @@ int updateVolumesUI (void* br) (static_cast(br))->updateVolumes (); return 1; } -int updateDirTreeUI (void* br) -{ - (static_cast(br))->updateDirTreeRoot (); - return 0; -} void DirBrowser::winDirChanged () { + const auto func = [](gpointer data) -> gboolean { + static_cast(data)->updateDirTreeRoot(); - g_idle_add (updateDirTreeUI, this); + return FALSE; + }; + + idle_register.add(func, this); } #endif diff --git a/rtgui/dirbrowser.h b/rtgui/dirbrowser.h index 850a9fa78..e8eefdd36 100644 --- a/rtgui/dirbrowser.h +++ b/rtgui/dirbrowser.h @@ -25,6 +25,8 @@ #include "windirmonitor.h" #endif +#include "guiutils.h" + class DirBrowser : public Gtk::VBox #ifdef WIN32 , public WinDirChangeListener @@ -95,8 +97,11 @@ private: Gtk::TreePath expandToDir (const Glib::ustring& dirName); void updateDir (const Gtk::TreeModel::iterator& iter); + IdleRegister idle_register; + public: DirBrowser (); + ~DirBrowser(); void fillDirTree (); void on_sort_column_changed() const; diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 7bc1631d3..668631474 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -1016,44 +1016,42 @@ void EditorPanel::procParamsChanged (rtengine::procparams::ProcParams* params, r // saveLabel->set_markup (Glib::ustring("") + M("MAIN_BUTTON_SAVE") + ""); } -struct spsparams { - bool inProcessing; - EditorPanelIdleHelper* epih; -}; - -int setProgressStateUIThread (void* data) -{ - - spsparams* p = static_cast (data); - - if (p->epih->destroyed) { - if (p->epih->pending == 1) { - delete p->epih; - } else { - p->epih->pending--; - } - - delete p; - - return 0; - } - - p->epih->epanel->refreshProcessingState (p->inProcessing); - p->epih->pending--; - delete p; - - return 0; -} - void EditorPanel::setProgressState (bool inProcessing) { + struct spsparams { + bool inProcessing; + EditorPanelIdleHelper* epih; + }; epih->pending++; spsparams* p = new spsparams; p->inProcessing = inProcessing; p->epih = epih; - g_idle_add (setProgressStateUIThread, p); + + const auto func = [](gpointer data) -> gboolean { + spsparams* const p = static_cast(data); + + if (p->epih->destroyed) { + if (p->epih->pending == 1) { + delete p->epih; + } else { + p->epih->pending--; + } + + delete p; + + return 0; + } + + p->epih->epanel->refreshProcessingState (p->inProcessing); + p->epih->pending--; + delete p; + + return FALSE; + }; + + idle_register.add(func, p); } void EditorPanel::setProgress (double p) @@ -1125,12 +1123,6 @@ void EditorPanel::refreshProcessingState (bool inProcessingP) setprogressStrUI (s); } -struct errparams { - Glib::ustring descr; - Glib::ustring title; - EditorPanelIdleHelper* epih; -}; - void EditorPanel::displayError (Glib::ustring title, Glib::ustring descr) { GtkWidget* msgd = gtk_message_dialog_new_with_markup (nullptr, @@ -1146,38 +1138,43 @@ void EditorPanel::displayError (Glib::ustring title, Glib::ustring descr) gtk_widget_show_all (msgd); } -int disperrorUI (void* data) -{ - errparams* p = static_cast (data); - - if (p->epih->destroyed) { - if (p->epih->pending == 1) { - delete p->epih; - } else { - p->epih->pending--; - } - - delete p; - - return 0; - } - - p->epih->epanel->displayError (p->title, p->descr); - p->epih->pending--; - delete p; - - return 0; -} - void EditorPanel::error (Glib::ustring title, Glib::ustring descr) { + struct errparams { + Glib::ustring descr; + Glib::ustring title; + EditorPanelIdleHelper* epih; + }; epih->pending++; - errparams* p = new errparams; + errparams* const p = new errparams; p->descr = descr; p->title = title; p->epih = epih; - g_idle_add (disperrorUI, p); + + const auto func = [](gpointer data) -> gboolean { + errparams* const p = static_cast (data); + + if (p->epih->destroyed) { + if (p->epih->pending == 1) { + delete p->epih; + } else { + p->epih->pending--; + } + + delete p; + + return 0; + } + + p->epih->epanel->displayError (p->title, p->descr); + p->epih->pending--; + delete p; + + return FALSE; + }; + + idle_register.add(func, p); } void EditorPanel::info_toggled () diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc index 5cbb5255b..5081962a1 100644 --- a/rtgui/filebrowser.cc +++ b/rtgui/filebrowser.cc @@ -455,6 +455,8 @@ FileBrowser::FileBrowser () FileBrowser::~FileBrowser () { + idle_register.destroy(); + profileStore.removeListener(this); delete pmenu; delete pmenuColorLabels; @@ -541,46 +543,44 @@ void FileBrowser::doubleClicked (ThumbBrowserEntryBase* entry) } } -struct addparams { - FileBrowserIdleHelper* fbih; - FileBrowserEntry* entry; -}; - -int AddEntryUIThread (void* data) -{ - - addparams* ap = static_cast(data); - FileBrowserIdleHelper* fbih = ap->fbih; - - if (fbih->destroyed) { - if (fbih->pending == 1) { - delete fbih; - } else { - fbih->pending--; - } - - delete ap->entry; - delete ap; - - return 0; - } - - ap->fbih->fbrowser->addEntry_ (ap->entry); - delete ap; - fbih->pending--; - - return 0; -} - void FileBrowser::addEntry (FileBrowserEntry* entry) { + struct addparams { + FileBrowserIdleHelper* fbih; + FileBrowserEntry* entry; + }; fbih->pending++; entry->setParent (this); - addparams* ap = new addparams; + addparams* const ap = new addparams; ap->fbih = fbih; ap->entry = entry; - g_idle_add (AddEntryUIThread, ap); + + const auto func = [](gpointer data) -> gboolean { + addparams* const ap = static_cast(data); + FileBrowserIdleHelper* fbih = ap->fbih; + + if (fbih->destroyed) { + if (fbih->pending == 1) { + delete fbih; + } else { + fbih->pending--; + } + + delete ap->entry; + delete ap; + + return 0; + } + + ap->fbih->fbrowser->addEntry_ (ap->entry); + delete ap; + fbih->pending--; + + return FALSE; + }; + + idle_register.add(func, ap); } void FileBrowser::addEntry_ (FileBrowserEntry* entry) @@ -1905,12 +1905,6 @@ void FileBrowser::openNextPreviousEditorImage (Glib::ustring fname, eRTNav nextP } } -int refreshThumbImagesUI (void* data) -{ - (static_cast(data))->_thumbRearrangementNeeded (); - return 0; -} - void FileBrowser::_thumbRearrangementNeeded () { refreshThumbImages (); // arrangeFiles is NOT enough @@ -1918,8 +1912,13 @@ void FileBrowser::_thumbRearrangementNeeded () void FileBrowser::thumbRearrangementNeeded () { - // refreshThumbImagesUI will handle thread safety itself - g_idle_add (refreshThumbImagesUI, this); + const auto func = [](gpointer data) -> gboolean { + static_cast(data)->_thumbRearrangementNeeded(); + + return FALSE; + }; + + idle_register.add(func, this); } void FileBrowser::selectionChanged () diff --git a/rtgui/filebrowser.h b/rtgui/filebrowser.h index fdb08ba24..ac6055696 100644 --- a/rtgui/filebrowser.h +++ b/rtgui/filebrowser.h @@ -67,11 +67,12 @@ class FileBrowser : public ThumbBrowserBase, public ExportPanelListener, public ProfileStoreListener { - +private: typedef sigc::signal type_trash_changed; -protected: + IdleRegister idle_register; +protected: Gtk::MenuItem* rank[6]; MyImageMenuItem* colorlabel[6]; Gtk::MenuItem* trash; @@ -143,7 +144,6 @@ protected: type_trash_changed m_trash_changed; public: - FileBrowser (); ~FileBrowser (); diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index a876dd54e..47466216e 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -435,6 +435,8 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) : FileCatalog::~FileCatalog() { + idle_register.destroy(); + for (int i = 0; i < 5; i++) { delete iranked[i]; delete igranked[i]; @@ -702,15 +704,15 @@ void FileCatalog::_refreshProgressBar () } } -int refreshProgressBarUI (void* data) -{ - (static_cast(data))->_refreshProgressBar (); - return 0; -} - void FileCatalog::filterApplied() { - g_idle_add (refreshProgressBarUI, this); + const auto func = [](gpointer data) -> gboolean { + static_cast(data)->_refreshProgressBar(); + + return FALSE; + }; + + idle_register.add(func, this); } @@ -776,12 +778,6 @@ void FileCatalog::previewReady (int dir_id, FileBrowserEntry* fdn) _refreshProgressBar(); } -int prevfinished (void* data) -{ - (static_cast(data))->previewsFinishedUI (); - return 0; -} - // Called within GTK UI thread void FileCatalog::previewsFinishedUI () { @@ -838,7 +834,13 @@ void FileCatalog::previewsFinished (int dir_id) currentEFS = dirEFS; } - g_idle_add (prevfinished, this); + const auto func = [](gpointer data) -> gboolean { + static_cast(data)->previewsFinishedUI(); + + return FALSE; + }; + + idle_register.add(func, this); } void FileCatalog::setEnabled (bool e) @@ -920,7 +922,7 @@ void FileCatalog::openRequested (std::vector tmb) tmb[i]->increaseRef (); } - g_idle_add (openRequestedUI, params); + idle_register.add(openRequestedUI, params); } void FileCatalog::deleteRequested (std::vector tbe, bool inclBatchProcessed) @@ -1744,15 +1746,16 @@ void FileCatalog::reparseDirectory () } #ifdef WIN32 -int winDirChangedUITread (void* cat) -{ - (static_cast(cat))->reparseDirectory (); - return 0; -} void FileCatalog::winDirChanged () { - g_idle_add(winDirChangedUITread, this); + const auto func = [](gpointer data) -> gboolean { + static_cast(data)->reparseDirectory(); + + return FALSE; + }; + + idle_register.add(func, this); } #else @@ -1857,7 +1860,7 @@ void FileCatalog::addAndOpenFile (const Glib::ustring& fname) params->catalog = this; params->tmb.push_back (tmb); tmb->increaseRef (); - g_idle_add (openRequestedUI, params); + idle_register.add(openRequestedUI, params); } catch(Gio::Error&) {} } diff --git a/rtgui/filecatalog.h b/rtgui/filecatalog.h index 3595f1fa1..5116f3bb3 100644 --- a/rtgui/filecatalog.h +++ b/rtgui/filecatalog.h @@ -161,6 +161,8 @@ private: WinDirMonitor* wdMonitor; #endif + IdleRegister idle_register; + void addAndOpenFile (const Glib::ustring& fname); void checkAndAddFile (Glib::RefPtr info); std::vector getFileList (); diff --git a/rtgui/histogrampanel.cc b/rtgui/histogrampanel.cc index 94fa2f24d..e9366fbfc 100644 --- a/rtgui/histogrampanel.cc +++ b/rtgui/histogrampanel.cc @@ -412,6 +412,7 @@ HistogramRGBArea::HistogramRGBArea () ://needChroma unactive by default HistogramRGBArea::~HistogramRGBArea () { + idle_register.destroy(); if (harih->pending) { harih->destroyed = true; @@ -703,30 +704,6 @@ void HistogramRGBArea::rgb2lab (Glib::ustring profile, Glib::ustring profileW, i } - -int histrgbupdate (void* data) -{ - - HistogramRGBAreaIdleHelper* harih = static_cast(data); - - if (harih->destroyed) { - if (harih->pending == 1) { - delete harih; - } else { - harih->pending--; - } - - return 0; - } - - harih->harea->updateBackBuffer(-1, -1, -1); - harih->harea->queue_draw (); - - harih->pending--; - - return 0; -} - void HistogramRGBArea::update (int valh, int rh, int gh, int bh) { @@ -741,7 +718,29 @@ void HistogramRGBArea::update (int valh, int rh, int gh, int bh) } harih->pending++; - g_idle_add (histrgbupdate, harih); + + const auto func = [](gpointer data) -> gboolean { + HistogramRGBAreaIdleHelper* const harih = static_cast(data); + + if (harih->destroyed) { + if (harih->pending == 1) { + delete harih; + } else { + harih->pending--; + } + + return 0; + } + + harih->harea->updateBackBuffer(-1, -1, -1); + harih->harea->queue_draw (); + + harih->pending--; + + return FALSE; + }; + + idle_register.add(func, harih); } void HistogramRGBArea::updateOptions (bool r, bool g, bool b, bool l, bool raw, bool bar, bool c) @@ -840,13 +839,13 @@ HistogramArea::HistogramArea (FullModeListener *fml) : //needChroma unactive by HistogramArea::~HistogramArea () { + idle_register.destroy(); if (haih->pending) { haih->destroyed = true; } else { delete haih; } - } Gtk::SizeRequestMode HistogramArea::get_request_mode_vfunc () const @@ -901,33 +900,8 @@ void HistogramArea::updateOptions (bool r, bool g, bool b, bool l, bool raw, boo updateBackBuffer (); } -int histupdateUI (void* data) -{ - - HistogramAreaIdleHelper* haih = static_cast(data); - - if (haih->destroyed) { - if (haih->pending == 1) { - delete haih; - } else { - haih->pending--; - } - - return 0; - } - - haih->harea->setDirty (true); - haih->harea->updateBackBuffer (); - haih->harea->queue_draw (); - - haih->pending--; - - return 0; -} - void HistogramArea::update (LUTu &histRed, LUTu &histGreen, LUTu &histBlue, LUTu &histLuma, LUTu &histRedRaw, LUTu &histGreenRaw, LUTu &histBlueRaw, LUTu &histChroma) { - if (histRed) { lhist = histLuma; chist = histChroma; @@ -945,7 +919,29 @@ void HistogramArea::update (LUTu &histRed, LUTu &histGreen, LUTu &histBlue, LUTu haih->pending++; // Can be done outside of the GUI thread - g_idle_add (histupdateUI, haih); + const auto func = [](gpointer data) -> gboolean { + HistogramAreaIdleHelper* const haih = static_cast(data); + + if (haih->destroyed) { + if (haih->pending == 1) { + delete haih; + } else { + haih->pending--; + } + + return 0; + } + + haih->harea->setDirty (true); + haih->harea->updateBackBuffer (); + haih->harea->queue_draw (); + + haih->pending--; + + return FALSE; + }; + + idle_register.add(func, haih); } SSEFUNCTION void HistogramArea::updateBackBuffer () diff --git a/rtgui/histogrampanel.h b/rtgui/histogrampanel.h index 2f8eb6da5..25fa15c23 100644 --- a/rtgui/histogrampanel.h +++ b/rtgui/histogrampanel.h @@ -45,11 +45,12 @@ struct HistogramRGBAreaIdleHelper { class HistogramRGBArea : public Gtk::DrawingArea, public BackBuffer { - +private: typedef const double (*TMatrix)[3]; -protected: + IdleRegister idle_register; +protected: int val; int r; int g; @@ -72,7 +73,6 @@ protected: HistogramRGBAreaIdleHelper* harih; public: - HistogramRGBArea(); ~HistogramRGBArea(); @@ -111,9 +111,10 @@ public: class HistogramArea : public Gtk::DrawingArea, public BackBuffer { +private: + IdleRegister idle_register; protected: - LUTu lhist, rhist, ghist, bhist, chist; LUTu lhistRaw, rhistRaw, ghistRaw, bhistRaw; @@ -127,7 +128,6 @@ protected: HistogramAreaIdleHelper* haih; public: - explicit HistogramArea(FullModeListener *fml = nullptr); ~HistogramArea(); diff --git a/rtgui/lensgeom.cc b/rtgui/lensgeom.cc index 423a7a3ec..5bcbf5494 100644 --- a/rtgui/lensgeom.cc +++ b/rtgui/lensgeom.cc @@ -45,7 +45,7 @@ LensGeometry::LensGeometry () : FoldableToolPanel(this, "lensgeom", M("TP_LENSGE LensGeometry::~LensGeometry () { - g_idle_remove_by_data(this); + idle_register.destroy(); } void LensGeometry::read (const ProcParams* pp, const ParamsEdited* pedited) @@ -121,27 +121,26 @@ void LensGeometry::setBatchMode (bool batchMode) void LensGeometry::disableAutoFillIfActive () { - g_idle_add(doDisableAutoFillIfActive, this); -} + const auto func = [](gpointer data) -> gboolean { + GThreadLock lock; // Is this really needed? -int LensGeometry::doDisableAutoFillIfActive (void* data) -{ - GThreadLock lock; // Is this really needed? + LensGeometry* const instance = static_cast(data); - LensGeometry* const instance = static_cast(data); + if (!instance->batchMode) { + if (instance->fill->get_active()) { + instance->fillConn.block(true); + instance->fill->set_active(false); - if (!instance->batchMode) { - if (instance->fill->get_active()) { - instance->fillConn.block (true); - instance->fill->set_active(false); + if (instance->listener) { + instance->listener->panelChanged (EvTransAutoFill, M("GENERAL_DISABLED")); + } - if (instance->listener) { - instance->listener->panelChanged (EvTransAutoFill, M("GENERAL_DISABLED")); + instance->fillConn.block(false); } - - instance->fillConn.block (false); } - } - return 0; + return FALSE; + }; + + idle_register.add(func, this); } diff --git a/rtgui/lensgeom.h b/rtgui/lensgeom.h index b963489e1..697fc73ce 100644 --- a/rtgui/lensgeom.h +++ b/rtgui/lensgeom.h @@ -57,8 +57,7 @@ public: void disableAutoFillIfActive (); private: - static int doDisableAutoFillIfActive (void* data); - + IdleRegister idle_register; }; #endif diff --git a/rtgui/mycurve.cc b/rtgui/mycurve.cc index c36ec1cc7..a851482ee 100644 --- a/rtgui/mycurve.cc +++ b/rtgui/mycurve.cc @@ -48,7 +48,6 @@ MyCurve::MyCurve () : pipetteR(-1.f), pipetteG(-1.f), pipetteB(-1.f), pipetteVal MyCurve::~MyCurve () { - if (mcih->pending) { mcih->destroyed = true; } else { diff --git a/rtgui/mycurve.h b/rtgui/mycurve.h index 0c27ba8b3..8521b5748 100644 --- a/rtgui/mycurve.h +++ b/rtgui/mycurve.h @@ -57,7 +57,6 @@ class CurveEditor; class MyCurve : public Gtk::DrawingArea, public BackBuffer, public ColorCaller, public CoordinateProvider { - friend class MyCurveIdleHelper; protected: diff --git a/rtgui/mydiagonalcurve.cc b/rtgui/mydiagonalcurve.cc index 8bdb7fa0d..d789ab705 100644 --- a/rtgui/mydiagonalcurve.cc +++ b/rtgui/mydiagonalcurve.cc @@ -49,6 +49,7 @@ MyDiagonalCurve::MyDiagonalCurve () : activeParam(-1), bghistvalid(false) MyDiagonalCurve::~MyDiagonalCurve () { + idle_register.destroy(); delete [] bghist; } @@ -1492,38 +1493,13 @@ void MyDiagonalCurve::setType (DiagonalCurveType t) void MyDiagonalCurve::setActiveParam (int ac) { - activeParam = ac; setDirty(true); queue_draw (); } -int diagonalmchistupdateUI (void* data) -{ - - MyCurveIdleHelper* mcih = static_cast(data); - - if (mcih->destroyed) { - if (mcih->pending == 1) { - delete mcih; - } else { - mcih->pending--; - } - - return 0; - } - - mcih->clearPixmap (); - mcih->myCurve->queue_draw (); - - mcih->pending--; - - return 0; -} - void MyDiagonalCurve::updateBackgroundHistogram (LUTu & hist) { - if (hist) { //memcpy (bghist, hist, 256*sizeof(unsigned int)); for (int i = 0; i < 256; i++) { @@ -1537,14 +1513,33 @@ void MyDiagonalCurve::updateBackgroundHistogram (LUTu & hist) } mcih->pending++; - // Can be done outside of the GUI thread, so we're using g_idle_add instead of add_idle - g_idle_add (diagonalmchistupdateUI, mcih); + const auto func = [](gpointer data) -> gboolean { + MyCurveIdleHelper* const mcih = static_cast(data); + + if (mcih->destroyed) { + if (mcih->pending == 1) { + delete mcih; + } else { + mcih->pending--; + } + + return 0; + } + + mcih->clearPixmap (); + mcih->myCurve->queue_draw (); + + mcih->pending--; + + return FALSE; + }; + + idle_register.add(func, mcih); } void MyDiagonalCurve::reset(const std::vector &resetCurve, double identityValue) { - stopNumericalAdjustment(); if (!resetCurve.empty()) { diff --git a/rtgui/mydiagonalcurve.h b/rtgui/mydiagonalcurve.h index cf8a1efee..abb8d3dc6 100644 --- a/rtgui/mydiagonalcurve.h +++ b/rtgui/mydiagonalcurve.h @@ -48,6 +48,8 @@ public: class MyDiagonalCurve : public MyCurve { +private: + IdleRegister idle_register; protected: DiagonalCurveDescr curve; diff --git a/rtgui/previewhandler.cc b/rtgui/previewhandler.cc index 650e323eb..45e46d2d8 100644 --- a/rtgui/previewhandler.cc +++ b/rtgui/previewhandler.cc @@ -23,6 +23,18 @@ using namespace rtengine; using namespace rtengine::procparams; +namespace +{ + +struct iaimgpar { + IImage8* image; + PreviewHandlerIdleHelper* pih; + double scale; + CropParams cp; +}; + +} + PreviewHandler::PreviewHandler () : image(nullptr), previewScale(1.) { @@ -34,6 +46,7 @@ PreviewHandler::PreviewHandler () : image(nullptr), previewScale(1.) PreviewHandler::~PreviewHandler () { + idle_register.destroy(); if (pih->pending) { pih->destroyed = true; @@ -44,50 +57,8 @@ PreviewHandler::~PreviewHandler () //----------------previewimagelistener functions-------------------- -struct iaimgpar { - IImage8* image; - PreviewHandlerIdleHelper* pih; - double scale; - CropParams cp; -}; - -int setImageUI (void* data) -{ - iaimgpar* iap = static_cast(data); - PreviewHandlerIdleHelper* pih = iap->pih; - - if (pih->destroyed) { - if (pih->pending == 1) { - delete pih; - } else { - pih->pending--; - } - - delete iap; - - return 0; - } - - if (pih->phandler->image) { - IImage8* oldImg = pih->phandler->image; - oldImg->getMutex().lock (); - pih->phandler->image = iap->image; - oldImg->getMutex().unlock (); - } else { - pih->phandler->image = iap->image; - } - - pih->phandler->cropParams = iap->cp; - pih->phandler->previewScale = iap->scale; - pih->pending--; - delete iap; - - return 0; -} - void PreviewHandler::setImage (rtengine::IImage8* i, double scale, rtengine::procparams::CropParams cp) { - pih->pending++; iaimgpar* iap = new iaimgpar; @@ -96,95 +67,123 @@ void PreviewHandler::setImage (rtengine::IImage8* i, double scale, rtengine::pro iap->scale = scale; iap->cp = cp; - g_idle_add (setImageUI, iap); -} + const auto func = [](gpointer data) -> gboolean { + iaimgpar* const iap = static_cast(data); + PreviewHandlerIdleHelper* const pih = iap->pih; + if (pih->destroyed) { + if (pih->pending == 1) { + delete pih; + } else { + pih->pending--; + } -int delImageUI (void* data) -{ + delete iap; - iaimgpar* iap = static_cast(data); - PreviewHandlerIdleHelper* pih = iap->pih; - - if (pih->destroyed) { - if (pih->pending == 1) { - delete pih; - } else { - pih->pending--; + return FALSE; } + if (pih->phandler->image) { + IImage8* const oldImg = pih->phandler->image; + oldImg->getMutex().lock (); + pih->phandler->image = iap->image; + oldImg->getMutex().unlock (); + } else { + pih->phandler->image = iap->image; + } + + pih->phandler->cropParams = iap->cp; + pih->phandler->previewScale = iap->scale; + pih->pending--; delete iap; - return 0; - } + return FALSE; + }; - if (pih->phandler->image) { - IImage8* oldImg = pih->phandler->image; - oldImg->getMutex().lock (); - pih->phandler->image = nullptr; - oldImg->getMutex().unlock (); - } - - iap->image->free (); - pih->phandler->previewImgMutex.lock (); - pih->phandler->previewImg.clear (); - pih->phandler->previewImgMutex.unlock (); - - pih->pending--; - delete iap; - - return 0; + idle_register.add(func, iap); } + void PreviewHandler::delImage (IImage8* i) { - pih->pending++; iaimgpar* iap = new iaimgpar; iap->image = i; iap->pih = pih; - g_idle_add (delImageUI, iap); -} + const auto func = [](gpointer data) -> gboolean { + iaimgpar* iap = static_cast(data); + PreviewHandlerIdleHelper* pih = iap->pih; -int imageReadyUI (void* data) -{ + if (pih->destroyed) { + if (pih->pending == 1) { + delete pih; + } else { + pih->pending--; + } - iaimgpar* iap = static_cast(data); - PreviewHandlerIdleHelper* pih = iap->pih; + delete iap; - if (pih->destroyed) { - if (pih->pending == 1) { - delete pih; - } else { - pih->pending--; + return FALSE; } + if (pih->phandler->image) { + IImage8* oldImg = pih->phandler->image; + oldImg->getMutex().lock (); + pih->phandler->image = nullptr; + oldImg->getMutex().unlock (); + } + + iap->image->free (); + pih->phandler->previewImgMutex.lock (); + pih->phandler->previewImg.clear (); + pih->phandler->previewImgMutex.unlock (); + + pih->pending--; delete iap; - return 0; - } + return FALSE; + }; - pih->phandler->previewImgMutex.lock (); - pih->phandler->previewImg = Gdk::Pixbuf::create_from_data (pih->phandler->image->getData(), Gdk::COLORSPACE_RGB, false, 8, pih->phandler->image->getWidth(), pih->phandler->image->getHeight(), 3 * pih->phandler->image->getWidth()); - pih->phandler->previewImgMutex.unlock (); - pih->phandler->cropParams = iap->cp; - pih->phandler->previewImageChanged (); - pih->pending--; - delete iap; - - return 0; + idle_register.add(func, iap); } void PreviewHandler::imageReady (CropParams cp) { - pih->pending++; iaimgpar* iap = new iaimgpar; iap->pih = pih; iap->cp = cp; - g_idle_add (imageReadyUI, iap); + + const auto func = [](gpointer data) -> gboolean { + iaimgpar* const iap = static_cast(data); + PreviewHandlerIdleHelper* pih = iap->pih; + + if (pih->destroyed) { + if (pih->pending == 1) { + delete pih; + } else { + pih->pending--; + } + + delete iap; + + return FALSE; + } + + pih->phandler->previewImgMutex.lock (); + pih->phandler->previewImg = Gdk::Pixbuf::create_from_data (pih->phandler->image->getData(), Gdk::COLORSPACE_RGB, false, 8, pih->phandler->image->getWidth(), pih->phandler->image->getHeight(), 3 * pih->phandler->image->getWidth()); + pih->phandler->previewImgMutex.unlock (); + pih->phandler->cropParams = iap->cp; + pih->phandler->previewImageChanged (); + pih->pending--; + delete iap; + + return FALSE; + }; + + idle_register.add(func, iap); } Glib::RefPtr PreviewHandler::getRoughImage (int x, int y, int w, int h, double zoom) diff --git a/rtgui/previewhandler.h b/rtgui/previewhandler.h index a0e6ca242..1258083ec 100644 --- a/rtgui/previewhandler.h +++ b/rtgui/previewhandler.h @@ -19,11 +19,15 @@ #ifndef _PREVIEWHANDLER_ #define _PREVIEWHANDLER_ -#include "../rtengine/rtengine.h" -#include "threadutils.h" -#include #include +#include + +#include "threadutils.h" +#include "guiutils.h" + +#include "../rtengine/rtengine.h" + class PreviewListener { @@ -41,11 +45,13 @@ struct PreviewHandlerIdleHelper { class PreviewHandler : public rtengine::PreviewImageListener { - +private: friend int setImageUI (void* data); friend int delImageUI (void* data); friend int imageReadyUI (void* data); + IdleRegister idle_register; + protected: rtengine::IImage8* image; rtengine::procparams::CropParams cropParams; diff --git a/rtgui/progressconnector.h b/rtgui/progressconnector.h index f62b645c3..4cf9b1e4e 100644 --- a/rtgui/progressconnector.h +++ b/rtgui/progressconnector.h @@ -65,32 +65,36 @@ public: template class ProgressConnector { - +private: sigc::signal0 opStart; sigc::signal0 opEnd; T retval; Glib::Thread *workThread; - - static int emitEndSignalUI (void* data) - { - - sigc::signal0* opEnd = (sigc::signal0*) data; - int r = opEnd->emit (); - delete opEnd; - - return r; - } + IdleRegister idle_register; void workingThread () { - retval = opStart.emit (); - g_idle_add (ProgressConnector::emitEndSignalUI, new sigc::signal0 (opEnd)); + retval = opStart.emit(); + + const auto func = [](gpointer data) -> gboolean { + sigc::signal0* const opEnd = static_cast*>(data); + const gboolean res = opEnd->emit(); + delete opEnd; + + return res; + }; + + idle_register.add(func, new sigc::signal0(opEnd)); + workThread = nullptr; } public: - ProgressConnector (): retval( 0 ), workThread( nullptr ) { } + ~ProgressConnector() + { + idle_register.destroy(); + } void startFunc (const sigc::slot0& startHandler, const sigc::slot0& endHandler ) { diff --git a/rtgui/retinex.cc b/rtgui/retinex.cc index b81e8f579..271aaec72 100644 --- a/rtgui/retinex.cc +++ b/rtgui/retinex.cc @@ -634,6 +634,8 @@ Retinex::Retinex () : FoldableToolPanel(this, "retinex", M("TP_RETINEX_LABEL"), Retinex::~Retinex() { + idle_register.destroy(); + delete curveEditorGD; delete curveEditorGDH; delete transmissionCurveEditorG; @@ -695,17 +697,6 @@ void Retinex::updateToolState(std::vector &tpOpen) } } - - - - -int minmaxChangedUI (void* data) -{ - GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected - (static_cast(data))->minmaxComputed_ (); - return 0; -} - void Retinex::minmaxChanged (double cdma, double cdmin, double mini, double maxi, double Tmean, double Tsigma, double Tmin, double Tmax) { nextmin = cdmin; @@ -716,8 +707,15 @@ void Retinex::minmaxChanged (double cdma, double cdmin, double mini, double maxi nextsigma = Tsigma; nextminT = Tmin; nextmaxT = Tmax; - g_idle_add (minmaxChangedUI, this); + const auto func = [](gpointer data) -> gboolean { + GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected + static_cast(data)->minmaxComputed_(); + + return FALSE; + }; + + idle_register.add(func, this); } bool Retinex::minmaxComputed_ () diff --git a/rtgui/retinex.h b/rtgui/retinex.h index da0ca3685..a3618e1e4 100644 --- a/rtgui/retinex.h +++ b/rtgui/retinex.h @@ -17,6 +17,8 @@ class Retinex : public ToolParamBlock, public FoldableToolPanel, public rtengin public AdjusterListener, public ColorProvider { +private: + IdleRegister idle_register; protected: CurveEditorGroup* curveEditorGD; diff --git a/rtgui/tonecurve.cc b/rtgui/tonecurve.cc index 74647c846..28dcf9f3d 100644 --- a/rtgui/tonecurve.cc +++ b/rtgui/tonecurve.cc @@ -188,6 +188,8 @@ ToneCurve::ToneCurve () : FoldableToolPanel(this, "tonecurve", M("TP_EXPOSURE_LA ToneCurve::~ToneCurve () { + idle_register.destroy(); + delete curveEditorG; delete curveEditorG2; } @@ -727,15 +729,8 @@ void ToneCurve::waitForAutoExp () method->set_sensitive(false); } -int autoExpChangedUI (void* data) -{ - (static_cast(data))->autoExpComputed_ (); - return 0; -} - void ToneCurve::autoExpChanged (double expcomp, int bright, int contr, int black, int hlcompr, int hlcomprthresh, bool hlrecons) { - nextBlack = black; nextExpcomp = expcomp; nextBrightness = bright; @@ -743,7 +738,14 @@ void ToneCurve::autoExpChanged (double expcomp, int bright, int contr, int black nextHlcompr = hlcompr; nextHlcomprthresh = hlcomprthresh; nextHLRecons = hlrecons; - g_idle_add (autoExpChangedUI, this); + + const auto func = [](gpointer data) -> gboolean { + static_cast(data)->autoExpComputed_(); + + return FALSE; + }; + + idle_register.add(func, this); } void ToneCurve::enableAll () diff --git a/rtgui/tonecurve.h b/rtgui/tonecurve.h index e2ba03602..11ec64b96 100644 --- a/rtgui/tonecurve.h +++ b/rtgui/tonecurve.h @@ -29,6 +29,8 @@ class ToneCurve : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public rtengine::AutoExpListener, public CurveListener { +private: + IdleRegister idle_register; protected: // from HLRecovery @@ -73,7 +75,6 @@ protected: bool nextHLRecons; public: - ToneCurve (); ~ToneCurve (); diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index e1d0fc425..eede02eff 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -877,6 +877,8 @@ Wavelet::Wavelet() : Wavelet::~Wavelet () { + idle_register.destroy(); + delete opaCurveEditorG; delete opacityCurveEditorG; delete CCWcurveEditorG; @@ -887,26 +889,28 @@ Wavelet::~Wavelet () delete opacityCurveEditorWL; } -int wavUpdateUI (void* data) -{ - GThreadLock lock; // All GUI acces from idle_add callbacks or separate thread HAVE to be protected - (static_cast(data))->wavComputed_ (); - return 0; -} - void Wavelet::wavChanged (double nlevel) { nextnlevel = nlevel; - g_idle_add (wavUpdateUI, this); + + const auto func = [](gpointer data) -> gboolean { + GThreadLock lock; // All GUI acces from idle_add callbacks or separate thread HAVE to be protected + static_cast(data)->wavComputed_(); + + return FALSE; + }; + + idle_register.add(func, this); } + bool Wavelet::wavComputed_ () { - disableListener (); enableListener (); updatewavLabel (); return false; } + void Wavelet::updatewavLabel () { if (!batchMode) { diff --git a/rtgui/wavelet.h b/rtgui/wavelet.h index ff0964731..b73045228 100644 --- a/rtgui/wavelet.h +++ b/rtgui/wavelet.h @@ -40,7 +40,7 @@ class Wavelet : { public: Wavelet (); - virtual ~Wavelet (); + ~Wavelet (); bool wavComputed_ (); void adjusterChanged (ThresholdAdjuster* a, double newBottom, double newTop); @@ -248,4 +248,6 @@ private: bool lastmedian, lastmedianlev, lastlinkedg, lastavoid, lastlipst, lasttmr, lastcbenab; int nextnlevel; + + IdleRegister idle_register; }; From 91f8e460293f31f729d8a4e888b43d576b625d0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=B6ssie?= Date: Thu, 30 Mar 2017 21:17:34 +0200 Subject: [PATCH 2/3] Revert `ProgressConnector` Doesn't work with `IdleRegister`. --- rtgui/progressconnector.h | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/rtgui/progressconnector.h b/rtgui/progressconnector.h index 4cf9b1e4e..3ce20f8f8 100644 --- a/rtgui/progressconnector.h +++ b/rtgui/progressconnector.h @@ -65,36 +65,32 @@ public: template class ProgressConnector { -private: + sigc::signal0 opStart; sigc::signal0 opEnd; T retval; Glib::Thread *workThread; - IdleRegister idle_register; + + static int emitEndSignalUI (void* data) + { + + sigc::signal0* opEnd = (sigc::signal0*) data; + int r = opEnd->emit (); + delete opEnd; + + return r; + } void workingThread () { - retval = opStart.emit(); - - const auto func = [](gpointer data) -> gboolean { - sigc::signal0* const opEnd = static_cast*>(data); - const gboolean res = opEnd->emit(); - delete opEnd; - - return res; - }; - - idle_register.add(func, new sigc::signal0(opEnd)); - + retval = opStart.emit (); + gdk_threads_add_idle(ProgressConnector::emitEndSignalUI, new sigc::signal0(opEnd)); workThread = nullptr; } public: + ProgressConnector (): retval( 0 ), workThread( nullptr ) { } - ~ProgressConnector() - { - idle_register.destroy(); - } void startFunc (const sigc::slot0& startHandler, const sigc::slot0& endHandler ) { From 6e1f7df2fb9ad180b982939cfb888f6c9ba918dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=B6ssie?= Date: Thu, 30 Mar 2017 21:40:09 +0200 Subject: [PATCH 3/3] Replace `g_idle_add_full()` with `IdleRegister` (#3767) --- rtgui/batchqueuepanel.cc | 23 ++++++----- rtgui/batchqueuepanel.h | 4 +- rtgui/filebrowserentry.cc | 83 ++++++++++++++++++++------------------- rtgui/filebrowserentry.h | 2 + rtgui/guiutils.cc | 10 +---- rtgui/guiutils.h | 4 +- 6 files changed, 64 insertions(+), 62 deletions(-) diff --git a/rtgui/batchqueuepanel.cc b/rtgui/batchqueuepanel.cc index 1810501b5..78f1a8976 100644 --- a/rtgui/batchqueuepanel.cc +++ b/rtgui/batchqueuepanel.cc @@ -24,14 +24,6 @@ #include "soundman.h" #include "rtimage.h" -int processLoadedBatchQueueUIThread (void* data) -{ - - BatchQueue* bq = static_cast(data); - bq->resizeLoadedQueue(); - return 0; -} - static Glib::ustring makeFolderLabel(Glib::ustring path) { if (!Glib::file_test (path, Glib::FILE_TEST_IS_DIR)) { @@ -185,11 +177,22 @@ BatchQueuePanel::BatchQueuePanel (FileCatalog* aFileCatalog) show_all (); - if (batchQueue->loadBatchQueue ()) { - g_idle_add_full (G_PRIORITY_LOW, processLoadedBatchQueueUIThread, batchQueue, nullptr); + if (batchQueue->loadBatchQueue()) { + const auto func = [](gpointer data) -> gboolean { + static_cast(data)->resizeLoadedQueue(); + + return FALSE; + }; + + idle_register.add(func, batchQueue, G_PRIORITY_LOW); } } +BatchQueuePanel::~BatchQueuePanel() +{ + idle_register.destroy(); +} + void BatchQueuePanel::init (RTWindow *parent) { this->parent = parent; diff --git a/rtgui/batchqueuepanel.h b/rtgui/batchqueuepanel.h index b92f300be..a4d6ed244 100644 --- a/rtgui/batchqueuepanel.h +++ b/rtgui/batchqueuepanel.h @@ -53,9 +53,11 @@ class BatchQueuePanel : public Gtk::VBox, Gtk::HBox* bottomBox; Gtk::HBox* topBox; -public: + IdleRegister idle_register; +public: explicit BatchQueuePanel (FileCatalog* aFileCatalog); + ~BatchQueuePanel(); void init (RTWindow* parent); diff --git a/rtgui/filebrowserentry.cc b/rtgui/filebrowserentry.cc index d452b88cd..a2f88ee40 100644 --- a/rtgui/filebrowserentry.cc +++ b/rtgui/filebrowserentry.cc @@ -67,6 +67,7 @@ FileBrowserEntry::FileBrowserEntry (Thumbnail* thm, const Glib::ustring& fname) FileBrowserEntry::~FileBrowserEntry () { + idle_register.destroy(); // so jobs arriving now do nothing if (feih->pending) { @@ -176,39 +177,6 @@ void FileBrowserEntry::procParamsChanged (Thumbnail* thm, int whoChangedIt) } } -struct tiupdate { - FileBrowserEntryIdleHelper* feih; - rtengine::IImage8* img; - double scale; - rtengine::procparams::CropParams cropParams; -}; - -int updateImageUI (void* data) -{ - - tiupdate* params = static_cast(data); - FileBrowserEntryIdleHelper* feih = params->feih; - - if (feih->destroyed) { - if (feih->pending == 1) { - delete feih; - } else { - feih->pending--; - } - - params->img->free (); - delete params; - return 0; - } - - feih->fbentry->_updateImage (params->img, params->scale, params->cropParams); - feih->pending--; - - delete params; - - return 0; -} - void FileBrowserEntry::updateImage (rtengine::IImage8* img, double scale, rtengine::procparams::CropParams cropParams) { @@ -225,16 +193,51 @@ void FileBrowserEntry::updateImage (rtengine::IImage8* img, double scale, rtengi feih->pending++; } - tiupdate* param = new tiupdate (); - param->feih = feih; - param->img = img; - param->scale = scale; - param->cropParams = cropParams; + struct tiupdate { + FileBrowserEntryIdleHelper* feih; + rtengine::IImage8* img; + double scale; + rtengine::procparams::CropParams cropParams; + }; + + tiupdate* param = new tiupdate{ + feih, + img, + scale, + cropParams + }; + #if __GNUC__ == 4 && __GNUC_MINOR__ == 8 && defined( WIN32 ) && defined(__x86_64__) - g_idle_add_full (G_PRIORITY_DEFAULT, updateImageUI, param, NULL); + const gint priority = G_PRIORITY_DEFAULT; #else - g_idle_add_full (G_PRIORITY_LOW, updateImageUI, param, nullptr); + const gint priority = G_PRIORITY_LOW; #endif + + const auto func = [](gpointer data) -> gboolean { + tiupdate* const params = static_cast(data); + FileBrowserEntryIdleHelper* const feih = params->feih; + + if (feih->destroyed) { + if (feih->pending == 1) { + delete feih; + } else { + feih->pending--; + } + + params->img->free (); + delete params; + return 0; + } + + feih->fbentry->_updateImage (params->img, params->scale, params->cropParams); + feih->pending--; + + delete params; + + return FALSE; + }; + + idle_register.add(func, param, priority); } void FileBrowserEntry::_updateImage (rtengine::IImage8* img, double s, rtengine::procparams::CropParams cropParams) diff --git a/rtgui/filebrowserentry.h b/rtgui/filebrowserentry.h index 5b95ca069..cbbe2c595 100644 --- a/rtgui/filebrowserentry.h +++ b/rtgui/filebrowserentry.h @@ -57,6 +57,8 @@ class FileBrowserEntry : public ThumbBrowserEntryBase, ImgEditState state; + IdleRegister idle_register; + bool onArea (CursorArea a, int x, int y); void updateCursor (int x, int y); void drawStraightenGuide (Cairo::RefPtr c); diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc index 451af4e38..f78ee34e4 100644 --- a/rtgui/guiutils.cc +++ b/rtgui/guiutils.cc @@ -38,18 +38,12 @@ Glib::RefPtr MyExpander::disabledPBuf; Glib::RefPtr MyExpander::openedPBuf; Glib::RefPtr MyExpander::closedPBuf; -guint add_idle (GSourceFunc function, gpointer data) -{ - return gdk_threads_add_idle(function, data); - //gtk_main_iteration_do(false); -} - IdleRegister::~IdleRegister() { destroy(); } -void IdleRegister::add(GSourceFunc function, gpointer data) +void IdleRegister::add(GSourceFunc function, gpointer data, gint priority) { struct DataWrapper { IdleRegister* const self; @@ -79,7 +73,7 @@ void IdleRegister::add(GSourceFunc function, gpointer data) }; mutex.lock(); - ids[data_wrapper] = add_idle(dispatch, data_wrapper); + ids[data_wrapper] = gdk_threads_add_idle_full(priority, dispatch, data_wrapper, nullptr); mutex.unlock(); } diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h index 3f88adf0c..88f572e5a 100644 --- a/rtgui/guiutils.h +++ b/rtgui/guiutils.h @@ -44,15 +44,13 @@ void drawCrop (Cairo::RefPtr cr, int imx, int imy, int imw, int gboolean acquireGUI(void* data); void setExpandAlignProperties(Gtk::Widget *widget, bool hExpand, bool vExpand, enum Gtk::Align hAlign, enum Gtk::Align vAlign); -guint add_idle (GSourceFunc function, gpointer data); - class IdleRegister final : public rtengine::NonCopyable { public: ~IdleRegister(); - void add(GSourceFunc function, gpointer data); + void add(GSourceFunc function, gpointer data, gint priority = G_PRIORITY_DEFAULT_IDLE); void destroy(); private: