From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: YAMAMOTO Mitsuharu Newsgroups: gmane.emacs.devel Subject: Re: Scrollbar thumbs Date: Tue, 10 Nov 2009 08:14:57 +0900 Organization: Faculty of Science, Chiba University Message-ID: References: <03A2EC54153A4BB1AAE5AF2D2E2B7264@editkapc> <87aaz3jgkp.fsf@catnip.gol.com> <4AF1D60C.6080005@swipnet.se> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Content-Type: text/plain; charset=US-ASCII X-Trace: ger.gmane.org 1257808537 24258 80.91.229.12 (9 Nov 2009 23:15:37 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Mon, 9 Nov 2009 23:15:37 +0000 (UTC) To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Tue Nov 10 00:15:30 2009 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1N7dSK-0002Bt-OE for ged-emacs-devel@m.gmane.org; Tue, 10 Nov 2009 00:15:30 +0100 Original-Received: from localhost ([127.0.0.1]:52336 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1N7dSK-0002YF-42 for ged-emacs-devel@m.gmane.org; Mon, 09 Nov 2009 18:15:28 -0500 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1N7dS2-0002Rp-Kz for emacs-devel@gnu.org; Mon, 09 Nov 2009 18:15:10 -0500 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1N7dRx-0002PC-0x for emacs-devel@gnu.org; Mon, 09 Nov 2009 18:15:09 -0500 Original-Received: from [199.232.76.173] (port=55808 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1N7dRw-0002P6-9x for emacs-devel@gnu.org; Mon, 09 Nov 2009 18:15:04 -0500 Original-Received: from ntp.math.s.chiba-u.ac.jp ([133.82.132.2]:61303 helo=mathmail.math.s.chiba-u.ac.jp) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1N7dRv-0005EH-9h for emacs-devel@gnu.org; Mon, 09 Nov 2009 18:15:04 -0500 Original-Received: from church.math.s.chiba-u.ac.jp (church [133.82.132.36]) by mathmail.math.s.chiba-u.ac.jp (Postfix) with ESMTP id BFFCAC0557 for ; Tue, 10 Nov 2009 08:14:57 +0900 (JST) In-Reply-To: User-Agent: Wanderlust/2.14.0 (Africa) SEMI/1.14.6 (Maruoka) FLIM/1.14.8 (=?ISO-8859-4?Q?Shij=F2?=) APEL/10.6 Emacs/22.3 (sparc-sun-solaris2.8) MULE/5.0 (SAKAKI) X-detected-operating-system: by monty-python.gnu.org: NetBSD 3.0 (DF) 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: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:116766 Archived-At: >>>>> On Thu, 05 Nov 2009 10:18:07 +0900, YAMAMOTO Mitsuharu said: > What the Carbon port (and its descendants) does is to process the > whole mouse events at the Emacs side. It includes timer processing > for repeated scrolling (e.g, pressing an arrow button for a while.) > The toolkit is used only for displaying the scrollbar with > highlighting, detecting which part of the bar is pressed, and > getting the rectangle for a specified part of the bar. > The result is like a sort of mixture of native and toolkit > scrollbars on X11: it generates Lisp events and looks like the > toolkit one, but the size of the thumb usually changes during > dragging and also overscrolling at the bottom works as in the native > one. We can port this thumb handling to scroll bars on Xaw3d compiled with ARROW_SCROLLBARS, because we can guess the rectangle of the thumb from available widget resource values. YAMAMOTO Mitsuharu mituharu@math.s.chiba-u.ac.jp Index: src/xterm.c =================================================================== RCS file: /sources/emacs/emacs/src/xterm.c,v retrieving revision 1.1051 diff -c -p -r1.1051 xterm.c *** src/xterm.c 6 Nov 2009 08:30:45 -0000 1.1051 --- src/xterm.c 9 Nov 2009 20:33:21 -0000 *************** static void x_create_toolkit_scroll_bar *** 4101,4107 **** struct scroll_bar *)); static void x_set_toolkit_scroll_bar_thumb P_ ((struct scroll_bar *, int, int, int)); ! /* Lisp window being scrolled. Set when starting to interact with a toolkit scroll bar, reset to nil when ending the interaction. */ --- 4101,4108 ---- struct scroll_bar *)); static void x_set_toolkit_scroll_bar_thumb P_ ((struct scroll_bar *, int, int, int)); ! static int x_scroll_bar_handle_thumb_event P_ ((struct scroll_bar *, XEvent *, ! struct input_event *)); /* Lisp window being scrolled. Set when starting to interact with a toolkit scroll bar, reset to nil when ending the interaction. */ *************** x_set_toolkit_scroll_bar_thumb (bar, por *** 4812,4817 **** --- 4813,4851 ---- } #else /* !USE_MOTIF i.e. use Xaw */ + if (xaw3d_arrow_scroll) + { + float old_top, old_shown; + Dimension length, thickness, min_thumb, shadow_width; + Dimension margin, min_shown_length; + + XtVaGetValues (widget, XtNtopOfThumb, &old_top, XtNshown, &old_shown, + XtNlength, &length, XtNthickness, &thickness, + XtNminimumThumb, &min_thumb, + XtNshadowWidth, &shadow_width, + NULL); + margin = thickness; + min_shown_length = min_thumb + 2 * shadow_width; + if (whole == 0 || length < 2 * margin + min_shown_length) + top = 0, shown = 1; + else + { + Dimension tzl; + float maximum, scale; + + tzl = length - margin - margin; + + maximum = tzl - min_shown_length; + scale = maximum / whole; + top = (position * scale) / tzl; + shown = (portion * scale + min_shown_length) / tzl; + } + if (top != old_top || shown != old_shown) + XawScrollbarSetThumb (widget, top, shown); + } + else + { + if (whole == 0) top = 0, shown = 1; else *************** x_set_toolkit_scroll_bar_thumb (bar, por *** 4854,4865 **** --- 4888,5025 ---- } } } + + } #endif /* !USE_MOTIF */ UNBLOCK_INPUT; } #endif /* not USE_GTK */ + /* Handle an X11 event EVENT if it is for the thumb of the scroll bar + BAR, and store an input event to *BUFP if necessary. Return + non-zero if the X11 event is handled (i.e., no further handling at + the toolkit side needed). */ + + static int + x_scroll_bar_handle_thumb_event (bar, event, bufp) + struct scroll_bar *bar; + XEvent *event; + struct input_event *bufp; + { + #if !defined (USE_GTK) && !defined (USE_MOTIF) + if (xaw3d_arrow_scroll) + switch (event->type) + { + case ButtonPress: + { + Widget widget = XtWindowToWidget (event->xbutton.display, + event->xbutton.window); + float top, shown; + Dimension length, thickness; + XtOrientation orientation; + Dimension margin, tzl; + Position top_loc, bottom_loc; + int pos; + + XtVaGetValues (widget, XtNtopOfThumb, &top, XtNshown, &shown, + XtNlength, &length, XtNthickness, &thickness, + XtNorientation, &orientation, + NULL); + margin = thickness; + if (length > 2 * margin) + tzl = length - margin - margin; + else + tzl = 0; + top_loc = margin + (int) (tzl * top); + bottom_loc = top_loc + (int) (tzl * shown); + + pos = (orientation == XtorientHorizontal + ? event->xbutton.x : event->xbutton.y); + if (pos >= top_loc && pos <= bottom_loc) + { + bar->dragging = make_number (- (pos - top_loc) - 1); + bar->tracking_thumb_p = 1; + + return 1; + } + } + break; + + case ButtonRelease: + if (bar->tracking_thumb_p) + { + if (INTEGERP (bar->dragging) && XINT (bar->dragging) >= 0) + { + bufp->kind = SCROLL_BAR_CLICK_EVENT; + bufp->frame_or_window = bar->window; + bufp->arg = Qnil; + bufp->timestamp = event->xbutton.time; + bufp->part = scroll_bar_end_scroll; + bufp->code = 0; + XSETINT (bufp->x, 0); + XSETINT (bufp->y, 0); + bufp->modifiers = 0; + } + bar->dragging = Qnil; + bar->tracking_thumb_p = 0; + + return 1; + } + break; + + case MotionNotify: + if (bar->tracking_thumb_p) + { + Widget widget = XtWindowToWidget (event->xmotion.display, + event->xmotion.window); + Dimension length, thickness, min_thumb, shadow_width; + XtOrientation orientation; + Dimension margin, min_shown_length, tzl; + int pos; + int portion, whole; + + if (INTEGERP (bar->dragging) && XINT (bar->dragging) < 0) + bar->dragging = make_number (- (XINT (bar->dragging) + 1)); + + XtVaGetValues (widget, XtNlength, &length, XtNthickness, &thickness, + XtNminimumThumb, &min_thumb, + XtNshadowWidth, &shadow_width, + XtNorientation, &orientation, + NULL); + margin = thickness; + min_shown_length = min_thumb + 2 * shadow_width; + tzl = length - margin - margin; + + pos = (orientation == XtorientHorizontal + ? event->xmotion.x : event->xmotion.y); + portion = pos - XINT (bar->dragging) - margin; + whole = tzl > min_shown_length ? tzl - min_shown_length : tzl; + if (portion < 0) + portion = 0; + if (portion > whole) + portion = whole; + + bufp->kind = SCROLL_BAR_CLICK_EVENT; + bufp->frame_or_window = bar->window; + bufp->arg = Qnil; + bufp->timestamp = event->xmotion.time; + bufp->part = scroll_bar_handle; + bufp->code = 0; + XSETINT (bufp->x, portion); + XSETINT (bufp->y, whole); + bufp->modifiers = 0; + } + + return 1; + break; + + default: + abort (); + } + #endif /* !USE_GTK && !USE_MOTIF */ + return 0; + } #endif /* USE_TOOLKIT_SCROLL_BARS */ *************** x_scroll_bar_create (w, top, left, width *** 4937,4942 **** --- 5097,5103 ---- bar->end = 0; bar->dragging = Qnil; bar->fringe_extended_p = 0; + bar->tracking_thumb_p = 0; /* Add bar to its frame's list of scroll bars. */ bar->next = FRAME_SCROLL_BARS (f); *************** handle_one_xevent (dpyinfo, eventp, fini *** 6729,6742 **** } else { - #ifndef USE_TOOLKIT_SCROLL_BARS struct scroll_bar *bar = x_window_to_scroll_bar (event.xmotion.display, event.xmotion.window); if (bar) x_scroll_bar_note_movement (bar, &event); ! #endif /* USE_TOOLKIT_SCROLL_BARS */ /* If we move outside the frame, then we're certainly no longer on any text in the frame. */ --- 6890,6906 ---- } else { struct scroll_bar *bar = x_window_to_scroll_bar (event.xmotion.display, event.xmotion.window); + #ifdef USE_TOOLKIT_SCROLL_BARS + if (bar && x_scroll_bar_handle_thumb_event (bar, &event, &inev.ie)) + *finish = X_EVENT_DROP; + #else /* !USE_TOOLKIT_SCROLL_BARS */ if (bar) x_scroll_bar_note_movement (bar, &event); ! #endif /* !USE_TOOLKIT_SCROLL_BARS */ /* If we move outside the frame, then we're certainly no longer on any text in the frame. */ *************** handle_one_xevent (dpyinfo, eventp, fini *** 6891,6896 **** --- 7055,7063 ---- x_scroll_bar_handle_click (bar, &event, &inev.ie); *finish = X_EVENT_DROP; } + else if (bar + && x_scroll_bar_handle_thumb_event (bar, &event, &inev.ie)) + *finish = X_EVENT_DROP; #else /* not USE_TOOLKIT_SCROLL_BARS */ if (bar) x_scroll_bar_handle_click (bar, &event, &inev.ie); Index: src/xterm.h =================================================================== RCS file: /sources/emacs/emacs/src/xterm.h,v retrieving revision 1.217 diff -c -p -r1.217 xterm.h *** src/xterm.h 21 Oct 2009 18:29:48 -0000 1.217 --- src/xterm.h 9 Nov 2009 20:33:21 -0000 *************** struct scroll_bar *** 776,781 **** --- 776,785 ---- /* 1 if the background of the fringe that is adjacent to a scroll bar is extended to the gap between the fringe and the bar. */ unsigned int fringe_extended_p : 1; + + /* 1 if the toolkit scroll bar thumb is currently being tracked at + the Emacs side. */ + unsigned int tracking_thumb_p : 1; }; /* The number of elements a vector holding a struct scroll_bar needs. */