summaryrefslogtreecommitdiff
path: root/src/nsterm.m
diff options
context:
space:
mode:
Diffstat (limited to 'src/nsterm.m')
-rw-r--r--src/nsterm.m156
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];
}
}