mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-06 09:29:38 +01:00
JBR-4618 Force window size update after display reconfiguration
- Re-create all GraphicsDevices on displayChanged()
This commit is contained in:
@@ -218,11 +218,9 @@ public class Win32GraphicsConfig extends GraphicsConfiguration
|
||||
return (super.toString()+"[dev="+device+",pixfmt="+visual+"]");
|
||||
}
|
||||
|
||||
private native Rectangle getBounds(int screen);
|
||||
|
||||
@Override
|
||||
public Rectangle getBounds() {
|
||||
return getBounds(device.getScreen());
|
||||
return device.getBounds();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -106,11 +106,12 @@ public class Win32GraphicsDevice extends GraphicsDevice implements
|
||||
|
||||
private static native void initIDs();
|
||||
|
||||
native void initDevice(int screen);
|
||||
native void initNativeScale(int screen);
|
||||
native void setNativeScale(int screen, float scaleX, float scaleY);
|
||||
native float getNativeScaleX(int screen);
|
||||
native float getNativeScaleY(int screen);
|
||||
private native void initDevice(int screen);
|
||||
private static native void initNativeScale(int screen);
|
||||
private static native void setNativeScale(int screen, float scaleX, float scaleY);
|
||||
private static native float getNativeScaleX(int screen);
|
||||
private static native float getNativeScaleY(int screen);
|
||||
private static native Rectangle getBounds(int screen);
|
||||
|
||||
public Win32GraphicsDevice(int screennum) {
|
||||
this.screen = screennum;
|
||||
@@ -169,6 +170,10 @@ public class Win32GraphicsDevice extends GraphicsDevice implements
|
||||
}
|
||||
}
|
||||
|
||||
public Rectangle getBounds() {
|
||||
return getBounds(getScreen());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this is a valid device. Device can become
|
||||
* invalid as a result of device removal event.
|
||||
@@ -256,7 +261,7 @@ public class Win32GraphicsDevice extends GraphicsDevice implements
|
||||
}
|
||||
}
|
||||
|
||||
private native int getMaxConfigsImpl(int screen);
|
||||
private static native int getMaxConfigsImpl(int screen);
|
||||
|
||||
/**
|
||||
* Returns whether or not the PixelFormat indicated by index is
|
||||
@@ -268,7 +273,7 @@ public class Win32GraphicsDevice extends GraphicsDevice implements
|
||||
* are disabled. Do not call this function with an index of 0.
|
||||
* @param index a PixelFormat index
|
||||
*/
|
||||
private native boolean isPixFmtSupported(int index, int screen);
|
||||
private static native boolean isPixFmtSupported(int index, int screen);
|
||||
|
||||
/**
|
||||
* Returns the PixelFormatID of the default graphics configuration
|
||||
@@ -287,7 +292,7 @@ public class Win32GraphicsDevice extends GraphicsDevice implements
|
||||
* Returns the default PixelFormat ID from GDI. Do not call if PixelFormats
|
||||
* are disabled.
|
||||
*/
|
||||
private native int getDefaultPixIDImpl(int screen);
|
||||
private static native int getDefaultPixIDImpl(int screen);
|
||||
|
||||
/**
|
||||
* Returns the default graphics configuration
|
||||
@@ -541,9 +546,8 @@ public class Win32GraphicsDevice extends GraphicsDevice implements
|
||||
dynamicColorModel = null;
|
||||
defaultConfig = null;
|
||||
configs = null;
|
||||
initScaleFactors();
|
||||
|
||||
Rectangle screenBounds = getDefaultConfiguration().getBounds();
|
||||
Rectangle screenBounds = getBounds();
|
||||
resizeFSWindow(getFullScreenWindow(), screenBounds);
|
||||
|
||||
// pass on to all top-level windows on this display
|
||||
@@ -577,8 +581,8 @@ public class Win32GraphicsDevice extends GraphicsDevice implements
|
||||
/**
|
||||
* Creates and returns the color model associated with this device
|
||||
*/
|
||||
private native ColorModel makeColorModel (int screen,
|
||||
boolean dynamic);
|
||||
private static native ColorModel makeColorModel(int screen,
|
||||
boolean dynamic);
|
||||
|
||||
/**
|
||||
* Returns a dynamic ColorModel which is updated when there
|
||||
|
||||
@@ -31,6 +31,7 @@ import java.awt.GraphicsDevice;
|
||||
import java.awt.peer.ComponentPeer;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.ListIterator;
|
||||
|
||||
import sun.awt.windows.WToolkit;
|
||||
@@ -147,41 +148,23 @@ public final class Win32GraphicsEnvironment extends SunGraphicsEnvironment {
|
||||
*/
|
||||
@Override
|
||||
public void displayChanged() {
|
||||
if (screens != null) {
|
||||
if (oldDevices == null) {
|
||||
oldDevices = new ArrayList<>();
|
||||
}
|
||||
for (int i = 0; i < screens.length; i++) {
|
||||
if (screens[i] instanceof Win32GraphicsDevice gd) {
|
||||
oldDevices.add(new WeakReference<>(gd));
|
||||
} else {
|
||||
// REMIND: can we ever have anything other than Win32GD?
|
||||
assert (false) : screens[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
// create the new devices
|
||||
// getNumScreens() will return the correct current number of screens
|
||||
GraphicsDevice[] newDevices = new GraphicsDevice[getNumScreens()];
|
||||
GraphicsDevice[] oldScreens = screens;
|
||||
// go through the list of current devices and determine if they
|
||||
// could be reused, or will have to be replaced
|
||||
if (oldScreens != null) {
|
||||
for (int i = 0; i < oldScreens.length; i++) {
|
||||
if (!(screens[i] instanceof Win32GraphicsDevice)) {
|
||||
// REMIND: can we ever have anything other than Win32GD?
|
||||
assert (false) : oldScreens[i];
|
||||
continue;
|
||||
}
|
||||
Win32GraphicsDevice gd = (Win32GraphicsDevice)oldScreens[i];
|
||||
// devices may be invalidated from the native code when the
|
||||
// display change happens (device add/removal also causes a
|
||||
// display change)
|
||||
if (!gd.isValid()) {
|
||||
if (oldDevices == null) {
|
||||
oldDevices =
|
||||
new ArrayList<WeakReference<Win32GraphicsDevice>>();
|
||||
}
|
||||
oldDevices.add(new WeakReference<Win32GraphicsDevice>(gd));
|
||||
} else if (i < newDevices.length) {
|
||||
// reuse the device
|
||||
newDevices[i] = gd;
|
||||
}
|
||||
}
|
||||
oldScreens = null;
|
||||
}
|
||||
// create the new devices (those that weren't reused)
|
||||
for (int i = 0; i < newDevices.length; i++) {
|
||||
if (newDevices[i] == null) {
|
||||
newDevices[i] = makeScreenDevice(i);
|
||||
}
|
||||
}
|
||||
Arrays.setAll(newDevices, this::makeScreenDevice);
|
||||
// install the new array of devices
|
||||
// Note: no synchronization here, it doesn't matter if a thread gets
|
||||
// a new or an old array this time around
|
||||
|
||||
@@ -631,6 +631,14 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
|
||||
|
||||
AWTAccessor.getComponentAccessor().
|
||||
setGraphicsConfiguration((Component)target, winGraphicsConfig);
|
||||
|
||||
// Windows may have already sent us WM_PAINT,
|
||||
// which we have processed before updating the GC,
|
||||
// so force full repaint just to be sure we don't leave damaged content.
|
||||
if (oldDev != newDev) {
|
||||
Rectangle b = getBounds();
|
||||
handlePaint(0, 0, b.width, b.height);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -214,6 +214,7 @@ BOOL Devices::UpdateInstance(JNIEnv *env)
|
||||
}
|
||||
for (i = 0; i < numScreens; ++i) {
|
||||
rawDevices[i]->Initialize();
|
||||
rawDevices[i]->InitDesktopScales();
|
||||
}
|
||||
{
|
||||
CriticalSection::Lock l(arrayLock);
|
||||
|
||||
@@ -912,6 +912,20 @@ void AwtToolkit::DestroyComponentHWND(HWND hwnd)
|
||||
void SpyWinMessage(HWND hwnd, UINT message, LPCTSTR szComment);
|
||||
#endif
|
||||
|
||||
static BOOL CALLBACK UpdateAllThreadWindowSizes(HWND hWnd, LPARAM)
|
||||
{
|
||||
TRY;
|
||||
AwtComponent *c = AwtComponent::GetComponent(hWnd);
|
||||
if (c) {
|
||||
RECT r;
|
||||
GetWindowRect(hWnd, &r);
|
||||
c->WmSize(SIZENORMAL, r.right-r.left, r.bottom-r.top);
|
||||
c->Invalidate(NULL);
|
||||
}
|
||||
return TRUE;
|
||||
CATCH_BAD_ALLOC_RET(FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* An AwtToolkit window is just a means of routing toolkit messages to here.
|
||||
*/
|
||||
@@ -1302,6 +1316,7 @@ LRESULT CALLBACK AwtToolkit::WndProc(HWND hWnd, UINT message,
|
||||
case WM_DISPLAYCHANGE: {
|
||||
// Reinitialize screens
|
||||
initScreens(env);
|
||||
::EnumThreadWindows(MainThread(), (WNDENUMPROC)UpdateAllThreadWindowSizes, 0);
|
||||
|
||||
// Notify Java side - call WToolkit.displayChanged()
|
||||
jclass clazz = env->FindClass("sun/awt/windows/WToolkit");
|
||||
|
||||
@@ -76,50 +76,3 @@ inline int shiftToMask(int numBits, int shift) {
|
||||
mask = mask << shift;
|
||||
return mask;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_awt_Win32GraphicsConfig
|
||||
* Method: getBounds
|
||||
* Signature: ()Ljava/awt/Rectangle
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_sun_awt_Win32GraphicsConfig_getBounds(JNIEnv *env, jobject thisobj,
|
||||
jint screen)
|
||||
{
|
||||
jclass clazz;
|
||||
jmethodID mid;
|
||||
jobject bounds = NULL;
|
||||
|
||||
clazz = env->FindClass("java/awt/Rectangle");
|
||||
CHECK_NULL_RETURN(clazz, NULL);
|
||||
mid = env->GetMethodID(clazz, "<init>", "(IIII)V");
|
||||
if (mid != 0) {
|
||||
RECT rRW = {0, 0, 0, 0};
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice *device = devices->GetDevice(screen);
|
||||
|
||||
if (TRUE == MonitorBounds(AwtWin32GraphicsDevice::GetMonitor(screen), &rRW)) {
|
||||
int w = (device == NULL) ? rRW.right - rRW.left
|
||||
: device->ScaleDownX(rRW.right - rRW.left);
|
||||
int h = (device == NULL) ? rRW.bottom - rRW.top
|
||||
: device->ScaleDownY(rRW.bottom - rRW.top);
|
||||
|
||||
bounds = env->NewObject(clazz, mid, rRW.left, rRW.top, w, h);
|
||||
}
|
||||
else {
|
||||
// 4910760 - don't return a null bounds, return the bounds of the
|
||||
// primary screen
|
||||
int w = ::GetSystemMetrics(SM_CXSCREEN);
|
||||
int h = ::GetSystemMetrics(SM_CYSCREEN);
|
||||
|
||||
bounds = env->NewObject(clazz, mid,
|
||||
0, 0,
|
||||
device == NULL ? w : device->ScaleDownX(w),
|
||||
device == NULL ? h : device->ScaleDownY(h));
|
||||
}
|
||||
if (safe_ExceptionOccurred(env)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return bounds;
|
||||
}
|
||||
|
||||
@@ -1017,7 +1017,7 @@ Java_sun_awt_Win32GraphicsDevice_initIDs(JNIEnv *env, jclass cls)
|
||||
*/
|
||||
|
||||
JNIEXPORT jint JNICALL Java_sun_awt_Win32GraphicsDevice_getMaxConfigsImpl
|
||||
(JNIEnv* jniEnv, jobject theThis, jint screen) {
|
||||
(JNIEnv* jniEnv, jclass clazz, jint screen) {
|
||||
TRY;
|
||||
HDC hDC = AwtWin32GraphicsDevice::GetDCFromScreen(screen);
|
||||
|
||||
@@ -1044,7 +1044,7 @@ JNIEXPORT jint JNICALL Java_sun_awt_Win32GraphicsDevice_getMaxConfigsImpl
|
||||
*/
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_sun_awt_Win32GraphicsDevice_isPixFmtSupported
|
||||
(JNIEnv* env, jobject theThis, jint pixFmtID, jint screen) {
|
||||
(JNIEnv* env, jclass clazz, jint pixFmtID, jint screen) {
|
||||
TRY;
|
||||
jboolean suppColor = JNI_TRUE;
|
||||
HDC hDC = AwtWin32GraphicsDevice::GetDCFromScreen(screen);
|
||||
@@ -1086,7 +1086,7 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_Win32GraphicsDevice_isPixFmtSupported
|
||||
*/
|
||||
|
||||
JNIEXPORT jint JNICALL Java_sun_awt_Win32GraphicsDevice_getDefaultPixIDImpl
|
||||
(JNIEnv* env, jobject theThis, jint screen) {
|
||||
(JNIEnv* env, jclass clazz, jint screen) {
|
||||
TRY;
|
||||
int pixFmtID = 0;
|
||||
HDC hDC = AwtWin32GraphicsDevice::GetDCFromScreen(screen);
|
||||
@@ -1118,7 +1118,7 @@ JNIEXPORT jint JNICALL Java_sun_awt_Win32GraphicsDevice_getDefaultPixIDImpl
|
||||
}
|
||||
|
||||
if (JNI_FALSE == Java_sun_awt_Win32GraphicsDevice_isPixFmtSupported(
|
||||
env, theThis, pixFmtID, screen)) {
|
||||
env, clazz, pixFmtID, screen)) {
|
||||
/* Can't find a suitable pixel format ID. Fall back on 0. */
|
||||
pixFmtID = 0;
|
||||
}
|
||||
@@ -1415,7 +1415,7 @@ JNIEXPORT void JNICALL Java_sun_awt_Win32GraphicsDevice_enumDisplayModes
|
||||
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_sun_awt_Win32GraphicsDevice_makeColorModel
|
||||
(JNIEnv *env, jobject thisPtr, jint screen, jboolean dynamic)
|
||||
(JNIEnv *env, jclass clazz, jint screen, jboolean dynamic)
|
||||
{
|
||||
Devices::InstanceAccess devices;
|
||||
return devices->GetDevice(screen)->GetColorModel(env, dynamic);
|
||||
@@ -1428,10 +1428,10 @@ JNIEXPORT jobject JNICALL
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_awt_Win32GraphicsDevice_initDevice
|
||||
(JNIEnv *env, jobject thisPtr, jint screen)
|
||||
(JNIEnv *env, jobject graphicsDevice, jint screen)
|
||||
{
|
||||
Devices::InstanceAccess devices;
|
||||
devices->GetDevice(screen)->SetJavaDevice(env, thisPtr);
|
||||
devices->GetDevice(screen)->SetJavaDevice(env, graphicsDevice);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1441,7 +1441,7 @@ JNIEXPORT void JNICALL
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_awt_Win32GraphicsDevice_setNativeScale
|
||||
(JNIEnv *env, jobject thisPtr, jint screen, jfloat scaleX, jfloat scaleY)
|
||||
(JNIEnv *env, jclass clazz, jint screen, jfloat scaleX, jfloat scaleY)
|
||||
{
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice *device = devices->GetDevice(screen);
|
||||
@@ -1459,7 +1459,7 @@ JNIEXPORT void JNICALL
|
||||
*/
|
||||
JNIEXPORT jfloat JNICALL
|
||||
Java_sun_awt_Win32GraphicsDevice_getNativeScaleX
|
||||
(JNIEnv *env, jobject thisPtr, jint screen)
|
||||
(JNIEnv *env, jclass clazz, jint screen)
|
||||
{
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice *device = devices->GetDevice(screen);
|
||||
@@ -1473,7 +1473,7 @@ JNIEXPORT jfloat JNICALL
|
||||
*/
|
||||
JNIEXPORT jfloat JNICALL
|
||||
Java_sun_awt_Win32GraphicsDevice_getNativeScaleY
|
||||
(JNIEnv *env, jobject thisPtr, jint screen)
|
||||
(JNIEnv *env, jclass clazz, jint screen)
|
||||
{
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice *device = devices->GetDevice(screen);
|
||||
@@ -1487,7 +1487,7 @@ JNIEXPORT jfloat JNICALL
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_awt_Win32GraphicsDevice_initNativeScale
|
||||
(JNIEnv *env, jobject thisPtr, jint screen)
|
||||
(JNIEnv *env, jclass clazz, jint screen)
|
||||
{
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice *device = devices->GetDevice(screen);
|
||||
@@ -1496,3 +1496,48 @@ Java_sun_awt_Win32GraphicsDevice_initNativeScale
|
||||
device->InitDesktopScales();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_awt_Win32GraphicsDevice
|
||||
* Method: getBounds
|
||||
* Signature: (I)Ljava/awt/Rectangle
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_sun_awt_Win32GraphicsDevice_getBounds(JNIEnv *env, jclass clazz, jint screen)
|
||||
{
|
||||
jmethodID mid;
|
||||
jobject bounds = NULL;
|
||||
|
||||
clazz = env->FindClass("java/awt/Rectangle");
|
||||
CHECK_NULL_RETURN(clazz, NULL);
|
||||
mid = env->GetMethodID(clazz, "<init>", "(IIII)V");
|
||||
if (mid != 0) {
|
||||
RECT rRW = {0, 0, 0, 0};
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice *device = devices->GetDevice(screen);
|
||||
|
||||
if (TRUE == MonitorBounds(AwtWin32GraphicsDevice::GetMonitor(screen), &rRW)) {
|
||||
int w = (device == NULL) ? rRW.right - rRW.left
|
||||
: device->ScaleDownX(rRW.right - rRW.left);
|
||||
int h = (device == NULL) ? rRW.bottom - rRW.top
|
||||
: device->ScaleDownY(rRW.bottom - rRW.top);
|
||||
|
||||
bounds = env->NewObject(clazz, mid, rRW.left, rRW.top, w, h);
|
||||
}
|
||||
else {
|
||||
// 4910760 - don't return a null bounds, return the bounds of the
|
||||
// primary screen
|
||||
int w = ::GetSystemMetrics(SM_CXSCREEN);
|
||||
int h = ::GetSystemMetrics(SM_CYSCREEN);
|
||||
|
||||
bounds = env->NewObject(clazz, mid,
|
||||
0, 0,
|
||||
device == NULL ? w : device->ScaleDownX(w),
|
||||
device == NULL ? h : device->ScaleDownY(h));
|
||||
}
|
||||
if (safe_ExceptionOccurred(env)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return bounds;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user