News:

Accounts with zero posts and zero activity during the last months will be deleted periodically to fight SPAM!

Main Menu

problem with wxSmith and Mac-OSX

Started by usenechal, May 23, 2007, 10:04:52 AM

Previous topic - Next topic

Auria

okay - I haven't gotten your SVN updates yet, I will do that next. (My build problems turned out to be a stupid path problem. oops! I needed a night of sleep to see that ^^)

I have tried with the patched code (rev 4028)
When opening wxSmith, I saw a blue rectangle briefly appear then it turned back grey again. If i hide the app, then bring it to front, i see a red one appear briefly but then disappear too.

If I click on the button icon, first time I saw a blue rect, then a red one, then it all went grey again. When trying to add various components, I see sometimes the blue one, sometimes the red one, sometimes it stays there but now always.

The red one sometimes appears (when the moving the mouse?)

I am now doing the svn update - coming back when it's done

Auria

#16
I now have the new code (rev 4051)

Widgets appear when added but disappear shortly afterwards (everything turns grey)

EDIT:I have been doing some tests with std::cout ;)

when trying to add a button

fast repaint
before content changed
after content changed
start fetching sequence
on fetch sequence
refresh timer
fetch sequence phase 2
fetch screen
hide children
erase
erase

hmm paint is called first, then erase. on screen, I see the button appear as repaint is called and disappear as erase is called. If it normal that erase is called now?

void OnEraseBack(wxEraseEvent& event)

well it's empty - I'm just not sure I get how wxSmith displays widgets. Does it use some sort of screen capture?

byo

Quote from: Auria on June 03, 2007, 08:37:35 PM

hmm paint is called first, then erase. on screen, I see the button appear as repaint is called and disappear as erase is called. If it normal that erase is called now?

void OnEraseBack(wxEraseEvent& event)

well it's empty - I'm just not sure I get how wxSmith displays widgets. Does it use some sort of screen capture?

Yes, exactly, the screen is captured and the extra content is drawn over it.

And I thing that we have the reason of hiding content - it looks like this empty erase function is responsible for this. Could you comment line 96:


Connect(DrawingPanelId,wxEVT_ERASE_BACKGROUND,(wxObjectEventFunction)&wxsDrawingWindow::DrawingPanel::OnEraseBack);


And check what will happen?
Regards
   BYO

Auria

I commented out the line and it still disappears.

I think they disappear on HideChildren() and then the new background is not drawn over it.

byo

Hmm, another thing that came into my mind:

Could you put on line 292? :


void wxsDrawingWindow::FetchSequencePhase2()
{
    if ( !Panel ) return;
    if ( IsDestroyed ) return;
    FetchScreen();
    HideChildren();
    Panel->Show();
    DuringFetch = false;
    FastRepaint();            // <----
}


and maybe other solution for this problem:


void wxsDrawingWindow::FetchSequencePhase2()
{
    if ( !Panel ) return;
    if ( IsDestroyed ) return;
    FetchScreen();
    HideChildren();
    DuringFetch = false;        // <--- This and
    Panel->Show();              // <--- this line were swapped
}


Maybe it's just as you say that children are hidden, panel is shown but it doesn't paint.
It may not paint because DuringFetch is still false. On Win and Linux, Panel->Show causes some extra event to be generated and paint procedure is actually done after jumping out of FetchSequencePhase2(). On Mac it may be done while calling Show function.

Regards
   BYO

Auria

#20
I tried both with still no luck :?

HOWEVER, i made a little experiment that most likely shows the issue.

i added

if(!Bitmap->SaveFile(wxT("wxSmithScreen.bmp"),wxBITMAP_TYPE_BMP)) std::cout << "saving failed" << std::endl;


at the end of FetchScreen(). I then opened wxSmith, then opened the generated file - and it was empty (transparent). So it seems like fetchScreen() doesn't work.

byo

Quote from: Auria on June 06, 2007, 01:40:12 AM
I tried both with still no luck :?

HOWEVER, i made a little experiment that most likely shows the issue.

i added

if(!Bitmap->SaveFile(wxT("wxSmithScreen.bmp"),wxBITMAP_TYPE_BMP)) std::cout << "saving failed" << std::endl;


at the end of FetchScreen(). I then opened wxSmith, then opened the generated file - and it was empty (transparent). So it seems like fetchScreen() doesn't work.

Hmm, doesn't look very optimistic :(. But there is a way to fetch screen since splashscreen uses this. Maybe the screen is fetched in wrong time or maybe it's fetched properly but cleared right after :/

Could you check this code instead of the one you presented ? It will save each fetch at different bitmap and show number of fetches made. If at least one bitmap will have valid content, it would be huge milestone. There will also be a hint how many fetches are done after each change (it will put number of fetches done so far into stdout). The correct behavior would be to fetch only once after each resource change / editor content resize.


static int Cnt = 0;
if(!Bitmap->SaveFile(wxString::Format(wxT("wxSmithScreen%d.bmp"),++Cnt),wxBITMAP_TYPE_BMP)) std::cout << "saving failed" << std::endl;
std::cout << "fetch " << Cnt << std::endl;


Regards
   BYO

Auria

Quote from: byo on June 12, 2007, 11:34:10 PM
But there is a way to fetch screen since splashscreen uses this.

Actually no :( The splash screen on mac doesn't use any transparency... not sure why, afb could probably tell you.

Quote from: byo on June 12, 2007, 11:34:10 PM
Could you check this code instead of the one you presented ?

The screen is not fetched too often, and images are always empty.

Seems like a good conadidate for wxBug report :(

afb

Quote from: Auria on June 13, 2007, 01:23:02 AM
Quote from: byo on June 12, 2007, 11:34:10 PM
But there is a way to fetch screen since splashscreen uses this.

Actually no :( The splash screen on mac doesn't use any transparency... not sure why, afb could probably tell you.

Actually it does use transparency, but the old-skool Carbon apis that the wxMac port is using only supported window "regions" (i.e. black-white mask) and not full alpha-channel transparency for the windows...

The fetch screen sorta worked, but since it left a rect around the fetched area and other such artificats it didn't really fool anyone it was transparent. Looked more like "screen dump as background" or such.

byo

Quote from: afb on June 13, 2007, 08:40:30 PM
The fetch screen sorta worked, but since it left a rect around the fetched area and other such artificats it didn't really fool anyone it was transparent. Looked more like "screen dump as background" or such.

Hmm and that "screen dump as background" is exactly what I need :). Just need to find out why it fetches empty images instead of what's shown on the screen :?

Auria: I got another idea. Could you put ::wxSleep(few seconds) just before saving the bitmap into files ? It will delay there and let you see what's shown on the screen when the fetching routine runs. If it's empty content, that would mean that items are not shown properly, if it's content of edited window, it would mean that fetching routine is wrong.


BYO

Auria

Thanks for leading me - guess what? I have a fix!!!


void wxsDrawingWindow::FetchScreen()
{
    if ( !Bitmap ){ return; }

    wxYield();  // <-----

    // Fetching preview directly from screen
wxScreenDC DC;


As simple as that :lol: now i don't say it fixes everything, but it fixes the most obvious bug. apparently wx just didnt have time to draw before you got the screen capture. maybe it would be better to call for redrawing the window instead of yield.

BTW What's wrong with autotools?? i need to issue the make command several times in a row as it randomly crashes or fails even though the code is valid. just reissuing it many times in a row fixes the problems...

I get seemingly randomly
Quote
/bin/sh: line 1: make: No such file or directory
Quote
ranlib $  d   
ranlib: can't open file: $ (No such file or directory)
ranlib: can't open file: d (No such file or directory)


MortenMacFly

Quote from: Auria on June 14, 2007, 01:47:09 AM

    wxYield();  // <-----

Remember that IMHO you'd better use

Manager::Yield();

at this point...
With regards, Morten.
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: [url="https://www.codeblocks.org/docs/main_codeblocks_en.html"]https://www.codeblocks.org/docs/main_codeblocks_en.html[/url]
C::B FAQ: [url="https://wiki.codeblocks.org/index.php?title=FAQ"]https://wiki.codeblocks.org/index.php?title=FAQ[/url]

byo

Quote from: Auria on June 14, 2007, 01:47:09 AM
Thanks for leading me - guess what? I have a fix!!!


void wxsDrawingWindow::FetchScreen()
{
    if ( !Bitmap ){ return; }

    wxYield();  // <-----

    // Fetching preview directly from screen
wxScreenDC DC;


As simple as that :lol: now i don't say it fixes everything, but it fixes the most obvious bug. apparently wx just didnt have time to draw before you got the screen capture. maybe it would be better to call for redrawing the window instead of yield.


Wow, thanks for all your investigations :) Now we really have something  8)
That's funny because I've used Yields before switching to timers :? Maybe some unique combination: first call timer, than yield is the only available solution. But just to make sure: there's small inline function at the beginning of wxsdrawingwindow.cpp:

    inline RepaintDelayType GetDelayType()
    {
        // Looks like this gives best results so far on both linux and windows
        return TimerNormal;
    }


If you change it's content to return Yield; it will use yields instead of timers. Can you check if this works ? (It shouldn't because it didn't worked ealier).

Anyway, I'd like to avoid calling Yields because it can lead to some rare crashes, expecially when editor is being closed. And there's only one solution that come into my mind now: just call Refresh right before Update in OnFetchSequence (line 236). I assumed that refresh request is sent automaticaly after show/hide stuff, but obviously it was a bad assumption. I'll see how it works on other oses, maybe it's possible to avoid any timer/yield stuff.


Regards
   BYO

Auria

Hi Byo,

your code works as well. When using this code components do not disappear. (they do disappear when trying to play with them e.g. clicking on a text area to add text in it but i think it did it with my other code too)

so it looks like


#ifdef __WXMAC__
return Yield;
#else
return TimerNormal;
#endif

byo

Ok, I've updated sources so they use Yields on MAC. I also added Refresh() just before Update() and it works even without timers on Win now (and probably on Linux), but it's not as smooth as when using timers ;). So my request to Auria: Could you test the new code and play with it a little bit? (maybe this Refresh() / Update() sequence will work even withou any yields - using "None" delay type). Anyway, you've writteh that currently there's something shown inside wxSmith but it disappears on some circumstances. Could you describe more exact what are those circumstances? Thanks for your work :)

Regards
   BYO