aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOscar Fuentes2016-02-06 22:12:53 +0100
committerOscar Fuentes2016-02-06 22:18:47 +0100
commitc77ffc8019bceb850a794c13f2e3ad991cc7e412 (patch)
tree8c6bc33063694642ce003fde76cf529985b69e4d
parent49e57490d0023b10629cd1a3c2d5f0fc6068a58c (diff)
downloademacs-c77ffc8019bceb850a794c13f2e3ad991cc7e412.tar.gz
emacs-c77ffc8019bceb850a794c13f2e3ad991cc7e412.zip
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.
-rw-r--r--src/xfns.c61
1 files changed, 49 insertions, 12 deletions
diff --git a/src/xfns.c b/src/xfns.c
index 9624ac5d9ac..20ac6271715 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -5683,6 +5683,7 @@ compute_tip_xy (struct frame *f, Lisp_Object parms, Lisp_Object dx, Lisp_Object
5683 int win_x, win_y; 5683 int win_x, win_y;
5684 Window root, child; 5684 Window root, child;
5685 unsigned pmask; 5685 unsigned pmask;
5686 int min_x, min_y, max_x, max_y = -1;
5686 5687
5687 /* User-specified position? */ 5688 /* User-specified position? */
5688 left = Fcdr (Fassq (Qleft, parms)); 5689 left = Fcdr (Fassq (Qleft, parms));
@@ -5695,45 +5696,81 @@ compute_tip_xy (struct frame *f, Lisp_Object parms, Lisp_Object dx, Lisp_Object
5695 if ((!INTEGERP (left) && !INTEGERP (right)) 5696 if ((!INTEGERP (left) && !INTEGERP (right))
5696 || (!INTEGERP (top) && !INTEGERP (bottom))) 5697 || (!INTEGERP (top) && !INTEGERP (bottom)))
5697 { 5698 {
5699 Lisp_Object frame, attributes, monitor, geometry;
5700
5698 block_input (); 5701 block_input ();
5699 XQueryPointer (FRAME_X_DISPLAY (f), FRAME_DISPLAY_INFO (f)->root_window, 5702 XQueryPointer (FRAME_X_DISPLAY (f), FRAME_DISPLAY_INFO (f)->root_window,
5700 &root, &child, root_x, root_y, &win_x, &win_y, &pmask); 5703 &root, &child, root_x, root_y, &win_x, &win_y, &pmask);
5701 unblock_input (); 5704 unblock_input ();
5705
5706 XSETFRAME(frame, f);
5707 attributes = Fx_display_monitor_attributes_list (frame);
5708
5709 /* Try to determine the monitor where the mouse pointer is and
5710 its geometry. See bug#22549. */
5711 while (CONSP (attributes))
5712 {
5713 monitor = XCAR (attributes);
5714 geometry = Fassq (Qgeometry, monitor);
5715 if (CONSP (geometry))
5716 {
5717 min_x = XINT (Fnth (make_number (1), geometry));
5718 min_y = XINT (Fnth (make_number (2), geometry));
5719 max_x = min_x + XINT (Fnth (make_number (3), geometry));
5720 max_y = min_y + XINT (Fnth (make_number (4), geometry));
5721 if (min_x <= *root_x && *root_x < max_x
5722 && min_y <= *root_y && *root_y < max_y)
5723 {
5724 break;
5725 }
5726 max_y = -1;
5727 }
5728
5729 attributes = XCDR (attributes);
5730 }
5731 }
5732
5733 /* It was not possible to determine the monitor's geometry, so we
5734 assign some sane defaults here: */
5735 if ( max_y < 0 )
5736 {
5737 min_x = 0;
5738 min_y = 0;
5739 max_x = x_display_pixel_width (FRAME_DISPLAY_INFO (f));
5740 max_y = x_display_pixel_height (FRAME_DISPLAY_INFO (f));
5702 } 5741 }
5703 5742
5704 if (INTEGERP (top)) 5743 if (INTEGERP (top))
5705 *root_y = XINT (top); 5744 *root_y = XINT (top);
5706 else if (INTEGERP (bottom)) 5745 else if (INTEGERP (bottom))
5707 *root_y = XINT (bottom) - height; 5746 *root_y = XINT (bottom) - height;
5708 else if (*root_y + XINT (dy) <= 0) 5747 else if (*root_y + XINT (dy) <= min_y)
5709 *root_y = 0; /* Can happen for negative dy */ 5748 *root_y = min_y; /* Can happen for negative dy */
5710 else if (*root_y + XINT (dy) + height 5749 else if (*root_y + XINT (dy) + height <= max_y)
5711 <= x_display_pixel_height (FRAME_DISPLAY_INFO (f)))
5712 /* It fits below the pointer */ 5750 /* It fits below the pointer */
5713 *root_y += XINT (dy); 5751 *root_y += XINT (dy);
5714 else if (height + XINT (dy) <= *root_y) 5752 else if (height + XINT (dy) + min_y <= *root_y)
5715 /* It fits above the pointer. */ 5753 /* It fits above the pointer. */
5716 *root_y -= height + XINT (dy); 5754 *root_y -= height + XINT (dy);
5717 else 5755 else
5718 /* Put it on the top. */ 5756 /* Put it on the top. */
5719 *root_y = 0; 5757 *root_y = min_y;
5720 5758
5721 if (INTEGERP (left)) 5759 if (INTEGERP (left))
5722 *root_x = XINT (left); 5760 *root_x = XINT (left);
5723 else if (INTEGERP (right)) 5761 else if (INTEGERP (right))
5724 *root_x = XINT (right) - width; 5762 *root_x = XINT (right) - width;
5725 else if (*root_x + XINT (dx) <= 0) 5763 else if (*root_x + XINT (dx) <= min_x)
5726 *root_x = 0; /* Can happen for negative dx */ 5764 *root_x = 0; /* Can happen for negative dx */
5727 else if (*root_x + XINT (dx) + width 5765 else if (*root_x + XINT (dx) + width <= max_x)
5728 <= x_display_pixel_width (FRAME_DISPLAY_INFO (f)))
5729 /* It fits to the right of the pointer. */ 5766 /* It fits to the right of the pointer. */
5730 *root_x += XINT (dx); 5767 *root_x += XINT (dx);
5731 else if (width + XINT (dx) <= *root_x) 5768 else if (width + XINT (dx) + min_x <= *root_x)
5732 /* It fits to the left of the pointer. */ 5769 /* It fits to the left of the pointer. */
5733 *root_x -= width + XINT (dx); 5770 *root_x -= width + XINT (dx);
5734 else 5771 else
5735 /* Put it left-justified on the screen--it ought to fit that way. */ 5772 /* Put it left justified on the screen -- it ought to fit that way. */
5736 *root_x = 0; 5773 *root_x = min_x;
5737} 5774}
5738 5775
5739 5776