diff options
| author | Po Lu | 2022-05-21 11:17:34 +0800 |
|---|---|---|
| committer | Po Lu | 2022-05-21 11:17:34 +0800 |
| commit | edf9700c3ca65d92bdfca59306845ffc0717d690 (patch) | |
| tree | b00568cd7c0875f4ff23c3e6dc613c2d3c25a5b6 /src | |
| parent | 1cbabe973be88bed5a21d77defc3220034f7c91f (diff) | |
| download | emacs-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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/keyboard.c | 23 | ||||
| -rw-r--r-- | src/termhooks.h | 11 | ||||
| -rw-r--r-- | src/xterm.c | 52 | ||||
| -rw-r--r-- | src/xterm.h | 3 |
4 files changed, 83 insertions, 6 deletions
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 | |||
| 12953 | moved. */); | 12967 | moved. */); |
| 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. | ||
| 12972 | This can happen if a monitor is rotated, moved, plugged in or removed | ||
| 12973 | from a multi-monitor setup, if the primary monitor changes, or if the | ||
| 12974 | resolution of a monitor changes. The hook should accept a single | ||
| 12975 | argument, which is the terminal on which the monitor configuration | ||
| 12976 | changed. */); | ||
| 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 | ||
| 32 | INLINE_HEADER_BEGIN | 32 | INLINE_HEADER_BEGIN |
| 33 | 33 | ||
| 34 | enum scroll_bar_part { | 34 | enum 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 |