@var{display} should be the name of an X display (a string).
@end deffn
+@cindex monitor change functions
+@defvar display-monitors-changed-functions
+This variable is an abnormal hook run when the monitor configuration
+changes, which can happen if a monitor is rotated, moved, added or
+removed from a multiple-monitor setup, if the primary monitor changes,
+or if the resolution of a monitor changes. It is called with a single
+argument consisting of the terminal on which the monitor configuration
+changed.
+@end defvar
+
@node Frame Geometry
@section Frame Geometry
@cindex frame geometry
\f
* Lisp Changes in Emacs 29.1
++++
+** New hook 'display-monitors-changed-functions'.
+It is called whenever the configuration of different monitors on a
+display changes.
+
+++
** 'prin1' and 'prin1-to-string' now take an optional OVERRIDES parameter.
This parameter can be used to override values of print-related settings.
}
#endif
+ case MONITORS_CHANGED_EVENT:
+ {
+ kbd_fetch_ptr = next_kbd_event (event);
+ input_pending = readable_events (0);
+
+ CALLN (Frun_hook_with_args,
+ Qdisplay_monitors_changed_functions,
+ event->ie.arg);
+
+ break;
+ }
+
#ifdef HAVE_EXT_MENU_BAR
case MENU_BAR_ACTIVATE_EVENT:
{
DEFSYM (Qtouchscreen_end, "touchscreen-end");
DEFSYM (Qtouchscreen_update, "touchscreen-update");
DEFSYM (Qpinch, "pinch");
+ DEFSYM (Qdisplay_monitors_changed_functions,
+ "display-monitors-changed-functions");
DEFSYM (Qcoding, "coding");
moved. */);
mwheel_coalesce_scroll_events = true;
+ DEFVAR_LISP ("display-monitors-changed-functions", Vdisplay_monitors_changed_functions,
+ doc: /* Abnormal hook run when the monitor configuration changes.
+This can happen if a monitor is rotated, moved, plugged in or removed
+from a multi-monitor setup, if the primary monitor changes, or if the
+resolution of a monitor changes. The hook should accept a single
+argument, which is the terminal on which the monitor configuration
+changed. */);
+ Vdisplay_monitors_changed_functions = Qnil;
+
pdumper_do_now_and_after_load (syms_of_keyboard_for_pdumper);
}
INLINE_HEADER_BEGIN
-enum scroll_bar_part {
+enum scroll_bar_part
+{
scroll_bar_nowhere,
scroll_bar_above_handle,
scroll_bar_handle,
#endif
#ifdef HAVE_XWIDGETS
- /* events generated by xwidgets*/
+ /* An event generated by an xwidget to tell us something. */
, XWIDGET_EVENT
+
/* Event generated when WebKit asks us to display another widget. */
, XWIDGET_DISPLAY_EVENT
#endif
positive delta represents a change clockwise, and a negative
delta represents a change counter-clockwise. */
, PINCH_EVENT
+
+ /* In a MONITORS_CHANGED_EVENT, .arg gives the terminal on which the
+ monitor configuration changed. .timestamp gives the time on
+ which the monitors changed. */
+ , MONITORS_CHANGED_EVENT
};
/* Bit width of an enum event_kind tag at the start of structs and unions. */
}
}
}
+#endif
+#ifdef HAVE_XRANDR
+ if (dpyinfo->xrandr_supported_p
+ && (event->type == (dpyinfo->xrandr_event_base
+ + RRScreenChangeNotify)
+ || event->type == (dpyinfo->xrandr_event_base
+ + RRNotify)))
+ {
+ union buffered_input_event *ev;
+ Time timestamp;
+
+ if (event->type == (dpyinfo->xrandr_event_base
+ + RRScreenChangeNotify))
+ timestamp = ((XRRScreenChangeNotifyEvent *) event)->timestamp;
+ else
+ timestamp = 0;
+
+ ev = (kbd_store_ptr == kbd_buffer
+ ? kbd_buffer + KBD_BUFFER_SIZE - 1
+ : kbd_store_ptr - 1);
+
+ if (kbd_store_ptr != kbd_fetch_ptr
+ && ev->ie.kind == MONITORS_CHANGED_EVENT
+ && XTERMINAL (ev->ie.arg) == dpyinfo->terminal)
+ /* Don't store a MONITORS_CHANGED_EVENT if there is
+ already an undelivered event on the queue. */
+ goto OTHER;
+
+ inev.ie.kind = MONITORS_CHANGED_EVENT;
+ inev.ie.timestamp = timestamp;
+ XSETTERMINAL (inev.ie.arg, dpyinfo->terminal);
+ }
#endif
OTHER:
#ifdef USE_X_TOOLKIT
#endif
#ifdef HAVE_XRANDR
- int xrr_event_base, xrr_error_base;
- bool xrr_ok = false;
- xrr_ok = XRRQueryExtension (dpy, &xrr_event_base, &xrr_error_base);
- if (xrr_ok)
+ dpyinfo->xrandr_supported_p
+ = XRRQueryExtension (dpy, &dpyinfo->xrandr_event_base,
+ &dpyinfo->xrandr_error_base);
+ if (dpyinfo->xrandr_supported_p)
{
XRRQueryVersion (dpy, &dpyinfo->xrandr_major_version,
&dpyinfo->xrandr_minor_version);
+
+ if (dpyinfo->xrandr_major_version == 1
+ && dpyinfo->xrandr_minor_version >= 2)
+ XRRSelectInput (dpyinfo->display,
+ dpyinfo->root_window,
+ (RRScreenChangeNotifyMask
+ | RRCrtcChangeNotifyMask
+ | RROutputChangeNotifyMask
+ /* Emacs doesn't actually need this, but GTK
+ selects for it when the display is
+ initialized. */
+ | RROutputPropertyNotifyMask));
}
#endif
XModifierKeymap *modmap;
#ifdef HAVE_XRANDR
+ bool xrandr_supported_p;
+ int xrandr_event_base;
+ int xrandr_error_base;
int xrandr_major_version;
int xrandr_minor_version;
#endif