Hello,
regarding that bug:
https://bugs.launchpad.net/ubuntu/+source/emerald/+bug/726229
The situation is so, that Ubuntu is delivering for Oneiric (11.10)
compiz based on master 0.9.5, but emerald based on compiz++ branch
with API level of 0.9.4. The decor_quads_to_property() has changed,
thats that crash.
As appropriate, I forward ported the changes in gtk-window-decorator
to emerald. In between it had worked, but now after cleaning and completing
compiz segfaults in "decor" plugin. So, please find attached my patch:
- patch-emerald.txt
Thats now time for code-review, as suggested earlier on mailing list.
Thanks in advance,
Roland "Test-tools" Baer
--
/------------------------------------------------------------------------------\
| Verifysoft Technology GmbH | Registergericht: Amtsgericht Freiburg HRB 472242|
| In der Spoeck 10 | Geschaeftsfuehrer: Klaus Lambertz |
| 77656 Offenburg | Telefon: +49-781-12781189 Skype: twiddletec |
\------------------------------------------------------------------------------/
diff --git a/src/main.c b/src/main.c
index eddd11c..4b06e91 100644
--- a/src/main.c
+++ b/src/main.c
@@ -38,8 +38,22 @@
#define wnck_window_get_geometry wnck_window_get_client_window_geometry
#endif
+#define WINDOW_TYPE_FRAMES_NUM 5
+
void reload_all_settings(int sig);
+static unsigned int
+populate_frame_type (decor_t *d);
+
+static unsigned int
+populate_frame_state (decor_t *d);
+
+static unsigned int
+populate_frame_actions (decor_t *d);
+
+static const gchar *
+get_frame_type (WnckWindow *win);
+
GdkPixmap *pdeb;
static gboolean do_reload = FALSE;
@@ -93,6 +107,10 @@ static Atom emerald_sigusr1_atom;
static Atom utf8_string_atom;
+static Atom net_wm_state_atom;
+static Atom net_wm_state_modal_atom;
+
+
static Time dm_sn_timestamp;
#define C(name) { 0, XC_ ## name }
@@ -472,12 +490,16 @@ decor_update_blur_property (decor_t *d,
static void decor_update_window_property(decor_t * d)
{
- long data[256];
+ long *data;
Display *xdisplay = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
window_settings *ws = d->fs->ws;
decor_extents_t maxextents;
decor_extents_t extents = ws->win_extents;
gint nQuad;
+ unsigned int nOffset = 1;
+ unsigned int frame_type = populate_frame_type (d);
+ unsigned int frame_state = populate_frame_state (d);
+ unsigned int frame_actions = populate_frame_actions (d);
decor_quad_t quads[N_QUADS_MAX];
int w, h;
gint stretch_offset;
@@ -504,15 +526,19 @@ static void decor_update_window_property(decor_t * d)
else
maxextents = extents;
- decor_quads_to_property(data, GDK_PIXMAP_XID(d->pixmap),
- &extents, &maxextents, &maxextents, &maxextents, 0,
0, quads, nQuad);
-
+ data = decor_alloc_property (nOffset, WINDOW_DECORATION_TYPE_PIXMAP);
+ decor_quads_to_property (data, nOffset - 1, GDK_PIXMAP_XID (d->pixmap),
+ &extents, &extents,
+ &extents, &extents,
+ 0 /* ICON_SPACE + d->button_width */,
+ 0,
+ quads, nQuad, frame_type, frame_state,
frame_actions);
gdk_error_trap_push();
XChangeProperty(xdisplay, d->prop_xid,
win_decor_atom,
XA_INTEGER,
32, PropModeReplace, (guchar *) data,
- BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
+ PROP_HEADER_SIZE +BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
XSync(xdisplay, FALSE);
gdk_error_trap_pop();
@@ -554,6 +580,7 @@ static void decor_update_window_property(decor_t * d)
&bottom, w / 2,
&left, h / 2,
&right, h / 2);
+ free(data);
}
static int
@@ -1925,10 +1952,14 @@ static void draw_shadow_window(decor_t * d)
static void decor_update_switcher_property(decor_t * d)
{
- long data[256];
+ long *data;
Display *xdisplay = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
gint nQuad;
decor_quad_t quads[N_QUADS_MAX];
+ unsigned int nOffset = 1;
+ unsigned int frame_type = populate_frame_type (d);
+ unsigned int frame_state = populate_frame_state (d);
+ unsigned int frame_actions = populate_frame_actions (d);
window_settings *ws = d->fs->ws;
decor_extents_t extents = ws->switcher_extents;
GtkStyle *style;
@@ -1936,8 +1967,10 @@ static void decor_update_switcher_property(decor_t * d)
nQuad = set_switcher_quads(quads, d->width, d->height, ws);
- decor_quads_to_property(data, GDK_PIXMAP_XID(d->pixmap),
- &extents, &extents, &extents, &extents, 0, 0,
quads, nQuad);
+ data = decor_alloc_property (nOffset, WINDOW_DECORATION_TYPE_PIXMAP);
+ decor_quads_to_property (data, nOffset - 1, GDK_PIXMAP_XID (d->pixmap),
+ &extents, &extents, &extents, &extents,
+ 0, 0, quads, nQuad, frame_type, frame_state,
frame_actions);
style = gtk_widget_get_style (style_window);
@@ -1956,6 +1989,8 @@ static void decor_update_switcher_property(decor_t * d)
XA_INTEGER, 32, PropModeReplace, (guchar *) fgColor, 4);
XSync(xdisplay, FALSE);
gdk_error_trap_pop();
+
+ free(data);
}
static void draw_switcher_background(decor_t * d)
@@ -2336,11 +2371,11 @@ static void
update_default_decorations(GdkScreen * screen, frame_settings * fs_act,
frame_settings * fs_inact)
{
- long data[256];
+ long *data;
Window xroot;
GdkDisplay *gdkdisplay = gdk_display_get_default();
Display *xdisplay = gdk_x11_display_get_xdisplay(gdkdisplay);
- Atom bareAtom, normalAtom, activeAtom;
+ Atom bareAtom, activeAtom;
decor_t d;
gint nQuad;
decor_quad_t quads[N_QUADS_MAX];
@@ -2352,20 +2387,21 @@ update_default_decorations(GdkScreen * screen,
frame_settings * fs_act,
xroot = RootWindowOfScreen(gdk_x11_screen_get_xscreen(screen));
bareAtom = XInternAtom(xdisplay, DECOR_BARE_ATOM_NAME, FALSE);
- normalAtom = XInternAtom(xdisplay, DECOR_NORMAL_ATOM_NAME, FALSE);
activeAtom = XInternAtom(xdisplay, DECOR_ACTIVE_ATOM_NAME, FALSE);
if (ws->shadow_pixmap)
{
int width, height;
+ long *data = decor_alloc_property (1, WINDOW_DECORATION_TYPE_PIXMAP);
+
gdk_drawable_get_size(ws->shadow_pixmap, &width, &height);
nQuad = set_shadow_quads(quads, width, height, ws);
- decor_quads_to_property(data, GDK_PIXMAP_XID(ws->shadow_pixmap),
+ decor_quads_to_property(data, 0, GDK_PIXMAP_XID(ws->shadow_pixmap),
&ws->shadow_extents, &ws->shadow_extents,
&ws->shadow_extents, &ws->shadow_extents, 0, 0,
- quads, nQuad);
+ quads, nQuad, 0, 0, 0);
XChangeProperty(xdisplay, xroot,
bareAtom,
@@ -2373,10 +2409,13 @@ update_default_decorations(GdkScreen * screen,
frame_settings * fs_act,
32, PropModeReplace, (guchar *) data,
BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
+ free(data);
}
else
XDeleteProperty(xdisplay, xroot, bareAtom);
+ data = decor_alloc_property (WINDOW_TYPE_FRAMES_NUM * 2,
WINDOW_DECORATION_TYPE_PIXMAP); /* FIXME, first parameter most likely to be 1 */
+
d.width =
ws->left_space + ws->left_corner_space + 200 +
ws->right_corner_space + ws->right_space;
@@ -2423,17 +2462,8 @@ update_default_decorations(GdkScreen * screen,
frame_settings * fs_act,
(*d.draw) (&d);
- decor_quads_to_property(data, GDK_PIXMAP_XID(d.p_inactive),
- &extents, &extents, &extents, &extents, 0, 0,
quads, nQuad);
-
- XChangeProperty(xdisplay, xroot,
- normalAtom,
- XA_INTEGER,
- 32, PropModeReplace, (guchar *) data,
- BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
-
- decor_quads_to_property(data, GDK_PIXMAP_XID(d.p_active),
- &extents, &extents, &extents, &extents, 0, 0,
quads, nQuad);
+ decor_quads_to_property(data, 0, GDK_PIXMAP_XID(d.p_active),
+ &extents, &extents, &extents, &extents, 0, 0,
quads, nQuad, 0, 0, 0);
XChangeProperty(xdisplay, xroot,
activeAtom,
@@ -2441,6 +2471,8 @@ update_default_decorations(GdkScreen * screen,
frame_settings * fs_act,
32, PropModeReplace, (guchar *) data,
BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
}
+
+ free(data);
}
static gboolean get_window_prop(Window xwindow, Atom atom, Window * val)
@@ -5025,6 +5057,144 @@ static int update_shadow(frame_settings * fs)
return 1;
}
+
+/*
+ * populate_type
+ *
+ * Returns: void
+ * Description: Sets the window type flags for compiz to know what window type
+ * this decoration is for
+ *
+ */
+static unsigned int
+populate_frame_type (decor_t *d)
+{
+ /* FIXME: This would be nicer if Wnck actually worked here,
+ * but for now we need to use that frame string since that's
+ * the only way we can get the modal_dialog type */
+
+ const unsigned int n_type_strings = 5;
+ unsigned int frame_type = 0;
+ unsigned int i;
+ WnckWindow *win;
+
+ struct typestrings {
+ const char *type;
+ unsigned int flag;
+ } type_strings[] =
+ {
+ {"normal", DECOR_WINDOW_TYPE_NORMAL },
+ {"dialog", DECOR_WINDOW_TYPE_DIALOG },
+ {"modal_dialog", DECOR_WINDOW_TYPE_MODAL_DIALOG },
+ {"menu", DECOR_WINDOW_TYPE_MENU },
+ {"utility", DECOR_WINDOW_TYPE_UTILITY}
+ };
+
+ win = wnck_window_get(d->prop_xid);
+
+ if (win) {
+ const gchar* t = get_frame_type(win);
+ for (i = 0; i < n_type_strings; i++)
+ {
+ if (strcmp (t, type_strings[i].type) == 0)
+ frame_type |= type_strings[i].flag;
+ }
+ }
+
+ return frame_type;
+}
+
+/*
+ * populate_state
+ *
+ * Returns void
+ * Description: Sets the window state flags for compiz to know what state of
+ * window this decoration is for
+ */
+static unsigned int
+populate_frame_state (decor_t *d)
+{
+ unsigned int frame_state = 0;
+
+ WnckWindowState win_state;
+ const unsigned int n_state_bits = 3;
+ unsigned int i;
+
+ if (d->active)
+ frame_state |= DECOR_WINDOW_STATE_FOCUS;
+
+ struct typestrings {
+ unsigned int wnck_flag;
+ unsigned int decor_flag;
+ } state_bits[] =
+ {
+ { WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY,
DECOR_WINDOW_STATE_MAXIMIZED_VERT },
+ { WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY,
DECOR_WINDOW_STATE_MAXIMIZED_HORZ },
+ { WNCK_WINDOW_STATE_SHADED, DECOR_WINDOW_STATE_SHADED }
+ };
+
+ /* Not possible to match further than active or not if there is
+ * no window but FIXME we might want to do that later down the line */
+
+ win_state = d->state;
+
+ for (i = 0; i < n_state_bits; i++)
+ {
+ if (win_state & state_bits[i].wnck_flag)
+ frame_state |= state_bits[i].decor_flag;
+ }
+
+ return frame_state;
+}
+
+/*
+ * populate_actions
+ *
+ * Returns void
+ * Description: Sets the window actions flags for compiz to know what state of
+ * window this decoration is for
+ */
+static unsigned int
+populate_frame_actions (decor_t *d)
+{
+ unsigned int frame_actions = 0;
+
+ WnckWindowActions win_actions = d->actions;
+ const unsigned int n_action_bits = 16;
+ unsigned int i;
+ struct typestrings {
+ unsigned int decor_flag;
+ unsigned int wnck_flag;
+ } action_bits[] =
+ {
+ { DECOR_WINDOW_ACTION_RESIZE_HORZ, WNCK_WINDOW_ACTION_RESIZE },
+ { DECOR_WINDOW_ACTION_RESIZE_VERT, WNCK_WINDOW_ACTION_RESIZE },
+ { DECOR_WINDOW_ACTION_CLOSE, WNCK_WINDOW_ACTION_CLOSE },
+ { DECOR_WINDOW_ACTION_MINIMIZE, WNCK_WINDOW_ACTION_MINIMIZE },
+ { DECOR_WINDOW_ACTION_UNMINIMIZE, WNCK_WINDOW_ACTION_UNMINIMIZE },
+ { DECOR_WINDOW_ACTION_MAXIMIZE_HORZ,
WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY },
+ { DECOR_WINDOW_ACTION_MAXIMIZE_VERT,
WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY },
+ { DECOR_WINDOW_ACTION_UNMAXIMIZE_HORZ,
WNCK_WINDOW_ACTION_UNMAXIMIZE_HORIZONTALLY },
+ { DECOR_WINDOW_ACTION_UNMAXIMIZE_VERT,
WNCK_WINDOW_ACTION_UNMAXIMIZE_VERTICALLY },
+ { DECOR_WINDOW_ACTION_SHADE, WNCK_WINDOW_ACTION_SHADE },
+ { DECOR_WINDOW_ACTION_UNSHADE, WNCK_WINDOW_ACTION_UNSHADE },
+ { DECOR_WINDOW_ACTION_STICK, WNCK_WINDOW_ACTION_STICK },
+ { DECOR_WINDOW_ACTION_UNSTICK, WNCK_WINDOW_ACTION_UNSTICK },
+ { DECOR_WINDOW_ACTION_FULLSCREEN, WNCK_WINDOW_ACTION_FULLSCREEN },
+ { DECOR_WINDOW_ACTION_ABOVE, WNCK_WINDOW_ACTION_ABOVE },
+ { DECOR_WINDOW_ACTION_BELOW, WNCK_WINDOW_ACTION_BELOW },
+ };
+
+ for (i = 0; i < n_action_bits; i++)
+ {
+ if (win_actions & action_bits[i].wnck_flag)
+ frame_actions |= action_bits[i].decor_flag;
+ }
+
+ return frame_actions;
+}
+
+
static void titlebar_font_changed(window_settings * ws)
{
PangoFontMetrics *metrics;
@@ -5536,6 +5706,9 @@ int main(int argc, char *argv[])
XInternAtom(xdisplay, "_COMPIZ_TOOLKIT_ACTION_FORCE_QUIT_DIALOG",
FALSE);
+ net_wm_state_atom = XInternAtom (xdisplay,"_NET_WM_STATE", 0);
+ net_wm_state_modal_atom = XInternAtom (xdisplay, "_NET_WM_STATE_MODAL", 0);
+
emerald_sigusr1_atom = XInternAtom(xdisplay, "emerald-sigusr1", FALSE);
utf8_string_atom = XInternAtom(xdisplay, "UTF8_STRING", FALSE);
@@ -5629,3 +5802,51 @@ int main(int argc, char *argv[])
return 0;
}
+
+static const gchar *
+get_frame_type (WnckWindow *win)
+{
+ WnckWindowType wnck_type = wnck_window_get_window_type (win);
+
+ switch (wnck_type)
+ {
+ case WNCK_WINDOW_NORMAL:
+ return "normal";
+ case WNCK_WINDOW_DIALOG:
+ {
+ Atom actual;
+ int result, format;
+ unsigned long n, left;
+ unsigned char *data;
+
+ result = XGetWindowProperty (gdk_x11_get_default_xdisplay (),
wnck_window_get_xid (win),
+ net_wm_state_atom,
+ 0L, 1024L, FALSE, XA_ATOM, &actual,
&format,
+ &n, &left, &data);
+
+ if (result == Success && data)
+ {
+ Atom *a = (Atom *) data;
+
+ while (n--)
+ if (*a++ == net_wm_state_modal_atom)
+ {
+ XFree ((void *) data);
+ return "modal_dialog";
+ }
+
+
+ }
+
+ return "dialog";
+ }
+ case WNCK_WINDOW_MENU:
+ return "menu";
+ case WNCK_WINDOW_UTILITY:
+ return "utility";
+ default:
+ return "bare";
+ }
+
+ return "normal";
+}
_______________________________________________
dev mailing list
[email protected]
http://lists.compiz.org/mailman/listinfo/dev