mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-29 00:31:01 -08:00
Reduce flicker in GTK scrollbars.
This commit is contained in:
parent
7c928b8f67
commit
cea9be5461
2 changed files with 90 additions and 6 deletions
|
|
@ -1,3 +1,17 @@
|
|||
2003-03-14 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
|
||||
|
||||
* gtkutil.c (struct xg_last_sb_pos): New structure.
|
||||
(handle_fixed_child): New function.
|
||||
(xg_resize_widgets): Call handle_fixed_child on all scroll bar widgets
|
||||
and force a redraw on them.
|
||||
(xg_gtk_scroll_destroy): Free struct xg_last_sb_pos also.
|
||||
(xg_create_scroll_bar): Add struct xg_last_sb_pos to scroll bar
|
||||
so we can avoid unneeded redraws.
|
||||
(xg_update_scrollbar_pos): Invalidate data in xg_last_sb_pos
|
||||
and force a redraw on the scroll bar.
|
||||
(xg_set_toolkit_scroll_bar_thumb): Do not change/redraw scroll bar
|
||||
if xg_last_sb_pos shows the positions are up to date.
|
||||
|
||||
2003-03-13 Kenichi Handa <handa@m17n.org>
|
||||
|
||||
* coding.c (Fdetect_coding_region): Fix docstring.
|
||||
|
|
|
|||
|
|
@ -35,6 +35,19 @@ Boston, MA 02111-1307, USA. */
|
|||
|
||||
#define FRAME_TOTAL_PIXEL_HEIGHT(f) \
|
||||
(PIXEL_HEIGHT (f) + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f))
|
||||
|
||||
|
||||
/* Key to save a struct xg_last_sb_pos in the scroll bars. */
|
||||
#define XG_LAST_SB_POS "emacs_last_sb_pos"
|
||||
|
||||
|
||||
/* Use this in scroll bars to keep track of when redraw is really needed. */
|
||||
struct xg_last_sb_pos
|
||||
{
|
||||
int portion, position, whole;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
Utility functions
|
||||
|
|
@ -285,6 +298,24 @@ xg_resize_outer_widget (f, columns, rows)
|
|||
gdk_window_process_all_updates ();
|
||||
}
|
||||
|
||||
/* When the Emacs frame is resized, we must call this function for each
|
||||
child of our GtkFixed widget. The children are scroll bars and
|
||||
we invalidate the last position data here so it will be properly
|
||||
redrawn later when xg_update_scrollbar_pos is called.
|
||||
W is the child widget.
|
||||
CLIENT_DATA is not used. */
|
||||
static handle_fixed_child (w, client_data)
|
||||
GtkWidget *w;
|
||||
gpointer client_data;
|
||||
{
|
||||
struct xg_last_sb_pos *last_pos
|
||||
= g_object_get_data (G_OBJECT (w), XG_LAST_SB_POS);
|
||||
if (last_pos)
|
||||
{
|
||||
last_pos->portion = last_pos->position = last_pos->whole = .1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Function to handle resize of our widgets. Since Emacs has some layouts
|
||||
that does not fit well with GTK standard containers, we do most layout
|
||||
manually.
|
||||
|
|
@ -314,6 +345,12 @@ xg_resize_widgets (f, pixelwidth, pixelheight)
|
|||
all.height = pixelheight - mbheight - tbheight;
|
||||
|
||||
gtk_widget_size_allocate (x->edit_widget, &all);
|
||||
|
||||
gtk_container_foreach (GTK_CONTAINER (x->edit_widget),
|
||||
(GtkCallback) handle_fixed_child,
|
||||
NULL);
|
||||
gtk_container_set_reallocate_redraws (GTK_CONTAINER (x->edit_widget),
|
||||
TRUE);
|
||||
gdk_window_process_all_updates ();
|
||||
|
||||
change_frame_size (f, rows, columns, 0, 1, 0);
|
||||
|
|
@ -2330,7 +2367,7 @@ xg_get_scroll_id_for_window (wid)
|
|||
|
||||
/* Callback invoked when scroll bar WIDGET is destroyed.
|
||||
DATA is the index into id_to_widget for WIDGET.
|
||||
We free pointer to last scroll bar value here and remove the index. */
|
||||
We free pointer to last scroll bar values here and remove the index. */
|
||||
static void
|
||||
xg_gtk_scroll_destroy (widget, data)
|
||||
GtkWidget *widget;
|
||||
|
|
@ -2341,6 +2378,8 @@ xg_gtk_scroll_destroy (widget, data)
|
|||
|
||||
p = g_object_get_data (G_OBJECT (widget), XG_LAST_SB_DATA);
|
||||
if (p) xfree (p);
|
||||
p = g_object_get_data (G_OBJECT (widget), XG_LAST_SB_POS);
|
||||
if (p) xfree (p);
|
||||
xg_remove_widget_from_map (id);
|
||||
}
|
||||
|
||||
|
|
@ -2420,6 +2459,16 @@ xg_create_scroll_bar (f, bar, scroll_callback, scroll_bar_name)
|
|||
/* Set the cursor to an arrow. */
|
||||
xg_set_cursor (wscroll, &xg_left_ptr_cursor);
|
||||
|
||||
/* Allocate a place to hold the last scollbar size. GTK redraw for
|
||||
scroll bars is basically clear all, and then redraw. This flickers
|
||||
a lot since xg_update_scrollbar_pos gets called on every cursor move
|
||||
and a lot more places. So we have this to check if a redraw really
|
||||
is needed. */
|
||||
struct xg_last_sb_pos *last_pos
|
||||
= (struct xg_last_sb_pos *) xmalloc (sizeof (struct xg_last_sb_pos));
|
||||
last_pos->portion = last_pos->position = last_pos->whole = -1;
|
||||
g_object_set_data (G_OBJECT (wscroll), XG_LAST_SB_POS, last_pos);
|
||||
|
||||
SET_SCROLL_BAR_X_WINDOW (bar, scroll_id);
|
||||
}
|
||||
|
||||
|
|
@ -2467,12 +2516,18 @@ xg_update_scrollbar_pos (f, scrollbar_id, top, left, width, height)
|
|||
if (wscroll)
|
||||
{
|
||||
int gheight = max (height, 1);
|
||||
struct xg_last_sb_pos *last_pos
|
||||
= g_object_get_data (G_OBJECT (wscroll), XG_LAST_SB_POS);
|
||||
GtkWidget *wfixed = f->output_data.x->edit_widget;
|
||||
|
||||
gtk_fixed_move (GTK_FIXED (f->output_data.x->edit_widget),
|
||||
wscroll, left, top);
|
||||
last_pos->portion = last_pos->position = last_pos->whole = -1;
|
||||
xg_ignore_next_thumb = 0;
|
||||
|
||||
gtk_fixed_move (GTK_FIXED (wfixed), wscroll, left, top);
|
||||
gtk_widget_set_size_request (wscroll, width, gheight);
|
||||
|
||||
gtk_container_set_reallocate_redraws (GTK_CONTAINER (wfixed), TRUE);
|
||||
|
||||
/* Must force out update so wscroll gets the resize.
|
||||
Otherwise, the gdk_window_clear clears the old window size. */
|
||||
gdk_window_process_all_updates ();
|
||||
|
|
@ -2502,9 +2557,16 @@ xg_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
|
|||
GtkWidget *wscroll = xg_get_widget_from_map (SCROLL_BAR_X_WINDOW (bar));
|
||||
|
||||
FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
|
||||
struct xg_last_sb_pos *last_pos
|
||||
= (wscroll ? g_object_get_data (G_OBJECT (wscroll), XG_LAST_SB_POS) : 0);
|
||||
|
||||
BLOCK_INPUT;
|
||||
if (wscroll && ! xg_ignore_next_thumb)
|
||||
if (wscroll
|
||||
&& ! xg_ignore_next_thumb
|
||||
&& last_pos
|
||||
&& (last_pos->portion != portion
|
||||
|| last_pos->position != position
|
||||
|| last_pos->whole != whole))
|
||||
{
|
||||
GtkAdjustment *adj;
|
||||
gdouble shown;
|
||||
|
|
@ -2538,15 +2600,23 @@ xg_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
|
|||
/* Assume all lines are equal. */
|
||||
adj->step_increment = portion / max (1, FRAME_HEIGHT (f));
|
||||
|
||||
if (last_pos)
|
||||
{
|
||||
last_pos->portion = portion;
|
||||
last_pos->position = position;
|
||||
last_pos->whole = whole;
|
||||
}
|
||||
|
||||
/* gtk_range_set_value invokes the callback. Set
|
||||
ignore_gtk_scrollbar to make the callback do nothing */
|
||||
xg_ignore_gtk_scrollbar = 1;
|
||||
gtk_range_set_value (GTK_RANGE (wscroll), (gdouble)value);
|
||||
xg_ignore_gtk_scrollbar = 0;
|
||||
|
||||
/* Make sure the scroll bar is redrawn with new thumb */
|
||||
gtk_widget_queue_draw (wscroll);
|
||||
}
|
||||
|
||||
/* Make sure the scroll bar is redrawn with new thumb */
|
||||
gtk_widget_queue_draw (wscroll);
|
||||
gdk_window_process_all_updates ();
|
||||
xg_ignore_next_thumb = 0;
|
||||
UNBLOCK_INPUT;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue