Skip to content
This repository was archived by the owner on Aug 27, 2022. It is now read-only.
/ lanai Public archive

Commit be2a92d

Browse files
author
Pankaj Bansal
committedJul 15, 2020
8249251: [dark_mode ubuntu 20.04] The selected menu is not highlighted in GTKLookAndFeel
Reviewed-by: serb, prr
1 parent 681d06d commit be2a92d

File tree

2 files changed

+228
-78
lines changed

2 files changed

+228
-78
lines changed
 

‎src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java

+22-78
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,21 @@ public void paintRadioButtonBackground(SynthContext context,
185185
}
186186
}
187187

188+
//This is workaround used to draw the highlight
189+
// when the MENU or MenuItem is selected on some platforms
190+
//This should be properly fixed by reading color from css
191+
private void paintComponentBackground(SynthContext context,
192+
Graphics g, int x, int y,
193+
int w, int h) {
194+
GTKStyle style = (GTKStyle) context.getStyle();
195+
Color highlightColor =
196+
style.getGTKColor(GTKEngine.WidgetType.TEXT_AREA.ordinal(),
197+
GTKLookAndFeel.synthStateToGTKStateType(SynthConstants.SELECTED).ordinal(),
198+
ColorType.BACKGROUND.getID());
199+
g.setColor(highlightColor);
200+
g.fillRect(x, y, w, h);
201+
}
202+
188203
//
189204
// RADIO_BUTTON_MENU_ITEM
190205
//
@@ -196,6 +211,10 @@ public void paintRadioButtonMenuItemBackground(SynthContext context,
196211
int gtkState = GTKLookAndFeel.synthStateToGTKState(
197212
id, context.getComponentState());
198213
if (gtkState == SynthConstants.MOUSE_OVER) {
214+
if (GTKLookAndFeel.is3()) {
215+
paintComponentBackground(context, g, x, y, w, h);
216+
return;
217+
}
199218
synchronized (UNIXToolkit.GTK_LOCK) {
200219
if (! ENGINE.paintCachedImage(g, x, y, w, h, id)) {
201220
ShadowType shadow = (GTKLookAndFeel.is2_2() ?
@@ -535,34 +554,6 @@ public void paintMenuBarBackground(SynthContext context, Graphics g,
535554
}
536555
}
537556

538-
private int getBrightness(Color c) {
539-
return Math.max(c.getRed(), Math.max(c.getGreen(), c.getBlue()));
540-
}
541-
542-
private int getMaxColorDiff(Color c1, Color c2) {
543-
return Math.max(Math.abs(c1.getRed() - c2.getRed()),
544-
Math.max(Math.abs(c1.getGreen() - c2.getGreen()),
545-
Math.abs(c1.getBlue() - c2.getBlue())));
546-
}
547-
548-
private int scaleColorComponent(int color, double scaleFactor) {
549-
return (int)(color + color * scaleFactor);
550-
}
551-
private Color deriveColor(Color originalColor, int originalBrightness,
552-
int targetBrightness) {
553-
int r, g, b;
554-
if (originalBrightness == 0) {
555-
r = g = b = targetBrightness;
556-
} else {
557-
double scaleFactor = (targetBrightness - originalBrightness)
558-
/ originalBrightness ;
559-
r = scaleColorComponent(originalColor.getRed(), scaleFactor);
560-
g = scaleColorComponent(originalColor.getGreen(), scaleFactor);
561-
b = scaleColorComponent(originalColor.getBlue(), scaleFactor);
562-
}
563-
return new Color(r, g, b);
564-
}
565-
566557
//
567558
// MENU
568559
//
@@ -579,56 +570,9 @@ public void paintMenuItemBackground(SynthContext context,
579570
int gtkState = GTKLookAndFeel.synthStateToGTKState(
580571
context.getRegion(), context.getComponentState());
581572
if (gtkState == SynthConstants.MOUSE_OVER) {
582-
if (GTKLookAndFeel.is3() && context.getRegion() == Region.MENU) {
583-
GTKStyle style = (GTKStyle)context.getStyle();
584-
Color highlightColor = style.getGTKColor(
585-
GTKEngine.WidgetType.MENU_ITEM.ordinal(),
586-
gtkState, ColorType.BACKGROUND.getID());
587-
Color backgroundColor = style.getGTKColor(
588-
GTKEngine.WidgetType.MENU_BAR.ordinal(),
589-
SynthConstants.ENABLED, ColorType.BACKGROUND.getID());
590-
591-
int minBrightness = 0, maxBrightness = 255;
592-
int minBrightnessDifference = 100;
593-
int actualBrightnessDifference =
594-
getMaxColorDiff(highlightColor, backgroundColor);
595-
if (actualBrightnessDifference < minBrightnessDifference) {
596-
int highlightBrightness =
597-
getBrightness(highlightColor);
598-
int backgroundBrightness =
599-
getBrightness(backgroundColor);
600-
int originalHighlightBrightness =
601-
highlightBrightness;
602-
if (highlightBrightness >= backgroundBrightness) {
603-
if (backgroundBrightness + minBrightnessDifference <=
604-
maxBrightness) {
605-
highlightBrightness =
606-
backgroundBrightness +
607-
minBrightnessDifference;
608-
} else {
609-
highlightBrightness =
610-
backgroundBrightness -
611-
minBrightnessDifference;
612-
}
613-
} else {
614-
if (backgroundBrightness - minBrightnessDifference >=
615-
minBrightness) {
616-
highlightBrightness =
617-
backgroundBrightness -
618-
minBrightnessDifference;
619-
} else {
620-
highlightBrightness =
621-
backgroundBrightness +
622-
minBrightnessDifference;
623-
}
624-
}
625-
626-
g.setColor(deriveColor(highlightColor,
627-
originalHighlightBrightness,
628-
highlightBrightness));
629-
g.fillRect(x, y, w, h);
630-
return;
631-
}
573+
if (GTKLookAndFeel.is3()) {
574+
paintComponentBackground(context, g, x, y, w, h);
575+
return;
632576
}
633577
Region id = Region.MENU_ITEM;
634578
synchronized (UNIXToolkit.GTK_LOCK) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
/*
2+
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/*
25+
* @test
26+
* @requires (os.family == "linux")
27+
* @key headful
28+
* @bug 8248637
29+
* @summary Tests selected JMenu and JMenuitem is properly highlighted in GTKL&F
30+
* with gtk3 version
31+
* @run main/othervm -Djdk.gtk.version=3 JMenuSelectedColorTest
32+
*/
33+
34+
import javax.swing.JFrame;
35+
import javax.swing.JMenu;
36+
import javax.swing.JMenuBar;
37+
import javax.swing.JMenuItem;
38+
import javax.swing.JPanel;
39+
import javax.swing.SwingUtilities;
40+
import javax.swing.UIManager;
41+
import javax.swing.UnsupportedLookAndFeelException;
42+
import java.awt.BorderLayout;
43+
import java.awt.Color;
44+
import java.awt.Component;
45+
import java.awt.FlowLayout;
46+
import java.awt.Point;
47+
import java.awt.Rectangle;
48+
import java.awt.Robot;
49+
import java.awt.event.InputEvent;
50+
51+
public class JMenuSelectedColorTest {
52+
private static JFrame frame;
53+
private static JMenu menu;
54+
private static JMenuItem menuitem;
55+
private static Point point;
56+
private static Rectangle rect;
57+
private static Robot robot;
58+
private static final String GTK_LAF_CLASS = "GTKLookAndFeel";
59+
private static int minColorDifference = 100;
60+
61+
private static void blockTillDisplayed(Component comp) {
62+
Point p = null;
63+
while (p == null) {
64+
try {
65+
p = comp.getLocationOnScreen();
66+
} catch (IllegalStateException e) {
67+
try {
68+
Thread.sleep(500);
69+
} catch (InterruptedException ie) {
70+
}
71+
}
72+
}
73+
}
74+
75+
private static int getMaxColorDiff(Color c1, Color c2) {
76+
return Math.max(Math.abs(c1.getRed() - c2.getRed()),
77+
Math.max(Math.abs(c1.getGreen() - c2.getGreen()),
78+
Math.abs(c1.getBlue() - c2.getBlue())));
79+
}
80+
81+
public static void main(String[] args) throws Exception {
82+
if (!System.getProperty("os.name").startsWith("Linux")) {
83+
System.out.println("This test is meant for Linux platform only");
84+
return;
85+
}
86+
87+
for (UIManager.LookAndFeelInfo lookAndFeelInfo :
88+
UIManager.getInstalledLookAndFeels()) {
89+
if (lookAndFeelInfo.getClassName().contains(GTK_LAF_CLASS)) {
90+
try {
91+
UIManager.setLookAndFeel(lookAndFeelInfo.getClassName());
92+
} catch (final UnsupportedLookAndFeelException ignored) {
93+
System.out.println("GTK L&F could not be set, so this " +
94+
"test can not be run in this scenario ");
95+
return;
96+
}
97+
}
98+
}
99+
100+
robot = new Robot();
101+
robot.setAutoDelay(100);
102+
103+
try {
104+
SwingUtilities.invokeAndWait(new Runnable() {
105+
public void run() {
106+
menu = new JMenu(" ") ;
107+
menuitem = new JMenuItem(" ");
108+
menu.add(menuitem);
109+
110+
JPanel panel = new JPanel();
111+
panel.setLayout(new BorderLayout());
112+
113+
JMenuBar menuBar = new JMenuBar();
114+
JPanel menuPanel = new JPanel();
115+
116+
menuPanel.setLayout(new FlowLayout());
117+
118+
menuBar.add(menu);
119+
menuPanel.add(menuBar);
120+
panel.add(menuPanel, BorderLayout.CENTER);
121+
frame = new JFrame("JMenuSelectedColor");
122+
frame.add(panel);
123+
frame.setSize(200, 200);
124+
frame.setAlwaysOnTop(true);
125+
frame.setLocationRelativeTo(null);
126+
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
127+
frame.setVisible(true);
128+
}
129+
});
130+
131+
robot.waitForIdle();
132+
robot.delay(500);
133+
134+
blockTillDisplayed(menu);
135+
SwingUtilities.invokeAndWait(() -> {
136+
point = menu.getLocationOnScreen();
137+
rect = menu.getBounds();
138+
});
139+
robot.waitForIdle();
140+
robot.delay(500);
141+
142+
Color backgroundColor = robot
143+
.getPixelColor(point.x+rect.width/2, point.y+rect.height/2);
144+
robot.waitForIdle();
145+
robot.delay(500);
146+
147+
menu.setSelected(true);
148+
robot.waitForIdle();
149+
robot.delay(500);
150+
151+
Color highlightColor = robot
152+
.getPixelColor(point.x+rect.width/2, point.y+rect.height/2);
153+
robot.waitForIdle();
154+
robot.delay(500);
155+
156+
int actualColorDifference = getMaxColorDiff(backgroundColor, highlightColor);
157+
if (actualColorDifference < minColorDifference) {
158+
throw new RuntimeException("The expected highlight color for " +
159+
"Menu was not found");
160+
}
161+
162+
robot.mouseMove(point.x + rect.width / 2,
163+
point.y + rect.height / 2);
164+
robot.waitForIdle();
165+
robot.delay(500);
166+
167+
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
168+
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
169+
robot.waitForIdle();
170+
robot.delay(500);
171+
172+
blockTillDisplayed(menuitem);
173+
SwingUtilities.invokeAndWait(() -> {
174+
point = menuitem.getLocationOnScreen();
175+
rect = menuitem.getBounds();
176+
});
177+
robot.waitForIdle();
178+
robot.delay(500);
179+
180+
backgroundColor = robot
181+
.getPixelColor(point.x+rect.width/2, point.y+rect.height/2);
182+
robot.waitForIdle();
183+
robot.delay(500);
184+
185+
robot.mouseMove(point.x + rect.width / 2,
186+
point.y + rect.height / 2);
187+
robot.waitForIdle();
188+
robot.delay(500);
189+
190+
highlightColor = robot
191+
.getPixelColor(point.x+rect.width/2, point.y+rect.height/2);
192+
robot.waitForIdle();
193+
robot.delay(500);
194+
195+
actualColorDifference = getMaxColorDiff(backgroundColor, highlightColor);
196+
if (actualColorDifference < minColorDifference) {
197+
throw new RuntimeException("The expected highlight color for " +
198+
"Menuitem was not found");
199+
}
200+
} finally {
201+
if (frame != null) {
202+
SwingUtilities.invokeAndWait(frame::dispose);
203+
}
204+
}
205+
}
206+
}

0 commit comments

Comments
 (0)
This repository has been archived.