diff options
Diffstat (limited to 'src/nsterm.m')
-rw-r--r-- | src/nsterm.m | 156 |
1 files changed, 76 insertions, 80 deletions
diff --git a/src/nsterm.m b/src/nsterm.m index 518b38658d1..faf9324402b 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -550,6 +550,15 @@ ns_relocate (const char *epath) void +ns_init_pool (void) +/* Initialize the 'outerpool' autorelease pool. This should be called + from main before any Objective C code is run. */ +{ + outerpool = [[NSAutoreleasePool alloc] init]; +} + + +void ns_init_locale (void) /* macOS doesn't set any environment variables for the locale when run from the GUI. Get the locale from the OS and set LANG. */ @@ -1627,7 +1636,7 @@ ns_free_frame_resources (struct frame *f) [f->output_data.ns->miniimage release]; [[view window] close]; - [view release]; + [view removeFromSuperview]; xfree (f->output_data.ns); f->output_data.ns = NULL; @@ -2707,12 +2716,11 @@ ns_scroll_run (struct window *w, struct run *run) { NSRect srcRect = NSMakeRect (x, from_y, width, height); NSPoint dest = NSMakePoint (x, to_y); - NSRect destRect = NSMakeRect (x, from_y, width, height); EmacsView *view = FRAME_NS_VIEW (f); [view copyRect:srcRect to:dest]; -#ifdef NS_IMPL_COCOA - [view setNeedsDisplayInRect:destRect]; +#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED < 101400 + [view setNeedsDisplayInRect:srcRect]; #endif } @@ -2731,6 +2739,7 @@ ns_clear_under_internal_border (struct frame *f) int width = FRAME_PIXEL_WIDTH (f); int height = FRAME_PIXEL_HEIGHT (f); int margin = FRAME_TOP_MARGIN_HEIGHT (f); + int bottom_margin = FRAME_BOTTOM_MARGIN_HEIGHT (f); int face_id = (FRAME_PARENT_FRAME (f) ? (!NILP (Vface_remapping_alist) @@ -2756,7 +2765,8 @@ ns_clear_under_internal_border (struct frame *f) NSRectFill (NSMakeRect (0, 0, border, height)); NSRectFill (NSMakeRect (0, margin, width, border)); NSRectFill (NSMakeRect (width - border, 0, border, height)); - NSRectFill (NSMakeRect (0, height - border, width, border)); + NSRectFill (NSMakeRect (0, height - bottom_margin - border, + width, border)); ns_unfocus (f); } } @@ -4562,21 +4572,6 @@ ns_send_appdefined (int value) /* Only post this event if we haven't already posted one. This will end the [NXApp run] main loop after having processed all events queued at this moment. */ - -#ifdef NS_IMPL_COCOA - if (! send_appdefined) - { - /* OS X 10.10.1 swallows the AppDefined event we are sending ourselves - in certain situations (rapid incoming events). - So check if we have one, if not add one. */ - NSEvent *appev = [NSApp nextEventMatchingMask:NSEventMaskApplicationDefined - untilDate:[NSDate distantPast] - inMode:NSDefaultRunLoopMode - dequeue:NO]; - if (! appev) send_appdefined = YES; - } -#endif - if (send_appdefined) { NSEvent *nxev; @@ -4611,7 +4606,7 @@ ns_send_appdefined (int value) #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 static void -check_native_fs () +check_native_fs (void) { Lisp_Object frame, tail; @@ -4744,12 +4739,15 @@ ns_select_1 (int nfds, fd_set *readfds, fd_set *writefds, check_native_fs (); #endif - if (hold_event_q.nr > 0 && !run_loop_only) + /* If there are input events pending, store them so that Emacs can + recognize C-g. (And we must make sure [NSApp run] is called in + this function, so that C-g has a chance to land in + hold_event_q.) */ + if (hold_event_q.nr > 0) { - /* We already have events pending. */ - raise (SIGIO); - errno = EINTR; - return -1; + for (int i = 0; i < hold_event_q.nr; ++i) + kbd_buffer_store_event_hold (&hold_event_q.q[i], NULL); + hold_event_q.nr = 0; } eassert (nfds <= FD_SETSIZE); @@ -4759,11 +4757,15 @@ ns_select_1 (int nfds, fd_set *readfds, fd_set *writefds, if (writefds && FD_ISSET(k, writefds)) ++nr; } - if (NSApp == nil - || ![NSThread isMainThread] + /* emacs -nw doesn't have an NSApp, so we're done. */ + if (NSApp == nil) + return thread_select (pselect, nfds, readfds, writefds, exceptfds, + timeout, sigmask); + + if (![NSThread isMainThread] || (timeout && timeout->tv_sec == 0 && timeout->tv_nsec == 0)) - return thread_select (pselect, nfds, readfds, writefds, - exceptfds, timeout, sigmask); + thread_select (pselect, nfds, readfds, writefds, + exceptfds, timeout, sigmask); else { struct timespec t = {0, 0}; @@ -6716,16 +6718,8 @@ ns_create_font_panel_buttons (id target, SEL select, SEL cancel_action) - (void)resetCursorRects { - NSRect visible; - NSCursor *currentCursor; - - /* On macOS 13, [resetCursorRects:] could be called even after the - window is closed. */ - if (! emacsframe || ! FRAME_OUTPUT_DATA (emacsframe)) - return; - - visible = [self visibleRect]; - currentCursor = FRAME_POINTER_TYPE (emacsframe); + NSRect visible = [self visibleRect]; + NSCursor *currentCursor = FRAME_POINTER_TYPE (emacsframe); NSTRACE ("[EmacsView resetCursorRects]"); if (currentCursor == nil) @@ -7080,13 +7074,9 @@ ns_create_font_panel_buttons (id target, SEL select, SEL cancel_action) static Lisp_Object ns_in_echo_area_1 (void *ptr) { - Lisp_Object in_echo_area; - specpdl_ref count; - - count = SPECPDL_INDEX (); + const specpdl_ref count = SPECPDL_INDEX (); specbind (Qinhibit_quit, Qt); - in_echo_area = safe_call (1, Qns_in_echo_area); - + const Lisp_Object in_echo_area = safe_calln (Qns_in_echo_area); return unbind_to (count, in_echo_area); } @@ -7434,7 +7424,7 @@ ns_in_echo_area (void) int x = lrint (p.x); int y = lrint (p.y); - window = window_from_coordinates (emacsframe, x, y, 0, true, true); + window = window_from_coordinates (emacsframe, x, y, 0, true, true, true); tab_bar_p = EQ (window, emacsframe->tab_bar_window); if (tab_bar_p) @@ -7540,7 +7530,7 @@ ns_in_echo_area (void) NSTRACE_MSG ("mouse_autoselect_window"); static Lisp_Object last_mouse_window; Lisp_Object window - = window_from_coordinates (emacsframe, pt.x, pt.y, 0, 0, 0); + = window_from_coordinates (emacsframe, pt.x, pt.y, 0, 0, 0, 0); if (WINDOWP (window) && !EQ (window, last_mouse_window) @@ -7936,8 +7926,6 @@ ns_in_echo_area (void) maximizing_resize = NO; #endif - [[EmacsWindow alloc] initWithEmacsFrame:f]; - #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MIN_REQUIRED >= 101400 /* These settings mean AppKit will retain the contents of the frame on resize. Unfortunately it also means the frame will not be @@ -7948,9 +7936,16 @@ ns_in_echo_area (void) NSViewLayerContentsRedrawOnSetNeedsDisplay]; [self setLayerContentsPlacement:NSViewLayerContentsPlacementTopLeft]; - /* initWithEmacsFrame can't create the toolbar before the layer is - set, so have another go at creating the toolbar here. */ - [(EmacsWindow*)[self window] createToolbar:f]; + [[EmacsWindow alloc] initWithEmacsFrame:f]; + + /* Now the NSWindow has been created, we can finish up configuring + the layer. */ + [(EmacsLayer *)[self layer] setColorSpace: + [[[self window] colorSpace] CGColorSpace]]; + [(EmacsLayer *)[self layer] setContentsScale: + [[self window] backingScaleFactor]]; +#else + [[EmacsWindow alloc] initWithEmacsFrame:f]; #endif if (ns_drag_types) @@ -8621,9 +8616,9 @@ ns_in_echo_area (void) - (CALayer *)makeBackingLayer { EmacsLayer *l = [[EmacsLayer alloc] - initWithColorSpace:[[[self window] colorSpace] CGColorSpace]]; + initWithDoubleBuffered:FRAME_DOUBLE_BUFFERED (emacsframe)]; + [l setDelegate:(id)self]; - [l setContentsScale:[[self window] backingScaleFactor]]; return l; } @@ -8678,8 +8673,10 @@ ns_in_echo_area (void) NSHeight (srcRect)); #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MIN_REQUIRED >= 101400 - double scale = [[self window] backingScaleFactor]; CGContextRef context = [(EmacsLayer *)[self layer] getContext]; + CGContextFlush (context); + + double scale = [[self window] backingScaleFactor]; int bpp = CGBitmapContextGetBitsPerPixel (context) / 8; void *pixels = CGBitmapContextGetData (context); int rowSize = CGBitmapContextGetBytesPerRow (context); @@ -8844,8 +8841,8 @@ ns_in_echo_area (void) so call this function instead. */ XSETFRAME (frame, emacsframe); - safe_call (4, Vns_drag_motion_function, frame, - make_fixnum (x), make_fixnum (y)); + safe_calln (Vns_drag_motion_function, frame, + make_fixnum (x), make_fixnum (y)); redisplay (); #endif @@ -10449,22 +10446,19 @@ nswindow_orderedIndex_sort (id w1, id w2, void *c) cache. If no free surfaces are found in the cache then a new one is created. */ -#define CACHE_MAX_SIZE 2 - -- (id) initWithColorSpace: (CGColorSpaceRef)cs +- (id) initWithDoubleBuffered: (bool)db { - NSTRACE ("[EmacsLayer initWithColorSpace:]"); + NSTRACE ("[EmacsLayer initWithDoubleBuffered:]"); self = [super init]; if (self) { - cache = [[NSMutableArray arrayWithCapacity:CACHE_MAX_SIZE] retain]; - [self setColorSpace:cs]; + [self setColorSpace:nil]; + [self setDoubleBuffered:db]; + cache = [[NSMutableArray arrayWithCapacity:(doubleBuffered ? 2 : 1)] retain]; } else - { - return nil; - } + return nil; return self; } @@ -10481,6 +10475,15 @@ nswindow_orderedIndex_sort (id w1, id w2, void *c) } +- (void) setDoubleBuffered: (bool)db +{ + if (doubleBuffered != db) + [self releaseSurfaces]; + + doubleBuffered = db; +} + + - (void) dealloc { [self releaseSurfaces]; @@ -10552,7 +10555,7 @@ nswindow_orderedIndex_sort (id w1, id w2, void *c) } } - if (!surface && [cache count] >= CACHE_MAX_SIZE) + if (!surface && [cache count] >= (doubleBuffered ? 2 : 1)) { /* Just grab the first one off the cache. This may result in tearing effects. The alternative is to wait for one @@ -10605,7 +10608,7 @@ nswindow_orderedIndex_sort (id w1, id w2, void *c) return nil; } - CGContextTranslateCTM(context, 0, IOSurfaceGetHeight (currentSurface)); + CGContextTranslateCTM(context, 0, IOSurfaceGetHeight (surface)); CGContextScaleCTM(context, scale, -scale); } @@ -10622,6 +10625,7 @@ nswindow_orderedIndex_sort (id w1, id w2, void *c) if (!context) return; + CGContextFlush (context); CGContextRelease (context); context = NULL; @@ -10635,26 +10639,18 @@ nswindow_orderedIndex_sort (id w1, id w2, void *c) { NSTRACE_WHEN (NSTRACE_GROUP_FOCUS, "[EmacsLayer display]"); - if (context) + if (context && context != [[NSGraphicsContext currentContext] CGContext]) { [self releaseContext]; -#if CACHE_MAX_SIZE == 1 - /* This forces the layer to see the surface as updated. */ + /* This forces the layer to see the surface as updated even if + we replace it with itself. */ [self setContents:nil]; -#endif - [self setContents:(id)currentSurface]; /* Put currentSurface back on the end of the cache. */ [cache addObject:(id)currentSurface]; currentSurface = NULL; - - /* Schedule a run of getContext so that if Emacs is idle it will - perform the buffer copy, etc. */ - [self performSelectorOnMainThread:@selector (getContext) - withObject:nil - waitUntilDone:NO]; } } |