[Bf-committers] Blender Window manager doc

Ton Roosendaal ton at blender.org
Fri Dec 3 14:54:12 CET 2004


Hi,

Checking on a bug report I noticed again the flaws in the python Window  
module...
This module was added sometime long ago, and expanded with calls  
later... it has become one of the most popular modules to play with,  
but its design really conflicts with how Blender's window manager is  
intended to work.
This - of course - as a result of a total lack of any documentation on  
this issue, something that should be solved once. So here we go! :)


1) Screens/Areas/Windows
Blender has its own full functional window manager. The subdividision  
UI concept Blender was based on demanded development of such a system.
On the top level of the window manager you can find the "Screen", which  
actually just is the "window" in the OS Desktop environment. The Screen  
again is subdivided into "Areas", which act as a "sub window". (Back  
then I've choosen the words "Screen" and "Area" mostly to prevent  
confusement with much the abused word "window".)

In the very first incarnation of Blender (1.0) control over drawing of  
Areas was left to the "sub window" feature the Irix window manager  
offered. This is available in X11 and other windowmangers too btw.  
After a while I decided to drop this, mostly because using many  
sub-windows within a main window is handled extremely slow. Speed is  
comparable to a single application trying to manage like 10-20 separate  
windows, causing a lot of system overhead. One full redraw of a new  
Screen setup took seconds (a slowness you can now still watch in Modo  
btw, they apparently didn't copy Blender completely yet ;-).

Instead I found a way to completely mimic sub-windows with OpenGL  
features. By using the glScissor() and glViewPort() combo you can  
effectively achieve that. Code for that resides in the src/mywindow.c  
file. Note that there you find still find wrappers for the former  
sub-window system, introducing a 'bWindow' layer.

So in this stage, the first confusion was already introduced, mixing up  
"Area" features with "bWindow" ones... and to make the whole system  
even more interesting, the port to Glut was added on top of that again,  
and later on the port to Ghost. The wrapping from "bWindow" to  
GhostWindow is done with another "Window" being defined in  
ghostwinlay.c. So we now have the very interesting series of wrappers:

System Window  <-> GHOST_Window  <->   Window   <->   bWindow   <->    
ScrArea
(OS specific)      (Ghost lib)     (ghostwinlay.c)  (mywindow.c)     
(editscreen.c)

Especially the way how the renderwindow is hacked into this system is a  
total nightmare, with even code comments like "Do not ever release this  
after 2.23!"). This was part of a restructuring process never even  
finished...

The obvious wrapper series should be something like this:

System Window  <-> GHOST_Window  <->  Screen

Making the "render output window" just an Area in a Screen, or as a new  
(system) Window with a Screen, and thus allowing multiple Screens to be  
opened in separate windows (dual monitor purpose for example).

2) Areas and Spaces

Within the Blender universe the "active window" therefore is just the  
active Area, the part within the subdivided Screen where input goes to  
or output has to be drawn. The editscreen.c code manages this, defining  
which area is currently active for input, and what areas need to be  
redrawn, and in what situations a full or partial swapbuffers should be  
done.

For that reason Areas have their own event queues, and (function  
pointers) callbacks for queue handling and drawing. The Screen system  
reads the main queues, distributes it to the areas, executes the queue  
callbacks, and for proper swapbuffering also can execute redraws.
This all goes well balanced, buffering queue overloading to prevent 100  
redraws to be executed 100 times as well.

The Blender "Space" is another new definition to prevent the word  
"window". Decided was to fully separate the application that runs  
within an Area from the Screen/Area system itself. This allows each  
Area to transparently run any application, which is an important  
feature in Blender (changing "window" type). A space is simply  
definined by the following items;

- a SpaceXXX struct to hold persistant data. Data that's relevant for  
saving in a file, for copying or restoring.
- functions to allocate, free or copy SpaceXXX structs
- a winhandle() callback for handling the Area events
- a windraw() callback for the full (re)drawing
- a winchange() callback for reinitializing windowsize or other changes

Each area is allowed to store a SpaceXXX struct for each Space type (in  
a list), which enables proper restoring when applications change in an  
area. For example when you invoke the SpaceFile, it can safely return  
to its previous SpaceView3D type without any change in its settings.

Another important aspect is that any Space is supposed to run fully  
local. It is not (should not) be aware of any other editors that are  
open, nor read data from it, nor access them to change data. The Spaces  
should be treated as individual applications, storing settings in their  
own SpaceXXX structs, and only working on what the Blender database is  
providing, or what the Screen defines to be the active context (like  
active Scene, Object, etc).

(Read the notes on the Blender architecture for more about this).

There's still no good protocol or document on adding new Space types,  
but in theory it is possible to hook up any application with Blender  
this way. Using the callback structure it can even be plug-inned...  
think for example what would happen to have a web browser or text  
editor or terminal running there. Your own deskop environment! :)

Blender is far from perfect, so you can also find ancient abuses of the  
system, especially in using global settings... like for example Edit  
Mode or FaceSelect. The implementation of tools in the Buttons window  
is another exception, the tools actually work in a 3d window, but are  
accessed from another Space type. Cleaning up such issues is also part  
of the 2.3 UI project, with attempts to keep the used context as clean  
as obvious as possible.

In most situations it works well though, with individual Spaces only  
communicating with each other by sending out events to the Screen  
manager, which distributes it over the other Areas again.

3) The ugly struct Global

The goal of any good structured program is to limit usage of global  
variables to an absolute minimum (yes, lessons learnt :). One reason  
why it's good to have them in struct Global is as punishment, since it  
forces a full recompile. Another reason is to keep things together that  
way, prevents unpleasant surprises.

Since - right now - only 1 screen is in use or displayed in a time,  
Blender's Screen manager puts "helpful" global variables in the G  
struct too.

What you can see all over the code is usage of "G.vd" or "G.sipo" and  
so on... these are the pointers to the *active* SpaceXXX structure, and  
is being set by the Screen manager on mousemoves and when the Areas  
handle their queues or redraws.
Any code that uses these variables has to be 100% certain belong to its  
own Space type. No G.vd (View3D) access should be allowed in Buttons,  
or Fileselect, or Script space, since that's undefined then (or can  
even be zero). It's a common mistake in Blender code - I even violated  
it sometimes - and it always were reasons for bugs or crashes. The  
Python Window module also abuses that, and this should be removed  
a.s.a.p. :)

These variables actually belong to the "Screen context", and will be  
recoded to go there once.

4) How to move on

There's clearly work to be done on the following areas:

- remove the ridiculous 5 level deep wrapping of the "window" concept.
- design a new method for Spaces to handle queues (using dynamic event  
handlers)
- design a method for how Python scripts can be attached to any Space  
type (probably by just becoming an event handler!)

So, that's the lecture for today, back to the bugs! :)

-Ton-

------------------------------------------------------------------------ 
--
Ton Roosendaal  Blender Foundation ton at blender.org  
http://www.blender.org



More information about the Bf-committers mailing list