diff options
author | Martin Rudalics <rudalics@gmx.at> | 2022-02-28 16:36:15 +0100 |
---|---|---|
committer | Martin Rudalics <rudalics@gmx.at> | 2022-02-28 16:36:15 +0100 |
commit | 0d123d602c68c3634f9d5d0260c1fea552825f06 (patch) | |
tree | bdf5f38349b18c4d648e3f691289394332247a05 /src/xterm.c | |
parent | cde8e5afbb651f1be04b5e79db984d00d751ca04 (diff) | |
download | emacs-0d123d602c68c3634f9d5d0260c1fea552825f06.tar.gz |
; In xterm.c add comment about frame resizing under X
Diffstat (limited to 'src/xterm.c')
-rw-r--r-- | src/xterm.c | 116 |
1 files changed, 114 insertions, 2 deletions
diff --git a/src/xterm.c b/src/xterm.c index 64c340e4dc5..adfd7d2f9ee 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -257,7 +257,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ roughly be classified as belonging to one of three categories: - Using no toolkit at all. - - Using the X Toolkit Intrinstics (Xt). + - Using the X Toolkit Intrinsics (Xt). - Using GTK. The no toolkit configuration is the simplest: no toolkit widgets are @@ -336,7 +336,119 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ then the event will not be dispatched to Xt or utilized by GTK. Code inside `handle_one_xevent' should thus avoid making assumptions about the event dispatch mechanism and use that parameter - instead. */ + instead. + + FRAME RESIZING + + In the following explanations "frame size" refers to the "native size" + of a frame as reported by the (frame.h) macros FRAME_PIXEL_WIDTH and + FRAME_PIXEL_HEIGHT. These specify the size of a frame as the values + passed to/received from a toolkit and the window manager. The "text + size" Emacs Lisp code uses in functions like 'set-frame-size' or sees + in the ‘width’ and 'height' frame parameters is only loosely related + to the native size. The necessary translations are provided by the + macros FRAME_TEXT_TO_PIXEL_WIDTH and FRAME_TEXT_TO_PIXEL_HEIGHT as + well as FRAME_PIXEL_TO_TEXT_WIDTH and FRAME_PIXEL_TO_TEXT_HEIGHT (in + frame.h). + + Lisp functions may ask for resizing a frame either explicitly, using + one of the interfaces provided for that purpose like, for example, + 'set-frame-size' or changing the 'height' or 'width' parameter of that + frame, or implicitly, for example, by turning off/on or changing the + width of fringes or scroll bars for that frame. Any such request + passes through the routine 'adjust_frame_size' (in frame.c) which + decides, among others, whether the native frame size would really + change and whether it is allowed to change it at that moment. Only if + 'adjust_frame_size' decides that the corresponding terminal's + 'set_window_size_hook' may be run, it will dispatch execution to the + appropriate function which, for X builds, is 'x_set_window_size' in + this file. + + For GTK builds, 'x_set_window_size' calls 'xg_frame_set_char_size' in + gtkutil.c if the frame has an edit widget and 'x_set_window_size_1' in + this file otherwise. For non-GTK builds, 'x_set_window_size' always + calls 'x_set_window_size_1' directly. + + 'xg_frame_set_char_size' calls the GTK function 'gtk_window_resize' + for the frame's outer widget; x_set_window_size_1 calls the Xlib + function 'XResizeWindow' instead. In either case, if Emacs thinks + that the frame is visible, it will wait for a ConfigureNotify event + (see below) to occur within a timeout of 'x-wait-for-event-timeout' + (the default is 0.1 seconds). If Emacs thinks that the frame is not + visible, it calls 'adjust_frame_size' to run 'resize_frame_windows' + (see below) and hopes for the best. + + Note that if Emacs receives a ConfigureEvent in response to an earlier + resize request, the sizes specified by that event are not necessarily + the sizes Emacs requested. Window manager and toolkit may override + any of the requested sizes for their own reasons. + + On X, size notifications are received as ConfigureNotify events. The + expected reaction to such an event on the Emacs side is to resize all + Emacs windows that are on the frame referred to by the event. Since + resizing Emacs windows and redisplaying their buffers is a costly + operation, Emacs may collapse several subsequent ConfigureNotify + events into one to avoid that Emacs falls behind in user interactions + like resizing a frame by dragging one of its borders with the mouse. + + Each ConfigureEvent event specifies a window, a width and a height. + The event loop uses 'x_top_window_to_frame' to associate the window + with its frame. Once the frame has been identified, on GTK the event + is dispatched to 'xg_frame_resized'. On Motif/Lucid 'x_window' has + installed 'EmacsFrameResize' as the routine that handles resize + events. In either case, these routines end up calling the function + 'change_frame_size' in dispnew.c. On non-toolkit builds the effect is + to call 'change_frame_size' directly from the event loop. In either + case, the value true is passed as the DELAY argument. + + 'change_frame_size' is the central function to decide whether it is + safe to process a resize request immediately or it has to be delayed + (usually because its DELAY argument is true). Since resizing a + frame's windows may run arbitrary Lisp code, Emacs cannot generally + process resize requests during redisplay and therefore has to queue + them. If processing the event must be delayed, the new sizes (that + is, the ones requested by the ConfigureEvent) are stored in the + new_width and new_height slots of the respective frame structure, + possibly replacing ones that have been stored there upon the receipt + of a preceding ConfigureEvent. + + Delayed size changes are applied eventually upon calls of the function + 'do_pending_window_change' (in dispnew.c) which is called by the + redisplay code at suitable spots where it's safe to change sizes. + 'do_pending_window_change' calls 'change_frame_size' with its DELAY + argument false in the hope that it is now safe to call the function + 'resize_frame_windows' (in window.c) which is in charge of adjusting + the sizes of all Emacs windows on the frame accordingly. Note that if + 'resize_frame_windows' decides that the windows of a frame do not fit + into the constraints set up by the new frame sizes, it will resize the + windows to some minimum sizes with the effect that parts of the frame + at the right and bottom will appear clipped off. + + In addition to explicitly passing width and height values in functions + like 'gtk_window_resize' or 'XResizeWindow', Emacs also sets window + manager size hints - a more implicit form of asking for the size Emacs + would like its frames to assume. Some of these hints only restate the + size and the position explicitly requested for a frame. Another hint + specifies the increments in which the window manager should resize a + frame to - either set to the default character size of a frame or to + one pixel for a non-nil value of 'frame-resize-pixelwise'. See the + function 'x_wm_set_size_hint' - in gtkutil.c for GTK and in this file + for other builds - for the details. + + We have not discussed here a number of special issues like, for + example, how to handle size requests and notifications for maximized + and fullscreen frames or how to resize child frames. Some of these + require special treatment depending on the desktop or window manager + used. + + One thing that might come handy when investigating problems wrt + resizing frames is the variable 'frame-size-history'. Setting this to + a non-nil value, will cause Emacs to start recording frame size + adjustments, usually specified by the function that asked for an + adjustment, a sizes part that records the old and new values of the + frame's width and height and maybe some additional information. The + internal function `frame--size-history' can then be used to display + the value of this variable in a more readable form. */ #include <config.h> #include <stdlib.h> |