Page 1 of 2
[PBv5.30b2] Missing #PB_Event_SizeWindow Event On Startup
Posted: Sun Jun 01, 2014 5:26 pm
by grabiller
Hi,
When an application is started, no #PB_Event_SizeWindow is received.
On Windows, this is a bug, as a Windows application always receives a Size event on startup.
PB does not report it anymore due to, I guess, the new #PB_Event_SizeWindow behavior being too strict.
On a side not, this change of #PB_Event_SizeWindow behavior is wrong. Flickering should not be a reason to remove realtime #PB_Event_SizeWindow. PB should start by not creating a background brush for its Windows Class, which should already greatly reduce flickering. Removing realtime behavior of #PB_Event_SizeWindow is like trying to 'hide' a problem instead of 'solving' it.
Re: [PBv5.30b2] Missing #PB_Event_SizeWindow Event On Startu
Posted: Sun Jun 01, 2014 5:48 pm
by Fred
When opening a window, why would a resize event be fired ? It had been reported as a bug and fixed, so yes it has been changed but it sounds better here.
http://www.purebasic.fr/english/viewtop ... =4&t=59314
ps: Windows doesn't allow natively to recieve size event outside of the callback. We hacked the way Windows processed the message to make it possible, but it generates wierd issues (mainly flickering) and it's not future proof. It also doesn't work on Linux or OS X, so now at least it's consistent accross OS.
Re: [PBv5.30b2] Missing #PB_Event_SizeWindow Event On Startu
Posted: Mon Jun 02, 2014 10:41 am
by grabiller
When you do event based programming, it sounds logical to have an event for everything.
It seems you are having hard time to decide if PureBasic is event driven or callback driven by (partly) offering both for almost the same purpose. As the creator of PureBasic you should decide purely and simply which direction to take, even if it means - for instance - creating events that the OS does not send. I understand offering both offers more options to the programmer but then why restrict those same options by removing events at the same time ? This is paradoxical.
The Size event at startup is - well, was - very useful, especially to retrieve the topology of a Window, including inner client size. Not all programs have a OpenWindow() with hardcoded width and height. Now we will have to query the window size at another moment, relying on procedural programming rather than event programming (if not using callbacks).
This is simply regression.
Regarding the flickering: this has nothing to do with when the event is received. This has to do with:
1) having a background brush by default for the main Windows Class which redraw the entire window with a white (or chosen background color) rectangle every time, and
2) not validating the redrawn client area.
3) the time it takes to redraw the all GUI.
When you hack PB (on Windows) by removing that brush and by validating any redraw in the the client area, then no flickering happen anymore (well, it may happen if the UI is really heavy yes, but this is not PB related).
The only issue left is that you see the black areas on the right and down part of the window you uncover when enlarging that window. But then this is the same behavior as in C++ or any other languages.
Also, with an OpenGL window (and now with the OpenGLGadget), when you resize the window you don't get flickering but you must adjust the Viewport in realtime which is not possible anymore through Events.. This is regression too, we now have to resort to callbacks which is much less elegant (not a big deal though, but conceptually disappointing).
Re: [PBv5.30b2] Missing #PB_Event_SizeWindow Event On Startu
Posted: Thu Jun 05, 2014 9:10 pm
by grabiller
Due to that stupid decision to remove the first #PB_Event_SizeWindow event triggered on startup of a Windows application, Windowed applications that starts maximized (for instance) now present the risk to show wrong gadget layout or drawing on startup.
Here is a patch to correct this, to retrieve the old behavior:
Code: Select all
DeclareModule pb
Declare patch()
EndDeclareModule
Module pb
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
Procedure WinCallback( hWnd, uMsg, WParam, LParam )
If uMsg = #WM_SIZE
PostEvent(#PB_Event_SizeWindow)
SetWindowCallback(0)
ProcedureReturn 0
EndIf
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
CompilerEndIf
Procedure patch()
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
SetWindowCallback(@WinCallback())
CompilerEndIf
EndProcedure
EndModule
Then before opening any Window, just use:
This patch just enforces the first #PB_Event_SizeWindow of any regular Windows application to reach the Purebasic message loop through WaitWindowEvent() or WindowsEvent(). It then deactivates itself.
Hope this helps.
Cheers,
Guy.
Re: [PBv5.30b2] Missing #PB_Event_SizeWindow Event On Startu
Posted: Fri Jun 06, 2014 7:20 pm
by acreis
I think it's not polite to qualify as stupid the purebasic team decision about the size event.
As was pointed out by Fred, many users believe that this event should not occur when opening a window.
But I think that in an event driven model, the size event has a purpose: it lets the event loop knows what is the size of the window.
So, I ask: If the window was just opened, how would the event loop know ist size?
I think the size event is the right way to do it.
If the size changes later, then a new size event will give this info to the event loop.
As an old VB programmer, I remember when a "Form" was created, there was a size event too.
Re: [PBv5.30b2] Missing #PB_Event_SizeWindow Event On Startu
Posted: Fri Jun 06, 2014 10:19 pm
by grabiller
acreis wrote:../.. But I think that in an event driven model, the size event has a purpose: it lets the event loop knows what is the size of the window ../..
Of course it has a purpose. What the point proposing an event driven model if it is to remove harmless fundamental events ?
Having a size event on window creation is (should be) a fundamental behavior in an event driven model.
The thing is I'm not sure it is decided if PB should be really event driven or purely procedural. Or half both.
acreis wrote:As was pointed out by Fred, many users believe that this event should not occur when opening a window.
And many users believe Elvis Presley is not dead, so we should all believe he is alive right ?
I still think it's a stupid decision, indeed.
acreis wrote:I think it's not polite to qualify as stupid the purebasic team decision about the size event.
No disrespect toward Fred, and he knows it. We all do stupid mistakes or take stupid decisions sometimes. I do. You do. He does.
I respect Fred a lot, and I like PureBasic a lot, but Fred is stubborn, and I know it.
What the point removing an event because one user complain about it, an event that can simply be ignored, an event that do absolutely no harm if still present ?
And why removing real-time size event while keeping real-time size callbacks !? To remove flickering ? So flickering is removed with events but not with callback ? Common.. This is absolutely stupid!
Flickering has nothing to do with the size event ! It's like hiding a problem by removing a feature that shows the problem (but then again, why keep the callback !?).
Why not removing Windows at all then ? We would only use OpenScreen, no more flickering!
No, really.. this does not make sense, at all.
It is so obvious.
Cheers,
Guy.
Re: [PBv5.30b2] Missing #PB_Event_SizeWindow Event On Startu
Posted: Fri Jun 06, 2014 10:39 pm
by rsts
acreis wrote:I think it's not polite to qualify as stupid the purebasic team decision about the size event.
Maybe "Ill advised"?
acreis wrote:As was pointed out by Fred, many users believe that this event should not occur when opening a window.
I believe it was a "vocal few" not "many".
I agree with grabiller, it was [s]a stupid[/s] an ill advised decision.
Re: [PBv5.30b2] Missing #PB_Event_SizeWindow Event On Startu
Posted: Sat Jun 07, 2014 5:31 am
by GJ-68
Not a problem for me, I always hide the window during initialization.
Code: Select all
OpenWindow(#MainForm, ..., ..., ..., ..., ..., ...|#PB_Window_Invisible)
; GUI initialization goes here
...
...
HideWindow(#MainForm, 0) ; <- #PB_Event_SizeWindow fired here
Re: [PBv5.30b2] Missing #PB_Event_SizeWindow Event On Startu
Posted: Sat Jun 07, 2014 9:30 am
by HeX0R
I'm also not happy with the new way PB is doing the sizing.
I have serious problems in converting my current project to PB5.30, because I use quite some linked lists in it.
In the past I didn't had to care about securing my lists, and I thought using BindEvent is no big deal.
But the big advantage of the event driven system gets lost, those events fire in the middle of my other code and I have to secure anything.
Don't like this decision at all!
Re: [PBv5.30b2] Missing #PB_Event_SizeWindow Event On Startu
Posted: Sat Jun 07, 2014 12:43 pm
by Fred
I see no problem to put back the #PB_Window_SizeEvent at window opening if it was that useful. I will need to add it on other OS as well for consistency.
Re: [PBv5.30b2] Missing #PB_Event_SizeWindow Event On Startu
Posted: Sat Jun 07, 2014 2:06 pm
by freak
@grabiller
You should maybe come down from your high horse since it is obvious that you don't really understand the issue (with regards to real-time sizing) at all.
There seems to be a lot of disinformation/confusion about the real-time size event floating around, so let me clear this up a bit.
How it works in Windows (and also in OSX):
Windows uses callbacks to dispatch events. The main event loop is only there to dispatch events and usually not used to handle the events directly. This is generally not a problem for the PB event-loop system because you can generally also handle the events in the main loop. However, the #WM_SIZE and #WM_MOVE Windows events (and some others too) are different: Once the user starts draging the window edge to do a resize, control does not return to the main loop until the user finishes draging. Instead, Windows repeatedly calls the callback to inform about the ongoing sizing activity. The main loop only gets control at the end of the sizing.
How it worked in PB before 5.30:
Since there was no BindEvent() in PB before 5.20, this behavior presented a real problem, because there was no way to react to sizing events while the window edge was dragged with PB only means. You needed a Window callback to do it. To solve this problem, I actually did a little bit of reverse-engineering to figure out which messages Windows sends during the resizing and re-implemented my own window resizing code that mimics the Windows behavior, but gives control back to the event loop. This way, no OS specific window callback was needed to properly handle size events.
I did this way back when Windows XP was new and shiny. Since then, new Windows versions have come out which implemented their Sizing-Code differently and it is hard to keep imitating it correctly. You can see that there are differences with the PB version even since Windows Vista, because PB windows react differently to the "drag a Window to the edge of the screen" resizing functionality that was introduced there. Furthermore, since Windows 7 or 8, there are these flickering issues which are hard to overcome with our custom sizing hack. I do not have to tell you that trying to reverse-engineer such code is not a good idea in the long term. This is why we were never really happy with this solution, but before 5.20, there was simply no other way. The "flickering" issue describe in the 5.30 announcement is only the most visible result of a generally bad solution.
Why we changed it in 5.30:
I already wrote why the solution is bad. Since release 5.20 we now have the BindEvent() command which is a PB only and cross-platform method to register an event callback. This is why we removed the above hack in favor of the native solutions. This way, PB created windows once again act 100% like other Windows in terms of resiting behavior and the solution is future proof.
What changed:
All you have to do is to move your resize code from the main loop into a procedure and call BindEvent() for it. You then once again get all events like you did before. Nothing has been removed. Only the method of event delivery has changed.
> But the big advantage of the event driven system gets lost, those events fire in the middle of my other code and I have to secure anything.
This not true: The BindEvent procedures are only called while you are inside of a WaitWindowEvent() or WindowEvent() call. They are sometimes also called from functions that change the GUI (if this change directly generates an event). However, they are never called "in the middle of your code". There is no multi-threading going on here, so there is no need to secure anything in the event callbacks.
Re: [PBv5.30b2] Missing #PB_Event_SizeWindow Event On Startu
Posted: Sat Jun 07, 2014 2:42 pm
by grabiller
Fred wrote:I see no problem to put back the #PB_Window_SizeEvent at window opening if it was that useful. I will need to add it on other OS as well for consistency.
That would be really appreciated. And if done consistently across OS, I firmly believe that would be the best choice.
Re: [PBv5.30b2] Missing #PB_Event_SizeWindow Event On Startu
Posted: Sat Jun 07, 2014 2:59 pm
by Danilo
grabiller wrote:That would be really appreciated. And if done consistently across OS, I firmly believe that would be the best choice.
If you place your gadgets on the correct x/y position already, you don't need/want that event.
In this case it would re-position the already correctly positioned gadgets again.
What's the problem with calling your resize procedure manually?
Code: Select all
Procedure Win1_Resize()
Debug "Win1_Resize()"
ResizeGadget(1,10,10,WindowWidth(1)-20,WindowHeight(1)-20)
EndProcedure
If OpenWindow(1, 0, 0, 220, 100, "Win1",
#PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_SizeGadget|#PB_Window_Invisible)
BindEvent(#PB_Event_SizeWindow,@Win1_Resize())
ListViewGadget(1,10,10,WindowWidth(1)-20,WindowHeight(1)-20)
For i = 1 To 100:AddGadgetItem(1,-1,"ListViewGadget Line "+i):Next
HideWindow(1,0)
;Win1_Resize() ; you can call resize anytime manually
;PostEvent(#PB_Event_SizeWindow,1,0)
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Re: [PBv5.30b2] Missing #PB_Event_SizeWindow Event On Startu
Posted: Sat Jun 07, 2014 3:22 pm
by grabiller
freak wrote:@grabiller
You should maybe come down from your high horse since it is obvious that you don't really understand the issue (with regards to real-time sizing) at all.
I'm not on my "high horse" but I certainly have a tendency to react emotionally when confronted to decisions that I find not justified or illogical. That's me and I apology if my comments are misinterpreted (yet knowing that english is not my native tongue). That said, I don't pretend I understand everything, but being a C/C++ developer myself, I think I understand enough to stand by my comments regarding real-time sizing,
from a PB user point of view.
And I think this last point is what
you don't understand.
You are in control of the PureBasic language, so what prevent you to internally rewire the real-time sizing binded event as a PureBasic window event/message ?
I don't think PureBasic users care to be close to how the OS works internally, I think what is more important is to have consistency, yet consistency across platforms.
freak wrote:What changed:
All you have to do is to move your resize code from the main loop into a procedure and call BindEvent() for it. You then once again get all events like you did before. Nothing has been removed. Only the method of event delivery has changed.
This comment alone comfort my comments above. I think you have no clue about what PB users feel about this kind of changes.
All we have to do is to refactor our entire code base to adapt to this kind of decisions at each PureBasic new versions.. right. I think you don't realize what that imply for us, especially on heavy projects.
I don't mind when such changes are really fundamentals, elegant and bring something really great. Like Modules for instance, which led us to refactor everything but in this case it was justified and worth the pain.
That said, this real-time sizing event issue is not really a big thing, just an annoying detail. We now have to resort to Binded events ? Ok, fine, lets do that.. Bad taste but we will swallow.
Re: [PBv5.30b2] Missing #PB_Event_SizeWindow Event On Startu
Posted: Sat Jun 07, 2014 3:34 pm
by grabiller
Danilo wrote:../.. If you place your gadgets on the correct x/y position already, you don't need/want that event.
In this case it would re-position the already correctly positioned gadgets again.
What's the problem with calling your resize procedure manually?
Let me rephrase your question, if you don't mind:
If you do it manually on your side, what's the problem having this first size event triggered on startup ? Why do you care ?
I mean, does it has any impact on your own code ?
On the opposite, removing this first event
do has some impact on some existing user code. Simple as that.
So what the point removing this event at all in the first place ? What is the benefit ?