Section 2 - Desktop Areas as opposed to multiple desktops.

The best way to explain this is as follows. Desktops are completely geometrically disjoint workspaces. They have no geometric relevance to each other in terms of the client window plane. Desktop Areas have geometric relevance - they are next to, above or below each other. The best examples are FVWM's desktops and virtual desktops - you can have multiple desktops that are disjoint and each desktop can be N x M screens in size - these N x M areas are what are termed ``desktop areas'' for the purposes of this document and the WM API.

If your WM supports both methods like FVMW, Enlightenment and possible others, you should use _WIN_WORKSPACE messages and atoms for the geometrically disjoint desktops - for geometrically arranged desktops you should use the _WIN_AREA messages and atoms. if you only support one of these it is preferable to use _WIN_WORKSPACE only.

The APi for _WIN_AREA is very similar to _WIN_WORKSPACE. To advertise the size of your areas (ie N x M screens in size) you set an atom on the root window as follows:

  Display            *disp;
  Window              root;
  Atom                atom_set;
  CARD32              val[2];
    
  atom_set = XInternAtom(disp, "_WIN_AREA_COUNT", False);
  val[0] = number_of_screens_horizontally;
  val[1] = number_of_screens_vertically;
  XChangeProperty(disp, root, atom_set, XA_CARDINAL, 32, PropModeReplace,
                  (unsigned char *)val, 2);
 

To advertise which desktop area is the currently active one:

  Display            *disp;
  Window              root;
  Atom                atom_set;
  CARD32              val[2];

  atom_set = XInternAtom(disp, "_WIN_AREA", False);
  val[0] = current_active_area_x; /* starts at 0 */
  val[1] = current_active_area_y; /* starts at 0 */
  XChangeProperty(disp, root, atom_set, XA_CARDINAL, 32, PropModeReplace,
                  (unsigned char *)val, 2);
 

If a client wishes to change what the current active area is they simply send a client message like:

  Display            *disp;
  Window              root;
  XClientMessageEvent xev;
  
  xev.type = ClientMessage;
  xev.window = root;
  xev.message_type = XInternAtom(disp, "_WIN_AREA", False);
  xev.format = 32;
  xev.data.l[0] = new_active_area_x;
  xev.data.l[0] = new_active_area_y;
  XSendEvent(disp, root, False, SubstructureNotifyMask, (XEvent *) );