Created attachment 544 [details] modified source Greetings, our application (using Jogl in a GLJPanel) blocks third party software that use the EnumWindows()/GetWindowText() Win32 functions to discover/retrieve window title names. The problem is that the dummy windows created by Jogl do not process any messages. The attached files modify the window creation process to occur each in its own thread that then falls into a message processing loop for this window. The dummy window destruction also needed to change to not use DestroyWindow() but to send a WM_CLOSE message instead. See the attached files. With these changes in place, our application no longer blocks other applications. regards, Randolf
Created attachment 545 [details] modified source
*** Bug 899 has been marked as a duplicate of this bug. ***
Dear Randolf, what is 'your application' you mention as 3rd party software .. ? I dislike the idea of creating one native thread per dummy-window - of course, since it would explode the number of used resources even if they are almost sleeping. I will look at this issue later on, but also would like to learn about this test case of yours. Such knowledge might help to find another solution for the issue.
Created attachment 547 [details] GDIMisc.c revised to use only one thread I have revised the code to use only one extra thread. The thread is created/destroyed with the window class. Window creation/destruction is done via user-defined messages. The ugly volatile stuff to communicate/sync is still there and could be replaced by events. This probably breaks NEWT unless the creation of the message processing thread is confined to AWT by another if statement (you are probably more qualified than I to insert this one).
(In reply to comment #3) > Dear Randolf, what is 'your application' you mention as 3rd party software it is actually a whole application scenario, in a hospital, where the blocked application tries to connect a patient information system and yet another system. The connecting application is probably continually sending messages to wait for a certain window to appear. Needless to say: all three applications are completely beyond our control. When we run with OpenGL activated, the connecting application is blocked. The only real solution is to start processing messages. For testing purposes, I can provide a Win32 executable that just does the EnumWindows()/GetWindowText() in an endless loop (just like the connecting app) and that we also successfully block/unblock depending on the changes to GDImisc.c... regards, Randolf
(In reply to comment #4) > Created attachment 547 [details] > GDIMisc.c revised to use only one thread > > I have revised the code to use only one extra thread. > The thread is created/destroyed with the window class. > Window creation/destruction is done via user-defined > messages. The ugly volatile stuff to communicate/sync > is still there and could be replaced by events. Reads much better now, thank you! Please provide a git patch (email or pull request from a repo) if possible. Otherwise I would need to apply your patch using your author name. What I don't understand - why should we use WM_CLOSE for destruction ? AFAIK we do not use such mechanism in NEWT, but simply destroy the window - will double check. > > This probably breaks NEWT unless the creation of the > message processing thread is confined to AWT by another > if statement (you are probably more qualified than I to > insert this one). Yes. So this must be made optional for creating the 'window class'. Note: All this has nothing todo w/ AWT!
(In reply to comment #5) > (In reply to comment #3) > > Dear Randolf, what is 'your application' you mention as 3rd party software > > it is actually a whole application scenario, in a hospital, where the > blocked application tries to connect a patient information system and > yet another system. The connecting application is probably continually > sending messages to wait for a certain window to appear. > Needless to say: all three applications are completely beyond our control. > > When we run with OpenGL activated, the connecting application is > blocked. The only real solution is to start processing messages. > > For testing purposes, I can provide a Win32 executable that just does > the EnumWindows()/GetWindowText() in an endless loop (just like the > connecting app) and that we also successfully block/unblock depending > on the changes to GDImisc.c... > Thank you for sharing the rational. Pls do attach a test case (ANSI-C source code - ofc). I will add it to the test-native folder. It is mandatory to have this test to validate against it. > regards, > Randolf
(In reply to comment #7) > Pls do attach a test case (ANSI-C source code - ofc). We must be able to compile the ANSI-C source code w/ MINGW-64.
Dear Randolf, I would appreciate your input/results, so we can add the solution into 2.1.3 release. If we fail 2.1.3, 2.2.0 is next and is planned to 'take a while'. At least - pls provide the test case, to validate changes. Thank you!
Created attachment 561 [details] test program Dear Sven, sorry for getting back to you so late. I have attached a simple test program as source. It prints "SUCCESS!"/"FAILURE!" to the console depending on whether there are windows that do not process the WM_GETTEXT message. Regarding your questions: Sending WM_CLOSE was necessary in my first version of the patch as this was a multi-thread scenario and you can not use DestroyWindow() over a thread boundary. In the one-thread version we can use DestroyWindow() directly again, as it is called from the ThreadFunc(). Thanks for clarification wrt. AWT, I used the term to distinguish between NEWT and "the other integration" we use. :) Randolf
(In reply to comment #10) > Created attachment 561 [details] > test program > > Dear Sven, > > sorry for getting back to you so late. still in time for 2.1.3 - thank you for getting back at all > > I have attached a simple test program as source. > It prints "SUCCESS!"/"FAILURE!" to the console > depending on whether there are windows that do > not process the WM_GETTEXT message. Great. > > Regarding your questions: > Sending WM_CLOSE was necessary in my first version > of the patch as this was a multi-thread scenario > and you can not use DestroyWindow() over a thread > boundary. In the one-thread version we can use > DestroyWindow() directly again, as it is called > from the ThreadFunc(). Perfect. > > Thanks for clarification wrt. AWT, I used the term > to distinguish between NEWT and "the other integration" > we use. :) Since you have not provided a git patch or git pull request, [1] I need to merge your changes and hence need your full name and your email address for the git commit. Either I take your credentials as known from this bug report, or [2] you provide a git patch (email, pull request, ..). Regardless, I test your changes now and hence may already performed [1]. ~Sven > > Randolf
(In reply to comment #11) Dear Sven, > Since you have not provided a git patch or git pull request, > [1] I need to merge your changes and hence need your > full name and your email address for the git commit. you can use the information from Bugzilla. Note, that there is still some work left to do: a) The creation of the thread must not take place for NEWT. b) The original CreateDummyWindow0() can probably be removed altogether (but I did not check for potential references besides the one from GDIUtil and so left it in). regards, Randolf
e9c711a86aa05f4f24c69972532833f5a98911a3 Initial patch allowing Jogl to respond to other applications that try to retrieve window names 52c95c19dbd69a7fc6b307d2b2db357ceb43ddf5 Cleanup Commit e9c711a86aa05f4f24c69972532833f5a98911a3: - Fix while loop in SendCloseMessage (native) - static 'threadid' must be volatile - Whitespace - Redundancy - CreateDummyWindow - Scope (java, move JNI funcs back to private) - Remove [invalid] pointer usage (native) - ThreadParam's threadReady and hWndPtr shall not be pointers - invalid - No need to use a threadReady pointer. - Validate threadid (native) TODO: - Make 'native dispatch thread' optional - Store 'native dispatch thread' in window class f52c89e36cccd5eb141882a4b3378efe54aa9576 Bug 907 - Fix regression of 'cleanup' Commit 52c95c19dbd69a7fc6b307d2b2db357ceb43ddf5 586446311ea1ba87f98236d5347955bf99b465d6 Refine DummyDispatchThread (DDT) Handling ... 586446311ea1ba87f98236d5347955bf99b465d6 Proper OO integration of DDT in RegisteredClass - DDT is optional to RegisteredClass[Factory], i.e. NEWT without DDT and DummyWindow with DDT. - Using native type DummyThreadContext per DDT passed as DDT handle to java referenced in RegisteredClass - Passing DDT handle to related native methods, if not null use DDT - otherwise work on current thread. The latter impacts CreateDummyWindow0 and DestroyWindow0. Safe DDT Post/WaitForReady handling and error cases ; ... - Wait until command it complete using a 3s timeout - Terminate thread if errors occur and throw an exception +++ Discussion: DDT Native Implementation Due to original code, the DDT is implemented in native code. Usually we should favor running the DDT from a java thread. However, since it's main purpose is _not_ to interact w/ java and the native implementation has less footprint (performance and memory) we shall be OK w/ it for now - as long the implementation IS SAFE.
efc158abbb2c282029aaa746e032ec678e374d7b Add native Windows test sending WM_GETTEXT to all windows and dumping the result. If working, Bug907 is fixed and hence DDT is working.