Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 332752

Summary: NO_BACKGROUND bug
Product: [Eclipse Project] Platform Reporter: Alexey Kuznetsov <axet>
Component: SWTAssignee: Platform-SWT-Inbox <platform-swt-inbox>
Status: CLOSED WONTFIX QA Contact:
Severity: normal    
Priority: P3 CC: eclipse.felipe
Version: 3.6.1   
Target Milestone: ---   
Hardware: PC   
OS: Linux   
Whiteboard:
Attachments:
Description Flags
linux-look
none
osx-look
none
work-application-linux none

Description Alexey Kuznetsov CLA 2010-12-16 10:54:30 EST
i tried to use Composite elements on my nice background image and found Composite with (NO_BACKGROUND) flag still clear it.

(os linux, gtk2)

        Display display = new Display();
        Shell shell = new Shell(display);
        shell.setBounds(0,0,200,200);
        shell.setBackground(new Color(display, new RGB(20,20,20)));
        Composite c = new Composite(shell, SWT.NO_BACKGROUND);
        c.setBounds(50,50,20,20);
        shell.open();
        
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
Comment 1 Alexey Kuznetsov CLA 2010-12-16 10:58:01 EST
Created attachment 185335 [details]
linux-look
Comment 2 Felipe Heidrich CLA 2010-12-16 11:00:05 EST
What are you trying to do ?
What is the expected result and the actual one ?
Comment 3 Alexey Kuznetsov CLA 2010-12-16 11:01:31 EST
expected result - blank screen.

i'll show how it looks on my osx machine.
Comment 4 Alexey Kuznetsov CLA 2010-12-16 11:03:43 EST
*black
Comment 5 Alexey Kuznetsov CLA 2010-12-16 11:04:46 EST
Created attachment 185339 [details]
osx-look

absolutely black screen (as it should be)
Comment 6 Felipe Heidrich CLA 2010-12-16 11:09:13 EST
Okay, but at the end of the day you don't want a black rectangle in your app, right ?
What is it that you trying to do (the final goal) and is not working ?
Comment 7 Alexey Kuznetsov CLA 2010-12-16 11:12:52 EST
My goal to create my own GUI application with nice design (designer works well and create a bunch of images for each button / form element / backgrounds).

I tried to create main Composite component with background image and post over it my own controls (Composite's) some of which represents buttons (Composite with addListners events), other with input fields and many other elements. All images attached to Composited and sub Composites, posted by .addPaintListener to each Composite on screen.

So, when i did it on Mac OSX everytin goes well, but after i put my work to linux i got a lot of white blocks (Composite's with NO_BACKGROUND suddenly starts to paint backgound).

And i post example here:

- Main Composite (Shell) with backgound (in my case also Image)
- Sub Composite (Button, in this example just Composite) with NO_BACKGROUND, because i paint it with my own image attached by addPaintListener to this component.


Is here any way to fix this problem? Like patch GTK, or SWT?
Comment 8 Alexey Kuznetsov CLA 2010-12-16 12:49:39 EST
Created attachment 185349 [details]
work-application-linux

let me explain.

1) parent composite have background iamage
2) child composite is a rectangle with transparent image with smooth corners
3) area around child composite is must not be erased

but it is erased by child composite created with NO_BACKGROUND.
Comment 9 Alexey Kuznetsov CLA 2010-12-16 12:51:44 EST
more over.

looks like child composite prevents to paint over it's area by Paint event of parent Composite. but it should't prevent this action, because it has NO_BACKGROUND flag.
Comment 10 Felipe Heidrich CLA 2010-12-16 14:10:11 EST
(In reply to comment #9)
> more over.
> looks like child composite prevents to paint over it's area by Paint event of
> parent Composite. but it should't prevent this action, because it has
> NO_BACKGROUND flag.

That is not what NO_BACKGROUND is. Please, read javadoc again. Basically it is a old technique stop prevent flashing (from win32). Basically in the old days windows would fill the background of the window with some color during WM_ERASEBKGND, a instant later the application would process WM_PAINT and redraw the entire to a different color. That caused flashing. Basically NO_BACKGROUND stops windows from filling the background during WM_ERASEBKGND.
Nowadays (almost) everything is double buffer, thus NO_BACKGROUND became obsolete.



I think what you want is control that is transparent, except but the region of the control where you draw your image.

Try to use setBackgroundMode in the shell, set it to INHERIT_FORCE. See if it helps.

Note: do not use SWT.TRANSPARENT, it does not work.
Comment 11 Alexey Kuznetsov CLA 2010-12-16 15:37:31 EST
Thanks for suggestion. But it does not work for me.

I need to get able to draw over child component. And to do this i can use only setBackgroundImage technique. Which is very limited to one big image (not dynamicaly calculated from many multiply images). But drawing one big image, or prepare it dynamically is very slow.

Here an another example. Child Composite over laps parent composite, but child do not do any drawings. I try to avoid this effect.

Seems like SWT can't solve it efficiently (in case if NO_BACKGROUND is obsolute, which works under OSX. So, then sorry for report).

    public static void main(String[] args) {
        final Display display = new Display();
        Shell shell = new Shell(display);
        shell.setBounds(0,0,500,500);
        shell.setBackground(new Color(display, new RGB(20,20,20)));
        
        final Composite c = new Composite(shell, SWT.NONE);
        c.setBounds(100,100,100,100);
        c.setBackground(new Color(display, new RGB(120,120,120)));
        c.setBackgroundMode(SWT.INHERIT_FORCE);
        c.addPaintListener(new PaintListener() {
            
            @Override
            public void paintControl(PaintEvent arg0) {
                arg0.gc.setForeground(new Color(display, new RGB(20,20,20)));
                arg0.gc.drawText("1234567890", 20, 50);
            }
        });

        Composite c2 = new Composite(c, SWT.NONE);
        c2.setBounds(50,50,20,20);

        shell.open();

        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
    }
Comment 12 Alexey Kuznetsov CLA 2010-12-16 15:40:24 EST
I probably need something like this:

c2.setBackground(SWT.TRANSPARENT);
Comment 13 Felipe Heidrich CLA 2010-12-16 16:03:39 EST
I didn't understand why INHERIT_FORCE is no good for you. Arn't already using setBackgroundImage().
Note that background image will tile small images to cover the client area. If you need to compose one big image from several different smaller images need to do it when the composite is created, then just again when it resizes (your image is always the size of the client area). I don't think it should be too slow.

In the snippet you gave in comment 11, how is that failing for you.I tested here, and the code was exactly what you programmed. Did you expect it to be different ?
Comment 14 Alexey Kuznetsov CLA 2010-12-16 16:33:30 EST
I need to prevent background from painting for all child Composite's.

SWT.TRANSPARENT - refering to documentation is exactly what i need. But it still under development since swt-3.4.

seems this bug is closed. thanks for your help, really get me understand the problem very deep.
Comment 15 Felipe Heidrich CLA 2010-12-16 16:51:24 EST
(In reply to comment #14)
> seems this bug is closed. 

Okay, closing.