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