system-specific. VALUE must contain unsigned integer data in native
endian-ness in multiples of the size of the C type 'long': the low 32
bits of each such number are used as the value of each element of the
-property. */)
+property.
+
+Wait for the request to complete and signal any error, unless
+`x-fast-protocol-requests' is non-nil, in which case errors will be
+silently ignored. */)
(Lisp_Object prop, Lisp_Object value, Lisp_Object frame,
Lisp_Object type, Lisp_Object format, Lisp_Object outer_p,
Lisp_Object window_id)
{
- struct frame *f = decode_window_system_frame (frame);
+ struct frame *f;
Atom prop_atom;
Atom target_type = XA_STRING;
int element_format = 8;
unsigned char *data;
int nelements;
Window target_window;
+ struct x_display_info *dpyinfo;
#ifdef USE_XCB
bool intern_prop;
bool intern_target;
bool rc;
#endif
+ f = decode_window_system_frame (frame);
+ dpyinfo = FRAME_DISPLAY_INFO (f);
+
CHECK_STRING (prop);
if (! NILP (format))
{
CONS_TO_INTEGER (window_id, Window, target_window);
if (! target_window)
- target_window = FRAME_DISPLAY_INFO (f)->root_window;
+ target_window = dpyinfo->root_window;
}
else
{
block_input ();
#ifndef USE_XCB
- prop_atom = x_intern_cached_atom (FRAME_DISPLAY_INFO (f),
- SSDATA (prop), false);
+ prop_atom = x_intern_cached_atom (dpyinfo, SSDATA (prop),
+ false);
if (! NILP (type))
{
CHECK_STRING (type);
- target_type = x_intern_cached_atom (FRAME_DISPLAY_INFO (f),
- SSDATA (type), false);
+ target_type = x_intern_cached_atom (dpyinfo, SSDATA (type),
+ false);
}
#else
rc = true;
intern_target = true;
intern_prop = true;
- prop_atom = x_intern_cached_atom (FRAME_DISPLAY_INFO (f),
- SSDATA (prop), true);
+ prop_atom = x_intern_cached_atom (dpyinfo, SSDATA (prop),
+ true);
if (prop_atom != None)
intern_prop = false;
else
prop_atom_cookie
- = xcb_intern_atom (FRAME_DISPLAY_INFO (f)->xcb_connection,
+ = xcb_intern_atom (dpyinfo->xcb_connection,
0, SBYTES (prop), SSDATA (prop));
if (!NILP (type))
{
CHECK_STRING (type);
- target_type = x_intern_cached_atom (FRAME_DISPLAY_INFO (f),
- SSDATA (type), true);
+ target_type = x_intern_cached_atom (dpyinfo, SSDATA (type),
+ true);
if (target_type)
intern_target = false;
else
target_type_cookie
- = xcb_intern_atom (FRAME_DISPLAY_INFO (f)->xcb_connection,
+ = xcb_intern_atom (dpyinfo->xcb_connection,
0, SBYTES (type), SSDATA (type));
}
if (intern_prop)
{
- reply = xcb_intern_atom_reply (FRAME_DISPLAY_INFO (f)->xcb_connection,
+ reply = xcb_intern_atom_reply (dpyinfo->xcb_connection,
prop_atom_cookie, &generic_error);
if (reply)
if (!NILP (type) && intern_target)
{
- reply = xcb_intern_atom_reply (FRAME_DISPLAY_INFO (f)->xcb_connection,
+ reply = xcb_intern_atom_reply (dpyinfo->xcb_connection,
target_type_cookie, &generic_error);
if (reply)
error ("Failed to intern type or property atom");
#endif
- x_catch_errors (FRAME_X_DISPLAY (f));
- XChangeProperty (FRAME_X_DISPLAY (f), target_window,
- prop_atom, target_type, element_format, PropModeReplace,
- data, nelements);
+ x_catch_errors_for_lisp (dpyinfo);
- if (CONSP (value)) xfree (data);
- x_check_errors (FRAME_X_DISPLAY (f),
- "Couldn't change window property: %s");
- x_uncatch_errors_after_check ();
+ XChangeProperty (dpyinfo->display, target_window,
+ prop_atom, target_type, element_format,
+ PropModeReplace, data, nelements);
+
+ if (CONSP (value))
+ xfree (data);
+
+ x_check_errors_for_lisp (dpyinfo,
+ "Couldn't change window property: %s");
+ x_uncatch_errors_for_lisp (dpyinfo);
unblock_input ();
return value;
across X displays or screens on the same display, so FRAME provides
context for the window ID.
-Value is PROP. */)
+Value is PROP.
+
+Wait for the request to complete and signal any error, unless
+`x-fast-protocol-requests' is non-nil, in which case errors will be
+silently ignored. */)
(Lisp_Object prop, Lisp_Object frame, Lisp_Object window_id)
{
struct frame *f = decode_window_system_frame (frame);
prop_atom = x_intern_cached_atom (FRAME_DISPLAY_INFO (f),
SSDATA (prop), false);
- x_catch_errors (FRAME_X_DISPLAY (f));
+ x_catch_errors_for_lisp (FRAME_DISPLAY_INFO (f));
XDeleteProperty (FRAME_X_DISPLAY (f), target_window, prop_atom);
- x_check_errors (FRAME_X_DISPLAY (f),
- "Couldn't delete window property: %s");
- x_uncatch_errors_after_check ();
+ x_check_errors_for_lisp (FRAME_DISPLAY_INFO (f),
+ "Couldn't delete window property: %s");
+ x_uncatch_errors_for_lisp (FRAME_DISPLAY_INFO (f));
unblock_input ();
return prop;
the Atom is sent. If a value is a cons, it is converted to a 32 bit number
with the high 16 bits from the car and the lower 16 bit from the cdr.
If more values than fits into the event is given, the excessive values
-are ignored. */)
+are ignored.
+
+Wait for the event to be sent and signal any error, unless
+`x-fast-protocol-requests' is non-nil, in which case errors will be
+silently ignored. */)
(Lisp_Object display, Lisp_Object dest, Lisp_Object from,
Lisp_Object message_type, Lisp_Object format, Lisp_Object values)
{
the destination window. But if we are sending to the root window,
there is no such client. Then we set the event mask to 0xffffff. The
event then goes to clients selecting for events on the root window. */
- x_catch_errors (dpyinfo->display);
+ x_catch_errors_for_lisp (dpyinfo);
{
bool propagate = !to_root;
long mask = to_root ? 0xffffff : 0;
XSendEvent (dpyinfo->display, wdest, propagate, mask, &event);
XFlush (dpyinfo->display);
}
- x_uncatch_errors ();
+ x_check_errors_for_lisp (dpyinfo, "Failed to send client event: %s");
+ x_uncatch_errors_for_lisp (dpyinfo);
unblock_input ();
}
#endif
}
+/* Error handling functions for Lisp functions that expose X protocol
+ requests. They are mostly like `x_catch_errors' and friends, but
+ respect `x-fast-protocol-requests'. */
+
+void
+x_catch_errors_for_lisp (struct x_display_info *dpyinfo)
+{
+ if (!x_fast_protocol_requests)
+ x_catch_errors (dpyinfo->display);
+ else
+ x_ignore_errors_for_next_request (dpyinfo);
+}
+
+void
+x_check_errors_for_lisp (struct x_display_info *dpyinfo,
+ const char *format)
+{
+ if (!x_fast_protocol_requests)
+ x_check_errors (dpyinfo->display, format);
+}
+
+void
+x_uncatch_errors_for_lisp (struct x_display_info *dpyinfo)
+{
+ if (!x_fast_protocol_requests)
+ x_uncatch_errors ();
+ else
+ x_stop_ignoring_errors (dpyinfo);
+}
+
void
syms_of_xterm (void)
{
to emulate the drag-and-drop of `STRING', `UTF8_STRING',
`COMPOUND_TEXT' or `TEXT'. */);
x_dnd_use_unsupported_drop = true;
+
+ DEFVAR_BOOL ("x-fast-protocol-requests", x_fast_protocol_requests,
+ doc: /* Whether or not X protocol-related functions should wait for errors.
+When this is nil, functions such as `x-delete-window-property',
+`x-change-window-property' and `x-send-client-message' will wait for a
+reply from the X server, and signal any errors that occurred while
+executing the protocol request. Otherwise, errors will be silently
+ignored without waiting, which is generally faster. */);
+ x_fast_protocol_requests = false;
}