[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]
TreeView flickers inside ScrolledWindow
- From: Drew Parsons <dparsons emerall com>
- To: gtk-app-devel-list gnome org
- Subject: TreeView flickers inside ScrolledWindow
- Date: Thu, 2 Jan 2003 01:24:40 +1000
A few months ago I described a problem with my GtkTreeView-based clock
(gworldclock, http://www.debian.org/packages/unstable/gworldclock), where it
flickers as the clock is updated each second. A suggestion was made to
freeze it with something like gtk_widget_freeze_child_notify(..) while it is
being updated.
That suggestion did not seem to help, I could still see the flickering.
However, I think I have now isolated the flickering, it seems to come from
the GtkScrolledWindow that I placed my GtkTreeView inside (this is the only
way to get scrollbars controlling the view of a GtkTreeView, right?). I've
got the GtkScrolledWindow set to GTK_POLICY_AUTOMATIC on the horizontal
scrollbar, so it only appears if the window is too small to fit the
displayed contents. When the window is large enough (horizontally) so that
no scrollbar is needed, then the flickering appears - a blue flash along the
bottom of the window, where the horizontal scrollbar would have been. If I
resize the window, making it smaller, then scrollbar appears and there is no
flickering.
If I set the horizontal scrollbar policy to GTK_POLICY_NEVER, then no
scrollbar appears, but no flickering occurs either. The drawback is the
window can not be made smaller.
Likewise setting the policy to GTK_POLICY_ALWAYS means the scrollbar is
always present, and there is no flickering. But I think this looks ugly
when the window is wide enough to not need the scrollbar.
I've attached a pared down version of the clock, showing the essential
features demonstrating the problem. The window is manually set too large in
line 175 and the horizontal scrollbar policy is set to GTK_POLICY_AUTOMATIC
in line 121 so that the flickering can be easily seen. You'll see the
flickering stop when the scrollbar appears if you make the window size
smaller with your mouse.
If you comment out l.121 in favour of l.123 or l.125, you can see the other
policies at work.
The test program also shows what I tried to do with
gtk_widget_freeze_child_notify, around line 40.
The test program compiles with
gcc `pkg-config --cflags --libs "gtk+-2.0"` test.c -o test
Press Ctrl-C on the command line to quit.
Am I doing something wrong, or does this flickering mean there's a bug in
the interaction between GtkScrolledWindow and GtkTreeView?
I'm using GTK+ 2.0.9, haven't yet upgraded to 2.2.
Drew
--
PGP public key available at http://people.debian.org/~dparsons/drewskey.txt
Fingerprint: A110 EAE1 D7D2 8076 5FE0 EC0A B6CE 7041 6412 4E4A
#include <errno.h>
#include <unistd.h> /* getopt */
#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
enum
{
TZ_NAME,
TZ_DESCRIPTION,
TZ_TIMEDATE,
LIST_COLUMNS
};
/* id of second timer.
Set to -1 during synchronisation.
*/
gint timer;
#define DEFAULT_ZONES_TO_VIEW 4
gint SetTime(gpointer clocklist);
gboolean SetToGivenTime( GtkTreeModel *clocklist,
GtkTreePath *path,
GtkTreeIter *iter,
gpointer timeToSet);
void resizeWindow( GtkWidget *window, GtkTreeView *clocklist );
gint SetTime(gpointer clocklist)
{
time_t currenttime;
GdkWindow *window;
time(¤ttime);
gtk_widget_freeze_child_notify( GTK_WIDGET(clocklist) );
gtk_tree_model_foreach( gtk_tree_view_get_model(GTK_TREE_VIEW(clocklist)),
(GtkTreeModelForeachFunc) SetToGivenTime,
(gpointer) currenttime );
gtk_widget_thaw_child_notify( GTK_WIDGET(clocklist) );
return 1;
}
#define TIME_DISPLAY_SIZE 50
gboolean SetToGivenTime (GtkTreeModel *clocklistModel,
GtkTreePath *path,
GtkTreeIter *iter,
gpointer timeToSet)
{
gchar *timezone="Local", *TZdefault;
gint N,i;
char rawTimeDisplay[TIME_DISPLAY_SIZE];
gchar *timeDisplay;
/* in the future, can replace "%c" with a user-configured display format */
gchar *displayFormat = "%c"; /* default display for locale */
strftime (rawTimeDisplay, TIME_DISPLAY_SIZE,
displayFormat,
localtime( (time_t *) &timeToSet )
);
timeDisplay = g_locale_to_utf8 ( rawTimeDisplay,
-1, NULL, NULL, NULL );
gtk_list_store_set ( GTK_LIST_STORE(clocklistModel), iter,
TZ_TIMEDATE, timeDisplay,
-1);
g_free( timeDisplay );
return FALSE;
}
gint start_timer( gpointer clocklist )
{
return gtk_timeout_add( 1000, SetTime, clocklist);
}
int main( int argc, char *argv[] )
{
GtkWidget *window, *scrolled_window;
GtkWidget *main_vbox;
GtkWidget *menubar;
GtkListStore *clocklistModel;
GtkWidget *clocklist;
gchar *titles[2] = { "Time Zone", "Time&Date" };
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
GtkTreeSelection *select;
GdkRectangle cell;
gint cellHeight;
gint xoff, yoff, h, w;
GSignalQuery query;
GtkTreeIter iter;
gint i;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_signal_connect (GTK_OBJECT (window), "destroy",
GTK_SIGNAL_FUNC (gtk_main_quit),
"WM destroy");
gtk_window_set_title (GTK_WINDOW(window), "gworldclock");
main_vbox = gtk_vbox_new (FALSE, 5);
gtk_container_border_width (GTK_CONTAINER (main_vbox), 1);
gtk_container_add (GTK_CONTAINER (window), main_vbox);
gtk_widget_show (main_vbox);
/* Create a scrolled window to pack the list widget into */
scrolled_window = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
/* GTK_POLICY_AUTOMATIC horizontally leads to ugly flickering */
GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
/* GTK_POLICY_NEVER prevents resizing smaller (but has no flickering) */
// GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
/* GTK_POLICY_ALWAYS allows resizing without flickering, but looks kinda ugly */
// GTK_POLICY_ALWAYS, GTK_POLICY_ALWAYS);
gtk_box_pack_end(GTK_BOX(main_vbox), scrolled_window, TRUE, TRUE, 0);
gtk_widget_show (scrolled_window);
clocklistModel = gtk_list_store_new (LIST_COLUMNS,
G_TYPE_STRING, /* TZ name */
G_TYPE_STRING, /* TZ description */
G_TYPE_STRING /* time/date */
);
clocklist = gtk_tree_view_new_with_model (GTK_TREE_MODEL (clocklistModel));
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes (titles[0],
renderer,
"text", TZ_DESCRIPTION,
NULL);
gtk_tree_view_column_set_sizing( column, GTK_TREE_VIEW_COLUMN_AUTOSIZE );
gtk_tree_view_append_column (GTK_TREE_VIEW (clocklist), column);
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes (titles[1],
renderer,
"text", TZ_TIMEDATE,
NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (clocklist), column);
gtk_container_add(GTK_CONTAINER(scrolled_window), clocklist);
gtk_widget_show (clocklist);
for (i=0; i < 7; i++ )
{
gtk_list_store_append ( GTK_LIST_STORE(clocklistModel), &iter);
gtk_list_store_set ( GTK_LIST_STORE(clocklistModel), &iter,
TZ_NAME, timezone,
TZ_DESCRIPTION, "Local",
-1);
}
gtk_signal_connect (GTK_OBJECT (window), "delete_event",
GTK_SIGNAL_FUNC (gtk_main_quit), (gpointer)clocklist);
/* calculate the time each second */
timer = start_timer( (gpointer)clocklist );
gtk_widget_show (window);
gtk_window_resize( GTK_WINDOW(window), 300, 200);
gtk_main ();
return(0);
}
PGP signature
[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]