mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2025-12-06 14:00:55 +03:00
macOS: fixed window "flashing" when switching from a light to a dark theme (or vice versa), especially when using animated theme changer
This commit is contained in:
@@ -9,11 +9,12 @@ FlatLaf Change Log
|
|||||||
named Java modules, it is no longer necessary to add `opens com.myapp.themes;`
|
named Java modules, it is no longer necessary to add `opens com.myapp.themes;`
|
||||||
to `module-info.java`. (issue #1026)
|
to `module-info.java`. (issue #1026)
|
||||||
|
|
||||||
|
|
||||||
#### Fixed bugs
|
#### Fixed bugs
|
||||||
|
|
||||||
- Tree and List: Fixed painting of rounded drop backgrounds. (issue #1023)
|
- Tree and List: Fixed painting of rounded drop backgrounds. (issue #1023)
|
||||||
|
- macOS: Fixed window "flashing" when switching from a light to a dark theme (or
|
||||||
|
vice versa). Especially when using animated theme changer (see
|
||||||
|
[FlatLaf Extras](flatlaf-extras)).
|
||||||
|
|
||||||
#### Incompatibilities
|
#### Incompatibilities
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import java.awt.Color;
|
|||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Container;
|
import java.awt.Container;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
|
import java.awt.EventQueue;
|
||||||
import java.awt.Frame;
|
import java.awt.Frame;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
@@ -153,8 +154,28 @@ public class FlatRootPaneUI
|
|||||||
Container parent = c.getParent();
|
Container parent = c.getParent();
|
||||||
if( parent instanceof JFrame || parent instanceof JDialog ) {
|
if( parent instanceof JFrame || parent instanceof JDialog ) {
|
||||||
Color background = parent.getBackground();
|
Color background = parent.getBackground();
|
||||||
if( background == null || background instanceof UIResource )
|
if( background == null || background instanceof UIResource ) {
|
||||||
parent.setBackground( UIManager.getColor( "control" ) );
|
if( SystemInfo.isMacOS ) {
|
||||||
|
// Setting window background on macOS immediately fills the whole window
|
||||||
|
// with that color, and slightly delayed, the Swing repaint manager
|
||||||
|
// repaints the actual window content. This results in some flashing
|
||||||
|
// when switching from a light to a dark theme (or vice versa).
|
||||||
|
// --> delay setting window background and immediately repaint window content
|
||||||
|
Runnable r = () -> {
|
||||||
|
parent.setBackground( UIManager.getColor( "control" ) );
|
||||||
|
c.paintImmediately( 0, 0, c.getWidth(), c.getHeight() );
|
||||||
|
};
|
||||||
|
|
||||||
|
// for class FlatAnimatedLafChange:
|
||||||
|
// if animated Laf change is in progress, set background color when
|
||||||
|
// animation has finished to avoid/reduce flashing
|
||||||
|
if( c.getClientProperty( "FlatLaf.internal.animatedLafChange" ) != null )
|
||||||
|
c.putClientProperty( "FlatLaf.internal.animatedLafChange.runWhenFinished", r );
|
||||||
|
else
|
||||||
|
EventQueue.invokeLater( r );
|
||||||
|
} else
|
||||||
|
parent.setBackground( UIManager.getColor( "control" ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macClearBackgroundForTranslucentWindow( c );
|
macClearBackgroundForTranslucentWindow( c );
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import java.util.Map;
|
|||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JLayeredPane;
|
import javax.swing.JLayeredPane;
|
||||||
|
import javax.swing.JRootPane;
|
||||||
import javax.swing.RootPaneContainer;
|
import javax.swing.RootPaneContainer;
|
||||||
import com.formdev.flatlaf.FlatSystemProperties;
|
import com.formdev.flatlaf.FlatSystemProperties;
|
||||||
import com.formdev.flatlaf.util.Animator;
|
import com.formdev.flatlaf.util.Animator;
|
||||||
@@ -80,7 +81,7 @@ public class FlatAnimatedLafChange
|
|||||||
showSnapshot( true, oldUIsnapshots );
|
showSnapshot( true, oldUIsnapshots );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void showSnapshot( boolean useAlpha, Map<JLayeredPane, JComponent> map ) {
|
private static void showSnapshot( boolean old, Map<JLayeredPane, JComponent> map ) {
|
||||||
inShowSnapshot = true;
|
inShowSnapshot = true;
|
||||||
|
|
||||||
// create snapshots for all shown windows
|
// create snapshots for all shown windows
|
||||||
@@ -107,7 +108,7 @@ public class FlatAnimatedLafChange
|
|||||||
if( inShowSnapshot || snapshot.contentsLost() )
|
if( inShowSnapshot || snapshot.contentsLost() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( useAlpha )
|
if( old )
|
||||||
((Graphics2D)g).setComposite( AlphaComposite.getInstance( AlphaComposite.SRC_OVER, alpha ) );
|
((Graphics2D)g).setComposite( AlphaComposite.getInstance( AlphaComposite.SRC_OVER, alpha ) );
|
||||||
g.drawImage( snapshot, 0, 0, null );
|
g.drawImage( snapshot, 0, 0, null );
|
||||||
}
|
}
|
||||||
@@ -120,13 +121,17 @@ public class FlatAnimatedLafChange
|
|||||||
snapshot.flush();
|
snapshot.flush();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if( !useAlpha )
|
if( !old )
|
||||||
snapshotLayer.setOpaque( true );
|
snapshotLayer.setOpaque( true );
|
||||||
snapshotLayer.setSize( layeredPane.getSize() );
|
snapshotLayer.setSize( layeredPane.getSize() );
|
||||||
|
|
||||||
// add image layer to layered pane
|
// add image layer to layered pane
|
||||||
layeredPane.add( snapshotLayer, Integer.valueOf( JLayeredPane.DRAG_LAYER + (useAlpha ? 2 : 1) ) );
|
layeredPane.add( snapshotLayer, Integer.valueOf( JLayeredPane.DRAG_LAYER + (old ? 2 : 1) ) );
|
||||||
map.put( layeredPane, snapshotLayer );
|
map.put( layeredPane, snapshotLayer );
|
||||||
|
|
||||||
|
// let FlatRootPaneUI know that animated Laf change is in progress
|
||||||
|
if( old )
|
||||||
|
layeredPane.getRootPane().putClientProperty( "FlatLaf.internal.animatedLafChange", true );
|
||||||
}
|
}
|
||||||
|
|
||||||
inShowSnapshot = false;
|
inShowSnapshot = false;
|
||||||
@@ -180,6 +185,15 @@ public class FlatAnimatedLafChange
|
|||||||
for( Map.Entry<JLayeredPane, JComponent> e : map.entrySet() ) {
|
for( Map.Entry<JLayeredPane, JComponent> e : map.entrySet() ) {
|
||||||
e.getKey().remove( e.getValue() );
|
e.getKey().remove( e.getValue() );
|
||||||
e.getKey().repaint();
|
e.getKey().repaint();
|
||||||
|
|
||||||
|
// run Runnable that FlatRootPaneUI put into client properties
|
||||||
|
JRootPane rootPane = e.getKey().getRootPane();
|
||||||
|
rootPane.putClientProperty( "FlatLaf.internal.animatedLafChange", null );
|
||||||
|
Runnable r = (Runnable) rootPane.getClientProperty( "FlatLaf.internal.animatedLafChange.runWhenFinished" );
|
||||||
|
if( r != null ) {
|
||||||
|
rootPane.putClientProperty( "FlatLaf.internal.animatedLafChange.runWhenFinished", null );
|
||||||
|
r.run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
map.clear();
|
map.clear();
|
||||||
|
|||||||
Reference in New Issue
Block a user