summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIain Holmes <iain@src.gnome.org>2007-11-22 23:36:51 +0000
committerIain Holmes <iain@src.gnome.org>2007-11-22 23:36:51 +0000
commit59c097840c2b6a08b1071b2e7b149b256c11a256 (patch)
treecb2da7d77ce5a82e86625dffe13c573a5666c026
parent234f1c2ee38631c1348bf424278f44ce39752acf (diff)
downloadmetacity-59c097840c2b6a08b1071b2e7b149b256c11a256.tar.gz
Listen for transparency property changes
svn path=/branches/iains-blingtastic-bucket-o-bling/; revision=3430
-rw-r--r--src/compositor.c96
-rw-r--r--src/display.c11
-rw-r--r--src/display.h3
3 files changed, 78 insertions, 32 deletions
diff --git a/src/compositor.c b/src/compositor.c
index dd9e9e78..13a818e9 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -33,7 +33,8 @@
#include "frame.h"
#include "errors.h"
#include "compositor.h"
-
+#include "xprops.h"
+#include <X11/Xatom.h>
#include <X11/extensions/shape.h>
#include <X11/extensions/Xcomposite.h>
#include <X11/extensions/Xdamage.h>
@@ -50,6 +51,10 @@ struct _MetaCompositor
{
MetaDisplay *display;
+ Atom atom_x_root_pixmap;
+ Atom atom_x_set_root;
+ Atom atom_net_wm_window_opacity;
+
#ifdef USE_IDLE_REPAINT
guint repaint_id;
#endif
@@ -122,8 +127,7 @@ typedef struct _MetaCompWindow
#define OPAQUE 0xffffffff
#define WINDOW_SOLID 0
-#define WINDOW_TRANS 1
-#define WINDOW_ARGB 2
+#define WINDOW_ARGB 1
#define SHADOW_RADIUS 6.0
#define SHADOW_OFFSET_X (SHADOW_RADIUS * -3 / 2)
@@ -561,8 +565,8 @@ root_tile (MetaScreen *screen)
Atom pixmap_atom;
pixmap = None;
- background_atoms[0] = display->atom_x_root_pixmap;
- background_atoms[1] = display->atom_x_set_root;
+ background_atoms[0] = display->compositor->atom_x_root_pixmap;
+ background_atoms[1] = display->compositor->atom_x_set_root;
pixmap_atom = XInternAtom (display->xdisplay, "PIXMAP", False);
for (p = 0; p < 2; p++)
@@ -717,7 +721,7 @@ win_extents (MetaCompWindow *cw)
if (!cw->shadow)
{
double opacity = SHADOW_OPACITY;
- if (cw->mode == WINDOW_TRANS)
+ if (cw->opacity != (int) OPAQUE)
opacity = opacity * ((double) cw->opacity) / ((double) OPAQUE);
cw->shadow = shadow_picture (display, screen, opacity, cw->alpha_pict,
@@ -971,7 +975,7 @@ paint_windows (MetaScreen *screen,
if (shadow_clip)
XFixesDestroyRegion (xdisplay, shadow_clip);
}
-
+
if ((cw->opacity != (int) OPAQUE) && !(cw->alpha_pict))
{
cw->alpha_pict = solid_picture (display, screen, FALSE,
@@ -983,8 +987,7 @@ paint_windows (MetaScreen *screen,
cw->border_size);
XFixesSetPictureClipRegion (xdisplay, root_buffer, 0, 0,
cw->border_clip);
-
- if (cw->mode == WINDOW_TRANS || cw->mode == WINDOW_ARGB)
+ if (cw->mode == WINDOW_ARGB)
{
int x, y, wid, hei;
#ifdef HAVE_NAME_WINDOW_PIXMAP
@@ -1275,7 +1278,6 @@ determine_mode (MetaDisplay *display,
MetaCompWindow *cw)
{
XRenderPictFormat *format;
- int mode;
if (cw->alpha_pict)
{
@@ -1294,20 +1296,18 @@ determine_mode (MetaDisplay *display,
else
format = XRenderFindVisualFormat (display->xdisplay, cw->attrs.visual);
- if (format && format->type == PictTypeDirect && format->direct.alphaMask)
- mode = WINDOW_ARGB;
- else if (cw->opacity != (int) OPAQUE)
- mode = WINDOW_TRANS;
+ if ((format && format->type == PictTypeDirect && format->direct.alphaMask)
+ || cw->opacity != (int) OPAQUE)
+ cw->mode = WINDOW_ARGB;
else
- mode = WINDOW_SOLID;
- cw->mode = mode;
+ cw->mode = WINDOW_SOLID;
if (cw->extents)
{
XserverRegion damage;
damage = XFixesCreateRegion (display->xdisplay, NULL, 0);
XFixesCopyRegion (display->xdisplay, damage, cw->extents);
-
+
add_damage (display, screen, damage);
}
}
@@ -1340,6 +1340,7 @@ add_win (MetaScreen *screen,
MetaDisplay *display = screen->display;
MetaCompScreen *info = screen->compositor_data;
MetaCompWindow *cw = g_new0 (MetaCompWindow, 1);
+ gulong event_mask;
if (info == NULL)
{
@@ -1359,6 +1360,13 @@ add_win (MetaScreen *screen,
return;
}
+ /* If Metacity has decided not to manage this window then the input events
+ won't have been set on the window */
+ event_mask = cw->attrs.your_event_mask | PropertyChangeMask;
+
+ XSelectInput (display->xdisplay, xwindow, event_mask);
+
+
#ifdef HAVE_NAME_WINDOW_PIXMAP
cw->pixmap = None;
#endif
@@ -1598,8 +1606,9 @@ process_property_notify (MetaCompositor *compositor,
int p;
Atom background_atoms[2];
- background_atoms[0] = display->atom_x_root_pixmap;
- background_atoms[1] = display->atom_x_set_root;
+ /* Check for the background property changing */
+ background_atoms[0] = compositor->atom_x_root_pixmap;
+ background_atoms[1] = compositor->atom_x_set_root;
for (p = 0; p < 2; p++)
{
@@ -1615,7 +1624,7 @@ process_property_notify (MetaCompositor *compositor,
0, 0, 0, 0, TRUE);
XRenderFreePicture (display->xdisplay, info->root_tile);
info->root_tile = None;
-#ifdef USE_IDLE_REPAIR
+#ifdef USE_IDLE_REPAINT
add_repair (display);
#endif
@@ -1625,7 +1634,39 @@ process_property_notify (MetaCompositor *compositor,
}
}
- /* Handle transparency here... */
+ /* Check for the opacity changing */
+ if (event->atom == compositor->atom_net_wm_window_opacity)
+ {
+ MetaCompWindow *cw = find_window_in_display (display, event->window);
+ gulong value;
+
+ if (!cw) {
+ g_print ("No window\n");
+ return;
+ }
+
+ if (meta_prop_get_cardinal (display, event->window,
+ compositor->atom_net_wm_window_opacity,
+ &value) == FALSE)
+ value = OPAQUE;
+
+ cw->opacity = value;
+ determine_mode (display, cw->screen, cw);
+ if (cw->shadow)
+ {
+ XRenderFreePicture (display->xdisplay, cw->shadow);
+ cw->shadow = None;
+ }
+
+ if (cw->extents)
+ XFixesDestroyRegion (display->xdisplay, cw->extents);
+ cw->extents = win_extents (cw);
+
+ cw->damaged = TRUE;
+#ifdef USE_IDLE_REPAINT
+ add_repair (display);
+#endif
+ }
}
static void
@@ -1780,11 +1821,24 @@ MetaCompositor *
meta_compositor_new (MetaDisplay *display)
{
#ifdef HAVE_COMPOSITE_EXTENSIONS
+ char *atom_names[] = {
+ "_XROOTPMAP_ID",
+ "_XSETROOT_ID",
+ "_NET_WM_WINDOW_OPACITY",
+ };
+ Atom atoms[G_N_ELEMENTS(atom_names)];
MetaCompositor *compositor;
compositor = g_new (MetaCompositor, 1);
compositor->display = display;
+ g_print ("Creating %d atoms\n", G_N_ELEMENTS (atom_names));
+ XInternAtoms (display->xdisplay, atom_names, G_N_ELEMENTS (atom_names),
+ False, atoms);
+ compositor->atom_x_root_pixmap = atoms[0];
+ compositor->atom_x_set_root = atoms[1];
+ compositor->atom_net_wm_window_opacity = atoms[2];
+
#ifdef USE_IDLE_REPAINT
g_print ("Using idle repaint\n");
compositor->repaint_id = 0;
diff --git a/src/display.c b/src/display.c
index 03925cba..e0a9af3e 100644
--- a/src/display.c
+++ b/src/display.c
@@ -343,10 +343,7 @@ meta_display_open (void)
"_NET_WM_VISIBLE_ICON_NAME",
"_NET_WM_USER_TIME_WINDOW",
"_NET_WM_ACTION_ABOVE",
- "_NET_WM_ACTION_BELOW"
- "_XROOTPMAP_ID",
- "_XSETROOT_ID",
- "ESETROOT_PMAP_ID"
+ "_NET_WM_ACTION_BELOW",
};
Atom atoms[G_N_ELEMENTS(atom_names)];
@@ -408,7 +405,8 @@ meta_display_open (void)
update_window_grab_modifiers (display);
meta_prefs_add_listener (prefs_changed_callback, display);
-
+
+ g_print ("Creating %d atoms\n", G_N_ELEMENTS (atom_names));
XInternAtoms (display->xdisplay, atom_names, G_N_ELEMENTS (atom_names),
False, atoms);
display->atom_net_wm_name = atoms[0];
@@ -508,9 +506,6 @@ meta_display_open (void)
display->atom_net_wm_user_time_window = atoms[94];
display->atom_net_wm_action_above = atoms[95];
display->atom_net_wm_action_below = atoms[96];
- display->atom_x_root_pixmap = atoms[97];
- display->atom_x_set_root = atoms[98];
- display->atom_e_set_root = atoms[99];
display->prop_hooks = NULL;
meta_display_init_window_prop_hooks (display);
diff --git a/src/display.h b/src/display.h
index 1e9fa1b2..24af571f 100644
--- a/src/display.h
+++ b/src/display.h
@@ -184,9 +184,6 @@ struct _MetaDisplay
Atom atom_net_wm_visible_name;
Atom atom_net_wm_visible_icon_name;
Atom atom_net_wm_user_time_window;
- Atom atom_x_root_pixmap;
- Atom atom_x_set_root;
- Atom atom_e_set_root;
/* This is the actual window from focus events,
* not the one we last set