Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
emacs
emacs
Commits
7863d625
Commit
7863d625
authored
Mar 23, 2003
by
Jan Djärv
Browse files
Finally (?) fix flicker in scroll bar.
parent
56c806b7
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
156 additions
and
70 deletions
+156
-70
src/ChangeLog
src/ChangeLog
+21
-0
src/gtkutil.c
src/gtkutil.c
+124
-66
src/gtkutil.h
src/gtkutil.h
+5
-2
src/xterm.c
src/xterm.c
+6
-2
No files found.
src/ChangeLog
View file @
7863d625
2003-03-23 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
* gtkutil.h: Take two more arguments to xg_update_scrollbar_pos.
(XG_SB_RANGE): New define.
* gtkutil.c (xg_fixed_handle_expose): New function.
(xg_create_frame_widgets): Call xg_fixed_handle_expose for
expose events.
(xg_update_scrollbar_pos): Take two more arguments, left and width
of scroll bar including borders.
Clear left and right part outside scroll bar separately as some
themes have bars that are not an even number of pixels.
Don't set reallocate_redraws, don't call
gdk_window_process_all_updates.
(xg_set_toolkit_scroll_bar_thumb): Upper value is fixed,
so no need to change it. Calculate size and value with XG_SB_RANGE.
* xterm.c (x_scroll_bar_create, XTset_vertical_scroll_bar): Pass
left and width of scroll bar including borders to
xg_update_scrollbar_pos.
2003-03-22 Thien-Thi Nguyen <ttn@gnu.org>
* Makefile.in: Make sure space precedes end-of-line backslashes.
...
...
src/gtkutil.c
View file @
7863d625
...
...
@@ -151,7 +151,7 @@ xg_process_timeouts (timer)
/* Start the xg_timer with an interval of 0.1 seconds, if not already started.
xg_process_timeouts is called when the timer expires. The timer
stared is continuous, i.e. runs until xg_stop_timer is called. */
star
t
ed is continuous, i.e. runs until xg_stop_timer is called. */
static
void
xg_start_timer
()
{
...
...
@@ -412,6 +412,54 @@ xg_pix_to_gcolor (w, pixel, c)
gdk_colormap_query_color
(
map
,
pixel
,
c
);
}
/* Turning off double buffering for our GtkFixed widget has the side
effect of turning it off also for its children (scroll bars).
But we want those to be double buffered to not flicker so handle
expose manually here.
WIDGET is the GtkFixed widget that gets exposed.
EVENT is the expose event.
USER_DATA is unused.
Return TRUE to tell GTK that this expose event has been fully handeled
and that GTK shall do nothing more with it. */
static
gboolean
xg_fixed_handle_expose
(
GtkWidget
*
widget
,
GdkEventExpose
*
event
,
gpointer
user_data
)
{
GList
*
iter
;
for
(
iter
=
GTK_FIXED
(
widget
)
->
children
;
iter
;
iter
=
g_list_next
(
iter
))
{
GtkFixedChild
*
child_data
=
(
GtkFixedChild
*
)
iter
->
data
;
GtkWidget
*
child
=
child_data
->
widget
;
GdkWindow
*
window
=
child
->
window
;
GdkRegion
*
region
=
gtk_widget_region_intersect
(
child
,
event
->
region
);
if
(
!
gdk_region_empty
(
region
))
{
GdkEvent
child_event
;
child_event
.
expose
=
*
event
;
child_event
.
expose
.
region
=
region
;
/* Turn on double buffering, i.e. draw to an off screen area. */
gdk_window_begin_paint_region
(
window
,
region
);
/* Tell child to redraw itself. */
gdk_region_get_clipbox
(
region
,
&
child_event
.
expose
.
area
);
gtk_widget_send_expose
(
child
,
&
child_event
);
gdk_window_process_updates
(
window
,
TRUE
);
/* Copy off screen area to the window. */
gdk_window_end_paint
(
window
);
}
gdk_region_destroy
(
region
);
}
return
TRUE
;
}
/* Create and set up the GTK widgets for frame F.
Return 0 if creation failed, non-zero otherwise. */
int
...
...
@@ -478,9 +526,19 @@ xg_create_frame_widgets (f)
if
(
FRAME_EXTERNAL_TOOL_BAR
(
f
)
&&
FRAME_TOOLBAR_HEIGHT
(
f
)
==
0
)
FRAME_TOOLBAR_HEIGHT
(
f
)
=
34
;
gtk_widget_set_double_buffered
(
wvbox
,
FALSE
);
/* We don't want this widget double buffered, because we draw on it
with regular X drawing primitives, so from a GTK/GDK point of
view, the widget is totally blank. When an expose comes, this
will make the widget blank, and then Emacs redraws it. This flickers
a lot, so we turn off double buffering. */
gtk_widget_set_double_buffered
(
wfixed
,
FALSE
);
gtk_widget_set_double_buffered
(
wtop
,
FALSE
);
/* Turning off double buffering above has the side effect of turning
it off also for its children (scroll bars). But we want those
to be double buffered to not flicker so handle expose manually. */
g_signal_connect
(
G_OBJECT
(
wfixed
),
"expose-event"
,
G_CALLBACK
(
xg_fixed_handle_expose
),
0
);
/* GTK documents says use gtk_window_set_resizable. But then a user
can't shrink the window from its starting size. */
...
...
@@ -1159,6 +1217,7 @@ make_widget_for_menu_item (utf8_label, utf8_key)
gtk_widget_set_name
(
wlbl
,
MENU_ITEM_NAME
);
gtk_widget_set_name
(
wkey
,
MENU_ITEM_NAME
);
gtk_widget_set_name
(
wbox
,
MENU_ITEM_NAME
);
return
wbox
;
}
...
...
@@ -2497,7 +2556,8 @@ xg_find_top_left_in_fixed (w, wfixed, left, top)
TOP/LEFT are the new pixel positions where the bar shall appear.
WIDTH, HEIGHT is the size in pixels the bar shall have. */
void
xg_update_scrollbar_pos
(
f
,
scrollbar_id
,
top
,
left
,
width
,
height
)
xg_update_scrollbar_pos
(
f
,
scrollbar_id
,
top
,
left
,
width
,
height
,
real_left
,
canon_width
)
FRAME_PTR
f
;
int
scrollbar_id
;
int
top
;
...
...
@@ -2507,19 +2567,18 @@ xg_update_scrollbar_pos (f, scrollbar_id, top, left, width, height)
{
GtkWidget
*
wscroll
=
xg_get_widget_from_map
(
scrollbar_id
);
if
(
wscroll
)
{
GtkWidget
*
wfixed
=
f
->
output_data
.
x
->
edit_widget
;
int
gheight
=
max
(
height
,
1
);
int
canon_width
=
FRAME_SCROLL_BAR_COLS
(
f
)
*
CANON_X_UNIT
(
f
);
int
winextra
=
canon_width
>
width
?
(
canon_width
-
width
)
/
2
:
0
;
int
bottom
=
top
+
gheight
;
gint
slider_width
;
int
oldtop
,
oldleft
,
oldbottom
;
GtkRequisition
req
;
/* Get old values. */
xg_find_top_left_in_fixed
(
wscroll
,
wfixed
,
&
oldleft
,
&
oldtop
);
gtk_widget_size_request
(
wscroll
,
&
req
);
...
...
@@ -2547,49 +2606,57 @@ xg_update_scrollbar_pos (f, scrollbar_id, top, left, width, height)
the remains of the mode line can be seen in these blank spaces.
So we must clear them explicitly.
GTK scroll bars should do that, but they don't.
Also, the scroll bar canonical width may be wider than the width
passed in here. */
Also, the canonical width may be wider than the width for the
scroll bar so that there is some space (typically 1 pixel) between
the scroll bar and the edge of the window and between the scroll
bar and the fringe. */
if
(
oldtop
!=
-
1
&&
oldleft
!=
-
1
)
{
int
gtkextra
;
int
xl
,
xr
,
wbl
ank
;
int
gtkextra
l
,
gtkextrah
;
int
xl
,
xr
,
wbl
,
wbr
;
int
bottomdiff
,
topdiff
;
gtk_widget_style_get
(
wscroll
,
"slider_width"
,
&
slider_width
,
NULL
);
gtkextra
=
width
>
slider_width
?
(
width
-
slider_width
)
/
2
:
0
;
xl
=
left
-
winextra
;
wblank
=
gtkextra
+
winextra
;
xr
=
left
+
gtkextra
+
slider_width
;
gtkextral
=
width
>
slider_width
?
(
width
-
slider_width
)
/
2
:
0
;
gtkextrah
=
gtkextral
?
(
width
-
slider_width
-
gtkextral
)
:
0
;
xl
=
real_left
;
wbl
=
gtkextral
+
winextra
;
wbr
=
gtkextrah
+
winextra
;
xr
=
left
+
gtkextral
+
slider_width
;
bottomdiff
=
abs
(
oldbottom
-
bottom
);
topdiff
=
abs
(
oldtop
-
top
);
if
(
oldleft
!=
left
)
{
gdk_window_clear_area
(
wfixed
->
window
,
xl
,
top
,
wbl
,
gheight
);
gdk_window_clear_area
(
wfixed
->
window
,
xr
,
top
,
wbr
,
gheight
);
}
if
(
oldtop
>
top
)
{
gdk_window_clear_area
(
wfixed
->
window
,
xl
,
top
,
wbl
ank
,
topdiff
);
gdk_window_clear_area
(
wfixed
->
window
,
xr
,
top
,
wb
lank
,
topdiff
);
gdk_window_clear_area
(
wfixed
->
window
,
xl
,
top
,
wbl
,
topdiff
);
gdk_window_clear_area
(
wfixed
->
window
,
xr
,
top
,
wb
r
,
topdiff
);
}
else
if
(
oldtop
<
top
)
{
gdk_window_clear_area
(
wfixed
->
window
,
xl
,
oldtop
,
wblank
,
topdiff
);
gdk_window_clear_area
(
wfixed
->
window
,
xr
,
oldtop
,
wblank
,
topdiff
);
gdk_window_clear_area
(
wfixed
->
window
,
xl
,
oldtop
,
wbl
,
topdiff
);
gdk_window_clear_area
(
wfixed
->
window
,
xr
,
oldtop
,
wbr
,
topdiff
);
}
if
(
oldbottom
>
bottom
)
{
gdk_window_clear_area
(
wfixed
->
window
,
xl
,
bottom
,
wbl
ank
,
gdk_window_clear_area
(
wfixed
->
window
,
xl
,
bottom
,
wbl
,
bottomdiff
);
gdk_window_clear_area
(
wfixed
->
window
,
xr
,
bottom
,
wb
lank
,
gdk_window_clear_area
(
wfixed
->
window
,
xr
,
bottom
,
wb
r
,
bottomdiff
);
}
else
if
(
oldbottom
<
bottom
)
{
gdk_window_clear_area
(
wfixed
->
window
,
xl
,
oldbottom
,
wbl
ank
,
gdk_window_clear_area
(
wfixed
->
window
,
xl
,
oldbottom
,
wbl
,
bottomdiff
);
gdk_window_clear_area
(
wfixed
->
window
,
xr
,
oldbottom
,
wb
lank
,
gdk_window_clear_area
(
wfixed
->
window
,
xr
,
oldbottom
,
wb
r
,
bottomdiff
);
}
}
...
...
@@ -2598,12 +2665,6 @@ xg_update_scrollbar_pos (f, scrollbar_id, top, left, width, height)
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
);
/* Make GTK draw the new sizes. We are not using a pure GTK event
loop so we need to do this. */
gdk_window_process_all_updates
();
SET_FRAME_GARBAGED
(
f
);
cancel_mouse_face
(
f
);
}
...
...
@@ -2620,15 +2681,14 @@ xg_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
FRAME_PTR
f
=
XFRAME
(
WINDOW_FRAME
(
XWINDOW
(
bar
->
window
)));
BLOCK_INPUT
;
if
(
wscroll
&&
NILP
(
bar
->
dragging
))
{
GtkAdjustment
*
adj
;
gdouble
shown
;
gdouble
top
;
int
size
,
value
;
int
new_upper
,
new_step
;
int
new_step
;
int
changed
=
0
;
adj
=
gtk_range_get_adjustment
(
GTK_RANGE
(
wscroll
));
...
...
@@ -2644,53 +2704,51 @@ xg_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
top
=
0
,
shown
=
1
;
else
{
shown
=
(
gdouble
)
portion
/
whole
;
top
=
(
gdouble
)
position
/
whole
;
shown
=
(
gdouble
)
portion
/
whole
;
}
size
=
shown
*
whole
;
size
=
min
(
size
,
whole
);
size
=
shown
*
XG_SB_RANGE
;
size
=
min
(
size
,
XG_SB_RANGE
);
size
=
max
(
size
,
1
);
value
=
top
*
whole
;
value
=
min
(
value
,
whole
-
size
);
value
=
top
*
XG_SB_RANGE
;
value
=
min
(
value
,
XG_SB_MAX
-
size
);
value
=
max
(
value
,
XG_SB_MIN
);
/* gtk_range_set_value invokes the callback. Set
ignore_gtk_scrollbar to make the callback do nothing */
xg_ignore_gtk_scrollbar
=
1
;
new_upper
=
max
(
whole
,
size
);
new_step
=
portion
/
max
(
1
,
FRAME_HEIGHT
(
f
));
/* Assume all lines are of equal size. */
new_step
=
size
/
max
(
1
,
FRAME_HEIGHT
(
f
));
if
((
int
)
adj
->
page_size
!=
size
||
(
int
)
adj
->
upper
!=
new_upper
||
(
int
)
adj
->
step_increment
!=
new_step
)
{
adj
->
page_size
=
(
int
)
size
;
gtk_range_set_range
(
GTK_RANGE
(
wscroll
),
adj
->
lower
,
(
gdouble
)
new_upper
);
/* Assume all lines are of equal size. */
adj
->
page_size
=
size
;
adj
->
step_increment
=
new_step
;
/* Assume a page increment is about 95% of the page size */
gtk_range_set_increments
(
GTK_RANGE
(
wscroll
),
portion
/
max
(
1
,
FRAME_HEIGHT
(
f
)),
(
int
)
(
0
.
95
*
adj
->
page_size
));
adj
->
page_increment
=
(
int
)
(
0
.
95
*
adj
->
page_size
);
changed
=
1
;
}
if
((
int
)
gtk_range_get_value
(
GTK_RANGE
(
wscroll
))
!=
value
)
gtk_range_set_value
(
GTK_RANGE
(
wscroll
),
(
gdouble
)
value
);
if
(
changed
||
(
int
)
gtk_range_get_value
(
GTK_RANGE
(
wscroll
))
!=
value
)
{
GtkWidget
*
wfixed
=
f
->
output_data
.
x
->
edit_widget
;
xg_ignore_gtk_scrollbar
=
0
;
BLOCK_INPUT
;
/* Make GTK draw the new thumb. We are not using a pure GTK event
loop so we need to do this. */
gdk_window_process_all_updates
();
}
/* gtk_range_set_value invokes the callback. Set
ignore_gtk_scrollbar to make the callback do nothing */
xg_ignore_gtk_scrollbar
=
1
;
UNBLOCK_INPUT
;
if
((
int
)
gtk_range_get_value
(
GTK_RANGE
(
wscroll
))
!=
value
)
gtk_range_set_value
(
GTK_RANGE
(
wscroll
),
(
gdouble
)
value
);
else
if
(
changed
)
gtk_adjustment_changed
(
adj
);
xg_ignore_gtk_scrollbar
=
0
;
UNBLOCK_INPUT
;
}
}
}
...
...
@@ -3098,7 +3156,7 @@ update_frame_tool_bar (f)
/* Must force out update so changed images gets redrawn. */
gdk_window_process_all_updates
();
if
(
icon_list
)
g_list_free
(
icon_list
);
UNBLOCK_INPUT
;
...
...
src/gtkutil.h
View file @
7863d625
...
...
@@ -30,8 +30,9 @@ Boston, MA 02111-1307, USA. */
/* Minimum and maximum values used for GTK scroll bars */
#define XG_SB_MIN
0
#define XG_SB_MIN
1
#define XG_SB_MAX 10000000
#define XG_SB_RANGE (XG_SB_MAX-XG_SB_MIN)
/* Key for data that is valid for menus in a frame */
#define XG_FRAME_DATA "emacs_frame"
...
...
@@ -165,7 +166,9 @@ extern void xg_update_scrollbar_pos P_ ((FRAME_PTR f,
int
top
,
int
left
,
int
width
,
int
height
));
int
height
,
int
real_left
,
int
canon_width
));
extern
void
xg_set_toolkit_scroll_bar_thumb
P_
((
struct
scroll_bar
*
bar
,
int
portion
,
...
...
src/xterm.c
View file @
7863d625
...
...
@@ -4780,7 +4780,9 @@ x_scroll_bar_create (w, top, left, width, height)
top,
left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
max (height, 1));
max (height, 1),
left,
width);
xg_show_scroll_bar (SCROLL_BAR_X_WINDOW (bar));
#else /* not USE_GTK */
Widget scroll_bar = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar);
...
...
@@ -5030,7 +5032,9 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
top,
sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
max (height, 1));
max (height, 1),
left,
width);
#else /* not USE_GTK */
/* Since toolkit scroll bars are smaller than the space reserved
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment