RE: Mouse offset when using java swing based gui applications
Yes, my experience is the same as yours. The menus test starts with the frame hidden off the top left, as before, but when I move the window, the menus _do_ work OK. Apps which set an initial location (add jframe.setLocation(400, 400); after the pack() call) appear correctly and the menus still work. Interestingly with the 1.7.3 XWin, the app would appear in the right place but would tend to snap back to the top left if you tried to resize the window. This does not seem to happen with the patched server. Richard -Original Message- From: Jon TURNEY [mailto:jon.tur...@dronecode.org.uk] Sent: 21 July 2010 20:08 To: cygwin-xfree@cygwin.com; Richard Evans Subject: Re: Mouse offset when using java swing based gui applications On 19/07/2010 17:27, Richard Evans wrote: I've attached a small test case which shows the menu problems. Thanks very much, that was very helpful in investigating this problem. This menu behaviour has been seen for all versions of JDK 1.6 as far as I remember; it certainly happens with 1.6u3 and 1.6u4. Yes, I wasn't testing what I thought I was testing, and was completely wrong when I said sun bug #6434227 was fixed in the JRE that it claims it's fixed in. It's fixed in JDK1.7 and OpenJDK, but that bug lies when it says the fix is in 1.6 as well. However, it does identify what's going wrong. The significant difference in XDecoratedPeer.java between 1.6u21 and a fixed version is: --- /opt/wip/jdk-1_6_0/j2se/src/solaris/classes/sun/awt/X11/XDecoratedPeer.j ava 2010-07-21 15:46:33.28125 +0100 +++ /opt/wip/openjdk/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java 2010-06-21 22:15:43.0 +0100 @@ -752,79 +748,69 @@ Point newLocation = targetBounds.getLocation(); -if (xe.get_send_event()) { +if (xe.get_send_event() || runningWM == XWM.NO_WM || XWM.isNonReparentingWM()) { // Location, Client size + insets newLocation = new Point(xe.get_x() - currentInsets.left, xe.get_y() - currentInsets.top); } else { // CDE/MWM/Metacity/Sawfish bug: if shell is resized using // top or left border, we don't receive synthetic // ConfigureNotify, only the one from X with zero // coordinates. This is the workaround to get real // location, 6261336 -// Do the same for non-reparenting WMs (Compiz, Looking Glass) switch (XWM.getWMID()) { case XWM.CDE_WM: case XWM.MOTIF_WM: case XWM.METACITY_WM: case XWM.SAWFISH_WM: - case XWM.COMPIZ_WM: - case XWM.LG3D_WM: { Point xlocation = queryXLocation(); if (log.isLoggable(Level.FINE)) { log.log(Level.FINE, New X location: {0}, new Object[]{String.valueOf(xlocation)}); } if (xlocation != null) { newLocation = xlocation; } break; } default: break; } } Location updates from ConfigureNotify are not processed in the NO_WM case, presumably causing the menus behave as if the window was still located where it was created. There are 2 possible workarounds which occur to me: (i) Lie and pretend we are a non-reparenting WM on the list that AWT knows about, like LG3D. This one of the workarounds suggested in the manpage for dwm (a non-reparenting, tiling WM) Unfortunately, we have to tell a more lies to get AWT to accept this lie, and in particular, we have to claim to support EWMH, which the internal WM doesn't really (although it should), so I'm not too keen on this approach. (ii) Alternatively, it's a straightforward workaround to add to the internal WM to cause it to send synthetic ConfigureNotify for these windows when a non-synthetic ConfigureNotify occurs. From a quick test, this approach seems to work ok. But the Java window still appears with the frame off the top-left, rather than getting nudged away from the origin so the frame is visible, which is rather mysterious. I've uploaded a build with this change at [1], patch to follow. Perhaps you could try it out and see if it works for you? [1] ftp://cygwin.com/pub/cygwinx/XWin.20100721-git-2704058015f198ce.exe.bz2 -- Jon TURNEY Volunteer Cygwin/X X Server maintainer -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://x.cygwin.com/docs/ FAQ: http://x.cygwin.com/docs/faq/
[PATCH] Cygwin/X: Fix a GDI bitmap resource leak of window icons
Ensure any icon created specially for a window is destroyed when the window is destroyed Signed-off-by: Jon TURNEY jon.tur...@dronecode.org.uk --- hw/xwin/winmultiwindowicons.c |3 ++- hw/xwin/winmultiwindowwindow.c | 13 - hw/xwin/winwin32rootless.c | 20 ++-- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/hw/xwin/winmultiwindowicons.c b/hw/xwin/winmultiwindowicons.c index cb27d2f..86ad51e 100644 --- a/hw/xwin/winmultiwindowicons.c +++ b/hw/xwin/winmultiwindowicons.c @@ -631,6 +631,7 @@ void winSelectIcons(WindowPtr pWin, HICON *pIcon, HICON *pSmallIcon) *pIcon = hIcon; else winDestroyIcon(hIcon); + if (pSmallIcon) *pSmallIcon = hSmallIcon; else @@ -639,7 +640,7 @@ void winSelectIcons(WindowPtr pWin, HICON *pIcon, HICON *pSmallIcon) void winDestroyIcon(HICON hIcon) { - /* Delete the icon if its not the default */ + /* Delete the icon if its not one of the application defaults or an override */ if (hIcon hIcon != g_hIconX hIcon != g_hSmallIconX diff --git a/hw/xwin/winmultiwindowwindow.c b/hw/xwin/winmultiwindowwindow.c index fd87c66..d9bec35 100644 --- a/hw/xwin/winmultiwindowwindow.c +++ b/hw/xwin/winmultiwindowwindow.c @@ -602,7 +602,9 @@ winDestroyWindowsWindow (WindowPtr pWin) MSG msg; winWindowPriv(pWin); BOOL oldstate = winInDestroyWindowsWindow; - + HICON hIcon; + HICON hIconSm; + #if CYGMULTIWINDOW_DEBUG ErrorF (winDestroyWindowsWindow\n); #endif @@ -613,13 +615,22 @@ winDestroyWindowsWindow (WindowPtr pWin) winInDestroyWindowsWindow = TRUE; + /* Store the info we need to destroy after this window is gone */ + hIcon = (HICON)SendMessage(pWinPriv-hWnd, WM_GETICON, ICON_BIG, 0); + hIconSm = (HICON)SendMessage(pWinPriv-hWnd, WM_GETICON, ICON_SMALL, 0); + SetProp (pWinPriv-hWnd, WIN_WINDOW_PROP, NULL); + /* Destroy the Windows window */ DestroyWindow (pWinPriv-hWnd); /* Null our handle to the Window so referencing it will cause an error */ pWinPriv-hWnd = NULL; + /* Destroy any icons we created for this window */ + winDestroyIcon(hIcon); + winDestroyIcon(hIconSm); + /* Process all messages on our queue */ while (PeekMessage (msg, NULL, 0, 0, PM_REMOVE)) { diff --git a/hw/xwin/winwin32rootless.c b/hw/xwin/winwin32rootless.c index c225a44..0e2f979 100755 --- a/hw/xwin/winwin32rootless.c +++ b/hw/xwin/winwin32rootless.c @@ -367,8 +367,8 @@ void winMWExtWMDestroyFrame (RootlessFrameID wid) { win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; - HICONhiconClass; - HICONhiconSmClass; + HICONhIcon; + HICONhIconSm; HMODULE hInstance; int iReturn; char pszClass[CLASS_NAME_LENGTH]; @@ -399,8 +399,8 @@ winMWExtWMDestroyFrame (RootlessFrameID wid) /* Store the info we need to destroy after this window is gone */ hInstance = (HINSTANCE) GetClassLongPtr (pRLWinPriv-hWnd, GCLP_HMODULE); - hiconClass = (HICON) GetClassLongPtr (pRLWinPriv-hWnd, GCLP_HICON); - hiconSmClass = (HICON) GetClassLongPtr (pRLWinPriv-hWnd, GCLP_HICONSM); + hIcon = (HICON)SendMessage(pRLWinPriv-hWnd, WM_GETICON, ICON_BIG, 0); + hIconSm = (HICON)SendMessage(pRLWinPriv-hWnd, WM_GETICON, ICON_SMALL, 0); iReturn = GetClassName (pRLWinPriv-hWnd, pszClass, CLASS_NAME_LENGTH); pRLWinPriv-fClose = TRUE; @@ -416,14 +416,14 @@ winMWExtWMDestroyFrame (RootlessFrameID wid) winDebug (winMWExtWMDestroyFrame - Unregistering %s: , pszClass); #endif iReturn = UnregisterClass (pszClass, hInstance); - +} + #if CYGMULTIWINDOW_DEBUG - winDebug (winMWExtWMDestroyFramew - %d Deleting Icon: , iReturn); + winDebug (winMWExtWMDestroyFramew - Deleting Icon\n); #endif - - winDestroyIcon(hiconClass); - winDestroyIcon(hiconSmClass); -} + + winDestroyIcon(hIcon); + winDestroyIcon(hIconSm); #if CYGMULTIWINDOW_DEBUG winDebug (winMWExtWMDestroyFrame - done\n); -- 1.7.1 -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://x.cygwin.com/docs/ FAQ: http://x.cygwin.com/docs/faq/