wxSplashScreen delayed transparency

Do you have a typical platform dependent issue you're battling with ? Ask it here. Make sure you mention your platform, compiler, and wxWidgets version.
heinermueller
Experienced Solver
Experienced Solver
Posts: 99
Joined: Sat Oct 26, 2013 11:54 am

wxSplashScreen delayed transparency

Post by heinermueller »

Hi all,

after upgrading to wx 3.2.1 i have an issue with the splash screen. The splash is shaped is created from a BMP with black (0/0/0) selected as transparent:

Code: Select all

bitmap.LoadFile(getResourceFilePath(splashfile), wxBITMAP_TYPE_BMP)
wxMask* mask = new wxMask(bitmap, wxColour(0u, 0u, 0u));
bitmap.SetMask(mask);
wxRegion path(bitmap);

//
// add splash
long splashstyle = wxSPLASH_CENTRE_ON_SCREEN | wxSPLASH_TIMEOUT;
splash = new wxSplashScreen(
		bitmap, splashstyle, 
		8000, wxGetApp().getFrame(), ID_SPLASH, wxDefaultPosition, wxDefaultSize, wxNO_BORDER | wxSTAY_ON_TOP | wxFRAME_SHAPED);
splash->SetShape(path);

Actually everything works as expected, but under win10 with Intel GFX, for a short moment (ca. 1 second) the transparency is all black, then the transparent parts become transparent. this does not happen under linux or win/amd. Did not test other. With wx28 it worked as expected. Did anyone experience something similar?

Oh, and does wx 3.2 support alpha in splashes e.g. when using a .png?

Best wishes,
Heiner
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7458
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: wxSplashScreen delayed transparency

Post by ONEEYEMAN »

Hi,
Could you post the image?
Does it happen in the splash or drawing sample?

Thank you.
heinermueller
Experienced Solver
Experienced Solver
Posts: 99
Joined: Sat Oct 26, 2013 11:54 am

Re: wxSplashScreen delayed transparency

Post by heinermueller »

Hi,
yes, the splash sample application has the same problems. The splash is attached, please have a look at it,

Best wishes,
Heiner
Attachments
sample.bmp.tar.gz
(661.19 KiB) Downloaded 130 times
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxSplashScreen delayed transparency

Post by doublemax »

As the shape is very complex, i guess the SetPath() call takes so long. Try hiding the splashscreen until it's done.

Untested code:

Code: Select all

splash = new wxSplashScreen();
splash->Hide();
splash->Create( bitmap, splashstyle, 
		8000, wxGetApp().getFrame(), ID_SPLASH, wxDefaultPosition, wxDefaultSize, wxNO_BORDER | wxSTAY_ON_TOP | wxFRAME_SHAPED);
splash->SetShape(path);
splash->Show();
Use the source, Luke!
heinermueller
Experienced Solver
Experienced Solver
Posts: 99
Joined: Sat Oct 26, 2013 11:54 am

Re: wxSplashScreen delayed transparency

Post by heinermueller »

Ho doublemax,

i tried it with a hidden window, but there is only one constructor that immediately presents the splash.

Code: Select all

splash->Create( bitmap, splashstyle, 
		8000, wxGetApp().getFrame(), ID_SPLASH, wxDefaultPosition, wxDefaultSize, wxNO_BORDER | wxSTAY_ON_TOP | wxFRAME_SHAPED);
This specialized ->Create(..) function does not exist, the 3.2 splash header is as this:

Code: Select all

class WXDLLIMPEXP_CORE wxSplashScreen: public wxFrame,
                                      public wxEventFilter
{
public:
    // for RTTI macros only
    wxSplashScreen() { Init(); }
    wxSplashScreen(const wxBitmap& bitmap, long splashStyle, int milliseconds,
                   wxWindow* parent, wxWindowID id,
                   const wxPoint& pos = wxDefaultPosition,
                   const wxSize& size = wxDefaultSize,
                   long style = wxSIMPLE_BORDER|wxFRAME_NO_TASKBAR|wxSTAY_ON_TOP);
    virtual ~wxSplashScreen();

    void OnCloseWindow(wxCloseEvent& event);
    void OnNotify(wxTimerEvent& event);

    long GetSplashStyle() const { return m_splashStyle; }
    wxSplashScreenWindow* GetSplashWindow() const { return m_window; }
    int GetTimeout() const { return m_milliseconds; }

    // Override wxEventFilter method to hide splash screen on any user input.
    virtual int FilterEvent(wxEvent& event) wxOVERRIDE;

protected:
    // Common part of all ctors.
    void Init();

    wxSplashScreenWindow*   m_window;
    long                    m_splashStyle;
    int                     m_milliseconds;
    wxTimer                 m_timer;

    wxDECLARE_DYNAMIC_CLASS(wxSplashScreen);
    wxDECLARE_EVENT_TABLE();
    wxDECLARE_NO_COPY_CLASS(wxSplashScreen);
};
Is there a style that i can apply so it does not Show() on construction? Or maybe i can derive from it and delay wxShowEvent?
heinermueller
Experienced Solver
Experienced Solver
Posts: 99
Joined: Sat Oct 26, 2013 11:54 am

Re: wxSplashScreen delayed transparency

Post by heinermueller »

I tried it with subclassing and FilterEvent:

Code: Select all

class ms : public wxSplashScreen
{
public:
	ms(const wxBitmap& bitmap, long splashStyle, int milliseconds,
		wxWindow* parent, wxWindowID id,
		const wxPoint& pos = wxDefaultPosition,
		const wxSize& size = wxDefaultSize,
		long style = wxSIMPLE_BORDER | wxFRAME_NO_TASKBAR | wxSTAY_ON_TOP)
	:
	wxSplashScreen(bitmap, splashStyle, milliseconds, parent, id, pos, size, style)
	{
	}

	int FilterEvent(wxEvent& event) override
	{
		// Update the last user activity
		const wxEventType t = event.GetEventType();
		if (t == wxEVT_SHOW)
		{
			BREAK
		}
		// Continue processing the event normally as well.
		return Event_Skip;
	}
};
But the BREAK line is hit after the splash becomes visible on screen, probably because that is when event handling starts. I had a look at the source, and the splash is Show(true) in its ctor, is there any way i can block this?
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxSplashScreen delayed transparency

Post by doublemax »

I would try to create it with size (0,0) (or an off-screen position), then SetShape(), then set actual size ( or position)
Use the source, Luke!
heinermueller
Experienced Solver
Experienced Solver
Posts: 99
Joined: Sat Oct 26, 2013 11:54 am

Re: wxSplashScreen delayed transparency

Post by heinermueller »

doublemax wrote: Sat Feb 04, 2023 1:40 pm I would try to create it with size (0,0) (or an off-screen position), then SetShape(), then set actual size ( or position)
yes, that was my next idea also, but then i went into the splash source and saw, that pos and size is not passed to the wxFrame ctor:

Code: Select all


/* Note that unless we pass a non-default size to the frame, SetClientSize
 * won't work properly under Windows, and the splash screen frame is sized
 * slightly too small.
 */

wxSplashScreen::wxSplashScreen(const wxBitmap& bitmap, long splashStyle, int milliseconds,
                               wxWindow* parent, wxWindowID id, const wxPoint& pos,
                               const wxSize& size, long style)
    : wxFrame(parent, id, wxEmptyString, wxPoint(0,0), wxSize(100, 100),
              style | wxFRAME_TOOL_WINDOW | wxFRAME_NO_TASKBAR)
{
    Init();

    // splash screen must not be used as parent by the other windows because it
    // is going to disappear soon, indicate it by giving it this special style
    SetExtraStyle(GetExtraStyle() | wxWS_EX_TRANSIENT);

#if defined(__WXGTK20__)
    gtk_window_set_type_hint(GTK_WINDOW(m_widget),
                             GDK_WINDOW_TYPE_HINT_SPLASHSCREEN);
#endif

    m_splashStyle = splashStyle;
    m_milliseconds = milliseconds;

    m_window = new wxSplashScreenWindow(bitmap, this, wxID_ANY, pos, size, wxNO_BORDER);

    SetClientSize(bitmap.GetLogicalWidth(), bitmap.GetLogicalHeight());

    if (m_splashStyle & wxSPLASH_CENTRE_ON_PARENT)
        CentreOnParent();
    else if (m_splashStyle & wxSPLASH_CENTRE_ON_SCREEN)
        CentreOnScreen();

    if (m_splashStyle & wxSPLASH_TIMEOUT)
    {
        m_timer.SetOwner(this, wxSPLASH_TIMER_ID);
        m_timer.Start(milliseconds, true);
    }

    Show(true);
    m_window->SetFocus();
#if defined( __WXMSW__ ) || defined(__WXMAC__)
    Update(); // Without this, you see a blank screen for an instant
#elif defined(__WXGTK20__)
    // we don't need to do anything at least on wxGTK with GTK+ 2.12.9
#else
    wxYieldIfNeeded(); // Should eliminate this
#endif
}
and indeed, after removing wxSPLASH_CENTRE_ON_SCREEN and creating with wxPoint(-100, -100) or wxPoint(100,10000) the bitmap still opens opaque in the top left corner of the screen.
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxSplashScreen delayed transparency

Post by doublemax »

At this point i would just copy the whole wxSplashScreen code and create my own class from it.
Use the source, Luke!
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7458
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: wxSplashScreen delayed transparency

Post by ONEEYEMAN »

Hi,
Or report it as an issue on wxWidgets GitHub repo.

Thank you.
heinermueller
Experienced Solver
Experienced Solver
Posts: 99
Joined: Sat Oct 26, 2013 11:54 am

Re: wxSplashScreen delayed transparency

Post by heinermueller »

doublemax wrote: Sat Feb 04, 2023 2:35 pm At this point i would just copy the whole wxSplashScreen code and create my own class from it.
Yes, i think i will give this a try!
heinermueller
Experienced Solver
Experienced Solver
Posts: 99
Joined: Sat Oct 26, 2013 11:54 am

Re: wxSplashScreen delayed transparency

Post by heinermueller »

ONEEYEMAN wrote: Sat Feb 04, 2023 4:31 pm Hi,
Or report it as an issue on wxWidgets GitHub repo.

Thank you.
Sure, i can report this. "Delayed splash transparency when using complex shape" - does this headline describe the problem?
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7458
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: wxSplashScreen delayed transparency

Post by ONEEYEMAN »

Hi,
As long as you attach an image and describe what you observe vs what should happen.

Thank you.
User avatar
doublemax@work
Super wx Problem Solver
Super wx Problem Solver
Posts: 474
Joined: Wed Jul 29, 2020 6:06 pm
Location: NRW, Germany

Re: wxSplashScreen delayed transparency

Post by doublemax@work »

The key issue is that SetShape() can take long, leading to visual artifacts. One solution would be to use two-step creation which is not supported at the moment. You should also mention that the parameters for pos and size passed to the ctor are ignored.
heinermueller
Experienced Solver
Experienced Solver
Posts: 99
Joined: Sat Oct 26, 2013 11:54 am

Re: wxSplashScreen delayed transparency

Post by heinermueller »

Ok, i will do that. Maybe a good description and a link to this thread?
Post Reply