After some reading regarding of using _NET_WM_WINDOW_OPACITY in Busy
and Composite, I finally figures out how to do it right.
Here is the detailed explanation (long):

1. Hierarchy of windows in X.
  Windows in X is just like NSView in NSWindow. Every NSView in NSWindow
  is subview of the content view of NSWindow. Every X window is child
of root window.
  If there it NO window manager running and an application create a X
window (client window)
  that client window is a direct child of root window.
  The hierarchy is: root window -> client window
  When window manager is running. things become complicate.
  The application still creats the client window exactly the same,
with or without window manager.
  So the application programmingly creates a client window as direct
child of root window.
  But window manager notice that and try to manage that client window.
  Window manager create another X window (frame window) as direct
child of root window,
  and move client window as a chilrd of frame window.
  It is called reparenting.
  The hierarchy becomes: root window -> frame window -> client window.
  Frame window is usually bigger than client window so that it can
draw title bar on top, etc.
  By design, some window manager, like Azalea, actually has this hierarchy:
  root window -> frame window -> plate window -> client window.
  The plate window is also created by Azalea with the same size of
client window.
  Plate window is for conveniency of Azalea, nothing more.
  So in this case, client window have two parents beside root window.

2. Event dispatch
  X event dispatch is like NSNotificationCenter.
  Every application can register to listen to any event for any window.
  Normally application only listen to event for its own window (client window).
  But window manager listen to all the events to all the window, like
wiretapping.

3. Comminucation between windows
  Frame window is created and listened by window manager
  while client window is created and listened by application,
  how does window manager know application want to change its title bar ?
  And how does window manager notify application that users change the
size of frame window and application should resize its client window
according ?
  The answer is to send event to each other's window.
  For example, if application want to change the title on frame window
  and since window manager always listen to root window,
  it can send an event to root window saying "I am client window A, I
want to change my title and the new title text is ..."
  and window manager will change the text on title bar according.
  If users change the size of frame window, window manager will send an event
  to client window saying "the new size is ..." and application will
redraw the content.
  By sending event to each other's window, applications and window
manager can comminucate with each other.

4. How to find the right window ?
  Window manager know every X window in the system.
  But how about that application A want to send an event to application B
  through application B's client window ?
  Well, it can find out the children of root window easily with XQueryTree.
  But unfortunately, children of root window is frame windows created
by window manager,
  and application only listen to its client window, which is child (or
grand child) of frame window.
  And application has no idea how many parents the client window have
  and don't know which one is the client window, not frame window or
plate window.
  So at most, it can only find out the frame window and send event to
frame window
  because frame window is the direct child of root window.
  Then window manager come to rescue.
  Application A will send a "Client Message" to root window, specify
which frame window it want to talk to (XSendEvent).
  Once window manager receive this "Client Message",
  it transfers this event to the client window and application B will
receive it.

  If there is no window manager, this "client message" will not work
  because there is no window manager to transfer the message.
  But if there is no window manager, the chilren of root window
  will be client windows !!
  So application A can just set the property of application B's client
window straight (XChangeProperty).

  Therefore, you often see that application A do two things to notify
application B:
  1. use XChangeProperty() in case there is no window manager.
  2. use XSendEvent() in case there is window manager.

  There is another way to get a list of clients:
  _NET_CLIENT_LIST and _NET_CLIENT_LIST_STACKING.
  It is a list of *client window* and is organized by window manager.
  So instead of using XQueryTree, _NET_CLIENT_LIST gives
  you a list of *client window* which you can talk to straight.

5. Busy, window manager, composite manager and application.

  This is an example of how things *should* work.

  A) Busy uses _NET_CLIENT_LIST_STACKING to get a list of client
windows and send _NET_WM_PING to each client window. Each client
(application) should reply in a short time, otherwise, it is treated
as non-response client.
  B) Once Busy know which client window does not respond, Busy want to
tell composite manager to change translucency of non-response window.
  C) Therefore, Busy send a "Client Message" to root window, telling
window manager which client window does not response.
  D) Window manager receive Busy's notification from root window and
chage the _NET_WM_WINDOW_OPACITY on the frame window of non-response
client window
  (Remember the hierarchy: root window -> frame window -> plate window
-> client window)
  E) Composite manager receive the _NET_WM_WINDOW_OPACITY from frame
window and chage translucency of frame window.

  (Note: Composite manager is listening to frame window, not client window).

  Current implementation is slightly different from what i describe.
  While it is a very minor issue,
  I will change it after the refectory of Composite is done.
  Hope this explanation make things clear.

  Yen-Ju

_______________________________________________
Etoile-dev mailing list
[email protected]
https://mail.gna.org/listinfo/etoile-dev

Reply via email to