| Summary: | [CSS] Gradient in background-color is not applied to children | ||
|---|---|---|---|
| Product: | [Eclipse Project] Platform | Reporter: | Daniel Rolka <daniel.rolka> |
| Component: | UI | Assignee: | Daniel Rolka <daniel.rolka> |
| Status: | CLOSED WONTFIX | QA Contact: | |
| Severity: | normal | ||
| Priority: | P3 | CC: | bsd, daniel_megert, sudol.wojciech |
| Version: | 4.4 | ||
| Target Milestone: | --- | ||
| Hardware: | PC | ||
| OS: | All | ||
| Whiteboard: | stalebug | ||
| Attachments: | |||
Gerrit review link: https://git.eclipse.org/r/#/c/19513/ Daniel Daniel, unfortunately this fix will do the right thing for more complicated arrangements nor for circular gradients. I think you want to use the "swt-background-mode" property to set to "inherit". (In reply to Brian de Alwis from comment #2) > Daniel, unfortunately this fix will do the right thing for more complicated > arrangements nor for circular gradients. I think you want to use the > "swt-background-mode" property to set to "inherit". Where do we need to set that, on each rule where we want to change the background in CSS? Won't that effect widgets in a view or editor (that we technically don't control)? PW If I recall correctly, the problem in Daniel's specific example is actually caused by the CTabRendering pulling the button background from its parent's background colour. I switched my app to use the CTabFolderRenderer due to this issue (and some others); unfortunately I didn't write up them up at the time. But Daniel's fix will solve the immediate problem, just not handle all of the cases, correct? He's trying to expose some of the CSS to Color/Font bridge work in the classic CSS style sheet we ship in the SDK. Classic is most compatible with the 3.x default theme PW The problem that I see is that the patch causes the gradient to be applied to all children. That may be applicable for the CTabFolder, but is unlikely to work elsewhere. And in the radial case, the slice computed for the parent is almost certainly not right for the children.
The test should be:
{ background-color: gradient radial yellow green 60%; }
I haven't managed to come up with a fragment that accomplishes what Daniel's looking for. I hoped the following might do the trick:
.MPartStack { background-color: gradient radial yellow green 95%; }
.MPartStack, .MPartStack > ToolBar, .MPartStack > Composite > ToolBar { swt-background-mode: force; }
But I suspect I might have some other rules in place at the moment.
A better solution might be to change how the children are exposed from CTabFolder so that it's easier to address the CTabItem's toolbar(s).
Created attachment 238183 [details] Gradient after modifying the background-mode flag (In reply to Brian de Alwis from comment #6) > The problem that I see is that the patch causes the gradient to be applied > to all children. That may be applicable for the CTabFolder, but is unlikely > to work elsewhere. And in the radial case, the slice computed for the > parent is almost certainly not right for the children. > > The test should be: > > { background-color: gradient radial yellow green 60%; } > > I haven't managed to come up with a fragment that accomplishes what Daniel's > looking for. I hoped the following might do the trick: > > .MPartStack { background-color: gradient radial yellow green 95%; } > .MPartStack, .MPartStack > ToolBar, .MPartStack > Composite > ToolBar { > swt-background-mode: force; } > > But I suspect I might have some other rules in place at the moment. > > A better solution might be to change how the children are exposed from > CTabFolder so that it's easier to address the CTabItem's toolbar(s). Thanks for finding the case where my fix doesn't work. I'm going to update the patch to handle this additional case. Unfortunately the background-mode flag does not work for me (I was trying to fix it in this way before I've modified the code). We need transparent background for toolbar, but this CSS entry sets the transparent background for part, see 2nd attachment, Daniel Created attachment 238198 [details]
linear gradient after applying the new fix
Created attachment 238199 [details]
radial gradient after applying the new fix
Created attachment 238200 [details] Alternative fix for the issue (playing with sub-images) During testing the attached fix I've realized that we can solve the issue in the simpler way - https://git.eclipse.org/r/#/c/19513/ (patset #2) Anyway I attach my original idea for the new fix since it can be useful for somebody, Daniel So that makes the radial case look right, but it's still treating the symptom rather than the underlying problem. The original problem is still there: (In reply to Brian de Alwis from comment #6) > The problem that I see is that the patch causes the gradient to be applied > to all children. That may be applicable for the CTabFolder, but is unlikely > to work elsewhere. What's strange is that I have this working for a custom app. It turns out that the min/max area can be set to a gradient with "swt-unselected-tabs-color" (which actually requires a gradient). For example: swt-unselected-tabs-color: purple brown 50% 100%; Providing the part's tool area doesn't overflow, this seems to do the right thing for both the stock SWT CTabFolderRenderer and our custom E4 CTabRendering. But the overflow toolbar area (if the tools can't fit in the tab area) has to be a single colour. Putting a breakpoint in ToolBar#setBackground(), CTabFolder explicitly bashes the background image and background colour of its tool-control area (stack trace below). Thread [main] (Suspended (entry into method setBackground in Control)) ToolBar(Control).setBackground(Color) line: 3477 CTabFolder.updateBkImages() line: 3752 CTabFolder.setButtonBounds(GC) line: 2509 CTabFolder.updateItems(int) line: 3674 CTabFolder.updateItems() line: 3609 CTabFolder.onResize(Event) line: 2012 CTabFolder$1.handleEvent(Event) line: 286 EventTable.sendEvent(Event) line: 84 Display.sendEvent(EventTable, Event) line: 4170 CTabFolder(Widget).sendEvent(Event) line: 1466 CTabFolder(Widget).sendEvent(int, Event, boolean) line: 1489 CTabFolder(Widget).sendEvent(int) line: 1470 CTabFolder(Control).resized() line: 3296 CTabFolder(Composite).resized() line: 937 CTabFolder(Control).setFrameSize(long, long, NSSize) line: 3838 Display.windowProc(long, long, long) line: 5578 OS.objc_msgSend(long, long, NSRect) line: not available [native method] SWTCanvasView(NSView).setFrame(NSRect) line: 275 CTabFolder(Control).setBounds(int, int, int, int, boolean, boolean) line: 3568 CTabFolder(Control).setBounds(int, int, int, int) line: 3550 FillLayout.layout(Composite, boolean) line: 201 Composite.updateLayout(boolean) line: 1201 Composite.resized() line: 940 Composite(Control).setFrameSize(long, long, NSSize) line: 3838 Display.windowProc(long, long, long) line: 5578 OS.objc_msgSend(long, long, NSRect) line: not available [native method] SWTCanvasView(NSView).setFrame(NSRect) line: 275 Composite(Control).setBounds(int, int, int, int, boolean, boolean) line: 3568 Composite(Control).setBounds(int, int, int, int) line: 3550 FillLayout.layout(Composite, boolean) line: 201 Composite.updateLayout(boolean) line: 1201 Composite.resized() line: 940 Composite(Control).setFrameSize(long, long, NSSize) line: 3838 Display.windowProc(long, long, long) line: 5578 OS.objc_msgSend(long, long, NSRect) line: not available [native method] SWTCanvasView(NSView).setFrame(NSRect) line: 275 Composite(Control).setBounds(int, int, int, int, boolean, boolean) line: 3568 Composite(Control).setBounds(Rectangle) line: 3604 SashLayout.setRectangle(MUIElement, Rectangle) line: 319 SashLayout.tileSubNodes(Rectangle, MUIElement) line: 264 SashLayout.tileSubNodes(Rectangle, MUIElement) line: 307 SashLayout.tileSubNodes(Rectangle, MUIElement) line: 307 SashLayout.tileSubNodes(Rectangle, MUIElement) line: 307 SashLayout.layout(Composite, boolean) line: 174 Composite.updateLayout(boolean) line: 1201 Composite.updateLayout(boolean) line: 1207 Composite.updateLayout(boolean) line: 1207 Composite.updateLayout(boolean) line: 1207 Composite.updateLayout(boolean) line: 1207 Shell(Composite).updateLayout(boolean) line: 1207 Shell(Composite).setLayoutDeferred(boolean) line: 1085 Display.runDeferredLayouts() line: 4037 Display.readAndDispatch() line: 3638 PartRenderingEngine$9.run() line: 1113 Realm.runWithDefault(Realm, Runnable) line: 332 PartRenderingEngine.run(MApplicationElement, IEclipseContext) line: 997 E4Workbench.createAndRunUI(MApplicationElement) line: 146 Workbench$5.run() line: 613 Realm.runWithDefault(Realm, Runnable) line: 332 Workbench.createAndRunWorkbench(Display, WorkbenchAdvisor) line: 567 PlatformUI.createAndRunWorkbench(Display, WorkbenchAdvisor) line: 150 IDEApplication.start(IApplicationContext) line: 124 EclipseAppHandle.run(Object) line: 196 EclipseAppLauncher.runApplication(Object) line: 109 EclipseAppLauncher.start(Object) line: 80 EclipseStarter.run(Object) line: 372 EclipseStarter.run(String[], Runnable) line: 226 NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method] NativeMethodAccessorImpl.invoke(Object, Object[]) line: 57 DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43 Method.invoke(Object, Object...) line: 601 Main.invokeFramework(String[], URL[]) line: 636 Main.basicRun(String[]) line: 591 Main.run(String[]) line: 1450 Main.main(String[]) line: 1426 (In reply to Brian de Alwis from comment #11) > So that makes the radial case look right, but it's still treating the > symptom rather than the underlying problem. The original problem is still > there: > > (In reply to Brian de Alwis from comment #6) > > The problem that I see is that the patch causes the gradient to be applied > > to all children. That may be applicable for the CTabFolder, but is unlikely > > to work elsewhere. > > > What's strange is that I have this working for a custom app. It turns out > that the min/max area can be set to a gradient with > "swt-unselected-tabs-color" (which actually requires a gradient). For > example: > > swt-unselected-tabs-color: purple brown 50% 100%; > > Providing the part's tool area doesn't overflow, this seems to do the right > thing for both the stock SWT CTabFolderRenderer and our custom E4 > CTabRendering. > > But the overflow toolbar area (if the tools can't fit in the tab area) has > to be a single colour. Putting a breakpoint in ToolBar#setBackground(), > CTabFolder explicitly bashes the background image and background colour of > its tool-control area (stack trace below). > > Thread [main] (Suspended (entry into method setBackground in Control)) > ToolBar(Control).setBackground(Color) line: 3477 > CTabFolder.updateBkImages() line: 3752 > CTabFolder.setButtonBounds(GC) line: 2509 > CTabFolder.updateItems(int) line: 3674 > CTabFolder.updateItems() line: 3609 > CTabFolder.onResize(Event) line: 2012 > CTabFolder$1.handleEvent(Event) line: 286 > EventTable.sendEvent(Event) line: 84 > Display.sendEvent(EventTable, Event) line: 4170 > CTabFolder(Widget).sendEvent(Event) line: 1466 > CTabFolder(Widget).sendEvent(int, Event, boolean) line: 1489 > CTabFolder(Widget).sendEvent(int) line: 1470 > CTabFolder(Control).resized() line: 3296 > CTabFolder(Composite).resized() line: 937 > CTabFolder(Control).setFrameSize(long, long, NSSize) line: 3838 > Display.windowProc(long, long, long) line: 5578 > OS.objc_msgSend(long, long, NSRect) line: not available [native method] > SWTCanvasView(NSView).setFrame(NSRect) line: 275 > CTabFolder(Control).setBounds(int, int, int, int, boolean, boolean) line: > 3568 > CTabFolder(Control).setBounds(int, int, int, int) line: 3550 > FillLayout.layout(Composite, boolean) line: 201 > Composite.updateLayout(boolean) line: 1201 > Composite.resized() line: 940 > Composite(Control).setFrameSize(long, long, NSSize) line: 3838 > Display.windowProc(long, long, long) line: 5578 > OS.objc_msgSend(long, long, NSRect) line: not available [native method] > SWTCanvasView(NSView).setFrame(NSRect) line: 275 > Composite(Control).setBounds(int, int, int, int, boolean, boolean) line: > 3568 > Composite(Control).setBounds(int, int, int, int) line: 3550 > FillLayout.layout(Composite, boolean) line: 201 > Composite.updateLayout(boolean) line: 1201 > Composite.resized() line: 940 > Composite(Control).setFrameSize(long, long, NSSize) line: 3838 > Display.windowProc(long, long, long) line: 5578 > OS.objc_msgSend(long, long, NSRect) line: not available [native method] > SWTCanvasView(NSView).setFrame(NSRect) line: 275 > Composite(Control).setBounds(int, int, int, int, boolean, boolean) line: > 3568 > Composite(Control).setBounds(Rectangle) line: 3604 > SashLayout.setRectangle(MUIElement, Rectangle) line: 319 > SashLayout.tileSubNodes(Rectangle, MUIElement) line: 264 > SashLayout.tileSubNodes(Rectangle, MUIElement) line: 307 > SashLayout.tileSubNodes(Rectangle, MUIElement) line: 307 > SashLayout.tileSubNodes(Rectangle, MUIElement) line: 307 > SashLayout.layout(Composite, boolean) line: 174 > Composite.updateLayout(boolean) line: 1201 > Composite.updateLayout(boolean) line: 1207 > Composite.updateLayout(boolean) line: 1207 > Composite.updateLayout(boolean) line: 1207 > Composite.updateLayout(boolean) line: 1207 > Shell(Composite).updateLayout(boolean) line: 1207 > Shell(Composite).setLayoutDeferred(boolean) line: 1085 > Display.runDeferredLayouts() line: 4037 > Display.readAndDispatch() line: 3638 > PartRenderingEngine$9.run() line: 1113 > Realm.runWithDefault(Realm, Runnable) line: 332 > PartRenderingEngine.run(MApplicationElement, IEclipseContext) line: 997 > E4Workbench.createAndRunUI(MApplicationElement) line: 146 > Workbench$5.run() line: 613 > Realm.runWithDefault(Realm, Runnable) line: 332 > Workbench.createAndRunWorkbench(Display, WorkbenchAdvisor) line: 567 > PlatformUI.createAndRunWorkbench(Display, WorkbenchAdvisor) line: 150 > IDEApplication.start(IApplicationContext) line: 124 > EclipseAppHandle.run(Object) line: 196 > EclipseAppLauncher.runApplication(Object) line: 109 > EclipseAppLauncher.start(Object) line: 80 > EclipseStarter.run(Object) line: 372 > EclipseStarter.run(String[], Runnable) line: 226 > NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not > available [native method] > NativeMethodAccessorImpl.invoke(Object, Object[]) line: 57 > DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43 > Method.invoke(Object, Object...) line: 601 > Main.invokeFramework(String[], URL[]) line: 636 > Main.basicRun(String[]) line: 591 > Main.run(String[]) line: 1450 > Main.main(String[]) line: 1426 OK, I've prepared the new version of patch that handles the new usecase as well. However I think we should consider it as the temporary fix for the gradient issue. In my opinion to solve the issue in the right way we have to add the 'transparent' color support to the CSS engine and use it as one of the global, default colors for all Widgets and next replace it with proper CSS style (or skip when style is not present). Currently we reuse the existing styles from Widgets that is not good in all cases - see the bug 423813. Probably with the transparent color we will have some issues since it is the general issue for the regular CSS supported by Web browsers (i.e. for 6 > IE <= 8 you have to play with the Alpha channel, because by default you get black color instead) Solving it in the CTabFolderRenderer class doesn't seem to be the proper place for this fix since we can use the default SWT renderer (as it is in the case of the 'classic' stylesheet), but if you think that it is the proper place for the fix, I think we can open proper bug to the SWT team. Basically we need the fix to enable the CSS bridge (bug 419016) that is required by other bugs (i.e. bug 421764 or bug 344234) I've added you as the reviewer to Gerrit. If you see another idea about how to fix it please put proper comment I think Brian's right, we can't just blindly apply something to a control's children. Why wouldn't the child pick up the gradient when it's styled independent of it's parents? I thought CSS children inherited their parent's style unless they had applying rules of their own? PW (In reply to Paul Webster from comment #13) > I think Brian's right, we can't just blindly apply something to a control's > children. > > Why wouldn't the child pick up the gradient when it's styled independent of > it's parents? I thought CSS children inherited their parent's style unless > they had applying rules of their own? > > PW Yes, child inherits the parent's style in this case as well - the background color that is gray in this case (but not background image). To fix the gradient issue we have to just make the child's background transparent (Widget.setBackground(null)). I've updated the patch and I believe now it handles all cases (the previous version also worked fine, but the new one is safer according to me). So now when child has got the same background color as parent then it is nulled (it gives us transparent background and fixes the issue) Daniel It seems Daniel's motivating example is solved using the swt-unselected-tabs-color property. Comparing the implementation of that property, CSSPropertyUnselectedTabsSWTHandler, with the background implementation in CSSPropertyBackgroundSWTHandler, shows two differences: * CSSPropertyBackgroundSWTHandler has special-case code for CTabItem, and none for CTabFolder * CSSPropertyUnselectedTabsSWTHandler has special-case code for CTabFolder to make some special calls on the CTabFolderRenderer (setActiveToolbarGradient() and setInactiveToolbarGradient()). Isn't the right solution here to modify CSSPropertyBackgroundSWTHandler to handle CTabFolder directly (since your usecase seems legitimate) and invoke the same special-case code as in CSSPropertyUnselectedTabsSWTHandler? I do find the CTabFolder styling to be a swamp to navigate, and it's been on my Eclipse bucket list to clean up, but it's a daunting task... This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant. -- The automated Eclipse Genie. |
Created attachment 238170 [details] Gradient issue I have the following CSS stylesheet: .MPartStack { background-color: yellow green 100%; } After running the Eclipse I see that gradient was set to the parent control, but not for its children (see attachment)