From: Alan Third <alan@idiocy.org>
To: emacs-devel@gnu.org
Subject: NS port horizontal scroll-bars
Date: Sun, 24 Apr 2016 17:01:23 +0100 [thread overview]
Message-ID: <20160424160123.GA37657@breton.local> (raw)
[-- Attachment #1: Type: text/plain, Size: 510 bytes --]
I've been trying to complete the horizontal scroll-bars implementation
in the NS port and have run into a bit of a problem I can't work out.
They display correctly, and when you click on them they, I think, send
a correctly formatted emacs_event, but nothing happens. Vertical
scroll-bars work as expected.
Have I missed somewhere where I need to enable the horizontal
scroll-bar events or something? Any pointers would be appreciated.
I've attached a patch containing what I've done so far.
--
Alan Third
[-- Attachment #2: Horizontal scroll-bars patch --]
[-- Type: text/plain, Size: 10421 bytes --]
diff --git a/lisp/scroll-bar.el b/lisp/scroll-bar.el
index 5cfa2c4..01194f9 100644
--- a/lisp/scroll-bar.el
+++ b/lisp/scroll-bar.el
@@ -149,7 +149,8 @@ horizontal-scroll-bars-available-p
(and (display-graphic-p)
(boundp 'x-toolkit-scroll-bars)
x-toolkit-scroll-bars
- (not (eq (window-system) 'ns))))
+ ;; (not (eq (window-system) 'ns))
+ ))
(define-minor-mode horizontal-scroll-bar-mode
"Toggle horizontal scroll bars on all frames (Horizontal Scroll Bar mode).
diff --git a/src/nsterm.h b/src/nsterm.h
index 0aea9cc..93b19e4 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -72,7 +72,7 @@ typedef float EmacsCGFloat;
Hint: keep the trailing whitespace -- the version control system
will reject accidental commits. */
-/* #define NSTRACE_ENABLED 1 */
+#define NSTRACE_ENABLED 1
/* When non-zero, trace output is enabled for all parts, except those
@@ -681,6 +681,8 @@ char const * nstrace_fullscreen_type_name (int);
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..91af34f 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -4442,11 +4442,11 @@ 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);
- top = WINDOW_SCROLL_BAR_AREA_Y (window);
+ top = WINDOW_SCROLL_BAR_AREA_Y (window) - FRAME_LINE_HEIGHT (f);
r = NSMakeRect (left, top, width, height);
/* the parent view is flipped, so we need to flip y value */
@@ -4484,10 +4484,10 @@ 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;
+ r.size.height = oldRect.size.height;
if (FRAME_LIVE_P (f) && !NSEqualRects (oldRect, r))
{
- if (oldRect.origin.x != r.origin.x)
+ if (oldRect.origin.y != r.origin.y)
ns_clear_frame_area (f, left, top, width, height);
[bar setFrame: r];
update_p = YES;
@@ -8110,12 +8110,21 @@ 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;
+ r.size.height = [EmacsScroller scrollerWidth];
+ }
+ else
+ {
+ horizontal = NO;
+ r.size.width = [EmacsScroller scrollerWidth];
+ }
+
[super initWithFrame: r/*NSMakeRect (0, 0, 0, 0)*/];
[self setContinuous: YES];
[self setEnabled: YES];
@@ -8131,7 +8140,10 @@ not_in_argv (NSString *arg)
window = XWINDOW (nwin);
condemned = NO;
- pixel_height = NSHeight (r);
+ if (horizontal)
+ pixel_height = NSWidth (r);
+ else
+ pixel_height = NSHeight (r);
if (pixel_height == 0) pixel_height = 1;
min_portion = 20 / pixel_height;
@@ -8162,7 +8174,10 @@ not_in_argv (NSString *arg)
NSTRACE ("[EmacsScroller setFrame:]");
/* block_input (); */
- pixel_height = NSHeight (newRect);
+ if (newRect.size.width > newRect.size.height)
+ pixel_height = NSWidth (newRect);
+ else
+ pixel_height = NSHeight (newRect);
if (pixel_height == 0) pixel_height = 1;
min_portion = 20 / pixel_height;
[super setFrame: newRect];
@@ -8174,7 +8189,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];
}
@@ -8289,10 +8309,15 @@ 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);
+ if (horizontal)
+ emacs_event->kind = HORIZONTAL_SCROLL_BAR_CLICK_EVENT;
+ else
+ emacs_event->kind = SCROLL_BAR_CLICK_EVENT;
+ XSETINT (emacs_event->x, loc);
XSETINT (emacs_event->y, pixel_height-20);
+ emacs_event->arg = Qnil;
+
+ printf("x: %d, y: %d\n", emacs_event->x, emacs_event->y);
if (q_event_ptr)
{
@@ -8355,13 +8380,13 @@ not_in_argv (NSString *arg)
switch (part)
{
case NSScrollerDecrementPage:
- last_hit_part = scroll_bar_above_handle; inc = -1.0; break;
+ last_hit_part = scroll_bar_above_handle; break;
case NSScrollerIncrementPage:
- last_hit_part = scroll_bar_below_handle; inc = 1.0; break;
+ last_hit_part = scroll_bar_below_handle; break;
case NSScrollerDecrementLine:
- last_hit_part = scroll_bar_up_arrow; inc = -0.1; break;
+ last_hit_part = scroll_bar_up_arrow; break;
case NSScrollerIncrementLine:
- last_hit_part = scroll_bar_down_arrow; inc = 0.1; break;
+ last_hit_part = scroll_bar_down_arrow; break;
case NSScrollerKnob:
last_hit_part = scroll_bar_handle; break;
case NSScrollerKnobSlot: /* GNUstep-only */
@@ -8372,36 +8397,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 +8434,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 / length;
/* send a fake mouse-up to super to preempt modal -trackKnob: mode */
fake_event = [NSEvent mouseEventWithType: NSLeftMouseUp
@@ -8435,6 +8457,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 +8481,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
next reply other threads:[~2016-04-24 16:01 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-04-24 16:01 Alan Third [this message]
2016-04-24 17:28 ` NS port horizontal scroll-bars Anders Lindgren
2016-04-25 20:34 ` Alan Third
2016-04-26 5:39 ` Anders Lindgren
2016-04-26 6:35 ` martin rudalics
2016-04-26 9:51 ` Alan Third
2016-04-26 11:27 ` YAMAMOTO Mitsuharu
2016-04-26 17:07 ` Alan Third
-- strict thread matches above, loose matches on Subject: below --
2016-05-01 14:40 Angelo Graziosi
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
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20160424160123.GA37657@breton.local \
--to=alan@idiocy.org \
--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 public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).