From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from sa-prd-fep-041.btinternet.com (mailomta28-sa.btinternet.com [213.120.69.34]) by sourceware.org (Postfix) with ESMTPS id C96633857BA6 for ; Sun, 14 Aug 2022 11:08:16 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org C96633857BA6 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=dronecode.org.uk Authentication-Results: sourceware.org; spf=none smtp.mailfrom=dronecode.org.uk Received: from sa-prd-rgout-001.btmx-prd.synchronoss.net ([10.2.38.4]) by sa-prd-fep-041.btinternet.com with ESMTP id <20220814110815.SADN3213.sa-prd-fep-041.btinternet.com@sa-prd-rgout-001.btmx-prd.synchronoss.net>; Sun, 14 Aug 2022 12:08:15 +0100 Authentication-Results: btinternet.com; auth=pass (PLAIN) smtp.auth=jonturney@btinternet.com; bimi=skipped X-SNCR-Rigid: 62E573CC029E8F59 X-Originating-IP: [81.153.98.171] X-OWM-Source-IP: 81.153.98.171 (GB) X-OWM-Env-Sender: jonturney@btinternet.com X-VadeSecure-score: verdict=clean score=0/300, class=clean X-RazorGate-Vade: gggruggvucftvghtrhhoucdtuddrgedvfedrvdehtddgfeeiucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuueftkffvkffujffvgffngfevqffopdfqfgfvnecuuegrihhlohhuthemuceftddunecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefkffggfgfhuffvfhgjtgfgsehtjeertddtfeejnecuhfhrohhmpeflohhnucfvuhhrnhgvhicuoehjohhnrdhtuhhrnhgvhiesughrohhnvggtohguvgdrohhrghdruhhkqeenucggtffrrghtthgvrhhnpeffhfdugfdvffdtgeefgfevveejfeekffdvhfefgfelueeggfffgefgteffgeekhfenucffohhmrghinhepvgigrdhnvghtnecukfhppeekuddrudehfedrleekrddujedunecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehhvghloheplgduledvrdduieekrddurddutdehngdpihhnvghtpeekuddrudehfedrleekrddujedupdhmrghilhhfrhhomhepjhhonhdrthhurhhnvgihsegurhhonhgvtghouggvrdhorhhgrdhukhdpnhgspghrtghpthhtohepvddprhgtphhtthhopegthihgfihinhestgihghifihhnrdgtohhmpdhrtghpthhtohepshhjrghluhhosehgmhgrihhlrdgtohhm X-RazorGate-Vade-Verdict: clean 0 X-RazorGate-Vade-Classification: clean Received: from [192.168.1.105] (81.153.98.171) by sa-prd-rgout-001.btmx-prd.synchronoss.net (5.8.716.04) (authenticated as jonturney@btinternet.com) id 62E573CC029E8F59; Sun, 14 Aug 2022 12:08:15 +0100 Message-ID: Date: Sun, 14 Aug 2022 12:08:13 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Thunderbird/91.12.0 From: Jon Turney Subject: Re: Window flickering problem in XWin multiwindow mode To: "S.J. Luo" , The Cygwin Mailing List References: Content-Language: en-GB In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-1192.3 required=5.0 tests=BAYES_00, FORGED_SPF_HELO, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, NICE_REPLY_A, RCVD_IN_DNSWL_NONE, SPF_HELO_PASS, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: cygwin@cygwin.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: General Cygwin discussions and problem reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 14 Aug 2022 11:08:18 -0000 On 07/05/2022 03:01, S.J. Luo wrote: > Hi, > >>>> I have some EDA tools running on a Linux machine and display on my Windows >>>> PC using xorg-server-21.1.3 XWin multiwindow mode >>>> Sometimes the application window flickers forever for an unknown reason. >>>> The problem became more severe after my PC upgrade to Windows10. >>>> >>>> Knowing the root cause, I am now able to demonstrate the issue with a small >>>> test case as well as a patch that works for me. Both are attached below. >>> >>> Thanks very much for taking the time to look into this, and writing a patch. >>> But I'd like to add a bit more commentary, which perhaps you can supply, >>> about the analysis you did to determine: >>> >>> 1. how the code is misbehaving >>> 2. how this change remedies that >>> 3. how this change doesn't effect anything else >>> >>> What your fix does is examine the queue of pending WM messages to >>> determine if there are any more pending for the window receiving a >>> WM_WM_CHANGE_STATE message, and if there are, ignore it. >>> >>> It seems to me that is error prone, in a couple of ways: >>> >>> 1. it should check the message type as well, as e.g. a pending message >>> of a different type could cause a WM_WM_CHANGE_STATE message to be ignored. >>> >>> 2. even then, assuming that successive WM_WM_CHANGE_STATE messages >>> cancel out each other isn't always true e.g. consider a sequence of >>> _NET_WM_STATE_ADD _NET_WM_STATE_MAXIMIZED_VERT followed by >>> _NET_WM_STATE_ADD _NET_WM_STATE_MAXIMIZED_HORZ. >>> > >> Here I have some details on the problem: >> In following, WWCS means WM_WM_CHANGE_STATE >> There exists a message self-generating loop >> I.e., a WWCS message may generate another WWCS. >> >> winSendMessageToWM(WWCS) --> MultiWindowWMProc(WWCS) >> --> UpdateState() --> ShowWindow() --> MultiWindowProc(WM_SIZE) >> --> winAdjustXWindowState() --> winSendMessageToWM(WWCS) >> >> In normal case, there is a conditional code inside UpdateState() that >> could break the loop. >> >> if (current_state == state) >> return; >> >> Normally after maximizing the window, the WWCS just >> to be self-generated once. On processing the 2nd WWCS, >> the current window state matches WWCS target state >> and ShowWindow() won't be called and the loop could end. >> >> Initial >> Window state normal >> queue : | WWCS(max1) | >> --> process WWCS(max1) : >> Winow state (norm) != target state (max2) >> Set Window state to max and generate WWCS(max2) >> queue : | WWCS(max2) | >> --> Process WWCS(max2) : >> Winow state (max) == target state (max) >> break >> >> where WWCS(max1) means WWCS msg with target state max >> and 1 means first generated/inserted WWCS in queue. >> >> However, there is case triggering this loop running forever. >> Assuming intitially there are two WWCS message exists >> where one is to maximize window and one is to normal window >> The condition of state compare in UpdateState() would never match. >> And WWCS(max) and WWCS(norm) is going to self-generate in turn. >> >> Initial >> Window state normal >> queue : | WWCS(max1) | WWCS(norm1) | >> --> process WWCS(max1) >> Winow state (norm) != target state (max) >> Set window state to max and generate WWCS(max2) >> queue : | WWCS(norm1) | WWCS(max2) | >> --> Process WWCS(norm1) >> Winow state (max) != target state (norm) >> Set window state to norm and generate WWCS(norm2) >> queue : | WWCS(max2) | WWCS(norm2) | >> --> Process WWCS(max2) >> Winow state (norm) != target state (max) >> Set window state to max and generate WWCS(max3) >> queue : | WWCS(norm2) | WWCS(max3) | >> --> Process WWCS(norm2) >> Winow state (max) != target state (norm) >> Set window state to norm and generate WWCS(norm3) >> queue : | WWCS(max3) | WWCS(norm3) | >> : >> (loop forever) >> Thanks for providing this analysis. > > I just did some more study on the code of multiwindow window manager and > X11 Window Properties as well as the questions you brought up. > > The first question : > >> it should check the message type as well, as e.g. >> a different type mesage could cause WM_WM_CHANGE_STYLE to be ignored. > > Not sure what the "type" of a message means. > Do you mean window manager message WM_xxxxx that is processed by > winMultiWindowWMProc() where it is alreadychecked in HaveMessage(), > or do you mean X message XCB_xxxxxx that is processed by > winMultiWindowXMsgProc()? > Maybe you can provide an example of another message type? I mean the various WM_WM_* messages, e.g. WM_WM_NAME_EVENT. > > The second question: > >> Successive WM_WM_CHANGE_STATE messages cancel out each other >> isn't always true ex. _NET_WM_STATE_ADD _NET_WM_STATE_MAXIMIZED_VERT >> followed by _NET_WM_STATE_ADD _NET_WM_STATE_MAXIMIZED_HORZ. > > Inspecting the code that deal with XCB_CLIENT_MESSAGE, it seems already > true before the patch: The window goes maximized only if X client do one > _WM_STATE_ADD action with _NET_WM_STATE_MAXIMIZED_VERT and > _NET_WM_STATE_MAXIMIZED_HORZ simultaneously specified. Otherwise, > the WM_WM_CHANGE would not be sent to the queue. Well, that's arguably a bug in this code :) > Further, in UpdateWindowState(), the state and related X properties are > either all-overwritten or all-skipped. > There seems to be no state property half-update case if we skip > UpdateWindowState(). > > In anyway, I just came out somewhat different patch attached. > Where it just skips the Win32 ShowWindow() call instead of > skipping processing WM_WM_CHANGE_STATE. It might be better because > the X properties are still always updated in each in WM_WM_CHANGE_STATE. > Maybe you could provide further comment. I applied a different fix in xserver 21.1.4-1, which prevents the redundant messages which winAdjustXWindowState() was queuing, which caused this thrashing to occur. This makes your test case work correctly, but perhaps you could verify that the problem is also fixed with the application you use.