From: Po Lu Date: Fri, 11 Mar 2022 01:33:24 +0000 (+0000) Subject: Fix scroll bar portion on Haiku scroll bars X-Git-Tag: emacs-29.0.90~1931^2~1203 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=170cae0e9080697e1efa1678bc1504890bcf4a6e;p=emacs.git Fix scroll bar portion on Haiku scroll bars * 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): --- diff --git a/src/haiku_support.cc b/src/haiku_support.cc index 2f2adfd8f8a..6f5196dc1ce 100644 --- a/src/haiku_support.cc +++ b/src/haiku_support.cc @@ -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); } diff --git a/src/haiku_support.h b/src/haiku_support.h index fb86372c4ff..e7c55d4d758 100644 --- a/src/haiku_support.h +++ b/src/haiku_support.h @@ -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); diff --git a/src/haikuterm.c b/src/haikuterm.c index d3168129ce4..b100952f111 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -40,6 +40,9 @@ along with GNU Emacs. If not, see . */ #include #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; diff --git a/src/haikuterm.h b/src/haikuterm.h index a2520858f54..64fd0ec2b71 100644 --- a/src/haikuterm.h +++ b/src/haikuterm.h @@ -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))