summaryrefslogtreecommitdiffstats
path: root/compton.c
diff options
context:
space:
mode:
authorRichard Grenville <[email protected]>2013-08-22 21:15:04 +0800
committerRichard Grenville <[email protected]>2013-08-22 21:44:15 +0800
commitcd62d55a5b62c97cff3e60ebc0b3a66b8c7fa891 (patch)
treece698806bb2637abccb679e118ef9b21c66c7ad3 /compton.c
parent8f6c2d89ea6883d5cee95cfeb83618c5c11cbf12 (diff)
downloadtdebase-cd62d55a5b62c97cff3e60ebc0b3a66b8c7fa891.tar.gz
tdebase-cd62d55a5b62c97cff3e60ebc0b3a66b8c7fa891.zip
Improvement #137: --xinerama-shadow-crop
Add --xinerama-shadow-crop to crop shadow to current Xinerama screen. Thanks to Feltzer for suggestion.
Diffstat (limited to 'compton.c')
-rw-r--r--compton.c70
1 files changed, 69 insertions, 1 deletions
diff --git a/compton.c b/compton.c
index 474d2a277..6fe927986 100644
--- a/compton.c
+++ b/compton.c
@@ -1817,6 +1817,12 @@ paint_all(session_t *ps, XserverRegion region, XserverRegion region_real, win *t
if (ps->o.clear_shadow && w->border_size)
XFixesSubtractRegion(ps->dpy, reg_paint, reg_paint, w->border_size);
+#ifdef CONFIG_XINERAMA
+ if (ps->o.xinerama_shadow_crop && w->xinerama_scr >= 0)
+ XFixesIntersectRegion(ps->dpy, reg_paint, reg_paint,
+ ps->xinerama_scr_regs[w->xinerama_scr]);
+#endif
+
// Detect if the region is empty before painting
{
reg_data_t cache_reg = REG_DATA_INIT;
@@ -2035,6 +2041,8 @@ map_win(session_t *ps, Window id) {
w->a.map_state = IsViewable;
+ cxinerama_win_upd_scr(ps, w);
+
// Set focused to false
bool focused_real = false;
if (ps->o.track_focus && ps->o.use_ewmh_active_win
@@ -2677,6 +2685,9 @@ add_win(session_t *ps, Window id, Window prev) {
.id = None,
.a = { },
+#ifdef CONFIG_XINERAMA
+ .xinerama_scr = -1,
+#endif
.pictfmt = NULL,
.mode = WMODE_TRANS,
.damaged = false,
@@ -2989,8 +3000,10 @@ configure_win(session_t *ps, XConfigureEvent *ce) {
add_damage(ps, damage);
}
- if (factor_change)
+ if (factor_change) {
+ cxinerama_win_upd_scr(ps, w);
win_on_factor_change(ps, w);
+ }
}
// override_redirect flag cannot be changed after window creation, as far
@@ -4417,6 +4430,15 @@ usage(int ret) {
" should not be painted in, such as a dock window region.\n"
" Use --shadow-exclude-reg \'x10+0-0\', for example, if the 10 pixels\n"
" on the bottom of the screen should not have shadows painted on.\n"
+#undef WARNING
+#ifndef CONFIG_XINERAMA
+#define WARNING WARNING_DISABLED
+#else
+#define WARNING
+#endif
+ "--xinerama-shadow-crop\n"
+ " Crop shadow of a window fully on a particular Xinerama screen to the\n"
+ " screen." WARNING "\n"
"--backend backend\n"
" Choose backend. Possible choices are xrender and glx" WARNING ".\n"
"--glx-no-stencil\n"
@@ -5245,6 +5267,7 @@ get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass) {
{ "opacity-rule", required_argument, NULL, 304 },
{ "shadow-exclude-reg", required_argument, NULL, 305 },
{ "paint-exclude", required_argument, NULL, 306 },
+ { "xinerama-shadow-crop", no_argument, NULL, 307 },
// Must terminate with a NULL entry
{ NULL, 0, NULL, 0 },
};
@@ -5492,6 +5515,7 @@ get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass) {
// --paint-exclude
condlst_add(ps, &ps->o.paint_blacklist, optarg);
break;
+ P_CASEBOOL(307, xinerama_shadow_crop);
default:
usage(1);
break;
@@ -6343,6 +6367,35 @@ mainloop(session_t *ps) {
return true;
}
+static void
+cxinerama_upd_scrs(session_t *ps) {
+#ifdef CONFIG_XINERAMA
+ free_xinerama_info(ps);
+
+ if (!ps->o.xinerama_shadow_crop || !ps->xinerama_exists) return;
+
+ if (!XineramaIsActive(ps->dpy)) return;
+
+ ps->xinerama_scrs = XineramaQueryScreens(ps->dpy, &ps->xinerama_nscrs);
+
+ // Just in case the shit hits the fan...
+ if (!ps->xinerama_nscrs) {
+ cxfree(ps->xinerama_scrs);
+ ps->xinerama_scrs = NULL;
+ return;
+ }
+
+ ps->xinerama_scr_regs = allocchk(malloc(sizeof(XserverRegion *)
+ * ps->xinerama_nscrs));
+ for (int i = 0; i < ps->xinerama_nscrs; ++i) {
+ const XineramaScreenInfo * const s = &ps->xinerama_scrs[i];
+ XRectangle r = { .x = s->x_org, .y = s->y_org,
+ .width = s->width, .height = s->height };
+ ps->xinerama_scr_regs[i] = XFixesCreateRegion(ps->dpy, &r, 1);
+ }
+#endif
+}
+
/**
* Initialize a session.
*
@@ -6409,6 +6462,7 @@ session_init(session_t *ps_old, int argc, char **argv) {
.shadow_blacklist = NULL,
.shadow_ignore_shaped = false,
.respect_prop_shadow = false,
+ .xinerama_shadow_crop = false,
.wintype_fade = { false },
.fade_in_step = 0.028 * OPAQUE,
@@ -6663,6 +6717,17 @@ session_init(session_t *ps_old, int argc, char **argv) {
ps->o.dbe = false;
}
+ // Query X Xinerama extension
+ if (ps->o.xinerama_shadow_crop) {
+#ifdef CONFIG_XINERAMA
+ int xinerama_event = 0, xinerama_error = 0;
+ if (XineramaQueryExtension(ps->dpy, &xinerama_event, &xinerama_error))
+ ps->xinerama_exists = true;
+#else
+ printf_errf("(): Xinerama support not compiled in.");
+#endif
+ }
+
rebuild_screen_reg(ps);
// Overlay must be initialized before double buffer, and before creation
@@ -6697,6 +6762,8 @@ session_init(session_t *ps_old, int argc, char **argv) {
if (!vsync_init(ps))
exit(1);
+ cxinerama_upd_scrs(ps);
+
// Create registration window
if (!ps->reg_win && !register_cm(ps))
exit(1);
@@ -6923,6 +6990,7 @@ session_destroy(session_t *ps) {
free(ps->pfds_read);
free(ps->pfds_write);
free(ps->pfds_except);
+ free_xinerama_info(ps);
#ifdef CONFIG_VSYNC_OPENGL
glx_destroy(ps);