Commit 00eef465 authored by Zbigniew Chyla's avatar Zbigniew Chyla Committed by Alexander Larsson

Avoid heavy operations inside "motion_notify_event" handler: don't call

2006-02-26  Zbigniew Chyla  <mail@zbigniew.chyla.pl>

	Avoid heavy operations inside "motion_notify_event" handler: don't
	call gtk_tree_model_row_changed (which causes updating the whole
	view), don't create new mouse cursor, change cursor only when
	necessary.
	As a bonus we avoid leaking hand cursor in nautilus and X server.

	* src/file-manager/fm-list-view.c:
	(hand_cursor): new global variable for storing hand cursor used in
	single click mode
	(motion_notify_callback): don't call gtk_tree_model_row_changed on
	the model when changing rows, it's very slow and unnecessary - GTK+
	automatically invalidates parts of the view occupied by old and new
	row; don't leak the hand cursor (GdkCursor), change mouse cursor
	only when necessary (from GDK_HAND2 to default and the other way
	round)
	(leave_notify_callback): don't call gtk_tree_model_row_changed on
	the current row in the model, GTK+ automatically redraws the current
	row
	(enter_notify_callback): in case single click mode is used, update
	details->hover_path and set hand cursor if necessary
	(create_and_set_up_tree_view): connect to enter_notify_event signal
	in addition to leave_notify_event.
	(fm_list_view_click_policy_changed): unref global hand_cursor and
	set it to NULL when changing to double click mode, create new cursor
	and assign it to hand_cursor when changing to single click one.
	(fm_list_view_finalize): free details->hover_path if necessary
	(fm_list_view_init): explicitly set details->hover_path to NULL
parent 3ca224bd
2006-02-26 Zbigniew Chyla <mail@zbigniew.chyla.pl>
Avoid heavy operations inside "motion_notify_event" handler: don't
call gtk_tree_model_row_changed (which causes updating the whole
view), don't create new mouse cursor, change cursor only when
necessary.
As a bonus we avoid leaking hand cursor in nautilus and X server.
* src/file-manager/fm-list-view.c:
(hand_cursor): new global variable for storing hand cursor used in
single click mode
(motion_notify_callback): don't call gtk_tree_model_row_changed on
the model when changing rows, it's very slow and unnecessary - GTK+
automatically invalidates parts of the view occupied by old and new
row; don't leak the hand cursor (GdkCursor), change mouse cursor
only when necessary (from GDK_HAND2 to default and the other way
round)
(leave_notify_callback): don't call gtk_tree_model_row_changed on
the current row in the model, GTK+ automatically redraws the current
row
(enter_notify_callback): in case single click mode is used, update
details->hover_path and set hand cursor if necessary
(create_and_set_up_tree_view): connect to enter_notify_event signal
in addition to leave_notify_event.
(fm_list_view_click_policy_changed): unref global hand_cursor and
set it to NULL when changing to double click mode, create new cursor
and assign it to hand_cursor when changing to single click one.
(fm_list_view_finalize): free details->hover_path if necessary
(fm_list_view_init): explicitly set details->hover_path to NULL
2006-02-27 Alexander Larsson <alexl@redhat.com>
* src/nautilus-window-manage-views.c:
......
......@@ -141,6 +141,7 @@ static gboolean default_sort_reversed_auto_value;
static NautilusZoomLevel default_zoom_level_auto_value;
static GList * default_visible_columns_auto_value;
static GList * default_column_order_auto_value;
static GdkCursor * hand_cursor = NULL;
static GList *fm_list_view_get_selection (FMDirectoryView *view);
static GList *fm_list_view_get_selection_for_file_transfer (FMDirectoryView *view);
......@@ -457,9 +458,6 @@ motion_notify_callback (GtkWidget *widget,
{
FMListView *view;
GdkDragContext *context;
GdkCursor *cursor;
GtkTreePath *last_hover_path;
GtkTreeIter iter;
view = FM_LIST_VIEW (callback_data);
......@@ -468,42 +466,25 @@ motion_notify_callback (GtkWidget *widget,
}
if (click_policy_auto_value == NAUTILUS_CLICK_POLICY_SINGLE) {
last_hover_path = view->details->hover_path;
GtkTreePath *old_hover_path;
old_hover_path = view->details->hover_path;
gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget),
event->x, event->y,
&view->details->hover_path,
NULL, NULL, NULL);
if (view->details->hover_path != NULL) {
cursor = gdk_cursor_new (GDK_HAND2);
} else {
cursor = NULL;
}
gdk_window_set_cursor (widget->window, cursor);
/* only redraw if the hover row has changed */
if (!(last_hover_path == NULL && view->details->hover_path == NULL) &&
(!(last_hover_path != NULL && view->details->hover_path != NULL) ||
gtk_tree_path_compare (last_hover_path, view->details->hover_path))) {
if (last_hover_path) {
if (gtk_tree_model_get_iter (GTK_TREE_MODEL (view->details->model),
&iter, last_hover_path)) {
gtk_tree_model_row_changed (GTK_TREE_MODEL (view->details->model),
last_hover_path, &iter);
}
}
if (view->details->hover_path) {
gtk_tree_model_get_iter (GTK_TREE_MODEL (view->details->model),
&iter, view->details->hover_path);
gtk_tree_model_row_changed (GTK_TREE_MODEL (view->details->model),
view->details->hover_path, &iter);
if ((old_hover_path != NULL) != (view->details->hover_path != NULL)) {
if (view->details->hover_path != NULL) {
gdk_window_set_cursor (widget->window, hand_cursor);
} else {
gdk_window_set_cursor (widget->window, NULL);
}
}
gtk_tree_path_free (last_hover_path);
if (old_hover_path != NULL) {
gtk_tree_path_free (old_hover_path);
}
}
if (view->details->drag_button != 0) {
......@@ -531,22 +512,40 @@ leave_notify_callback (GtkWidget *widget,
gpointer callback_data)
{
FMListView *view;
GtkTreeIter iter;
view = FM_LIST_VIEW (callback_data);
if (click_policy_auto_value == NAUTILUS_CLICK_POLICY_SINGLE &&
view->details->hover_path != NULL) {
if (gtk_tree_model_get_iter (GTK_TREE_MODEL (view->details->model),
&iter, view->details->hover_path)) {
gtk_tree_model_row_changed (GTK_TREE_MODEL (view->details->model),
view->details->hover_path, &iter);
}
gtk_tree_path_free (view->details->hover_path);
view->details->hover_path = NULL;
}
return TRUE;
return FALSE;
}
static gboolean
enter_notify_callback (GtkWidget *widget,
GdkEventCrossing *event,
gpointer callback_data)
{
FMListView *view;
view = FM_LIST_VIEW (callback_data);
if (click_policy_auto_value == NAUTILUS_CLICK_POLICY_SINGLE) {
if (view->details->hover_path != NULL) {
gtk_tree_path_free (view->details->hover_path);
}
gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget),
event->x, event->y,
&view->details->hover_path,
NULL, NULL, NULL);
if (view->details->hover_path != NULL) {
gdk_window_set_cursor (widget->window, hand_cursor);
}
}
return FALSE;
......@@ -1234,6 +1233,8 @@ create_and_set_up_tree_view (FMListView *view)
G_CALLBACK (drag_data_get_callback), view, 0);
g_signal_connect_object (view->details->tree_view, "motion_notify_event",
G_CALLBACK (motion_notify_callback), view, 0);
g_signal_connect_object (view->details->tree_view, "enter_notify_event",
G_CALLBACK (enter_notify_callback), view, 0);
g_signal_connect_object (view->details->tree_view, "leave_notify_event",
G_CALLBACK (leave_notify_callback), view, 0);
g_signal_connect_object (view->details->tree_view, "button_press_event",
......@@ -2288,10 +2289,10 @@ fm_list_view_click_policy_changed (FMDirectoryView *directory_view)
GtkTreeIter iter;
GtkTreeView *tree;
view = FM_LIST_VIEW (directory_view);
/* ensure that we unset the hand cursor and refresh underlined rows */
if (click_policy_auto_value == NAUTILUS_CLICK_POLICY_DOUBLE) {
view = FM_LIST_VIEW (directory_view);
if (view->details->hover_path != NULL) {
if (gtk_tree_model_get_iter (GTK_TREE_MODEL (view->details->model),
&iter, view->details->hover_path)) {
......@@ -2313,7 +2314,15 @@ fm_list_view_click_policy_changed (FMDirectoryView *directory_view)
gdk_display_flush (display);
}
}
if (hand_cursor != NULL) {
gdk_cursor_unref (hand_cursor);
hand_cursor = NULL;
}
} else if (click_policy_auto_value == NAUTILUS_CLICK_POLICY_SINGLE) {
if (hand_cursor == NULL) {
hand_cursor = gdk_cursor_new(GDK_HAND2);
}
}
}
......@@ -2457,6 +2466,10 @@ fm_list_view_finalize (GObject *object)
g_list_free (list_view->details->cells);
g_hash_table_destroy (list_view->details->columns);
if (list_view->details->hover_path != NULL) {
gtk_tree_path_free (list_view->details->hover_path);
}
g_free (list_view->details);
G_OBJECT_CLASS (parent_class)->finalize (object);
......@@ -2663,6 +2676,8 @@ fm_list_view_init (FMListView *list_view)
/* ensure that the zoom level is always set in begin_loading */
list_view->details->zoom_level = NAUTILUS_ZOOM_LEVEL_SMALLEST - 1;
list_view->details->hover_path = NULL;
}
static NautilusView *
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment