From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Alan Third Newsgroups: gmane.emacs.bugs Subject: bug#22660: [PATCH v2] Implement horizontal scroll-bars in NS port Date: Sat, 30 Apr 2016 21:53:35 +0100 Message-ID: <20160430205335.GA79254@breton.local> References: <20160430153518.GA53154@breton.local> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1462049684 4997 80.91.229.3 (30 Apr 2016 20:54:44 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sat, 30 Apr 2016 20:54:44 +0000 (UTC) Cc: 22660@debbugs.gnu.org To: martin rudalics Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Sat Apr 30 22:54:34 2016 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1awbuL-0004ea-RR for geb-bug-gnu-emacs@m.gmane.org; Sat, 30 Apr 2016 22:54:34 +0200 Original-Received: from localhost ([::1]:59612 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1awbuI-0002A4-2o for geb-bug-gnu-emacs@m.gmane.org; Sat, 30 Apr 2016 16:54:30 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:44191) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1awbu6-0001u6-W0 for bug-gnu-emacs@gnu.org; Sat, 30 Apr 2016 16:54:26 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1awbtu-0004NN-4I for bug-gnu-emacs@gnu.org; Sat, 30 Apr 2016 16:54:13 -0400 Original-Received: from debbugs.gnu.org ([208.118.235.43]:46226) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1awbts-0004MC-TQ for bug-gnu-emacs@gnu.org; Sat, 30 Apr 2016 16:54:06 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1awbtp-00086O-Qx for bug-gnu-emacs@gnu.org; Sat, 30 Apr 2016 16:54:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Alan Third Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 30 Apr 2016 20:54:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 22660 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 22660-submit@debbugs.gnu.org id=B22660.146204962631124 (code B ref 22660); Sat, 30 Apr 2016 20:54:01 +0000 Original-Received: (at 22660) by debbugs.gnu.org; 30 Apr 2016 20:53:46 +0000 Original-Received: from localhost ([127.0.0.1]:58563 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1awbta-00085u-87 for submit@debbugs.gnu.org; Sat, 30 Apr 2016 16:53:46 -0400 Original-Received: from mail-wm0-f67.google.com ([74.125.82.67]:35505) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1awbtY-00085h-2s for 22660@debbugs.gnu.org; Sat, 30 Apr 2016 16:53:45 -0400 Original-Received: by mail-wm0-f67.google.com with SMTP id e201so11338679wme.2 for <22660@debbugs.gnu.org>; Sat, 30 Apr 2016 13:53:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20120113; h=sender:date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=9KrbqrStj4n9fa4UFHfwyTCLT6m3RKg3ZyrF/N+QmV4=; b=GMgKq8hxXADiHJWdfbfHSr0fl8eIquiOXebp+pG6Ru31z7xS/nffTpuCV2uu1u1UMa 6febwcvCVRAYG7EFhqz8XeUKDNuHjMX0m6+ulGyKaBhhjWZFie4qTVzfx4ZaGiIWBSxk Gp29aYczfFoM7ZNRFv//2vmXeJTVqU4mRgaVfuEld/XLAUEaB/1XwgsFQh9Vc9AgwAKT F6n0R0+HQ7QmIqbo8bOmWbsRPgn/uwvf1P1bGMS8Zah3mUgVjSMDULTfSvpYnqt6/MUB 4SRfGKT5hlsdCt8oKN709aDangZV4C+NZ1rczHNQAhgn62MEMX1i72Hpg6yKPYMoFBTl gfjQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:date:from:to:cc:subject:message-id :references:mime-version:content-disposition:in-reply-to:user-agent; bh=9KrbqrStj4n9fa4UFHfwyTCLT6m3RKg3ZyrF/N+QmV4=; b=KkmMeoWXn4dFkH32GatHK2OiHWDMrh3K8w9uRzmCMx0mfn7186yul53nuIvaEKCtAb U09dJbHVGqodz4tbWBJvNx80zCoSmJuHiE6Nj3uExMCQJHuPuHFaKqqtfNg5QBMAl/qS pPucatBd1hEtdAazi9febSRGGHjcJJXIIIxmaqcrAD210bE2RJ8Tft2BzhS0fRX7AJPV PqYsGUZaIj2ilWWCGSCDeaXQQdULm8HF+2x3gvijXw1DJ/onFRZeNeQzrw5JRAGbR3VG y2nOJVEsjmUCHHilNVEjhVt1na6LfcCKLf9pqdo4shb+GXEYR51BT20i4kvKY//0T/wt ZvaQ== X-Gm-Message-State: AOPr4FWG+Kqkg2uRvbS4IDLlsW/LGUbX1SQmkyg4W8dhJ8CvJ09E+mOL02D6/auY5aGtNA== X-Received: by 10.194.221.37 with SMTP id qb5mr27954146wjc.171.1462049618361; Sat, 30 Apr 2016 13:53:38 -0700 (PDT) Original-Received: from breton.local (ip6-2001-08b0-03f8-8129-4cff-dbe8-a261-f149.holly.idiocy.org. [2001:8b0:3f8:8129:4cff:dbe8:a261:f149]) by smtp.gmail.com with ESMTPSA id k133sm10099845wmg.7.2016.04.30.13.53.37 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 30 Apr 2016 13:53:37 -0700 (PDT) Content-Disposition: inline In-Reply-To: <20160430153518.GA53154@breton.local> User-Agent: Mutt/1.5.24 (2015-08-30) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:117449 Archived-At: * lisp/scroll-bar.el (horizontal-scroll-bars-available-p): Remove NS check. * lisp/term/ns-win.el: Remove custom NS scroll-bar handlers and bind scroll-bar mouse clicks to standard handlers. * src/nsterm.h (EmacsScroller): Add 'horizontal' property and rename pixel_height to pixel_length. * src/nsterm.m (x_set_window_size): Remove left-hand scroll-bar code. It caused scroll-bars to be over-drawn and the best working solution appears to be complete removal. (ns_set_horizontal_scroll_bar): Rewrite to handle horizontal scrollers correctly. (ns_set_vertical_scroll_bar): Set width to actual scroller width. (setFrame): Handle horizontal case. (dealloc): Handle horizontal case. (judge): Handle horizontal case. (setPosition): Rename pixel_height to pixel_length. (sendScrollEventAtLoc): Handle horizontal case. (mouseDown): Handle horizontal case and general tidy up of code. (mouseDragged): Handle horizontal case. Call sendScrollEventAtLoc with absolute pixel size instead of ratio. * src/window.h: Remove NS check. --- lisp/scroll-bar.el | 3 +- lisp/term/ns-win.el | 56 ++------------- src/nsterm.h | 4 +- src/nsterm.m | 201 +++++++++++++++++++++++++++++----------------------- src/window.h | 2 +- 5 files changed, 123 insertions(+), 143 deletions(-) diff --git a/lisp/scroll-bar.el b/lisp/scroll-bar.el index 5cfa2c4..838f9bf 100644 --- a/lisp/scroll-bar.el +++ b/lisp/scroll-bar.el @@ -148,8 +148,7 @@ horizontal-scroll-bars-available-p "Return non-nil when horizontal scroll bars are available on this system." (and (display-graphic-p) (boundp 'x-toolkit-scroll-bars) - x-toolkit-scroll-bars - (not (eq (window-system) 'ns)))) + x-toolkit-scroll-bars)) (define-minor-mode horizontal-scroll-bar-mode "Toggle horizontal scroll bars on all frames (Horizontal Scroll Bar mode). diff --git a/lisp/term/ns-win.el b/lisp/term/ns-win.el index e737131..8b676ce 100644 --- a/lisp/term/ns-win.el +++ b/lisp/term/ns-win.el @@ -717,60 +717,12 @@ ns-paste-secondary ;;;; Scrollbar handling. -(global-set-key [vertical-scroll-bar down-mouse-1] 'ns-handle-scroll-bar-event) +(global-set-key [vertical-scroll-bar down-mouse-1] 'scroll-bar-toolkit-scroll) +(global-set-key [horizontal-scroll-bar down-mouse-1] 'scroll-bar-toolkit-horizontal-scroll) (global-unset-key [vertical-scroll-bar mouse-1]) (global-unset-key [vertical-scroll-bar drag-mouse-1]) - -(declare-function scroll-bar-scale "scroll-bar" (num-denom whole)) - -(defun ns-scroll-bar-move (event) - "Scroll the frame according to a Nextstep scroller event." - (interactive "e") - (let* ((pos (event-end event)) - (window (nth 0 pos)) - (scale (nth 2 pos))) - (with-current-buffer (window-buffer window) - (cond - ((eq (car scale) (cdr scale)) - (goto-char (point-max))) - ((= (car scale) 0) - (goto-char (point-min))) - (t - (goto-char (+ (point-min) 1 - (scroll-bar-scale scale (- (point-max) (point-min))))))) - (beginning-of-line) - (set-window-start window (point)) - (vertical-motion (/ (window-height window) 2) window)))) - -(defun ns-handle-scroll-bar-event (event) - "Handle scroll bar EVENT to emulate Nextstep style scrolling." - (interactive "e") - (let* ((position (event-start event)) - (bar-part (nth 4 position)) - (window (nth 0 position)) - (old-window (selected-window))) - (cond - ((eq bar-part 'ratio) - (ns-scroll-bar-move event)) - ((eq bar-part 'handle) - (if (eq window (selected-window)) - (track-mouse (ns-scroll-bar-move event)) - ;; track-mouse faster for selected window, slower for unselected. - (ns-scroll-bar-move event))) - (t - (select-window window) - (cond - ((eq bar-part 'up) - (goto-char (window-start window)) - (scroll-down 1)) - ((eq bar-part 'above-handle) - (scroll-down)) - ((eq bar-part 'below-handle) - (scroll-up)) - ((eq bar-part 'down) - (goto-char (window-start window)) - (scroll-up 1))) - (select-window old-window))))) +(global-unset-key [horizontal-scroll-bar mouse-1]) +(global-unset-key [horizontal-scroll-bar drag-mouse-1]) ;;;; Color support. diff --git a/src/nsterm.h b/src/nsterm.h index 0aea9cc..6cad337 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -676,11 +676,13 @@ char const * nstrace_fullscreen_type_name (int); /* offset to the bottom of knob of last mouse down */ CGFloat last_mouse_offset; float min_portion; - int pixel_height; + int pixel_length; enum scroll_bar_part last_hit_part; BOOL condemned; + BOOL horizontal; + /* optimize against excessive positioning calls generated by emacs */ int em_position; int em_portion; diff --git a/src/nsterm.m b/src/nsterm.m index 34c5395..1d48c04 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -1801,23 +1801,6 @@ x_set_window_size (struct frame *f, [window setFrame: wr display: YES]; - /* This is a trick to compensate for Emacs' managing the scrollbar area - as a fixed number of standard character columns. Instead of leaving - blank space for the extra, we chopped it off above. Now for - left-hand scrollbars, we shift all rendering to the left by the - difference between the real width and Emacs' imagined one. For - right-hand bars, don't worry about it since the extra is never used. - (Obviously doesn't work for vertically split windows tho..) */ - { - NSPoint origin = FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f) - ? NSMakePoint (FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f) - - NS_SCROLL_BAR_WIDTH (f), 0) - : NSMakePoint (0, 0); - - [view setFrame: NSMakeRect (0, 0, pixelwidth, pixelheight)]; - [view setBoundsOrigin: origin]; - } - [view updateFrameSize: NO]; unblock_input (); } @@ -4351,7 +4334,7 @@ ns_set_vertical_scroll_bar (struct window *window, window_box (window, ANY_AREA, 0, &window_y, 0, &window_height); top = window_y; height = window_height; - width = WINDOW_CONFIG_SCROLL_BAR_COLS (window) * FRAME_COLUMN_WIDTH (f); + width = NS_SCROLL_BAR_WIDTH (f); left = WINDOW_SCROLL_BAR_AREA_X (window); r = NSMakeRect (left, top, width, height); @@ -4442,34 +4425,20 @@ ns_set_horizontal_scroll_bar (struct window *window, NSTRACE ("ns_set_horizontal_scroll_bar"); /* Get dimensions. */ - window_box (window, ANY_AREA, 0, &window_x, &window_width, 0); + window_box (window, ANY_AREA, &window_x, 0, &window_width, 0); left = window_x; width = window_width; - height = WINDOW_CONFIG_SCROLL_BAR_LINES (window) * FRAME_LINE_HEIGHT (f); + height = NS_SCROLL_BAR_HEIGHT (f); top = WINDOW_SCROLL_BAR_AREA_Y (window); r = NSMakeRect (left, top, width, height); /* the parent view is flipped, so we need to flip y value */ v = [view frame]; - /* ??????? PXW/scrollbars !!!!!!!!!!!!!!!!!!!! */ r.origin.y = (v.size.height - r.size.height - r.origin.y); XSETWINDOW (win, window); block_input (); - if (WINDOW_TOTAL_COLS (window) < 5) - { - if (!NILP (window->horizontal_scroll_bar)) - { - bar = XNS_SCROLL_BAR (window->horizontal_scroll_bar); - [bar removeFromSuperview]; - wset_horizontal_scroll_bar (window, Qnil); - } - ns_clear_frame_area (f, left, top, width, height); - unblock_input (); - return; - } - if (NILP (window->horizontal_scroll_bar)) { if (width > 0 && height > 0) @@ -4484,16 +4453,22 @@ ns_set_horizontal_scroll_bar (struct window *window, NSRect oldRect; bar = XNS_SCROLL_BAR (window->horizontal_scroll_bar); oldRect = [bar frame]; - r.size.width = oldRect.size.width; if (FRAME_LIVE_P (f) && !NSEqualRects (oldRect, r)) { - if (oldRect.origin.x != r.origin.x) - ns_clear_frame_area (f, left, top, width, height); + if (oldRect.origin.y != r.origin.y) + ns_clear_frame_area (f, left, top, width, height); [bar setFrame: r]; update_p = YES; } } + /* If there are both horizontal and vertical scroll-bars they leave + a square that belongs to neither. We need to clear it otherwise + it fills with junk. */ + if (!NILP (window->vertical_scroll_bar)) + ns_clear_frame_area (f, WINDOW_SCROLL_BAR_AREA_X (window), top, + NS_SCROLL_BAR_HEIGHT (f), height); + if (update_p) [bar setPosition: position portion: portion whole: whole]; unblock_input (); @@ -4531,13 +4506,15 @@ ns_redeem_scroll_bar (struct window *window) { id bar; NSTRACE ("ns_redeem_scroll_bar"); - if (!NILP (window->vertical_scroll_bar)) + if (!NILP (window->vertical_scroll_bar) + && WINDOW_HAS_VERTICAL_SCROLL_BAR (window)) { bar = XNS_SCROLL_BAR (window->vertical_scroll_bar); [bar reprieve]; } - if (!NILP (window->horizontal_scroll_bar)) + if (!NILP (window->horizontal_scroll_bar) + && WINDOW_HAS_HORIZONTAL_SCROLL_BAR (window)) { bar = XNS_SCROLL_BAR (window->horizontal_scroll_bar); [bar reprieve]; @@ -8110,12 +8087,15 @@ not_in_argv (NSString *arg) return r; } - - initFrame: (NSRect )r window: (Lisp_Object)nwin { NSTRACE ("[EmacsScroller initFrame: window:]"); - r.size.width = [EmacsScroller scrollerWidth]; + if (r.size.width > r.size.height) + horizontal = YES; + else + horizontal = NO; + [super initWithFrame: r/*NSMakeRect (0, 0, 0, 0)*/]; [self setContinuous: YES]; [self setEnabled: YES]; @@ -8131,9 +8111,12 @@ not_in_argv (NSString *arg) window = XWINDOW (nwin); condemned = NO; - pixel_height = NSHeight (r); - if (pixel_height == 0) pixel_height = 1; - min_portion = 20 / pixel_height; + if (horizontal) + pixel_length = NSWidth (r); + else + pixel_length = NSHeight (r); + if (pixel_length == 0) pixel_length = 1; + min_portion = 20 / pixel_length; frame = XFRAME (window->frame); if (FRAME_LIVE_P (frame)) @@ -8162,9 +8145,12 @@ not_in_argv (NSString *arg) NSTRACE ("[EmacsScroller setFrame:]"); /* block_input (); */ - pixel_height = NSHeight (newRect); - if (pixel_height == 0) pixel_height = 1; - min_portion = 20 / pixel_height; + if (horizontal) + pixel_length = NSWidth (newRect); + else + pixel_length = NSHeight (newRect); + if (pixel_length == 0) pixel_length = 1; + min_portion = 20 / pixel_length; [super setFrame: newRect]; /* unblock_input (); */ } @@ -8174,7 +8160,12 @@ not_in_argv (NSString *arg) { NSTRACE ("[EmacsScroller dealloc]"); if (window) - wset_vertical_scroll_bar (window, Qnil); + { + if (horizontal) + wset_horizontal_scroll_bar (window, Qnil); + else + wset_vertical_scroll_bar (window, Qnil); + } window = 0; [super dealloc]; } @@ -8209,7 +8200,12 @@ not_in_argv (NSString *arg) if (view != nil) view->scrollbarsNeedingUpdate++; if (window) - wset_vertical_scroll_bar (window, Qnil); + { + if (horizontal) + wset_horizontal_scroll_bar (window, Qnil); + else + wset_vertical_scroll_bar (window, Qnil); + } window = 0; [self removeFromSuperview]; [self release]; @@ -8259,7 +8255,7 @@ not_in_argv (NSString *arg) { float pos; CGFloat por; - portion = max ((float)whole*min_portion/pixel_height, portion); + portion = max ((float)whole*min_portion/pixel_length, portion); pos = (float)position / (whole - portion); por = (CGFloat)portion/whole; #ifdef NS_IMPL_COCOA @@ -8289,10 +8285,20 @@ not_in_argv (NSString *arg) XSETWINDOW (win, window); emacs_event->frame_or_window = win; emacs_event->timestamp = EV_TIMESTAMP (e); - emacs_event->kind = SCROLL_BAR_CLICK_EVENT; emacs_event->arg = Qnil; - XSETINT (emacs_event->x, loc * pixel_height); - XSETINT (emacs_event->y, pixel_height-20); + + if (horizontal) + { + emacs_event->kind = HORIZONTAL_SCROLL_BAR_CLICK_EVENT; + XSETINT (emacs_event->x, em_whole * loc / pixel_length); + XSETINT (emacs_event->y, em_whole); + } + else + { + emacs_event->kind = SCROLL_BAR_CLICK_EVENT; + XSETINT (emacs_event->x, loc); + XSETINT (emacs_event->y, pixel_length-20); + } if (q_event_ptr) { @@ -8355,15 +8361,15 @@ not_in_argv (NSString *arg) switch (part) { case NSScrollerDecrementPage: - last_hit_part = scroll_bar_above_handle; inc = -1.0; break; + last_hit_part = horizontal ? scroll_bar_before_handle : scroll_bar_above_handle; break; case NSScrollerIncrementPage: - last_hit_part = scroll_bar_below_handle; inc = 1.0; break; + last_hit_part = horizontal ? scroll_bar_after_handle : scroll_bar_below_handle; break; case NSScrollerDecrementLine: - last_hit_part = scroll_bar_up_arrow; inc = -0.1; break; + last_hit_part = horizontal ? scroll_bar_left_arrow : scroll_bar_up_arrow; break; case NSScrollerIncrementLine: - last_hit_part = scroll_bar_down_arrow; inc = 0.1; break; + last_hit_part = horizontal ? scroll_bar_right_arrow : scroll_bar_down_arrow; break; case NSScrollerKnob: - last_hit_part = scroll_bar_handle; break; + last_hit_part = horizontal ? scroll_bar_horizontal_handle : scroll_bar_handle; break; case NSScrollerKnobSlot: /* GNUstep-only */ last_hit_part = scroll_bar_move_ratio; break; default: /* NSScrollerNoPart? */ @@ -8372,36 +8378,34 @@ not_in_argv (NSString *arg) return; } - if (inc != 0.0) - { - pos = 0; /* ignored */ - - /* set a timer to repeat, as we can't let superclass do this modally */ - scroll_repeat_entry - = [[NSTimer scheduledTimerWithTimeInterval: SCROLL_BAR_FIRST_DELAY - target: self - selector: @selector (repeatScroll:) - userInfo: 0 - repeats: YES] - retain]; - } - else + if (part == NSScrollerKnob || part == NSScrollerKnobSlot) { /* handle, or on GNUstep possibly slot */ NSEvent *fake_event; + int length; /* compute float loc in slot and mouse offset on knob */ sr = [self convertRect: [self rectForPart: NSScrollerKnobSlot] toView: nil]; - loc = NSHeight (sr) - ([e locationInWindow].y - NSMinY (sr)); + if (horizontal) + { + length = NSWidth (sr); + loc = ([e locationInWindow].x - NSMinX (sr)); + } + else + { + length = NSHeight (sr); + loc = length - ([e locationInWindow].y - NSMinY (sr)); + } + if (loc <= 0.0) { loc = 0.0; edge = -1; } - else if (loc >= NSHeight (sr)) + else if (loc >= length) { - loc = NSHeight (sr); + loc = length; edge = 1; } @@ -8411,17 +8415,16 @@ not_in_argv (NSString *arg) { kr = [self convertRect: [self rectForPart: NSScrollerKnob] toView: nil]; - kloc = NSHeight (kr) - ([e locationInWindow].y - NSMinY (kr)); + if (horizontal) + kloc = ([e locationInWindow].x - NSMinX (kr)); + else + kloc = NSHeight (kr) - ([e locationInWindow].y - NSMinY (kr)); } last_mouse_offset = kloc; - /* if knob, tell emacs a location offset by knob pos - (to indicate top of handle) */ - if (part == NSScrollerKnob) - pos = (loc - last_mouse_offset) / NSHeight (sr); - else - /* else this is a slot click on GNUstep: go straight there */ - pos = loc / NSHeight (sr); + if (part != NSScrollerKnob) + /* this is a slot click on GNUstep: go straight there */ + pos = loc; /* send a fake mouse-up to super to preempt modal -trackKnob: mode */ fake_event = [NSEvent mouseEventWithType: NSLeftMouseUp @@ -8435,6 +8438,19 @@ not_in_argv (NSString *arg) pressure: [e pressure]]; [super mouseUp: fake_event]; } + else + { + pos = 0; /* ignored */ + + /* set a timer to repeat, as we can't let superclass do this modally */ + scroll_repeat_entry + = [[NSTimer scheduledTimerWithTimeInterval: SCROLL_BAR_FIRST_DELAY + target: self + selector: @selector (repeatScroll:) + userInfo: 0 + repeats: YES] + retain]; + } if (part != NSScrollerKnob) [self sendScrollEventAtLoc: pos fromEvent: e]; @@ -8446,23 +8462,34 @@ not_in_argv (NSString *arg) { NSRect sr; double loc, pos; + int length; NSTRACE ("[EmacsScroller mouseDragged:]"); sr = [self convertRect: [self rectForPart: NSScrollerKnobSlot] toView: nil]; - loc = NSHeight (sr) - ([e locationInWindow].y - NSMinY (sr)); + + if (horizontal) + { + length = NSWidth (sr); + loc = ([e locationInWindow].x - NSMinX (sr)); + } + else + { + length = NSHeight (sr); + loc = length - ([e locationInWindow].y - NSMinY (sr)); + } if (loc <= 0.0) { loc = 0.0; } - else if (loc >= NSHeight (sr) + last_mouse_offset) + else if (loc >= length + last_mouse_offset) { - loc = NSHeight (sr) + last_mouse_offset; + loc = length + last_mouse_offset; } - pos = (loc - last_mouse_offset) / NSHeight (sr); + pos = (loc - last_mouse_offset); [self sendScrollEventAtLoc: pos fromEvent: e]; } diff --git a/src/window.h b/src/window.h index 0cfff88..a1c4aaa 100644 --- a/src/window.h +++ b/src/window.h @@ -786,7 +786,7 @@ wset_next_buffers (struct window *w, Lisp_Object val) || WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (W)) #if (defined (HAVE_WINDOW_SYSTEM) \ - && ((defined (USE_TOOLKIT_SCROLL_BARS) && !defined (HAVE_NS)) \ + && ((defined (USE_TOOLKIT_SCROLL_BARS)) \ || defined (HAVE_NTGUI))) # define USE_HORIZONTAL_SCROLL_BARS true #else -- OK, I really hope I've cracked it this time! Just after I sent the last patch I noticed an issue with left-hand scroll-bars where they were overlapping the text area, but only if you enabled them *without* any other scroll-bars being enabled first. -- Alan Third