From 6263f586b87a952e00103a82af1dd0360c1a238d Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sun, 12 Jun 2022 13:04:19 +0000 Subject: [PATCH] Fix handling of scroll bar clicks on Haiku * src/haiku_support.cc (class EmacsView, BasicMouseDown) (BasicMouseUp): Move MouseDown and MouseUp here. New parameter `scroll_bar'. (MouseDown, MouseUp): Call basic variants. (class EmacsScrollBar): New field `parent'. (BScrollBar_make_for_view): Rename to `be_create_scroll_bar_for_view'. * src/haiku_support.h (struct haiku_button_event): New field `scroll_bar'. * src/haikuterm.c (haiku_scroll_bar_from_widget): Handle NULL widget. (haiku_scroll_bar_create): Update calls. (haiku_mouse_position): Fix scroll bar part. (haiku_read_socket): Handle button events on scroll bars as scroll bar click events. --- src/haiku_support.cc | 69 ++++++++++++++++++++++++++----------------- src/haiku_support.h | 3 +- src/haikuterm.c | 70 ++++++++++++++++++++++++++++++++------------ 3 files changed, 96 insertions(+), 46 deletions(-) diff --git a/src/haiku_support.cc b/src/haiku_support.cc index bc82069789b..182f2128473 100644 --- a/src/haiku_support.cc +++ b/src/haiku_support.cc @@ -1826,10 +1826,10 @@ public: } void - MouseDown (BPoint point) + BasicMouseDown (BPoint point, BView *scroll_bar) { struct haiku_button_event rq; - uint32 buttons; + uint32 mods, buttons; this->GetMouse (&point, &buttons, false); @@ -1840,6 +1840,7 @@ public: grab_view_locker.Unlock (); rq.window = this->Window (); + rq.scroll_bar = scroll_bar; if (!(previous_buttons & B_PRIMARY_MOUSE_BUTTON) && (buttons & B_PRIMARY_MOUSE_BUTTON)) @@ -1858,7 +1859,7 @@ public: rq.x = point.x; rq.y = point.y; - uint32_t mods = modifiers (); + mods = modifiers (); rq.modifiers = 0; if (mods & B_SHIFT_KEY) @@ -1873,18 +1874,25 @@ public: if (mods & B_OPTION_KEY) rq.modifiers |= HAIKU_MODIFIER_SUPER; - SetMouseEventMask (B_POINTER_EVENTS, (B_LOCK_WINDOW_FOCUS - | B_NO_POINTER_HISTORY)); + if (!scroll_bar) + SetMouseEventMask (B_POINTER_EVENTS, (B_LOCK_WINDOW_FOCUS + | B_NO_POINTER_HISTORY)); rq.time = system_time (); haiku_write (BUTTON_DOWN, &rq); } void - MouseUp (BPoint point) + MouseDown (BPoint point) + { + BasicMouseDown (point, NULL); + } + + void + BasicMouseUp (BPoint point, BView *scroll_bar) { struct haiku_button_event rq; - uint32 buttons; + uint32 buttons, mods; this->GetMouse (&point, &buttons, false); @@ -1905,6 +1913,7 @@ public: } rq.window = this->Window (); + rq.scroll_bar = scroll_bar; if ((previous_buttons & B_PRIMARY_MOUSE_BUTTON) && !(buttons & B_PRIMARY_MOUSE_BUTTON)) @@ -1923,7 +1932,7 @@ public: rq.x = point.x; rq.y = point.y; - uint32_t mods = modifiers (); + mods = modifiers (); rq.modifiers = 0; if (mods & B_SHIFT_KEY) @@ -1938,12 +1947,15 @@ public: if (mods & B_OPTION_KEY) rq.modifiers |= HAIKU_MODIFIER_SUPER; - if (!buttons) - SetMouseEventMask (0, 0); - rq.time = system_time (); haiku_write (BUTTON_UP, &rq); } + + void + MouseUp (BPoint point) + { + BasicMouseUp (point, NULL); + } }; class EmacsScrollBar : public BScrollBar @@ -1965,15 +1977,18 @@ public: int max_value, real_max_value; int overscroll_start_value; bigtime_t repeater_start; + EmacsView *parent; - EmacsScrollBar (int x, int y, int x1, int y1, bool horizontal_p) + EmacsScrollBar (int x, int y, int x1, int y1, bool horizontal_p, + EmacsView *parent) : BScrollBar (BRect (x, y, x1, y1), NULL, NULL, 0, 0, horizontal_p ? B_HORIZONTAL : B_VERTICAL), dragging (0), handle_button (false), in_overscroll (false), can_overscroll (false), - maybe_overscroll (false) + maybe_overscroll (false), + parent (parent) { BView *vw = (BView *) this; vw->SetResizingMode (B_FOLLOW_NONE); @@ -2174,7 +2189,6 @@ public: BLooper *looper; BMessage *message; int32 buttons, mods; - BView *parent; looper = Looper (); message = NULL; @@ -2195,8 +2209,9 @@ public: { /* Allow C-mouse-3 to split the window on a scroll bar. */ handle_button = true; - parent = Parent (); - parent->MouseDown (ConvertToParent (pt)); + SetMouseEventMask (B_POINTER_EVENTS, (B_SUSPEND_VIEW_FOCUS + | B_LOCK_WINDOW_FOCUS)); + parent->BasicMouseDown (ConvertToParent (pt), this); return; } @@ -2259,7 +2274,6 @@ public: MouseUp (BPoint pt) { struct haiku_scroll_bar_drag_event rq; - BView *parent; in_overscroll = false; maybe_overscroll = false; @@ -2267,8 +2281,7 @@ public: if (handle_button) { handle_button = false; - parent = Parent (); - parent->MouseUp (ConvertToParent (pt)); + parent->BasicMouseUp (ConvertToParent (pt), this); return; } @@ -3509,20 +3522,22 @@ BWindow_Flush (void *window) /* Make a scrollbar, attach it to VIEW's window, and return it. */ void * -BScrollBar_make_for_view (void *view, int horizontal_p, - int x, int y, int x1, int y1, - void *scroll_bar_ptr) +be_make_scroll_bar_for_view (void *view, int horizontal_p, + int x, int y, int x1, int y1) { - EmacsScrollBar *sb = new EmacsScrollBar (x, y, x1, y1, horizontal_p); + EmacsScrollBar *scroll_bar; BView *vw = (BView *) view; - BView *sv = (BView *) sb; if (!vw->LockLooper ()) gui_abort ("Failed to lock scrollbar owner"); - vw->AddChild ((BView *) sb); - sv->WindowActivated (vw->Window ()->IsActive ()); + + scroll_bar = new EmacsScrollBar (x, y, x1, y1, horizontal_p, + (EmacsView *) vw); + + vw->AddChild (scroll_bar); vw->UnlockLooper (); - return sb; + + return scroll_bar; } void diff --git a/src/haiku_support.h b/src/haiku_support.h index a2ad222f85a..7f8d471b650 100644 --- a/src/haiku_support.h +++ b/src/haiku_support.h @@ -209,6 +209,7 @@ struct haiku_menu_bar_click_event struct haiku_button_event { void *window; + void *scroll_bar; int btn_no; int modifiers; int x; @@ -575,7 +576,7 @@ extern void *be_create_cursor_from_id (int); extern void *be_create_pixmap_cursor (void *, int, int); extern void be_delete_cursor (void *); -extern void *BScrollBar_make_for_view (void *, int, int, int, int, int, void *); +extern void *be_make_scroll_bar_for_view (void *, int, int, int, int, int); extern void BScrollBar_delete (void *); extern int BScrollBar_default_size (int); diff --git a/src/haikuterm.c b/src/haikuterm.c index 55d6a9be273..365b23cd92c 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -516,6 +516,9 @@ haiku_scroll_bar_from_widget (void *scroll_bar, void *window) if (!frame) return NULL; + if (!scroll_bar) + return NULL; + if (!NILP (FRAME_SCROLL_BARS (frame))) { for (tem = FRAME_SCROLL_BARS (frame); !NILP (tem); @@ -2527,9 +2530,9 @@ haiku_scroll_bar_create (struct window *w, int left, int top, bar->update = -1; bar->horizontal = horizontal_p; - scroll_bar = BScrollBar_make_for_view (view, horizontal_p, - left, top, left + width - 1, - top + height - 1, bar); + scroll_bar = be_make_scroll_bar_for_view (view, horizontal_p, + left, top, left + width - 1, + top + height - 1); BView_publish_scroll_bar (view, left, top, width, height); bar->next = FRAME_SCROLL_BARS (f); @@ -2884,7 +2887,7 @@ haiku_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window, x_display_list->last_mouse_glyph_frame = f1; *bar_window = Qnil; - *part = scroll_bar_above_handle; + *part = scroll_bar_nowhere; /* If track-mouse is `drag-source' and the mouse pointer is certain to not be actually under the chosen frame, return @@ -3471,13 +3474,13 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit) Lisp_Object tab_bar_arg = Qnil; int tab_bar_p = 0, tool_bar_p = 0; bool up_okay_p = false; + struct scroll_bar *bar; if (popup_activated_p || !f) continue; - struct haiku_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); - inev.modifiers = haiku_modifiers_to_emacs (b->modifiers); + bar = haiku_scroll_bar_from_widget (b->scroll_bar, b->window); x_display_list->last_mouse_glyph_frame = 0; x_display_list->last_mouse_movement_time = b->time / 1000; @@ -3525,34 +3528,64 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit) if (type == BUTTON_UP) { inev.modifiers |= up_modifier; - up_okay_p = (dpyinfo->grabbed & (1 << b->btn_no)); - dpyinfo->grabbed &= ~(1 << b->btn_no); + up_okay_p = (x_display_list->grabbed & (1 << b->btn_no)); + x_display_list->grabbed &= ~(1 << b->btn_no); } else { up_okay_p = true; inev.modifiers |= down_modifier; - dpyinfo->last_mouse_frame = f; - dpyinfo->grabbed |= (1 << b->btn_no); + x_display_list->last_mouse_frame = f; + x_display_list->grabbed |= (1 << b->btn_no); if (f && !tab_bar_p) f->last_tab_bar_item = -1; if (f && !tool_bar_p) f->last_tool_bar_item = -1; } - if (up_okay_p - && !(tab_bar_p && NILP (tab_bar_arg)) - && !tool_bar_p) + if (bar) + { + inev.kind = (bar->horizontal + ? HORIZONTAL_SCROLL_BAR_CLICK_EVENT + : SCROLL_BAR_CLICK_EVENT); + inev.part = (bar->horizontal + ? scroll_bar_horizontal_handle + : scroll_bar_handle); + } + else if (up_okay_p + && !(tab_bar_p && NILP (tab_bar_arg)) + && !tool_bar_p) inev.kind = MOUSE_CLICK_EVENT; + inev.arg = tab_bar_arg; inev.code = b->btn_no; f->mouse_moved = false; - XSETINT (inev.x, b->x); - XSETINT (inev.y, b->y); + if (bar) + { + if (bar->horizontal) + { + XSETINT (inev.x, min (max (0, b->x - bar->left), + bar->width)); + XSETINT (inev.y, bar->width); + } + else + { + XSETINT (inev.x, min (max (0, b->y - bar->top), + bar->height)); + XSETINT (inev.y, bar->height); + } + + inev.frame_or_window = bar->window; + } + else + { + XSETINT (inev.x, b->x); + XSETINT (inev.y, b->y); + XSETFRAME (inev.frame_or_window, f); + } - XSETFRAME (inev.frame_or_window, f); break; } case ICONIFICATION: @@ -3652,8 +3685,9 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit) inev.kind = (bar->horizontal ? HORIZONTAL_SCROLL_BAR_CLICK_EVENT : SCROLL_BAR_CLICK_EVENT); - inev.part = bar->horizontal ? - scroll_bar_horizontal_handle : scroll_bar_handle; + inev.part = (bar->horizontal + ? scroll_bar_horizontal_handle + : scroll_bar_handle); if (bar->horizontal) { -- 2.39.2