* bug#26905: 25.2: MacOS: tooltips show in wrong display
@ 2017-05-13 7:43 Charles A. Roelli
2017-05-13 9:02 ` Charles A. Roelli
2017-05-16 21:56 ` bug#26905: [PATCH] Show tooltip on correct screen (bug#26905) Alan Third
0 siblings, 2 replies; 8+ messages in thread
From: Charles A. Roelli @ 2017-05-13 7:43 UTC (permalink / raw)
To: 26905
Continuing from bug#26816
(https://debbugs.gnu.org/cgi/bugreport.cgi?bug=26816#32):
On 11/05/2017 23:43, Alan Third wrote:
>> This now reminds me of a related problem, though: with Emacs 25.2 (or in
>> Emacs 26, with the above change applied to NS_PARENT_WINDOW_TOP_POS(f)),
>> tooltips originating from an area with a help-echo property (like "Lisp
>> Interaction" in the mode line in emacs -Q) in a frame on the secondary
>> monitor actually show up in the primary monitor instead -- as if the tooltip
>> frame is constrained to having a positive x-coordinate only. I haven't
>> found where it happens, but I guess the cause is similar.
>
> Look at compute_tip_xy in nsfns.m. It moves tooltips into the positive
> screen space. I’ve not managed to get to grips with this code yet.
>
> I think what we want is for it to try to keep the tooltip on one
> screen, so it’s not spanning two monitors, but allow it to go into
> negative space.
>
> Perhaps this should be a separate bug report.
"Primary" and "secondary" monitors are as follows:
(display-monitor-attributes-list) =>
(((name . "Color LCD")
(geometry 0 0 1280 800)
(workarea 0 22 1280 714)
(mm-size 290 180)
(frames #<frame emacs-devel 0x105044260> #<frame *Backtrace*
0x1199eca10> #<frame *vc-diff* 0x117dc82b8> #<frame nsterm.m
0x121c49ad8> #<frame *shell* 0x119adf830> #<frame *Minibuf-1* 0x119b33030>)
(source . "NS"))
((name . "DELL 2007WFP")
(geometry -1050 -880 1050 1680)
(workarea -1050 -880 1050 1680)
(mm-size 430 270)
(frames #<frame nsterm.h 0x117c83fd0>)
(source . "NS")))
^ permalink raw reply [flat|nested] 8+ messages in thread
* bug#26905: 25.2: MacOS: tooltips show in wrong display
2017-05-13 7:43 bug#26905: 25.2: MacOS: tooltips show in wrong display Charles A. Roelli
@ 2017-05-13 9:02 ` Charles A. Roelli
2017-05-13 9:56 ` Eli Zaretskii
2017-05-13 15:28 ` Alan Third
2017-05-16 21:56 ` bug#26905: [PATCH] Show tooltip on correct screen (bug#26905) Alan Third
1 sibling, 2 replies; 8+ messages in thread
From: Charles A. Roelli @ 2017-05-13 9:02 UTC (permalink / raw)
To: 26905
If I remove the marked lines in compute_tip_xy:
if (INTEGERP (left) || INTEGERP (right))
*root_x = pt.x;
=> else if (pt.x + XINT (dx) <= 0)
=> *root_x = 0; /* Can happen for negative dx */
else if (pt.x + XINT (dx) + width
<= x_display_pixel_width (FRAME_DISPLAY_INFO (f)))
/* It fits to the right of the pointer. */
*root_x = pt.x + XINT (dx);
else if (width + XINT (dx) <= pt.x)
/* It fits to the left of the pointer. */
*root_x = pt.x - width - XINT (dx);
else
/* Put it left justified on the screen -- it ought to fit that
way. */
*root_x = 0;
Then the problem is gone.
I notice now, though, that the tooltip can end up partially offscreen,
both with and without the above change (e.g. when you create a tooltip
with the mouse pointer at the right edge of the primary monitor). IIRC
on GNU/Linux the tooltip is adjusted to fit on screen. Maybe this
adjustment works on newer versions of OS X?
^ permalink raw reply [flat|nested] 8+ messages in thread
* bug#26905: 25.2: MacOS: tooltips show in wrong display
2017-05-13 9:02 ` Charles A. Roelli
@ 2017-05-13 9:56 ` Eli Zaretskii
2017-05-13 14:04 ` Charles A. Roelli
2017-05-13 15:28 ` Alan Third
1 sibling, 1 reply; 8+ messages in thread
From: Eli Zaretskii @ 2017-05-13 9:56 UTC (permalink / raw)
To: Charles A. Roelli; +Cc: 26905
> From: "Charles A. Roelli" <charles@aurox.ch>
> Date: Sat, 13 May 2017 11:02:04 +0200
>
> If I remove the marked lines in compute_tip_xy:
>
> if (INTEGERP (left) || INTEGERP (right))
> *root_x = pt.x;
> => else if (pt.x + XINT (dx) <= 0)
> => *root_x = 0; /* Can happen for negative dx */
> else if (pt.x + XINT (dx) + width
> <= x_display_pixel_width (FRAME_DISPLAY_INFO (f)))
> /* It fits to the right of the pointer. */
> *root_x = pt.x + XINT (dx);
> else if (width + XINT (dx) <= pt.x)
> /* It fits to the left of the pointer. */
> *root_x = pt.x - width - XINT (dx);
> else
> /* Put it left justified on the screen -- it ought to fit that way. */
> *root_x = 0;
>
> Then the problem is gone.
Those lines were added to fix some problems (whose particulars I
cannot find at the moment), so we shouldn't remove them without
understanding what is going on.
^ permalink raw reply [flat|nested] 8+ messages in thread
* bug#26905: 25.2: MacOS: tooltips show in wrong display
2017-05-13 9:56 ` Eli Zaretskii
@ 2017-05-13 14:04 ` Charles A. Roelli
0 siblings, 0 replies; 8+ messages in thread
From: Charles A. Roelli @ 2017-05-13 14:04 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: 26905
FWIW, I found this change to the Windows port of Emacs (not sure if it
was ever committed):
https://lists.gnu.org/archive/html/bug-gnu-emacs/2007-07/msg00153.html
And a more recent change as a result of #22549: commit
c77ffc8019bceb850a794c13f2e3ad991cc7e412, with changes to xfns.c.
c77ffc8..: Oscar Fuentes 2016-02-06 Use monitor's resolution for
positioning tooltips
commit c77ffc8019bceb850a794c13f2e3ad991cc7e412
Author: Oscar Fuentes <ofv@wanadoo.es>
Date: Sat Feb 6 22:12:53 2016 +0100
Use monitor's resolution for positioning tooltips
* src/xfns.c (compute_tip_xy): Use the resolution of the monitor where
the mouse pointer is to avoid placing the tooltip over the border of
the monitor on multi-head displays. Fixes bug#22549.
Seems like the Windows and X versions nowadays have a check that looks
like this:
else if (*root_x + XINT (dx) <= min_x)
*root_x = 0; /* Can happen for negative dx */
i.e. compare *root_x + XINT (dx) against the variable "min_x", rather
than comparing against zero, as is done in the NS port. Since frames can
be in the negative coordinate space, it makes sense to allow a tooltip
to have a x-coordinate less than 0 -- so the NS port's code should
probably be changed.
I'm also not sure why, in the above code from the Windows and X
versions, *root_x is constrained to zero if *root_x + dx goes below
min_x. Wouldn't it make more sense to constrain to min_x, which could
be negative?
On 13/05/2017 11:56, Eli Zaretskii wrote:
>> From: "Charles A. Roelli" <charles@aurox.ch>
>> Date: Sat, 13 May 2017 11:02:04 +0200
>>
>> If I remove the marked lines in compute_tip_xy:
>>
>> if (INTEGERP (left) || INTEGERP (right))
>> *root_x = pt.x;
>> => else if (pt.x + XINT (dx) <= 0)
>> => *root_x = 0; /* Can happen for negative dx */
>> else if (pt.x + XINT (dx) + width
>> <= x_display_pixel_width (FRAME_DISPLAY_INFO (f)))
>> /* It fits to the right of the pointer. */
>> *root_x = pt.x + XINT (dx);
>> else if (width + XINT (dx) <= pt.x)
>> /* It fits to the left of the pointer. */
>> *root_x = pt.x - width - XINT (dx);
>> else
>> /* Put it left justified on the screen -- it ought to fit that way. */
>> *root_x = 0;
>>
>> Then the problem is gone.
> Those lines were added to fix some problems (whose particulars I
> cannot find at the moment), so we shouldn't remove them without
> understanding what is going on.
^ permalink raw reply [flat|nested] 8+ messages in thread
* bug#26905: 25.2: MacOS: tooltips show in wrong display
2017-05-13 9:02 ` Charles A. Roelli
2017-05-13 9:56 ` Eli Zaretskii
@ 2017-05-13 15:28 ` Alan Third
1 sibling, 0 replies; 8+ messages in thread
From: Alan Third @ 2017-05-13 15:28 UTC (permalink / raw)
To: Charles A. Roelli; +Cc: 26905
On Sat, May 13, 2017 at 11:02:04AM +0200, Charles A. Roelli wrote:
> I notice now, though, that the tooltip can end up partially offscreen, both
> with and without the above change (e.g. when you create a tooltip with the
> mouse pointer at the right edge of the primary monitor). IIRC on GNU/Linux
> the tooltip is adjusted to fit on screen. Maybe this adjustment works on
> newer versions of OS X?
I was thinking about this earlier and I suspect that if we want to
avoid tooltips crossing monitors we’ll have to step through each
screen in [NSScreen screens], check if `pt` is within it’s bounds, and
when we find the right screen, use it’s origin and frame to calculate
the min/max x/y.
constrain_frame_rect in nsterm.m does something similar already.
There’s a method in CGRect called CGRectContainsPoint, which should
help us here, as NSRect is really just a CGRect. Unfortunately it
doesn’t appear to be available in GNUstep, so it may be necessary to
implement the check ourselves.
If we don’t care about spanning monitors, I think we still need to
step through each screen and calculate the overall min/max values.
What do you think?
--
Alan Third
^ permalink raw reply [flat|nested] 8+ messages in thread
* bug#26905: [PATCH] Show tooltip on correct screen (bug#26905)
2017-05-13 7:43 bug#26905: 25.2: MacOS: tooltips show in wrong display Charles A. Roelli
2017-05-13 9:02 ` Charles A. Roelli
@ 2017-05-16 21:56 ` Alan Third
2017-05-19 16:30 ` Charles A. Roelli
1 sibling, 1 reply; 8+ messages in thread
From: Alan Third @ 2017-05-16 21:56 UTC (permalink / raw)
To: Charles A. Roelli; +Cc: 26905
* src/nsfns.m (compute_tip_xy): Find the correct screen for the
tooltip and constrain it to that screen.
---
src/nsfns.m | 27 ++++++++++++++++++++-------
1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/src/nsfns.m b/src/nsfns.m
index cbe0ffb858..04565a99bb 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -2760,6 +2760,7 @@ and GNUstep implementations ("distributor-specific release
EmacsView *view = FRAME_NS_VIEW (f);
struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
NSPoint pt;
+ NSScreen *screen;
/* Start with user-specified or mouse position. */
left = Fcdr (Fassq (Qleft, parms));
@@ -2794,13 +2795,25 @@ and GNUstep implementations ("distributor-specific release
- height);
}
+ /* Find the screen that pt is on. */
+ for (screen in [NSScreen screens])
+#ifdef NS_IMPL_COCOA
+ if (CGRectContainsPoint ([screen frame], pt))
+#else
+ if (pt.x >= screen.frame.origin.x
+ && pt.x < screen.frame.origin.x + screen.frame.size.width
+ && pt.y >= screen.frame.origin.y
+ && pt.y < screen.frame.origin.y + screen.frame.size.height)
+#endif
+ break;
+
/* Ensure in bounds. (Note, screen origin = lower left.) */
if (INTEGERP (left) || INTEGERP (right))
*root_x = pt.x;
- else if (pt.x + XINT (dx) <= 0)
- *root_x = 0; /* Can happen for negative dx */
+ else if (pt.x + XINT (dx) <= screen.frame.origin.x)
+ *root_x = screen.frame.origin.x; /* Can happen for negative dx */
else if (pt.x + XINT (dx) + width
- <= x_display_pixel_width (FRAME_DISPLAY_INFO (f)))
+ <= screen.frame.origin.x + screen.frame.size.width)
/* It fits to the right of the pointer. */
*root_x = pt.x + XINT (dx);
else if (width + XINT (dx) <= pt.x)
@@ -2808,20 +2821,20 @@ and GNUstep implementations ("distributor-specific release
*root_x = pt.x - width - XINT (dx);
else
/* Put it left justified on the screen -- it ought to fit that way. */
- *root_x = 0;
+ *root_x = screen.frame.origin.x;
if (INTEGERP (top) || INTEGERP (bottom))
*root_y = pt.y;
- else if (pt.y - XINT (dy) - height >= 0)
+ else if (pt.y - XINT (dy) - height >= screen.frame.origin.y)
/* It fits below the pointer. */
*root_y = pt.y - height - XINT (dy);
else if (pt.y + XINT (dy) + height
- <= x_display_pixel_height (FRAME_DISPLAY_INFO (f)))
+ <= screen.frame.origin.y + screen.frame.size.height)
/* It fits above the pointer */
*root_y = pt.y + XINT (dy);
else
/* Put it on the top. */
- *root_y = x_display_pixel_height (FRAME_DISPLAY_INFO (f)) - height;
+ *root_y = screen.frame.origin.y + screen.frame.size.height - height;
}
--
Here’s my go at this. It seems to work OK on single and multi‐monitor
setups in macOS, and in GNUstep in single monitor (I can’t test it
multi‐monitor).
--
Alan Third
^ permalink raw reply related [flat|nested] 8+ messages in thread
* bug#26905: [PATCH] Show tooltip on correct screen (bug#26905)
2017-05-16 21:56 ` bug#26905: [PATCH] Show tooltip on correct screen (bug#26905) Alan Third
@ 2017-05-19 16:30 ` Charles A. Roelli
2017-05-20 23:15 ` Alan Third
0 siblings, 1 reply; 8+ messages in thread
From: Charles A. Roelli @ 2017-05-19 16:30 UTC (permalink / raw)
To: Alan Third; +Cc: 26905
Works fine for me too! Thanks for coming up with this fix.
> On 16 May 2017, at 23:56, Alan Third <alan@idiocy.org> wrote:
>
> * src/nsfns.m (compute_tip_xy): Find the correct screen for the
> tooltip and constrain it to that screen.
> ---
> src/nsfns.m | 27 ++++++++++++++++++++-------
> 1 file changed, 20 insertions(+), 7 deletions(-)
>
> diff --git a/src/nsfns.m b/src/nsfns.m
> index cbe0ffb858..04565a99bb 100644
> --- a/src/nsfns.m
> +++ b/src/nsfns.m
> @@ -2760,6 +2760,7 @@ and GNUstep implementations ("distributor-specific release
> EmacsView *view = FRAME_NS_VIEW (f);
> struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
> NSPoint pt;
> + NSScreen *screen;
>
> /* Start with user-specified or mouse position. */
> left = Fcdr (Fassq (Qleft, parms));
> @@ -2794,13 +2795,25 @@ and GNUstep implementations ("distributor-specific release
> - height);
> }
>
> + /* Find the screen that pt is on. */
> + for (screen in [NSScreen screens])
> +#ifdef NS_IMPL_COCOA
> + if (CGRectContainsPoint ([screen frame], pt))
> +#else
> + if (pt.x >= screen.frame.origin.x
> + && pt.x < screen.frame.origin.x + screen.frame.size.width
> + && pt.y >= screen.frame.origin.y
> + && pt.y < screen.frame.origin.y + screen.frame.size.height)
> +#endif
> + break;
> +
> /* Ensure in bounds. (Note, screen origin = lower left.) */
> if (INTEGERP (left) || INTEGERP (right))
> *root_x = pt.x;
> - else if (pt.x + XINT (dx) <= 0)
> - *root_x = 0; /* Can happen for negative dx */
> + else if (pt.x + XINT (dx) <= screen.frame.origin.x)
> + *root_x = screen.frame.origin.x; /* Can happen for negative dx */
> else if (pt.x + XINT (dx) + width
> - <= x_display_pixel_width (FRAME_DISPLAY_INFO (f)))
> + <= screen.frame.origin.x + screen.frame.size.width)
> /* It fits to the right of the pointer. */
> *root_x = pt.x + XINT (dx);
> else if (width + XINT (dx) <= pt.x)
> @@ -2808,20 +2821,20 @@ and GNUstep implementations ("distributor-specific release
> *root_x = pt.x - width - XINT (dx);
> else
> /* Put it left justified on the screen -- it ought to fit that way. */
> - *root_x = 0;
> + *root_x = screen.frame.origin.x;
>
> if (INTEGERP (top) || INTEGERP (bottom))
> *root_y = pt.y;
> - else if (pt.y - XINT (dy) - height >= 0)
> + else if (pt.y - XINT (dy) - height >= screen.frame.origin.y)
> /* It fits below the pointer. */
> *root_y = pt.y - height - XINT (dy);
> else if (pt.y + XINT (dy) + height
> - <= x_display_pixel_height (FRAME_DISPLAY_INFO (f)))
> + <= screen.frame.origin.y + screen.frame.size.height)
> /* It fits above the pointer */
> *root_y = pt.y + XINT (dy);
> else
> /* Put it on the top. */
> - *root_y = x_display_pixel_height (FRAME_DISPLAY_INFO (f)) - height;
> + *root_y = screen.frame.origin.y + screen.frame.size.height - height;
> }
>
>
> --
>
> Here’s my go at this. It seems to work OK on single and multi‐monitor
> setups in macOS, and in GNUstep in single monitor (I can’t test it
> multi‐monitor).
>
> --
> Alan Third
^ permalink raw reply [flat|nested] 8+ messages in thread
* bug#26905: [PATCH] Show tooltip on correct screen (bug#26905)
2017-05-19 16:30 ` Charles A. Roelli
@ 2017-05-20 23:15 ` Alan Third
0 siblings, 0 replies; 8+ messages in thread
From: Alan Third @ 2017-05-20 23:15 UTC (permalink / raw)
To: Charles A. Roelli; +Cc: 26905-done
"Charles A. Roelli" <charles@aurox.ch> writes:
> Works fine for me too! Thanks for coming up with this fix.
>>
>> Here’s my go at this. It seems to work OK on single and multi‐monitor
>> setups in macOS, and in GNUstep in single monitor (I can’t test it
>> multi‐monitor).
Pushed to master.
--
Alan Third
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2017-05-20 23:15 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-05-13 7:43 bug#26905: 25.2: MacOS: tooltips show in wrong display Charles A. Roelli
2017-05-13 9:02 ` Charles A. Roelli
2017-05-13 9:56 ` Eli Zaretskii
2017-05-13 14:04 ` Charles A. Roelli
2017-05-13 15:28 ` Alan Third
2017-05-16 21:56 ` bug#26905: [PATCH] Show tooltip on correct screen (bug#26905) Alan Third
2017-05-19 16:30 ` Charles A. Roelli
2017-05-20 23:15 ` Alan Third
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).