diff --git a/modules/highgui/src/window_gtk.cpp b/modules/highgui/src/window_gtk.cpp
index 0cfa59b1a9f2ba2f4e40c569a4e1c7b3cc28c77c..5bfd29e45d49fb5f0f2c0dad67c3eb1556d83879 100644
--- a/modules/highgui/src/window_gtk.cpp
+++ b/modules/highgui/src/window_gtk.cpp
@@ -42,6 +42,8 @@
 #include "precomp.hpp"
 #include "opencv2/imgproc.hpp"
 
+using namespace cv;
+
 #ifndef _WIN32
 
 #if defined (HAVE_GTK)
@@ -508,12 +510,30 @@ GType cvImageWidget_get_type (void){
 
 struct CvWindow;
 
-typedef struct CvTrackbar
-{
+struct CvUIBase {
+    CvUIBase(int signature_) : signature(signature_) { }
+
     int signature;
+};
+
+struct CvTrackbar : CvUIBase
+{
+    CvTrackbar(const char* trackbar_name) :
+        CvUIBase(CV_TRACKBAR_MAGIC_VAL),
+        widget(NULL), name(trackbar_name),
+        parent(NULL), data(NULL),
+        pos(0), maxval(0), minval(0),
+        notify(NULL), notify2(NULL), userdata(NULL)
+    {
+        // nothing
+    }
+    ~CvTrackbar()
+    {
+        // destroyed by parent window
+    }
+
     GtkWidget* widget;
-    char* name;
-    CvTrackbar* next;
+    std::string name;
     CvWindow* parent;
     int* data;
     int pos;
@@ -522,19 +542,28 @@ typedef struct CvTrackbar
     CvTrackbarCallback notify;
     CvTrackbarCallback2 notify2;
     void* userdata;
-}
-CvTrackbar;
+};
 
 
-typedef struct CvWindow
+struct CvWindow : CvUIBase
 {
-    int signature;
+    CvWindow(const char* window_name) :
+        CvUIBase(CV_WINDOW_MAGIC_VAL),
+        widget(NULL), frame(NULL), paned(NULL), name(window_name),
+        last_key(0), flags(0), status(0),
+        on_mouse(NULL), on_mouse_param(NULL)
+#ifdef HAVE_OPENGL
+        ,useGl(false), glDrawCallback(NULL), glDrawData(NULL)
+#endif
+    {
+        // nothing
+    }
+    ~CvWindow();
+
     GtkWidget* widget;
     GtkWidget* frame;
     GtkWidget* paned;
-    char* name;
-    CvWindow* prev;
-    CvWindow* next;
+    std::string name;
 
     int last_key;
     int flags;
@@ -543,13 +572,7 @@ typedef struct CvWindow
     CvMouseCallback on_mouse;
     void* on_mouse_param;
 
-    struct
-    {
-        int pos;
-        int rows;
-        CvTrackbar* first;
-    }
-    toolbar;
+    std::vector< Ptr<CvTrackbar> > trackbars;
 
 #ifdef HAVE_OPENGL
     bool useGl;
@@ -557,8 +580,7 @@ typedef struct CvWindow
     CvOpenGlDrawCallback glDrawCallback;
     void* glDrawData;
 #endif
-}
-CvWindow;
+};
 
 
 static gboolean icvOnClose( GtkWidget* widget, GdkEvent* event, gpointer user_data );
@@ -569,15 +591,14 @@ static gboolean icvOnMouse( GtkWidget *widget, GdkEvent *event, gpointer user_da
 #ifdef HAVE_GTHREAD
 int thread_started=0;
 static gpointer icvWindowThreadLoop();
-GMutex*				   last_key_mutex;
-GCond*				   cond_have_key;
-GMutex*				   window_mutex;
-GThread*			   window_thread;
-GtkWidget*             cvTopLevelWidget = 0;
+GMutex*				   last_key_mutex = NULL;
+GCond*				   cond_have_key = NULL;
+GMutex*				   window_mutex = NULL;
+GThread*			   window_thread = NULL;
 #endif
 
 static int             last_key = -1;
-static CvWindow* hg_windows = 0;
+static std::vector< Ptr<CvWindow> > g_windows;
 
 CV_IMPL int cvInitSystem( int argc, char** argv )
 {
@@ -586,8 +607,6 @@ CV_IMPL int cvInitSystem( int argc, char** argv )
     // check initialization status
     if( !wasInitialized )
     {
-        hg_windows = 0;
-
         gtk_init( &argc, &argv );
         setlocale(LC_NUMERIC,"C");
 
@@ -635,7 +654,8 @@ CV_IMPL int cvStartWindowThread(){
 }
 
 #ifdef HAVE_GTHREAD
-gpointer icvWindowThreadLoop(){
+gpointer icvWindowThreadLoop()
+{
     while(1){
         g_mutex_lock(window_mutex);
         gtk_main_iteration_do(FALSE);
@@ -649,201 +669,152 @@ gpointer icvWindowThreadLoop(){
     return NULL;
 }
 
-#define CV_LOCK_MUTEX() \
-if(thread_started && g_thread_self()!=window_thread){ g_mutex_lock( window_mutex ); } else { }
 
-#define CV_UNLOCK_MUTEX() \
-if(thread_started && g_thread_self()!=window_thread){ g_mutex_unlock( window_mutex); } else { }
+class GMutexLock {
+    GMutex* mutex_;
+public:
+    GMutexLock(GMutex* mutex) : mutex_(mutex) { if (mutex_) g_mutex_lock(mutex_); }
+    ~GMutexLock() { if (mutex_) g_mutex_unlock(mutex_); mutex_ = NULL; }
+};
+
+#define CV_LOCK_MUTEX() GMutexLock lock(window_mutex);
 
 #else
 #define CV_LOCK_MUTEX()
-#define CV_UNLOCK_MUTEX()
 #endif
 
 static CvWindow* icvFindWindowByName( const char* name )
 {
-    CvWindow* window = hg_windows;
-    while( window != 0 && strcmp(name, window->name) != 0 )
-        window = window->next;
-
-    return window;
+    for(size_t i = 0; i < g_windows.size(); ++i)
+    {
+        CvWindow* window = g_windows[i].get();
+        if (window->name == name)
+            return window;
+    }
+    return NULL;
 }
 
 static CvWindow* icvWindowByWidget( GtkWidget* widget )
 {
-    CvWindow* window = hg_windows;
-
-    while( window != 0 && window->widget != widget &&
-           window->frame != widget && window->paned != widget )
-        window = window->next;
-
-    return window;
+    for (size_t i = 0; i < g_windows.size(); ++i)
+    {
+        CvWindow* window = g_windows[i].get();
+        if (window->widget == widget || window->frame == widget || window->paned == widget)
+            return window;
+    }
+    return NULL;
 }
 
 double cvGetModeWindow_GTK(const char* name)//YV
 {
-    double result = -1;
-
-    CV_FUNCNAME( "cvGetModeWindow_GTK" );
-
-    __BEGIN__;
-
-    CvWindow* window;
-
-    if (!name)
-        CV_ERROR( CV_StsNullPtr, "NULL name string" );
-
-    window = icvFindWindowByName( name );
-    if (!window)
-        CV_ERROR( CV_StsNullPtr, "NULL window" );
+    CV_Assert(name && "NULL name string");
 
     CV_LOCK_MUTEX();
-    result = window->status;
-    CV_UNLOCK_MUTEX();
+    CvWindow* window = icvFindWindowByName(name);
+    if (!window)
+        CV_Error( CV_StsNullPtr, "NULL window" );
 
-    __END__;
+    double result = window->status;
     return result;
 }
 
 
 void cvSetModeWindow_GTK( const char* name, double prop_value)//Yannick Verdie
 {
+    CV_Assert(name && "NULL name string");
 
-    CV_FUNCNAME( "cvSetModeWindow_GTK" );
-
-    __BEGIN__;
-
-    CvWindow* window;
-
-    if(!name)
-        CV_ERROR( CV_StsNullPtr, "NULL name string" );
+    CV_LOCK_MUTEX();
 
-    window = icvFindWindowByName( name );
+    CvWindow* window = icvFindWindowByName(name);
     if( !window )
-        CV_ERROR( CV_StsNullPtr, "NULL window" );
+        CV_Error( CV_StsNullPtr, "NULL window" );
 
     if(window->flags & CV_WINDOW_AUTOSIZE)//if the flag CV_WINDOW_AUTOSIZE is set
-        EXIT;
+        return;
 
     //so easy to do fullscreen here, Linux rocks !
 
     if (window->status==CV_WINDOW_FULLSCREEN && prop_value==CV_WINDOW_NORMAL)
     {
-        CV_LOCK_MUTEX();
         gtk_window_unfullscreen(GTK_WINDOW(window->frame));
         window->status=CV_WINDOW_NORMAL;
-        CV_UNLOCK_MUTEX();
-        EXIT;
+        return;
     }
 
     if (window->status==CV_WINDOW_NORMAL && prop_value==CV_WINDOW_FULLSCREEN)
     {
-        CV_LOCK_MUTEX();
         gtk_window_fullscreen(GTK_WINDOW(window->frame));
         window->status=CV_WINDOW_FULLSCREEN;
-        CV_UNLOCK_MUTEX();
-        EXIT;
+        return;
     }
-
-    __END__;
 }
 
 void cv::setWindowTitle(const String& winname, const String& title)
 {
+    CV_LOCK_MUTEX();
+
     CvWindow* window = icvFindWindowByName(winname.c_str());
 
     if (!window)
     {
         namedWindow(winname);
         window = icvFindWindowByName(winname.c_str());
+        CV_Assert(window);
     }
 
-    if (!window)
-        CV_Error(Error::StsNullPtr, "NULL window");
-
-    CV_LOCK_MUTEX();
     gtk_window_set_title(GTK_WINDOW(window->frame), title.c_str());
-    CV_UNLOCK_MUTEX();
 }
 
 double cvGetPropWindowAutoSize_GTK(const char* name)
 {
-    double result = -1;
-
-    CV_FUNCNAME( "cvGetPropWindowAutoSize_GTK" );
+    CV_Assert(name && "NULL name string");
 
-    __BEGIN__;
-
-    CvWindow* window;
-
-    if (!name)
-        CV_ERROR( CV_StsNullPtr, "NULL name string" );
+    CV_LOCK_MUTEX();
 
-    window = icvFindWindowByName( name );
+    CvWindow* window = icvFindWindowByName(name);
     if (!window)
-        EXIT; // keep silence here
-
-    result = window->flags & CV_WINDOW_AUTOSIZE;
-
-    __END__;
+        return -1; // keep silence here
 
+    double result = window->flags & CV_WINDOW_AUTOSIZE;
     return result;
 }
 
 double cvGetRatioWindow_GTK(const char* name)
 {
-    double result = -1;
-
-    CV_FUNCNAME( "cvGetRatioWindow_GTK" );
-
-    __BEGIN__;
+    CV_Assert(name && "NULL name string");
 
-    CvWindow* window;
-
-    if (!name)
-        CV_ERROR( CV_StsNullPtr, "NULL name string" );
+    CV_LOCK_MUTEX();
 
-    window = icvFindWindowByName( name );
+    CvWindow* window = icvFindWindowByName(name);
     if (!window)
-        EXIT; // keep silence here
+        return -1; // keep silence here
 
 #if defined (GTK_VERSION3)
-    result = static_cast<double>(
+    double result = static_cast<double>(
         gtk_widget_get_allocated_width(window->widget)) / gtk_widget_get_allocated_height(window->widget);
 #else
-    result = static_cast<double>(window->widget->allocation.width) / window->widget->allocation.height;
+    double result = static_cast<double>(window->widget->allocation.width) / window->widget->allocation.height;
 #endif // GTK_VERSION3
-    __END__;
-
     return result;
 }
 
 double cvGetOpenGlProp_GTK(const char* name)
 {
-    double result = -1;
-
 #ifdef HAVE_OPENGL
-    CV_FUNCNAME( "cvGetOpenGlProp_GTK" );
+    CV_Assert(name && "NULL name string");
 
-    __BEGIN__;
-
-    CvWindow* window;
-
-    if (!name)
-        CV_ERROR( CV_StsNullPtr, "NULL name string" );
+    CV_LOCK_MUTEX();
 
-    window = icvFindWindowByName( name );
+    CvWindow* window = icvFindWindowByName(name);
     if (!window)
-        EXIT; // keep silence here
-
-    result = window->useGl;
+        return -1; // keep silence here
 
-    __END__;
+    double result = window->useGl;
+    return result;
 #else
     (void)name;
+    return -1;
 #endif
-
-    return result;
 }
 
 
@@ -857,35 +828,25 @@ namespace
     {
         GdkGLConfig* glconfig;
 
-        CV_FUNCNAME( "createGlContext" );
-
-        __BEGIN__;
-
         // Try double-buffered visual
         glconfig = gdk_gl_config_new_by_mode((GdkGLConfigMode)(GDK_GL_MODE_RGB | GDK_GL_MODE_DEPTH | GDK_GL_MODE_DOUBLE));
         if (!glconfig)
-            CV_ERROR( CV_OpenGlApiCallError, "Can't Create A GL Device Context" );
+            CV_Error( CV_OpenGlApiCallError, "Can't Create A GL Device Context" );
 
         // Set OpenGL-capability to the widget
         if (!gtk_widget_set_gl_capability(window->widget, glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE))
-            CV_ERROR( CV_OpenGlApiCallError, "Can't Create A GL Device Context" );
+            CV_Error( CV_OpenGlApiCallError, "Can't Create A GL Device Context" );
 
         window->useGl = true;
-
-        __END__;
     }
 
     void drawGl(CvWindow* window)
     {
-        CV_FUNCNAME( "drawGl" );
-
-        __BEGIN__;
-
         GdkGLContext* glcontext = gtk_widget_get_gl_context(window->widget);
         GdkGLDrawable* gldrawable = gtk_widget_get_gl_drawable(window->widget);
 
         if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext))
-            CV_ERROR( CV_OpenGlApiCallError, "Can't Activate The GL Rendering Context" );
+            CV_Error( CV_OpenGlApiCallError, "Can't Activate The GL Rendering Context" );
 
         glViewport(0, 0, window->widget->allocation.width, window->widget->allocation.height);
 
@@ -900,8 +861,6 @@ namespace
             glFlush();
 
         gdk_gl_drawable_gl_end(gldrawable);
-
-        __END__;
     }
 }
 
@@ -1015,43 +974,21 @@ static gboolean cvImageWidget_expose(GtkWidget* widget, GdkEventExpose* event, g
 
 CV_IMPL int cvNamedWindow( const char* name, int flags )
 {
-    int result = 0;
-    CV_FUNCNAME( "cvNamedWindow" );
-
-    __BEGIN__;
-
-    CvWindow* window;
-    int len;
-    int b_nautosize;
+    cvInitSystem(name ? 1 : 0,(char**)&name);
+    CV_Assert(name && "NULL name string");
 
-    cvInitSystem(1,(char**)&name);
-    if( !name )
-        CV_ERROR( CV_StsNullPtr, "NULL name string" );
+    CV_LOCK_MUTEX();
 
     // Check the name in the storage
-    if( icvFindWindowByName( name ) != 0 )
+    if (icvFindWindowByName(name))
     {
-        result = 1;
-        EXIT;
+        return 1;
     }
 
-    len = strlen(name);
-    CV_CALL( window = (CvWindow*)cvAlloc(sizeof(CvWindow) + len + 1));
-    memset( window, 0, sizeof(*window));
-    window->name = (char*)(window + 1);
-    memcpy( window->name, name, len + 1 );
+    Ptr<CvWindow> window = makePtr<CvWindow>(name);
     window->flags = flags;
-    window->signature = CV_WINDOW_MAGIC_VAL;
-    window->last_key = 0;
-    window->on_mouse = 0;
-    window->on_mouse_param = 0;
-    memset( &window->toolbar, 0, sizeof(window->toolbar));
-    window->next = hg_windows;
-    window->prev = 0;
     window->status = CV_WINDOW_NORMAL;//YV
 
-    CV_LOCK_MUTEX();
-
     window->frame = gtk_window_new( GTK_WINDOW_TOPLEVEL );
 
     window->paned = gtk_vbox_new( FALSE, 0 );
@@ -1063,7 +1000,7 @@ CV_IMPL int cvNamedWindow( const char* name, int flags )
 
 #ifndef HAVE_OPENGL
     if (flags & CV_WINDOW_OPENGL)
-        CV_ERROR( CV_OpenGlNotSupported, "Library was built without OpenGL support" );
+        CV_Error( CV_OpenGlNotSupported, "Library was built without OpenGL support" );
 #else
     if (flags & CV_WINDOW_OPENGL)
         createGlContext(window);
@@ -1105,11 +1042,9 @@ CV_IMPL int cvNamedWindow( const char* name, int flags )
     gtk_widget_show( window->frame );
     gtk_window_set_title( GTK_WINDOW(window->frame), name );
 
-    if( hg_windows )
-        hg_windows->prev = window;
-    hg_windows = window;
+    g_windows.push_back(window);
 
-    b_nautosize = ((flags & CV_WINDOW_AUTOSIZE) == 0);
+    bool b_nautosize = ((flags & CV_WINDOW_AUTOSIZE) == 0);
     gtk_window_set_resizable( GTK_WINDOW(window->frame), b_nautosize );
 
     // allow window to be resized
@@ -1121,17 +1056,12 @@ CV_IMPL int cvNamedWindow( const char* name, int flags )
             &geometry, (GdkWindowHints) (GDK_HINT_MIN_SIZE));
     }
 
-    CV_UNLOCK_MUTEX();
-
 #ifdef HAVE_OPENGL
     if (window->useGl)
         cvSetOpenGlContext(name);
 #endif
 
-    result = 1;
-    __END__;
-
-    return result;
+    return 1;
 }
 
 
@@ -1139,110 +1069,71 @@ CV_IMPL int cvNamedWindow( const char* name, int flags )
 
 CV_IMPL void cvSetOpenGlContext(const char* name)
 {
-    CvWindow* window;
     GdkGLContext* glcontext;
     GdkGLDrawable* gldrawable;
 
-    CV_FUNCNAME( "cvSetOpenGlContext" );
-
-    __BEGIN__;
+    CV_Assert(name && "NULL name string");
 
-    if(!name)
-        CV_ERROR( CV_StsNullPtr, "NULL name string" );
+    CV_LOCK_MUTEX();
 
-    window = icvFindWindowByName( name );
+    CvWindow* window = icvFindWindowByName(name);
     if (!window)
-        CV_ERROR( CV_StsNullPtr, "NULL window" );
+        CV_Error( CV_StsNullPtr, "NULL window" );
 
     if (!window->useGl)
-        CV_ERROR( CV_OpenGlNotSupported, "Window doesn't support OpenGL" );
+        CV_Error( CV_OpenGlNotSupported, "Window doesn't support OpenGL" );
 
     glcontext = gtk_widget_get_gl_context(window->widget);
     gldrawable = gtk_widget_get_gl_drawable(window->widget);
 
     if (!gdk_gl_drawable_make_current(gldrawable, glcontext))
-        CV_ERROR( CV_OpenGlApiCallError, "Can't Activate The GL Rendering Context" );
-
-    __END__;
+        CV_Error( CV_OpenGlApiCallError, "Can't Activate The GL Rendering Context" );
 }
 
 CV_IMPL void cvUpdateWindow(const char* name)
 {
-    CV_FUNCNAME( "cvUpdateWindow" );
-
-    __BEGIN__;
-
-    CvWindow* window;
+    CV_Assert(name && "NULL name string");
 
-    if (!name)
-        CV_ERROR( CV_StsNullPtr, "NULL name string" );
+    CV_LOCK_MUTEX();
 
-    window = icvFindWindowByName( name );
+    CvWindow* window = icvFindWindowByName(name);
     if (!window)
-        EXIT;
+        return;
 
     // window does not refresh without this
     gtk_widget_queue_draw( GTK_WIDGET(window->widget) );
-
-    __END__;
 }
 
 CV_IMPL void cvSetOpenGlDrawCallback(const char* name, CvOpenGlDrawCallback callback, void* userdata)
 {
-    CvWindow* window;
-
-    CV_FUNCNAME( "cvCreateOpenGLCallback" );
+    CV_Assert(name && "NULL name string");
 
-    __BEGIN__;
-
-    if(!name)
-        CV_ERROR( CV_StsNullPtr, "NULL name string" );
+    CV_LOCK_MUTEX();
 
-    window = icvFindWindowByName( name );
+    CvWindow* window = icvFindWindowByName(name);
     if( !window )
-        EXIT;
+        return;
 
     if (!window->useGl)
-        CV_ERROR( CV_OpenGlNotSupported, "Window was created without OpenGL context" );
+        CV_Error( CV_OpenGlNotSupported, "Window was created without OpenGL context" );
 
     window->glDrawCallback = callback;
     window->glDrawData = userdata;
-
-    __END__;
 }
 
 #endif // HAVE_OPENGL
 
 
 
-
-static void icvDeleteWindow( CvWindow* window )
+CvWindow::~CvWindow()
 {
-    CvTrackbar* trackbar;
-
-    if( window->prev )
-        window->prev->next = window->next;
-    else
-        hg_windows = window->next;
-
-    if( window->next )
-        window->next->prev = window->prev;
-
-    window->prev = window->next = 0;
-
-    gtk_widget_destroy( window->frame );
-
-    for( trackbar = window->toolbar.first; trackbar != 0; )
-    {
-        CvTrackbar* next = trackbar->next;
-        cvFree( &trackbar );
-        trackbar = next;
-    }
-
-    cvFree( &window );
+    gtk_widget_destroy(frame);
+}
 
+static void checkLastWindow()
+{
     // if last window...
-    if( hg_windows == 0 )
+    if (g_windows.empty())
     {
 #ifdef HAVE_GTHREAD
         if( thread_started )
@@ -1269,32 +1160,44 @@ static void icvDeleteWindow( CvWindow* window )
     }
 }
 
-
-CV_IMPL void cvDestroyWindow( const char* name )
+static void icvDeleteWindow( CvWindow* window )
 {
-    CV_FUNCNAME( "cvDestroyWindow" );
-
-    __BEGIN__;
-
-    CvWindow* window;
+    bool found = false;
+    for (std::vector< Ptr<CvWindow> >::iterator i = g_windows.begin();
+         i != g_windows.end(); ++i)
+    {
+        if (i->get() == window)
+        {
+            g_windows.erase(i);
+            found = true;
+            break;
+        }
+    }
+    CV_Assert(found && "Can't destroy non-registered window");
 
-    if(!name)
-        CV_ERROR( CV_StsNullPtr, "NULL name string" );
+    checkLastWindow();
+}
 
-    window = icvFindWindowByName( name );
-    if( !window )
-        EXIT;
+CV_IMPL void cvDestroyWindow( const char* name )
+{
+    CV_Assert(name && "NULL name string");
 
-    // note that it is possible for the update thread to run this function
-    // if there is a call to cvShowImage in a mouse callback
-    // (this would produce a deadlock on window_mutex)
     CV_LOCK_MUTEX();
 
-    icvDeleteWindow( window );
-
-    CV_UNLOCK_MUTEX();
+    bool found = false;
+    for (std::vector< Ptr<CvWindow> >::iterator i = g_windows.begin();
+         i != g_windows.end(); ++i)
+    {
+        if (i->get()->name == name)
+        {
+            g_windows.erase(i);
+            found = true;
+            break;
+        }
+    }
+    CV_Assert(found && "Can't destroy non-registered window");
 
-    __END__;
+    checkLastWindow();
 }
 
 
@@ -1303,12 +1206,8 @@ cvDestroyAllWindows( void )
 {
     CV_LOCK_MUTEX();
 
-    while( hg_windows )
-    {
-        CvWindow* window = hg_windows;
-        icvDeleteWindow( window );
-    }
-    CV_UNLOCK_MUTEX();
+    g_windows.clear();
+    checkLastWindow();
 }
 
 // CvSize icvCalcOptimalWindowSize( CvWindow * window, CvSize new_image_size){
@@ -1326,25 +1225,19 @@ cvDestroyAllWindows( void )
 CV_IMPL void
 cvShowImage( const char* name, const CvArr* arr )
 {
-    CV_FUNCNAME( "cvShowImage" );
-
-    __BEGIN__;
-
-    CvWindow* window;
-
-    if( !name )
-        CV_ERROR( CV_StsNullPtr, "NULL name" );
+    CV_Assert(name && "NULL name string");
 
     CV_LOCK_MUTEX();
 
-    window = icvFindWindowByName(name);
+    CvWindow* window = icvFindWindowByName(name);
     if(!window)
     {
         cvNamedWindow(name, 1);
         window = icvFindWindowByName(name);
     }
+    CV_Assert(window);
 
-    if( window && arr )
+    if (arr)
     {
     #ifdef HAVE_OPENGL
         if (window->useGl)
@@ -1357,81 +1250,55 @@ cvShowImage( const char* name, const CvArr* arr )
         CvImageWidget * image_widget = CV_IMAGE_WIDGET( window->widget );
         cvImageWidgetSetImage( image_widget, arr );
     }
-
-    CV_UNLOCK_MUTEX();
-
-    __END__;
 }
 
 CV_IMPL void cvResizeWindow(const char* name, int width, int height )
 {
-    CV_FUNCNAME( "cvResizeWindow" );
-
-    __BEGIN__;
+    CV_Assert(name && "NULL name string");
 
-    CvWindow* window;
-    CvImageWidget * image_widget;
-
-    if( !name )
-        CV_ERROR( CV_StsNullPtr, "NULL name" );
+    CV_LOCK_MUTEX();
 
-    window = icvFindWindowByName(name);
+    CvWindow* window = icvFindWindowByName(name);
     if(!window)
-        EXIT;
+        return;
 
-    image_widget = CV_IMAGE_WIDGET( window->widget );
+    CvImageWidget* image_widget = CV_IMAGE_WIDGET( window->widget );
     //if(image_widget->flags & CV_WINDOW_AUTOSIZE)
         //EXIT;
 
-    CV_LOCK_MUTEX();
-
     gtk_window_set_resizable( GTK_WINDOW(window->frame), 1 );
     gtk_window_resize( GTK_WINDOW(window->frame), width, height );
 
     // disable initial resize since presumably user wants to keep
     // this window size
     image_widget->flags &= ~CV_WINDOW_NO_IMAGE;
-
-    CV_UNLOCK_MUTEX();
-
-    __END__;
 }
 
 
 CV_IMPL void cvMoveWindow( const char* name, int x, int y )
 {
-    CV_FUNCNAME( "cvMoveWindow" );
+    CV_Assert(name && "NULL name string");
 
-    __BEGIN__;
-
-    CvWindow* window;
-
-    if( !name )
-        CV_ERROR( CV_StsNullPtr, "NULL name" );
+    CV_LOCK_MUTEX();
 
-    window = icvFindWindowByName(name);
+    CvWindow* window = icvFindWindowByName(name);
     if(!window)
-        EXIT;
-
-    CV_LOCK_MUTEX();
+        return;
 
     gtk_window_move( GTK_WINDOW(window->frame), x, y );
-
-    CV_UNLOCK_MUTEX();
-
-    __END__;
 }
 
 
 static CvTrackbar*
 icvFindTrackbarByName( const CvWindow* window, const char* name )
 {
-    CvTrackbar* trackbar = window->toolbar.first;
-
-    for( ; trackbar != 0 && strcmp( trackbar->name, name ) != 0; trackbar = trackbar->next )
-        ;
-
-    return trackbar;
+    for (size_t i = 0; i < window->trackbars.size(); ++i)
+    {
+        CvTrackbar* trackbar = window->trackbars[i].get();
+        if (trackbar->name == name)
+            return trackbar;
+    }
+    return NULL;
 }
 
 static int
@@ -1439,41 +1306,25 @@ icvCreateTrackbar( const char* trackbar_name, const char* window_name,
                    int* val, int count, CvTrackbarCallback on_notify,
                    CvTrackbarCallback2 on_notify2, void* userdata )
 {
-    int result = 0;
-
-    CV_FUNCNAME( "icvCreateTrackbar" );
-
-    __BEGIN__;
-
-    /*char slider_name[32];*/
-    CvWindow* window = 0;
-    CvTrackbar* trackbar = 0;
-
-    if( !window_name || !trackbar_name )
-        CV_ERROR( CV_StsNullPtr, "NULL window or trackbar name" );
+    CV_Assert(window_name && "NULL window name");
+    CV_Assert(trackbar_name && "NULL trackbar name");
 
     if( count <= 0 )
-        CV_ERROR( CV_StsOutOfRange, "Bad trackbar maximal value" );
-
-    window = icvFindWindowByName(window_name);
-    if( !window )
-        EXIT;
-
-    trackbar = icvFindTrackbarByName(window,trackbar_name);
+        CV_Error( CV_StsOutOfRange, "Bad trackbar maximal value" );
 
     CV_LOCK_MUTEX();
 
-    if( !trackbar )
+    CvWindow* window = icvFindWindowByName(window_name);
+    if(!window)
+        return 0;
+
+    CvTrackbar* trackbar = icvFindTrackbarByName(window, trackbar_name);
+    if (!trackbar)
     {
-        int len = strlen(trackbar_name);
-        trackbar = (CvTrackbar*)cvAlloc(sizeof(CvTrackbar) + len + 1);
-        memset( trackbar, 0, sizeof(*trackbar));
-        trackbar->signature = CV_TRACKBAR_MAGIC_VAL;
-        trackbar->name = (char*)(trackbar+1);
-        memcpy( trackbar->name, trackbar_name, len + 1 );
+        Ptr<CvTrackbar> trackbar_ = makePtr<CvTrackbar>(trackbar_name);
+        trackbar = trackbar_.get();
         trackbar->parent = window;
-        trackbar->next = window->toolbar.first;
-        window->toolbar.first = trackbar;
+        window->trackbars.push_back(trackbar_);
 
         GtkWidget* hscale_box = gtk_hbox_new( FALSE, 10 );
         GtkWidget* hscale_label = gtk_label_new( trackbar_name );
@@ -1489,7 +1340,6 @@ icvCreateTrackbar( const char* trackbar_name, const char* window_name,
         gtk_widget_show( hscale );
         gtk_box_pack_start( GTK_BOX(window->paned), hscale_box, FALSE, FALSE, 5 );
         gtk_widget_show( hscale_box );
-
     }
 
     if( val )
@@ -1515,14 +1365,7 @@ icvCreateTrackbar( const char* trackbar_name, const char* window_name,
     // compensate for the addition of trackbars
     gtk_widget_queue_resize( GTK_WIDGET(window->widget) );
 
-
-    CV_UNLOCK_MUTEX();
-
-    result = 1;
-
-    __END__;
-
-    return result;
+    return 1;
 }
 
 
@@ -1548,209 +1391,134 @@ cvCreateTrackbar2( const char* trackbar_name, const char* window_name,
 CV_IMPL void
 cvSetMouseCallback( const char* window_name, CvMouseCallback on_mouse, void* param )
 {
-    CV_FUNCNAME( "cvSetMouseCallback" );
-
-    __BEGIN__;
-
-    CvWindow* window = 0;
+    CV_Assert(window_name && "NULL window name");
 
-    if( !window_name )
-        CV_ERROR( CV_StsNullPtr, "NULL window name" );
+    CV_LOCK_MUTEX();
 
-    window = icvFindWindowByName(window_name);
-    if( !window )
-        EXIT;
+    CvWindow* window = icvFindWindowByName(window_name);
+    if (!window)
+        return;
 
     window->on_mouse = on_mouse;
     window->on_mouse_param = param;
-
-    __END__;
 }
 
 
 CV_IMPL int cvGetTrackbarPos( const char* trackbar_name, const char* window_name )
 {
-    int pos = -1;
-
-    CV_FUNCNAME( "cvGetTrackbarPos" );
-
-    __BEGIN__;
-
-    CvWindow* window;
-    CvTrackbar* trackbar = 0;
+    CV_Assert(window_name && "NULL window name");
+    CV_Assert(trackbar_name && "NULL trackbar name");
 
-    if( trackbar_name == 0 || window_name == 0 )
-        CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name" );
-
-    window = icvFindWindowByName( window_name );
-    if( window )
-        trackbar = icvFindTrackbarByName( window, trackbar_name );
+    CV_LOCK_MUTEX();
 
-    if( trackbar )
-        pos = trackbar->pos;
+    CvWindow* window = icvFindWindowByName(window_name);
+    if (!window)
+        return -1;
 
-    __END__;
+    CvTrackbar* trackbar = icvFindTrackbarByName(window,trackbar_name);
+    if (!trackbar)
+        return -1;
 
-    return pos;
+    return trackbar->pos;
 }
 
 
 CV_IMPL void cvSetTrackbarPos( const char* trackbar_name, const char* window_name, int pos )
 {
-    CV_FUNCNAME( "cvSetTrackbarPos" );
+    CV_Assert(window_name && "NULL window name");
+    CV_Assert(trackbar_name && "NULL trackbar name");
 
-    __BEGIN__;
-
-    CvWindow* window;
-    CvTrackbar* trackbar = 0;
-
-    if( trackbar_name == 0 || window_name == 0 )
-        CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name" );
+    CV_LOCK_MUTEX();
 
-    window = icvFindWindowByName( window_name );
-    if( window )
-        trackbar = icvFindTrackbarByName( window, trackbar_name );
+    CvWindow* window = icvFindWindowByName(window_name);
+    if(!window)
+        return;
 
+    CvTrackbar* trackbar = icvFindTrackbarByName(window,trackbar_name);
     if( trackbar )
     {
-        if( pos < 0 )
-            pos = 0;
+        if( pos < trackbar->minval )
+            pos = trackbar->minval;
 
         if( pos > trackbar->maxval )
             pos = trackbar->maxval;
     }
     else
     {
-        CV_ERROR( CV_StsNullPtr, "No trackbar found" );
+        CV_Error( CV_StsNullPtr, "No trackbar found" );
     }
 
-    CV_LOCK_MUTEX();
-
     gtk_range_set_value( GTK_RANGE(trackbar->widget), pos );
-
-    CV_UNLOCK_MUTEX();
-
-    __END__;
 }
 
 
 CV_IMPL void cvSetTrackbarMax(const char* trackbar_name, const char* window_name, int maxval)
 {
-    CV_FUNCNAME("cvSetTrackbarMax");
+    CV_Assert(window_name && "NULL window name");
+    CV_Assert(trackbar_name && "NULL trackbar name");
 
-    __BEGIN__;
-
-    if (maxval >= 0)
-    {
-        CvWindow* window = 0;
-        CvTrackbar* trackbar = 0;
-
-        if (trackbar_name == 0 || window_name == 0)
-        {
-            CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name");
-        }
-
-        window = icvFindWindowByName( window_name );
-        if (window)
-        {
-            trackbar = icvFindTrackbarByName(window, trackbar_name);
-            if (trackbar)
-            {
-                trackbar->maxval = (trackbar->minval>maxval)?trackbar->minval:maxval;
-
-                CV_LOCK_MUTEX();
+    CV_LOCK_MUTEX();
 
-                gtk_range_set_range(GTK_RANGE(trackbar->widget), 0, trackbar->maxval);
+    CvWindow* window = icvFindWindowByName(window_name);
+    if(!window)
+        return;
 
-                CV_UNLOCK_MUTEX();
-            }
-        }
-    }
+    CvTrackbar* trackbar = icvFindTrackbarByName(window,trackbar_name);
+    if(!trackbar)
+        return;
 
-    __END__;
+    trackbar->maxval = maxval;
+    if (trackbar->maxval >= trackbar->minval)
+        gtk_range_set_range(GTK_RANGE(trackbar->widget), trackbar->minval, trackbar->maxval);
 }
 
 
 CV_IMPL void cvSetTrackbarMin(const char* trackbar_name, const char* window_name, int minval)
 {
-    CV_FUNCNAME("cvSetTrackbarMin");
-
-    __BEGIN__;
-
-    if (minval >= 0)
-    {
-        CvWindow* window = 0;
-        CvTrackbar* trackbar = 0;
+    CV_Assert(window_name && "NULL window name");
+    CV_Assert(trackbar_name && "NULL trackbar name");
 
-        if (trackbar_name == 0 || window_name == 0)
-        {
-            CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name");
-        }
-
-        window = icvFindWindowByName( window_name );
-        if (window)
-        {
-            trackbar = icvFindTrackbarByName(window, trackbar_name);
-            if (trackbar)
-            {
-                trackbar->minval = (minval<trackbar->maxval)?minval:trackbar->maxval;
-
-                CV_LOCK_MUTEX();
+    CV_LOCK_MUTEX();
 
-                gtk_range_set_range(GTK_RANGE(trackbar->widget), minval, trackbar->maxval);
+    CvWindow* window = icvFindWindowByName(window_name);
+    if(!window)
+        return;
 
-                CV_UNLOCK_MUTEX();
-            }
-        }
-    }
+    CvTrackbar* trackbar = icvFindTrackbarByName(window,trackbar_name);
+    if(!trackbar)
+        return;
 
-    __END__;
+    trackbar->minval = minval;
+    if (trackbar->maxval >= trackbar->minval)
+        gtk_range_set_range(GTK_RANGE(trackbar->widget), trackbar->minval, trackbar->maxval);
 }
 
 
 CV_IMPL void* cvGetWindowHandle( const char* window_name )
 {
-    void* widget = 0;
-
-    CV_FUNCNAME( "cvGetWindowHandle" );
-
-    __BEGIN__;
-
-    CvWindow* window;
-
-    if( window_name == 0 )
-        CV_ERROR( CV_StsNullPtr, "NULL window name" );
+    CV_Assert(window_name && "NULL window name");
 
-    window = icvFindWindowByName( window_name );
-    if( window )
-        widget = (void*)window->widget;
+    CV_LOCK_MUTEX();
 
-    __END__;
+    CvWindow* window = icvFindWindowByName(window_name);
+    if(!window)
+        return NULL;
 
-    return widget;
+    return (void*)window->widget;
 }
 
 
 CV_IMPL const char* cvGetWindowName( void* window_handle )
 {
-    const char* window_name = "";
-
-    CV_FUNCNAME( "cvGetWindowName" );
-
-    __BEGIN__;
+    CV_Assert(window_handle && "NULL window handle");
 
-    CvWindow* window;
-
-    if( window_handle == 0 )
-        CV_ERROR( CV_StsNullPtr, "NULL window" );
-
-    window = icvWindowByWidget( (GtkWidget*)window_handle );
-    if( window )
-        window_name = window->name;
+    CV_LOCK_MUTEX();
 
-    __END__;
+    CvWindow* window = icvWindowByWidget( (GtkWidget*)window_handle );
+    if (window)
+        return window->name.c_str();
 
-    return window_name;
+    return ""; // FIXME: NULL?
 }
 
 static GtkFileFilter* icvMakeGtkFilter(const char* name, const char* patterns, GtkFileFilter* images)
@@ -1812,7 +1580,7 @@ static void icvShowSaveAsDialog(GtkWidget* widget, CvWindow* window)
     };
 
     for (size_t idx = 0; idx < sizeof(file_filters)/sizeof(file_filters[0]); ++idx)
-        gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), file_filters[idx]);
+        gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), file_filters[idx]); // filter ownership is transferred to dialog
     gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter_images);
 
     cv::String filename;
@@ -1993,9 +1761,11 @@ static gboolean icvOnMouse( GtkWidget *widget, GdkEvent *event, gpointer user_da
             break;
 #endif //GTK_VERSION3_4
         case GDK_SCROLL_LEFT:  cv_event = CV_EVENT_MOUSEHWHEEL;
+            /* FALLTHRU */
         case GDK_SCROLL_UP:    flags |= ~0xffff;
             break;
         case GDK_SCROLL_RIGHT: cv_event = CV_EVENT_MOUSEHWHEEL;
+            /* FALLTHRU */
         case GDK_SCROLL_DOWN:  flags |= (((int)1 << 16));
             break;
         default: ;
@@ -2072,7 +1842,7 @@ CV_IMPL int cvWaitKey( int delay )
         }
         my_last_key = last_key;
         g_mutex_unlock(last_key_mutex);
-        if(expired || hg_windows==0){
+        if(expired || g_windows.empty()){
             return -1;
         }
         return my_last_key;
@@ -2084,7 +1854,7 @@ CV_IMPL int cvWaitKey( int delay )
         if( delay > 0 )
             timer = g_timeout_add( delay, icvAlarm, &expired );
         last_key = -1;
-        while( gtk_main_iteration_do(TRUE) && last_key < 0 && !expired && hg_windows != 0 )
+        while( gtk_main_iteration_do(TRUE) && last_key < 0 && !expired && !g_windows.empty())
             ;
 
         if( delay > 0 && !expired )
diff --git a/samples/cpp/falsecolor.cpp b/samples/cpp/falsecolor.cpp
index 3e62434cf086569dd4f0af7c4b9fe7a871034e87..c0d9436ea1114f86756598463b1e52c48e9dedb5 100644
--- a/samples/cpp/falsecolor.cpp
+++ b/samples/cpp/falsecolor.cpp
@@ -15,6 +15,7 @@ String winName="False color";
 
 static void TrackColorMap(int x, void *r)
 {
+    std::cout << "selected: " << x << std::endl;
     ParamColorMar *p = (ParamColorMar*)r;
     Mat dst;
     p->iColormap= x;
@@ -23,9 +24,8 @@ static void TrackColorMap(int x, void *r)
         if (!lutRND)
         {
             RNG ra;
-            Mat *palette = new Mat(256, 1, CV_8UC3);
-            ra.fill(*palette, RNG::UNIFORM, 0, 256);
-            lutRND = Ptr<Mat>(palette);
+            lutRND = makePtr<Mat>(256, 1, CV_8UC3);
+            ra.fill(*lutRND, RNG::UNIFORM, 0, 256);
         }
         applyColorMap(p->img, dst, *lutRND.get());
     }
@@ -77,6 +77,7 @@ static void TrackColorMap(int x, void *r)
         colorMapName = "User colormap : random";
         break;
     }
+    std::cout << "> " << colorMapName << std::endl;
     putText(dst, colorMapName, Point(10, 20), cv::FONT_HERSHEY_SIMPLEX, 1, Scalar(255, 255, 255));
     imshow(winName, dst);
 }
@@ -144,7 +145,10 @@ int main(int argc, char** argv)
     setTrackbarMax("colormap", winName, cv::COLORMAP_PARULA+1);
     setTrackbarPos("colormap", winName, -1);
 
-    TrackColorMap(0,(void*)&p);
-    waitKey(0);
+    TrackColorMap((int)getTrackbarPos("colormap", winName),(void*)&p);
+    while (waitKey(0) != 27)
+    {
+        std::cout << "Press 'ESC' to exit" << std::endl;
+    }
     return 0;
 }