]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix scroll bar portion on Haiku scroll bars
authorPo Lu <luangruo@yahoo.com>
Fri, 11 Mar 2022 01:33:24 +0000 (01:33 +0000)
committerPo Lu <luangruo@yahoo.com>
Fri, 11 Mar 2022 01:33:24 +0000 (01:33 +0000)
* src/haiku_support.cc (EmacsScrollBar): Set steps to
appropriate value.
(ValueChanged): Test new value against old value before sending
value event.
(MessageReceived): Handle portion and range.
(BView_scroll_bar_update): New argument for portion.
* src/haiku_support.h: Update prototypes.
* src/haikuterm.c (haiku_set_scroll_bar_thumb):
(haiku_set_horizontal_scroll_bar_thumb): New functions.
(haiku_set_horizontal_scroll_bar):
(haiku_set_vertical_scroll_bar): Use those functions to set
scroll bar values.
(haiku_read_socket): Handle new meanings of scroll bar values.
* src/haikuterm.h (struct scroll_bar):

src/haiku_support.cc
src/haiku_support.h
src/haikuterm.c
src/haikuterm.h

index 2f2adfd8f8a003a39c23840b89f95c4eda4f199d..6f5196dc1ceb64094295b653087924c77ab00ddf 100644 (file)
@@ -1571,16 +1571,26 @@ public:
     vw->SetResizingMode (B_FOLLOW_NONE);
     horizontal = horizontal_p;
     get_scroll_bar_info (&info);
+    SetSteps (5000, 10000);
   }
 
   void
   MessageReceived (BMessage *msg)
   {
+    int32 portion, range;
+
     if (msg->what == SCROLL_BAR_UPDATE)
       {
        old_value = msg->GetInt32 ("emacs:units", 0);
-       this->SetRange (0, msg->GetInt32 ("emacs:range", 0));
-       this->SetValue (msg->GetInt32 ("emacs:units", 0));
+       portion = msg->GetInt32 ("emacs:portion", 0);
+       range = msg->GetInt32 ("emacs:range", 0);
+
+       if (!msg->GetBool ("emacs:dragging", false))
+         {
+           this->SetRange (0, range);
+           this->SetValue (old_value);
+           this->SetProportion ((float) portion / range);
+         }
       }
 
     BScrollBar::MessageReceived (msg);
@@ -1612,11 +1622,15 @@ public:
        return;
       }
 
-    rq.scroll_bar = this;
-    rq.window = Window ();
-    rq.position = new_value;
+    if (new_value != old_value)
+      {
+       rq.scroll_bar = this;
+       rq.window = Window ();
+       rq.position = new_value;
+       old_value = new_value;
 
-    haiku_write (SCROLL_BAR_VALUE_EVENT, &rq);
+       haiku_write (SCROLL_BAR_VALUE_EVENT, &rq);
+      }
   }
 
   BRegion
@@ -2269,13 +2283,16 @@ BView_move_frame (void *view, int x, int y, int x1, int y1)
 }
 
 void
-BView_scroll_bar_update (void *sb, int portion, int whole, int position)
+BView_scroll_bar_update (void *sb, int portion, int whole, int position,
+                        bool dragging)
 {
   BScrollBar *bar = (BScrollBar *) sb;
   BMessage msg = BMessage (SCROLL_BAR_UPDATE);
   BMessenger mr = BMessenger (bar);
   msg.AddInt32 ("emacs:range", whole);
   msg.AddInt32 ("emacs:units", position);
+  msg.AddInt32 ("emacs:portion", portion);
+  msg.AddBool ("emacs:dragging", dragging);
 
   mr.SendMessage (&msg);
 }
index fb86372c4ff2366872ea3ca3659fa0da2537de2a..e7c55d4d75896946701f73953be9a706864fb34f 100644 (file)
@@ -628,7 +628,8 @@ extern "C"
   BView_move_frame (void *view, int x, int y, int x1, int y1);
 
   extern void
-  BView_scroll_bar_update (void *sb, int portion, int whole, int position);
+  BView_scroll_bar_update (void *sb, int portion, int whole, int position,
+                          bool dragging);
 
   extern int
   BScrollBar_default_size (int horizontal_p);
index d3168129ce4ee93a79d0f385131bd92cd3a75ee9..b100952f111de5bad66e552d7ace874bc47a0276 100644 (file)
@@ -40,6 +40,9 @@ along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
 #include <cairo.h>
 #endif
 
+/* Minimum and maximum values used for Haiku scroll bars.  */
+#define BE_SB_MAX 10000000
+
 struct haiku_display_info *x_display_list = NULL;
 extern frame_parm_handler haiku_frame_parm_handlers[];
 
@@ -428,6 +431,78 @@ haiku_mouse_or_wdesc_frame (void *window)
     }
 }
 
+/* Set the thumb size and position of scroll bar BAR.  We are
+   currently displaying PORTION out of a whole WHOLE, and our position
+   POSITION.  */
+
+static void
+haiku_set_scroll_bar_thumb (struct scroll_bar *bar, int portion,
+                           int position, int whole)
+{
+  void *scroll_bar = bar->scroll_bar;
+  float top, shown;
+  int size, value;
+
+  if (scroll_bar_adjust_thumb_portion_p)
+    {
+      /* 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.  */
+      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
+    {
+      top = (float) position / whole;
+      shown = (float) portion / whole;
+    }
+
+  /* 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 = clip_to_bounds (1, shown * BE_SB_MAX, BE_SB_MAX);
+
+  /* Position.  Must be in the range [MIN .. MAX - SLIDER_SIZE].  */
+  value = top * BE_SB_MAX;
+  value = min (value, BE_SB_MAX - size);
+
+  if (!bar->dragging)
+    bar->page_size = size;
+
+  BView_scroll_bar_update (scroll_bar, size, BE_SB_MAX, value,
+                          bar->dragging);
+}
+
+static void
+haiku_set_horizontal_scroll_bar_thumb (struct scroll_bar *bar, int portion,
+                                      int position, int whole)
+{
+  void *scroll_bar = bar->scroll_bar;
+  float shown, top;
+  int size, value;
+
+  shown = (float) portion / whole;
+  top = (float) position / (whole - portion);
+
+  size = clip_to_bounds (1, shown * BE_SB_MAX, BE_SB_MAX);
+  value = clip_to_bounds (0, top * (BE_SB_MAX - size), BE_SB_MAX - size);
+
+  if (!bar->dragging)
+    bar->page_size = size;
+
+  BView_scroll_bar_update (scroll_bar, shown, BE_SB_MAX, value,
+                          bar->dragging);
+}
+
 static struct scroll_bar *
 haiku_scroll_bar_from_widget (void *scroll_bar, void *window)
 {
@@ -2211,7 +2286,6 @@ haiku_set_horizontal_scroll_bar (struct window *w, int portion, int whole, int p
   if (NILP (w->horizontal_scroll_bar))
     {
       bar = haiku_scroll_bar_create (w, left, top, width, height, true);
-      BView_scroll_bar_update (bar->scroll_bar, portion, whole, position);
       bar->update = position;
       bar->position = position;
       bar->total = whole;
@@ -2234,13 +2308,9 @@ haiku_set_horizontal_scroll_bar (struct window *w, int portion, int whole, int p
          bar->width = width;
          bar->height = height;
        }
-
-      if (!bar->dragging)
-       {
-         BView_scroll_bar_update (bar->scroll_bar, portion, whole, position);
-         BView_invalidate (bar->scroll_bar);
-       }
     }
+
+  haiku_set_horizontal_scroll_bar_thumb (bar, portion, position, whole);
   bar->position = position;
   bar->total = whole;
   XSETVECTOR (barobj, bar);
@@ -2271,7 +2341,6 @@ haiku_set_vertical_scroll_bar (struct window *w,
   if (NILP (w->vertical_scroll_bar))
     {
       bar = haiku_scroll_bar_create (w, left, top, width, height, false);
-      BView_scroll_bar_update (bar->scroll_bar, portion, whole, position);
       bar->position = position;
       bar->total = whole;
     }
@@ -2293,15 +2362,9 @@ haiku_set_vertical_scroll_bar (struct window *w,
          bar->width = width;
          bar->height = height;
        }
-
-      if (!bar->dragging)
-       {
-         BView_scroll_bar_update (bar->scroll_bar, portion, whole, position);
-         bar->update = position;
-         BView_invalidate (bar->scroll_bar);
-       }
     }
 
+  haiku_set_scroll_bar_thumb (bar, portion, position, whole);
   bar->position = position;
   bar->total = whole;
 
@@ -3191,6 +3254,7 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
            struct haiku_scroll_bar_value_event *b = buf;
            struct scroll_bar *bar
              = haiku_scroll_bar_from_widget (b->scroll_bar, b->window);
+           int portion, whole;
 
            if (!bar)
              continue;
@@ -3205,13 +3269,29 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
 
            if (bar->position != b->position)
              {
-               inev.kind = bar->horizontal ? HORIZONTAL_SCROLL_BAR_CLICK_EVENT :
-                 SCROLL_BAR_CLICK_EVENT;
+               inev.kind = (bar->horizontal
+                            ? HORIZONTAL_SCROLL_BAR_CLICK_EVENT :
+                            SCROLL_BAR_CLICK_EVENT);
                inev.part = bar->horizontal ?
                  scroll_bar_horizontal_handle : scroll_bar_handle;
 
-               XSETINT (inev.x, b->position);
-               XSETINT (inev.y, bar->total);
+               if (bar->horizontal)
+                 {
+                   portion = bar->total * ((float) b->position
+                                           / BE_SB_MAX);
+                   whole = (bar->total
+                            * ((float) (BE_SB_MAX - bar->page_size)
+                               / BE_SB_MAX));
+                   portion = min (portion, whole);
+                 }
+               else
+                 {
+                   whole = BE_SB_MAX - bar->page_size;
+                   portion = min (b->position, whole);
+                 }
+
+               XSETINT (inev.x, portion);
+               XSETINT (inev.y, whole);
                XSETWINDOW (inev.frame_or_window, w);
              }
            break;
index a2520858f54493855c00982f8b48afa646061a79..64fd0ec2b71854aed87fec02c13ebc56ad7a9e59 100644 (file)
@@ -213,6 +213,8 @@ struct scroll_bar
 
   /* True if the scroll bar is horizontal.  */
   bool horizontal;
+
+  int page_size;
 };
 
 #define XSCROLL_BAR(vec) ((struct scroll_bar *) XVECTOR (vec))