Merge branch 'backport' into work
authorDana Jansens <danakj@orodu.net>
Thu, 31 Jan 2008 17:36:06 +0000 (12:36 -0500)
committerDana Jansens <danakj@orodu.net>
Thu, 31 Jan 2008 17:51:38 +0000 (12:51 -0500)
Conflicts:

openbox/client.c
openbox/config.c
openbox/event.c
openbox/extensions.c
openbox/focus_cycle_indicator.c
openbox/focus_cycle_popup.c
openbox/menuframe.c
openbox/moveresize.c
openbox/openbox.c
openbox/screen.c
openbox/stacking.c
openbox/startupnotify.c

24 files changed:
1  2 
.gitignore
Makefile.am
data/rc.xml
openbox/actions.c
openbox/actions/execute.c
openbox/client.c
openbox/client_menu.c
openbox/config.c
openbox/config.h
openbox/dock.c
openbox/event.c
openbox/focus_cycle_indicator.c
openbox/focus_cycle_popup.c
openbox/frame.c
openbox/framerender.c
openbox/menuframe.c
openbox/menuframe.h
openbox/moveresize.c
openbox/openbox.c
openbox/popup.c
openbox/screen.c
openbox/stacking.c
openbox/startupnotify.c
render/theme.c

diff --cc .gitignore
@@@ -44,9 -44,11 +44,12 @@@ po/insert-header.si
  po/quot.sed
  po/remove-potcdate.sin
  po/stamp-po
+ po/en@boldquot.insert-header
+ po/en@quot.insert-header
+ po/remove-potcdate.sed
  *.gmo
 -render/obrender-3.0.pc
 +render/obrender-4.0.pc
 +obt/obt-4.0.pc
  tools/gnome-panel-control/gnome-panel-control
  version.h
  .libs
diff --cc Makefile.am
Simple merge
diff --cc data/rc.xml
Simple merge
Simple merge
@@@ -2,9 -2,12 +2,13 @@@
  #include "openbox/event.h"
  #include "openbox/startupnotify.h"
  #include "openbox/screen.h"
 +#include "obt/paths.h"
  #include "gettext.h"
  
+ #ifdef HAVE_STDLIB_H
+ #  include <stdlib.h>
+ #endif
  typedef struct {
      gchar   *cmd;
      gboolean sn;
@@@ -288,9 -292,14 +291,14 @@@ void client_manage(Window window
      ob_debug("Window type: %d\n", self->type);
      ob_debug("Window group: 0x%x\n", self->group?self->group->leader:0);
  
+     /* now we have all of the window's information so we can set this up.
+        do this before creating the frame, so it can tell that we are still
+        mapping and doesn't go applying things right away */
+     client_setup_decor_and_functions(self, FALSE);
      /* specify that if we exit, the window should not be destroyed and
         should be reparented back to root automatically */
 -    XChangeSaveSet(ob_display, window, SetModeInsert);
 +    XChangeSaveSet(obt_display, window, SetModeInsert);
  
      /* create the decoration frame for the client window */
      self->frame = frame_new(self);
@@@ -1805,38 -1809,38 +1811,38 @@@ static void client_change_allowed_actio
  
      /* desktop windows are kept on all desktops */
      if (self->type != OB_CLIENT_TYPE_DESKTOP)
 -        actions[num++] = prop_atoms.net_wm_action_change_desktop;
 +        actions[num++] = OBT_PROP_ATOM(NET_WM_ACTION_CHANGE_DESKTOP);
  
      if (self->functions & OB_CLIENT_FUNC_SHADE)
 -        actions[num++] = prop_atoms.net_wm_action_shade;
 +        actions[num++] = OBT_PROP_ATOM(NET_WM_ACTION_SHADE);
      if (self->functions & OB_CLIENT_FUNC_CLOSE)
 -        actions[num++] = prop_atoms.net_wm_action_close;
 +        actions[num++] = OBT_PROP_ATOM(NET_WM_ACTION_CLOSE);
      if (self->functions & OB_CLIENT_FUNC_MOVE)
 -        actions[num++] = prop_atoms.net_wm_action_move;
 +        actions[num++] = OBT_PROP_ATOM(NET_WM_ACTION_MOVE);
      if (self->functions & OB_CLIENT_FUNC_ICONIFY)
 -        actions[num++] = prop_atoms.net_wm_action_minimize;
 +        actions[num++] = OBT_PROP_ATOM(NET_WM_ACTION_MINIMIZE);
      if (self->functions & OB_CLIENT_FUNC_RESIZE)
 -        actions[num++] = prop_atoms.net_wm_action_resize;
 +        actions[num++] = OBT_PROP_ATOM(NET_WM_ACTION_RESIZE);
      if (self->functions & OB_CLIENT_FUNC_FULLSCREEN)
 -        actions[num++] = prop_atoms.net_wm_action_fullscreen;
 +        actions[num++] = OBT_PROP_ATOM(NET_WM_ACTION_FULLSCREEN);
      if (self->functions & OB_CLIENT_FUNC_MAXIMIZE) {
 -        actions[num++] = prop_atoms.net_wm_action_maximize_horz;
 -        actions[num++] = prop_atoms.net_wm_action_maximize_vert;
 +        actions[num++] = OBT_PROP_ATOM(NET_WM_ACTION_MAXIMIZE_HORZ);
 +        actions[num++] = OBT_PROP_ATOM(NET_WM_ACTION_MAXIMIZE_VERT);
      }
      if (self->functions & OB_CLIENT_FUNC_ABOVE)
 -        actions[num++] = prop_atoms.net_wm_action_above;
 +        actions[num++] = OBT_PROP_ATOM(NET_WM_ACTION_ABOVE);
      if (self->functions & OB_CLIENT_FUNC_BELOW)
 -        actions[num++] = prop_atoms.net_wm_action_below;
 +        actions[num++] = OBT_PROP_ATOM(NET_WM_ACTION_BELOW);
      if (self->functions & OB_CLIENT_FUNC_UNDECORATE)
 -        actions[num++] = prop_atoms.ob_wm_action_undecorate;
 +        actions[num++] = OBT_PROP_ATOM(OB_WM_ACTION_UNDECORATE);
  
 -    PROP_SETA32(self->window, net_wm_allowed_actions, atom, actions, num);
 +    OBT_PROP_SETA32(self->window, NET_WM_ALLOWED_ACTIONS, ATOM, actions, num);
  
--   /* make sure the window isn't breaking any rules now
++    /* make sure the window isn't breaking any rules now
  
--   don't check ICONIFY here.  just cuz a window can't iconify doesnt mean
--   it can't be iconified with its parent
--   */
++       don't check ICONIFY here.  just cuz a window can't iconify doesnt mean
++       it can't be iconified with its parent
++    */
  
      if (!(self->functions & OB_CLIENT_FUNC_SHADE) && self->shaded) {
          if (self->frame) client_shade(self, FALSE);
@@@ -2081,16 -2090,32 +2093,32 @@@ void client_update_icons(ObClient *self
          g_free(self->icons);
      self->nicons = 0;
  
 -    if (PROP_GETA32(self->window, net_wm_icon, cardinal, &data, &num)) {
 +    if (OBT_PROP_GETA32(self->window, NET_WM_ICON, CARDINAL, &data, &num)) {
          /* figure out how many valid icons are in here */
          i = 0;
-         while (num - i > 2) {
-             w = data[i++];
-             h = data[i++];
-             i += w * h;
-             if (i > num || w*h == 0) break;
-             ++self->nicons;
-         }
+         num_seen = num_small_seen = 0;
+         smallest = smallest_area = 0;
+         if (num > 2)
+             while (i < num) {
+                 w = data[i++];
+                 h = data[i++];
+                 i += w * h;
+                 /* watch for it being too small for the specified size, or for
+                    zero sized icons. */
+                 if (i > num || w == 0 || h == 0) break;
+                 if (!smallest_area || w*h < smallest_area) {
+                     smallest = num_seen;
+                     smallest_area = w*h;
+                 }
+                 ++num_seen;
+                 if (w <= AVOID_ABOVE && h <= AVOID_ABOVE)
+                     ++num_small_seen;
+             }
+         if (num_small_seen > 0)
+             self->nicons = num_small_seen;
+         else if (num_seen)
+             self->nicons = 1;
  
          self->icons = g_new(ObClientIcon, self->nicons);
  
@@@ -2178,12 -2218,13 +2221,14 @@@ void client_update_icon_geometry(ObClie
  
      RECT_SET(self->icon_geometry, 0, 0, 0, 0);
  
 -    if (PROP_GETA32(self->window, net_wm_icon_geometry, cardinal, &data, &num))
 +    if (OBT_PROP_GETA32(self->window, NET_WM_ICON_GEOMETRY, CARDINAL,
-                         &data, &num) && num == 4)
++                        &data, &num))
      {
-         /* don't let them set it with an area < 0 */
-         RECT_SET(self->icon_geometry, data[0], data[1],
-                  MAX(data[2],0), MAX(data[3],0));
+         if (num == 4)
+             /* don't let them set it with an area < 0 */
+             RECT_SET(self->icon_geometry, data[0], data[1],
+                      MAX(data[2],0), MAX(data[3],0));
+         g_free(data);
      }
  }
  
Simple merge
@@@ -476,16 -486,21 +476,20 @@@ static void parse_placement(xmlNodePtr 
  
      node = node->children;
  
 -    if ((n = parse_find_node("policy", node)))
 -        if (parse_contains("UnderMouse", doc, n))
 +    if ((n = obt_parse_find_node(node, "policy")))
 +        if (obt_parse_node_contains(n, "UnderMouse"))
              config_place_policy = OB_PLACE_POLICY_MOUSE;
 -    if ((n = parse_find_node("center", node)))
 -        config_place_center = parse_bool(doc, n);
 -    if ((n = parse_find_node("monitor", node))) {
 -        if (parse_contains("active", doc, n))
 +    if ((n = obt_parse_find_node(node, "center")))
 +        config_place_center = obt_parse_node_bool(n);
-     if ((n = obt_parse_find_node(node, "active")))
-         config_place_active = obt_parse_node_bool(n);
++    if ((n = obt_parse_find_node(node, "monitor"))) {
++        if (obt_parse_node_contains(n, "active"))
+             config_place_monitor = OB_PLACE_MONITOR_ACTIVE;
 -        else if (parse_contains("mouse", doc, n))
++        else if (obt_parse_node_contains(n, "mouse"))
+             config_place_monitor = OB_PLACE_MONITOR_MOUSE;
+     }
  }
  
 -static void parse_margins(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
 -                          gpointer data)
 +static void parse_margins(xmlNodePtr node, gpointer d)
  {
      xmlNodePtr n;
  
@@@ -589,13 -606,13 +593,13 @@@ static void parse_desktops(xmlNodePtr n
  
      node = node->children;
  
 -    if ((n = parse_find_node("number", node))) {
 -        gint d = parse_int(doc, n);
 +    if ((n = obt_parse_find_node(node, "number"))) {
 +        gint d = obt_parse_node_int(n);
          if (d > 0)
-             config_desktops_num = d;
+             config_desktops_num = (unsigned) d;
      }
 -    if ((n = parse_find_node("firstdesk", node))) {
 -        gint d = parse_int(doc, n);
 +    if ((n = obt_parse_find_node(node, "firstdesk"))) {
 +        gint d = obt_parse_node_int(n);
          if (d > 0)
              config_screen_firstdesk = (unsigned) d;
      }
@@@ -870,9 -890,9 +874,9 @@@ void config_startup(ObtParseInst *i
  
      config_place_policy = OB_PLACE_POLICY_SMART;
      config_place_center = TRUE;
-     config_place_active = FALSE;
+     config_place_monitor = OB_PLACE_MONITOR_ANY;
  
 -    parse_register(i, "placement", parse_placement, NULL);
 +    obt_parse_register(i, "placement", parse_placement, NULL);
  
      STRUT_PARTIAL_SET(config_margins, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  
Simple merge
diff --cc openbox/dock.c
@@@ -519,13 -528,16 +522,16 @@@ void dock_configure(void
  
          RrPaint(dock->a_frame, dock->frame, dock->area.width,
                  dock->area.height);
 -        XMapWindow(ob_display, dock->frame);
 +        XMapWindow(obt_display, dock->frame);
      } else
 -        XUnmapWindow(ob_display, dock->frame);
 +        XUnmapWindow(obt_display, dock->frame);
  
-     /* but they are useful outside of this function! */
-     dock->area.width += ob_rr_theme->obwidth * 2;
-     dock->area.height += ob_rr_theme->obwidth * 2;
+     /* but they are useful outside of this function! but don't add it if the
+        dock is actually not visible */
+     if (dock->dock_apps) {
+         dock->area.width += ob_rr_theme->obwidth * 2;
+         dock->area.height += ob_rr_theme->obwidth * 2;
+     }
  
      screen_update_areas();
  
diff --cc openbox/event.c
@@@ -268,8 -269,9 +268,9 @@@ static void event_hack_mods(XEvent *e
          /* If XKB is present, then the modifiers are all strange from its
             magic.  Our X core protocol stuff won't work, so we use this to
             find what the modifier state is instead. */
 -        if (XkbGetState(ob_display, XkbUseCoreKbd, &xkb_state) == Success)
 +        if (XkbGetState(obt_display, XkbUseCoreKbd, &xkb_state) == Success)
-             e->xkey.state = xkb_state.compat_state;
+             e->xkey.state =
 -                modkeys_only_modifier_masks(xkb_state.compat_state);
++                obt_keyboard_only_modmasks(xkb_state.compat_state);
          else
  #endif
          {
@@@ -1929,8 -1928,7 +1930,7 @@@ void event_halt_focus_delay(void
  
  gulong event_start_ignore_all_enters(void)
  {
-     XSync(obt_display, FALSE);
-     return LastKnownRequestProcessed(obt_display);
 -    return NextRequest(ob_display);
++    return NextRequest(obt_display);
  }
  
  static void event_ignore_enter_range(gulong start, gulong end)
                    r->start, r->end);
  
      /* increment the serial so we don't ignore events we weren't meant to */
-     XSync(obt_display, FALSE);
 -    PROP_ERASE(screen_support_win, motif_wm_hints);
++    OBT_PROP_ERASE(screen_support_win, MOTIF_WM_HINTS);
  }
  
  void event_end_ignore_all_enters(gulong start)
  {
-     XSync(obt_display, FALSE);
-     event_ignore_enter_range(start, LastKnownRequestProcessed(obt_display));
+     /* Use (NextRequest-1) so that we ignore up to the current serial only.
+        Inside event_ignore_enter_range, we increment the serial by one, but if
+        we ignore that serial too, then any enter events generated by mouse
+        movement will be ignored until we create some further network traffic.
+        Instead ignore up to NextRequest-1, then when we increment the serial,
+        we will be *past* the range of ignored serials */
 -    event_ignore_enter_range(start, NextRequest(ob_display)-1);
++    event_ignore_enter_range(start, NextRequest(obt_display)-1);
  }
  
  static gboolean is_enter_focus_event_ignored(XEvent *e)
@@@ -166,7 -167,10 +167,10 @@@ void focus_cycle_draw_indicator(ObClien
          w = c->frame->area.width;
          h = wt;
  
 -        XMoveResizeWindow(ob_display, focus_indicator.top.win,
+         /* kill enter events cause by this moving */
+         ignore_start = event_start_ignore_all_enters();
 +        XMoveResizeWindow(obt_display, focus_indicator.top.window,
                            x, y, w, h);
          a_focus_indicator->texture[0].data.lineart.x1 = 0;
          a_focus_indicator->texture[0].data.lineart.y1 = h-1;
          a_focus_indicator->texture[3].data.lineart.y1 = 0;
          a_focus_indicator->texture[3].data.lineart.x2 = w - wr;
          a_focus_indicator->texture[3].data.lineart.y2 = 0;
 -        RrPaint(a_focus_indicator, focus_indicator.bottom.win,
 +        RrPaint(a_focus_indicator, focus_indicator.bottom.window,
                  w, h);
  
 -        XMapWindow(ob_display, focus_indicator.top.win);
 -        XMapWindow(ob_display, focus_indicator.left.win);
 -        XMapWindow(ob_display, focus_indicator.right.win);
 -        XMapWindow(ob_display, focus_indicator.bottom.win);
 +        XMapWindow(obt_display, focus_indicator.top.window);
 +        XMapWindow(obt_display, focus_indicator.left.window);
 +        XMapWindow(obt_display, focus_indicator.right.window);
 +        XMapWindow(obt_display, focus_indicator.bottom.window);
  
+         event_end_ignore_all_enters(ignore_start);
          visible = TRUE;
      }
  }
@@@ -479,7 -480,8 +479,8 @@@ void focus_cycle_popup_hide(void
          ObFocusCyclePopupTarget *t = popup.targets->data;
  
          g_free(t->text);
 -        XDestroyWindow(ob_display, t->win);
 +        XDestroyWindow(obt_display, t->win);
+         g_free(t);
  
          popup.targets = g_list_delete_link(popup.targets, popup.targets);
      }
diff --cc openbox/frame.c
@@@ -194,36 -196,26 +194,26 @@@ ObFrame *frame_new(ObClient *client
  static void set_theme_statics(ObFrame *self)
  {
      /* set colors/appearance/sizes for stuff that doesn't change */
 -    XResizeWindow(ob_display, self->max,
 +    XResizeWindow(obt_display, self->max,
                    ob_rr_theme->button_size, ob_rr_theme->button_size);
 -    XResizeWindow(ob_display, self->iconify,
 +    XResizeWindow(obt_display, self->iconify,
                    ob_rr_theme->button_size, ob_rr_theme->button_size);
 -    XResizeWindow(ob_display, self->icon,
 +    XResizeWindow(obt_display, self->icon,
                    ob_rr_theme->button_size + 2, ob_rr_theme->button_size + 2);
 -    XResizeWindow(ob_display, self->close,
 +    XResizeWindow(obt_display, self->close,
                    ob_rr_theme->button_size, ob_rr_theme->button_size);
 -    XResizeWindow(ob_display, self->desk,
 +    XResizeWindow(obt_display, self->desk,
                    ob_rr_theme->button_size, ob_rr_theme->button_size);
 -    XResizeWindow(ob_display, self->shade,
 +    XResizeWindow(obt_display, self->shade,
                    ob_rr_theme->button_size, ob_rr_theme->button_size);
 -    XResizeWindow(ob_display, self->tltresize,
 +    XResizeWindow(obt_display, self->tltresize,
                    ob_rr_theme->grip_width, ob_rr_theme->paddingy + 1);
 -    XResizeWindow(ob_display, self->trtresize,
 +    XResizeWindow(obt_display, self->trtresize,
                    ob_rr_theme->grip_width, ob_rr_theme->paddingy + 1);
 -    XResizeWindow(ob_display, self->tllresize,
 +    XResizeWindow(obt_display, self->tllresize,
                    ob_rr_theme->paddingx + 1, ob_rr_theme->title_height);
 -    XResizeWindow(ob_display, self->trrresize,
 +    XResizeWindow(obt_display, self->trrresize,
                    ob_rr_theme->paddingx + 1, ob_rr_theme->title_height);
-     /* set up the dynamic appearances */
-     self->a_unfocused_title = RrAppearanceCopy(ob_rr_theme->a_unfocused_title);
-     self->a_focused_title = RrAppearanceCopy(ob_rr_theme->a_focused_title);
-     self->a_unfocused_label = RrAppearanceCopy(ob_rr_theme->a_unfocused_label);
-     self->a_focused_label = RrAppearanceCopy(ob_rr_theme->a_focused_label);
-     self->a_unfocused_handle =
-         RrAppearanceCopy(ob_rr_theme->a_unfocused_handle);
-     self->a_focused_handle = RrAppearanceCopy(ob_rr_theme->a_focused_handle);
-     self->a_icon = RrAppearanceCopy(ob_rr_theme->a_icon);
  }
  
  static void free_theme_statics(ObFrame *self)
Simple merge
@@@ -77,7 -78,7 +77,7 @@@ ObMenuFrame* menu_frame_new(ObMenu *men
      XSetWindowAttributes attr;
  
      self = g_new0(ObMenuFrame, 1);
-     self->type = OB_WINDOW_CLASS_MENUFRAME;
 -    self->type = Window_Menu;
++    self->obwin.type = OB_WINDOW_CLASS_MENUFRAME;
      self->menu = menu;
      self->selected = NULL;
      self->client = client;
      self->show_from = show_from;
  
      attr.event_mask = FRAME_EVENTMASK;
 -    self->window = createWindow(RootWindow(ob_display, ob_screen),
 +    self->window = createWindow(obt_root(ob_screen),
                                  CWEventMask, &attr);
  
 -    XSetWindowBorderWidth(ob_display, self->window, ob_rr_theme->mbwidth);
 -    XSetWindowBorder(ob_display, self->window,
 +    XSetWindowBorderWidth(obt_display, self->window, ob_rr_theme->mbwidth);
 +    XSetWindowBorder(obt_display, self->window,
                       RrColorPixel(ob_rr_theme->menu_border_color));
  
-     self->a_title = RrAppearanceCopy(ob_rr_theme->a_menu_title);
      self->a_items = RrAppearanceCopy(ob_rr_theme->a_menu);
  
 -    stacking_add(MENU_AS_WINDOW(self));
 +    window_add(&self->window, MENUFRAME_AS_WINDOW(self));
 +    stacking_add(MENUFRAME_AS_WINDOW(self));
  
      return self;
  }
@@@ -109,13 -108,11 +108,12 @@@ void menu_frame_free(ObMenuFrame *self
              self->entries = g_list_delete_link(self->entries, self->entries);
          }
  
 -        stacking_remove(MENU_AS_WINDOW(self));
 +        stacking_remove(MENUFRAME_AS_WINDOW(self));
 +        window_remove(self->window);
  
-         XDestroyWindow(obt_display, self->window);
          RrAppearanceFree(self->a_items);
-         RrAppearanceFree(self->a_title);
 -        XDestroyWindow(ob_display, self->window);
++        XDestroyWindow(obt_display, self->window);
  
          g_free(self);
      }
@@@ -147,41 -144,8 +145,10 @@@ static ObMenuEntryFrame* menu_entry_fra
          g_hash_table_insert(menu_frame_map, &self->bullet, self);
      }
  
 -    XMapWindow(ob_display, self->window);
 -    XMapWindow(ob_display, self->text);
 +    XMapWindow(obt_display, self->window);
 +    XMapWindow(obt_display, self->text);
 +
-     self->a_normal = RrAppearanceCopy(ob_rr_theme->a_menu_normal);
-     self->a_selected = RrAppearanceCopy(ob_rr_theme->a_menu_selected);
-     self->a_disabled = RrAppearanceCopy(ob_rr_theme->a_menu_disabled);
-     self->a_disabled_selected =
-         RrAppearanceCopy(ob_rr_theme->a_menu_disabled_selected);
-     if (entry->type == OB_MENU_ENTRY_TYPE_SEPARATOR) {
-         self->a_separator = RrAppearanceCopy(ob_rr_theme->a_clear_tex);
-         self->a_separator->texture[0].type = RR_TEXTURE_LINE_ART;
-     } else {
-         self->a_icon = RrAppearanceCopy(ob_rr_theme->a_clear_tex);
-         self->a_icon->texture[0].type = RR_TEXTURE_RGBA;
-         self->a_mask = RrAppearanceCopy(ob_rr_theme->a_clear_tex);
-         self->a_mask->texture[0].type = RR_TEXTURE_MASK;
-         self->a_bullet_normal =
-             RrAppearanceCopy(ob_rr_theme->a_menu_bullet_normal);
-         self->a_bullet_selected =
-             RrAppearanceCopy(ob_rr_theme->a_menu_bullet_selected);
-     }
-     self->a_text_normal =
-         RrAppearanceCopy(ob_rr_theme->a_menu_text_normal);
-     self->a_text_selected =
-         RrAppearanceCopy(ob_rr_theme->a_menu_text_selected);
-     self->a_text_disabled =
-         RrAppearanceCopy(ob_rr_theme->a_menu_text_disabled);
-     self->a_text_disabled_selected =
-         RrAppearanceCopy(ob_rr_theme->a_menu_text_disabled_selected);
-     self->a_text_title =
-         RrAppearanceCopy(ob_rr_theme->a_menu_text_title);
 +    window_add(&self->window, MENUFRAME_AS_WINDOW(self->frame));
  
      return self;
  }
@@@ -477,20 -427,24 +432,24 @@@ static void menu_entry_frame_render(ObM
                      ob_rr_theme->menu_title_height -
                      2*ob_rr_theme->paddingy);
          } else {
+             RrAppearance *clear;
              /* unlabeled separaator */
 -            XMoveResizeWindow(ob_display, self->text, PADDING, PADDING,
 +            XMoveResizeWindow(obt_display, self->text, PADDING, PADDING,
                                self->area.width - 2*PADDING, SEPARATOR_HEIGHT);
-             self->a_separator->surface.parent = item_a;
-             self->a_separator->surface.parentx = PADDING;
-             self->a_separator->surface.parenty = PADDING;
-             self->a_separator->texture[0].data.lineart.color =
+             clear = ob_rr_theme->a_clear_tex;
+             clear->texture[0].type = RR_TEXTURE_LINE_ART;
+             clear->surface.parent = item_a;
+             clear->surface.parentx = PADDING;
+             clear->surface.parenty = PADDING;
+             clear->texture[0].data.lineart.color =
                  text_a->texture[0].data.text.color;
-             self->a_separator->texture[0].data.lineart.x1 = 2*PADDING;
-             self->a_separator->texture[0].data.lineart.y1 = SEPARATOR_HEIGHT/2;
-             self->a_separator->texture[0].data.lineart.x2 =
-                 self->area.width - 4*PADDING;
-             self->a_separator->texture[0].data.lineart.y2 = SEPARATOR_HEIGHT/2;
-             RrPaint(self->a_separator, self->text,
+             clear->texture[0].data.lineart.x1 = 2*PADDING;
+             clear->texture[0].data.lineart.y1 = SEPARATOR_HEIGHT/2;
+             clear->texture[0].data.lineart.x2 = self->area.width - 4*PADDING;
+             clear->texture[0].data.lineart.y2 = SEPARATOR_HEIGHT/2;
+             RrPaint(clear, self->text,
                      self->area.width - 2*PADDING, SEPARATOR_HEIGHT);
          }
          break;
      if (self->entry->type == OB_MENU_ENTRY_TYPE_NORMAL &&
          self->entry->data.normal.icon_data)
      {
 -        XMoveResizeWindow(ob_display, self->icon,
+         RrAppearance *clear;
 +        XMoveResizeWindow(obt_display, self->icon,
                            PADDING, frame->item_margin.top,
                            ITEM_HEIGHT - frame->item_margin.top
                            - frame->item_margin.bottom,
                 self->entry->data.normal.mask)
      {
          RrColor *c;
+         RrAppearance *clear;
  
 -        XMoveResizeWindow(ob_display, self->icon,
 +        XMoveResizeWindow(obt_display, self->icon,
                            PADDING, frame->item_margin.top,
                            ITEM_HEIGHT - frame->item_margin.top
                            - frame->item_margin.bottom,
@@@ -38,7 -38,7 +38,7 @@@ extern GList *menu_frame_visible
  struct _ObMenuFrame
  {
      /* stuff to be an ObWindow */
-     ObWindow type;
 -    Window_InternalType type;
++    ObWindow obwin;
      Window window;
  
      struct _ObMenu *menu;
@@@ -255,8 -251,9 +255,9 @@@ void moveresize_start(ObClient *c, gin
      moveresize_in_progress = TRUE;
  
  #ifdef SYNC
 -    if (config_resize_redraw && !moving && extensions_sync &&
 +    if (config_resize_redraw && !moving && obt_display_extension_sync &&
-         moveresize_client->sync_request && moveresize_client->sync_counter)
+         moveresize_client->sync_request && moveresize_client->sync_counter &&
+         !moveresize_client->not_responding)
      {
          /* Initialize values for the resize syncing, and create an alarm for
             the client's xsync counter */
@@@ -370,8 -367,9 +371,9 @@@ static void do_resize(void
      }
  
  #ifdef SYNC
 -    if (config_resize_redraw && extensions_sync &&
 +    if (config_resize_redraw && obt_display_extension_sync &&
-         moveresize_client->sync_request && moveresize_client->sync_counter)
+         moveresize_client->sync_request && moveresize_client->sync_counter &&
+         !moveresize_client->not_responding)
      {
          XEvent ce;
          XSyncValue val;
  #include "focus_cycle_popup.h"
  #include "moveresize.h"
  #include "frame.h"
+ #include "framerender.h"
  #include "keyboard.h"
  #include "mouse.h"
 -#include "extensions.h"
  #include "menuframe.h"
  #include "grab.h"
  #include "group.h"
@@@ -175,9 -189,12 +176,9 @@@ gint main(gint argc, gchar **argv
      if (!XSetLocaleModifiers(""))
          g_message(_("Cannot set locale modifiers for the X server."));
  
 -    /* set our error handler */
 -    XSetErrorHandler(xerror_handler);
 -
      /* set the DISPLAY environment variable for any lauched children, to the
         display we're using, so they open in the right place. */
-     putenv(g_strdup_printf("DISPLAY=%s", DisplayString(obt_display)));
 -    setenv("DISPLAY", DisplayString(ob_display), TRUE);
++    setenv("DISPLAY", DisplayString(obt_display), TRUE);
  
      /* create available cursors */
      cursors[OB_CURSOR_NONE] = None;
diff --cc openbox/popup.c
Simple merge
@@@ -389,9 -400,15 +389,15 @@@ void screen_startup(gboolean reconfig
         this will also set the default names from the config file up for
         desktops that don't have names yet */
      screen_num_desktops = 0;
 -    if (PROP_GET32(RootWindow(ob_display, ob_screen),
 -                   net_number_of_desktops, cardinal, &d))
 +    if (OBT_PROP_GET32(obt_root(ob_screen),
 +                       NET_NUMBER_OF_DESKTOPS, CARDINAL, &d))
+     {
+         if (d != config_desktops_num) {
+             g_warning(_("Openbox is configured for %d desktops, but the current session has %d.  Overriding the Openbox configuration."),
+                       config_desktops_num, d);
+         }
          screen_set_num_desktops(d);
+     }
      /* restore from session if possible */
      else if (session_num_desktops)
          screen_set_num_desktops(session_num_desktops);
@@@ -1278,55 -1299,6 +1284,54 @@@ typedef struct 
      } \
  }
  
-         g_print("Using fake xinerama !\n");
 +static void get_xinerama_screens(Rect **xin_areas, guint *nxin)
 +{
 +    guint i;
 +    gint l, r, t, b;
 +
 +    if (ob_debug_xinerama) {
 +        gint w = WidthOfScreen(ScreenOfDisplay(obt_display, ob_screen));
 +        gint h = HeightOfScreen(ScreenOfDisplay(obt_display, ob_screen));
 +        *nxin = 2;
 +        *xin_areas = g_new(Rect, *nxin + 1);
 +        RECT_SET((*xin_areas)[0], 0, 0, w/2, h);
 +        RECT_SET((*xin_areas)[1], w/2, 0, w-(w/2), h);
 +    }
 +#ifdef XINERAMA
 +    else if (obt_display_extension_xinerama) {
 +        guint i;
 +        gint n;
 +        XineramaScreenInfo *info = XineramaQueryScreens(obt_display, &n);
 +        *nxin = n;
 +        *xin_areas = g_new(Rect, *nxin + 1);
 +        for (i = 0; i < *nxin; ++i)
 +            RECT_SET((*xin_areas)[i], info[i].x_org, info[i].y_org,
 +                     info[i].width, info[i].height);
 +        XFree(info);
 +    }
 +#endif
 +    else {
 +        *nxin = 1;
 +        *xin_areas = g_new(Rect, *nxin + 1);
 +        RECT_SET((*xin_areas)[0], 0, 0,
 +                 WidthOfScreen(ScreenOfDisplay(obt_display, ob_screen)),
 +                 HeightOfScreen(ScreenOfDisplay(obt_display, ob_screen)));
 +    }
 +
 +    /* returns one extra with the total area in it */
 +    l = (*xin_areas)[0].x;
 +    t = (*xin_areas)[0].y;
 +    r = (*xin_areas)[0].x + (*xin_areas)[0].width - 1;
 +    b = (*xin_areas)[0].y + (*xin_areas)[0].height - 1;
 +    for (i = 1; i < *nxin; ++i) {
 +        l = MIN(l, (*xin_areas)[i].x);
 +        t = MIN(l, (*xin_areas)[i].y);
 +        r = MAX(r, (*xin_areas)[i].x + (*xin_areas)[i].width - 1);
 +        b = MAX(b, (*xin_areas)[i].y + (*xin_areas)[i].height - 1);
 +    }
 +    RECT_SET((*xin_areas)[*nxin], l, t, r - l + 1, b - t + 1);
 +}
 +
  void screen_update_areas(void)
  {
      guint i, j;
@@@ -24,8 -25,8 +24,9 @@@
  #include "group.h"
  #include "frame.h"
  #include "window.h"
+ #include "event.h"
  #include "debug.h"
 +#include "obt/prop.h"
  
  GList  *stacking_list = NULL;
  /*! When true, stacking changes will not be reflected on the screen.  This is
@@@ -129,7 -131,9 +131,9 @@@ void stacking_temp_raise(ObWindow *wind
      }
  
      win[1] = window_top(window);
 -    XRestackWindows(ob_display, win, 2);
+     start = event_start_ignore_all_enters();
 +    XRestackWindows(obt_display, win, 2);
+     event_end_ignore_all_enters(start);
  
      pause_changes = TRUE;
  }
@@@ -144,7 -149,9 +149,9 @@@ void stacking_restore(void
      win[0] = screen_support_win;
      for (i = 1, it = stacking_list; it; ++i, it = g_list_next(it))
          win[i] = window_top(it->data);
 -    XRestackWindows(ob_display, win, i);
+     start = event_start_ignore_all_enters();
 +    XRestackWindows(obt_display, win, i);
+     event_end_ignore_all_enters(start);
      g_free(win);
  
      pause_changes = FALSE;
@@@ -57,16 -61,9 +60,9 @@@ static void sn_event_func(SnMonitorEven
  
  void sn_startup(gboolean reconfig)
  {
-     gchar *s;
      if (reconfig) return;
  
-     /* unset this so we don't pass it on unknowingly */
-     s = g_strdup("DESKTOP_STARTUP_ID");
-     putenv(s);
-     g_free(s);
 -    sn_display = sn_display_new(ob_display, NULL, NULL);
 +    sn_display = sn_display_new(obt_display, NULL, NULL);
      sn_context = sn_monitor_context_new(sn_display, ob_screen,
                                          sn_event_func, NULL, NULL);
      sn_launcher = sn_launcher_context_new(sn_display, ob_screen);
@@@ -257,12 -261,12 +260,12 @@@ void sn_setup_spawn_environment(const g
  
      /* 20 second timeout for apps to start */
      sn_launcher_context_ref(sn_launcher);
 -    ob_main_loop_timeout_add(ob_main_loop, 20 * G_USEC_PER_SEC,
 -                             sn_launch_wait_timeout, sn_launcher,
 -                             g_direct_equal,
 -                             (GDestroyNotify)sn_launcher_context_unref);
 +    obt_main_loop_timeout_add(ob_main_loop, 20 * G_USEC_PER_SEC,
 +                              sn_launch_wait_timeout, sn_launcher,
 +                              g_direct_equal,
 +                              (GDestroyNotify)sn_launcher_context_unref);
  
-     putenv(g_strdup_printf("DESKTOP_STARTUP_ID=%s", id));
+     setenv("DESKTOP_STARTUP_ID", id, TRUE);
  
      g_free(desc);
  }
diff --cc render/theme.c
Simple merge