diff options
| author | Po Lu | 2022-12-26 15:57:06 +0800 |
|---|---|---|
| committer | Po Lu | 2022-12-26 15:57:48 +0800 |
| commit | cc29fab3a66c59e77d0ff67c0f3e2e34ec80a03c (patch) | |
| tree | 07d54371ad2a25bd0f01b0cfbfeffefb574f87cc /src | |
| parent | 419ca81809c2eda9c9f102b7da820a6eb9685cc8 (diff) | |
| download | emacs-cc29fab3a66c59e77d0ff67c0f3e2e34ec80a03c.tar.gz emacs-cc29fab3a66c59e77d0ff67c0f3e2e34ec80a03c.zip | |
Redisplay "invisible" frames that are actually visible on modern X
* etc/NEWS: Document that "invisible" frames are now redisplayed
if the compositing manager is still displaying it as part of a
thumbnail out of Emacs's control.
* src/dispnew.c (Fredraw_display): Use FRAME_REDISPLAY_P.
* src/frame.h (FRAME_REDISPLAY_P): New macro.
* src/xdisp.c (clear_garbaged_frames, echo_area_display)
(prepare_menu_bars, redisplay_internal, display_and_set_cursor)
(gui_clear_cursor): Use FRAME_REDISPLAY_P to determine whether
or not a frame should be redisplayed.
* src/xfns.c (Fx_create_frame): Set visibility state initially.
* src/xterm.c (handle_one_xevent): Likewise.
* src/xterm.h (struct x_output): New field `visibility_state'.
Diffstat (limited to 'src')
| -rw-r--r-- | src/dispnew.c | 2 | ||||
| -rw-r--r-- | src/frame.h | 14 | ||||
| -rw-r--r-- | src/xdisp.c | 24 | ||||
| -rw-r--r-- | src/xfns.c | 1 | ||||
| -rw-r--r-- | src/xterm.c | 6 | ||||
| -rw-r--r-- | src/xterm.h | 10 |
6 files changed, 41 insertions, 16 deletions
diff --git a/src/dispnew.c b/src/dispnew.c index 5a9ba8909e3..b845acdcbc4 100644 --- a/src/dispnew.c +++ b/src/dispnew.c | |||
| @@ -3188,7 +3188,7 @@ DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, "", | |||
| 3188 | Lisp_Object tail, frame; | 3188 | Lisp_Object tail, frame; |
| 3189 | 3189 | ||
| 3190 | FOR_EACH_FRAME (tail, frame) | 3190 | FOR_EACH_FRAME (tail, frame) |
| 3191 | if (FRAME_VISIBLE_P (XFRAME (frame))) | 3191 | if (FRAME_REDISPLAY_P (XFRAME (frame))) |
| 3192 | redraw_frame (XFRAME (frame)); | 3192 | redraw_frame (XFRAME (frame)); |
| 3193 | 3193 | ||
| 3194 | return Qnil; | 3194 | return Qnil; |
diff --git a/src/frame.h b/src/frame.h index dcd32036b86..f29cc249ea8 100644 --- a/src/frame.h +++ b/src/frame.h | |||
| @@ -1010,6 +1010,20 @@ default_pixels_per_inch_y (void) | |||
| 1010 | /* True if frame F is currently visible. */ | 1010 | /* True if frame F is currently visible. */ |
| 1011 | #define FRAME_VISIBLE_P(f) (f)->visible | 1011 | #define FRAME_VISIBLE_P(f) (f)->visible |
| 1012 | 1012 | ||
| 1013 | /* True if frame F should be redisplayed. This is normally the same | ||
| 1014 | as FRAME_VISIBLE_P (f). Under X, frames can continue to be | ||
| 1015 | displayed to the user by the compositing manager even if they are | ||
| 1016 | invisible, so this also checks whether or not the frame is reported | ||
| 1017 | visible by the X server. */ | ||
| 1018 | |||
| 1019 | #ifndef HAVE_X_WINDOWS | ||
| 1020 | #define FRAME_REDISPLAY_P(f) (FRAME_VISIBLE_P (f)) | ||
| 1021 | #else | ||
| 1022 | #define FRAME_REDISPLAY_P(f) (FRAME_VISIBLE_P (f) \ | ||
| 1023 | || (FRAME_X_P (f) \ | ||
| 1024 | && FRAME_X_VISIBLE (f))) | ||
| 1025 | #endif | ||
| 1026 | |||
| 1013 | /* True if frame F is currently visible but hidden. */ | 1027 | /* True if frame F is currently visible but hidden. */ |
| 1014 | #define FRAME_OBSCURED_P(f) ((f)->visible > 1) | 1028 | #define FRAME_OBSCURED_P(f) ((f)->visible > 1) |
| 1015 | 1029 | ||
diff --git a/src/xdisp.c b/src/xdisp.c index 08565d55322..8a32ce66235 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -12938,7 +12938,7 @@ clear_garbaged_frames (void) | |||
| 12938 | { | 12938 | { |
| 12939 | struct frame *f = XFRAME (frame); | 12939 | struct frame *f = XFRAME (frame); |
| 12940 | 12940 | ||
| 12941 | if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f)) | 12941 | if (FRAME_REDISPLAY_P (f) && FRAME_GARBAGED_P (f)) |
| 12942 | { | 12942 | { |
| 12943 | if (f->resized_p | 12943 | if (f->resized_p |
| 12944 | /* It makes no sense to redraw a non-selected TTY | 12944 | /* It makes no sense to redraw a non-selected TTY |
| @@ -12987,7 +12987,7 @@ echo_area_display (bool update_frame_p) | |||
| 12987 | f = XFRAME (WINDOW_FRAME (w)); | 12987 | f = XFRAME (WINDOW_FRAME (w)); |
| 12988 | 12988 | ||
| 12989 | /* Don't display if frame is invisible or not yet initialized. */ | 12989 | /* Don't display if frame is invisible or not yet initialized. */ |
| 12990 | if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p) | 12990 | if (!FRAME_REDISPLAY_P (f) || !f->glyphs_initialized_p) |
| 12991 | return; | 12991 | return; |
| 12992 | 12992 | ||
| 12993 | #ifdef HAVE_WINDOW_SYSTEM | 12993 | #ifdef HAVE_WINDOW_SYSTEM |
| @@ -13543,7 +13543,7 @@ prepare_menu_bars (void) | |||
| 13543 | TTY frames to be completely redrawn, when there | 13543 | TTY frames to be completely redrawn, when there |
| 13544 | are more than one of them, even though nothing | 13544 | are more than one of them, even though nothing |
| 13545 | should be changed on display. */ | 13545 | should be changed on display. */ |
| 13546 | || (FRAME_VISIBLE_P (f) == 2 && FRAME_WINDOW_P (f)))) | 13546 | || (FRAME_REDISPLAY_P (f) && FRAME_WINDOW_P (f)))) |
| 13547 | gui_consider_frame_title (frame); | 13547 | gui_consider_frame_title (frame); |
| 13548 | } | 13548 | } |
| 13549 | } | 13549 | } |
| @@ -16430,7 +16430,7 @@ redisplay_internal (void) | |||
| 16430 | { | 16430 | { |
| 16431 | struct frame *f = XFRAME (frame); | 16431 | struct frame *f = XFRAME (frame); |
| 16432 | 16432 | ||
| 16433 | if (FRAME_VISIBLE_P (f)) | 16433 | if (FRAME_REDISPLAY_P (f)) |
| 16434 | { | 16434 | { |
| 16435 | ++number_of_visible_frames; | 16435 | ++number_of_visible_frames; |
| 16436 | /* Adjust matrices for visible frames only. */ | 16436 | /* Adjust matrices for visible frames only. */ |
| @@ -16572,7 +16572,7 @@ redisplay_internal (void) | |||
| 16572 | && !w->update_mode_line | 16572 | && !w->update_mode_line |
| 16573 | && !current_buffer->clip_changed | 16573 | && !current_buffer->clip_changed |
| 16574 | && !current_buffer->prevent_redisplay_optimizations_p | 16574 | && !current_buffer->prevent_redisplay_optimizations_p |
| 16575 | && FRAME_VISIBLE_P (XFRAME (w->frame)) | 16575 | && FRAME_REDISPLAY_P (XFRAME (w->frame)) |
| 16576 | && !FRAME_OBSCURED_P (XFRAME (w->frame)) | 16576 | && !FRAME_OBSCURED_P (XFRAME (w->frame)) |
| 16577 | && !XFRAME (w->frame)->cursor_type_changed | 16577 | && !XFRAME (w->frame)->cursor_type_changed |
| 16578 | && !XFRAME (w->frame)->face_change | 16578 | && !XFRAME (w->frame)->face_change |
| @@ -16850,7 +16850,7 @@ redisplay_internal (void) | |||
| 16850 | if (gcscrollbars && FRAME_TERMINAL (f)->condemn_scroll_bars_hook) | 16850 | if (gcscrollbars && FRAME_TERMINAL (f)->condemn_scroll_bars_hook) |
| 16851 | FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f); | 16851 | FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f); |
| 16852 | 16852 | ||
| 16853 | if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f)) | 16853 | if (FRAME_REDISPLAY_P (f) && !FRAME_OBSCURED_P (f)) |
| 16854 | { | 16854 | { |
| 16855 | /* Don't allow freeing images and faces for this | 16855 | /* Don't allow freeing images and faces for this |
| 16856 | frame as long as the frame's update wasn't | 16856 | frame as long as the frame's update wasn't |
| @@ -16876,7 +16876,7 @@ redisplay_internal (void) | |||
| 16876 | if (gcscrollbars && FRAME_TERMINAL (f)->judge_scroll_bars_hook) | 16876 | if (gcscrollbars && FRAME_TERMINAL (f)->judge_scroll_bars_hook) |
| 16877 | FRAME_TERMINAL (f)->judge_scroll_bars_hook (f); | 16877 | FRAME_TERMINAL (f)->judge_scroll_bars_hook (f); |
| 16878 | 16878 | ||
| 16879 | if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f)) | 16879 | if (FRAME_REDISPLAY_P (f) && !FRAME_OBSCURED_P (f)) |
| 16880 | { | 16880 | { |
| 16881 | /* If fonts changed on visible frame, display again. */ | 16881 | /* If fonts changed on visible frame, display again. */ |
| 16882 | if (f->fonts_changed) | 16882 | if (f->fonts_changed) |
| @@ -16982,7 +16982,7 @@ redisplay_internal (void) | |||
| 16982 | } | 16982 | } |
| 16983 | } | 16983 | } |
| 16984 | } | 16984 | } |
| 16985 | else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf)) | 16985 | else if (FRAME_REDISPLAY_P (sf) && !FRAME_OBSCURED_P (sf)) |
| 16986 | { | 16986 | { |
| 16987 | sf->inhibit_clear_image_cache = true; | 16987 | sf->inhibit_clear_image_cache = true; |
| 16988 | displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents); | 16988 | displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents); |
| @@ -17033,7 +17033,7 @@ redisplay_internal (void) | |||
| 17033 | unrequest_sigio (); | 17033 | unrequest_sigio (); |
| 17034 | STOP_POLLING; | 17034 | STOP_POLLING; |
| 17035 | 17035 | ||
| 17036 | if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf)) | 17036 | if (FRAME_REDISPLAY_P (sf) && !FRAME_OBSCURED_P (sf)) |
| 17037 | { | 17037 | { |
| 17038 | if (hscroll_retries <= MAX_HSCROLL_RETRIES | 17038 | if (hscroll_retries <= MAX_HSCROLL_RETRIES |
| 17039 | && hscroll_windows (selected_window)) | 17039 | && hscroll_windows (selected_window)) |
| @@ -17132,7 +17132,7 @@ redisplay_internal (void) | |||
| 17132 | 17132 | ||
| 17133 | FOR_EACH_FRAME (tail, frame) | 17133 | FOR_EACH_FRAME (tail, frame) |
| 17134 | { | 17134 | { |
| 17135 | if (XFRAME (frame)->visible) | 17135 | if (FRAME_REDISPLAY_P (XFRAME (frame))) |
| 17136 | new_count++; | 17136 | new_count++; |
| 17137 | } | 17137 | } |
| 17138 | 17138 | ||
| @@ -33256,7 +33256,7 @@ display_and_set_cursor (struct window *w, bool on, | |||
| 33256 | windows and frames; in the latter case, the frame or window may | 33256 | windows and frames; in the latter case, the frame or window may |
| 33257 | be in the midst of changing its size, and x and y may be off the | 33257 | be in the midst of changing its size, and x and y may be off the |
| 33258 | window. */ | 33258 | window. */ |
| 33259 | if (! FRAME_VISIBLE_P (f) | 33259 | if (! FRAME_REDISPLAY_P (f) |
| 33260 | || vpos >= w->current_matrix->nrows | 33260 | || vpos >= w->current_matrix->nrows |
| 33261 | || hpos >= w->current_matrix->matrix_w) | 33261 | || hpos >= w->current_matrix->matrix_w) |
| 33262 | return; | 33262 | return; |
| @@ -33417,7 +33417,7 @@ gui_update_cursor (struct frame *f, bool on_p) | |||
| 33417 | void | 33417 | void |
| 33418 | gui_clear_cursor (struct window *w) | 33418 | gui_clear_cursor (struct window *w) |
| 33419 | { | 33419 | { |
| 33420 | if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p) | 33420 | if (FRAME_REDISPLAY_P (XFRAME (w->frame)) && w->phys_cursor_on_p) |
| 33421 | update_window_cursor (w, false); | 33421 | update_window_cursor (w, false); |
| 33422 | } | 33422 | } |
| 33423 | 33423 | ||
diff --git a/src/xfns.c b/src/xfns.c index 668f711bdb5..1cc5aec1eb4 100644 --- a/src/xfns.c +++ b/src/xfns.c | |||
| @@ -4741,6 +4741,7 @@ This function is an internal primitive--use `make-frame' instead. */) | |||
| 4741 | #endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */ | 4741 | #endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */ |
| 4742 | f->output_data.x->white_relief.pixel = -1; | 4742 | f->output_data.x->white_relief.pixel = -1; |
| 4743 | f->output_data.x->black_relief.pixel = -1; | 4743 | f->output_data.x->black_relief.pixel = -1; |
| 4744 | f->output_data.x->visibility_state = VisibilityFullyObscured; | ||
| 4744 | 4745 | ||
| 4745 | fset_icon_name (f, gui_display_get_arg (dpyinfo, | 4746 | fset_icon_name (f, gui_display_get_arg (dpyinfo, |
| 4746 | parms, | 4747 | parms, |
diff --git a/src/xterm.c b/src/xterm.c index 8e0a97899fe..1eef8e7a724 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -21743,9 +21743,9 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 21743 | 21743 | ||
| 21744 | case VisibilityNotify: | 21744 | case VisibilityNotify: |
| 21745 | f = x_top_window_to_frame (dpyinfo, event->xvisibility.window); | 21745 | f = x_top_window_to_frame (dpyinfo, event->xvisibility.window); |
| 21746 | if (f && (event->xvisibility.state == VisibilityUnobscured | 21746 | |
| 21747 | || event->xvisibility.state == VisibilityPartiallyObscured)) | 21747 | if (f) |
| 21748 | SET_FRAME_VISIBLE (f, 1); | 21748 | FRAME_X_OUTPUT (f)->visibility_state = event->xvisibility.state; |
| 21749 | 21749 | ||
| 21750 | goto OTHER; | 21750 | goto OTHER; |
| 21751 | 21751 | ||
diff --git a/src/xterm.h b/src/xterm.h index 832ffc172b9..f06e1ec5bc6 100644 --- a/src/xterm.h +++ b/src/xterm.h | |||
| @@ -1290,6 +1290,11 @@ struct x_output | |||
| 1290 | strictly an optimization to avoid extraneous synchronizing in | 1290 | strictly an optimization to avoid extraneous synchronizing in |
| 1291 | some cases. */ | 1291 | some cases. */ |
| 1292 | int root_x, root_y; | 1292 | int root_x, root_y; |
| 1293 | |||
| 1294 | /* The frame visibility state. This starts out | ||
| 1295 | VisibilityFullyObscured, but is set to something else in | ||
| 1296 | handle_one_xevent. */ | ||
| 1297 | int visibility_state; | ||
| 1293 | }; | 1298 | }; |
| 1294 | 1299 | ||
| 1295 | enum | 1300 | enum |
| @@ -1408,6 +1413,11 @@ extern void x_mark_frame_dirty (struct frame *f); | |||
| 1408 | /* And its corresponding visual info. */ | 1413 | /* And its corresponding visual info. */ |
| 1409 | #define FRAME_X_VISUAL_INFO(f) (&FRAME_DISPLAY_INFO (f)->visual_info) | 1414 | #define FRAME_X_VISUAL_INFO(f) (&FRAME_DISPLAY_INFO (f)->visual_info) |
| 1410 | 1415 | ||
| 1416 | /* Whether or not the frame is visible. Do not test this alone. | ||
| 1417 | Instead, use FRAME_REDISPLAY_P. */ | ||
| 1418 | #define FRAME_X_VISIBLE(f) (FRAME_X_OUTPUT (f)->visibility_state \ | ||
| 1419 | != VisibilityFullyObscured) | ||
| 1420 | |||
| 1411 | #ifdef HAVE_XRENDER | 1421 | #ifdef HAVE_XRENDER |
| 1412 | #define FRAME_X_PICTURE_FORMAT(f) FRAME_DISPLAY_INFO (f)->pict_format | 1422 | #define FRAME_X_PICTURE_FORMAT(f) FRAME_DISPLAY_INFO (f)->pict_format |
| 1413 | #define FRAME_X_PICTURE(f) ((f)->output_data.x->picture) | 1423 | #define FRAME_X_PICTURE(f) ((f)->output_data.x->picture) |