Add a hook run upon monitor configuration changes
* doc/lispref/frames.texi (Multiple Terminals): Document new hook `display-monitors-changed-functions'. * etc/NEWS: Announce new abnormal hook. * src/keyboard.c (kbd_buffer_get_event): Handle MONITORS_CHANGED_EVENT. (syms_of_keyboard): New hook and defsyms. * src/termhooks.h (enum event_kind): Add new event `MONITORS_CHANGED_EVENT'. * src/xterm.c (handle_one_xevent): Handle RRNotify and RRScreenChangeNotify events. (x_term_init): Select for RRScreenChange, RRCrtcChange and RROutputChange. * src/xterm.h (struct x_display_info): Improve RandR version detection.
This commit is contained in:
parent
1cbabe973b
commit
edf9700c3c
6 changed files with 98 additions and 6 deletions
|
@ -458,6 +458,16 @@ monitor, the same string as returned by the function
|
|||
@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
|
||||
|
|
5
etc/NEWS
5
etc/NEWS
|
@ -1850,6 +1850,11 @@ functions.
|
|||
|
||||
* 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.
|
||||
|
|
|
@ -4058,6 +4058,18 @@ kbd_buffer_get_event (KBOARD **kbp,
|
|||
}
|
||||
#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:
|
||||
{
|
||||
|
@ -12609,6 +12621,8 @@ See also `pre-command-hook'. */);
|
|||
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");
|
||||
|
||||
|
@ -12953,6 +12967,15 @@ Otherwise, a wheel event will be sent every time the mouse wheel is
|
|||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,8 @@ struct glyph;
|
|||
|
||||
INLINE_HEADER_BEGIN
|
||||
|
||||
enum scroll_bar_part {
|
||||
enum scroll_bar_part
|
||||
{
|
||||
scroll_bar_nowhere,
|
||||
scroll_bar_above_handle,
|
||||
scroll_bar_handle,
|
||||
|
@ -301,8 +302,9 @@ enum event_kind
|
|||
#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
|
||||
|
@ -349,6 +351,11 @@ enum event_kind
|
|||
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. */
|
||||
|
|
52
src/xterm.c
52
src/xterm.c
|
@ -20103,6 +20103,38 @@ handle_one_xevent (struct x_display_info *dpyinfo,
|
|||
}
|
||||
}
|
||||
}
|
||||
#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
|
||||
|
@ -24405,13 +24437,25 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
|
|||
#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
|
||||
|
||||
|
|
|
@ -602,6 +602,9 @@ struct x_display_info
|
|||
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
|
||||
|
|
Loading…
Add table
Reference in a new issue