From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Stefan Monnier Newsgroups: gmane.emacs.devel Subject: Re: Addition to emacsbug.el Date: Wed, 27 Oct 2004 09:27:15 -0400 Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Message-ID: References: <417F6C5E.5070801@swipnet.se> NNTP-Posting-Host: deer.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: sea.gmane.org 1098883744 31449 80.91.229.6 (27 Oct 2004 13:29:04 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Wed, 27 Oct 2004 13:29:04 +0000 (UTC) Cc: emacs devel Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Wed Oct 27 15:28:48 2004 Return-path: Original-Received: from lists.gnu.org ([199.232.76.165]) by deer.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 1CMnr5-0004na-00 for ; Wed, 27 Oct 2004 15:28:47 +0200 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.33) id 1CMnyp-0004tB-Np for ged-emacs-devel@m.gmane.org; Wed, 27 Oct 2004 09:36:47 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.33) id 1CMnxw-0004dP-Fl for emacs-devel@gnu.org; Wed, 27 Oct 2004 09:35:52 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.33) id 1CMnxv-0004d6-7J for emacs-devel@gnu.org; Wed, 27 Oct 2004 09:35:51 -0400 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.33) id 1CMnxu-0004cv-SJ for emacs-devel@gnu.org; Wed, 27 Oct 2004 09:35:51 -0400 Original-Received: from [132.204.24.67] (helo=mercure.iro.umontreal.ca) by monty-python.gnu.org with esmtp (Exim 4.34) id 1CMnpe-0004of-Q7 for emacs-devel@gnu.org; Wed, 27 Oct 2004 09:27:19 -0400 Original-Received: from hidalgo.iro.umontreal.ca (hidalgo.iro.umontreal.ca [132.204.27.50]) by mercure.iro.umontreal.ca (Postfix) with ESMTP id 923CA82830D; Wed, 27 Oct 2004 09:27:18 -0400 (EDT) Original-Received: from asado.iro.umontreal.ca (asado.iro.umontreal.ca [132.204.24.84]) by hidalgo.iro.umontreal.ca (Postfix) with ESMTP id 778E74AC80B; Wed, 27 Oct 2004 09:27:16 -0400 (EDT) Original-Received: by asado.iro.umontreal.ca (Postfix, from userid 20848) id 612778CA23; Wed, 27 Oct 2004 09:27:16 -0400 (EDT) Original-To: "Jan D." In-Reply-To: <417F6C5E.5070801@swipnet.se> (Jan D.'s message of "Wed, 27 Oct 2004 11:37:34 +0200") User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/21.3.50 (gnu/linux) X-DIRO-MailScanner-Information: Please contact the ISP for more information X-DIRO-MailScanner: Found to be clean X-DIRO-MailScanner-SpamCheck: n'est pas un polluriel, SpamAssassin (score=0, requis 5) X-MailScanner-From: monnier@iro.umontreal.ca X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: main.gmane.org gmane.emacs.devel:29056 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:29056 > I'm working on the GTK scroll bars again, trying to get overscrolling to > work as in the native scroll bars. But I see that depending on what GTK > version and what X server version I run on (specifically with DAMAGE > extension or not), I sometimes get different behaviour. Therefore I would > like to have this information inserted by report-emacs-bug. The GTK version > is already in emacs-version, so I propose this patch to emacsbug.el: BTW, with the Xaw3d scrollbars (which had/have the same problem), I've been using the following trick very happily: - use the "normal" thumb position and size (the same as was used for the non-toolkit scroll bars). - at the beginning of a thumb-drag, set the thumb size to 0. - at the end of a thumb-drag reset the thumb-size to its real value. I find this to be the best solution to the problem: from the code's point of view, it's clean and simple (much cleaner and simpler than the hacks that are currently used in xterm.c). From the user's point of view, it makes dragging a bit strange at first because the thumb almost disappears under the mouse cursor, but to make up for it, the actual behavior during dragging is now flawless and so is the rest of the behavior. Since we can't have a perfect behavior I find this trade off to be much better than anything I've seen so far. And also I suggest to merge xg_set_toolkit_scroll_bar_thumb back into x_set_toolkit_scroll_bar_thumb. Here is my current patch to xterm.c (barely tested under Gtk, tho). Stefan *** orig/src/xterm.c --- mod/src/xterm.c *************** *** 4019,4030 **** static Boolean xaw3d_arrow_scroll; - /* Whether the drag scrolling maintains the mouse at the top of the - thumb. If not, resizing the thumb needs to be done more carefully - to avoid jerkyness. */ - - static Boolean xaw3d_pick_top; - extern void set_vertical_scroll_bar P_ ((struct window *)); /* Action hook installed via XtAppAddActionHook when toolkit scroll --- 4019,4024 ---- *************** *** 4183,4193 **** } ! #ifdef USE_MOTIF ! /* Minimum and maximum values used for Motif scroll bars. */ ! #define XM_SB_MAX 10000000 /* Scroll bar callback for Motif scroll bars. WIDGET is the scroll --- 4177,4187 ---- } ! /* Maximum size value used for some scroll bars. */ ! #define SB_MAX 10000000 ! #ifdef USE_MOTIF /* Scroll bar callback for Motif scroll bars. WIDGET is the scroll *************** *** 4244,4250 **** XtVaGetValues (widget, XmNsliderSize, &slider_size, NULL); UNBLOCK_INPUT; ! whole = XM_SB_MAX - slider_size; portion = min (cs->value, whole); part = scroll_bar_handle; bar->dragging = make_number (cs->value); --- 4238,4244 ---- XtVaGetValues (widget, XmNsliderSize, &slider_size, NULL); UNBLOCK_INPUT; ! whole = SB_MAX - slider_size; portion = min (cs->value, whole); part = scroll_bar_handle; bar->dragging = make_number (cs->value); *************** *** 4263,4271 **** } } - #else /* !USE_MOTIF, i.e. Xaw or GTK */ - #ifdef USE_GTK /* Scroll bar callback for GTK scroll bars. WIDGET is the scroll bar widget. DATA is a pointer to the scroll_bar structure. */ --- 4257,4264 ---- } } + #elif defined USE_GTK /* Scroll bar callback for GTK scroll bars. WIDGET is the scroll bar widget. DATA is a pointer to the scroll_bar structure. */ *************** *** 4336,4342 **** } } ! #else /* not USE_GTK */ /* Xaw scroll bar callback. Invoked when the thumb is dragged. WIDGET is the scroll bar widget. CLIENT_DATA is a pointer to the --- 4329,4335 ---- } } ! #else /* not USE_GTK and not USE_MOTIF */ /* Xaw scroll bar callback. Invoked when the thumb is dragged. WIDGET is the scroll bar widget. CLIENT_DATA is a pointer to the *************** *** 4350,4376 **** { struct scroll_bar *bar = (struct scroll_bar *) client_data; float top = *(float *) call_data; ! float shown; ! int whole, portion, height; int part; ! /* Get the size of the thumb, a value between 0 and 1. */ ! BLOCK_INPUT; ! XtVaGetValues (widget, XtNshown, &shown, XtNheight, &height, NULL); ! UNBLOCK_INPUT; ! ! whole = 10000000; ! portion = shown < 1 ? top * whole : 0; ! ! if (shown < 1 && (abs (top + shown - 1) < 1.0/height)) ! /* Some derivatives of Xaw refuse to shrink the thumb when you reach ! the bottom, so we force the scrolling whenever we see that we're ! too close to the bottom (in x_set_toolkit_scroll_bar_thumb ! we try to ensure that we always stay two pixels away from the ! bottom). */ ! part = scroll_bar_down_arrow; ! else ! part = scroll_bar_handle; window_being_scrolled = bar->window; bar->dragging = make_number (portion); --- 4343,4357 ---- { struct scroll_bar *bar = (struct scroll_bar *) client_data; float top = *(float *) call_data; ! int whole, portion; int part; ! whole = SB_MAX; ! portion = min (SB_MAX * top, whole); ! part = scroll_bar_handle; ! /* The thumb can't be resized while dragging and could thus prevent us ! from reaching the end: let's set it to 0 temporarily. */ ! XawScrollbarSetThumb (widget, top, 0); window_being_scrolled = bar->window; bar->dragging = make_number (portion); *************** *** 4419,4426 **** x_send_scroll_bar_event (bar->window, part, position, height); } ! #endif /* not USE_GTK */ ! #endif /* not USE_MOTIF */ #define SCROLL_BAR_NAME "verticalScrollBar" --- 4400,4406 ---- x_send_scroll_bar_event (bar->window, part, position, height); } ! #endif /* not USE_GTK and not USE_MOTIF */ #define SCROLL_BAR_NAME "verticalScrollBar" *************** *** 4461,4467 **** /* Set resources. Create the widget. */ XtSetArg (av[ac], XtNmappedWhenManaged, False); ++ac; XtSetArg (av[ac], XmNminimum, 0); ++ac; ! XtSetArg (av[ac], XmNmaximum, XM_SB_MAX); ++ac; XtSetArg (av[ac], XmNorientation, XmVERTICAL); ++ac; XtSetArg (av[ac], XmNprocessingDirection, XmMAX_ON_BOTTOM), ++ac; XtSetArg (av[ac], XmNincrement, 1); ++ac; --- 4441,4447 ---- /* Set resources. Create the widget. */ XtSetArg (av[ac], XtNmappedWhenManaged, False); ++ac; XtSetArg (av[ac], XmNminimum, 0); ++ac; ! XtSetArg (av[ac], XmNmaximum, SB_MAX); ++ac; XtSetArg (av[ac], XmNorientation, XmVERTICAL); ++ac; XtSetArg (av[ac], XmNprocessingDirection, XmMAX_ON_BOTTOM), ++ac; XtSetArg (av[ac], XmNincrement, 1); ++ac; *************** *** 4593,4600 **** { char *initial = ""; char *val = initial; ! XtVaGetValues (widget, XtNscrollVCursor, (XtPointer) &val, ! XtNpickTop, (XtPointer) &xaw3d_pick_top, NULL); if (val == initial) { /* ARROW_SCROLL */ xaw3d_arrow_scroll = True; --- 4573,4579 ---- { char *initial = ""; char *val = initial; ! XtVaGetValues (widget, XtNscrollVCursor, (XtPointer) &val, NULL); if (val == initial) { /* ARROW_SCROLL */ xaw3d_arrow_scroll = True; *************** *** 4631,4675 **** /* Set the thumb size and position of scroll bar BAR. We are currently displaying PORTION out of a whole WHOLE, and our position POSITION. */ - #ifdef USE_GTK static void x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole) struct scroll_bar *bar; int portion, position, whole; { - xg_set_toolkit_scroll_bar_thumb (bar, portion, position, whole); - } - - #else /* not USE_GTK */ - static void - x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole) - struct scroll_bar *bar; - int portion, position, whole; - { - struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); - Widget widget = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar); float top, shown; - BLOCK_INPUT; - - #ifdef USE_MOTIF - - /* We use an estimate of 30 chars per line rather than the real - `portion' value. This has the disadvantage that the thumb size - is not very representative, but it makes our life a lot easier. - Otherwise, we have to constantly adjust the thumb size, which - we can't always do quickly enough: while dragging, the size of - the thumb might prevent the user from dragging the thumb all the - way to the end. but Motif and some versions of Xaw3d don't allow - updating the thumb size while dragging. Also, even if we can update - its size, the update will often happen too late. - If you don't believe it, check out revision 1.650 of xterm.c to see - what hoops we were going through and the still poor behavior we got. */ - portion = WINDOW_TOTAL_LINES (XWINDOW (bar->window)) * 30; - /* When the thumb is at the bottom, position == whole. - So we need to increase `whole' to make space for the thumb. */ - whole += portion; - if (whole <= 0) top = 0, shown = 1; else --- 4610,4622 ---- *************** *** 4678,4768 **** shown = (float) portion / whole; } if (NILP (bar->dragging)) { int size, value; /* Slider size. Must be in the range [1 .. MAX - MIN] where MAX is the scroll bar's maximum and MIN is the scroll bar's minimum value. */ ! size = shown * XM_SB_MAX; ! size = min (size, XM_SB_MAX); size = max (size, 1); /* Position. Must be in the range [MIN .. MAX - SLIDER_SIZE]. */ ! value = top * XM_SB_MAX; ! value = min (value, XM_SB_MAX - size); XmScrollBarSetValues (widget, value, size, 0, 0, False); ! } ! #else /* !USE_MOTIF i.e. use Xaw */ ! if (whole == 0) ! top = 0, shown = 1; ! else ! { ! top = (float) position / whole; ! shown = (float) portion / whole; ! } ! { ! float old_top, old_shown; ! Dimension height; ! XtVaGetValues (widget, ! XtNtopOfThumb, &old_top, ! XtNshown, &old_shown, ! XtNheight, &height, ! NULL); ! ! /* Massage the top+shown values. */ ! if (NILP (bar->dragging) || last_scroll_bar_part == scroll_bar_down_arrow) ! top = max (0, min (1, top)); ! else ! top = old_top; ! /* Keep two pixels available for moving the thumb down. */ ! shown = max (0, min (1 - top - (2.0 / height), shown)); ! ! /* If the call to XawScrollbarSetThumb below doesn't seem to work, ! check that your system's configuration file contains a define ! for `NARROWPROTO'. See s/freebsd.h for an example. */ ! if (top != old_top || shown != old_shown) ! { ! if (NILP (bar->dragging)) ! XawScrollbarSetThumb (widget, top, shown); ! else { ! #ifdef HAVE_XAW3D ! ScrollbarWidget sb = (ScrollbarWidget) widget; ! int scroll_mode = 0; ! /* `scroll_mode' only exists with Xaw3d + ARROW_SCROLLBAR. */ ! if (xaw3d_arrow_scroll) ! { ! /* Xaw3d stupidly ignores resize requests while dragging ! so we have to make it believe it's not in dragging mode. */ ! scroll_mode = sb->scrollbar.scroll_mode; ! if (scroll_mode == 2) ! sb->scrollbar.scroll_mode = 0; ! } ! #endif ! /* Try to make the scrolling a tad smoother. */ ! if (!xaw3d_pick_top) ! shown = min (shown, old_shown); ! ! XawScrollbarSetThumb (widget, top, shown); ! ! #ifdef HAVE_XAW3D ! if (xaw3d_arrow_scroll && scroll_mode == 2) ! sb->scrollbar.scroll_mode = scroll_mode; ! #endif } } ! } #endif /* !USE_MOTIF */ UNBLOCK_INPUT; } - #endif /* not USE_GTK */ #endif /* USE_TOOLKIT_SCROLL_BARS */ --- 4625,4709 ---- shown = (float) portion / whole; } + BLOCK_INPUT; + if (NILP (bar->dragging)) { + FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); + #ifdef USE_GTK + GtkWidget *wscroll = xg_get_widget_from_map (SCROLL_BAR_X_WINDOW (bar)); + #else + Widget widget = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar); + #endif + + #if defined USE_MOTIF || defined USE_GTK int size, value; /* Slider size. Must be in the range [1 .. MAX - MIN] where MAX is the scroll bar's maximum and MIN is the scroll bar's minimum value. */ ! size = shown * SB_MAX; ! size = min (size, SB_MAX); size = max (size, 1); /* Position. Must be in the range [MIN .. MAX - SLIDER_SIZE]. */ ! value = top * SB_MAX; ! value = min (value, SB_MAX - size); + #ifdef USE_MOTIF XmScrollBarSetValues (widget, value, size, 0, 0, False); ! #else /* USE_GTK */ ! { ! GtkAdjustment *adj; ! int new_step; ! int changed = 0; ! adj = gtk_range_get_adjustment (GTK_RANGE (wscroll)); ! /* Assume all lines are of equal size. */ ! new_step = size / max (1, FRAME_HEIGHT (f)); ! ! if ((int) adj->page_size != size ! || (int) adj->step_increment != new_step) { ! adj->page_size = size; ! adj->step_increment = new_step; ! /* Assume a page increment is about 95% of the page size */ ! adj->page_increment = (int) (0.95*adj->page_size); ! changed = 1; ! } ! if (changed || (int) gtk_range_get_value (GTK_RANGE (wscroll)) != value) ! { ! GtkWidget *wfixed = f->output_data.x->edit_widget; ! ! BLOCK_INPUT; ! ! /* gtk_range_set_value invokes the callback. Set ! ignore_gtk_scrollbar to make the callback do nothing */ ! xg_ignore_gtk_scrollbar = 1; ! ! 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; } } ! #endif ! #else /* not USE_MOTIF and not USE_GTK i.e. use Xaw */ ! /* If the call to XawScrollbarSetThumb below doesn't seem to work, ! check that your system's configuration file contains a define ! for `NARROWPROTO'. See s/freebsd.h for an example. */ ! XawScrollbarSetThumb (widget, top, shown); #endif /* !USE_MOTIF */ + } UNBLOCK_INPUT; } #endif /* USE_TOOLKIT_SCROLL_BARS */ *************** *** 4878,4883 **** --- 4819,4826 ---- } + #ifndef USE_TOOLKIT_SCROLL_BARS + /* Draw BAR's handle in the proper position. If the handle is already drawn from START to END, don't bother *************** *** 4891,4898 **** the bar's top is as far down as it goes; otherwise, there's no way to move to the very end of the buffer. */ - #ifndef USE_TOOLKIT_SCROLL_BARS - static void x_scroll_bar_set_handle (bar, start, end, rebuild) struct scroll_bar *bar; --- 4834,4839 ---- *************** *** 10840,10846 **** #ifdef USE_TOOLKIT_SCROLL_BARS #ifndef USE_GTK xaw3d_arrow_scroll = False; - xaw3d_pick_top = True; #endif #endif --- 10780,10785 ----