diff options
| author | Oscar Fuentes | 2016-02-06 22:12:53 +0100 |
|---|---|---|
| committer | Oscar Fuentes | 2016-02-06 22:18:47 +0100 |
| commit | c77ffc8019bceb850a794c13f2e3ad991cc7e412 (patch) | |
| tree | 8c6bc33063694642ce003fde76cf529985b69e4d | |
| parent | 49e57490d0023b10629cd1a3c2d5f0fc6068a58c (diff) | |
| download | emacs-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.c | 61 |
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 | ||