Merge branch 'backport' into work
authorDana Jansens <danakj@orodu.net>
Fri, 22 Feb 2008 17:31:26 +0000 (12:31 -0500)
committerDana Jansens <danakj@orodu.net>
Fri, 22 Feb 2008 17:31:26 +0000 (12:31 -0500)
Conflicts:

openbox/menuframe.c
openbox/prompt.c
openbox/prop.c
openbox/prop.h

1  2 
obt/prop.c
obt/prop.h
openbox/client.c
openbox/menuframe.c
openbox/prompt.c
openbox/prompt.h
render/theme.c
render/theme.h

diff --cc obt/prop.c
index 108c118,0000000..1e324b9
mode 100644,000000..100644
--- /dev/null
@@@ -1,496 -1,0 +1,497 @@@
 +/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
 +
 +   obt/prop.c for the Openbox window manager
 +   Copyright (c) 2006        Mikael Magnusson
 +   Copyright (c) 2003-2007   Dana Jansens
 +
 +   This program is free software; you can redistribute it and/or modify
 +   it under the terms of the GNU General Public License as published by
 +   the Free Software Foundation; either version 2 of the License, or
 +   (at your option) any later version.
 +
 +   This program is distributed in the hope that it will be useful,
 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +   GNU General Public License for more details.
 +
 +   See the COPYING file for a copy of the GNU General Public License.
 +*/
 +
 +#include "obt/prop.h"
 +#include "obt/display.h"
 +
 +#include <X11/Xatom.h>
 +#ifdef HAVE_STRING_H
 +#  include <string.h>
 +#endif
 +
 +Atom prop_atoms[OBT_PROP_NUM_ATOMS];
 +gboolean prop_started = FALSE;
 +
 +#define CREATE_NAME(var, name) (prop_atoms[OBT_PROP_##var] = \
 +                                XInternAtom((obt_display), (name), FALSE))
 +#define CREATE(var) CREATE_NAME(var, #var)
 +#define CREATE_(var) CREATE_NAME(var, "_" #var)
 +
 +void obt_prop_startup(void)
 +{
 +    if (prop_started) return;
 +    prop_started = TRUE;
 +
 +    g_assert(obt_display);
 +
 +    CREATE(CARDINAL);
 +    CREATE(WINDOW);
 +    CREATE(PIXMAP);
 +    CREATE(ATOM);
 +    CREATE(STRING);
 +    CREATE_NAME(UTF8, "UTF8_STRING");
 +
 +    CREATE(MANAGER);
 +
 +    CREATE(WM_COLORMAP_WINDOWS);
 +    CREATE(WM_PROTOCOLS);
 +    CREATE(WM_STATE);
 +    CREATE(WM_CHANGE_STATE);
 +    CREATE(WM_DELETE_WINDOW);
 +    CREATE(WM_TAKE_FOCUS);
 +    CREATE(WM_NAME);
 +    CREATE(WM_ICON_NAME);
 +    CREATE(WM_CLASS);
 +    CREATE(WM_WINDOW_ROLE);
 +    CREATE(WM_CLIENT_MACHINE);
 +    CREATE(WM_COMMAND);
 +    CREATE(WM_CLIENT_LEADER);
++    CREATE(WM_TRANSIENT_FOR);
 +    CREATE_(MOTIF_WM_HINTS);
 +
 +    CREATE(SM_CLIENT_ID);
 +
 +    CREATE_(NET_WM_FULL_PLACEMENT);
 +
 +    CREATE_(NET_SUPPORTED);
 +    CREATE_(NET_CLIENT_LIST);
 +    CREATE_(NET_CLIENT_LIST_STACKING);
 +    CREATE_(NET_NUMBER_OF_DESKTOPS);
 +    CREATE_(NET_DESKTOP_GEOMETRY);
 +    CREATE_(NET_DESKTOP_VIEWPORT);
 +    CREATE_(NET_CURRENT_DESKTOP);
 +    CREATE_(NET_DESKTOP_NAMES);
 +    CREATE_(NET_ACTIVE_WINDOW);
 +/*    CREATE_(NET_RESTACK_WINDOW);*/
 +    CREATE_(NET_WORKAREA);
 +    CREATE_(NET_SUPPORTING_WM_CHECK);
 +    CREATE_(NET_DESKTOP_LAYOUT);
 +    CREATE_(NET_SHOWING_DESKTOP);
 +
 +    CREATE_(NET_CLOSE_WINDOW);
 +    CREATE_(NET_WM_MOVERESIZE);
 +    CREATE_(NET_MOVERESIZE_WINDOW);
 +    CREATE_(NET_REQUEST_FRAME_EXTENTS);
 +    CREATE_(NET_RESTACK_WINDOW);
 +
 +    CREATE_(NET_STARTUP_ID);
 +
 +    CREATE_(NET_WM_NAME);
 +    CREATE_(NET_WM_VISIBLE_NAME);
 +    CREATE_(NET_WM_ICON_NAME);
 +    CREATE_(NET_WM_VISIBLE_ICON_NAME);
 +    CREATE_(NET_WM_DESKTOP);
 +    CREATE_(NET_WM_WINDOW_TYPE);
 +    CREATE_(NET_WM_STATE);
 +    CREATE_(NET_WM_STRUT);
 +    CREATE_(NET_WM_STRUT_PARTIAL);
 +    CREATE_(NET_WM_ICON);
 +    CREATE_(NET_WM_ICON_GEOMETRY);
 +    CREATE_(NET_WM_PID);
 +    CREATE_(NET_WM_ALLOWED_ACTIONS);
 +    CREATE_(NET_WM_USER_TIME);
 +/*  CREATE_(NET_WM_USER_TIME_WINDOW); */
 +    CREATE_(KDE_NET_WM_FRAME_STRUT);
 +    CREATE_(NET_FRAME_EXTENTS);
 +
 +    CREATE_(NET_WM_PING);
 +#ifdef SYNC
 +    CREATE_(NET_WM_SYNC_REQUEST);
 +    CREATE_(NET_WM_SYNC_REQUEST_COUNTER);
 +#endif
 +
 +    CREATE_(NET_WM_WINDOW_TYPE_DESKTOP);
 +    CREATE_(NET_WM_WINDOW_TYPE_DOCK);
 +    CREATE_(NET_WM_WINDOW_TYPE_TOOLBAR);
 +    CREATE_(NET_WM_WINDOW_TYPE_MENU);
 +    CREATE_(NET_WM_WINDOW_TYPE_UTILITY);
 +    CREATE_(NET_WM_WINDOW_TYPE_SPLASH);
 +    CREATE_(NET_WM_WINDOW_TYPE_DIALOG);
 +    CREATE_(NET_WM_WINDOW_TYPE_NORMAL);
 +    CREATE_(NET_WM_WINDOW_TYPE_POPUP_MENU);
 +
 +    prop_atoms[OBT_PROP_NET_WM_MOVERESIZE_SIZE_TOPLEFT] = 0;
 +    prop_atoms[OBT_PROP_NET_WM_MOVERESIZE_SIZE_TOP] = 1;
 +    prop_atoms[OBT_PROP_NET_WM_MOVERESIZE_SIZE_TOPRIGHT] = 2;
 +    prop_atoms[OBT_PROP_NET_WM_MOVERESIZE_SIZE_RIGHT] = 3;
 +    prop_atoms[OBT_PROP_NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT] = 4;
 +    prop_atoms[OBT_PROP_NET_WM_MOVERESIZE_SIZE_BOTTOM] = 5;
 +    prop_atoms[OBT_PROP_NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT] = 6;
 +    prop_atoms[OBT_PROP_NET_WM_MOVERESIZE_SIZE_LEFT] = 7;
 +    prop_atoms[OBT_PROP_NET_WM_MOVERESIZE_MOVE] = 8;
 +    prop_atoms[OBT_PROP_NET_WM_MOVERESIZE_SIZE_KEYBOARD] = 9;
 +    prop_atoms[OBT_PROP_NET_WM_MOVERESIZE_MOVE_KEYBOARD] = 10;
 +    prop_atoms[OBT_PROP_NET_WM_MOVERESIZE_CANCEL] = 11;
 +
 +    CREATE_(NET_WM_ACTION_MOVE);
 +    CREATE_(NET_WM_ACTION_RESIZE);
 +    CREATE_(NET_WM_ACTION_MINIMIZE);
 +    CREATE_(NET_WM_ACTION_SHADE);
 +    CREATE_(NET_WM_ACTION_MAXIMIZE_HORZ);
 +    CREATE_(NET_WM_ACTION_MAXIMIZE_VERT);
 +    CREATE_(NET_WM_ACTION_FULLSCREEN);
 +    CREATE_(NET_WM_ACTION_CHANGE_DESKTOP);
 +    CREATE_(NET_WM_ACTION_CLOSE);
 +    CREATE_(NET_WM_ACTION_ABOVE);
 +    CREATE_(NET_WM_ACTION_BELOW);
 +
 +    CREATE_(NET_WM_STATE_MODAL);
 +/*    CREATE_(NET_WM_STATE_STICKY);*/
 +    CREATE_(NET_WM_STATE_MAXIMIZED_VERT);
 +    CREATE_(NET_WM_STATE_MAXIMIZED_HORZ);
 +    CREATE_(NET_WM_STATE_SHADED);
 +    CREATE_(NET_WM_STATE_SKIP_TASKBAR);
 +    CREATE_(NET_WM_STATE_SKIP_PAGER);
 +    CREATE_(NET_WM_STATE_HIDDEN);
 +    CREATE_(NET_WM_STATE_FULLSCREEN);
 +    CREATE_(NET_WM_STATE_ABOVE);
 +    CREATE_(NET_WM_STATE_BELOW);
 +    CREATE_(NET_WM_STATE_DEMANDS_ATTENTION);
 +
 +    prop_atoms[OBT_PROP_NET_WM_STATE_ADD] = 1;
 +    prop_atoms[OBT_PROP_NET_WM_STATE_REMOVE] = 0;
 +    prop_atoms[OBT_PROP_NET_WM_STATE_TOGGLE] = 2;
 +
 +    prop_atoms[OBT_PROP_NET_WM_ORIENTATION_HORZ] = 0;
 +    prop_atoms[OBT_PROP_NET_WM_ORIENTATION_VERT] = 1;
 +    prop_atoms[OBT_PROP_NET_WM_TOPLEFT] = 0;
 +    prop_atoms[OBT_PROP_NET_WM_TOPRIGHT] = 1;
 +    prop_atoms[OBT_PROP_NET_WM_BOTTOMRIGHT] = 2;
 +    prop_atoms[OBT_PROP_NET_WM_BOTTOMLEFT] = 3;
 +
 +    CREATE_(KDE_WM_CHANGE_STATE);
 +    CREATE_(KDE_NET_WM_WINDOW_TYPE_OVERRIDE);
 +
 +/*
 +    CREATE_NAME(ROOTPMAPId, "_XROOTPMAP_ID");
 +    CREATE_NAME(ESETROOTId, "ESETROOT_PMAP_ID");
 +*/
 +
 +    CREATE_(OPENBOX_PID);
 +    CREATE_(OB_THEME);
 +    CREATE_(OB_CONFIG_FILE);
 +    CREATE_(OB_WM_ACTION_UNDECORATE);
 +    CREATE_(OB_WM_STATE_UNDECORATED);
 +    CREATE_(OB_CONTROL);
 +}
 +
 +Atom obt_prop_atom(ObtPropAtom a)
 +{
 +    g_assert(prop_started);
 +    g_assert(a < OBT_PROP_NUM_ATOMS);
 +    return prop_atoms[a];
 +}
 +
 +static gboolean get_prealloc(Window win, Atom prop, Atom type, gint size,
 +                             guchar *data, gulong num)
 +{
 +    gboolean ret = FALSE;
 +    gint res;
 +    guchar *xdata = NULL;
 +    Atom ret_type;
 +    gint ret_size;
 +    gulong ret_items, bytes_left;
 +    glong num32 = 32 / size * num; /* num in 32-bit elements */
 +
 +    res = XGetWindowProperty(obt_display, win, prop, 0l, num32,
 +                             FALSE, type, &ret_type, &ret_size,
 +                             &ret_items, &bytes_left, &xdata);
 +    if (res == Success && ret_items && xdata) {
 +        if (ret_size == size && ret_items >= num) {
 +            guint i;
 +            for (i = 0; i < num; ++i)
 +                switch (size) {
 +                case 8:
 +                    data[i] = xdata[i];
 +                    break;
 +                case 16:
 +                    ((guint16*)data)[i] = ((gushort*)xdata)[i];
 +                    break;
 +                case 32:
 +                    ((guint32*)data)[i] = ((gulong*)xdata)[i];
 +                    break;
 +                default:
 +                    g_assert_not_reached(); /* unhandled size */
 +                }
 +            ret = TRUE;
 +        }
 +        XFree(xdata);
 +    }
 +    return ret;
 +}
 +
 +static gboolean get_all(Window win, Atom prop, Atom type, gint size,
 +                        guchar **data, guint *num)
 +{
 +    gboolean ret = FALSE;
 +    gint res;
 +    guchar *xdata = NULL;
 +    Atom ret_type;
 +    gint ret_size;
 +    gulong ret_items, bytes_left;
 +
 +    res = XGetWindowProperty(obt_display, win, prop, 0l, G_MAXLONG,
 +                             FALSE, type, &ret_type, &ret_size,
 +                             &ret_items, &bytes_left, &xdata);
 +    if (res == Success) {
 +        if (ret_size == size && ret_items > 0) {
 +            guint i;
 +
 +            *data = g_malloc(ret_items * (size / 8));
 +            for (i = 0; i < ret_items; ++i)
 +                switch (size) {
 +                case 8:
 +                    (*data)[i] = xdata[i];
 +                    break;
 +                case 16:
 +                    ((guint16*)*data)[i] = ((gushort*)xdata)[i];
 +                    break;
 +                case 32:
 +                    ((guint32*)*data)[i] = ((gulong*)xdata)[i];
 +                    break;
 +                default:
 +                    g_assert_not_reached(); /* unhandled size */
 +                }
 +            *num = ret_items;
 +            ret = TRUE;
 +        }
 +        XFree(xdata);
 +    }
 +    return ret;
 +}
 +
 +static gboolean get_stringlist(Window win, Atom prop, gchar ***list, gint *nstr)
 +{
 +    XTextProperty tprop;
 +    gboolean ret = FALSE;
 +
 +    if (XGetTextProperty(obt_display, win, &tprop, prop) && tprop.nitems) {
 +        if (XTextPropertyToStringList(&tprop, list, nstr))
 +            ret = TRUE;
 +        XFree(tprop.value);
 +    }
 +    return ret;
 +}
 +
 +gboolean obt_prop_get32(Window win, Atom prop, Atom type, guint32 *ret)
 +{
 +    return get_prealloc(win, prop, type, 32, (guchar*)ret, 1);
 +}
 +
 +gboolean obt_prop_get_array32(Window win, Atom prop, Atom type, guint32 **ret,
 +                              guint *nret)
 +{
 +    return get_all(win, prop, type, 32, (guchar**)ret, nret);
 +}
 +
 +gboolean obt_prop_get_string_locale(Window win, Atom prop, gchar **ret)
 +{
 +    gchar **list;
 +    gint nstr;
 +    gchar *s;
 +
 +    if (get_stringlist(win, prop, &list, &nstr) && nstr) {
 +        s = g_locale_to_utf8(list[0], -1, NULL, NULL, NULL);
 +        XFreeStringList(list);
 +        if (s) {
 +            *ret = s;
 +            return TRUE;
 +        }
 +    }
 +    return FALSE;
 +}
 +
 +gboolean obt_prop_get_strings_locale(Window win, Atom prop, gchar ***ret)
 +{
 +    GSList *strs = NULL, *it;
 +    gchar *raw, *p;
 +    guint num, i, count = 0;
 +
 +    if (get_all(win, prop, OBT_PROP_ATOM(STRING), 8,
 +                (guchar**)&raw, &num))
 +    {
 +        p = raw;
 +        while (p < raw + num) {
 +            ++count;
 +            strs = g_slist_append(strs, p);
 +            p += strlen(p) + 1; /* next string */
 +        }
 +
 +        *ret = g_new0(gchar*, count + 1);
 +        (*ret)[count] = NULL; /* null terminated list */
 +
 +        for (i = 0, it = strs; it; ++i, it = g_slist_next(it)) {
 +            (*ret)[i] = g_locale_to_utf8(it->data, -1, NULL, NULL, NULL);
 +            /* make sure translation did not fail */
 +            if (!(*ret)[i])
 +                (*ret)[i] = g_strdup("");
 +        }
 +        g_free(raw);
 +        g_slist_free(strs);
 +        return TRUE;
 +    }
 +    return FALSE;
 +}
 +
 +gboolean obt_prop_get_string_utf8(Window win, Atom prop, gchar **ret)
 +{
 +    gchar *raw;
 +    gchar *str;
 +    guint num;
 +
 +    if (get_all(win, prop, OBT_PROP_ATOM(UTF8), 8,
 +                (guchar**)&raw, &num))
 +    {
 +        str = g_strndup(raw, num); /* grab the first string from the list */
 +        g_free(raw);
 +        if (g_utf8_validate(str, -1, NULL)) {
 +            *ret = str;
 +            return TRUE;
 +        }
 +        g_free(str);
 +    }
 +    return FALSE;
 +}
 +
 +gboolean obt_prop_get_strings_utf8(Window win, Atom prop, gchar ***ret)
 +{
 +    GSList *strs = NULL, *it;
 +    gchar *raw, *p;
 +    guint num, i, count = 0;
 +
 +    if (get_all(win, prop, OBT_PROP_ATOM(UTF8), 8,
 +                (guchar**)&raw, &num))
 +    {
 +        p = raw;
 +        while (p < raw + num) {
 +            ++count;
 +            strs = g_slist_append(strs, p);
 +            p += strlen(p) + 1; /* next string */
 +        }
 +
 +        *ret = g_new0(gchar*, count + 1);
 +
 +        for (i = 0, it = strs; it; ++i, it = g_slist_next(it)) {
 +            if (g_utf8_validate(it->data, -1, NULL))
 +                (*ret)[i] = g_strdup(it->data);
 +            else
 +                (*ret)[i] = g_strdup("");
 +        }
 +        g_free(raw);
 +        g_slist_free(strs);
 +        return TRUE;
 +    }
 +    return FALSE;
 +}
 +
 +void obt_prop_set32(Window win, Atom prop, Atom type, gulong val)
 +{
 +    XChangeProperty(obt_display, win, prop, type, 32, PropModeReplace,
 +                    (guchar*)&val, 1);
 +}
 +
 +void obt_prop_set_array32(Window win, Atom prop, Atom type, gulong *val,
 +                      guint num)
 +{
 +    XChangeProperty(obt_display, win, prop, type, 32, PropModeReplace,
 +                    (guchar*)val, num);
 +}
 +
 +void obt_prop_set_string_locale(Window win, Atom prop, const gchar *val)
 +{
 +    gchar const *s[2] = { val, NULL };
 +    obt_prop_set_strings_locale(win, prop, s);
 +}
 +
 +void obt_prop_set_strings_locale(Window win, Atom prop, const gchar **strs)
 +{
 +    gint i, count;
 +    gchar **lstrs;
 +    XTextProperty tprop;
 +
 +    /* count the strings in strs, and convert them to the locale format */
 +    for (count = 0; strs[count]; ++count);
 +    lstrs = g_new0(char*, count);
 +    for (i = 0; i < count; ++i) {
 +        lstrs[i] = g_locale_from_utf8(strs[i], -1, NULL, NULL, NULL);
 +        if (!lstrs[i]) {
 +            lstrs[i] = g_strdup(""); /* make it an empty string */
 +            g_warning("Unable to translate string '%s' from UTF8 to locale "
 +                      "format", strs[i]);
 +        }
 +    }
 +
 +
 +    XStringListToTextProperty(lstrs, count, &tprop);
 +    XSetTextProperty(obt_display, win, &tprop, prop);
 +    XFree(tprop.value);
 +}
 +
 +void obt_prop_set_string_utf8(Window win, Atom prop, const gchar *val)
 +{
 +    XChangeProperty(obt_display, win, prop, OBT_PROP_ATOM(UTF8), 8,
 +                    PropModeReplace, (const guchar*)val, strlen(val));
 +}
 +
 +void obt_prop_set_strings_utf8(Window win, Atom prop, const gchar **strs)
 +{
 +    GString *str;
 +    gchar const **s;
 +
 +    str = g_string_sized_new(0);
 +    for (s = strs; *s; ++s) {
 +        str = g_string_append(str, *s);
 +        str = g_string_append_c(str, '\0');
 +    }
 +    XChangeProperty(obt_display, win, prop, obt_prop_atom(OBT_PROP_UTF8), 8,
 +                    PropModeReplace, (guchar*)str->str, str->len);
 +    g_string_free(str, TRUE);
 +}
 +
 +void obt_prop_erase(Window win, Atom prop)
 +{
 +    XDeleteProperty(obt_display, win, prop);
 +}
 +
 +void obt_prop_message(gint screen, Window about, Atom messagetype,
 +                      glong data0, glong data1, glong data2, glong data3,
 +                      glong data4, glong mask)
 +{
 +    obt_prop_message_to(obt_root(screen), about, messagetype,
 +                        data0, data1, data2, data3, data4, mask);
 +}
 +
 +void obt_prop_message_to(Window to, Window about,
 +                         Atom messagetype,
 +                         glong data0, glong data1, glong data2, glong data3,
 +                         glong data4, glong mask)
 +{
 +    XEvent ce;
 +    ce.xclient.type = ClientMessage;
 +    ce.xclient.message_type = messagetype;
 +    ce.xclient.display = obt_display;
 +    ce.xclient.window = about;
 +    ce.xclient.format = 32;
 +    ce.xclient.data.l[0] = data0;
 +    ce.xclient.data.l[1] = data1;
 +    ce.xclient.data.l[2] = data2;
 +    ce.xclient.data.l[3] = data3;
 +    ce.xclient.data.l[4] = data4;
 +    XSendEvent(obt_display, to, FALSE, mask, &ce);
 +}
diff --cc obt/prop.h
index 97a2c9f,0000000..22a1ab4
mode 100644,000000..100644
--- /dev/null
@@@ -1,280 -1,0 +1,281 @@@
 +/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
 +
 +   obt/prop.h for the Openbox window manager
 +   Copyright (c) 2006        Mikael Magnusson
 +   Copyright (c) 2003-2007   Dana Jansens
 +
 +   This program is free software; you can redistribute it and/or modify
 +   it under the terms of the GNU General Public License as published by
 +   the Free Software Foundation; either version 2 of the License, or
 +   (at your option) any later version.
 +
 +   This program is distributed in the hope that it will be useful,
 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +   GNU General Public License for more details.
 +
 +   See the COPYING file for a copy of the GNU General Public License.
 +*/
 +
 +#ifndef __obt_prop_h
 +#define __obt_prop_h
 +
 +#include <X11/Xlib.h>
 +#include <glib.h>
 +
 +G_BEGIN_DECLS
 +
 +typedef enum {
 +    /* types */
 +    OBT_PROP_CARDINAL, /*!< The atom which represents the Cardinal data type */
 +    OBT_PROP_WINDOW,   /*!< The atom which represents window ids */
 +    OBT_PROP_PIXMAP,   /*!< The atom which represents pixmap ids */
 +    OBT_PROP_ATOM,     /*!< The atom which represents atom values */
 +    OBT_PROP_STRING,   /*!< The atom which represents ascii strings */
 +    OBT_PROP_UTF8,     /*!< The atom which represents utf8-encoded strings */
 +
 +    /* selection stuff */
 +    OBT_PROP_MANAGER,
 +
 +    /* window hints */
 +    OBT_PROP_WM_COLORMAP_WINDOWS,
 +    OBT_PROP_WM_PROTOCOLS,
 +    OBT_PROP_WM_STATE,
 +    OBT_PROP_WM_DELETE_WINDOW,
 +    OBT_PROP_WM_TAKE_FOCUS,
 +    OBT_PROP_WM_CHANGE_STATE,
 +    OBT_PROP_WM_NAME,
 +    OBT_PROP_WM_ICON_NAME,
 +    OBT_PROP_WM_CLASS,
 +    OBT_PROP_WM_WINDOW_ROLE,
 +    OBT_PROP_WM_CLIENT_MACHINE,
 +    OBT_PROP_WM_COMMAND,
 +    OBT_PROP_WM_CLIENT_LEADER,
++    OBT_PROP_WM_TRANSIENT_FOR,
 +    OBT_PROP_MOTIF_WM_HINTS,
 +
 +    /* SM atoms */
 +    OBT_PROP_SM_CLIENT_ID,
 +
 +    /* NETWM atoms */
 +
 +    /* Atoms that are used inside messages - these don't go in net_supported */
 +
 +    OBT_PROP_NET_WM_MOVERESIZE_SIZE_TOPLEFT,
 +    OBT_PROP_NET_WM_MOVERESIZE_SIZE_TOP,
 +    OBT_PROP_NET_WM_MOVERESIZE_SIZE_TOPRIGHT,
 +    OBT_PROP_NET_WM_MOVERESIZE_SIZE_RIGHT,
 +    OBT_PROP_NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT,
 +    OBT_PROP_NET_WM_MOVERESIZE_SIZE_BOTTOM,
 +    OBT_PROP_NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT,
 +    OBT_PROP_NET_WM_MOVERESIZE_SIZE_LEFT,
 +    OBT_PROP_NET_WM_MOVERESIZE_MOVE,
 +    OBT_PROP_NET_WM_MOVERESIZE_SIZE_KEYBOARD,
 +    OBT_PROP_NET_WM_MOVERESIZE_MOVE_KEYBOARD,
 +    OBT_PROP_NET_WM_MOVERESIZE_CANCEL,
 +
 +    OBT_PROP_NET_WM_STATE_ADD,
 +    OBT_PROP_NET_WM_STATE_REMOVE,
 +    OBT_PROP_NET_WM_STATE_TOGGLE,
 +
 +    OBT_PROP_NET_WM_ORIENTATION_HORZ,
 +    OBT_PROP_NET_WM_ORIENTATION_VERT,
 +    OBT_PROP_NET_WM_TOPLEFT,
 +    OBT_PROP_NET_WM_TOPRIGHT,
 +    OBT_PROP_NET_WM_BOTTOMRIGHT,
 +    OBT_PROP_NET_WM_BOTTOMLEFT,
 +
 +    OBT_PROP_NET_WM_WINDOW_TYPE_POPUP_MENU,
 +
 +    OBT_PROP_PRIVATE_PADDING1,
 +    OBT_PROP_PRIVATE_PADDING2,
 +    OBT_PROP_PRIVATE_PADDING3,
 +    OBT_PROP_PRIVATE_PADDING4,
 +    OBT_PROP_PRIVATE_PADDING5,
 +    OBT_PROP_PRIVATE_PADDING6,
 +    OBT_PROP_PRIVATE_PADDING7,
 +    OBT_PROP_PRIVATE_PADDING8,
 +    OBT_PROP_PRIVATE_PADDING9,
 +    OBT_PROP_PRIVATE_PADDING10,
 +    OBT_PROP_PRIVATE_PADDING11,
 +    OBT_PROP_PRIVATE_PADDING12,
 +
 +    /* Everything below here must go in net_supported on the root window */
 +
 +    /* root window properties */
 +    OBT_PROP_NET_SUPPORTED,
 +    OBT_PROP_NET_CLIENT_LIST,
 +    OBT_PROP_NET_CLIENT_LIST_STACKING,
 +    OBT_PROP_NET_NUMBER_OF_DESKTOPS,
 +    OBT_PROP_NET_DESKTOP_GEOMETRY,
 +    OBT_PROP_NET_DESKTOP_VIEWPORT,
 +    OBT_PROP_NET_CURRENT_DESKTOP,
 +    OBT_PROP_NET_DESKTOP_NAMES,
 +    OBT_PROP_NET_ACTIVE_WINDOW,
 +/*    Atom net_restack_window;*/
 +    OBT_PROP_NET_WORKAREA,
 +    OBT_PROP_NET_SUPPORTING_WM_CHECK,
 +    OBT_PROP_NET_DESKTOP_LAYOUT,
 +    OBT_PROP_NET_SHOWING_DESKTOP,
 +
 +    /* root window messages */
 +    OBT_PROP_NET_CLOSE_WINDOW,
 +    OBT_PROP_NET_WM_MOVERESIZE,
 +    OBT_PROP_NET_MOVERESIZE_WINDOW,
 +    OBT_PROP_NET_REQUEST_FRAME_EXTENTS,
 +    OBT_PROP_NET_RESTACK_WINDOW,
 +
 +    /* helpful hints to apps that aren't used for anything */
 +    OBT_PROP_NET_WM_FULL_PLACEMENT,
 +
 +    /* startup-notification extension */
 +    OBT_PROP_NET_STARTUP_ID,
 +
 +    /* application window properties */
 +    OBT_PROP_NET_WM_NAME,
 +    OBT_PROP_NET_WM_VISIBLE_NAME,
 +    OBT_PROP_NET_WM_ICON_NAME,
 +    OBT_PROP_NET_WM_VISIBLE_ICON_NAME,
 +    OBT_PROP_NET_WM_DESKTOP,
 +    OBT_PROP_NET_WM_WINDOW_TYPE,
 +    OBT_PROP_NET_WM_STATE,
 +    OBT_PROP_NET_WM_STRUT,
 +    OBT_PROP_NET_WM_STRUT_PARTIAL,
 +    OBT_PROP_NET_WM_ICON,
 +    OBT_PROP_NET_WM_ICON_GEOMETRY,
 +    OBT_PROP_NET_WM_PID,
 +    OBT_PROP_NET_WM_ALLOWED_ACTIONS,
 +    OBT_PROP_NET_WM_USER_TIME,
 +/*  OBT_PROP_NET_WM_USER_TIME_WINDOW, */
 +    OBT_PROP_NET_FRAME_EXTENTS,
 +
 +    /* application protocols */
 +    OBT_PROP_NET_WM_PING,
 +#ifdef SYNC
 +    OBT_PROP_NET_WM_SYNC_REQUEST,
 +    OBT_PROP_NET_WM_SYNC_REQUEST_COUNTER,
 +#endif
 +
 +    OBT_PROP_NET_WM_WINDOW_TYPE_DESKTOP,
 +    OBT_PROP_NET_WM_WINDOW_TYPE_DOCK,
 +    OBT_PROP_NET_WM_WINDOW_TYPE_TOOLBAR,
 +    OBT_PROP_NET_WM_WINDOW_TYPE_MENU,
 +    OBT_PROP_NET_WM_WINDOW_TYPE_UTILITY,
 +    OBT_PROP_NET_WM_WINDOW_TYPE_SPLASH,
 +    OBT_PROP_NET_WM_WINDOW_TYPE_DIALOG,
 +    OBT_PROP_NET_WM_WINDOW_TYPE_NORMAL,
 +
 +    OBT_PROP_NET_WM_ACTION_MOVE,
 +    OBT_PROP_NET_WM_ACTION_RESIZE,
 +    OBT_PROP_NET_WM_ACTION_MINIMIZE,
 +    OBT_PROP_NET_WM_ACTION_SHADE,
 +/*    OBT_PROP_NET_WM_ACTION_STICK,*/
 +    OBT_PROP_NET_WM_ACTION_MAXIMIZE_HORZ,
 +    OBT_PROP_NET_WM_ACTION_MAXIMIZE_VERT,
 +    OBT_PROP_NET_WM_ACTION_FULLSCREEN,
 +    OBT_PROP_NET_WM_ACTION_CHANGE_DESKTOP,
 +    OBT_PROP_NET_WM_ACTION_CLOSE,
 +    OBT_PROP_NET_WM_ACTION_ABOVE,
 +    OBT_PROP_NET_WM_ACTION_BELOW,
 +
 +    OBT_PROP_NET_WM_STATE_MODAL,
 +/*    OBT_PROP_NET_WM_STATE_STICKY,*/
 +    OBT_PROP_NET_WM_STATE_MAXIMIZED_VERT,
 +    OBT_PROP_NET_WM_STATE_MAXIMIZED_HORZ,
 +    OBT_PROP_NET_WM_STATE_SHADED,
 +    OBT_PROP_NET_WM_STATE_SKIP_TASKBAR,
 +    OBT_PROP_NET_WM_STATE_SKIP_PAGER,
 +    OBT_PROP_NET_WM_STATE_HIDDEN,
 +    OBT_PROP_NET_WM_STATE_FULLSCREEN,
 +    OBT_PROP_NET_WM_STATE_ABOVE,
 +    OBT_PROP_NET_WM_STATE_BELOW,
 +    OBT_PROP_NET_WM_STATE_DEMANDS_ATTENTION,
 +
 +    /* KDE atoms */
 +
 +    OBT_PROP_KDE_WM_CHANGE_STATE,
 +    OBT_PROP_KDE_NET_WM_FRAME_STRUT,
 +    OBT_PROP_KDE_NET_WM_WINDOW_TYPE_OVERRIDE,
 +
 +/*
 +    OBT_PROP_ROOTPMAPID,
 +    OBT_PROP_ESETROOTID,
 +*/
 +
 +    /* Openbox specific atoms */
 +
 +    OBT_PROP_OB_WM_ACTION_UNDECORATE,
 +    OBT_PROP_OB_WM_STATE_UNDECORATED,
 +    OBT_PROP_OPENBOX_PID, /* this is depreecated in favour of ob_control */
 +    OBT_PROP_OB_THEME,
 +    OBT_PROP_OB_CONFIG_FILE,
 +    OBT_PROP_OB_CONTROL,
 +
 +    OBT_PROP_NUM_ATOMS
 +} ObtPropAtom;
 +
 +Atom obt_prop_atom(ObtPropAtom a);
 +
 +gboolean obt_prop_get32(Window win, Atom prop, Atom type, guint32 *ret);
 +gboolean obt_prop_get_array32(Window win, Atom prop, Atom type, guint32 **ret,
 +                              guint *nret);
 +gboolean obt_prop_get_string_locale(Window win, Atom prop, gchar **ret);
 +gboolean obt_prop_get_string_utf8(Window win, Atom prop, gchar **ret);
 +gboolean obt_prop_get_strings_locale(Window win, Atom prop, gchar ***ret);
 +gboolean obt_prop_get_strings_utf8(Window win, Atom prop, gchar ***ret);
 +
 +void obt_prop_set32(Window win, Atom prop, Atom type, gulong val);
 +void obt_prop_set_array32(Window win, Atom prop, Atom type, gulong *val,
 +                          guint num);
 +void obt_prop_set_string_locale(Window win, Atom prop, const gchar *val);
 +void obt_prop_set_string_utf8(Window win, Atom prop, const gchar *val);
 +void obt_prop_set_strings_locale(Window win, Atom prop, const gchar **strs);
 +void obt_prop_set_strings_utf8(Window win, Atom prop, const gchar **strs);
 +
 +void obt_prop_erase(Window win, Atom prop);
 +
 +void obt_prop_message(gint screen, Window about, Atom messagetype,
 +                      glong data0, glong data1, glong data2, glong data3,
 +                      glong data4, glong mask);
 +void obt_prop_message_to(Window to, Window about, Atom messagetype,
 +                         glong data0, glong data1, glong data2, glong data3,
 +                         glong data4, glong mask);
 +
 +#define OBT_PROP_ATOM(prop) obt_prop_atom(OBT_PROP_##prop)
 +
 +#define OBT_PROP_GET32(win, prop, type, ret) \
 +    (obt_prop_get32(win, OBT_PROP_ATOM(prop), OBT_PROP_ATOM(type), ret))
 +#define OBT_PROP_GETA32(win, prop, type, ret, nret) \
 +    (obt_prop_get_array32(win, OBT_PROP_ATOM(prop), OBT_PROP_ATOM(type), \
 +                          ret, nret))
 +#define OBT_PROP_GETS(win, prop, type, ret) \
 +    (obt_prop_get_string_##type(win, OBT_PROP_ATOM(prop), ret))
 +#define OBT_PROP_GETSS(win, prop, type, ret) \
 +    (obt_prop_get_strings_##type(win, OBT_PROP_ATOM(prop), ret))
 +
 +#define OBT_PROP_SET32(win, prop, type, val) \
 +    (obt_prop_set32(win, OBT_PROP_ATOM(prop), OBT_PROP_ATOM(type), val))
 +#define OBT_PROP_SETA32(win, prop, type, val, num) \
 +    (obt_prop_set_array32(win, OBT_PROP_ATOM(prop), OBT_PROP_ATOM(type), \
 +                          val, num))
 +#define OBT_PROP_SETS(win, prop, type, val) \
 +    (obt_prop_set_string_##type(win, OBT_PROP_ATOM(prop), val))
 +#define OBT_PROP_SETSS(win, prop, type, strs) \
 +    (obt_prop_set_strings_##type(win, OBT_PROP_ATOM(prop), strs))
 +
 +#define OBT_PROP_ERASE(win, prop) (obt_prop_erase(win, OBT_PROP_ATOM(prop)))
 +
 +#define OBT_PROP_MSG(screen, about, msgtype, data0, data1, data2, data3, \
 +                     data4) \
 +    (obt_prop_message(screen, about, OBT_PROP_ATOM(msgtype), \
 +                      data0, data1, data2, data3, data4, \
 +                      SubstructureNotifyMask | SubstructureRedirectMask))
 +
 +#define OBT_PROP_MSG_TO(to, about, msgtype, data0, data1, data2, data3, \
 +                        data4, mask) \
 +    (obt_prop_message_to(to, about, OBT_PROP_ATOM(msgtype), \
 +                         data0, data1, data2, data3, data4, mask))
 +
 +G_END_DECLS
 +
 +#endif /* __obt_prop_h */
Simple merge
@@@ -442,26 -450,31 +455,31 @@@ static void menu_entry_frame_render(ObM
                      ob_rr_theme->menu_title_height -
                      2*ob_rr_theme->paddingy);
          } else {
-             RrAppearance *clear;
-             /* unlabeled separaator */
-             XMoveResizeWindow(obt_display, self->text, PADDING, PADDING,
-                               self->area.width - 2*PADDING, SEPARATOR_HEIGHT);
-             clear = ob_rr_theme->a_clear_tex;
-             RrAppearanceClearTextures(clear);
-             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;
-             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);
+             gint i;
+             /* unlabeled separator */
 -            XMoveResizeWindow(ob_display, self->text, 0, 0,
++            XMoveResizeWindow(obt_display, self->text, 0, 0,
+                               self->area.width,
+                               ob_rr_theme->menu_sep_width +
+                               2*ob_rr_theme->menu_sep_paddingy);
+             a_sep->surface.parent = item_a;
+             a_sep->surface.parentx = 0;
+             a_sep->surface.parenty = 0;
+             for (i = 0; i < ob_rr_theme->menu_sep_width; ++i) {
+                 a_sep->texture[i].data.lineart.x1 =
+                     ob_rr_theme->menu_sep_paddingx;
+                 a_sep->texture[i].data.lineart.y1 =
+                     ob_rr_theme->menu_sep_paddingy + i;
+                 a_sep->texture[i].data.lineart.x2 =
+                     self->area.width - ob_rr_theme->menu_sep_paddingx - 1;
+                 a_sep->texture[i].data.lineart.y2 =
+                     ob_rr_theme->menu_sep_paddingy + i;
+             }
+             RrPaint(a_sep, self->text, self->area.width,
+                     ob_rr_theme->menu_sep_width +
+                     2*ob_rr_theme->menu_sep_paddingy);
          }
          break;
      }
  #include "prompt.h"
  #include "openbox.h"
  #include "screen.h"
 -#include "openbox.h"
  #include "client.h"
 -#include "prop.h"
 -#include "modkeys.h"
+ #include "group.h"
  #include "event.h"
 +#include "obt/display.h"
 +#include "obt/keyboard.h"
 +#include "obt/prop.h"
  #include "gettext.h"
  
  static GList *prompt_list = NULL;
@@@ -455,8 -458,33 +456,34 @@@ void prompt_show(ObPrompt *self, ObClie
              break;
          }
  
-     XSetTransientForHint(obt_display, self->super.window,
-                          (parent ? parent->window : 0));
+     if (parent) {
+         Atom states[1];
+         gint nstates;
+         Window p;
+         XWMHints h;
+         if (parent->group) {
+             /* make it transient for the window's group */
+             h.flags = WindowGroupHint;
+             h.window_group = parent->group->leader;
 -            p = RootWindow(ob_display, ob_screen);
++            p = obt_root(ob_screen);
+         }
+         else {
+             /* make it transient for the window directly */
+             h.flags = 0;
+             p = parent->window;
+         }
 -        XSetWMHints(ob_display, self->super.window, &h);
 -        PROP_SET32(self->super.window, wm_transient_for, window, p);
++        XSetWMHints(obt_display, self->super.window, &h);
++        OBT_PROP_SET32(self->super.window, WM_TRANSIENT_FOR, WINDOW, p);
 -        states[0] = prop_atoms.net_wm_state_modal;
++        states[0] = OBT_PROP_ATOM(NET_WM_STATE_MODAL);
+         nstates = (modal ? 1 : 0);
 -        PROP_SETA32(self->super.window, net_wm_state, atom, states, nstates);
++        OBT_PROP_SETA32(self->super.window, NET_WM_STATE, ATOM,
++                        states, nstates);
+     }
+     else
 -        PROP_ERASE(self->super.window, wm_transient_for);
++        OBT_PROP_ERASE(self->super.window, WM_TRANSIENT_FOR);
  
      /* set up the dialog and render it */
      prompt_layout(self);
Simple merge
diff --cc render/theme.c
Simple merge
diff --cc render/theme.h
Simple merge