From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Alan Third Newsgroups: gmane.emacs.bugs Subject: bug#46155: [PATCH v2] Fix flicker when resizing NS frame programmatically (bug#46155) Date: Thu, 11 Feb 2021 22:16:48 +0000 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="29237"; mail-complaints-to="usenet@ciao.gmane.io" Cc: 46155@debbugs.gnu.org, andreyk.mad@gmail.com To: Aaron Jensen Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Thu Feb 11 23:17:52 2021 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1lAKHX-0007V7-K1 for geb-bug-gnu-emacs@m.gmane-mx.org; Thu, 11 Feb 2021 23:17:51 +0100 Original-Received: from localhost ([::1]:44928 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lAKHW-0004Zd-9V for geb-bug-gnu-emacs@m.gmane-mx.org; Thu, 11 Feb 2021 17:17:50 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:34646) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lAKGk-0004XH-Ul for bug-gnu-emacs@gnu.org; Thu, 11 Feb 2021 17:17:02 -0500 Original-Received: from debbugs.gnu.org ([209.51.188.43]:47957) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lAKGk-0003YS-MX for bug-gnu-emacs@gnu.org; Thu, 11 Feb 2021 17:17:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1lAKGk-0008DD-I5 for bug-gnu-emacs@gnu.org; Thu, 11 Feb 2021 17:17:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Alan Third Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 11 Feb 2021 22:17:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 46155 X-GNU-PR-Package: emacs Original-Received: via spool by 46155-submit@debbugs.gnu.org id=B46155.161308181831553 (code B ref 46155); Thu, 11 Feb 2021 22:17:02 +0000 Original-Received: (at 46155) by debbugs.gnu.org; 11 Feb 2021 22:16:58 +0000 Original-Received: from localhost ([127.0.0.1]:59503 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lAKGf-0008Cr-Sn for submit@debbugs.gnu.org; Thu, 11 Feb 2021 17:16:58 -0500 Original-Received: from [217.169.17.33] (port=52054 helo=breton.holly.idiocy.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lAKGd-0008Cd-Rj for 46155@debbugs.gnu.org; Thu, 11 Feb 2021 17:16:56 -0500 Original-Received: by breton.holly.idiocy.org (Postfix, from userid 501) id 3B59B202A4F438; Thu, 11 Feb 2021 22:16:48 +0000 (GMT) Mail-Followup-To: Alan Third , Aaron Jensen , 46155@debbugs.gnu.org, andreyk.mad@gmail.com Content-Disposition: inline In-Reply-To: X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:199833 Archived-At: ; Incidentally fixes bug#21326. * src/nsterm.m ([EmacsView viewWillDraw]): New function. ([EmacsView viewDidResize:]): We now have to mark the frame for display on resize. ([EmacsView initFrameFromEmacs:]): Retain frame contents on resize. ([EmacsView updateLayer]): Don't update the layer is the frame is still garbaged. --- src/nsterm.m | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/nsterm.m b/src/nsterm.m index 1b2328628e..ab898184f5 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -7339,6 +7339,8 @@ - (void)viewDidResize:(NSNotification *)notification [surface release]; surface = nil; + + [self setNeedsDisplay:YES]; } #endif @@ -7510,6 +7512,16 @@ - (instancetype) initFrameFromEmacs: (struct frame *)f [self initWithFrame: r]; [self setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable]; +#ifdef NS_DRAW_TO_BUFFER + /* These settings mean AppKit will retain the contents of the frame + on resize. Unfortunately it also means the frame will not be + automatically marked for display, but we can do that ourselves in + viewDidResize. */ + [self setLayerContentsRedrawPolicy: + NSViewLayerContentsRedrawOnSetNeedsDisplay]; + [self setLayerContentsPlacement:NSViewLayerContentsPlacementTopLeft]; +#endif + FRAME_NS_VIEW (f) = self; emacsframe = f; #ifdef NS_IMPL_COCOA @@ -8452,6 +8464,34 @@ - (void)copyRect:(NSRect)srcRect to:(NSRect)dstRect } +#ifdef NS_IMPL_COCOA +/* If the frame has been garbaged but the toolkit wants to draw, for + example when resizing the frame, we end up with a blank screen. + Sometimes this results in an unpleasant flicker, so try to + redisplay before drawing. */ +- (void)viewWillDraw +{ + if (FRAME_GARBAGED_P (emacsframe) + && !redisplaying_p) + { + /* If there is IO going on when redisplay is run here Emacs + crashes. I think it's because this code will always be run + within the run loop and for whatever reason processing input + is dangerous. This technique was stolen wholesale from + nsmenu.m and seems to work. */ + bool owfi = waiting_for_input; + waiting_for_input = 0; + block_input (); + + redisplay (); + + unblock_input (); + waiting_for_input = owfi; + } +} +#endif + + #ifdef NS_DRAW_TO_BUFFER - (BOOL)wantsUpdateLayer { @@ -8469,6 +8509,13 @@ - (void)updateLayer { NSTRACE ("[EmacsView updateLayer]"); + /* We run redisplay on frames that are garbaged but marked for + display before updateLayer is called, so if the frame is still + garbaged that means the last redisplay must have refused to + update the frame. */ + if (FRAME_GARBAGED_P (emacsframe)) + return; + /* This can fail to update the screen if the same surface is provided twice in a row, even if its contents have changed. There's a private method, -[CALayer setContentsChanged], that we -- 2.29.2 -- Alan Third