[nautilus-actions] Fix main window destroy process
- From: Pierre Wieser <pwieser src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nautilus-actions] Fix main window destroy process
- Date: Wed, 1 Feb 2012 19:09:11 +0000 (UTC)
commit 0d5e65151d9c18536e8033f4ad14bf81dc4853a7
Author: Pierre Wieser <pwieser trychlos org>
Date: Mon Jan 30 05:46:13 2012 +0100
Fix main window destroy process
ChangeLog | 19 +++++
src/nact/base-window.c | 24 ++++++
src/nact/base-window.h | 1 +
src/nact/nact-main-window.c | 9 +-
src/nact/nact-match-list.c | 12 ++-
src/nact/nact-tree-model.c | 5 +
src/nact/nact-tree-view.c | 175 +++++++++++++++++++++----------------------
src/nact/nact-tree-view.h | 8 ++
8 files changed, 157 insertions(+), 96 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 0b24882..edf48ef 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2012-01-30 Pierre Wieser <pwieser trychlos org>
+
+ * src/nact/base-window.c:
+ * src/nact/base-window.h: Define a new BASE_PROP_DESTROY_ON_DISPOSE property.
+ When set, the underlying Gtk toplevel is destroyed when the BaseWindow is
+ unreffed.
+
+ * src/nact/nact-main-window.c (nact_main_window_new): Set the
+ DestroyOnDispose property.
+
+ * src/nact/nact-match-list.c (on_instance_finalized): Do not try to clear
+ the NactTreeModel after it has been finalized.
+
+ * src/nact/nact-tree-model.c (nact_tree_model_new): Improve comment.
+
+ * src/nact/nact-tree-view.c:
+ * src/nact/nact-tree-view.h(initialize_gtk): no more mimic a signal
+ handler.
+
2012-01-29 Pierre Wieser <pwieser trychlos org>
* src/nact/nact-tree-model.c (nact_tree_model_new): Unref filter model.
diff --git a/src/nact/base-window.c b/src/nact/base-window.c
index 34ed57e..9dafbce 100644
--- a/src/nact/base-window.c
+++ b/src/nact/base-window.c
@@ -63,6 +63,7 @@ struct _BaseWindowPrivate {
gboolean has_own_builder;
gchar *toplevel_name;
gchar *wsp_name;
+ gboolean destroy_on_dispose;
/* internals
*/
@@ -83,6 +84,7 @@ enum {
BASE_PROP_HAS_OWN_BUILDER_ID,
BASE_PROP_TOPLEVEL_NAME_ID,
BASE_PROP_WSP_NAME_ID,
+ BASE_PROP_DESTROY_ON_DISPOSE_ID,
BASE_PROP_N_PROPERTIES
};
@@ -243,6 +245,14 @@ class_init( BaseWindowClass *klass )
"",
G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
+ g_object_class_install_property( object_class, BASE_PROP_DESTROY_ON_DISPOSE_ID,
+ g_param_spec_boolean(
+ BASE_PROP_DESTROY_ON_DISPOSE,
+ _( "Destroy the Gtk toplevel" ),
+ _( "Whether the embedded Gtk Toplevel should be destroyed at dispose time" ),
+ FALSE,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
+
klass->private = g_new0( BaseWindowClassPrivate, 1 );
klass->private->builder = base_builder_new();
@@ -393,6 +403,10 @@ instance_get_property( GObject *object, guint property_id, GValue *value, GParam
g_value_set_string( value, self->private->wsp_name );
break;
+ case BASE_PROP_DESTROY_ON_DISPOSE_ID:
+ g_value_set_boolean( value, self->private->destroy_on_dispose );
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID( object, property_id, spec );
break;
@@ -438,6 +452,10 @@ instance_set_property( GObject *object, guint property_id, const GValue *value,
self->private->wsp_name = g_value_dup_string( value );
break;
+ case BASE_PROP_DESTROY_ON_DISPOSE_ID:
+ self->private->destroy_on_dispose = g_value_get_boolean( value );
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID( object, property_id, spec );
break;
@@ -520,6 +538,12 @@ instance_dispose( GObject *window )
}
g_list_free( priv->signals );
+ /* at least the main window should have this property set
+ */
+ if( priv->destroy_on_dispose ){
+ gtk_widget_destroy( GTK_WIDGET( priv->gtk_toplevel ));
+ }
+
#if 0
if( is_main_window( BASE_WINDOW( window ))){
g_debug( "%s: quitting main window", thisfn );
diff --git a/src/nact/base-window.h b/src/nact/base-window.h
index ff472f8..5c94805 100644
--- a/src/nact/base-window.h
+++ b/src/nact/base-window.h
@@ -189,6 +189,7 @@ typedef struct {
#define BASE_PROP_HAS_OWN_BUILDER "base-prop-window-has-own-builder"
#define BASE_PROP_TOPLEVEL_NAME "base-prop-window-toplevel-name"
#define BASE_PROP_WSP_NAME "base-prop-window-wsp-name"
+#define BASE_PROP_DESTROY_ON_DISPOSE "base-prop-window-destroy-on-dispose"
/**
* Signals defined by the BaseWindow class.
diff --git a/src/nact/nact-main-window.c b/src/nact/nact-main-window.c
index cd82299..b2f90f4 100644
--- a/src/nact/nact-main-window.c
+++ b/src/nact/nact-main-window.c
@@ -787,10 +787,11 @@ nact_main_window_new( const NactApplication *application )
g_return_val_if_fail( NACT_IS_APPLICATION( application ), NULL );
window = g_object_new( NACT_TYPE_MAIN_WINDOW,
- BASE_PROP_APPLICATION, application,
- BASE_PROP_XMLUI_FILENAME, st_xmlui_filename,
- BASE_PROP_TOPLEVEL_NAME, st_toplevel_name,
- BASE_PROP_WSP_NAME, st_wsp_name,
+ BASE_PROP_APPLICATION, application,
+ BASE_PROP_XMLUI_FILENAME, st_xmlui_filename,
+ BASE_PROP_TOPLEVEL_NAME, st_toplevel_name,
+ BASE_PROP_WSP_NAME, st_wsp_name,
+ BASE_PROP_DESTROY_ON_DISPOSE, TRUE,
NULL );
if( !base_window_init( BASE_WINDOW( window ))){
diff --git a/src/nact/nact-match-list.c b/src/nact/nact-match-list.c
index 31d2dbf..ca33f8e 100644
--- a/src/nact/nact-match-list.c
+++ b/src/nact/nact-match-list.c
@@ -1067,8 +1067,6 @@ static void
on_instance_finalized( MatchListData *data, BaseWindow *window )
{
static const gchar *thisfn = "nact_match_list_on_instance_finalized";
- GtkTreeModel *model;
- GtkTreeSelection *selection;
g_return_if_fail( data != NULL );
@@ -1079,10 +1077,16 @@ on_instance_finalized( MatchListData *data, BaseWindow *window )
g_object_set_data( G_OBJECT( window ), data->tab_name, NULL );
- model = gtk_tree_view_get_model( data->listview );
- selection = gtk_tree_view_get_selection( data->listview );
+ /* This function is called when the NactMainWindow is about to be finalized.
+ * At this time, the NactTreeModel has already been finalized.
+ * It is so too late to try to clear it...
+ */
+#if 0
+ GtkTreeModel *model = gtk_tree_view_get_model( data->listview );
+ GtkTreeSelection *selection = gtk_tree_view_get_selection( data->listview );
gtk_tree_selection_unselect_all( selection );
gtk_list_store_clear( GTK_LIST_STORE( model ));
+#endif
g_free( data->tab_name );
g_free( data->item_header );
diff --git a/src/nact/nact-tree-model.c b/src/nact/nact-tree-model.c
index 2749fc1..20ae21a 100644
--- a/src/nact/nact-tree-model.c
+++ b/src/nact/nact-tree-model.c
@@ -300,6 +300,11 @@ instance_finalize( GObject *object )
*
* The returned reference is owned by the #GtkTreeView, which will automatically
* take care of g_object_unref() its tree model when destroying its widget.
+ *
+ * Called from NactTreeView::initialize_gtk() method
+ * [..]
+ * which happens to be eventually called from NactMainWindow::on_initialize_gtk()
+ * signal handler.
*/
NactTreeModel *
nact_tree_model_new( BaseWindow *window, GtkTreeView *treeview, NactTreeMode mode )
diff --git a/src/nact/nact-tree-view.c b/src/nact/nact-tree-view.c
index 488eff7..058203d 100644
--- a/src/nact/nact-tree-view.c
+++ b/src/nact/nact-tree-view.c
@@ -65,25 +65,8 @@ struct _NactTreeViewPrivate {
gboolean notify_allowed;
/* runtime data
- *
- * Rationale:
- *
- * In Gtk2, we used to nact_tree_view_new() from
- * nact_main_window:on_instance_constructed().
- * This let us connect to on-base-initialize-gtk signal before it was
- * emitted, and so initialize the treeview on the handler.
- *
- * With Gtk3, we have to wait until the Gtk hierarchy of NactMainWindow
- * be actually built in order to be able to access to the embedded
- * GtkTreeView. As a consequence, nact_tree_view_new() has to be delayed
- * until nact_main_window_on_initialize_gtk().
- *
- * And so we no more can rely on the on-base-initialize-gtk signal to
- * initialize the view. So force a call to the handler from
- * on_base_initialize_view() handler.
*/
GtkTreeView *tree_view;
- gboolean gtk_initialized;
};
/* instance properties
@@ -141,7 +124,7 @@ static void instance_constructed( GObject *object );
static void instance_dispose( GObject *application );
static void instance_finalize( GObject *application );
-static void on_base_initialize_gtk( BaseWindow *window, GtkWindow *toplevel, gpointer user_data );
+static void initialize_gtk( NactTreeView *view );
static void on_base_initialize_view( BaseWindow *window, gpointer user_data );
static void on_base_all_widgets_showed( BaseWindow *window, gpointer user_data );
static gboolean on_button_press_event( GtkWidget *widget, GdkEventButton *event, BaseWindow *window );
@@ -487,7 +470,6 @@ instance_init( GTypeInstance *instance, gpointer klass )
self->private = g_new0( NactTreeViewPrivate, 1 );
self->private->dispose_has_run = FALSE;
- self->private->gtk_initialized = FALSE;
}
static void
@@ -599,6 +581,8 @@ instance_constructed( GObject *object )
G_CALLBACK( on_base_all_widgets_showed ));
g_object_set_data( G_OBJECT( priv->window ), WINDOW_DATA_TREE_VIEW, object );
+
+ initialize_gtk( NACT_TREE_VIEW( object ));
}
}
@@ -624,9 +608,6 @@ instance_dispose( GObject *object )
gtk_tree_store_clear( ts_model );
g_debug( "%s: tree store cleared", thisfn );
- g_debug( "%s: nact_tree_model_ref_count=%d", thisfn, G_OBJECT( model )->ref_count );
- g_object_unref( model );
-
if( self->private->mode == TREE_MODE_EDITION ){
nact_tree_ieditable_terminate( NACT_TREE_IEDITABLE( self ));
}
@@ -670,6 +651,9 @@ instance_finalize( GObject *instance )
* Returns: a newly allocated NactTreeView object, which will be owned
* by the caller. It is useless to unref it as it will automatically
* auto-destroys itself at @window finalization.
+ *
+ * This function is called from NactMainWindow::on_base_initialize_gtk()
+ * signal handler, thus only once during the application life.
*/
NactTreeView *
nact_tree_view_new( BaseWindow *window, GtkContainer *parent, const gchar *treeview_name, NactTreeMode mode )
@@ -692,11 +676,15 @@ nact_tree_view_new( BaseWindow *window, GtkContainer *parent, const gchar *treev
return( view );
}
+/*
+ * called from instance_constructed()
+ * from nact_tree_view_new()
+ * from NactMainWindow::on_base_initialize_gtk() signal handler
+ */
static void
-on_base_initialize_gtk( BaseWindow *window, GtkWindow *toplevel, gpointer user_data )
+initialize_gtk( NactTreeView *items_view )
{
- static const gchar *thisfn = "nact_tree_view_on_base_initialize_gtk";
- NactTreeView *items_view;
+ static const gchar *thisfn = "nact_tree_view_initialize_gtk";
GtkTreeView *treeview;
GtkWidget *label;
GtkTreeViewColumn *column;
@@ -704,56 +692,48 @@ on_base_initialize_gtk( BaseWindow *window, GtkWindow *toplevel, gpointer user_d
GtkTreeSelection *selection;
GList *renderers;
- items_view = NACT_TREE_VIEW( g_object_get_data( G_OBJECT( window ), WINDOW_DATA_TREE_VIEW ));
-
- if( !items_view->private->dispose_has_run ){
- g_debug( "%s: window=%p (%s), toplevel=%p (%s), user_data=%p",
- thisfn, ( void * ) window, G_OBJECT_TYPE_NAME( window ),
- ( void * ) toplevel, G_OBJECT_TYPE_NAME( toplevel ), ( void * ) user_data );
+ g_debug( "%s: items_view=%p", thisfn, ( void * ) items_view );
- treeview = GTK_TREE_VIEW( get_tree_view( items_view ));
- nact_tree_model_new( window, treeview, items_view->private->mode );
+ treeview = GTK_TREE_VIEW( get_tree_view( items_view ));
+ nact_tree_model_new( items_view->private->window, treeview, items_view->private->mode );
- /* associates the ItemsView to the label */
- label = na_gtk_utils_find_widget_by_name( items_view->private->parent, "ActionsListLabel" );
- gtk_label_set_mnemonic_widget( GTK_LABEL( label ), GTK_WIDGET( treeview ));
+ /* associates the ItemsView to the label */
+ label = na_gtk_utils_find_widget_by_name( items_view->private->parent, "ActionsListLabel" );
+ gtk_label_set_mnemonic_widget( GTK_LABEL( label ), GTK_WIDGET( treeview ));
- /* create visible columns on the tree view
- */
- column = gtk_tree_view_column_new_with_attributes(
- "icon",
- gtk_cell_renderer_pixbuf_new(),
- "pixbuf", TREE_COLUMN_ICON,
- NULL );
- gtk_tree_view_append_column( treeview, column );
-
- renderer = gtk_cell_renderer_text_new();
- column = gtk_tree_view_column_new_with_attributes(
- "label",
- renderer,
- "text", TREE_COLUMN_LABEL,
- NULL );
- gtk_tree_view_column_set_sort_column_id( column, TREE_COLUMN_LABEL );
- gtk_tree_view_append_column( treeview, column );
-
- /* allow multiple selection
- */
- selection = gtk_tree_view_get_selection( treeview );
- gtk_tree_selection_set_mode( selection, GTK_SELECTION_MULTIPLE );
+ /* create visible columns on the tree view
+ */
+ column = gtk_tree_view_column_new_with_attributes(
+ "icon",
+ gtk_cell_renderer_pixbuf_new(),
+ "pixbuf", TREE_COLUMN_ICON,
+ NULL );
+ gtk_tree_view_append_column( treeview, column );
- /* misc properties
- */
- gtk_tree_view_set_enable_tree_lines( treeview, TRUE );
+ renderer = gtk_cell_renderer_text_new();
+ column = gtk_tree_view_column_new_with_attributes(
+ "label",
+ renderer,
+ "text", TREE_COLUMN_LABEL,
+ NULL );
+ gtk_tree_view_column_set_sort_column_id( column, TREE_COLUMN_LABEL );
+ gtk_tree_view_append_column( treeview, column );
- if( items_view->private->mode == TREE_MODE_EDITION ){
- column = gtk_tree_view_get_column( treeview, TREE_COLUMN_LABEL );
- renderers = gtk_cell_layout_get_cells( GTK_CELL_LAYOUT( column ));
- renderer = GTK_CELL_RENDERER( renderers->data );
- gtk_tree_view_column_set_cell_data_func(
- column, renderer, ( GtkTreeCellDataFunc ) display_label, items_view, NULL );
- }
+ /* allow multiple selection
+ */
+ selection = gtk_tree_view_get_selection( treeview );
+ gtk_tree_selection_set_mode( selection, GTK_SELECTION_MULTIPLE );
- items_view->private->gtk_initialized = TRUE;
+ /* misc properties
+ */
+ gtk_tree_view_set_enable_tree_lines( treeview, TRUE );
+
+ if( items_view->private->mode == TREE_MODE_EDITION ){
+ column = gtk_tree_view_get_column( treeview, TREE_COLUMN_LABEL );
+ renderers = gtk_cell_layout_get_cells( GTK_CELL_LAYOUT( column ));
+ renderer = GTK_CELL_RENDERER( renderers->data );
+ gtk_tree_view_column_set_cell_data_func(
+ column, renderer, ( GtkTreeCellDataFunc ) display_label, items_view, NULL );
}
}
@@ -767,26 +747,31 @@ on_base_initialize_view( BaseWindow *window, gpointer user_data )
items_view = NACT_TREE_VIEW( g_object_get_data( G_OBJECT( window ), WINDOW_DATA_TREE_VIEW ));
- if( !items_view->private->gtk_initialized ){
- on_base_initialize_gtk( window, base_window_get_gtk_toplevel( window ), NULL );
- }
-
if( !items_view->private->dispose_has_run ){
+
g_debug( "%s: window=%p (%s), user_data=%p",
- thisfn, ( void * ) window, G_OBJECT_TYPE_NAME( window ), ( void * ) user_data );
+ thisfn,
+ ( void * ) window, G_OBJECT_TYPE_NAME( window ),
+ ( void * ) user_data );
treeview = GTK_TREE_VIEW( get_tree_view( items_view ));
items_view->private->tree_view = treeview;
/* monitors the selection */
selection = gtk_tree_view_get_selection( treeview );
- base_window_signal_connect( window,
- G_OBJECT( selection ), "changed", G_CALLBACK( on_selection_changed ));
+ base_window_signal_connect(
+ window,
+ G_OBJECT( selection ),
+ "changed",
+ G_CALLBACK( on_selection_changed ));
/* delay all other signal connections until the widget be realized
*/
- base_window_signal_connect( window,
- G_OBJECT( treeview ), "realize", G_CALLBACK( on_tree_view_realized ));
+ base_window_signal_connect(
+ window,
+ G_OBJECT( treeview ),
+ "realize",
+ G_CALLBACK( on_tree_view_realized ));
if( items_view->private->mode == TREE_MODE_EDITION ){
nact_tree_ieditable_initialize( NACT_TREE_IEDITABLE( items_view ), treeview, window );
@@ -918,19 +903,31 @@ on_tree_view_realized( GtkWidget *treeview, BaseWindow *window )
g_debug( "nact_tree_view_on_tree_view_realized" );
/* expand/collapse with the keyboard */
- base_window_signal_connect( window,
- G_OBJECT( treeview ), "key-press-event", G_CALLBACK( on_key_pressed_event ));
+ base_window_signal_connect(
+ window,
+ G_OBJECT( treeview ),
+ "key-press-event",
+ G_CALLBACK( on_key_pressed_event ));
/* monitors whether the focus is on the view */
- base_window_signal_connect( window,
- G_OBJECT( treeview ), "focus-in-event", G_CALLBACK( on_focus_in ));
-
- base_window_signal_connect( window,
- G_OBJECT( treeview ), "focus-out-event", G_CALLBACK( on_focus_out ));
+ base_window_signal_connect(
+ window,
+ G_OBJECT( treeview ),
+ "focus-in-event",
+ G_CALLBACK( on_focus_in ));
+
+ base_window_signal_connect(
+ window,
+ G_OBJECT( treeview ),
+ "focus-out-event",
+ G_CALLBACK( on_focus_out ));
/* monitors mouse events */
- base_window_signal_connect( window,
- G_OBJECT( treeview ), "button-press-event", G_CALLBACK( on_button_press_event ));
+ base_window_signal_connect(
+ window,
+ G_OBJECT( treeview ),
+ "button-press-event",
+ G_CALLBACK( on_button_press_event ));
/* force the treeview to have the focus at start
* and select the first row if it exists
@@ -1305,7 +1302,9 @@ get_selected_items( NactTreeView *view )
static GtkWidget *
get_tree_view( NactTreeView *items_view )
{
- return( na_gtk_utils_find_widget_by_name( items_view->private->parent, items_view->private->widget_name ));
+ return( na_gtk_utils_find_widget_by_name(
+ items_view->private->parent,
+ items_view->private->widget_name ));
}
static void
diff --git a/src/nact/nact-tree-view.h b/src/nact/nact-tree-view.h
index 88a9955..e4b4770 100644
--- a/src/nact/nact-tree-view.h
+++ b/src/nact/nact-tree-view.h
@@ -38,6 +38,14 @@
* @include: nact-tree-view.h
*
* This is a convenience class to manage a read-only items tree view.
+ *
+ * The NactTreeView encapsulates the GtkTreeView which displays the items
+ * list on the left of the main pane.
+ *
+ * It is instanciated from NactMainWindow::on_initialize_gtk().
+ *
+ * A pointer to this NactTreeView is attached to the NactMainWindow at
+ * construction time.
*/
#include <api/na-object-item.h>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]