X-Recipient: archive-cygwin AT delorie DOT com DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:to:subject:mime-version:content-type :content-transfer-encoding:date:from:in-reply-to:references :message-id; q=dns; s=default; b=fuDV4AGi+Qf4NRlBMOZ1Kw7lMVev0VO 0zlicRomTVVR8WpKSSdA7LW0KHxMVAmOAmcsN/i85VFWypYcZsxGjLxV1EEJ8Qsj VnunmHOR0cQI68UEJMYDMdO1Febu7KK87nn1SPDkjXl/khOntnbaDvdr5Wda7yDr jmI1kPLn9bc8= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:to:subject:mime-version:content-type :content-transfer-encoding:date:from:in-reply-to:references :message-id; s=default; bh=vepZWGX71E2zsQRm0VCnfiS+sG4=; b=JwLPk EtMzrfX6I+KVbPgwqkTFG/1pkNWvPD1BI6gOKtAe8w9lQZhpQ2VNMIBuL11yhvY0 i4vhpbgd0oFLAz2qaMwrARxrCFN/ND8I1/4lMJNSVDzcGc9MuLVXDv+QkBzLj4WB zzuvI49+hh1SymVgM2i1lX3L6fGpjtr4U0qNgA= Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.8 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 spammy=H*RU:64.59.136.137, Hx-spam-relays-external:64.59.136.137, H*i:sk:49c8dca, H*f:sk:49c8dca X-HELO: smtp-out-so.shaw.ca X-Authority-Analysis: v=2.2 cv=Q++Q2M+a c=1 sm=1 tr=0 a=WiYoHcCliNeVponEdG0Ckg==:117 a=WiYoHcCliNeVponEdG0Ckg==:17 a=L9H7d07YOLsA:10 a=9cW_t1CCXrUA:10 a=s5jvgZ67dGcA:10 a=cAmyUtKerLwA:10 a=2KUf1mbJAAAA:8 a=ejQruhyicXs5b7heL3gA:9 a=LME9DoRMzU6P72L8X6EC:22 To: Cygwin Subject: Re: [PATCH] Strange behavior of cmd.exe when hammered with clear screen operations from Cygwin program. X-PHP-Originating-Script: 501:rcmail.php MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Date: Wed, 27 Jul 2016 08:40:42 -0700 From: Kaz Kylheku In-Reply-To: <49c8dca543daed3fa35b29e41ebf449b@mail.kylheku.com> References: <05e87c9326e8bc9a32a5a3cd2511fe98 AT mail DOT kylheku DOT com> <9b05b6502dc0bdba2654069cfa924a50 AT mail DOT kylheku DOT com> <6d026b0ea424481879a89d480730c1f4 AT mail DOT kylheku DOT com> <49c8dca543daed3fa35b29e41ebf449b AT mail DOT kylheku DOT com> Message-ID: <50bb6b3942d5fb67057465f8b09b7121@mail.kylheku.com> X-Sender: kaz AT kylheku DOT com User-Agent: Roundcube Webmail/0.9.2 X-CMAE-Envelope: MS4wfN0dQa7GbWaMJcBAj8z58rVTEWgfyJeEFB8VThF7/RzcZhaMQtVMs3hruBsyZml2FQyzC0JoLwdRcCskV2DRBIoK0oNGenWpSKDUCfkqkQG+iAunxez+ Uf9+rG3O7j0cEKqNQ0AhY/xeJn2vaOPFRDhmvkdqm2lCNDwu9Gjx4+Vj Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from quoted-printable to 8bit by delorie.com id u6RFfBlq008362 On 27.07.2016 07:35, Kaz Kylheku wrote: > On 27.07.2016 07:31, Kaz Kylheku wrote: >> The patch below seems to solves it for me: > > Oops, no it doesn't. Stay tuned. :) This is a bit more like it: From: Kaz Kylheku Date: Wed, 27 Jul 2016 07:49:54 -0700 Subject: Replace bogus resize-window-to-clear-screen logic. This removes (ab)uses of SetConsoleScreenBufferSize which sometimes cause cmd.exe to badly misbehave. It probably doesn't like the closely spaced timing of shrinking the window down to one line followed by a restore of the size. Instead we just output newlines to clear the window. * winsup/cygwin/fhandler.h (dev_console::scroll_window): Member function declaration removed. (dev_console::clear_should_scroll): New member function declared. * winsup/cygwin/fhandler_console.cc (dev_console::scroll_window): Member function removed. (dev_console::clear_should_scroll): New member function. Performs only the test that was performed by scroll_window, not the actual scrolling. The scrolling is now done in the caller in the fhandler_console class. (fhandler_console::clear_screen): Call con.clear_should_scroll instead of con.scroll_window. If this returns false, act as before. Otherwise, clear the screen by scrolling the window. This is done not by making SetConsoleScreenBufferSize calls to shrink and restore the window, but by earnestly emitting a number of carriage returns equal to the vertical screen size and then restoring the cursor position. diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 21c71d7..4af584b 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1361,7 +1361,7 @@ class dev_console int set_cl_x (cltype); int set_cl_y (cltype); bool fillin (HANDLE); - bool __reg3 scroll_window (HANDLE, int, int, int, int); + bool __reg3 clear_should_scroll (HANDLE, int, int, int, int); void __reg3 scroll_buffer (HANDLE, int, int, int, int, int, int); void __reg3 clear_screen (HANDLE, int, int, int, int); void __reg3 save_restore (HANDLE, char); diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc index 5fe4480..380aeec 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -1209,38 +1209,11 @@ dev_console::set_cl_y (cltype y) } bool -dev_console::scroll_window (HANDLE h, int x1, int y1, int x2, int y2) +dev_console::clear_should_scroll (HANDLE h, int x1, int y1, int x2, int y2) { if (save_buf || x1 != 0 || x2 != dwWinSize.X - 1 || y1 != b.srWindow.Top || y2 != b.srWindow.Bottom || b.dwSize.Y <= dwWinSize.Y) return false; - - SMALL_RECT sr; - int toscroll = 2 + dwEnd.Y - b.srWindow.Top; - int shrink = 1 + toscroll + b.srWindow.Bottom - b.dwSize.Y; - sr.Left = sr.Right = dwEnd.X = 0; - /* Can't increment dwEnd yet since we may not have space in - the buffer. */ - SetConsoleCursorPosition (h, dwEnd); - if (shrink > 0) - { - COORD c = b.dwSize; - c.Y = dwEnd.Y - shrink; - SetConsoleScreenBufferSize (h, c); - SetConsoleScreenBufferSize (h, b.dwSize); - dwEnd.Y = 0; - fillin (h); - toscroll = 2 + dwEnd.Y - b.srWindow.Top; - } - - sr.Top = sr.Bottom = toscroll; - - SetConsoleWindowInfo (h, FALSE, &sr); - - dwEnd.Y++; - SetConsoleCursorPosition (h, dwEnd); - - fillin (h); return true; } @@ -1261,8 +1234,27 @@ fhandler_console::clear_screen (cltype xc1, cltype yc1, cltype xc2, cltype yc2) /* Detect special case - scroll the screen if we have a buffer in order to preserve the buffer. */ - if (!con.scroll_window (h, x1, y1, x2, y2)) - con.clear_screen (h, x1, y1, x2, y2); + if (!con.clear_should_scroll (h, x1, y1, x2, y2)) + { + con.clear_screen (h, x1, y1, x2, y2); + return; + } + + int xpos, ypos; + DWORD done; + cursor_get(&xpos, &ypos); + cursor_set(false, 0, con.b.dwSize.Y - 1); + + for (int i = 0; i < con.dwWinSize.Y; i += done) + { + if (!WriteConsoleW (h, L"\n", 1, &done, 0)) + { + __seterrno (); + break; + } + } + + cursor_set(false, xpos, ypos); } void __reg3 -- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple