Community
Participate
Working Groups
If a composite is inside a TabFolder with INHERIT_FORCE set, the native gradient from winXP will not be drawn in the child if V_SCROLL or H_SCROLL styles are used. Yet, a grandchild Canvas (without scrollbars) *will* inherit the gradient. The hack-around is to nest two composites inside each other using a ScrolledComposite approach, but this is cumbersome and may have other side effects. public static void main(String[] args) { Display d = Display.getDefault(); shell = new Shell(d, SWT.SHELL_TRIM); shell.setText("Inheriting background"); shell.setLayout(new GridLayout(2, false)); TabFolder folder = new TabFolder(shell, 0); folder.setBackgroundMode(SWT.INHERIT_FORCE); TabItem item = new TabItem(folder, 0); Composite c1 = new Composite(folder, SWT.BORDER | SWT.V_SCROLL); item.setControl(c1); FillLayout fill = new FillLayout(); fill.marginHeight = fill.marginWidth = 15; c1.setLayout(fill); new Composite(c1, SWT.BORDER); shell.pack(); shell.open(); while (!shell.isDisposed()) while (!d.readAndDispatch()) d.sleep(); }
It does seem like this should work however, you are making use of the fact that you know that the current themes on XP and Vista have a gradient tab folder background. Custom themese and future themes from Microsoft may not.
*** Bug 215402 has been marked as a duplicate of this bug. ***
I don't think the SWT.INHERIT_FORCE really matters here. The bug is this code in Composite: void createHandle () { super.createHandle (); state |= CANVAS; if ((style & (SWT.H_SCROLL | SWT.V_SCROLL)) == 0) { state |= THEME_BACKGROUND; } ... The "if" block should be removed and the state should be set like this: state |= CANVAS | THEME_BACKGROUND; There's no reason why a Composite/Canvas with scrollbars should be rendered different than a Composite without scrollbars. If you want to dig in history: The THEME_BACKGROUND was added in http://git.eclipse.org/c/platform/eclipse.platform.swt.git/commit/?id=bc4d3581c33a4dad038becb29f77136e2bbc5f2e
Created attachment 223449 [details] Testbed Here's a testbed that shows Composites without scrollbars (on top) and with scrollbars (bottom). The "ScrolledComposite 1" tab on the bottom is what makes the fix for bug 68062 look awful.
Back when theme was added, we decided that a Composite with scrollbars would not inherit the theme because it was probably being used to implement a control similar to a Text, List, Table, or Tree, and those controls do not inherit the background theme. We figured that a Composite that did not have scrollbars was probably just being used to group some other controls, therefore it should inherit. ScrolledComposite is the proof that this was not an accurate decision... however it is too late to change it now because it would break too many custom controls, for example, StyledText. TabFolder is "special" in that it declares itself to be a theme control (see findThemeControl() implementors), and so it specifies the background of its children, which is why Composites with scrollbars look funny when they are children of a TabFolder - they are not inheriting the TabFolder theme. The following horrible hack fixes the immediate problem, but it is not a real fix because there are other controls that can be theme controls (for example, CoolBar and ExpandBar), and because backgrounds can be changed dynamically. void createHandle () { super.createHandle (); state |= CANVAS; if ((style & (SWT.H_SCROLL | SWT.V_SCROLL)) == 0 || getParent() instanceof TabFolder) { state |= THEME_BACKGROUND; } We will think about this further, and decide what we want to do here. (Note that INHERIT_FORCE and INHERIT_DEFAULT do nothing unless a background color or a background image have been set).
Taking ownership and setting milestone to M4, so that this bug is not lost. SSQ, bug 68062 is waiting on this bug.
(In reply to comment #5) Instead of hardcoding TabFolder, can't we just use "parent.findThemeControl ()" in Composite#createHandle()? void createHandle () { super.createHandle (); state |= CANVAS; if ((style & (SWT.H_SCROLL | SWT.V_SCROLL)) == 0 || (parent != null && parent.findThemeControl () == parent)) { state |= THEME_BACKGROUND; }
Actually, I agree with comment 7: "If my parent declares itself to be a theme control, then I inherit the theme background." I think (?) that this is also correct: "If my parent is my theme control, then I inherit the theme background." Which looks like this in Composite#createHandle() code: void createHandle () { super.createHandle (); state |= CANVAS; if ((style & (SWT.H_SCROLL | SWT.V_SCROLL)) == 0 || findThemeControl () == parent) { state |= THEME_BACKGROUND; } ... If we put one of these fixes in, then we can finally make a fix for very old bug 68062. SSQ?
Fixed in 4.3 master: http://git.eclipse.org/c/platform/eclipse.platform.swt.git/commit/?id=fea0ec7e9dc9652fac38ed37d669dbd30c9ee1df Markus, you can fix bug 68062 now. :)