summaryrefslogtreecommitdiff
path: root/src/xfns.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xfns.c')
-rw-r--r--src/xfns.c561
1 files changed, 310 insertions, 251 deletions
diff --git a/src/xfns.c b/src/xfns.c
index 7c1bb1c2819..8571d0e20ab 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -19,6 +19,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <stdio.h>
+#include <stdlib.h>
#include <math.h>
#include <unistd.h>
@@ -91,11 +92,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "../lwlib/xlwmenu.h"
#endif
-#if !defined (NO_EDITRES)
-#define HACK_EDITRES
-extern void _XEditResCheckMessages (Widget, XtPointer, XEvent *, Boolean *);
-#endif /* not defined NO_EDITRES */
-
/* Unique id counter for widgets created by the Lucid Widget Library. */
extern LWLIB_ID widget_id_tick;
@@ -1313,7 +1309,6 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
}
#endif /* not USE_X_TOOLKIT && not USE_GTK */
adjust_frame_glyphs (f);
- run_window_configuration_change_hook (f);
}
@@ -1435,7 +1430,7 @@ x_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldva
if (border != FRAME_INTERNAL_BORDER_WIDTH (f))
{
- FRAME_INTERNAL_BORDER_WIDTH (f) = border;
+ f->internal_border_width = border;
#ifdef USE_X_TOOLKIT
if (FRAME_X_OUTPUT (f)->edit_widget)
@@ -2663,7 +2658,7 @@ x_window (struct frame *f, long window_prompting)
hack_wm_protocols (f, shell_widget);
-#ifdef HACK_EDITRES
+#ifdef X_TOOLKIT_EDITRES
XtAddEventHandler (shell_widget, 0, True, _XEditResCheckMessages, 0);
#endif
@@ -3129,7 +3124,7 @@ x_default_font_parameter (struct frame *f, Lisp_Object parms)
{
/* Remember the explicit font parameter, so we can re-apply it after
we've applied the `default' face settings. */
- AUTO_FRAME_ARG (arg, Qfont_param, font_param);
+ AUTO_FRAME_ARG (arg, Qfont_parameter, font_param);
x_set_frame_parameters (f, arg);
}
@@ -4296,8 +4291,8 @@ x_get_monitor_attributes_xrandr (struct x_display_info *dpyinfo)
{
XRROutputInfo *info = XRRGetOutputInfo (dpy, resources,
resources->outputs[i]);
- Connection conn = info ? info->connection : RR_Disconnected;
- RRCrtc id = info ? info->crtc : None;
+ if (!info)
+ continue;
if (strcmp (info->name, "default") == 0)
{
@@ -4308,9 +4303,9 @@ x_get_monitor_attributes_xrandr (struct x_display_info *dpyinfo)
return Qnil;
}
- if (conn != RR_Disconnected && id != None)
+ if (info->connection != RR_Disconnected && info->crtc != None)
{
- XRRCrtcInfo *crtc = XRRGetCrtcInfo (dpy, resources, id);
+ XRRCrtcInfo *crtc = XRRGetCrtcInfo (dpy, resources, info->crtc);
struct MonitorInfo *mi = &monitors[i];
XRectangle workarea_r;
@@ -4632,7 +4627,9 @@ frame_geometry (Lisp_Object frame, Lisp_Object attribute)
}
#else
tool_bar_height = FRAME_TOOL_BAR_HEIGHT (f);
- tool_bar_width = tool_bar_height ? native_width : 0;
+ tool_bar_width = (tool_bar_height
+ ? native_width - 2 * internal_border_width
+ : 0);
inner_top += tool_bar_height;
#endif
@@ -5112,11 +5109,18 @@ FRAME. Default is to change on the edit X window. */)
}
else
{
+ ptrdiff_t elsize;
+
CHECK_STRING (value);
data = SDATA (value);
if (INT_MAX < SBYTES (value))
error ("VALUE too long");
- nelements = SBYTES (value);
+
+ /* See comment above about longs and format=32 */
+ elsize = element_format == 32 ? sizeof (long) : element_format >> 3;
+ if (SBYTES (value) % elsize != 0)
+ error ("VALUE must contain an integral number of octets for FORMAT");
+ nelements = SBYTES (value) / elsize;
}
block_input ();
@@ -5216,7 +5220,7 @@ x_window_property_intern (struct frame *f,
property and those are indeed in 32 bit quantities if format is
32. */
- if (BITS_PER_LONG > 32 && actual_format == 32)
+ if (LONG_WIDTH > 32 && actual_format == 32)
{
unsigned long i;
int *idata = (int *) tmp_data;
@@ -5227,7 +5231,8 @@ x_window_property_intern (struct frame *f,
}
if (NILP (vector_ret_p))
- prop_value = make_string ((char *) tmp_data, actual_size);
+ prop_value = make_string ((char *) tmp_data,
+ (actual_format >> 3) * actual_size);
else
prop_value = x_property_data_to_lisp (f,
tmp_data,
@@ -5314,12 +5319,81 @@ no value of TYPE (always string in the MS Windows case). */)
return prop_value;
}
+DEFUN ("x-window-property-attributes", Fx_window_property_attributes, Sx_window_property_attributes,
+ 1, 3, 0,
+ doc: /* Retrieve metadata about window property PROP on FRAME.
+If FRAME is nil or omitted, use the selected frame.
+If SOURCE is non-nil, get the property on that window instead of from
+FRAME. The number 0 denotes the root window.
+
+Return value is nil if FRAME hasn't a property with name PROP.
+Otherwise, the return value is a vector with the following fields:
+
+0. The property type, as an integer. The symbolic name of
+ the type can be obtained with `x-get-atom-name'.
+1. The format of each element; one of 8, 16, or 32.
+2. The length of the property, in number of elements. */)
+ (Lisp_Object prop, Lisp_Object frame, Lisp_Object source)
+{
+ struct frame *f = decode_window_system_frame (frame);
+ Window target_window = FRAME_X_WINDOW (f);
+ Atom prop_atom;
+ Lisp_Object prop_attr = Qnil;
+ Atom actual_type;
+ int actual_format;
+ unsigned long actual_size, bytes_remaining;
+ unsigned char *tmp_data = NULL;
+ int rc;
+
+ CHECK_STRING (prop);
+
+ if (! NILP (source))
+ {
+ CONS_TO_INTEGER (source, Window, target_window);
+ if (! target_window)
+ target_window = FRAME_DISPLAY_INFO (f)->root_window;
+ }
+
+ block_input ();
+
+ prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (prop), False);
+ rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
+ prop_atom, 0, 0, False, AnyPropertyType,
+ &actual_type, &actual_format, &actual_size,
+ &bytes_remaining, &tmp_data);
+ if (rc == Success /* no invalid params */
+ && actual_format == 0 /* but prop not found */
+ && NILP (source)
+ && target_window != FRAME_OUTER_WINDOW (f))
+ {
+ /* analogous behavior to x-window-property: if property isn't found
+ on the frame's inner window and no alternate window id was
+ provided, try the frame's outer window. */
+ target_window = FRAME_OUTER_WINDOW (f);
+ rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
+ prop_atom, 0, 0, False, AnyPropertyType,
+ &actual_type, &actual_format, &actual_size,
+ &bytes_remaining, &tmp_data);
+ }
+
+ if (rc == Success && actual_format != 0)
+ {
+ XFree (tmp_data);
+
+ prop_attr = make_uninit_vector (3);
+ ASET (prop_attr, 0, make_number (actual_type));
+ ASET (prop_attr, 1, make_number (actual_format));
+ ASET (prop_attr, 2, make_number (bytes_remaining / (actual_format >> 3)));
+ }
+
+ unblock_input ();
+ return prop_attr;
+}
+
/***********************************************************************
Tool tips
***********************************************************************/
-static Lisp_Object x_create_tip_frame (struct x_display_info *,
- Lisp_Object, Lisp_Object);
static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,
Lisp_Object, int, int, int *, int *);
@@ -5363,9 +5437,7 @@ unwind_create_tip_frame (Lisp_Object frame)
when this happens. */
static Lisp_Object
-x_create_tip_frame (struct x_display_info *dpyinfo,
- Lisp_Object parms,
- Lisp_Object text)
+x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms)
{
struct frame *f;
Lisp_Object frame;
@@ -5373,8 +5445,6 @@ x_create_tip_frame (struct x_display_info *dpyinfo,
int width, height;
ptrdiff_t count = SPECPDL_INDEX ();
bool face_change_before = face_change;
- Lisp_Object buffer;
- struct buffer *old_buffer;
int x_width = 0, x_height = 0;
if (!dpyinfo->terminal->name)
@@ -5390,23 +5460,9 @@ x_create_tip_frame (struct x_display_info *dpyinfo,
error ("Invalid frame name--not a string or nil");
frame = Qnil;
- f = make_frame (true);
+ f = make_frame (false);
+ f->wants_modeline = false;
XSETFRAME (frame, f);
-
- AUTO_STRING (tip, " *tip*");
- buffer = Fget_buffer_create (tip);
- /* Use set_window_buffer instead of Fset_window_buffer (see
- discussion of bug#11984, bug#12025, bug#12026). */
- set_window_buffer (FRAME_ROOT_WINDOW (f), buffer, false, false);
- old_buffer = current_buffer;
- set_buffer_internal_1 (XBUFFER (buffer));
- bset_truncate_lines (current_buffer, Qnil);
- specbind (Qinhibit_read_only, Qt);
- specbind (Qinhibit_modification_hooks, Qt);
- Ferase_buffer ();
- Finsert (1, &text);
- set_buffer_internal_1 (old_buffer);
-
record_unwind_protect (unwind_create_tip_frame, frame);
f->terminal = dpyinfo->terminal;
@@ -5648,8 +5704,6 @@ x_create_tip_frame (struct x_display_info *dpyinfo,
{
Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
- /* Set tip_frame here, so that */
- tip_frame = frame;
call2 (Qface_set_after_frame_default, frame, Qnil);
if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
@@ -5788,6 +5842,85 @@ compute_tip_xy (struct frame *f, Lisp_Object parms, Lisp_Object dx, Lisp_Object
}
+/* Hide tooltip. Delete its frame if DELETE is true. */
+static Lisp_Object
+x_hide_tip (bool delete)
+{
+ if (!NILP (tip_timer))
+ {
+ call1 (Qcancel_timer, tip_timer);
+ tip_timer = Qnil;
+ }
+
+
+ if (NILP (tip_frame)
+ || (!delete && FRAMEP (tip_frame)
+ && !FRAME_VISIBLE_P (XFRAME (tip_frame))))
+ return Qnil;
+ else
+ {
+ ptrdiff_t count;
+ Lisp_Object was_open = Qnil;
+
+ count = SPECPDL_INDEX ();
+ specbind (Qinhibit_redisplay, Qt);
+ specbind (Qinhibit_quit, Qt);
+
+#ifdef USE_GTK
+ {
+ /* When using system tooltip, tip_frame is the Emacs frame on
+ which the tip is shown. */
+ struct frame *f = XFRAME (tip_frame);
+
+ if (FRAME_LIVE_P (f) && xg_hide_tooltip (f))
+ {
+ tip_frame = Qnil;
+ was_open = Qt;
+ }
+ }
+#endif
+
+ if (FRAMEP (tip_frame))
+ {
+ if (delete)
+ {
+ delete_frame (tip_frame, Qnil);
+ tip_frame = Qnil;
+ }
+ else
+ x_make_frame_invisible (XFRAME (tip_frame));
+
+ was_open = Qt;
+
+#ifdef USE_LUCID
+ /* Bloodcurdling hack alert: The Lucid menu bar widget's
+ redisplay procedure is not called when a tip frame over
+ menu items is unmapped. Redisplay the menu manually... */
+ {
+ Widget w;
+ struct frame *f = SELECTED_FRAME ();
+ if (FRAME_X_P (f) && FRAME_LIVE_P (f))
+ {
+ w = f->output_data.x->menubar_widget;
+
+ if (!DoesSaveUnders (FRAME_DISPLAY_INFO (f)->screen)
+ && w != NULL)
+ {
+ block_input ();
+ xlwmenu_redisplay (w);
+ unblock_input ();
+ }
+ }
+ }
+#endif /* USE_LUCID */
+ }
+ else
+ tip_frame = Qnil;
+
+ return unbind_to (count, was_open);
+ }
+}
+
DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
doc: /* Show STRING in a "tooltip" window on frame FRAME.
A tooltip window is a small X window displaying a string.
@@ -5820,15 +5953,17 @@ A tooltip's maximum size is specified by `x-max-tooltip-size'.
Text larger than the specified size is clipped. */)
(Lisp_Object string, Lisp_Object frame, Lisp_Object parms, Lisp_Object timeout, Lisp_Object dx, Lisp_Object dy)
{
- struct frame *f;
+ struct frame *f, *tip_f;
struct window *w;
int root_x, root_y;
struct buffer *old_buffer;
struct text_pos pos;
- int i, width, height;
- bool seen_reversed_p;
+ int width, height;
int old_windows_or_buffers_changed = windows_or_buffers_changed;
ptrdiff_t count = SPECPDL_INDEX ();
+ ptrdiff_t count_1;
+ Lisp_Object window, size;
+ AUTO_STRING (tip, " *tip*");
specbind (Qinhibit_redisplay, Qt);
@@ -5877,22 +6012,23 @@ Text larger than the specified size is clipped. */)
if (NILP (last_show_tip_args))
last_show_tip_args = Fmake_vector (make_number (3), Qnil);
- if (!NILP (tip_frame))
+ if (FRAMEP (tip_frame) && FRAME_LIVE_P (XFRAME (tip_frame)))
{
Lisp_Object last_string = AREF (last_show_tip_args, 0);
Lisp_Object last_frame = AREF (last_show_tip_args, 1);
Lisp_Object last_parms = AREF (last_show_tip_args, 2);
- if (EQ (frame, last_frame)
- && !NILP (Fequal (last_string, string))
+ if (FRAME_VISIBLE_P (XFRAME (tip_frame))
+ && EQ (frame, last_frame)
+ && !NILP (Fequal_including_properties (last_string, string))
&& !NILP (Fequal (last_parms, parms)))
{
- struct frame *tip_f = XFRAME (tip_frame);
-
/* Only DX and DY have changed. */
+ tip_f = XFRAME (tip_frame);
if (!NILP (tip_timer))
{
Lisp_Object timer = tip_timer;
+
tip_timer = Qnil;
call1 (Qcancel_timer, timer);
}
@@ -5903,41 +6039,102 @@ Text larger than the specified size is clipped. */)
XMoveWindow (FRAME_X_DISPLAY (tip_f), FRAME_X_WINDOW (tip_f),
root_x, root_y);
unblock_input ();
+
goto start_timer;
}
- }
+ else if (tooltip_reuse_hidden_frame && EQ (frame, last_frame))
+ {
+ bool delete = false;
+ Lisp_Object tail, elt, parm, last;
+
+ /* Check if every parameter in PARMS has the same value in
+ last_parms unless it should be ignored by means of
+ Vtooltip_reuse_hidden_frame_parameters. This may destruct
+ last_parms which, however, will be recreated below. */
+ for (tail = parms; CONSP (tail); tail = XCDR (tail))
+ {
+ elt = XCAR (tail);
+ parm = Fcar (elt);
+ /* The left, top, right and bottom parameters are handled
+ by compute_tip_xy so they can be ignored here. */
+ if (!EQ (parm, Qleft) && !EQ (parm, Qtop)
+ && !EQ (parm, Qright) && !EQ (parm, Qbottom))
+ {
+ last = Fassq (parm, last_parms);
+ if (NILP (Fequal (Fcdr (elt), Fcdr (last))))
+ {
+ /* We lost, delete the old tooltip. */
+ delete = true;
+ break;
+ }
+ else
+ last_parms = call2 (Qassq_delete_all, parm, last_parms);
+ }
+ else
+ last_parms = call2 (Qassq_delete_all, parm, last_parms);
+ }
- /* Hide a previous tip, if any. */
- Fx_hide_tip ();
+ /* Now check if every parameter in what is left of last_parms
+ with a non-nil value has an association in PARMS unless it
+ should be ignored by means of
+ Vtooltip_reuse_hidden_frame_parameters. */
+ for (tail = last_parms; CONSP (tail); tail = XCDR (tail))
+ {
+ elt = XCAR (tail);
+ parm = Fcar (elt);
+ if (!EQ (parm, Qleft) && !EQ (parm, Qtop) && !EQ (parm, Qright)
+ && !EQ (parm, Qbottom) && !NILP (Fcdr (elt)))
+ {
+ /* We lost, delete the old tooltip. */
+ delete = true;
+ break;
+ }
+ }
+
+ x_hide_tip (delete);
+ }
+ else
+ x_hide_tip (true);
+ }
+ else
+ x_hide_tip (true);
ASET (last_show_tip_args, 0, string);
ASET (last_show_tip_args, 1, frame);
ASET (last_show_tip_args, 2, parms);
- /* Add default values to frame parameters. */
- if (NILP (Fassq (Qname, parms)))
- parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
- if (NILP (Fassq (Qinternal_border_width, parms)))
- parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms);
- if (NILP (Fassq (Qborder_width, parms)))
- parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
- if (NILP (Fassq (Qbottom_divider_width, parms)))
- parms = Fcons (Fcons (Qbottom_divider_width, make_number (0)), parms);
- if (NILP (Fassq (Qright_divider_width, parms)))
- parms = Fcons (Fcons (Qright_divider_width, make_number (0)), parms);
- if (NILP (Fassq (Qborder_color, parms)))
- parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
- if (NILP (Fassq (Qbackground_color, parms)))
- parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
- parms);
-
- /* Create a frame for the tooltip, and record it in the global
- variable tip_frame. */
- frame = x_create_tip_frame (FRAME_DISPLAY_INFO (f), parms, string);
- f = XFRAME (frame);
-
- /* Set up the frame's root window. */
- w = XWINDOW (FRAME_ROOT_WINDOW (f));
+ if (!FRAMEP (tip_frame) || !FRAME_LIVE_P (XFRAME (tip_frame)))
+ {
+ /* Add default values to frame parameters. */
+ if (NILP (Fassq (Qname, parms)))
+ parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
+ if (NILP (Fassq (Qinternal_border_width, parms)))
+ parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms);
+ if (NILP (Fassq (Qborder_width, parms)))
+ parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
+ if (NILP (Fassq (Qborder_color, parms)))
+ parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
+ if (NILP (Fassq (Qbackground_color, parms)))
+ parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
+ parms);
+
+ /* Create a frame for the tooltip, and record it in the global
+ variable tip_frame. */
+ if (NILP (tip_frame = x_create_tip_frame (FRAME_DISPLAY_INFO (f), parms)))
+ /* Creating the tip frame failed. */
+ return unbind_to (count, Qnil);
+ }
+
+ tip_f = XFRAME (tip_frame);
+ window = FRAME_ROOT_WINDOW (tip_f);
+ set_window_buffer (window, Fget_buffer_create (tip), false, false);
+ w = XWINDOW (window);
+ w->pseudo_window_p = true;
+
+ /* Set up the frame's root window. Note: The following code does not
+ try to size the window or its frame correctly. Its only purpose is
+ to make the subsequent text size calculations work. The right
+ sizes should get installed when the toolkit gets back to us. */
w->left_col = 0;
w->top_line = 0;
w->pixel_left = 0;
@@ -5956,130 +6153,47 @@ Text larger than the specified size is clipped. */)
w->total_lines = 40;
}
- w->pixel_width = w->total_cols * FRAME_COLUMN_WIDTH (f);
- w->pixel_height = w->total_lines * FRAME_LINE_HEIGHT (f);
-
- FRAME_TOTAL_COLS (f) = w->total_cols;
- adjust_frame_glyphs (f);
- w->pseudo_window_p = true;
+ w->pixel_width = w->total_cols * FRAME_COLUMN_WIDTH (tip_f);
+ w->pixel_height = w->total_lines * FRAME_LINE_HEIGHT (tip_f);
+ FRAME_TOTAL_COLS (tip_f) = w->total_cols;
+ adjust_frame_glyphs (tip_f);
- /* Display the tooltip text in a temporary buffer. */
+ /* Insert STRING into root window's buffer and fit the frame to the
+ buffer. */
+ count_1 = SPECPDL_INDEX ();
old_buffer = current_buffer;
- set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->contents));
+ set_buffer_internal_1 (XBUFFER (w->contents));
bset_truncate_lines (current_buffer, Qnil);
+ specbind (Qinhibit_read_only, Qt);
+ specbind (Qinhibit_modification_hooks, Qt);
+ specbind (Qinhibit_point_motion_hooks, Qt);
+ Ferase_buffer ();
+ Finsert (1, &string);
clear_glyph_matrix (w->desired_matrix);
clear_glyph_matrix (w->current_matrix);
SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
- try_window (FRAME_ROOT_WINDOW (f), pos, TRY_WINDOW_IGNORE_FONTS_CHANGE);
-
- /* Compute width and height of the tooltip. */
- width = height = 0;
- seen_reversed_p = false;
- for (i = 0; i < w->desired_matrix->nrows; ++i)
- {
- struct glyph_row *row = &w->desired_matrix->rows[i];
- struct glyph *last;
- int row_width;
-
- /* Stop at the first empty row at the end. */
- if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
- break;
-
- /* Let the row go over the full width of the frame. */
- row->full_width_p = true;
-
- row_width = row->pixel_width;
- if (row->used[TEXT_AREA])
- {
- /* There's a glyph at the end of rows that is used to place
- the cursor there. Don't include the width of this glyph. */
- if (!row->reversed_p)
- {
- last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
- if (NILP (last->object))
- row_width -= last->pixel_width;
- }
- else
- {
- /* There could be a stretch glyph at the beginning of R2L
- rows that is produced by extend_face_to_end_of_line.
- Don't count that glyph. */
- struct glyph *g = row->glyphs[TEXT_AREA];
-
- if (g->type == STRETCH_GLYPH && NILP (g->object))
- {
- row_width -= g->pixel_width;
- seen_reversed_p = true;
- }
- }
- }
-
- height += row->height;
- width = max (width, row_width);
- }
-
- /* If we've seen partial-length R2L rows, we need to re-adjust the
- tool-tip frame width and redisplay it again, to avoid over-wide
- tips due to the stretch glyph that extends R2L lines to full
- width of the frame. */
- if (seen_reversed_p)
- {
- /* w->total_cols and FRAME_TOTAL_COLS want the width in columns,
- not in pixels. */
- w->pixel_width = width;
- width /= WINDOW_FRAME_COLUMN_WIDTH (w);
- w->total_cols = width;
- FRAME_TOTAL_COLS (f) = width;
- SET_FRAME_WIDTH (f, width);
- adjust_frame_glyphs (f);
- clear_glyph_matrix (w->desired_matrix);
- clear_glyph_matrix (w->current_matrix);
- try_window (FRAME_ROOT_WINDOW (f), pos, 0);
- width = height = 0;
- /* Recompute width and height of the tooltip. */
- for (i = 0; i < w->desired_matrix->nrows; ++i)
- {
- struct glyph_row *row = &w->desired_matrix->rows[i];
- struct glyph *last;
- int row_width;
-
- if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
- break;
- row->full_width_p = true;
- row_width = row->pixel_width;
- if (row->used[TEXT_AREA] && !row->reversed_p)
- {
- last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
- if (NILP (last->object))
- row_width -= last->pixel_width;
- }
-
- height += row->height;
- width = max (width, row_width);
- }
- }
-
- /* Add the frame's internal border to the width and height the X
- window should have. */
- height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
- width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
-
- /* Move the tooltip window where the mouse pointer is. Resize and
- show it. */
- compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
-
+ try_window (window, pos, TRY_WINDOW_IGNORE_FONTS_CHANGE);
+ /* Calculate size of tooltip window. */
+ size = Fwindow_text_pixel_size (window, Qnil, Qnil, Qnil,
+ make_number (w->pixel_height), Qnil);
+ /* Add the frame's internal border to calculated size. */
+ width = XINT (Fcar (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f);
+ height = XINT (Fcdr (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f);
+
+ /* Calculate position of tooltip frame. */
+ compute_tip_xy (tip_f, parms, dx, dy, width, height, &root_x, &root_y);
+
+ /* Show tooltip frame. */
block_input ();
- XMoveResizeWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+ XMoveResizeWindow (FRAME_X_DISPLAY (tip_f), FRAME_X_WINDOW (tip_f),
root_x, root_y, width, height);
- XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
+ XMapRaised (FRAME_X_DISPLAY (tip_f), FRAME_X_WINDOW (tip_f));
unblock_input ();
- /* Draw into the window. */
w->must_be_updated_p = true;
update_single_window (w);
-
- /* Restore original current buffer. */
set_buffer_internal_1 (old_buffer);
+ unbind_to (count_1, Qnil);
windows_or_buffers_changed = old_windows_or_buffers_changed;
start_timer:
@@ -6096,66 +6210,9 @@ DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
Value is t if tooltip was open, nil otherwise. */)
(void)
{
- ptrdiff_t count;
- Lisp_Object deleted, frame, timer;
-
- /* Return quickly if nothing to do. */
- if (NILP (tip_timer) && NILP (tip_frame))
- return Qnil;
-
- frame = tip_frame;
- timer = tip_timer;
- tip_frame = tip_timer = deleted = Qnil;
-
- count = SPECPDL_INDEX ();
- specbind (Qinhibit_redisplay, Qt);
- specbind (Qinhibit_quit, Qt);
-
- if (!NILP (timer))
- call1 (Qcancel_timer, timer);
-
-#ifdef USE_GTK
- {
- /* When using system tooltip, tip_frame is the Emacs frame on which
- the tip is shown. */
- struct frame *f = XFRAME (frame);
- if (FRAME_LIVE_P (f) && xg_hide_tooltip (f))
- frame = Qnil;
- }
-#endif
-
- if (FRAMEP (frame))
- {
- delete_frame (frame, Qnil);
- deleted = Qt;
-
-#ifdef USE_LUCID
- /* Bloodcurdling hack alert: The Lucid menu bar widget's
- redisplay procedure is not called when a tip frame over menu
- items is unmapped. Redisplay the menu manually... */
- {
- Widget w;
- struct frame *f = SELECTED_FRAME ();
- if (FRAME_X_P (f) && FRAME_LIVE_P (f))
- {
- w = f->output_data.x->menubar_widget;
-
- if (!DoesSaveUnders (FRAME_DISPLAY_INFO (f)->screen)
- && w != NULL)
- {
- block_input ();
- xlwmenu_redisplay (w);
- unblock_input ();
- }
- }
- }
-#endif /* USE_LUCID */
- }
-
- return unbind_to (count, deleted);
+ return x_hide_tip (!tooltip_reuse_hidden_frame);
}
-
/***********************************************************************
File selection dialog
@@ -6371,7 +6428,7 @@ value of DIR as in previous invocations; this is standard Windows behavior. */)
/* Make "Cancel" equivalent to C-g. */
if (NILP (file))
- Fsignal (Qquit, Qnil);
+ quit ();
decoded_file = DECODE_FILE (file);
@@ -6443,7 +6500,7 @@ value of DIR as in previous invocations; this is standard Windows behavior. */)
/* Make "Cancel" equivalent to C-g. */
if (NILP (file))
- Fsignal (Qquit, Qnil);
+ quit ();
decoded_file = DECODE_FILE (file);
@@ -6483,7 +6540,7 @@ nil, it defaults to the selected frame. */)
default_name = xlispstrdup (font_param);
else
{
- font_param = Fframe_parameter (frame, Qfont_param);
+ font_param = Fframe_parameter (frame, Qfont_parameter);
if (STRINGP (font_param))
default_name = xlispstrdup (font_param);
}
@@ -6494,7 +6551,7 @@ nil, it defaults to the selected frame. */)
unblock_input ();
if (NILP (font))
- Fsignal (Qquit, Qnil);
+ quit ();
return unbind_to (count, font);
}
@@ -6815,8 +6872,9 @@ syms_of_xfns (void)
DEFSYM (Qundefined_color, "undefined-color");
DEFSYM (Qcompound_text, "compound-text");
DEFSYM (Qcancel_timer, "cancel-timer");
- DEFSYM (Qfont_param, "font-parameter");
+ DEFSYM (Qfont_parameter, "font-parameter");
DEFSYM (Qmono, "mono");
+ DEFSYM (Qassq_delete_all, "assq-delete-all");
#ifdef USE_CAIRO
DEFSYM (Qpdf, "pdf");
@@ -6988,6 +7046,7 @@ When using Gtk+ tooltips, the tooltip face is not used. */);
defsubr (&Sx_change_window_property);
defsubr (&Sx_delete_window_property);
defsubr (&Sx_window_property);
+ defsubr (&Sx_window_property_attributes);
defsubr (&Sxw_display_color_p);
defsubr (&Sx_display_grayscale_p);