Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wxSplashScreen delayed transparency #23232

Open
mxwendler opened this issue Feb 7, 2023 · 5 comments
Open

wxSplashScreen delayed transparency #23232

mxwendler opened this issue Feb 7, 2023 · 5 comments

Comments

@mxwendler
Copy link

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:

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.

The bitmap is very complex, so creating the shape takes too long. An idea could be, to create the window, set the shape and then show it, but this is not possible since

Show(true)

is hardcoded into the wxSplashScreen ctor. Another idea could be, move the window outside the screen, set shape, then move to center, but this is not possible since pos and size are not forwarded to the wxSplashScreen/wxFrame ctor:

/* 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)

I solved the issue by copying the wxSplashScreen code and adding a "wxSPLASH_NO_AUTOSHOW" flag. Applied to the wx3.2.1 branch, a patch could be

$ git diff
diff --git a/include/wx/generic/splash.h b/include/wx/generic/splash.h
index 58a0add..a5466ae 100755
--- a/include/wx/generic/splash.h
+++ b/include/wx/generic/splash.h
@@ -25,6 +25,7 @@
 #define wxSPLASH_CENTRE_ON_SCREEN   0x02
 #define wxSPLASH_NO_CENTRE          0x00
 #define wxSPLASH_TIMEOUT            0x04
+#define wxSPLASH_NO_AUTOSHOW        0x08
 #define wxSPLASH_NO_TIMEOUT         0x00

 class WXDLLIMPEXP_FWD_CORE wxSplashScreenWindow;
diff --git a/src/generic/splash.cpp b/src/generic/splash.cpp
index 618c3a0..49c92fa 100755
--- a/src/generic/splash.cpp
+++ b/src/generic/splash.cpp
@@ -85,7 +85,7 @@ wxSplashScreen::wxSplashScreen(const wxBitmap& bitmap, long splashStyle, int mil
         m_timer.Start(milliseconds, true);
     }

-    Show(true);
+    Show(!(m_splashStyle & wxSPLASH_NO_AUTOSHOW));
     m_window->SetFocus();
 #if defined( __WXMSW__ ) || defined(__WXMAC__)
     Update(); // Without this, you see a blank screen for an instant

The issue is discussed here:
https://forums.wxwidgets.org/viewtopic.php?f=23&t=50112

@vadz
Copy link
Contributor

vadz commented Feb 7, 2023

I'd really like to know what has changed here as I don't see why would it work differently than with 2.8.

But independently of this I agree that it would make sense to set shape before showing the window. Adding a style just for this looks like an overkill, however. The usual idiom for creating a window initially hidden is

auto w = new wxWindow(); // default ctor
w->Hide();
w->Create(parent, ...);

and I'd prefer to make this work for wxSplashScreen too. AFAICS this should be simple enough, we just need to add Create() to it (which would do the same thing as the existing non-default ctor does, and this ctor would simply forward to Create()) and check for IsShown() before calling Show() there. Any PRs doing this would be welcome!

BTW, I'd definitely recommend converting your BMP to PNG to avoid creating mask during run-time (and also have a much smaller size) in any case.

@mxwendler
Copy link
Author

BTW, I'd definitely recommend converting your BMP to PNG to avoid creating mask during run-time (and also have a much smaller size) in any case.

I tried this and ran into another issue: i am running a non-dpi-aware application under a 'scaled' desktop (Windows 10 150% e.g.), and the transparent regions of the splash template have pixels from the backbuffer blended into them, but this 'screenshot' is scaled up before applying the blending, so it does not fit onto the original desktop any more (which would create the illusion af transparency)

@mxwendler
Copy link
Author

mxwendler commented Mar 27, 2023

Any PRs doing this would be welcome!

I am working on it, but still wip as you can see.

@vadz
Copy link
Contributor

vadz commented Mar 27, 2023

BTW, I'd definitely recommend converting your BMP to PNG to avoid creating mask during run-time (and also have a much smaller size) in any case.

I tried this and ran into another issue: i am running a non-dpi-aware application under a 'scaled' desktop (Windows 10 150% e.g.), and the transparent regions of the splash template have pixels from the backbuffer blended into them, but this 'screenshot' is scaled up before applying the blending, so it does not fit onto the original desktop any more (which would create the illusion af transparency)

Sorry, I don't understand how does using BMP vs PNG could change anything here. Also, with non-DPI-aware applications, the appearance must be the same at 100% and 150% (except blurry, of course), otherwise it would be a bug in Windows itself which seems unlikely.

@mxwendler
Copy link
Author

mxwendler commented Mar 27, 2023

Sorry, I don't understand how does using BMP vs PNG could change anything here.

I was surprised too. This is how it looks when i use a png file with an alpha channel. The splash has a width of 1200x692px, the desktop is native 3200x1800 and the (Windows-) scaling is 200%. In the background is this issue thread visible, and scaled up in the splash.

It looks a bit like

  1. screenshot taken
  2. composition made
  3. desktop scale applied
  4. sent back to compositor

screenshot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants