Hello,

looks now better, doesn't kill compiz any more, please find attached:
- emerald-patch2.txt (against compiz++ branch)
I'm quite sure that the changes itself are correct, until here.

Now we have the next show stopper, in ~/.xsession-errors multiple
compiz (decor) - Warn: No default decoration found, placement will not be 
correct

The decor plugin has significantly changed between 0.9.4 and 0.9.5
Could someone have a look? 

Thanks in advance,

       Roland "Test-tools" Baer

On Thu, Aug 11, 2011 at 01:10:02PM +0200, Roland Baer wrote:
> 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


-- 
/------------------------------------------------------------------------------\
| 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/include/emerald.h b/include/emerald.h
index 53e02a6..70fb087 100644
--- a/include/emerald.h
+++ b/include/emerald.h
@@ -321,6 +321,7 @@ typedef struct _decor
     GdkPixbuf        *icon_pixbuf;
     WnckWindowState   state;
     WnckWindowActions actions;
+    WnckWindowType    type;
     XID                      prop_xid;
     GtkWidget        *force_quit_dialog;
     frame_settings * fs;
diff --git a/src/main.c b/src/main.c
index eddd11c..15ef102 100644
--- a/src/main.c
+++ b/src/main.c
@@ -30,16 +30,23 @@
 //#define BASE_PROP_SIZE 12
 //#define QUAD_PROP_SIZE 9
 
-#ifndef DECOR_INTERFACE_VERSION
-#define DECOR_INTERFACE_VERSION 0
-#endif
-
 #if defined (HAVE_LIBWNCK_2_19_4)
 #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);
+
 GdkPixmap *pdeb;
 static gboolean do_reload = FALSE;
 
@@ -93,6 +100,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 +483,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 +519,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 +573,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 +1945,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 +1960,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 +1982,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 +2364,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 +2380,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 +2402,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 +2455,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 +2464,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)
@@ -2898,6 +2923,14 @@ static void update_window_decoration_icon(WnckWindow * 
win)
     }
 }
 
+static void update_window_decoration_type(WnckWindow * win)
+{
+    decor_t *d = g_object_get_data(G_OBJECT(win), "decor");
+
+    d->type = wnck_window_get_window_type(win);
+}
+
+
 static void update_window_decoration_state(WnckWindow * win)
 {
     decor_t *d = g_object_get_data(G_OBJECT(win), "decor");
@@ -3125,6 +3158,7 @@ static void add_frame_window(WnckWindow * win, Window 
frame)
 
 
        update_window_decoration_state(win);
+       update_window_decoration_type(win);
        update_window_decoration_actions(win);
        update_window_decoration_icon(win);
        update_window_decoration_size(win);
@@ -3463,6 +3497,7 @@ static void window_state_changed(WnckWindow * win)
     if (d->decorated)
     {
        update_window_decoration_state(win);
+       update_window_decoration_type(win);
        update_button_regions(d);
        stop_button_fade(d);
        update_window_decoration_size(win);
@@ -5025,6 +5060,161 @@ 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;
+
+    switch (d->type) 
+      {
+      default:
+      case WNCK_WINDOW_NORMAL:
+       frame_type = DECOR_WINDOW_TYPE_NORMAL;
+         break;
+      case WNCK_WINDOW_DIALOG:
+       frame_type = DECOR_WINDOW_TYPE_DIALOG;
+       {
+         Atom          actual;
+         int           result, format;
+         unsigned long n, left;
+         unsigned char *data;
+         
+         result = XGetWindowProperty (gdk_x11_get_default_xdisplay (), 
+                                      d->prop_xid,
+                                      net_wm_state_atom,
+                                      0L, 1024L, FALSE, XA_ATOM, &actual, 
&format,
+                                      &n, &left, &data);
+         
+         if (result == Success && data)
+           {
+             Atom *a = (Atom *) data;
+             
+             while (n-- && frame_type != DECOR_WINDOW_TYPE_MODAL_DIALOG)
+               if (*a++ == net_wm_state_modal_atom)
+                 {
+                   XFree ((void *) data);
+                   frame_type = DECOR_WINDOW_TYPE_MODAL_DIALOG;
+                 }
+           }
+       }
+      break;
+      case WNCK_WINDOW_MENU:
+       frame_type = DECOR_WINDOW_TYPE_MENU;
+         break;
+      case WNCK_WINDOW_UTILITY:
+       frame_type = DECOR_WINDOW_TYPE_UTILITY;
+         break;
+      }
+
+    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 +5726,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 +5822,4 @@ int main(int argc, char *argv[])
 
     return 0;
 }
+
_______________________________________________
dev mailing list
[email protected]
http://lists.compiz.org/mailman/listinfo/dev

Reply via email to