13
13
You should have received a copy of the GNU General Public License
14
14
along with this program; if not, write to the Free Software
15
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15
Foundation, Inc., Inc., 51 Franklin Street, Fifth Floor, Boston,
17
19
xcompmgr - (c) 2003 Keith Packard
18
20
metacity - (c) 2003, 2004 Red Hat, Inc.
19
xfwm4 - (c) 2005-2008 Olivier Fourdan
21
xfwm4 - (c) 2005-2009 Olivier Fourdan
48
50
#include <X11/extensions/Xrender.h>
50
52
#ifndef SHADOW_RADIUS
51
#define SHADOW_RADIUS 6
53
#define SHADOW_RADIUS 12
52
54
#endif /* SHADOW_RADIUS */
54
#ifndef SHADOW_OPACITY
55
#define SHADOW_OPACITY 0.66
56
#endif /* SHADOW_OPACITY */
58
56
#ifndef SHADOW_OFFSET_X
59
#define SHADOW_OFFSET_X (SHADOW_RADIUS * -3 /2)
57
#define SHADOW_OFFSET_X (-3 * SHADOW_RADIUS / 2)
60
58
#endif /* SHADOW_OFFSET_X */
62
60
#ifndef SHADOW_OFFSET_Y
63
#define SHADOW_OFFSET_Y (SHADOW_RADIUS * -5 / 4)
61
#define SHADOW_OFFSET_Y (-3 * SHADOW_RADIUS / 2)
64
62
#endif /* SHADOW_OFFSET_Y */
66
64
/* Some convenient macros */
69
67
!FLAG_TEST (cw->c->flags, CLIENT_FLAG_FULLSCREEN))
70
68
#define WIN_NO_SHADOW(cw) ((cw->c) && \
71
69
(FLAG_TEST (cw->c->flags, CLIENT_FLAG_FULLSCREEN | CLIENT_FLAG_BELOW) || \
72
(cw->c->type & (WINDOW_DOCK | WINDOW_DESKTOP))))
70
(cw->c->type & WINDOW_DESKTOP)))
73
71
#define WIN_IS_DOCK(cw) (WIN_HAS_CLIENT(cw) && (cw->c->type & WINDOW_DOCK))
74
72
#define WIN_IS_OVERRIDE(cw) (cw->attr.override_redirect)
75
73
#define WIN_IS_ARGB(cw) (cw->argb)
76
#define WIN_IS_OPAQUE(cw) (((cw->opacity == NET_WM_OPAQUE) && !WIN_IS_ARGB(cw)) || (cw->screen_info->wins_unredirected))
74
#define WIN_IS_OPAQUE(cw) ((cw->opacity == NET_WM_OPAQUE) && !WIN_IS_ARGB(cw))
77
75
#define WIN_IS_NATIVE_OPAQUE(cw) ((cw->native_opacity) && !WIN_IS_ARGB(cw))
78
76
#define WIN_IS_FULLSCREEN(cw) ((cw->attr.x <= 0) && \
79
77
(cw->attr.y <= 0) && \
87
85
#define WIN_IS_DAMAGED(cw) (cw->damaged)
88
86
#define WIN_IS_REDIRECTED(cw) (cw->redirected)
90
#define USE_IDLE_REPAINT
88
/* Set TIMEOUT_REPAINT to 0 to disable timeout repaint */
89
#define TIMEOUT_REPAINT 20 /* (1/50 sec.) */
92
91
typedef struct _CWindow CWindow;
935
934
!WIN_IS_OVERRIDE(cw) &&
936
935
!WIN_NO_SHADOW(cw) &&
937
936
!WIN_IS_DOCK(cw) &&
938
(WIN_HAS_FRAME(cw) || !(WIN_IS_ARGB(cw) || WIN_IS_SHAPED(cw)))))
937
(WIN_HAS_FRAME(cw) || !(WIN_IS_ARGB(cw) || WIN_IS_SHAPED(cw)))) ||
938
(screen_info->params->show_dock_shadow &&
940
!WIN_NO_SHADOW(cw) &&
941
!WIN_IS_OVERRIDE(cw) &&
942
(!(WIN_IS_ARGB(cw) || WIN_IS_SHAPED(cw)))))
948
952
double shadow_opacity;
949
953
shadow_opacity = (double) screen_info->params->frame_opacity
952
/ (NET_WM_OPAQUE * 100.0);
954
* (screen_info->params->shadow_opacity / 100.0)
956
/ (NET_WM_OPAQUE * 100.0);
954
958
cw->shadow = shadow_picture (screen_info, shadow_opacity,
955
959
cw->attr.width + 2 * cw->attr.border_width,
1083
1087
cw->redirected = FALSE;
1085
1089
XCompositeUnredirectWindow (display_info->dpy, cw->id, display_info->composite_mode);
1086
XSync (display_info->dpy, FALSE);
1088
1090
TRACE ("Window 0x%lx unredirected, wins_unredirected is %i", cw->id, screen_info->wins_unredirected);
1385
1387
XFixesDestroyRegion (dpy, paint_region);
1392
remove_timeouts (ScreenInfo *screen_info)
1394
if (screen_info->compositor_timeout_id != 0)
1396
g_source_remove (screen_info->compositor_timeout_id);
1397
screen_info->compositor_timeout_id = 0;
1400
#endif /* TIMEOUT_REPAINT */
1389
1403
repair_screen (ScreenInfo *screen_info)
1410
#ifdef USE_IDLE_REPAINT
1430
compositor_timeout_cb (gpointer data)
1432
ScreenInfo *screen_info;
1434
screen_info = (ScreenInfo *) data;
1435
screen_info->compositor_timeout_id = 0;
1436
repair_screen (screen_info);
1440
#endif /* TIMEOUT_REPAINT */
1412
remove_timeouts (DisplayInfo *display_info)
1443
add_repair (ScreenInfo *screen_info)
1414
if (display_info->compositor_idle_id != 0)
1416
g_source_remove (display_info->compositor_idle_id);
1417
display_info->compositor_idle_id = 0;
1420
if (display_info->compositor_timeout_id != 0)
1422
g_source_remove (display_info->compositor_timeout_id);
1423
display_info->compositor_timeout_id = 0;
1446
if (screen_info->compositor_timeout_id != 0)
1450
screen_info->compositor_timeout_id =
1451
g_timeout_add (TIMEOUT_REPAINT,
1452
compositor_timeout_cb, screen_info);
1453
#endif /* TIMEOUT_REPAINT */
1426
#endif /* USE_IDLE_REPAINT */
1456
#if TIMEOUT_REPAINT == 0
1429
1458
repair_display (DisplayInfo *display_info)
1433
1462
g_return_if_fail (display_info);
1434
1463
TRACE ("entering repair_display");
1436
#ifdef USE_IDLE_REPAINT
1437
remove_timeouts (display_info);
1438
#endif /* USE_IDLE_REPAINT */
1439
1465
for (screens = display_info->screens; screens; screens = g_slist_next (screens))
1441
repair_screen ((ScreenInfo *) screens->data);
1445
#ifdef USE_IDLE_REPAINT
1447
compositor_idle_cb (gpointer data)
1449
DisplayInfo *display_info = (DisplayInfo *) data;
1451
display_info->compositor_idle_id = 0;
1452
repair_display (display_info);
1458
compositor_timeout_cb (gpointer data)
1460
DisplayInfo *display_info;
1462
display_info = (DisplayInfo *) data;
1463
display_info->compositor_timeout_id = 0;
1464
repair_display (display_info);
1468
#endif /* USE_IDLE_REPAINT */
1471
add_repair (DisplayInfo *display_info)
1473
#ifdef USE_IDLE_REPAINT
1474
if (display_info->compositor_idle_id != 0)
1478
display_info->compositor_idle_id =
1479
g_idle_add_full (G_PRIORITY_HIGH_IDLE,
1480
compositor_idle_cb, display_info, NULL);
1481
if (display_info->compositor_timeout_id != 0)
1486
display_info->compositor_timeout_id =
1487
g_timeout_add (50 /* ms */,
1488
compositor_timeout_cb, display_info);
1489
#endif /* USE_IDLE_REPAINT */
1467
add_repair ((ScreenInfo *) screens->data);
1493
1473
add_damage (ScreenInfo *screen_info, XserverRegion damage)
1747
1727
XFixesDestroyRegion (display_info->dpy, cw->extents);
1749
1729
cw->extents = win_extents (cw);
1750
add_repair (display_info);
1730
add_repair (screen_info);
1879
1858
cw->native_opacity = FALSE;
1882
cw->opacity_locked = c->opacity_locked;
1861
cw->opacity_locked = FLAG_TEST (c->xfwm_flags, XFWM_FLAG_OPACITY_LOCKED);
1883
1862
cw->opacity = c->opacity_applied;
1884
1863
cw->native_opacity = WIN_IS_OPAQUE(cw);
2062
resize_win (CWindow *cw, gint x, gint y, gint width, gint height, gint bw, gboolean shape_notify)
2041
resize_win (CWindow *cw, gint x, gint y, gint width, gint height, gint bw)
2064
2043
DisplayInfo *display_info;
2065
2044
ScreenInfo *screen_info;
2137
2116
cw->extents = win_extents (cw);
2138
2117
XFixesUnionRegion (display_info->dpy, damage, damage, cw->extents);
2119
fix_region (cw, damage);
2120
/* damage region will be destroyed by add_damage () */
2121
add_damage (screen_info, damage);
2126
reshape_win (CWindow *cw)
2128
DisplayInfo *display_info;
2129
ScreenInfo *screen_info;
2130
XserverRegion damage;
2132
g_return_if_fail (cw != NULL);
2133
TRACE ("entering reshape_win");
2135
screen_info = cw->screen_info;
2136
display_info = screen_info->display_info;
2140
if (WIN_IS_VISIBLE(cw))
2142
damage = XFixesCreateRegion (display_info->dpy, NULL, 0);
2145
XFixesCopyRegion (display_info->dpy, damage, cw->extents);
2151
XFixesDestroyRegion (display_info->dpy, cw->extents);
2157
XRenderFreePicture (display_info->dpy, cw->shadow);
2163
XFixesDestroyRegion (display_info->dpy, cw->borderSize);
2164
cw->borderSize = None;
2169
XFixesDestroyRegion (display_info->dpy, cw->clientSize);
2170
cw->clientSize = None;
2175
cw->extents = win_extents (cw);
2176
XFixesUnionRegion (display_info->dpy, damage, damage, cw->extents);
2139
2178
/* A shape notify will likely change the shadows too, so clear the extents */
2142
XFixesDestroyRegion (display_info->dpy, cw->extents);
2179
XFixesDestroyRegion (display_info->dpy, cw->extents);
2145
2182
fix_region (cw, damage);
2146
2183
/* damage region will be destroyed by add_damage () */
2147
2184
add_damage (screen_info, damage);
2192
2230
cw = find_cwindow_in_display (display_info, ev->drawable);
2193
2231
if ((cw) && WIN_IS_REDIRECTED(cw))
2233
screen_info = cw->screen_info;
2195
2234
repair_win (cw, &ev->area);
2196
display_info->damages_pending = ev->more;
2197
#ifdef USE_IDLE_REPAINT
2198
/* If there are more damages to come, we'll schedule the repair later */
2199
if (!display_info->damages_pending)
2201
add_repair (display_info);
2203
#endif /* USE_IDLE_REPAINT */
2235
screen_info->damages_pending = ev->more;
2230
2262
XClearArea (display_info->dpy, screen_info->output, 0, 0, 0, 0, TRUE);
2231
2263
XRenderFreePicture (display_info->dpy, screen_info->rootTile);
2232
2264
screen_info->rootTile = None;
2233
add_repair (display_info);
2265
add_repair (screen_info);
2280
2312
cw->opacity_locked = getOpacityLock (display_info, cw->id);
2283
cw->c->opacity_locked = cw->opacity_locked;
2315
if (cw->opacity_locked)
2317
FLAG_SET (cw->c->xfwm_flags, XFWM_FLAG_OPACITY_LOCKED);
2321
FLAG_UNSET (cw->c->xfwm_flags, XFWM_FLAG_OPACITY_LOCKED);
2339
2378
restack_win (cw, ev->above);
2340
resize_win (cw, ev->x, ev->y, ev->width, ev->height, ev->border_width, FALSE);
2379
resize_win (cw, ev->x, ev->y, ev->width, ev->height, ev->border_width);
2482
2520
cw->shaped = FALSE;
2484
resize_win (cw, cw->attr.x, cw->attr.y,
2485
ev->width + ev->x, ev->height + ev->y,
2486
cw->attr.border_width, TRUE);
2487
2523
if ((ev->shaped) && !(cw->shaped))
2489
2525
cw->shaped = TRUE;
2644
2680
cw = find_cwindow_in_display (display_info, id);
2647
resize_win (cw, x, y, width, height, 0, FALSE);
2683
resize_win (cw, x, y, width, height, 0);
2649
2685
#endif /* HAVE_COMPOSITOR */
2706
2742
compositorHandleShapeNotify (display_info, (XShapeEvent *) ev);
2708
#ifndef USE_IDLE_REPAINT
2709
if (!display_info->damages_pending)
2711
repair_display (display_info);
2713
#endif /* USE_IDLE_REPAINT */
2744
#if TIMEOUT_REPAINT == 0
2745
repair_display (display_info);
2746
#endif /* TIMEOUT_REPAINT */
2715
2748
#endif /* HAVE_COMPOSITOR */
2780
2813
#endif /* DEBUG */
2783
display_info->compositor_idle_id = 0;
2784
display_info->compositor_timeout_id = 0;
2785
display_info->damages_pending = FALSE;
2787
2816
display_info->enable_compositor = ((display_info->have_render)
2788
2817
&& (display_info->have_composite)
2789
2818
&& (display_info->have_damage)
2923
2952
screen_info->cwindows = NULL;
2924
2953
screen_info->compositor_active = TRUE;
2925
2954
screen_info->wins_unredirected = 0;
2955
screen_info->compositor_timeout_id = 0;
2956
screen_info->damages_pending = FALSE;
2927
2958
XClearArea (display_info->dpy, screen_info->output, 0, 0, 0, 0, TRUE);
2928
2959
compositorSetCMSelection (screen_info, screen_info->xfwm4_win);
3038
XSync (display_info->dpy, FALSE);
3039
3073
myDisplayGrabServer (display_info);
3040
3074
XQueryTree (display_info->dpy, screen_info->xroot, &w1, &w2, &wins, &count);
3046
c = clientGetFromWindow (screen_info, wins[i], FRAME);
3080
c = myScreenGetClientFromWindow (screen_info, wins[i], SEARCH_FRAME);
3047
3081
compositorAddWindow (display_info, wins[i], c);