diff options
| author | Alan Third | 2019-07-28 15:10:29 +0100 |
|---|---|---|
| committer | Alan Third | 2020-01-24 16:05:40 +0000 |
| commit | ac6e620adc479a9e8c93c8ad787c3071aaefca23 (patch) | |
| tree | ad745bc205c3d2324a939a2fb81676eb0f3f245b | |
| parent | a76e7d592f428e04b868724c9dfe57d35eb3744e (diff) | |
| download | emacs-ac6e620adc479a9e8c93c8ad787c3071aaefca23.tar.gz emacs-ac6e620adc479a9e8c93c8ad787c3071aaefca23.zip | |
Revert "Fix some NS drawing issues (bug#32932)"
This reverts commit 7e8eee60a9dbb0c59cf26f237b21efe7fd1043c9.
| -rw-r--r-- | src/nsterm.m | 109 |
1 files changed, 63 insertions, 46 deletions
diff --git a/src/nsterm.m b/src/nsterm.m index fd23bf6b2c9..c2b95ad3cc0 100644 --- a/src/nsterm.m +++ b/src/nsterm.m | |||
| @@ -288,6 +288,7 @@ long context_menu_value = 0; | |||
| 288 | 288 | ||
| 289 | /* display update */ | 289 | /* display update */ |
| 290 | static int ns_window_num = 0; | 290 | static int ns_window_num = 0; |
| 291 | static BOOL gsaved = NO; | ||
| 291 | static BOOL ns_fake_keydown = NO; | 292 | static BOOL ns_fake_keydown = NO; |
| 292 | #ifdef NS_IMPL_COCOA | 293 | #ifdef NS_IMPL_COCOA |
| 293 | static BOOL ns_menu_bar_is_hidden = NO; | 294 | static BOOL ns_menu_bar_is_hidden = NO; |
| @@ -1150,6 +1151,7 @@ ns_clip_to_rect (struct frame *f, NSRect *r, int n) | |||
| 1150 | NSRectClipList (r, 2); | 1151 | NSRectClipList (r, 2); |
| 1151 | else | 1152 | else |
| 1152 | NSRectClip (*r); | 1153 | NSRectClip (*r); |
| 1154 | gsaved = YES; | ||
| 1153 | 1155 | ||
| 1154 | return YES; | 1156 | return YES; |
| 1155 | } | 1157 | } |
| @@ -1173,7 +1175,46 @@ ns_reset_clipping (struct frame *f) | |||
| 1173 | { | 1175 | { |
| 1174 | NSTRACE_WHEN (NSTRACE_GROUP_FOCUS, "ns_reset_clipping"); | 1176 | NSTRACE_WHEN (NSTRACE_GROUP_FOCUS, "ns_reset_clipping"); |
| 1175 | 1177 | ||
| 1176 | [[NSGraphicsContext currentContext] restoreGraphicsState]; | 1178 | if (gsaved) |
| 1179 | { | ||
| 1180 | [[NSGraphicsContext currentContext] restoreGraphicsState]; | ||
| 1181 | gsaved = NO; | ||
| 1182 | } | ||
| 1183 | } | ||
| 1184 | |||
| 1185 | |||
| 1186 | static BOOL | ||
| 1187 | ns_clip_to_row (struct window *w, struct glyph_row *row, | ||
| 1188 | enum glyph_row_area area, BOOL gc) | ||
| 1189 | /* -------------------------------------------------------------------------- | ||
| 1190 | Internal (but parallels other terms): Focus drawing on given row | ||
| 1191 | -------------------------------------------------------------------------- */ | ||
| 1192 | { | ||
| 1193 | struct frame *f = XFRAME (WINDOW_FRAME (w)); | ||
| 1194 | NSRect clip_rect; | ||
| 1195 | int window_x, window_y, window_width; | ||
| 1196 | |||
| 1197 | window_box (w, area, &window_x, &window_y, &window_width, 0); | ||
| 1198 | |||
| 1199 | clip_rect.origin.x = window_x; | ||
| 1200 | clip_rect.origin.y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, row->y)); | ||
| 1201 | clip_rect.origin.y = max (clip_rect.origin.y, window_y); | ||
| 1202 | clip_rect.size.width = window_width; | ||
| 1203 | clip_rect.size.height = row->visible_height; | ||
| 1204 | |||
| 1205 | return ns_clip_to_rect (f, &clip_rect, 1); | ||
| 1206 | } | ||
| 1207 | |||
| 1208 | |||
| 1209 | static void | ||
| 1210 | ns_flush_display (struct frame *f) | ||
| 1211 | /* Force the frame to redisplay. If areas have previously been marked | ||
| 1212 | dirty by setNeedsDisplayInRect (in ns_clip_to_rect), then this will call | ||
| 1213 | draw_rect: which will "expose" those areas. */ | ||
| 1214 | { | ||
| 1215 | block_input (); | ||
| 1216 | [FRAME_NS_VIEW (f) displayIfNeeded]; | ||
| 1217 | unblock_input (); | ||
| 1177 | } | 1218 | } |
| 1178 | 1219 | ||
| 1179 | 1220 | ||
| @@ -2813,8 +2854,6 @@ ns_clear_frame_area (struct frame *f, int x, int y, int width, int height) | |||
| 2813 | static void | 2854 | static void |
| 2814 | ns_copy_bits (struct frame *f, NSRect src, NSRect dest) | 2855 | ns_copy_bits (struct frame *f, NSRect src, NSRect dest) |
| 2815 | { | 2856 | { |
| 2816 | NSSize delta = NSMakeSize (dest.origin.x - src.origin.x, | ||
| 2817 | dest.origin.y - src.origin.y); | ||
| 2818 | NSTRACE ("ns_copy_bits"); | 2857 | NSTRACE ("ns_copy_bits"); |
| 2819 | 2858 | ||
| 2820 | if (FRAME_NS_VIEW (f)) | 2859 | if (FRAME_NS_VIEW (f)) |
| @@ -2823,21 +2862,10 @@ ns_copy_bits (struct frame *f, NSRect src, NSRect dest) | |||
| 2823 | 2862 | ||
| 2824 | /* FIXME: scrollRect:by: is deprecated in macOS 10.14. There is | 2863 | /* FIXME: scrollRect:by: is deprecated in macOS 10.14. There is |
| 2825 | no obvious replacement so we may have to come up with our own. */ | 2864 | no obvious replacement so we may have to come up with our own. */ |
| 2826 | [FRAME_NS_VIEW (f) scrollRect: src by: delta]; | 2865 | [FRAME_NS_VIEW (f) scrollRect: src |
| 2827 | 2866 | by: NSMakeSize (dest.origin.x - src.origin.x, | |
| 2828 | #ifdef NS_IMPL_COCOA | 2867 | dest.origin.y - src.origin.y)]; |
| 2829 | /* As far as I can tell from the documentation, scrollRect:by:, | 2868 | [FRAME_NS_VIEW (f) setNeedsDisplay:YES]; |
| 2830 | above, should copy the dirty rectangles from our source | ||
| 2831 | rectangle to our destination, however it appears it clips the | ||
| 2832 | operation to src. As a result we need to use | ||
| 2833 | translateRectsNeedingDisplayInRect:by: below, and we have to | ||
| 2834 | union src and dest so it can pick up the dirty rectangles, | ||
| 2835 | and place them, as it also clips to the rectangle. | ||
| 2836 | |||
| 2837 | FIXME: We need a GNUstep equivalent. */ | ||
| 2838 | [FRAME_NS_VIEW (f) translateRectsNeedingDisplayInRect:NSUnionRect (src, dest) | ||
| 2839 | by:delta]; | ||
| 2840 | #endif | ||
| 2841 | } | 2869 | } |
| 2842 | } | 2870 | } |
| 2843 | 2871 | ||
| @@ -3236,6 +3264,15 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, | |||
| 3236 | else | 3264 | else |
| 3237 | [FRAME_CURSOR_COLOR (f) set]; | 3265 | [FRAME_CURSOR_COLOR (f) set]; |
| 3238 | 3266 | ||
| 3267 | #ifdef NS_IMPL_COCOA | ||
| 3268 | /* TODO: This makes drawing of cursor plus that of phys_cursor_glyph | ||
| 3269 | atomic. Cleaner ways of doing this should be investigated. | ||
| 3270 | One way would be to set a global variable DRAWING_CURSOR | ||
| 3271 | when making the call to draw_phys..(), don't focus in that | ||
| 3272 | case, then move the ns_reset_clipping() here after that call. */ | ||
| 3273 | NSDisableScreenUpdates (); | ||
| 3274 | #endif | ||
| 3275 | |||
| 3239 | switch (cursor_type) | 3276 | switch (cursor_type) |
| 3240 | { | 3277 | { |
| 3241 | case DEFAULT_CURSOR: | 3278 | case DEFAULT_CURSOR: |
| @@ -3270,13 +3307,9 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, | |||
| 3270 | if (cursor_type == FILLED_BOX_CURSOR || cursor_type == HOLLOW_BOX_CURSOR) | 3307 | if (cursor_type == FILLED_BOX_CURSOR || cursor_type == HOLLOW_BOX_CURSOR) |
| 3271 | draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR); | 3308 | draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR); |
| 3272 | 3309 | ||
| 3273 | ns_reset_clipping (f); | 3310 | #ifdef NS_IMPL_COCOA |
| 3274 | } | 3311 | NSEnableScreenUpdates (); |
| 3275 | else if (! redisplaying_p) | 3312 | #endif |
| 3276 | { | ||
| 3277 | /* If this function is called outside redisplay, it probably | ||
| 3278 | means we need an immediate update. */ | ||
| 3279 | [FRAME_NS_VIEW (f) display]; | ||
| 3280 | } | 3313 | } |
| 3281 | } | 3314 | } |
| 3282 | 3315 | ||
| @@ -7169,6 +7202,7 @@ not_in_argv (NSString *arg) | |||
| 7169 | size_title = xmalloc (strlen (old_title) + 40); | 7202 | size_title = xmalloc (strlen (old_title) + 40); |
| 7170 | esprintf (size_title, "%s — (%d x %d)", old_title, cols, rows); | 7203 | esprintf (size_title, "%s — (%d x %d)", old_title, cols, rows); |
| 7171 | [window setTitle: [NSString stringWithUTF8String: size_title]]; | 7204 | [window setTitle: [NSString stringWithUTF8String: size_title]]; |
| 7205 | [window display]; | ||
| 7172 | xfree (size_title); | 7206 | xfree (size_title); |
| 7173 | } | 7207 | } |
| 7174 | } | 7208 | } |
| @@ -8218,8 +8252,8 @@ not_in_argv (NSString *arg) | |||
| 8218 | 8252 | ||
| 8219 | - (void)drawRect: (NSRect)rect | 8253 | - (void)drawRect: (NSRect)rect |
| 8220 | { | 8254 | { |
| 8221 | const NSRect *rectList; | 8255 | int x = NSMinX (rect), y = NSMinY (rect); |
| 8222 | NSInteger numRects; | 8256 | int width = NSWidth (rect), height = NSHeight (rect); |
| 8223 | 8257 | ||
| 8224 | NSTRACE ("[EmacsView drawRect:" NSTRACE_FMT_RECT "]", | 8258 | NSTRACE ("[EmacsView drawRect:" NSTRACE_FMT_RECT "]", |
| 8225 | NSTRACE_ARG_RECT(rect)); | 8259 | NSTRACE_ARG_RECT(rect)); |
| @@ -8227,26 +8261,9 @@ not_in_argv (NSString *arg) | |||
| 8227 | if (!emacsframe || !emacsframe->output_data.ns) | 8261 | if (!emacsframe || !emacsframe->output_data.ns) |
| 8228 | return; | 8262 | return; |
| 8229 | 8263 | ||
| 8264 | ns_clear_frame_area (emacsframe, x, y, width, height); | ||
| 8230 | block_input (); | 8265 | block_input (); |
| 8231 | 8266 | expose_frame (emacsframe, x, y, width, height); | |
| 8232 | /* Get only the precise dirty rectangles to avoid redrawing | ||
| 8233 | potentially large areas of the frame that haven't changed. | ||
| 8234 | |||
| 8235 | I'm not sure this actually provides much of a performance benefit | ||
| 8236 | as it's hard to benchmark, but it certainly doesn't seem to | ||
| 8237 | hurt. */ | ||
| 8238 | [self getRectsBeingDrawn:&rectList count:&numRects]; | ||
| 8239 | for (int i = 0 ; i < numRects ; i++) | ||
| 8240 | { | ||
| 8241 | NSRect r = rectList[i]; | ||
| 8242 | |||
| 8243 | NSTRACE_RECT ("r", r); | ||
| 8244 | |||
| 8245 | expose_frame (emacsframe, | ||
| 8246 | NSMinX (r), NSMinY (r), | ||
| 8247 | NSWidth (r), NSHeight (r)); | ||
| 8248 | } | ||
| 8249 | |||
| 8250 | unblock_input (); | 8267 | unblock_input (); |
| 8251 | 8268 | ||
| 8252 | /* | 8269 | /* |