all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
To: emacs-devel@gnu.org
Subject: Re: Scrollbar thumbs
Date: Tue, 10 Nov 2009 08:14:57 +0900	[thread overview]
Message-ID: <wlmy2vp9xq.wl%mituharu@math.s.chiba-u.ac.jp> (raw)
In-Reply-To: <wly6mlzs4w.wl%mituharu@math.s.chiba-u.ac.jp>

>>>>> On Thu, 05 Nov 2009 10:18:07 +0900, YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> 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.  */




  reply	other threads:[~2009-11-09 23:14 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-11-02 10:41 Scrollbar thumbs (was: Customizing the mode line) grischka
2009-11-02 11:21 ` Scrollbar thumbs Miles Bader
2009-11-03  0:48   ` grischka
2009-11-03  9:27     ` David Kastrup
2009-11-04  0:09     ` Miles Bader
2009-11-04  9:51       ` grischka
2009-11-04 11:18         ` joakim
2009-11-04 19:29           ` Jan Djärv
2009-11-04 20:57             ` Stefan Monnier
2009-11-05  1:18               ` YAMAMOTO Mitsuharu
2009-11-09 23:14                 ` YAMAMOTO Mitsuharu [this message]
2009-11-05  9:23               ` Jan D.
2009-11-05 13:59                 ` Stefan Monnier
2009-11-05 15:16               ` grischka
2009-11-05 15:32                 ` Lennart Borgman
2009-11-05 15:35                 ` Óscar Fuentes
2009-11-05 16:07                 ` David Kastrup
2009-11-05 23:55                   ` Jason Rumney
2009-11-06  0:31                     ` Miles Bader
2009-11-06  3:10                     ` Stephen J. Turnbull
2009-11-06  4:37                       ` Miles Bader
2009-11-06  8:42                     ` David Kastrup
2009-11-06  8:55                     ` Eli Zaretskii
2009-11-02 14:15 ` Stefan Monnier
2009-11-03  0:32   ` grischka
2009-11-03  1:18     ` Stefan Monnier
2009-11-03  5:37       ` grischka
2009-11-03 13:38         ` Stefan Monnier
2009-11-03 21:10           ` grischka
2009-11-03 23:00             ` Stefan Monnier
2009-11-03 10:02   ` joakim
2009-11-05  9:21     ` Jan D.
  -- strict thread matches above, loose matches on Subject: below --
2009-11-07 11:50 grischka
2009-11-07 16:38 ` Óscar Fuentes
2009-11-07 17:47   ` David De La Harpe Golden
2009-11-03 16:36 grischka
2009-11-03 17:13 ` David Kastrup
2009-10-30 11:18 Customizing the mode line Eli Zaretskii
2009-10-30 13:38 ` Stefan Monnier
2009-10-31  6:09   ` Manoj Srivastava
2009-10-31 20:38     ` Scrollbar thumbs (was: Customizing the mode line) Stefan Monnier
2009-11-01  3:11       ` Scrollbar thumbs Miles Bader
2009-11-02  6:55         ` Stefan Monnier
2009-11-02  7:41           ` Jason Rumney
2009-11-02 14:10             ` Stefan Monnier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=wlmy2vp9xq.wl%mituharu@math.s.chiba-u.ac.jp \
    --to=mituharu@math.s.chiba-u.ac.jp \
    --cc=emacs-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.