macOS: Fix a regression that could cause rendering of a kitty window to occasionally freeze in certain situations, such as moving it between monitors or transitioning from/to fullscreen

Fixes #1641
This commit is contained in:
Kovid Goyal 2019-05-28 17:54:34 +05:30
parent 39f50830d7
commit abf9c4117d
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 61 additions and 34 deletions

View File

@ -13,6 +13,10 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
- Fix a missing newline when using the pipe command between the
scrollback and screen contents (:iss:`1642`)
- macOS: Fix a regression that could cause rendering of a kitty window
to occasionally freeze in certain situations, such as moving it between
monitors or transitioning from/to fullscreen (:iss:`1641`)
0.14.0 [2019-05-24]
---------------------

View File

@ -366,6 +366,7 @@ void _glfwPollMonitorsNS(void)
free(disconnected);
free(displays);
_glfwRestartDisplayLinks();
}
// Change the current video mode

View File

@ -224,6 +224,7 @@ void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired);
void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor);
float _glfwTransformYNS(float y);
void _glfwClearDisplayLinks(void);
void _glfwRestartDisplayLinks(void);
void _glfwCocoaPostEmptyEvent(short subtype, long data1, bool at_start);
void _glfwDispatchTickCallback(void);
void _glfwDispatchRenderFrame(CGDirectDisplayID);

View File

@ -53,6 +53,51 @@ static NSUInteger getStyleMask(_GLFWwindow* window)
return styleMask;
}
CGDirectDisplayID displayIDForWindow(_GLFWwindow *w) {
NSWindow *nw = w->ns.object;
NSDictionary *dict = [nw.screen deviceDescription];
NSNumber *displayIDns = [dict objectForKey:@"NSScreenNumber"];
if (displayIDns) return [displayIDns unsignedIntValue];
return (CGDirectDisplayID)-1;
}
static inline void
requestRenderFrame(_GLFWwindow *w, GLFWcocoarenderframefun callback) {
if (!callback) {
w->ns.renderFrameRequested = GLFW_FALSE;
w->ns.renderFrameCallback = NULL;
return;
}
w->ns.renderFrameCallback = callback;
w->ns.renderFrameRequested = GLFW_TRUE;
CGDirectDisplayID displayID = displayIDForWindow(w);
[_glfw.ns.displayLinks.lock lock];
for (size_t i = 0; i < _glfw.ns.displayLinks.count; i++) {
_GLFWDisplayLinkNS *dl = &_glfw.ns.displayLinks.entries[i];
if (dl->displayID == displayID) {
dl->renderFrameRequested = GLFW_TRUE;
if (!dl->displayLinkStarted) {
CVDisplayLinkStart(dl->displayLink);
dl->displayLinkStarted = GLFW_TRUE;
}
break;
}
}
[_glfw.ns.displayLinks.lock unlock];
}
void
_glfwRestartDisplayLinks(void) {
_GLFWwindow* window;
for (window = _glfw.windowListHead; window; window = window->next) {
if (window->ns.renderFrameRequested && window->ns.renderFrameCallback) {
requestRenderFrame(window, window->ns.renderFrameCallback);
}
}
}
// Returns whether the cursor is in the content area of the specified window
//
static GLFWbool cursorInContentArea(_GLFWwindow* window)
@ -453,6 +498,16 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
_glfwInputWindowFocus(window, GLFW_FALSE);
}
- (void)windowDidChangeScreen:(NSNotification *)notification
{
if (window->ns.renderFrameRequested && window->ns.renderFrameCallback) {
// Ensure that if the window changed its monitor, CVDisplayLink
// is running for the new monitor
requestRenderFrame(window, window->ns.renderFrameCallback);
}
}
@end
@ -592,7 +647,6 @@ static GLFWapplicationshouldhandlereopenfun handle_reopen_callback = NULL;
_glfwInputLiveResize(window, false);
}
- (BOOL)wantsUpdateLayer
{
return YES;
@ -1774,14 +1828,6 @@ void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
[window->ns.object setAlphaValue:opacity];
}
CGDirectDisplayID displayIDForWindow(_GLFWwindow *w) {
NSWindow *nw = w->ns.object;
NSDictionary *dict = [nw.screen deviceDescription];
NSNumber *displayIDns = [dict objectForKey:@"NSScreenNumber"];
if (displayIDns) return [displayIDns unsignedIntValue];
return (CGDirectDisplayID)-1;
}
void
_glfwDispatchRenderFrame(CGDirectDisplayID displayID) {
_GLFWwindow *w = _glfw.windowListHead;
@ -1794,31 +1840,6 @@ _glfwDispatchRenderFrame(CGDirectDisplayID displayID) {
}
}
static inline void
requestRenderFrame(_GLFWwindow *w, GLFWcocoarenderframefun callback) {
if (!callback) {
w->ns.renderFrameRequested = GLFW_FALSE;
w->ns.renderFrameCallback = NULL;
return;
}
w->ns.renderFrameCallback = callback;
w->ns.renderFrameRequested = GLFW_TRUE;
CGDirectDisplayID displayID = displayIDForWindow(w);
[_glfw.ns.displayLinks.lock lock];
for (size_t i = 0; i < _glfw.ns.displayLinks.count; i++) {
_GLFWDisplayLinkNS *dl = &_glfw.ns.displayLinks.entries[i];
if (dl->displayID == displayID) {
dl->renderFrameRequested = GLFW_TRUE;
if (!dl->displayLinkStarted) {
CVDisplayLinkStart(dl->displayLink);
dl->displayLinkStarted = GLFW_TRUE;
}
break;
}
}
[_glfw.ns.displayLinks.lock unlock];
}
void _glfwCocoaPostEmptyEvent(short subtype, long data1, bool at_start)
{
@autoreleasepool {