Bug 581990 - SWT GC fillRectangle/drawImage are not working on macOS
Summary: SWT GC fillRectangle/drawImage are not working on macOS
Status: NEW
Alias: None
Product: Incubator
Classification: Eclipse Project
Component: e4 (show other bugs)
Version: unspecified   Edit
Hardware: PC Mac OS X
: P3 critical (vote)
Target Milestone: ---   Edit
Assignee: E4 Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-05-29 09:43 EDT by Dan Moldoveanu CLA
Modified: 2023-05-29 09:43 EDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Dan Moldoveanu CLA 2023-05-29 09:43:10 EDT
Hi,

I am trying to fix a problem that I'm currently running into and that is with the GC graphics context on mac OS. 
Lately after not developing that much on my eclipse extension, I noticed that the Eclipse IDE was crashing when trying to use fillRectangle or drawImage from GC. They are used to add a custom loading spin loader while our API calls are made. After fixing the crashing part, I noticed that the drawImage method is not working at all on macOS while it's perfectly working on windows and displaying my gif image.
Is this a known problem? 
If yes, do you have any ideas/workarounds for making it work on macOS as well?

Thanks!



private void createAnimationThread(int gifSize) {
        Display display = parent.getDisplay();
        Color shellBackground = getBackground();
        
        animateThread = new Thread() {
            @Override
            public void run() {
                /*
                 * Create an off-screen image to draw on, and fill it with the
                 * shell background.
                 */
                Image offScreenImage = new Image(display, loader.logicalScreenWidth,
                        loader.logicalScreenHeight);
                GC offScreenImageGC = new GC(offScreenImage);
                offScreenImageGC.setBackground(shellBackground);
                offScreenImageGC.fillRectangle(0, 0, loader.logicalScreenWidth,
                        loader.logicalScreenHeight);

                try {
                    /*
                     * Create the first image and draw it on the off-screen
                     * image.
                     */
                    int imageDataIndex = 0;
                    ImageData imageData = imageDataArray[imageDataIndex];
                    if (image != null && !image.isDisposed())
                        image.dispose();
                    image = new Image(display, imageData);
                    offScreenImageGC.drawImage(
                            image,
                            0,
                            0,
                            imageData.width,
                            imageData.height,
                            (imageData.width - gifSize) / 2,
                            (imageData.height - gifSize) / 2,
                            gifSize,
                            gifSize);

                    /*
                     * Now loop through the images, creating and drawing each
                     * one on the off-screen image before drawing it on the
                     * shell.
                     */
                    while (!stopAnimation) {
                        switch (imageData.disposalMethod) {
                            case SWT.DM_FILL_BACKGROUND:
                                /*
                                 * Fill with the background color before
                                 * drawing.
                                 */
                                Color bgColor = null;
                                offScreenImageGC.setBackground(bgColor != null ? bgColor : shellBackground);
                                offScreenImageGC.fillRectangle(imageData.x, imageData.y,
                                        imageData.width, imageData.height);
                                break;
                            case SWT.DM_FILL_PREVIOUS:
                                /*
                                 * Restore the previous image before drawing.
                                 */
                                offScreenImageGC.drawImage(
                                        image,
                                        0,
                                        0,
                                        imageData.width,
                                        imageData.height,
                                        (imageData.width - gifSize) / 2,
                                        (imageData.height - gifSize) / 2,
                                        gifSize,
                                        gifSize);
                                break;
                        }

                        imageDataIndex = (imageDataIndex + 1) % imageDataArray.length;
                        imageData = imageDataArray[imageDataIndex];
                        image.dispose();
                        image = new Image(display, imageData);
                        offScreenImageGC.drawImage(
                                image,
                                0,
                                0,
                                imageData.width,
                                imageData.height,
                                (imageData.width - gifSize) / 2,
                                (imageData.height - gifSize) / 2,
                                gifSize,
                                gifSize);

                        /*
                         * Draw the off-screen image
                         */

                        display.syncExec(new Runnable() {
                            @Override
                            public void run() {
                                if (LoadingComposite.this.isDisposed()) {
                                    return;
                                }

                                Point point = LoadingComposite.this.getSize();

                                int xPos = (point.x - offScreenImage.getBounds().width) / 2;

                                int yPos;
                                switch (loadingPosition) {
                                    case CENTER:
                                        yPos = (point.y - offScreenImage.getBounds().height) / 2;
                                        break;
                                    case TOP:
                                        yPos = 0 + offScreenImage.getBounds().height / 4;
                                        break;
                                    case BOTTOM:
                                        yPos = point.y - offScreenImage.getBounds().height;
                                        break;
                                    default:
                                        yPos = 0;
                                }

                                GC shellGC = new GC(LoadingComposite.this);
                                
                                shellGC.setBackground(new Color(255, 0, 0));
                                shellGC.fillRectangle(0, 0, 200, 200); // HERE - working on windows, not working on mac
                                shellGC.dispose();
                                
                                //shellGC.fillRectangle(0, 0, point.x, point.y);
                                //shellGC.drawImage(offScreenImage, xPos, yPos);
                            }
                        });

                        /*
                         * Sleep for the specified delay time (adding
                         * commonly-used slow-down fudge factors).
                         */
                        try {
                            int ms = imageData.delayTime * 10;
                            if (ms < 20)
                                ms += 30;
                            if (ms < 30)
                                ms += 10;
                            Thread.sleep(ms);
                        } catch (InterruptedException e) {
                        }
                    }
                } catch (SWTException ignored) {
                    // Assuming thread was stopped because component was
                    // disposed
                } finally {
                    if (offScreenImage != null && !offScreenImage.isDisposed())
                        offScreenImage.dispose();
                    if (offScreenImageGC != null && !offScreenImageGC.isDisposed())
                        offScreenImageGC.dispose();
                    if (image != null && !image.isDisposed())
                        image.dispose();
                }
            }
        };
        
        animateThread.setDaemon(true);
        animateThread.start();
    }