diff options
| author | Jan Djärv | 2003-03-17 23:03:53 +0000 |
|---|---|---|
| committer | Jan Djärv | 2003-03-17 23:03:53 +0000 |
| commit | 17097258bdba66a449f6c690090a2b536c80b17b (patch) | |
| tree | 52319a9267c01a419d7d0dc0302afc4fa913afea /src | |
| parent | 8cb9dfbfc56c4ca8dcd9adef11bbc8d949387936 (diff) | |
| download | emacs-17097258bdba66a449f6c690090a2b536c80b17b.tar.gz emacs-17097258bdba66a449f6c690090a2b536c80b17b.zip | |
New approach to scrolling and scroll bars for better redraw and smoother
scroll bar behaviour.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 24 | ||||
| -rw-r--r-- | src/gtkutil.c | 243 | ||||
| -rw-r--r-- | src/xterm.c | 7 |
3 files changed, 169 insertions, 105 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 4c9d573c74e..cd271f1b116 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,27 @@ | |||
| 1 | 2003-03-18 Jan Dj,Ad(Brv <jan.h.d@swipnet.se> | ||
| 2 | |||
| 3 | * xterm.c (xg_scroll_callback): Remove xg_ignore_next_thumb. | ||
| 4 | |||
| 5 | * gtkutil.c (xg_initialize): Remove xg_ignore_next_thumb. | ||
| 6 | |||
| 7 | 2003-03-17 Jan Dj,Ad(Brv <jan.h.d@swipnet.se> | ||
| 8 | |||
| 9 | * gtkutil.c: Removed handle_fixed_child, struct xg_last_sb_pos. | ||
| 10 | (xg_resize_widgets): Don't call foreach(handle_fixed_child). | ||
| 11 | (xg_gtk_scroll_destroy): Remove free of struct xg_last_sb_pos. | ||
| 12 | (scroll_bar_button_cb): Set bar->dragging to NIL on button release. | ||
| 13 | (xg_create_scroll_bar): Pass bar to button event callback. | ||
| 14 | (xg_find_top_left_in_fixed): New function. | ||
| 15 | (xg_update_scrollbar_pos): Don't call gdk_window_clear on | ||
| 16 | whole scroll bar area. Get old position with | ||
| 17 | xg_find_top_left_in_fixed, calculate and only clear needed areas. | ||
| 18 | (xg_set_toolkit_scroll_bar_thumb): Do not adjust scroll bar if | ||
| 19 | dragging is in progress. Calculate whole as for Motif. | ||
| 20 | Remove code that saved last values. Call gtk_range functions to | ||
| 21 | set scroll bar sizes. | ||
| 22 | |||
| 23 | * gtkutil.h: Removed xg_ignore_next_thumb. | ||
| 24 | |||
| 1 | 2003-03-17 Juanma Barranquero <lektu@terra.es> | 25 | 2003-03-17 Juanma Barranquero <lektu@terra.es> |
| 2 | 26 | ||
| 3 | * makefile.w32-in ($(BLD)/xdisp.$(O)): Add dependency on blockinput.h | 27 | * makefile.w32-in ($(BLD)/xdisp.$(O)): Add dependency on blockinput.h |
diff --git a/src/gtkutil.c b/src/gtkutil.c index 0b8f9294612..d66b8523b18 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c | |||
| @@ -37,17 +37,6 @@ Boston, MA 02111-1307, USA. */ | |||
| 37 | (PIXEL_HEIGHT (f) + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f)) | 37 | (PIXEL_HEIGHT (f) + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f)) |
| 38 | 38 | ||
| 39 | 39 | ||
| 40 | /* Key to save a struct xg_last_sb_pos in the scroll bars. */ | ||
| 41 | #define XG_LAST_SB_POS "emacs_last_sb_pos" | ||
| 42 | |||
| 43 | |||
| 44 | /* Use this in scroll bars to keep track of when redraw is really needed. */ | ||
| 45 | struct xg_last_sb_pos | ||
| 46 | { | ||
| 47 | int portion, position, whole; | ||
| 48 | }; | ||
| 49 | |||
| 50 | |||
| 51 | 40 | ||
| 52 | /*********************************************************************** | 41 | /*********************************************************************** |
| 53 | Utility functions | 42 | Utility functions |
| @@ -298,24 +287,6 @@ xg_resize_outer_widget (f, columns, rows) | |||
| 298 | gdk_window_process_all_updates (); | 287 | gdk_window_process_all_updates (); |
| 299 | } | 288 | } |
| 300 | 289 | ||
| 301 | /* When the Emacs frame is resized, we must call this function for each | ||
| 302 | child of our GtkFixed widget. The children are scroll bars and | ||
| 303 | we invalidate the last position data here so it will be properly | ||
| 304 | redrawn later when xg_update_scrollbar_pos is called. | ||
| 305 | W is the child widget. | ||
| 306 | CLIENT_DATA is not used. */ | ||
| 307 | static handle_fixed_child (w, client_data) | ||
| 308 | GtkWidget *w; | ||
| 309 | gpointer client_data; | ||
| 310 | { | ||
| 311 | struct xg_last_sb_pos *last_pos | ||
| 312 | = g_object_get_data (G_OBJECT (w), XG_LAST_SB_POS); | ||
| 313 | if (last_pos) | ||
| 314 | { | ||
| 315 | last_pos->portion = last_pos->position = last_pos->whole = .1; | ||
| 316 | } | ||
| 317 | } | ||
| 318 | |||
| 319 | /* This gets called after the frame F has been cleared. Since that is | 290 | /* This gets called after the frame F has been cleared. Since that is |
| 320 | done with X calls, we need to redraw GTK widget (scroll bars). */ | 291 | done with X calls, we need to redraw GTK widget (scroll bars). */ |
| 321 | void | 292 | void |
| @@ -326,9 +297,6 @@ xg_frame_cleared (f) | |||
| 326 | 297 | ||
| 327 | if (wfixed) | 298 | if (wfixed) |
| 328 | { | 299 | { |
| 329 | gtk_container_foreach (GTK_CONTAINER (wfixed), | ||
| 330 | (GtkCallback) handle_fixed_child, | ||
| 331 | NULL); | ||
| 332 | gtk_container_set_reallocate_redraws (GTK_CONTAINER (wfixed), TRUE); | 300 | gtk_container_set_reallocate_redraws (GTK_CONTAINER (wfixed), TRUE); |
| 333 | gdk_window_process_all_updates (); | 301 | gdk_window_process_all_updates (); |
| 334 | } | 302 | } |
| @@ -2277,11 +2245,6 @@ free_frame_menubar (f) | |||
| 2277 | to indicate that callback should do nothing. */ | 2245 | to indicate that callback should do nothing. */ |
| 2278 | int xg_ignore_gtk_scrollbar; | 2246 | int xg_ignore_gtk_scrollbar; |
| 2279 | 2247 | ||
| 2280 | /* After we send a scroll bar event, x_set_toolkit_scroll_bar_thumb will | ||
| 2281 | be called. For some reason that needs to be debugged, it gets called | ||
| 2282 | with bad values. Thus, we set this variable to ignore those calls. */ | ||
| 2283 | int xg_ignore_next_thumb; | ||
| 2284 | |||
| 2285 | /* SET_SCROLL_BAR_X_WINDOW assumes the second argument fits in | 2248 | /* SET_SCROLL_BAR_X_WINDOW assumes the second argument fits in |
| 2286 | 32 bits. But we want to store pointers, and they may be larger | 2249 | 32 bits. But we want to store pointers, and they may be larger |
| 2287 | than 32 bits. Keep a mapping from integer index to widget pointers | 2250 | than 32 bits. Keep a mapping from integer index to widget pointers |
| @@ -2391,16 +2354,15 @@ xg_gtk_scroll_destroy (widget, data) | |||
| 2391 | 2354 | ||
| 2392 | p = g_object_get_data (G_OBJECT (widget), XG_LAST_SB_DATA); | 2355 | p = g_object_get_data (G_OBJECT (widget), XG_LAST_SB_DATA); |
| 2393 | if (p) xfree (p); | 2356 | if (p) xfree (p); |
| 2394 | p = g_object_get_data (G_OBJECT (widget), XG_LAST_SB_POS); | ||
| 2395 | if (p) xfree (p); | ||
| 2396 | xg_remove_widget_from_map (id); | 2357 | xg_remove_widget_from_map (id); |
| 2397 | } | 2358 | } |
| 2398 | 2359 | ||
| 2399 | /* Callback for button press/release events. Used to start timer so that | 2360 | /* Callback for button press/release events. Used to start timer so that |
| 2400 | the scroll bar repetition timer in GTK gets handeled. | 2361 | the scroll bar repetition timer in GTK gets handeled. |
| 2362 | Also, sets bar->dragging to Qnil when dragging (button release) is done. | ||
| 2401 | WIDGET is the scroll bar widget the event is for (not used). | 2363 | WIDGET is the scroll bar widget the event is for (not used). |
| 2402 | EVENT contains the event. | 2364 | EVENT contains the event. |
| 2403 | USER_DATA is 0 (not used). | 2365 | USER_DATA points to the struct scrollbar structure. |
| 2404 | 2366 | ||
| 2405 | Returns FALSE to tell GTK that it shall continue propagate the event | 2367 | Returns FALSE to tell GTK that it shall continue propagate the event |
| 2406 | to widgets. */ | 2368 | to widgets. */ |
| @@ -2412,9 +2374,13 @@ scroll_bar_button_cb (widget, event, user_data) | |||
| 2412 | { | 2374 | { |
| 2413 | if (event->type == GDK_BUTTON_PRESS && ! xg_timer) | 2375 | if (event->type == GDK_BUTTON_PRESS && ! xg_timer) |
| 2414 | xg_start_timer (); | 2376 | xg_start_timer (); |
| 2415 | else if (event->type == GDK_BUTTON_RELEASE && xg_timer) | 2377 | else if (event->type == GDK_BUTTON_RELEASE) |
| 2416 | xg_stop_timer (); | 2378 | { |
| 2417 | 2379 | struct scroll_bar *bar = (struct scroll_bar *) user_data; | |
| 2380 | if (xg_timer) xg_stop_timer (); | ||
| 2381 | bar->dragging = Qnil; | ||
| 2382 | } | ||
| 2383 | |||
| 2418 | return FALSE; | 2384 | return FALSE; |
| 2419 | } | 2385 | } |
| 2420 | 2386 | ||
| @@ -2460,28 +2426,18 @@ xg_create_scroll_bar (f, bar, scroll_callback, scroll_bar_name) | |||
| 2460 | g_signal_connect (G_OBJECT (wscroll), | 2426 | g_signal_connect (G_OBJECT (wscroll), |
| 2461 | "button-press-event", | 2427 | "button-press-event", |
| 2462 | G_CALLBACK (scroll_bar_button_cb), | 2428 | G_CALLBACK (scroll_bar_button_cb), |
| 2463 | 0); | 2429 | (gpointer)bar); |
| 2464 | g_signal_connect (G_OBJECT (wscroll), | 2430 | g_signal_connect (G_OBJECT (wscroll), |
| 2465 | "button-release-event", | 2431 | "button-release-event", |
| 2466 | G_CALLBACK (scroll_bar_button_cb), | 2432 | G_CALLBACK (scroll_bar_button_cb), |
| 2467 | 0); | 2433 | (gpointer)bar); |
| 2468 | 2434 | ||
| 2469 | gtk_fixed_put (GTK_FIXED (f->output_data.x->edit_widget), | 2435 | gtk_fixed_put (GTK_FIXED (f->output_data.x->edit_widget), |
| 2470 | wscroll, 0, 0); | 2436 | wscroll, -1, -1); |
| 2471 | 2437 | ||
| 2472 | /* Set the cursor to an arrow. */ | 2438 | /* Set the cursor to an arrow. */ |
| 2473 | xg_set_cursor (wscroll, &xg_left_ptr_cursor); | 2439 | xg_set_cursor (wscroll, &xg_left_ptr_cursor); |
| 2474 | 2440 | ||
| 2475 | /* Allocate a place to hold the last scollbar size. GTK redraw for | ||
| 2476 | scroll bars is basically clear all, and then redraw. This flickers | ||
| 2477 | a lot since xg_update_scrollbar_pos gets called on every cursor move | ||
| 2478 | and a lot more places. So we have this to check if a redraw really | ||
| 2479 | is needed. */ | ||
| 2480 | struct xg_last_sb_pos *last_pos | ||
| 2481 | = (struct xg_last_sb_pos *) xmalloc (sizeof (struct xg_last_sb_pos)); | ||
| 2482 | last_pos->portion = last_pos->position = last_pos->whole = -1; | ||
| 2483 | g_object_set_data (G_OBJECT (wscroll), XG_LAST_SB_POS, last_pos); | ||
| 2484 | |||
| 2485 | SET_SCROLL_BAR_X_WINDOW (bar, scroll_id); | 2441 | SET_SCROLL_BAR_X_WINDOW (bar, scroll_id); |
| 2486 | } | 2442 | } |
| 2487 | 2443 | ||
| @@ -2509,6 +2465,29 @@ xg_remove_scroll_bar (f, scrollbar_id) | |||
| 2509 | } | 2465 | } |
| 2510 | } | 2466 | } |
| 2511 | 2467 | ||
| 2468 | /* Find left/top for widget W in GtkFixed widget WFIXED. */ | ||
| 2469 | static void | ||
| 2470 | xg_find_top_left_in_fixed (w, wfixed, left, top) | ||
| 2471 | GtkWidget *w, *wfixed; | ||
| 2472 | int *left, *top; | ||
| 2473 | { | ||
| 2474 | GList *iter; | ||
| 2475 | |||
| 2476 | for (iter = GTK_FIXED (wfixed)->children; iter; iter = g_list_next (iter)) | ||
| 2477 | { | ||
| 2478 | GtkFixedChild *child = (GtkFixedChild *) iter->data; | ||
| 2479 | |||
| 2480 | if (child->widget == w) | ||
| 2481 | { | ||
| 2482 | *left = child->x; | ||
| 2483 | *top = child->y; | ||
| 2484 | return; | ||
| 2485 | } | ||
| 2486 | } | ||
| 2487 | |||
| 2488 | /* Shall never end up here. */ | ||
| 2489 | abort (); | ||
| 2490 | } | ||
| 2512 | 2491 | ||
| 2513 | /* Update the position of the vertical scroll bar represented by SCROLLBAR_ID | 2492 | /* Update the position of the vertical scroll bar represented by SCROLLBAR_ID |
| 2514 | in frame F. | 2493 | in frame F. |
| @@ -2525,34 +2504,101 @@ xg_update_scrollbar_pos (f, scrollbar_id, top, left, width, height) | |||
| 2525 | { | 2504 | { |
| 2526 | 2505 | ||
| 2527 | GtkWidget *wscroll = xg_get_widget_from_map (scrollbar_id); | 2506 | GtkWidget *wscroll = xg_get_widget_from_map (scrollbar_id); |
| 2528 | 2507 | ||
| 2529 | if (wscroll) | 2508 | if (wscroll) |
| 2530 | { | 2509 | { |
| 2531 | int gheight = max (height, 1); | ||
| 2532 | struct xg_last_sb_pos *last_pos | ||
| 2533 | = g_object_get_data (G_OBJECT (wscroll), XG_LAST_SB_POS); | ||
| 2534 | GtkWidget *wfixed = f->output_data.x->edit_widget; | 2510 | GtkWidget *wfixed = f->output_data.x->edit_widget; |
| 2511 | int gheight = max (height, 1); | ||
| 2512 | int canon_width = FRAME_SCROLL_BAR_COLS (f) * CANON_X_UNIT (f); | ||
| 2513 | int winextra = canon_width > width ? (canon_width - width) / 2 : 0; | ||
| 2514 | int bottom = top + gheight; | ||
| 2535 | 2515 | ||
| 2536 | last_pos->portion = last_pos->position = last_pos->whole = -1; | 2516 | gint slider_width; |
| 2537 | xg_ignore_next_thumb = 0; | 2517 | int oldtop, oldleft, oldbottom; |
| 2518 | GtkRequisition req; | ||
| 2519 | |||
| 2520 | /* Get old values. */ | ||
| 2521 | xg_find_top_left_in_fixed (wscroll, wfixed, &oldleft, &oldtop); | ||
| 2522 | gtk_widget_size_request (wscroll, &req); | ||
| 2523 | oldbottom = oldtop + req.height; | ||
| 2524 | |||
| 2525 | /* Scroll bars in GTK has a fixed width, so if we say width 16, it | ||
| 2526 | will only be its fixed width (14 is default) anyway, the rest is | ||
| 2527 | blank. We are drawing the mode line across scroll bars when | ||
| 2528 | the frame is split: | ||
| 2529 | |bar| |fringe| | ||
| 2530 | ---------------- | ||
| 2531 | mode line | ||
| 2532 | ---------------- | ||
| 2533 | |bar| |fringe| | ||
| 2534 | |||
| 2535 | When we "unsplit" the frame: | ||
| 2536 | |||
| 2537 | |bar| |fringe| | ||
| 2538 | -| |-| | | ||
| 2539 | m¦ |i| | | ||
| 2540 | -| |-| | | ||
| 2541 | | | | | | ||
| 2542 | |||
| 2543 | |||
| 2544 | the remains of the mode line can be seen in these blank spaces. | ||
| 2545 | So we must clear them explicitly. | ||
| 2546 | GTK scroll bars should do that, but they don't. | ||
| 2547 | Also, the scroll bar canonical width may be wider than the width | ||
| 2548 | passed in here. */ | ||
| 2549 | |||
| 2550 | if (oldtop != -1 && oldleft != -1) | ||
| 2551 | { | ||
| 2552 | int gtkextra; | ||
| 2553 | int xl, xr, wblank; | ||
| 2554 | int bottomdiff, topdiff; | ||
| 2555 | |||
| 2556 | gtk_widget_style_get (wscroll, "slider_width", &slider_width, NULL); | ||
| 2557 | gtkextra = width > slider_width ? (width - slider_width) / 2 : 0; | ||
| 2558 | |||
| 2559 | xl = left - winextra; | ||
| 2560 | wblank = gtkextra + winextra; | ||
| 2561 | xr = left + gtkextra + slider_width; | ||
| 2562 | bottomdiff = abs (oldbottom - bottom); | ||
| 2563 | topdiff = abs (oldtop - top); | ||
| 2564 | |||
| 2565 | if (oldtop > top) | ||
| 2566 | { | ||
| 2567 | gdk_window_clear_area (wfixed->window, xl, top, wblank, topdiff); | ||
| 2568 | gdk_window_clear_area (wfixed->window, xr, top, wblank, topdiff); | ||
| 2569 | } | ||
| 2570 | else if (oldtop < top) | ||
| 2571 | { | ||
| 2572 | gdk_window_clear_area (wfixed->window, xl, oldtop, wblank, | ||
| 2573 | topdiff); | ||
| 2574 | gdk_window_clear_area (wfixed->window, xr, oldtop, wblank, | ||
| 2575 | topdiff); | ||
| 2576 | } | ||
| 2577 | |||
| 2578 | if (oldbottom > bottom) | ||
| 2579 | { | ||
| 2580 | gdk_window_clear_area (wfixed->window, xl, bottom, wblank, | ||
| 2581 | bottomdiff); | ||
| 2582 | gdk_window_clear_area (wfixed->window, xr, bottom, wblank, | ||
| 2583 | bottomdiff); | ||
| 2584 | } | ||
| 2585 | else if (oldbottom < bottom) | ||
| 2586 | { | ||
| 2587 | gdk_window_clear_area (wfixed->window, xl, oldbottom, wblank, | ||
| 2588 | bottomdiff); | ||
| 2589 | gdk_window_clear_area (wfixed->window, xr, oldbottom, wblank, | ||
| 2590 | bottomdiff); | ||
| 2591 | } | ||
| 2592 | } | ||
| 2538 | 2593 | ||
| 2594 | /* Move and resize to new values. */ | ||
| 2539 | gtk_fixed_move (GTK_FIXED (wfixed), wscroll, left, top); | 2595 | gtk_fixed_move (GTK_FIXED (wfixed), wscroll, left, top); |
| 2540 | gtk_widget_set_size_request (wscroll, width, gheight); | 2596 | gtk_widget_set_size_request (wscroll, width, gheight); |
| 2541 | 2597 | ||
| 2542 | gtk_container_set_reallocate_redraws (GTK_CONTAINER (wfixed), TRUE); | 2598 | gtk_container_set_reallocate_redraws (GTK_CONTAINER (wfixed), TRUE); |
| 2543 | 2599 | ||
| 2544 | /* Must force out update so wscroll gets the resize. | 2600 | /* Make GTK draw the new sizes. We are not using a pure GTK event |
| 2545 | Otherwise, the gdk_window_clear clears the old window size. */ | 2601 | loop so we need to do this. */ |
| 2546 | gdk_window_process_all_updates (); | ||
| 2547 | |||
| 2548 | /* The scroll bar doesn't explicitly redraw the whole window | ||
| 2549 | when a resize occurs. Since the scroll bar seems to be fixed | ||
| 2550 | in width it doesn't fill the space reserved, so we must clear | ||
| 2551 | the whole window. */ | ||
| 2552 | gdk_window_clear (wscroll->window); | ||
| 2553 | |||
| 2554 | /* Since we are not using a pure gtk event loop, we must force out | ||
| 2555 | pending update events with this call. */ | ||
| 2556 | gdk_window_process_all_updates (); | 2602 | gdk_window_process_all_updates (); |
| 2557 | 2603 | ||
| 2558 | SET_FRAME_GARBAGED (f); | 2604 | SET_FRAME_GARBAGED (f); |
| @@ -2570,16 +2616,10 @@ xg_set_toolkit_scroll_bar_thumb (bar, portion, position, whole) | |||
| 2570 | GtkWidget *wscroll = xg_get_widget_from_map (SCROLL_BAR_X_WINDOW (bar)); | 2616 | GtkWidget *wscroll = xg_get_widget_from_map (SCROLL_BAR_X_WINDOW (bar)); |
| 2571 | 2617 | ||
| 2572 | FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); | 2618 | FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); |
| 2573 | struct xg_last_sb_pos *last_pos | ||
| 2574 | = (wscroll ? g_object_get_data (G_OBJECT (wscroll), XG_LAST_SB_POS) : 0); | ||
| 2575 | 2619 | ||
| 2576 | BLOCK_INPUT; | 2620 | BLOCK_INPUT; |
| 2577 | if (wscroll | 2621 | |
| 2578 | && ! xg_ignore_next_thumb | 2622 | if (wscroll && NILP (bar->dragging)) |
| 2579 | && last_pos | ||
| 2580 | && (last_pos->portion != portion | ||
| 2581 | || last_pos->position != position | ||
| 2582 | || last_pos->whole != whole)) | ||
| 2583 | { | 2623 | { |
| 2584 | GtkAdjustment *adj; | 2624 | GtkAdjustment *adj; |
| 2585 | gdouble shown; | 2625 | gdouble shown; |
| @@ -2588,6 +2628,14 @@ xg_set_toolkit_scroll_bar_thumb (bar, portion, position, whole) | |||
| 2588 | 2628 | ||
| 2589 | adj = gtk_range_get_adjustment (GTK_RANGE (wscroll)); | 2629 | adj = gtk_range_get_adjustment (GTK_RANGE (wscroll)); |
| 2590 | 2630 | ||
| 2631 | /* We do the same as for MOTIF in xterm.c, assume 30 chars per line | ||
| 2632 | rather than the real portion value. This makes the thumb less likely | ||
| 2633 | to resize and that looks better. */ | ||
| 2634 | portion = XFASTINT (XWINDOW (bar->window)->height) * 30; | ||
| 2635 | /* When the thumb is at the bottom, position == whole. | ||
| 2636 | So we need to increase `whole' to make space for the thumb. */ | ||
| 2637 | whole += portion; | ||
| 2638 | |||
| 2591 | if (whole <= 0) | 2639 | if (whole <= 0) |
| 2592 | top = 0, shown = 1; | 2640 | top = 0, shown = 1; |
| 2593 | else | 2641 | else |
| @@ -2604,34 +2652,28 @@ xg_set_toolkit_scroll_bar_thumb (bar, portion, position, whole) | |||
| 2604 | value = min (value, whole - size); | 2652 | value = min (value, whole - size); |
| 2605 | value = max (value, XG_SB_MIN); | 2653 | value = max (value, XG_SB_MIN); |
| 2606 | 2654 | ||
| 2607 | adj->upper = max (whole, size); | ||
| 2608 | adj->page_size = (int)size; | 2655 | adj->page_size = (int)size; |
| 2609 | 2656 | ||
| 2610 | /* Assume a page increment is about 95% of the page size */ | ||
| 2611 | adj->page_increment = (int) (0.95*adj->page_size); | ||
| 2612 | |||
| 2613 | /* Assume all lines are equal. */ | ||
| 2614 | adj->step_increment = portion / max (1, FRAME_HEIGHT (f)); | ||
| 2615 | |||
| 2616 | if (last_pos) | ||
| 2617 | { | ||
| 2618 | last_pos->portion = portion; | ||
| 2619 | last_pos->position = position; | ||
| 2620 | last_pos->whole = whole; | ||
| 2621 | } | ||
| 2622 | |||
| 2623 | /* gtk_range_set_value invokes the callback. Set | 2657 | /* gtk_range_set_value invokes the callback. Set |
| 2624 | ignore_gtk_scrollbar to make the callback do nothing */ | 2658 | ignore_gtk_scrollbar to make the callback do nothing */ |
| 2625 | xg_ignore_gtk_scrollbar = 1; | 2659 | xg_ignore_gtk_scrollbar = 1; |
| 2660 | |||
| 2661 | gtk_range_set_range (GTK_RANGE (wscroll), adj->lower, max (whole, size)); | ||
| 2662 | |||
| 2663 | /* Assume all lines are of equal size. */ | ||
| 2664 | /* Assume a page increment is about 95% of the page size */ | ||
| 2665 | gtk_range_set_increments (GTK_RANGE (wscroll), | ||
| 2666 | portion / max (1, FRAME_HEIGHT (f)), | ||
| 2667 | (int) (0.95*adj->page_size)); | ||
| 2668 | |||
| 2626 | gtk_range_set_value (GTK_RANGE (wscroll), (gdouble)value); | 2669 | gtk_range_set_value (GTK_RANGE (wscroll), (gdouble)value); |
| 2627 | xg_ignore_gtk_scrollbar = 0; | 2670 | xg_ignore_gtk_scrollbar = 0; |
| 2628 | 2671 | ||
| 2629 | /* Make sure the scroll bar is redrawn with new thumb */ | 2672 | /* Make GTK draw the new thumb. We are not using a pure GTK event |
| 2630 | gtk_widget_queue_draw (wscroll); | 2673 | loop so we need to do this. */ |
| 2674 | gdk_window_process_all_updates (); | ||
| 2631 | } | 2675 | } |
| 2632 | 2676 | ||
| 2633 | gdk_window_process_all_updates (); | ||
| 2634 | xg_ignore_next_thumb = 0; | ||
| 2635 | UNBLOCK_INPUT; | 2677 | UNBLOCK_INPUT; |
| 2636 | } | 2678 | } |
| 2637 | 2679 | ||
| @@ -3079,7 +3121,6 @@ void | |||
| 3079 | xg_initialize () | 3121 | xg_initialize () |
| 3080 | { | 3122 | { |
| 3081 | xg_ignore_gtk_scrollbar = 0; | 3123 | xg_ignore_gtk_scrollbar = 0; |
| 3082 | xg_ignore_next_thumb = 0; | ||
| 3083 | xg_left_ptr_cursor = 0; | 3124 | xg_left_ptr_cursor = 0; |
| 3084 | xg_did_tearoff = 0; | 3125 | xg_did_tearoff = 0; |
| 3085 | 3126 | ||
diff --git a/src/xterm.c b/src/xterm.c index 380e4c73d7c..3aac2aeaf67 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -6395,7 +6395,7 @@ xm_scroll_callback (widget, client_data, call_data) | |||
| 6395 | 6395 | ||
| 6396 | #else /* !USE_MOTIF, i.e. Xaw or GTK */ | 6396 | #else /* !USE_MOTIF, i.e. Xaw or GTK */ |
| 6397 | #ifdef USE_GTK | 6397 | #ifdef USE_GTK |
| 6398 | /* Scroll bar callback for Gtk scroll bars. WIDGET is the scroll | 6398 | /* Scroll bar callback for GTK scroll bars. WIDGET is the scroll |
| 6399 | bar adjustment widget. DATA is a pointer to the scroll_bar structure. */ | 6399 | bar adjustment widget. DATA is a pointer to the scroll_bar structure. */ |
| 6400 | 6400 | ||
| 6401 | static void | 6401 | static void |
| @@ -6453,13 +6453,12 @@ xg_scroll_callback (widget, data) | |||
| 6453 | { | 6453 | { |
| 6454 | part = scroll_bar_handle; | 6454 | part = scroll_bar_handle; |
| 6455 | whole = adj->upper - adj->page_size; | 6455 | whole = adj->upper - adj->page_size; |
| 6456 | portion = min (position, whole); | 6456 | portion = min ((int)position, whole); |
| 6457 | bar->dragging = make_number (portion); | 6457 | bar->dragging = make_number ((int)portion); |
| 6458 | } | 6458 | } |
| 6459 | 6459 | ||
| 6460 | if (part >= 0) | 6460 | if (part >= 0) |
| 6461 | { | 6461 | { |
| 6462 | xg_ignore_next_thumb = 1; | ||
| 6463 | window_being_scrolled = bar->window; | 6462 | window_being_scrolled = bar->window; |
| 6464 | last_scroll_bar_part = part; | 6463 | last_scroll_bar_part = part; |
| 6465 | x_send_scroll_bar_event (bar->window, part, portion, whole); | 6464 | x_send_scroll_bar_event (bar->window, part, portion, whole); |