After syncing up this fix with 6489585, we discovered some interesting issues
with the sizing of JButtons, particularly those that are non-default. We dealt
with this problem partially for JButtons hosted in a JToolBar by treating them
always as non-default-capable, but a more complete solution for standalone
JButtons will be offered under the following bugid (to avoid overloading this
6495117: GTK L&F: non-default JButtons sized differently than native
The fix outlined above for issue (1) will not be needed once we have the fix
for 6489585 in place. There's no need to add special logic for "square"
(icon-only) toolbar buttons because as of the fix for 6489585, all buttons
(including toolbar ones) will be created with the appropriate offsets. This
means that icon-only toolbar buttons will be square by nature, no extra code
required. This greatly simplifies the fix, but of course we still need to
resolve issues (2) through (5).
And for the newly added issue:
5) The problem here is in GTKPainter.paintButtonBackgroundImpl():
if ((paintBackground && !toolButton) ||
(gtkState != SynthConstants.ENABLED))
Due to this logic, if toolButton is true and gtkState is DISABLED, then we
will end up painting the button background. We need to update this logic so
that we do not paint the background in this scenario.
Here's the evaluation for each of the above issues:
1) SynthToolBarUI does not override the create*Border() methods, nor does
GTKLookAndFeel provide UI defaults for rolloverBorder, etc. This is typically
the way that L&Fs provide square toolbar buttons (by specifying a square Border
for each of the three border properties).
2) Two things here... We need to update SynthToolBarLayoutManager to account
for the insets of the toolbar properly. But that change alone is not enough,
since GTK L&F is currently providing zero insets for JToolBars. So we need to
fix GTKStyle.getInsets() to return "thickness insets" for TOOL_BAR and
3) This one's easy. In GTKPainter.paintToggleButtonBackground(), we were
always passing false for the "toolButton" parameter of
paintButtonBackgroundImpl(). Clearly this needs to be updated to check for:
boolean toolButton = (toggleButton.getParent() instanceof JToolBar);
just as we do in paintButtonBackground(). This will cause native GTK engines
to paint the toggle button appropriately when it's in a toolbar context.
4) It seems that two methods in GTKPainter, paintToolBarBackground() and
paintToolBarContentBackground() are making the wrong GTK painting calls,
which causes the extra borders and incorrect rendering. I'm not sure why
these wrong calls are being made; either it was just a simple oversight when
the code was added in Mustang, or perhaps an older version of the GTK libraries
was actually making the calls this way (and the author of these methods
was just following that code), but somehow that seems unlikely. In any case,
I have consulted the GTK+ source code (version 2.8.20) for gtktoolbar.c and
gtkhandlebox.c and have found the proper way to paint these elements.
The paintToolBarBackground() method should be calling paintBox("handlebox_bin"),
while paintToolBarContentBackground() should be calling paintBox("toolbar").
This is because the "toolbar background" corresponds to the whole background
(which surrounds the toolbar and the handle, if present), which in native GTK
terminology is a GtkHandleBox. The "toolbar content background" corresponds
only to the background of the toolbar itself (not including the handle),
which in native GTK terminology is a GtkToolBar.
With these fixes in place, Swing's GTK L&F is now pixel-for-pixel accurate
with native GTK toolbars.