aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPo Lu2022-05-21 11:17:34 +0800
committerPo Lu2022-05-21 11:17:34 +0800
commitedf9700c3ca65d92bdfca59306845ffc0717d690 (patch)
treeb00568cd7c0875f4ff23c3e6dc613c2d3c25a5b6
parent1cbabe973be88bed5a21d77defc3220034f7c91f (diff)
downloademacs-edf9700c3ca65d92bdfca59306845ffc0717d690.tar.gz
emacs-edf9700c3ca65d92bdfca59306845ffc0717d690.zip
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.
-rw-r--r--doc/lispref/frames.texi10
-rw-r--r--etc/NEWS5
-rw-r--r--src/keyboard.c23
-rw-r--r--src/termhooks.h11
-rw-r--r--src/xterm.c52
-rw-r--r--src/xterm.h3
6 files changed, 98 insertions, 6 deletions
diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi
index 5ea060871f4..7d600b5a0c5 100644
--- a/doc/lispref/frames.texi
+++ b/doc/lispref/frames.texi
@@ -458,6 +458,16 @@ monitor, the same string as returned by the function
458@var{display} should be the name of an X display (a string). 458@var{display} should be the name of an X display (a string).
459@end deffn 459@end deffn
460 460
461@cindex monitor change functions
462@defvar display-monitors-changed-functions
463This variable is an abnormal hook run when the monitor configuration
464changes, which can happen if a monitor is rotated, moved, added or
465removed from a multiple-monitor setup, if the primary monitor changes,
466or if the resolution of a monitor changes. It is called with a single
467argument consisting of the terminal on which the monitor configuration
468changed.
469@end defvar
470
461@node Frame Geometry 471@node Frame Geometry
462@section Frame Geometry 472@section Frame Geometry
463@cindex frame geometry 473@cindex frame geometry
diff --git a/etc/NEWS b/etc/NEWS
index 70f2c0e6daf..5eab8e23bb2 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1851,6 +1851,11 @@ functions.
1851* Lisp Changes in Emacs 29.1 1851* Lisp Changes in Emacs 29.1
1852 1852
1853+++ 1853+++
1854** New hook 'display-monitors-changed-functions'.
1855It is called whenever the configuration of different monitors on a
1856display changes.
1857
1858+++
1854** 'prin1' and 'prin1-to-string' now take an optional OVERRIDES parameter. 1859** 'prin1' and 'prin1-to-string' now take an optional OVERRIDES parameter.
1855This parameter can be used to override values of print-related settings. 1860This parameter can be used to override values of print-related settings.
1856 1861
diff --git a/src/keyboard.c b/src/keyboard.c
index 481633f92fe..a2322f1b49d 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -4058,6 +4058,18 @@ kbd_buffer_get_event (KBOARD **kbp,
4058 } 4058 }
4059#endif 4059#endif
4060 4060
4061 case MONITORS_CHANGED_EVENT:
4062 {
4063 kbd_fetch_ptr = next_kbd_event (event);
4064 input_pending = readable_events (0);
4065
4066 CALLN (Frun_hook_with_args,
4067 Qdisplay_monitors_changed_functions,
4068 event->ie.arg);
4069
4070 break;
4071 }
4072
4061#ifdef HAVE_EXT_MENU_BAR 4073#ifdef HAVE_EXT_MENU_BAR
4062 case MENU_BAR_ACTIVATE_EVENT: 4074 case MENU_BAR_ACTIVATE_EVENT:
4063 { 4075 {
@@ -12609,6 +12621,8 @@ See also `pre-command-hook'. */);
12609 DEFSYM (Qtouchscreen_end, "touchscreen-end"); 12621 DEFSYM (Qtouchscreen_end, "touchscreen-end");
12610 DEFSYM (Qtouchscreen_update, "touchscreen-update"); 12622 DEFSYM (Qtouchscreen_update, "touchscreen-update");
12611 DEFSYM (Qpinch, "pinch"); 12623 DEFSYM (Qpinch, "pinch");
12624 DEFSYM (Qdisplay_monitors_changed_functions,
12625 "display-monitors-changed-functions");
12612 12626
12613 DEFSYM (Qcoding, "coding"); 12627 DEFSYM (Qcoding, "coding");
12614 12628
@@ -12953,6 +12967,15 @@ Otherwise, a wheel event will be sent every time the mouse wheel is
12953moved. */); 12967moved. */);
12954 mwheel_coalesce_scroll_events = true; 12968 mwheel_coalesce_scroll_events = true;
12955 12969
12970 DEFVAR_LISP ("display-monitors-changed-functions", Vdisplay_monitors_changed_functions,
12971 doc: /* Abnormal hook run when the monitor configuration changes.
12972This can happen if a monitor is rotated, moved, plugged in or removed
12973from a multi-monitor setup, if the primary monitor changes, or if the
12974resolution of a monitor changes. The hook should accept a single
12975argument, which is the terminal on which the monitor configuration
12976changed. */);
12977 Vdisplay_monitors_changed_functions = Qnil;
12978
12956 pdumper_do_now_and_after_load (syms_of_keyboard_for_pdumper); 12979 pdumper_do_now_and_after_load (syms_of_keyboard_for_pdumper);
12957} 12980}
12958 12981
diff --git a/src/termhooks.h b/src/termhooks.h
index 08bde0aec0d..d7190e77362 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -31,7 +31,8 @@ struct glyph;
31 31
32INLINE_HEADER_BEGIN 32INLINE_HEADER_BEGIN
33 33
34enum scroll_bar_part { 34enum scroll_bar_part
35{
35 scroll_bar_nowhere, 36 scroll_bar_nowhere,
36 scroll_bar_above_handle, 37 scroll_bar_above_handle,
37 scroll_bar_handle, 38 scroll_bar_handle,
@@ -301,8 +302,9 @@ enum event_kind
301#endif 302#endif
302 303
303#ifdef HAVE_XWIDGETS 304#ifdef HAVE_XWIDGETS
304 /* events generated by xwidgets*/ 305 /* An event generated by an xwidget to tell us something. */
305 , XWIDGET_EVENT 306 , XWIDGET_EVENT
307
306 /* Event generated when WebKit asks us to display another widget. */ 308 /* Event generated when WebKit asks us to display another widget. */
307 , XWIDGET_DISPLAY_EVENT 309 , XWIDGET_DISPLAY_EVENT
308#endif 310#endif
@@ -349,6 +351,11 @@ enum event_kind
349 positive delta represents a change clockwise, and a negative 351 positive delta represents a change clockwise, and a negative
350 delta represents a change counter-clockwise. */ 352 delta represents a change counter-clockwise. */
351 , PINCH_EVENT 353 , PINCH_EVENT
354
355 /* In a MONITORS_CHANGED_EVENT, .arg gives the terminal on which the
356 monitor configuration changed. .timestamp gives the time on
357 which the monitors changed. */
358 , MONITORS_CHANGED_EVENT
352}; 359};
353 360
354/* Bit width of an enum event_kind tag at the start of structs and unions. */ 361/* Bit width of an enum event_kind tag at the start of structs and unions. */
diff --git a/src/xterm.c b/src/xterm.c
index cbe6426447e..b321f43da16 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -20104,6 +20104,38 @@ handle_one_xevent (struct x_display_info *dpyinfo,
20104 } 20104 }
20105 } 20105 }
20106#endif 20106#endif
20107#ifdef HAVE_XRANDR
20108 if (dpyinfo->xrandr_supported_p
20109 && (event->type == (dpyinfo->xrandr_event_base
20110 + RRScreenChangeNotify)
20111 || event->type == (dpyinfo->xrandr_event_base
20112 + RRNotify)))
20113 {
20114 union buffered_input_event *ev;
20115 Time timestamp;
20116
20117 if (event->type == (dpyinfo->xrandr_event_base
20118 + RRScreenChangeNotify))
20119 timestamp = ((XRRScreenChangeNotifyEvent *) event)->timestamp;
20120 else
20121 timestamp = 0;
20122
20123 ev = (kbd_store_ptr == kbd_buffer
20124 ? kbd_buffer + KBD_BUFFER_SIZE - 1
20125 : kbd_store_ptr - 1);
20126
20127 if (kbd_store_ptr != kbd_fetch_ptr
20128 && ev->ie.kind == MONITORS_CHANGED_EVENT
20129 && XTERMINAL (ev->ie.arg) == dpyinfo->terminal)
20130 /* Don't store a MONITORS_CHANGED_EVENT if there is
20131 already an undelivered event on the queue. */
20132 goto OTHER;
20133
20134 inev.ie.kind = MONITORS_CHANGED_EVENT;
20135 inev.ie.timestamp = timestamp;
20136 XSETTERMINAL (inev.ie.arg, dpyinfo->terminal);
20137 }
20138#endif
20107 OTHER: 20139 OTHER:
20108#ifdef USE_X_TOOLKIT 20140#ifdef USE_X_TOOLKIT
20109 block_input (); 20141 block_input ();
@@ -24405,13 +24437,25 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
24405#endif 24437#endif
24406 24438
24407#ifdef HAVE_XRANDR 24439#ifdef HAVE_XRANDR
24408 int xrr_event_base, xrr_error_base; 24440 dpyinfo->xrandr_supported_p
24409 bool xrr_ok = false; 24441 = XRRQueryExtension (dpy, &dpyinfo->xrandr_event_base,
24410 xrr_ok = XRRQueryExtension (dpy, &xrr_event_base, &xrr_error_base); 24442 &dpyinfo->xrandr_error_base);
24411 if (xrr_ok) 24443 if (dpyinfo->xrandr_supported_p)
24412 { 24444 {
24413 XRRQueryVersion (dpy, &dpyinfo->xrandr_major_version, 24445 XRRQueryVersion (dpy, &dpyinfo->xrandr_major_version,
24414 &dpyinfo->xrandr_minor_version); 24446 &dpyinfo->xrandr_minor_version);
24447
24448 if (dpyinfo->xrandr_major_version == 1
24449 && dpyinfo->xrandr_minor_version >= 2)
24450 XRRSelectInput (dpyinfo->display,
24451 dpyinfo->root_window,
24452 (RRScreenChangeNotifyMask
24453 | RRCrtcChangeNotifyMask
24454 | RROutputChangeNotifyMask
24455 /* Emacs doesn't actually need this, but GTK
24456 selects for it when the display is
24457 initialized. */
24458 | RROutputPropertyNotifyMask));
24415 } 24459 }
24416#endif 24460#endif
24417 24461
diff --git a/src/xterm.h b/src/xterm.h
index a05bc404f69..8571bd9d39c 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -602,6 +602,9 @@ struct x_display_info
602 XModifierKeymap *modmap; 602 XModifierKeymap *modmap;
603 603
604#ifdef HAVE_XRANDR 604#ifdef HAVE_XRANDR
605 bool xrandr_supported_p;
606 int xrandr_event_base;
607 int xrandr_error_base;
605 int xrandr_major_version; 608 int xrandr_major_version;
606 int xrandr_minor_version; 609 int xrandr_minor_version;
607#endif 610#endif