JDK-6711576 : Applet warning icon is place on the Jdialog & JOptionPane in b26 pit build
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 6u10
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_vista
  • CPU: x86
  • Submitted: 2008-06-06
  • Updated: 2011-01-19
  • Resolved: 2008-09-02
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6
6u10 b31Fixed
Related Reports
Relates :  
Description
The new applet warning icon should be place with two pixel gap between the Top level ( frame , dialog) . This works fine for frame , but fails for JDialog & JOptionPane in vista theme. I have attached the screen shot of the same. 

Step to reproduce:-
---------------------
1) Run swingset2.
2) Select JOptionPane demo.
3) Click on "show confirmation button". Observe that applet warning icon is touching the border of the JOptionPane. If you see the same then the bug is reproduced.

Comments
EVALUATION Since there's another issue with the border (see 6728768), the patch for this CR is going to fix the location of the warning icon only.
24-07-2008

SUGGESTED FIX --- old/src/windows/native/sun/windows/awt_dlls.cpp 2008-07-28 17:37:09.000000000 +0400 +++ new/src/windows/native/sun/windows/awt_dlls.cpp 2008-07-28 17:37:08.000000000 +0400 @@ -409,3 +409,37 @@ } initialized = true; } + + +/***********************************************************************/ + +DwmIsCompositionEnabledType fn_dwm_is_composition_enabled = NULL; +DwmGetWindowAttributeType fn_dwm_get_window_attribute = NULL; + +void load_dwmapi_procs() +{ + static int initialized = 0; + if (initialized) { + return; + } + + // dwmapi.dll is known to appear in Vista. + if (!IS_WINVISTA) { + initialized = -1; + return; + } + + HMODULE lib = ::LoadLibrary(TEXT("DWMAPI.DLL")); + if (lib == NULL) { + initialized = -2; + return; + } + + fn_dwm_is_composition_enabled = (DwmIsCompositionEnabledType) + GetProcAddress(lib, "DwmIsCompositionEnabled"); + fn_dwm_get_window_attribute = (DwmGetWindowAttributeType) + GetProcAddress(lib, "DwmGetWindowAttribute"); + + initialized = 1; +} + --- old/src/windows/native/sun/windows/awt_dlls.h 2008-07-28 17:37:09.000000000 +0400 +++ new/src/windows/native/sun/windows/awt_dlls.h 2008-07-28 17:37:09.000000000 +0400 @@ -158,4 +158,17 @@ static PlaySoundWFunc* playSoundFunc; }; +//--------------------------------------------------------------------------- + +// Dynamically load in DWMAPI.DLL and define the procedure pointers listed below. +extern void load_dwmapi_procs(); + +// Procedure pointers obtained from DWMAPI.DLL +// You must call load_dwmapi_procs() before using any of these. +typedef HRESULT (WINAPI *DwmIsCompositionEnabledType)(BOOL*); +typedef HRESULT (WINAPI *DwmGetWindowAttributeType)(HWND hwnd, DWORD dwAttribute, + PVOID pvAttribute, DWORD cbAttribute); +extern DwmIsCompositionEnabledType fn_dwm_is_composition_enabled; +extern DwmGetWindowAttributeType fn_dwm_get_window_attribute; + #endif /* AWT_DLLS_H */ --- old/src/windows/native/sun/windows/awt_Toolkit.cpp 2008-07-28 17:37:09.000000000 +0400 +++ new/src/windows/native/sun/windows/awt_Toolkit.cpp 2008-07-28 17:37:09.000000000 +0400 @@ -34,6 +34,7 @@ #include "CmdIDList.h" #include "awt_new.h" #include "awt_Unicode.h" +#include "awt_dlls.h" #include "debug_trace.h" #include "debug_mem.h" @@ -1584,6 +1585,22 @@ return FALSE; } + +void AwtToolkit::GetWindowRect(HWND hWnd, LPRECT lpRect) +{ + // See DWMWINDOWATTRIBUTE enum in dwmapi.h + const DWORD AWT_DWMWA_EXTENDED_FRAME_BOUNDS = 9; + + load_dwmapi_procs(); + + if (fn_dwm_get_window_attribute != NULL && + S_OK != fn_dwm_get_window_attribute(hWnd, + AWT_DWMWA_EXTENDED_FRAME_BOUNDS, lpRect, sizeof(*lpRect))) + { + ::GetWindowRect(hWnd, lpRect); + } +} + /************************************************************************ * Toolkit native methods */ --- old/src/windows/native/sun/windows/awt_Toolkit.h 2008-07-28 17:37:10.000000000 +0400 +++ new/src/windows/native/sun/windows/awt_Toolkit.h 2008-07-28 17:37:09.000000000 +0400 @@ -466,6 +466,12 @@ static JNIEnv* GetEnv(); static BOOL GetScreenInsets(int screenNum, RECT * rect); + + // If the DWM is active, this function uses + // DwmGetWindowAttribute()/DWMWA_EXTENDED_FRAME_BOUNDS. + // Otherwise, fall back to regular ::GetWindowRect(). + // See 6711576 for more details. + static void GetWindowRect(HWND hWnd, LPRECT lpRect); }; /* --- old/src/windows/native/sun/windows/awt_Win32GraphicsEnv.cpp 2008-07-28 17:37:10.000000000 +0400 +++ new/src/windows/native/sun/windows/awt_Win32GraphicsEnv.cpp 2008-07-28 17:37:10.000000000 +0400 @@ -13,6 +13,7 @@ #include "awt_Win32GraphicsDevice.h" #include "Devices.h" #include "WindowsFlags.h" +#include "awt_dlls.h" BOOL DWMIsCompositionEnabled(); @@ -73,9 +74,6 @@ /** * Returns true if dwm composition is enabled, false if it is not applicable * (if the OS is not Vista) or dwm composition is disabled. - * - * Note: since DWM composition state changes are very rare we load/unload the - * dll on every change. */ BOOL DWMIsCompositionEnabled() { typedef HRESULT (WINAPI DwmIsCompositionEnabledFunc)(BOOL*); @@ -91,32 +89,23 @@ } BOOL bRes = FALSE; - HMODULE hDwmApiDll = ::LoadLibrary(TEXT("dwmapi.dll")); + load_dwmapi_procs(); - if (hDwmApiDll != NULL) { - DwmIsCompositionEnabledFunc *lpDwmIsCompEnabled = - (DwmIsCompositionEnabledFunc*) - GetProcAddress(hDwmApiDll, "DwmIsCompositionEnabled"); - if (lpDwmIsCompEnabled != NULL) { - BOOL bEnabled; - HRESULT res = lpDwmIsCompEnabled(&bEnabled); - if (SUCCEEDED(res)) { - bRes = bEnabled; - J2dTraceLn1(J2D_TRACE_VERBOSE, " composition enabled: %d",bRes); - } else { - J2dTraceLn1(J2D_TRACE_ERROR, - "IsDWMCompositionEnabled: error %x when detecting"\ - "if composition is enabled", res); - } + if (fn_dwm_is_composition_enabled != NULL) { + BOOL bEnabled; + HRESULT res = fn_dwm_is_composition_enabled(&bEnabled); + if (SUCCEEDED(res)) { + bRes = bEnabled; + J2dTraceLn1(J2D_TRACE_VERBOSE, " composition enabled: %d",bRes); } else { - J2dTraceLn(J2D_TRACE_ERROR, - "IsDWMCompositionEnabled: no DwmIsCompositionEnabled() "\ - "in dwmapi.dll"); + J2dTraceLn1(J2D_TRACE_ERROR, + "IsDWMCompositionEnabled: error %x when detecting"\ + "if composition is enabled", res); } - ::FreeLibrary(hDwmApiDll); } else { J2dTraceLn(J2D_TRACE_ERROR, - "IsDWMCompositionEnabled: error opening dwmapi.dll"); + "IsDWMCompositionEnabled: no DwmIsCompositionEnabled() "\ + "in dwmapi.dll or dwmapi.dll cannot be loaded"); } dwmIsCompositionEnabled = bRes; --- old/src/windows/native/sun/windows/awt_Window.cpp 2008-07-28 17:37:10.000000000 +0400 +++ new/src/windows/native/sun/windows/awt_Window.cpp 2008-07-28 17:37:10.000000000 +0400 @@ -344,7 +344,7 @@ } RECT rect; - CalculateWarningWindowBounds(wp->x, wp->y, wp->cx, wp->cy, &rect); + CalculateWarningWindowBounds(&rect); ::SetWindowPos(warningWindow, NULL, rect.left, rect.top, @@ -434,10 +434,10 @@ peer); // Now we need to create the warning window. - InitWarningWindow(x, y, w, h); + InitWarningWindow(); } -void AwtWindow::InitWarningWindow(int x, int y, int w, int h) +void AwtWindow::InitWarningWindow() { if (!IsUntrusted()) { return; @@ -446,7 +446,7 @@ InitSecurityWarningSize(); RECT rect; - CalculateWarningWindowBounds(x, y, w, h, &rect); + CalculateWarningWindowBounds(&rect); RegisterWarningWindowClass(); warningWindow = ::CreateWindowEx( @@ -586,14 +586,15 @@ return ico; } -// The rect arguments wx, wy, ww, wh define the bounds -// of the "main" window. This function calculates the bounds of -// the warning window and stores them into the RECT structure -// pointed by the argument rect. -void AwtWindow::CalculateWarningWindowBounds(int wx, int wy, int ww, int wh, LPRECT rect) +// This function calculates the bounds of the warning window and stores them +// into the RECT structure pointed by the argument rect. +void AwtWindow::CalculateWarningWindowBounds(LPRECT rect) { - int x = wx + ww + 2; - int y = wy; + RECT windowBounds; + AwtToolkit::GetWindowRect(GetHWnd(), &windowBounds); + + int x = windowBounds.right + 2; + int y = windowBounds.top; // Now make sure the warning window is visible on the screen MHND hmon = MonitorFromWindow(GetHWnd(), MONITOR_DEFAULT_TO_PRIMARY); --- old/src/windows/native/sun/windows/awt_Window.h 2008-07-28 17:37:10.000000000 +0400 +++ new/src/windows/native/sun/windows/awt_Window.h 2008-07-28 17:37:10.000000000 +0400 @@ -247,7 +247,7 @@ void InitSecurityWarningSize(); HICON GetSecurityWarningIcon(); - void InitWarningWindow(int x, int y, int w, int h); + void InitWarningWindow(); LPCTSTR GetWarningWindowClassName(); void FillWarningWindowClassInfo(WNDCLASS *lpwc); void RegisterWarningWindowClass(); @@ -258,8 +258,7 @@ static void PaintWarningWindow(HWND warningWindow); static void PaintWarningWindow(HWND warningWindow, HDC hdc); void RepaintWarningWindow(); - void CalculateWarningWindowBounds(int wx, int wy, int ww, int wh, - LPRECT rect); + void CalculateWarningWindowBounds(LPRECT rect); void AnimateSecurityWarning(bool enable, bool repaint = false); UINT securityWarningAnimationStage;
21-07-2008

EVALUATION According to Microsoft recommendations: 1. We should always use the screen DC obtained with ::GetDC(NULL) to paint the border. 2. When Aero is active the DWM becomes enabled. In this case we should use the ::DwmGetWindowAttribute() function and request the DWMWA_EXTENDED_FRAME_BOUNDS attribute instead of using the ::GetWindowRect() API.
17-07-2008

EVALUATION The problem is reproduced only if all the following conditions are true: 1. Running on Vista 2. Using Aero Windows Vista desktop theme (with translucent titlebars, etc.) 3. Creating a non-resizable Java window. Non-resizable windows don't have the WS_THICKFRAME window style. Experimets show that such windows experience the following difficulties on Vista with Aero theme: 1. The ::GetWindowRect() WinAPI function returns slightly incorrect results: the returned rect is actually located within the frame of the window. 2. The device context acquired with the ::GetWindowDC() WinAPI function is unable to paint above the window borders and the titlebar. Nothing gets drawn in this case. This is most probably due to the fact Vista Aero theme uses DirectX drawing to paint its fancy translucent borders/titlebars.
16-06-2008