Reparent problem



Hi.

Versions:
gtk+ 2.4.13
gtkmm 2.4.7

I have a problem with toolbar buttons when I am doing reparent from one toplevel window to another inserting new notebook page. The simple test in the attachment.

Follow this step:
1. start application;
2. push "NEW WINDOW" twice;
3. "DOCK" one of the windows with toolbar (see it has inactive toolbuttons now) 4. "DOCK" second window, and switch page to Page 2 (see it has inactive toolbuttons too)
5. switch page again (to Page 1) (now toolbuttons all are active)

Could someone explain, please, what's going on?
Is it bug or I forget to do something special after reparent? (I guess, it is obvious that problem should be searched in GTK) When I've been using gtkmm-2.2 (based on gtk+-2.2) everything been working properly.

thanks in advance,
-andrew

#include <gtk/gtk.h>

GtkWidget* main_window = 0;
GtkWidget* notebook = 0;

void free_page( GtkWidget* f )
{
    int num;
    num = gtk_notebook_page_num( GTK_NOTEBOOK( notebook ), f );
    gtk_notebook_remove_page( GTK_NOTEBOOK( notebook ), num );
}

GtkWidget* get_new_page()
{
    GtkWidget* f;
    f = gtk_frame_new( 0 );
    gtk_widget_show( f );
    gtk_notebook_append_page( GTK_NOTEBOOK( notebook ), f, 0 );

    return f;
}

void dock_cb( GtkWidget* button,
	      GtkWidget* vb )
{
    GtkWidget* parent_widget;
    gpointer* user_data;
    GtkWidget* window;

    user_data = g_object_steal_data( G_OBJECT( vb ), "child_widget" );
    if( user_data )
    {
	parent_widget = GTK_WIDGET( user_data );
	window = GTK_WIDGET( g_object_get_data( G_OBJECT( parent_widget ),
						"window" ) );
	gtk_widget_reparent( vb, window );
	free_page( parent_widget );
	gtk_widget_show( window );
    }
    else
    {
	window = gtk_widget_get_toplevel( vb );
	parent_widget = get_new_page();
	g_object_set_data( G_OBJECT( vb ), "child_widget", parent_widget );
	g_object_set_data( G_OBJECT( parent_widget ), "window", window );
	gtk_widget_reparent( vb, parent_widget );
	gtk_widget_hide( window );
    }
}

void toolbar_cb( GtkToolButton* tb, gpointer data )
{
    puts( (gchar*)data );
}

void new_win_cb( GtkWidget* button,
		 gpointer* data )
{
    GtkWidget* window;
    GtkWidget* vb;
    GtkWidget* toolbar;
    GtkWidget* but;
    GtkToolItem* item;

    window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
    g_signal_connect( main_window, "destroy",
		      G_CALLBACK( gtk_widget_destroyed ),
		      window );
    g_signal_connect( window, "delete-event",
		      G_CALLBACK( gtk_widget_destroy ),
		      window );

    vb = gtk_vbox_new( FALSE, 5 );
    gtk_container_add( GTK_CONTAINER( window ), vb );

    toolbar = gtk_toolbar_new();
    gtk_box_pack_start( GTK_BOX( vb ), toolbar, FALSE, FALSE, 0 );

    item = gtk_tool_button_new_from_stock( GTK_STOCK_ADD );
    g_signal_connect( GTK_WIDGET( item ), "clicked",
		      G_CALLBACK( toolbar_cb ),
		      "add toolbar" );
    gtk_toolbar_insert( GTK_TOOLBAR( toolbar ),
			item,
			-1 );

    item = gtk_tool_button_new_from_stock( GTK_STOCK_REMOVE );
    g_signal_connect( GTK_WIDGET( item ), "clicked",
		      G_CALLBACK( toolbar_cb ),
		      "remove toolbar" );
    gtk_toolbar_insert( GTK_TOOLBAR( toolbar ),
			item,
			-1 );

    but = gtk_button_new_with_label( "(UN)DOCK" );
    gtk_box_pack_start( GTK_BOX( vb ), but, FALSE, FALSE, 0 );
    g_signal_connect( but, "clicked",
		      G_CALLBACK( dock_cb ),
		      vb );

    gtk_widget_set_usize( window, 200, 100 );
    gtk_widget_show_all( window );
}

void create_window()
{
    GtkWidget* vb;
    GtkWidget* but;

    main_window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
    g_signal_connect( main_window, "destroy",
		      G_CALLBACK( gtk_main_quit ),
		      NULL );
    g_signal_connect( main_window, "delete-event",
		      G_CALLBACK( gtk_false ),
		      NULL );

    vb = gtk_vbox_new( FALSE, 5 );
    gtk_container_add( GTK_CONTAINER( main_window ), vb );

    notebook = gtk_notebook_new();
    gtk_box_pack_start( GTK_BOX( vb ), notebook, TRUE, TRUE, 0 );

    but = gtk_button_new_with_label( "NEW WINDOW" );
    gtk_box_pack_start( GTK_BOX( vb ), but, FALSE, FALSE, 0 );
    g_signal_connect( but, "clicked",
		      G_CALLBACK( new_win_cb ),
		      NULL );

    gtk_widget_set_usize( main_window, 200, 200 );
    gtk_widget_show_all( main_window );
}

int main( int argc, char* argv[] )
{
    gtk_init( &argc, &argv );
    create_window();
    gtk_main();

    return 0;
}
#include <gtkmm/main.h>
#include <gtkmm/window.h>
#include <gtkmm/notebook.h>
#include <gtkmm/toolbar.h>
#include <gtkmm/action.h>
#include <gtkmm/actiongroup.h>
#include <gtkmm/frame.h>
#include <gtkmm/button.h>
#include <gtkmm/box.h>
#include <gtkmm/stock.h>

#include <iostream>
using namespace std;

class SepWin;
class MyWin;

MyWin* main_window = 0;

class MyWin : public Gtk::Window
{
public:
   MyWin()
   {
       Gtk::VBox* hb = manage( new Gtk::VBox );
       add( *hb );

       notebook = manage( new Gtk::Notebook );
       hb->add( *notebook );

       Gtk::Button* b = manage( new Gtk::Button( "NEW WINDOW" ) );
       hb->pack_start( *b, Gtk::PACK_SHRINK );
       b->signal_clicked().connect
	   ( sigc::mem_fun( *this, &MyWin::new_win_cb ) );

       resize( 200, 200 );

       show_all_children();
   }
   ~MyWin()
   {
   }

   void new_win_cb();
   Gtk::Widget* get_new_page( const Glib::ustring& name )
   {
       Gtk::Frame* f = manage( new Gtk::Frame );
       f->show();
       notebook->append_page( *f, name );
       notebook->set_current_page( notebook->page_num( *f ) );

       return f;
   }
   void free_page( Gtk::Widget* widget )
   {
       notebook->remove_page( *widget );
   }

   Gtk::Notebook* notebook;
};

class SepWin : public Gtk::Window
{
public:
   SepWin() : docked( false )
   {
       Gtk::VBox* hb = manage( new Gtk::VBox );
       add( *hb );

       toolbar = manage( new Gtk::Toolbar );
       hb->pack_start( *toolbar, Gtk::PACK_SHRINK );

       {
	   Gtk::ToolButton* tb = manage
	       ( new Gtk::ToolButton( Gtk::Stock::ADD ) );
	   toolbar->append( *tb, sigc::mem_fun( *this, &SepWin::clicked_cb ) );
       }
       {
	   Gtk::ToolButton* tb = manage
	       ( new Gtk::ToolButton( Gtk::Stock::REMOVE ) );
	   toolbar->append( *tb, sigc::mem_fun( *this, &SepWin::clicked_cb ) );
       }

       dock_button = manage( new Gtk::Button( "(UN)DOCK" ) );
       hb->pack_start( *dock_button, Gtk::PACK_SHRINK );
       dock_button->signal_clicked().connect
	   ( sigc::mem_fun( *this, &SepWin::dock_cb ) );

       child_widget = hb;

       resize( 200, 100 );

       show_all_children();
   }
   ~SepWin()
   {
   }

   void clicked_cb()
   {
       cout << "tool clicked" << endl;
   }
   void dock_cb()
   {
       if( docked )
       {
	   child_widget->reparent( *this );
	   main_window->free_page( parent_widget );
	   docked = false;
	   show();
       }
       else
       {
	   docked = true;
	   parent_widget = main_window->get_new_page( get_title() );
	   child_widget->reparent( *parent_widget );
	   hide();
       }
   }

   Gtk::Toolbar* toolbar;
   Glib::RefPtr<Gtk::ActionGroup> action_group;
   Gtk::Button* dock_button;
   Gtk::Widget* child_widget;
   Gtk::Widget* parent_widget;
   bool docked;
};

void MyWin::new_win_cb()
{
    ( new SepWin() )->show();
}

int main( int argc, char* argv[] )
{
    Gtk::Main kit( &argc, &argv );

    MyWin win;
    main_window = &win;
    kit.run( win );

    return 0;
}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]