2003-11-10 11:45:17 +08:00
|
|
|
/*
|
2012-02-27 12:00:12 +08:00
|
|
|
* Compton - a compositor for X11
|
2003-11-10 11:45:17 +08:00
|
|
|
*
|
2012-02-27 12:00:12 +08:00
|
|
|
* Based on `xcompmgr` - Copyright (c) 2003, Keith Packard
|
2003-11-10 11:45:17 +08:00
|
|
|
*
|
2012-02-27 12:00:12 +08:00
|
|
|
* Copyright (c) 2011, Christopher Jeffrey
|
2011-11-07 09:58:30 +08:00
|
|
|
* See LICENSE for more information.
|
2003-11-10 11:45:17 +08:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2012-02-08 18:31:39 +08:00
|
|
|
#include "compton.h"
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
// === Macros ===
|
|
|
|
|
|
|
|
// #define MSTR_(s) #s
|
|
|
|
// #define MSTR(s) MSTR_(s)
|
2012-11-03 05:51:40 +08:00
|
|
|
|
|
|
|
// Use #s here to prevent macro expansion
|
2012-11-19 09:46:07 +08:00
|
|
|
/// Macro used for shortening some debugging code.
|
2012-11-03 05:51:40 +08:00
|
|
|
#define CASESTRRET(s) case s: return #s
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
// === Global constants ===
|
2012-02-27 12:00:12 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/// Name strings for window types.
|
2012-09-25 21:04:10 +08:00
|
|
|
const char *WINTYPES[NUM_WINTYPES] = {
|
|
|
|
"unknown",
|
|
|
|
"desktop",
|
|
|
|
"dock",
|
|
|
|
"toolbar",
|
|
|
|
"menu",
|
|
|
|
"utility",
|
|
|
|
"splash",
|
|
|
|
"dialog",
|
|
|
|
"normal",
|
|
|
|
"dropdown_menu",
|
|
|
|
"popup_menu",
|
|
|
|
"tooltip",
|
|
|
|
"notify",
|
|
|
|
"combo",
|
|
|
|
"dnd",
|
|
|
|
};
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/// Names of root window properties that could point to a pixmap of
|
|
|
|
/// background.
|
|
|
|
const char *background_props_str[] = {
|
2012-02-09 06:45:08 +08:00
|
|
|
"_XROOTPMAP_ID",
|
|
|
|
"_XSETROOT_ID",
|
|
|
|
0,
|
|
|
|
};
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
// === Global variables ===
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/// Pointer to current session, as a global variable. Only used by
|
|
|
|
/// <code>error()</code> and <code>reset_enable()</code>, which could not
|
|
|
|
/// have a pointer to current session passed in.
|
|
|
|
session_t *ps_g = NULL;
|
2003-11-25 01:11:00 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
// === Fading ===
|
2012-09-26 15:37:11 +08:00
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
/**
|
|
|
|
* Get the time left before next fading point.
|
|
|
|
*
|
|
|
|
* In milliseconds.
|
|
|
|
*/
|
|
|
|
static int
|
2012-11-19 09:46:07 +08:00
|
|
|
fade_timeout(session_t *ps) {
|
|
|
|
int diff = ps->o.fade_delta - get_time_ms() + ps->fade_time;
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
if (diff < 0)
|
|
|
|
diff = 0;
|
2004-07-08 15:07:26 +08:00
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
return diff;
|
2004-07-08 15:07:26 +08:00
|
|
|
}
|
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
/**
|
|
|
|
* Run fading on a window.
|
|
|
|
*
|
|
|
|
* @param steps steps of fading
|
|
|
|
*/
|
2012-02-27 12:00:12 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
run_fade(session_t *ps, win *w, unsigned steps) {
|
2012-10-29 22:00:11 +08:00
|
|
|
// If we have reached target opacity, return
|
2012-09-19 20:49:16 +08:00
|
|
|
if (w->opacity == w->opacity_tgt) {
|
|
|
|
return;
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
2004-07-08 15:07:26 +08:00
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
if (!w->fade)
|
|
|
|
w->opacity = w->opacity_tgt;
|
|
|
|
else if (steps) {
|
|
|
|
// Use double below because opacity_t will probably overflow during
|
|
|
|
// calculations
|
|
|
|
if (w->opacity < w->opacity_tgt)
|
|
|
|
w->opacity = normalize_d_range(
|
2012-11-19 09:46:07 +08:00
|
|
|
(double) w->opacity + (double) ps->o.fade_in_step * steps,
|
2012-09-19 20:49:16 +08:00
|
|
|
0.0, w->opacity_tgt);
|
|
|
|
else
|
|
|
|
w->opacity = normalize_d_range(
|
2012-11-19 09:46:07 +08:00
|
|
|
(double) w->opacity - (double) ps->o.fade_out_step * steps,
|
2012-09-19 20:49:16 +08:00
|
|
|
w->opacity_tgt, OPAQUE);
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
2004-07-08 15:07:26 +08:00
|
|
|
|
2012-10-29 22:00:11 +08:00
|
|
|
if (w->opacity != w->opacity_tgt) {
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->idling = false;
|
2012-09-29 22:53:57 +08:00
|
|
|
}
|
2004-07-08 15:07:26 +08:00
|
|
|
}
|
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
/**
|
|
|
|
* Set fade callback of a window, and possibly execute the previous
|
|
|
|
* callback.
|
|
|
|
*
|
|
|
|
* @param exec_callback whether the previous callback is to be executed
|
|
|
|
*/
|
2012-02-27 12:00:12 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
set_fade_callback(session_t *ps, win *w,
|
|
|
|
void (*callback) (session_t *ps, win *w), bool exec_callback) {
|
|
|
|
void (*old_callback) (session_t *ps, win *w) = w->fade_callback;
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
w->fade_callback = callback;
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
// Must be the last line as the callback could destroy w!
|
2012-09-29 22:53:57 +08:00
|
|
|
if (exec_callback && old_callback) {
|
2012-11-19 09:46:07 +08:00
|
|
|
old_callback(ps, w);
|
2012-09-29 22:53:57 +08:00
|
|
|
// Although currently no callback function affects window state on
|
|
|
|
// next paint, it could, in the future
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->idling = false;
|
2012-09-29 22:53:57 +08:00
|
|
|
}
|
2004-07-08 15:07:26 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
// === Shadows ===
|
2012-02-09 06:45:08 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
static double __attribute__((const))
|
2011-11-04 14:33:23 +08:00
|
|
|
gaussian(double r, double x, double y) {
|
|
|
|
return ((1 / (sqrt(2 * M_PI * r))) *
|
2012-02-27 20:49:50 +08:00
|
|
|
exp((- (x * x + y * y)) / (2 * r * r)));
|
2003-11-10 09:32:01 +08:00
|
|
|
}
|
|
|
|
|
2003-11-20 00:12:15 +08:00
|
|
|
static conv *
|
2012-11-19 09:46:07 +08:00
|
|
|
make_gaussian_map(double r) {
|
2011-11-04 16:41:56 +08:00
|
|
|
conv *c;
|
|
|
|
int size = ((int) ceil((r * 3)) + 1) & ~1;
|
|
|
|
int center = size / 2;
|
|
|
|
int x, y;
|
|
|
|
double t;
|
|
|
|
double g;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
|
|
|
c = malloc(sizeof(conv) + size * size * sizeof(double));
|
|
|
|
c->size = size;
|
|
|
|
c->data = (double *) (c + 1);
|
|
|
|
t = 0.0;
|
2011-11-04 16:41:56 +08:00
|
|
|
|
|
|
|
for (y = 0; y < size; y++) {
|
2011-11-04 14:33:23 +08:00
|
|
|
for (x = 0; x < size; x++) {
|
2012-11-19 09:46:07 +08:00
|
|
|
g = gaussian(r, x - center, y - center);
|
2011-11-04 14:33:23 +08:00
|
|
|
t += g;
|
|
|
|
c->data[y * size + x] = g;
|
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
for (y = 0; y < size; y++) {
|
2011-11-04 14:33:23 +08:00
|
|
|
for (x = 0; x < size; x++) {
|
2011-11-07 05:52:39 +08:00
|
|
|
c->data[y * size + x] /= t;
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
return c;
|
2003-11-10 09:32:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* A picture will help
|
|
|
|
*
|
2011-11-04 17:01:45 +08:00
|
|
|
* -center 0 width width+center
|
2003-11-10 09:32:01 +08:00
|
|
|
* -center +-----+-------------------+-----+
|
2011-11-04 17:01:45 +08:00
|
|
|
* | | | |
|
|
|
|
* | | | |
|
|
|
|
* 0 +-----+-------------------+-----+
|
|
|
|
* | | | |
|
|
|
|
* | | | |
|
|
|
|
* | | | |
|
2003-11-10 09:32:01 +08:00
|
|
|
* height +-----+-------------------+-----+
|
2011-11-04 17:01:45 +08:00
|
|
|
* | | | |
|
|
|
|
* height+ | | | |
|
2003-11-10 09:32:01 +08:00
|
|
|
* center +-----+-------------------+-----+
|
|
|
|
*/
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2003-11-20 00:12:15 +08:00
|
|
|
static unsigned char
|
2011-11-04 17:18:10 +08:00
|
|
|
sum_gaussian(conv *map, double opacity,
|
|
|
|
int x, int y, int width, int height) {
|
2011-11-04 16:41:56 +08:00
|
|
|
int fx, fy;
|
|
|
|
double *g_data;
|
|
|
|
double *g_line = map->data;
|
|
|
|
int g_size = map->size;
|
|
|
|
int center = g_size / 2;
|
|
|
|
int fx_start, fx_end;
|
|
|
|
int fy_start, fy_end;
|
|
|
|
double v;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Compute set of filter values which are "in range",
|
|
|
|
* that's the set with:
|
|
|
|
* 0 <= x + (fx-center) && x + (fx-center) < width &&
|
|
|
|
* 0 <= y + (fy-center) && y + (fy-center) < height
|
|
|
|
*
|
|
|
|
* 0 <= x + (fx - center) x + fx - center < width
|
|
|
|
* center - x <= fx fx < width + center - x
|
|
|
|
*/
|
|
|
|
|
|
|
|
fx_start = center - x;
|
2011-11-04 16:41:56 +08:00
|
|
|
if (fx_start < 0) fx_start = 0;
|
2011-11-04 14:33:23 +08:00
|
|
|
fx_end = width + center - x;
|
2011-11-04 16:41:56 +08:00
|
|
|
if (fx_end > g_size) fx_end = g_size;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
|
|
|
fy_start = center - y;
|
2011-11-04 16:41:56 +08:00
|
|
|
if (fy_start < 0) fy_start = 0;
|
2011-11-04 14:33:23 +08:00
|
|
|
fy_end = height + center - y;
|
2011-11-04 16:41:56 +08:00
|
|
|
if (fy_end > g_size) fy_end = g_size;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
|
|
|
g_line = g_line + fy_start * g_size + fx_start;
|
|
|
|
|
|
|
|
v = 0;
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
for (fy = fy_start; fy < fy_end; fy++) {
|
|
|
|
g_data = g_line;
|
|
|
|
g_line += g_size;
|
|
|
|
|
2011-11-04 16:41:56 +08:00
|
|
|
for (fx = fx_start; fx < fx_end; fx++) {
|
2011-11-04 14:33:23 +08:00
|
|
|
v += *g_data++;
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
|
|
|
if (v > 1) v = 1;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
|
|
|
return ((unsigned char) (v * opacity * 255.0));
|
2003-11-10 09:32:01 +08:00
|
|
|
}
|
|
|
|
|
2011-11-04 17:18:10 +08:00
|
|
|
/* precompute shadow corners and sides
|
|
|
|
to save time for large windows */
|
2012-02-27 20:49:50 +08:00
|
|
|
|
2004-09-22 06:59:38 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
presum_gaussian(session_t *ps, conv *map) {
|
2012-02-27 20:49:50 +08:00
|
|
|
int center = map->size / 2;
|
2011-11-04 14:33:23 +08:00
|
|
|
int opacity, x, y;
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->cgsize = map->size;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->shadow_corner)
|
|
|
|
free(ps->shadow_corner);
|
|
|
|
if (ps->shadow_top)
|
|
|
|
free(ps->shadow_top);
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->shadow_corner = malloc((ps->cgsize + 1) * (ps->cgsize + 1) * 26);
|
|
|
|
ps->shadow_top = malloc((ps->cgsize + 1) * 26);
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
for (x = 0; x <= ps->cgsize; x++) {
|
|
|
|
ps->shadow_top[25 * (ps->cgsize + 1) + x] =
|
|
|
|
sum_gaussian(map, 1, x - center, center, ps->cgsize * 2, ps->cgsize * 2);
|
2011-11-04 16:41:56 +08:00
|
|
|
|
|
|
|
for (opacity = 0; opacity < 25; opacity++) {
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->shadow_top[opacity * (ps->cgsize + 1) + x] =
|
|
|
|
ps->shadow_top[25 * (ps->cgsize + 1) + x] * opacity / 25;
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
for (y = 0; y <= x; y++) {
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->shadow_corner[25 * (ps->cgsize + 1) * (ps->cgsize + 1) + y * (ps->cgsize + 1) + x]
|
|
|
|
= sum_gaussian(map, 1, x - center, y - center, ps->cgsize * 2, ps->cgsize * 2);
|
|
|
|
ps->shadow_corner[25 * (ps->cgsize + 1) * (ps->cgsize + 1) + x * (ps->cgsize + 1) + y]
|
|
|
|
= ps->shadow_corner[25 * (ps->cgsize + 1) * (ps->cgsize + 1) + y * (ps->cgsize + 1) + x];
|
2011-11-04 16:41:56 +08:00
|
|
|
|
|
|
|
for (opacity = 0; opacity < 25; opacity++) {
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->shadow_corner[opacity * (ps->cgsize + 1) * (ps->cgsize + 1)
|
|
|
|
+ y * (ps->cgsize + 1) + x]
|
|
|
|
= ps->shadow_corner[opacity * (ps->cgsize + 1) * (ps->cgsize + 1)
|
|
|
|
+ x * (ps->cgsize + 1) + y]
|
|
|
|
= ps->shadow_corner[25 * (ps->cgsize + 1) * (ps->cgsize + 1)
|
|
|
|
+ y * (ps->cgsize + 1) + x] * opacity / 25;
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
|
|
|
}
|
2004-09-22 06:59:38 +08:00
|
|
|
}
|
|
|
|
|
2003-11-20 00:12:15 +08:00
|
|
|
static XImage *
|
2012-11-19 09:46:07 +08:00
|
|
|
make_shadow(session_t *ps, double opacity,
|
|
|
|
int width, int height) {
|
2011-11-04 16:41:56 +08:00
|
|
|
XImage *ximage;
|
|
|
|
unsigned char *data;
|
|
|
|
int ylimit, xlimit;
|
2012-11-19 09:46:07 +08:00
|
|
|
int swidth = width + ps->cgsize;
|
|
|
|
int sheight = height + ps->cgsize;
|
|
|
|
int center = ps->cgsize / 2;
|
2011-11-04 16:41:56 +08:00
|
|
|
int x, y;
|
|
|
|
unsigned char d;
|
|
|
|
int x_diff;
|
|
|
|
int opacity_int = (int)(opacity * 25);
|
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
data = malloc(swidth * sheight * sizeof(unsigned char));
|
2011-11-04 16:41:56 +08:00
|
|
|
if (!data) return 0;
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
ximage = XCreateImage(ps->dpy, ps->vis, 8,
|
|
|
|
ZPixmap, 0, (char *) data, swidth, sheight, 8, swidth * sizeof(char));
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
if (!ximage) {
|
|
|
|
free(data);
|
|
|
|
return 0;
|
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
/*
|
|
|
|
* Build the gaussian in sections
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* center (fill the complete data array)
|
|
|
|
*/
|
2011-11-04 17:18:10 +08:00
|
|
|
|
2012-09-26 18:54:35 +08:00
|
|
|
// If clear_shadow is enabled and the border & corner shadow (which
|
2012-09-12 21:01:06 +08:00
|
|
|
// later will be filled) could entirely cover the area of the shadow
|
|
|
|
// that will be displayed, do not bother filling other pixels. If it
|
|
|
|
// can't, we must fill the other pixels here.
|
2012-11-19 09:46:07 +08:00
|
|
|
/* if (!(clear_shadow && ps->o.shadow_offset_x <= 0 && ps->o.shadow_offset_x >= -ps->cgsize
|
|
|
|
&& ps->o.shadow_offset_y <= 0 && ps->o.shadow_offset_y >= -ps->cgsize)) { */
|
|
|
|
if (ps->cgsize > 0) {
|
|
|
|
d = ps->shadow_top[opacity_int * (ps->cgsize + 1) + ps->cgsize];
|
2012-02-27 12:00:12 +08:00
|
|
|
} else {
|
2012-11-19 09:46:07 +08:00
|
|
|
d = sum_gaussian(ps->gaussian_map,
|
2012-02-27 12:00:12 +08:00
|
|
|
opacity, center, center, width, height);
|
|
|
|
}
|
|
|
|
memset(data, d, sheight * swidth);
|
2012-10-28 17:02:07 +08:00
|
|
|
// }
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
/*
|
|
|
|
* corners
|
|
|
|
*/
|
2011-11-04 17:18:10 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
ylimit = ps->cgsize;
|
2011-11-04 16:41:56 +08:00
|
|
|
if (ylimit > sheight / 2) ylimit = (sheight + 1) / 2;
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
xlimit = ps->cgsize;
|
2011-11-04 16:41:56 +08:00
|
|
|
if (xlimit > swidth / 2) xlimit = (swidth + 1) / 2;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-02-27 12:00:12 +08:00
|
|
|
for (y = 0; y < ylimit; y++) {
|
2011-11-04 14:33:23 +08:00
|
|
|
for (x = 0; x < xlimit; x++) {
|
2012-11-19 09:46:07 +08:00
|
|
|
if (xlimit == ps->cgsize && ylimit == ps->cgsize) {
|
|
|
|
d = ps->shadow_corner[opacity_int * (ps->cgsize + 1) * (ps->cgsize + 1)
|
|
|
|
+ y * (ps->cgsize + 1) + x];
|
2011-11-04 16:41:56 +08:00
|
|
|
} else {
|
2012-11-19 09:46:07 +08:00
|
|
|
d = sum_gaussian(ps->gaussian_map,
|
2011-11-04 17:18:10 +08:00
|
|
|
opacity, x - center, y - center, width, height);
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
2011-11-04 14:33:23 +08:00
|
|
|
data[y * swidth + x] = d;
|
|
|
|
data[(sheight - y - 1) * swidth + x] = d;
|
|
|
|
data[(sheight - y - 1) * swidth + (swidth - x - 1)] = d;
|
|
|
|
data[y * swidth + (swidth - x - 1)] = d;
|
|
|
|
}
|
2012-02-27 12:00:12 +08:00
|
|
|
}
|
2011-11-04 14:33:23 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* top/bottom
|
|
|
|
*/
|
2011-11-04 17:18:10 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
x_diff = swidth - (ps->cgsize * 2);
|
2011-11-04 14:33:23 +08:00
|
|
|
if (x_diff > 0 && ylimit > 0) {
|
|
|
|
for (y = 0; y < ylimit; y++) {
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ylimit == ps->cgsize) {
|
|
|
|
d = ps->shadow_top[opacity_int * (ps->cgsize + 1) + y];
|
2011-11-04 16:41:56 +08:00
|
|
|
} else {
|
2012-11-19 09:46:07 +08:00
|
|
|
d = sum_gaussian(ps->gaussian_map,
|
2011-11-04 17:18:10 +08:00
|
|
|
opacity, center, y - center, width, height);
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
2012-11-19 09:46:07 +08:00
|
|
|
memset(&data[y * swidth + ps->cgsize], d, x_diff);
|
|
|
|
memset(&data[(sheight - y - 1) * swidth + ps->cgsize], d, x_diff);
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* sides
|
|
|
|
*/
|
|
|
|
|
|
|
|
for (x = 0; x < xlimit; x++) {
|
2012-11-19 09:46:07 +08:00
|
|
|
if (xlimit == ps->cgsize) {
|
|
|
|
d = ps->shadow_top[opacity_int * (ps->cgsize + 1) + x];
|
2011-11-04 16:41:56 +08:00
|
|
|
} else {
|
2012-11-19 09:46:07 +08:00
|
|
|
d = sum_gaussian(ps->gaussian_map,
|
2011-11-04 17:18:10 +08:00
|
|
|
opacity, x - center, center, width, height);
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
2012-11-19 09:46:07 +08:00
|
|
|
for (y = ps->cgsize; y < sheight - ps->cgsize; y++) {
|
2011-11-04 14:33:23 +08:00
|
|
|
data[y * swidth + x] = d;
|
|
|
|
data[y * swidth + (swidth - x - 1)] = d;
|
2003-11-10 09:32:01 +08:00
|
|
|
}
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2003-11-10 09:32:01 +08:00
|
|
|
|
2012-10-28 17:02:07 +08:00
|
|
|
/*
|
|
|
|
if (clear_shadow) {
|
2012-09-12 21:01:06 +08:00
|
|
|
// Clear the region in the shadow that the window would cover based
|
|
|
|
// on shadow_offset_{x,y} user provides
|
2012-11-19 09:46:07 +08:00
|
|
|
int xstart = normalize_i_range(- (int) ps->o.shadow_offset_x, 0, swidth);
|
|
|
|
int xrange = normalize_i_range(width - (int) ps->o.shadow_offset_x,
|
2012-09-12 21:01:06 +08:00
|
|
|
0, swidth) - xstart;
|
2012-11-19 09:46:07 +08:00
|
|
|
int ystart = normalize_i_range(- (int) ps->o.shadow_offset_y, 0, sheight);
|
|
|
|
int yend = normalize_i_range(height - (int) ps->o.shadow_offset_y,
|
2012-09-12 21:01:06 +08:00
|
|
|
0, sheight);
|
|
|
|
int y;
|
|
|
|
|
2012-09-13 13:58:05 +08:00
|
|
|
for (y = ystart; y < yend; y++) {
|
2012-09-12 21:01:06 +08:00
|
|
|
memset(&data[y * swidth + xstart], 0, xrange);
|
2012-09-13 13:58:05 +08:00
|
|
|
}
|
2012-02-02 03:52:35 +08:00
|
|
|
}
|
2012-10-28 17:02:07 +08:00
|
|
|
*/
|
2012-02-02 03:52:35 +08:00
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
return ximage;
|
2003-11-10 09:32:01 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* Generate shadow <code>Picture</code> for a window.
|
|
|
|
*/
|
2003-11-20 00:12:15 +08:00
|
|
|
static Picture
|
2012-11-19 09:46:07 +08:00
|
|
|
shadow_picture(session_t *ps, double opacity, int width, int height) {
|
2012-09-29 13:15:09 +08:00
|
|
|
XImage *shadow_image = NULL;
|
|
|
|
Pixmap shadow_pixmap = None, shadow_pixmap_argb = None;
|
|
|
|
Picture shadow_picture = None, shadow_picture_argb = None;
|
|
|
|
GC gc = None;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
shadow_image = make_shadow(ps, opacity, width, height);
|
2012-09-29 13:15:09 +08:00
|
|
|
if (!shadow_image)
|
|
|
|
return None;
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
shadow_pixmap = XCreatePixmap(ps->dpy, ps->root,
|
2012-06-04 00:08:50 +08:00
|
|
|
shadow_image->width, shadow_image->height, 8);
|
2012-11-19 09:46:07 +08:00
|
|
|
shadow_pixmap_argb = XCreatePixmap(ps->dpy, ps->root,
|
2012-09-29 13:15:09 +08:00
|
|
|
shadow_image->width, shadow_image->height, 32);
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-09-29 13:15:09 +08:00
|
|
|
if (!shadow_pixmap || !shadow_pixmap_argb)
|
|
|
|
goto shadow_picture_err;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
shadow_picture = XRenderCreatePicture(ps->dpy, shadow_pixmap,
|
|
|
|
XRenderFindStandardFormat(ps->dpy, PictStandardA8), 0, 0);
|
|
|
|
shadow_picture_argb = XRenderCreatePicture(ps->dpy, shadow_pixmap_argb,
|
|
|
|
XRenderFindStandardFormat(ps->dpy, PictStandardARGB32), 0, 0);
|
2012-09-29 13:15:09 +08:00
|
|
|
if (!shadow_picture || !shadow_picture_argb)
|
|
|
|
goto shadow_picture_err;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
gc = XCreateGC(ps->dpy, shadow_pixmap, 0, 0);
|
2012-09-29 13:15:09 +08:00
|
|
|
if (!gc)
|
|
|
|
goto shadow_picture_err;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
XPutImage(ps->dpy, shadow_pixmap, gc, shadow_image, 0, 0, 0, 0,
|
2012-06-04 00:08:50 +08:00
|
|
|
shadow_image->width, shadow_image->height);
|
2012-11-19 09:46:07 +08:00
|
|
|
XRenderComposite(ps->dpy, PictOpSrc, ps->cshadow_picture, shadow_picture,
|
2012-09-29 13:15:09 +08:00
|
|
|
shadow_picture_argb, 0, 0, 0, 0, 0, 0,
|
|
|
|
shadow_image->width, shadow_image->height);
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
XFreeGC(ps->dpy, gc);
|
2012-06-04 00:08:50 +08:00
|
|
|
XDestroyImage(shadow_image);
|
2012-11-19 09:46:07 +08:00
|
|
|
XFreePixmap(ps->dpy, shadow_pixmap);
|
|
|
|
XFreePixmap(ps->dpy, shadow_pixmap_argb);
|
|
|
|
XRenderFreePicture(ps->dpy, shadow_picture);
|
2012-09-29 13:15:09 +08:00
|
|
|
|
|
|
|
return shadow_picture_argb;
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-09-29 13:15:09 +08:00
|
|
|
shadow_picture_err:
|
|
|
|
if (shadow_image)
|
|
|
|
XDestroyImage(shadow_image);
|
|
|
|
if (shadow_pixmap)
|
2012-11-19 09:46:07 +08:00
|
|
|
XFreePixmap(ps->dpy, shadow_pixmap);
|
2012-09-29 13:15:09 +08:00
|
|
|
if (shadow_pixmap_argb)
|
2012-11-19 09:46:07 +08:00
|
|
|
XFreePixmap(ps->dpy, shadow_pixmap_argb);
|
2012-09-29 13:15:09 +08:00
|
|
|
if (shadow_picture)
|
2012-11-19 09:46:07 +08:00
|
|
|
XRenderFreePicture(ps->dpy, shadow_picture);
|
2012-09-29 13:15:09 +08:00
|
|
|
if (shadow_picture_argb)
|
2012-11-19 09:46:07 +08:00
|
|
|
XRenderFreePicture(ps->dpy, shadow_picture_argb);
|
2012-09-29 13:15:09 +08:00
|
|
|
if (gc)
|
2012-11-19 09:46:07 +08:00
|
|
|
XFreeGC(ps->dpy, gc);
|
2012-09-29 13:15:09 +08:00
|
|
|
return None;
|
2003-11-10 09:32:01 +08:00
|
|
|
}
|
2003-11-09 15:08:23 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* Generate a 1x1 <code>Picture</code> of a particular color.
|
|
|
|
*/
|
2012-02-27 12:00:12 +08:00
|
|
|
static Picture
|
2012-11-19 09:46:07 +08:00
|
|
|
solid_picture(session_t *ps, bool argb, double a,
|
2011-11-04 17:18:10 +08:00
|
|
|
double r, double g, double b) {
|
2011-11-04 16:41:56 +08:00
|
|
|
Pixmap pixmap;
|
|
|
|
Picture picture;
|
|
|
|
XRenderPictureAttributes pa;
|
|
|
|
XRenderColor c;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
pixmap = XCreatePixmap(ps->dpy, ps->root, 1, 1, argb ? 32 : 8);
|
2011-11-04 16:41:56 +08:00
|
|
|
|
|
|
|
if (!pixmap) return None;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
|
|
|
pa.repeat = True;
|
2012-11-19 09:46:07 +08:00
|
|
|
picture = XRenderCreatePicture(ps->dpy, pixmap,
|
|
|
|
XRenderFindStandardFormat(ps->dpy, argb
|
2011-11-04 17:18:10 +08:00
|
|
|
? PictStandardARGB32 : PictStandardA8),
|
2011-11-04 16:41:56 +08:00
|
|
|
CPRepeat,
|
|
|
|
&pa);
|
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
if (!picture) {
|
2012-11-19 09:46:07 +08:00
|
|
|
XFreePixmap(ps->dpy, pixmap);
|
2011-11-04 14:33:23 +08:00
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
|
|
|
c.alpha = a * 0xffff;
|
|
|
|
c.red = r * 0xffff;
|
|
|
|
c.green = g * 0xffff;
|
|
|
|
c.blue = b * 0xffff;
|
2011-11-05 05:18:56 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
XRenderFillRectangle(ps->dpy, PictOpSrc, picture, &c, 0, 0, 1, 1);
|
|
|
|
XFreePixmap(ps->dpy, pixmap);
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
return picture;
|
2004-06-27 12:48:37 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
// === Error handling ===
|
2012-02-09 06:45:08 +08:00
|
|
|
|
2012-02-27 12:00:12 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
discard_ignore(session_t *ps, unsigned long sequence) {
|
|
|
|
while (ps->ignore_head) {
|
|
|
|
if ((long) (sequence - ps->ignore_head->sequence) > 0) {
|
|
|
|
ignore_t *next = ps->ignore_head->next;
|
|
|
|
free(ps->ignore_head);
|
|
|
|
ps->ignore_head = next;
|
|
|
|
if (!ps->ignore_head) {
|
|
|
|
ps->ignore_tail = &ps->ignore_head;
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
|
|
|
} else {
|
2011-11-04 14:33:23 +08:00
|
|
|
break;
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2004-06-27 12:48:37 +08:00
|
|
|
}
|
|
|
|
|
2012-02-27 12:00:12 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
set_ignore(session_t *ps, unsigned long sequence) {
|
|
|
|
ignore_t *i = malloc(sizeof(ignore_t));
|
2011-11-04 16:41:56 +08:00
|
|
|
if (!i) return;
|
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
i->sequence = sequence;
|
|
|
|
i->next = 0;
|
2012-11-19 09:46:07 +08:00
|
|
|
*ps->ignore_tail = i;
|
|
|
|
ps->ignore_tail = &i->next;
|
2004-06-27 12:48:37 +08:00
|
|
|
}
|
|
|
|
|
2012-02-27 12:00:12 +08:00
|
|
|
static int
|
2012-11-19 09:46:07 +08:00
|
|
|
should_ignore(session_t *ps, unsigned long sequence) {
|
|
|
|
discard_ignore(ps, sequence);
|
|
|
|
return ps->ignore_head && ps->ignore_head->sequence == sequence;
|
2004-06-27 12:48:37 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
// === Windows ===
|
2012-02-09 06:45:08 +08:00
|
|
|
|
2012-10-01 10:34:40 +08:00
|
|
|
/**
|
|
|
|
* Check if a window has rounded corners.
|
|
|
|
*/
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
win_rounded_corners(session_t *ps, win *w) {
|
2012-10-01 10:34:40 +08:00
|
|
|
if (!w->bounding_shaped)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Fetch its bounding region
|
|
|
|
if (!w->border_size)
|
2012-11-19 09:46:07 +08:00
|
|
|
w->border_size = border_size(ps, w);
|
2012-10-01 10:34:40 +08:00
|
|
|
|
|
|
|
// Quit if border_size() returns None
|
|
|
|
if (!w->border_size)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Determine the minimum width/height of a rectangle that could mark
|
|
|
|
// a window as having rounded corners
|
|
|
|
unsigned short minwidth = max_i(w->widthb * (1 - ROUNDED_PERCENT),
|
|
|
|
w->widthb - ROUNDED_PIXELS);
|
|
|
|
unsigned short minheight = max_i(w->heightb * (1 - ROUNDED_PERCENT),
|
|
|
|
w->heightb - ROUNDED_PIXELS);
|
|
|
|
|
|
|
|
// Get the rectangles in the bounding region
|
|
|
|
int nrects = 0, i;
|
2012-11-19 09:46:07 +08:00
|
|
|
XRectangle *rects = XFixesFetchRegion(ps->dpy, w->border_size, &nrects);
|
2012-10-01 10:34:40 +08:00
|
|
|
if (!rects)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Look for a rectangle large enough for this window be considered
|
|
|
|
// having rounded corners
|
|
|
|
for (i = 0; i < nrects; ++i)
|
|
|
|
if (rects[i].width >= minwidth && rects[i].height >= minheight) {
|
2012-11-19 09:46:07 +08:00
|
|
|
w->rounded_corners = true;
|
2012-10-01 10:34:40 +08:00
|
|
|
XFree(rects);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
w->rounded_corners = false;
|
2012-10-01 10:34:40 +08:00
|
|
|
XFree(rects);
|
|
|
|
}
|
|
|
|
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
/**
|
|
|
|
* Match a window against a single window condition.
|
|
|
|
*
|
|
|
|
* @return true if matched, false otherwise.
|
|
|
|
*/
|
|
|
|
static bool
|
2012-11-19 09:46:07 +08:00
|
|
|
win_match_once(win *w, const wincond_t *cond) {
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
const char *target;
|
|
|
|
bool matched = false;
|
|
|
|
|
|
|
|
#ifdef DEBUG_WINMATCH
|
|
|
|
printf("win_match_once(%#010lx \"%s\"): cond = %p", w->id, w->name,
|
|
|
|
cond);
|
|
|
|
#endif
|
|
|
|
|
2012-10-27 21:46:01 +08:00
|
|
|
if (InputOnly == w->a.class) {
|
|
|
|
#ifdef DEBUG_WINMATCH
|
|
|
|
printf(": InputOnly\n");
|
|
|
|
#endif
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
// Determine the target
|
|
|
|
target = NULL;
|
|
|
|
switch (cond->target) {
|
|
|
|
case CONDTGT_NAME:
|
|
|
|
target = w->name;
|
|
|
|
break;
|
|
|
|
case CONDTGT_CLASSI:
|
|
|
|
target = w->class_instance;
|
|
|
|
break;
|
|
|
|
case CONDTGT_CLASSG:
|
|
|
|
target = w->class_general;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!target) {
|
|
|
|
#ifdef DEBUG_WINMATCH
|
|
|
|
printf(": Target not found\n");
|
|
|
|
#endif
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Determine pattern type and match
|
|
|
|
switch (cond->type) {
|
|
|
|
case CONDTP_EXACT:
|
|
|
|
if (cond->flags & CONDF_IGNORECASE)
|
|
|
|
matched = !strcasecmp(target, cond->pattern);
|
|
|
|
else
|
|
|
|
matched = !strcmp(target, cond->pattern);
|
|
|
|
break;
|
|
|
|
case CONDTP_ANYWHERE:
|
|
|
|
if (cond->flags & CONDF_IGNORECASE)
|
|
|
|
matched = strcasestr(target, cond->pattern);
|
|
|
|
else
|
|
|
|
matched = strstr(target, cond->pattern);
|
|
|
|
break;
|
|
|
|
case CONDTP_FROMSTART:
|
|
|
|
if (cond->flags & CONDF_IGNORECASE)
|
|
|
|
matched = !strncasecmp(target, cond->pattern,
|
|
|
|
strlen(cond->pattern));
|
|
|
|
else
|
|
|
|
matched = !strncmp(target, cond->pattern,
|
|
|
|
strlen(cond->pattern));
|
|
|
|
break;
|
|
|
|
case CONDTP_WILDCARD:
|
|
|
|
{
|
|
|
|
int flags = 0;
|
|
|
|
if (cond->flags & CONDF_IGNORECASE)
|
|
|
|
flags = FNM_CASEFOLD;
|
|
|
|
matched = !fnmatch(cond->pattern, target, flags);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CONDTP_REGEX_PCRE:
|
|
|
|
#ifdef CONFIG_REGEX_PCRE
|
|
|
|
matched = (pcre_exec(cond->regex_pcre, cond->regex_pcre_extra,
|
|
|
|
target, strlen(target), 0, 0, NULL, 0) >= 0);
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef DEBUG_WINMATCH
|
|
|
|
printf(", matched = %d\n", matched);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return matched;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Match a window against a condition linked list.
|
|
|
|
*
|
|
|
|
* @param cache a place to cache the last matched condition
|
|
|
|
* @return true if matched, false otherwise.
|
|
|
|
*/
|
|
|
|
static bool
|
2012-11-19 09:46:07 +08:00
|
|
|
win_match(win *w, wincond_t *condlst, wincond_t **cache) {
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
// Check if the cached entry matches firstly
|
|
|
|
if (cache && *cache && win_match_once(w, *cache))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// Then go through the whole linked list
|
|
|
|
for (; condlst; condlst = condlst->next) {
|
|
|
|
if (win_match_once(w, condlst)) {
|
2012-11-06 11:32:02 +08:00
|
|
|
if (cache)
|
|
|
|
*cache = condlst;
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add a pattern to a condition linked list.
|
|
|
|
*/
|
2012-11-19 09:46:07 +08:00
|
|
|
static bool
|
|
|
|
condlst_add(wincond_t **pcondlst, const char *pattern) {
|
2012-09-25 10:19:20 +08:00
|
|
|
if (!pattern)
|
2012-11-19 09:46:07 +08:00
|
|
|
return false;
|
2012-09-25 10:19:20 +08:00
|
|
|
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
unsigned plen = strlen(pattern);
|
2012-11-19 09:46:07 +08:00
|
|
|
wincond_t *cond;
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
const char *pos;
|
|
|
|
|
|
|
|
if (plen < 4 || ':' != pattern[1] || !strchr(pattern + 2, ':')) {
|
|
|
|
printf("Pattern \"%s\": Format invalid.\n", pattern);
|
2012-11-19 09:46:07 +08:00
|
|
|
return false;
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Allocate memory for the new condition
|
2012-11-19 09:46:07 +08:00
|
|
|
cond = malloc(sizeof(wincond_t));
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
|
|
|
|
// Determine the pattern target
|
|
|
|
switch (pattern[0]) {
|
|
|
|
case 'n':
|
|
|
|
cond->target = CONDTGT_NAME;
|
|
|
|
break;
|
|
|
|
case 'i':
|
|
|
|
cond->target = CONDTGT_CLASSI;
|
|
|
|
break;
|
|
|
|
case 'g':
|
|
|
|
cond->target = CONDTGT_CLASSG;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
printf("Pattern \"%s\": Target \"%c\" invalid.\n",
|
|
|
|
pattern, pattern[0]);
|
|
|
|
free(cond);
|
2012-11-19 09:46:07 +08:00
|
|
|
return false;
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Determine the pattern type
|
|
|
|
switch (pattern[2]) {
|
|
|
|
case 'e':
|
|
|
|
cond->type = CONDTP_EXACT;
|
|
|
|
break;
|
|
|
|
case 'a':
|
|
|
|
cond->type = CONDTP_ANYWHERE;
|
|
|
|
break;
|
|
|
|
case 's':
|
|
|
|
cond->type = CONDTP_FROMSTART;
|
|
|
|
break;
|
|
|
|
case 'w':
|
|
|
|
cond->type = CONDTP_WILDCARD;
|
|
|
|
break;
|
|
|
|
#ifdef CONFIG_REGEX_PCRE
|
|
|
|
case 'p':
|
|
|
|
cond->type = CONDTP_REGEX_PCRE;
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
default:
|
|
|
|
printf("Pattern \"%s\": Type \"%c\" invalid.\n",
|
|
|
|
pattern, pattern[2]);
|
|
|
|
free(cond);
|
2012-11-19 09:46:07 +08:00
|
|
|
return false;
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Determine the pattern flags
|
|
|
|
pos = &pattern[3];
|
|
|
|
cond->flags = 0;
|
|
|
|
while (':' != *pos) {
|
|
|
|
switch (*pos) {
|
|
|
|
case 'i':
|
|
|
|
cond->flags |= CONDF_IGNORECASE;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
printf("Pattern \"%s\": Flag \"%c\" invalid.\n",
|
|
|
|
pattern, *pos);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
++pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Copy the pattern
|
|
|
|
++pos;
|
|
|
|
cond->pattern = NULL;
|
|
|
|
#ifdef CONFIG_REGEX_PCRE
|
|
|
|
cond->regex_pcre = NULL;
|
|
|
|
cond->regex_pcre_extra = NULL;
|
|
|
|
#endif
|
|
|
|
if (CONDTP_REGEX_PCRE == cond->type) {
|
|
|
|
#ifdef CONFIG_REGEX_PCRE
|
|
|
|
const char *error = NULL;
|
|
|
|
int erroffset = 0;
|
|
|
|
int options = 0;
|
|
|
|
|
|
|
|
if (cond->flags & CONDF_IGNORECASE)
|
|
|
|
options |= PCRE_CASELESS;
|
|
|
|
|
|
|
|
cond->regex_pcre = pcre_compile(pos, options, &error, &erroffset,
|
|
|
|
NULL);
|
|
|
|
if (!cond->regex_pcre) {
|
|
|
|
printf("Pattern \"%s\": PCRE regular expression parsing failed on "
|
|
|
|
"offset %d: %s\n", pattern, erroffset, error);
|
|
|
|
free(cond);
|
2012-11-19 09:46:07 +08:00
|
|
|
return false;
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
}
|
|
|
|
#ifdef CONFIG_REGEX_PCRE_JIT
|
|
|
|
cond->regex_pcre_extra = pcre_study(cond->regex_pcre, PCRE_STUDY_JIT_COMPILE, &error);
|
|
|
|
if (!cond->regex_pcre_extra) {
|
|
|
|
printf("Pattern \"%s\": PCRE regular expression study failed: %s",
|
|
|
|
pattern, error);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
cond->pattern = mstrcpy(pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Insert it into the linked list
|
|
|
|
cond->next = *pcondlst;
|
|
|
|
*pcondlst = cond;
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
return true;
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* Determine the event mask for a window.
|
|
|
|
*/
|
2012-09-13 23:24:37 +08:00
|
|
|
static long
|
2012-11-19 09:46:07 +08:00
|
|
|
determine_evmask(session_t *ps, Window wid, win_evmode_t mode) {
|
2012-09-13 22:30:18 +08:00
|
|
|
long evmask = NoEventMask;
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (WIN_EVMODE_FRAME == mode || find_win(ps, wid)) {
|
2012-09-13 22:30:18 +08:00
|
|
|
evmask |= PropertyChangeMask;
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.track_focus && !ps->o.use_ewmh_active_win)
|
2012-11-04 18:11:08 +08:00
|
|
|
evmask |= FocusChangeMask;
|
2012-09-13 22:30:18 +08:00
|
|
|
}
|
2012-09-13 23:12:54 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (WIN_EVMODE_CLIENT == mode || find_toplevel(ps, wid)) {
|
|
|
|
if (ps->o.frame_opacity || ps->o.track_wdata
|
|
|
|
|| ps->o.detect_client_opacity)
|
2012-09-14 11:51:46 +08:00
|
|
|
evmask |= PropertyChangeMask;
|
2012-09-13 22:30:18 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return evmask;
|
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* Find a window from window id in window linked list of the session.
|
|
|
|
*/
|
2003-11-20 00:12:15 +08:00
|
|
|
static win *
|
2012-11-19 09:46:07 +08:00
|
|
|
find_win(session_t *ps, Window id) {
|
2011-11-04 16:41:56 +08:00
|
|
|
win *w;
|
2003-11-09 15:08:23 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
for (w = ps->list; w; w = w->next) {
|
2011-11-04 14:33:23 +08:00
|
|
|
if (w->id == id && !w->destroyed)
|
|
|
|
return w;
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
return 0;
|
2003-11-09 15:08:23 +08:00
|
|
|
}
|
|
|
|
|
2012-09-13 21:38:55 +08:00
|
|
|
/**
|
|
|
|
* Find out the WM frame of a client window using existing data.
|
|
|
|
*
|
|
|
|
* @param w window ID
|
|
|
|
* @return struct _win object of the found window, NULL if not found
|
|
|
|
*/
|
2012-09-13 23:12:54 +08:00
|
|
|
static win *
|
2012-11-19 09:46:07 +08:00
|
|
|
find_toplevel(session_t *ps, Window id) {
|
2012-02-01 06:10:30 +08:00
|
|
|
win *w;
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
for (w = ps->list; w; w = w->next) {
|
2012-02-01 06:10:30 +08:00
|
|
|
if (w->client_win == id && !w->destroyed)
|
|
|
|
return w;
|
|
|
|
}
|
|
|
|
|
2012-09-13 21:38:55 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Find out the WM frame of a client window by querying X.
|
|
|
|
*
|
2012-11-19 09:46:07 +08:00
|
|
|
* @param ps current session
|
2012-09-13 21:38:55 +08:00
|
|
|
* @param w window ID
|
|
|
|
* @return struct _win object of the found window, NULL if not found
|
|
|
|
*/
|
2012-09-13 23:12:54 +08:00
|
|
|
static win *
|
2012-11-19 09:46:07 +08:00
|
|
|
find_toplevel2(session_t *ps, Window wid) {
|
2012-09-13 21:38:55 +08:00
|
|
|
win *w = NULL;
|
|
|
|
|
|
|
|
// We traverse through its ancestors to find out the frame
|
2012-11-19 09:46:07 +08:00
|
|
|
while (wid && wid != ps->root && !(w = find_win(ps, wid))) {
|
2012-09-13 21:38:55 +08:00
|
|
|
Window troot;
|
|
|
|
Window parent;
|
|
|
|
Window *tchildren;
|
|
|
|
unsigned tnchildren;
|
|
|
|
|
|
|
|
// XQueryTree probably fails if you run compton when X is somehow
|
|
|
|
// initializing (like add it in .xinitrc). In this case
|
|
|
|
// just leave it alone.
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!XQueryTree(ps->dpy, wid, &troot, &parent, &tchildren,
|
2012-09-13 21:38:55 +08:00
|
|
|
&tnchildren)) {
|
2012-09-17 16:04:04 +08:00
|
|
|
parent = 0;
|
2012-09-13 21:38:55 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2012-09-13 23:12:54 +08:00
|
|
|
if (tchildren) XFree(tchildren);
|
|
|
|
|
2012-09-13 21:38:55 +08:00
|
|
|
wid = parent;
|
|
|
|
}
|
|
|
|
|
|
|
|
return w;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Recheck currently focused window and set its <code>w->focused</code>
|
2012-11-19 09:46:07 +08:00
|
|
|
* to true.
|
2012-09-13 21:38:55 +08:00
|
|
|
*
|
2012-11-19 09:46:07 +08:00
|
|
|
* @param ps current session
|
2012-09-13 21:38:55 +08:00
|
|
|
* @return struct _win of currently focused window, NULL if not found
|
|
|
|
*/
|
2012-09-13 23:12:54 +08:00
|
|
|
static win *
|
2012-11-19 09:46:07 +08:00
|
|
|
recheck_focus(session_t *ps) {
|
2012-11-04 18:11:08 +08:00
|
|
|
// Use EWMH _NET_ACTIVE_WINDOW if enabled
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.use_ewmh_active_win) {
|
|
|
|
update_ewmh_active_win(ps);
|
|
|
|
return ps->active_win;
|
2012-11-04 18:11:08 +08:00
|
|
|
}
|
|
|
|
|
2012-09-13 21:38:55 +08:00
|
|
|
// Determine the currently focused window so we can apply appropriate
|
|
|
|
// opacity on it
|
|
|
|
Window wid = 0;
|
|
|
|
int revert_to;
|
|
|
|
win *w = NULL;
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
XGetInputFocus(ps->dpy, &wid, &revert_to);
|
2012-09-13 21:38:55 +08:00
|
|
|
|
|
|
|
// Fallback to the old method if find_toplevel() fails
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!(w = find_toplevel(ps, wid))) {
|
|
|
|
w = find_toplevel2(ps, wid);
|
2012-09-13 23:12:54 +08:00
|
|
|
}
|
2012-09-13 21:38:55 +08:00
|
|
|
|
|
|
|
// And we set the focus state and opacity here
|
|
|
|
if (w) {
|
2012-11-19 09:46:07 +08:00
|
|
|
set_focused(ps, w, true);
|
2012-09-13 21:38:55 +08:00
|
|
|
return w;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
2012-02-01 06:10:30 +08:00
|
|
|
}
|
|
|
|
|
2003-11-20 00:12:15 +08:00
|
|
|
static Picture
|
2012-11-19 09:46:07 +08:00
|
|
|
root_tile_f(session_t *ps) {
|
2012-10-24 10:09:59 +08:00
|
|
|
/*
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.paint_on_overlay) {
|
|
|
|
return ps->root_picture;
|
2012-10-24 10:09:59 +08:00
|
|
|
} */
|
|
|
|
|
2011-11-04 16:41:56 +08:00
|
|
|
Picture picture;
|
|
|
|
Pixmap pixmap;
|
2012-11-19 09:46:07 +08:00
|
|
|
bool fill = false;
|
2011-11-04 16:41:56 +08:00
|
|
|
XRenderPictureAttributes pa;
|
|
|
|
int p;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
|
|
|
pixmap = None;
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-11-04 18:11:08 +08:00
|
|
|
// Get the values of background attributes
|
2012-11-19 09:46:07 +08:00
|
|
|
for (p = 0; background_props_str[p]; p++) {
|
|
|
|
winprop_t prop = wid_get_prop(ps, ps->root,
|
|
|
|
XInternAtom(ps->dpy, background_props_str[p], false),
|
|
|
|
1L, XA_PIXMAP, 32);
|
|
|
|
if (prop.nitems) {
|
|
|
|
pixmap = *((long *) prop.data);
|
|
|
|
fill = false;
|
|
|
|
free_winprop(&prop);
|
2011-11-04 14:33:23 +08:00
|
|
|
break;
|
2012-11-04 18:11:08 +08:00
|
|
|
}
|
2012-11-19 09:46:07 +08:00
|
|
|
free_winprop(&prop);
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
if (!pixmap) {
|
2012-11-19 09:46:07 +08:00
|
|
|
pixmap = XCreatePixmap(ps->dpy, ps->root, 1, 1, ps->depth);
|
|
|
|
fill = true;
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
pa.repeat = true;
|
2011-11-04 16:41:56 +08:00
|
|
|
picture = XRenderCreatePicture(
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->dpy, pixmap, XRenderFindVisualFormat(ps->dpy, ps->vis),
|
2011-11-04 16:41:56 +08:00
|
|
|
CPRepeat, &pa);
|
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
if (fill) {
|
|
|
|
XRenderColor c;
|
|
|
|
|
|
|
|
c.red = c.green = c.blue = 0x8080;
|
|
|
|
c.alpha = 0xffff;
|
2011-11-04 16:41:56 +08:00
|
|
|
XRenderFillRectangle(
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->dpy, PictOpSrc, picture, &c, 0, 0, 1, 1);
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
return picture;
|
2003-11-10 10:03:26 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* Paint root window content.
|
|
|
|
*/
|
2003-11-20 00:12:15 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
paint_root(session_t *ps, Picture tgt_buffer) {
|
|
|
|
if (!ps->root_tile) {
|
|
|
|
ps->root_tile = root_tile_f(ps);
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2011-11-04 16:41:56 +08:00
|
|
|
XRenderComposite(
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->dpy, PictOpSrc, ps->root_tile, None,
|
2012-10-24 10:09:59 +08:00
|
|
|
tgt_buffer, 0, 0, 0, 0, 0, 0,
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->root_width, ps->root_height);
|
2003-11-09 15:08:23 +08:00
|
|
|
}
|
|
|
|
|
2012-10-21 20:44:24 +08:00
|
|
|
/**
|
|
|
|
* Get a rectangular region a window occupies, excluding shadow.
|
|
|
|
*/
|
|
|
|
static XserverRegion
|
2012-11-19 09:46:07 +08:00
|
|
|
win_get_region(session_t *ps, win *w) {
|
2012-10-21 20:44:24 +08:00
|
|
|
XRectangle r;
|
|
|
|
|
|
|
|
r.x = w->a.x;
|
|
|
|
r.y = w->a.y;
|
|
|
|
r.width = w->widthb;
|
|
|
|
r.height = w->heightb;
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
return XFixesCreateRegion(ps->dpy, &r, 1);
|
2012-10-21 20:44:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get a rectangular region a window occupies, excluding frame and shadow.
|
|
|
|
*/
|
|
|
|
static XserverRegion
|
2012-11-19 09:46:07 +08:00
|
|
|
win_get_region_noframe(session_t *ps, win *w) {
|
2012-10-21 20:44:24 +08:00
|
|
|
XRectangle r;
|
|
|
|
|
2012-11-01 19:03:56 +08:00
|
|
|
r.x = w->a.x + w->a.border_width + w->left_width;
|
|
|
|
r.y = w->a.y + w->a.border_width + w->top_width;
|
|
|
|
r.width = max_i(w->a.width - w->left_width - w->right_width, 0);
|
|
|
|
r.height = max_i(w->a.height - w->top_width - w->bottom_width, 0);
|
|
|
|
|
|
|
|
if (r.width > 0 && r.height > 0)
|
2012-11-19 09:46:07 +08:00
|
|
|
return XFixesCreateRegion(ps->dpy, &r, 1);
|
2012-11-01 19:03:56 +08:00
|
|
|
else
|
2012-11-19 09:46:07 +08:00
|
|
|
return XFixesCreateRegion(ps->dpy, NULL, 0);
|
2012-10-21 20:44:24 +08:00
|
|
|
}
|
|
|
|
|
2012-09-17 22:15:04 +08:00
|
|
|
/**
|
|
|
|
* Get a rectangular region a window (and possibly its shadow) occupies.
|
|
|
|
*
|
|
|
|
* Note w->shadow and shadow geometry must be correct before calling this
|
|
|
|
* function.
|
|
|
|
*/
|
2003-11-20 00:12:15 +08:00
|
|
|
static XserverRegion
|
2012-11-19 09:46:07 +08:00
|
|
|
win_extents(session_t *ps, win *w) {
|
2011-11-04 16:41:56 +08:00
|
|
|
XRectangle r;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
|
|
|
r.x = w->a.x;
|
|
|
|
r.y = w->a.y;
|
2012-09-17 22:15:04 +08:00
|
|
|
r.width = w->widthb;
|
|
|
|
r.height = w->heightb;
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-09-17 22:15:04 +08:00
|
|
|
if (w->shadow) {
|
2011-11-04 17:18:10 +08:00
|
|
|
XRectangle sr;
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2011-11-04 17:18:10 +08:00
|
|
|
sr.x = w->a.x + w->shadow_dx;
|
|
|
|
sr.y = w->a.y + w->shadow_dy;
|
|
|
|
sr.width = w->shadow_width;
|
|
|
|
sr.height = w->shadow_height;
|
|
|
|
|
|
|
|
if (sr.x < r.x) {
|
|
|
|
r.width = (r.x + r.width) - sr.x;
|
|
|
|
r.x = sr.x;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sr.y < r.y) {
|
|
|
|
r.height = (r.y + r.height) - sr.y;
|
|
|
|
r.y = sr.y;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sr.x + sr.width > r.x + r.width) {
|
|
|
|
r.width = sr.x + sr.width - r.x;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sr.y + sr.height > r.y + r.height) {
|
|
|
|
r.height = sr.y + sr.height - r.y;
|
|
|
|
}
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
return XFixesCreateRegion(ps->dpy, &r, 1);
|
2003-11-10 09:32:01 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* Retrieve the bounding shape of a window.
|
|
|
|
*/
|
2003-11-20 00:12:15 +08:00
|
|
|
static XserverRegion
|
2012-11-19 09:46:07 +08:00
|
|
|
border_size(session_t *ps, win *w) {
|
2012-11-01 19:03:56 +08:00
|
|
|
// Start with the window rectangular region
|
2012-11-19 09:46:07 +08:00
|
|
|
XserverRegion fin = win_get_region(ps, w);
|
2012-11-01 19:03:56 +08:00
|
|
|
|
|
|
|
// Only request for a bounding region if the window is shaped
|
|
|
|
if (w->bounding_shaped) {
|
|
|
|
/*
|
|
|
|
* if window doesn't exist anymore, this will generate an error
|
|
|
|
* as well as not generate a region. Perhaps a better XFixes
|
|
|
|
* architecture would be to have a request that copies instead
|
|
|
|
* of creates, that way you'd just end up with an empty region
|
|
|
|
* instead of an invalid XID.
|
|
|
|
*/
|
|
|
|
|
|
|
|
XserverRegion border = XFixesCreateRegionFromWindow(
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->dpy, w->id, WindowRegionBounding);
|
2012-11-01 19:03:56 +08:00
|
|
|
|
|
|
|
if (!border)
|
|
|
|
return fin;
|
|
|
|
|
|
|
|
// Translate the region to the correct place
|
2012-11-19 09:46:07 +08:00
|
|
|
XFixesTranslateRegion(ps->dpy, border,
|
2012-11-01 19:03:56 +08:00
|
|
|
w->a.x + w->a.border_width,
|
|
|
|
w->a.y + w->a.border_width);
|
|
|
|
|
|
|
|
// Intersect the bounding region we got with the window rectangle, to
|
|
|
|
// make sure the bounding region is not bigger than the window
|
|
|
|
// rectangle
|
2012-11-19 09:46:07 +08:00
|
|
|
XFixesIntersectRegion(ps->dpy, fin, fin, border);
|
|
|
|
XFixesDestroyRegion(ps->dpy, border);
|
2012-11-01 19:03:56 +08:00
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-11-01 19:03:56 +08:00
|
|
|
return fin;
|
2003-11-09 15:08:23 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* Look for the client window of a particular window.
|
|
|
|
*/
|
2012-09-13 23:12:54 +08:00
|
|
|
static Window
|
2012-11-19 09:46:07 +08:00
|
|
|
find_client_win(session_t *ps, Window w) {
|
|
|
|
if (wid_has_attr(ps, w, ps->atom_client)) {
|
2012-09-13 21:38:55 +08:00
|
|
|
return w;
|
2012-09-13 23:12:54 +08:00
|
|
|
}
|
2011-11-06 10:39:58 +08:00
|
|
|
|
|
|
|
Window *children;
|
|
|
|
unsigned int nchildren;
|
|
|
|
unsigned int i;
|
2012-09-13 21:38:55 +08:00
|
|
|
Window ret = 0;
|
2011-11-06 10:39:58 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!wid_get_children(ps, w, &children, &nchildren)) {
|
2011-11-06 10:39:58 +08:00
|
|
|
return 0;
|
2012-09-13 23:12:54 +08:00
|
|
|
}
|
2011-11-06 10:39:58 +08:00
|
|
|
|
2012-09-13 23:12:54 +08:00
|
|
|
for (i = 0; i < nchildren; ++i) {
|
2012-11-19 09:46:07 +08:00
|
|
|
if ((ret = find_client_win(ps, children[i])))
|
2012-09-13 21:38:55 +08:00
|
|
|
break;
|
2012-09-13 23:12:54 +08:00
|
|
|
}
|
2011-11-06 10:39:58 +08:00
|
|
|
|
2012-09-13 21:38:55 +08:00
|
|
|
XFree(children);
|
2011-11-06 10:39:58 +08:00
|
|
|
|
2012-09-13 21:38:55 +08:00
|
|
|
return ret;
|
2011-11-06 10:39:58 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* Retrieve frame extents from a window.
|
|
|
|
*/
|
2011-11-06 10:39:58 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
get_frame_extents(session_t *ps, win *w, Window client) {
|
2012-09-20 13:50:27 +08:00
|
|
|
w->left_width = 0;
|
|
|
|
w->right_width = 0;
|
|
|
|
w->top_width = 0;
|
|
|
|
w->bottom_width = 0;
|
2011-11-06 10:39:58 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
winprop_t prop = wid_get_prop(ps, client, ps->atom_frame_extents,
|
2012-11-04 18:11:08 +08:00
|
|
|
4L, XA_CARDINAL, 32);
|
2011-11-06 10:39:58 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (4 == prop.nitems) {
|
|
|
|
long *extents = (long *) prop.data;
|
2012-11-04 18:11:08 +08:00
|
|
|
w->left_width = extents[0];
|
|
|
|
w->right_width = extents[1];
|
|
|
|
w->top_width = extents[2];
|
|
|
|
w->bottom_width = extents[3];
|
2012-10-31 08:54:09 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.frame_opacity)
|
|
|
|
update_reg_ignore_expire(ps, w);
|
2011-11-06 10:39:58 +08:00
|
|
|
}
|
2012-11-04 18:11:08 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
free_winprop(&prop);
|
2011-11-06 10:39:58 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* Get alpha <code>Picture</code> for an opacity in <code>double</code>.
|
|
|
|
*/
|
2012-10-13 18:46:59 +08:00
|
|
|
static inline Picture
|
2012-11-19 09:46:07 +08:00
|
|
|
get_alpha_pict_d(session_t *ps, double o) {
|
|
|
|
assert((lround(normalize_d(o) / ps->o.alpha_step)) <= lround(1.0 / ps->o.alpha_step));
|
|
|
|
return ps->alpha_picts[lround(normalize_d(o) / ps->o.alpha_step)];
|
2012-10-13 18:46:59 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* Get alpha <code>Picture</code> for an opacity in
|
|
|
|
* <code>opacity_t</code>.
|
|
|
|
*/
|
2012-10-13 18:46:59 +08:00
|
|
|
static inline Picture
|
2012-11-19 09:46:07 +08:00
|
|
|
get_alpha_pict_o(session_t *ps, opacity_t o) {
|
|
|
|
return get_alpha_pict_d(ps, (double) o / OPAQUE);
|
2012-10-13 18:46:59 +08:00
|
|
|
}
|
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
static win *
|
2012-11-19 09:46:07 +08:00
|
|
|
paint_preprocess(session_t *ps, win *list) {
|
2012-11-09 21:44:02 +08:00
|
|
|
// Initialize unredir_possible
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->unredir_possible = false;
|
2012-11-09 21:44:02 +08:00
|
|
|
|
2011-11-04 16:41:56 +08:00
|
|
|
win *w;
|
2012-09-19 20:49:16 +08:00
|
|
|
win *t = NULL, *next = NULL;
|
2012-11-09 21:44:02 +08:00
|
|
|
// Trace whether it's the highest window to paint
|
2012-11-19 09:46:07 +08:00
|
|
|
bool is_highest = true;
|
2011-11-04 16:41:56 +08:00
|
|
|
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
// Fading step calculation
|
2012-11-19 09:46:07 +08:00
|
|
|
unsigned steps = (sub_unslong(get_time_ms(), ps->fade_time)
|
|
|
|
+ FADE_DELTA_TOLERANCE * ps->o.fade_delta) / ps->o.fade_delta;
|
|
|
|
ps->fade_time += steps * ps->o.fade_delta;
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-10-21 20:44:24 +08:00
|
|
|
XserverRegion last_reg_ignore = None;
|
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
for (w = list; w; w = next) {
|
2012-11-19 09:46:07 +08:00
|
|
|
bool to_paint = true;
|
2012-10-31 08:54:09 +08:00
|
|
|
const winmode mode_old = w->mode;
|
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
// In case calling the fade callback function destroys this window
|
|
|
|
next = w->next;
|
|
|
|
opacity_t opacity_old = w->opacity;
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-10-21 20:44:24 +08:00
|
|
|
// Destroy reg_ignore on all windows if they should expire
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->reg_ignore_expire)
|
|
|
|
free_region(ps, &w->reg_ignore);
|
2012-10-21 20:44:24 +08:00
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
// Run fading
|
2012-11-19 09:46:07 +08:00
|
|
|
run_fade(ps, w, steps);
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-10-31 08:54:09 +08:00
|
|
|
// Give up if it's not damaged or invisible, or it's unmapped and its
|
|
|
|
// picture is gone (for example due to a ConfigureNotify)
|
2012-09-19 20:49:16 +08:00
|
|
|
if (!w->damaged
|
|
|
|
|| w->a.x + w->a.width < 1 || w->a.y + w->a.height < 1
|
2012-11-19 09:46:07 +08:00
|
|
|
|| w->a.x >= ps->root_width || w->a.y >= ps->root_height
|
|
|
|
|| ((IsUnmapped == w->a.map_state || w->destroyed)
|
|
|
|
&& !w->picture)) {
|
|
|
|
to_paint = false;
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
|
|
|
|
2012-10-31 08:54:09 +08:00
|
|
|
if (to_paint) {
|
|
|
|
// If opacity changes
|
|
|
|
if (w->opacity != opacity_old) {
|
2012-11-19 09:46:07 +08:00
|
|
|
determine_mode(ps, w);
|
|
|
|
add_damage_win(ps, w);
|
2012-10-31 08:54:09 +08:00
|
|
|
}
|
2012-09-20 13:50:27 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
w->alpha_pict = get_alpha_pict_o(ps, w->opacity);
|
2012-10-21 20:44:24 +08:00
|
|
|
|
2012-10-31 08:54:09 +08:00
|
|
|
// End the game if we are using the 0 opacity alpha_pict
|
2012-11-19 09:46:07 +08:00
|
|
|
if (w->alpha_pict == ps->alpha_picts[0]) {
|
|
|
|
to_paint = false;
|
2012-10-31 08:54:09 +08:00
|
|
|
}
|
2012-09-20 13:50:27 +08:00
|
|
|
}
|
|
|
|
|
2012-10-31 08:54:09 +08:00
|
|
|
if (to_paint) {
|
2012-11-01 10:43:15 +08:00
|
|
|
// Fetch bounding region
|
2012-10-31 08:54:09 +08:00
|
|
|
if (!w->border_size) {
|
2012-11-19 09:46:07 +08:00
|
|
|
w->border_size = border_size(ps, w);
|
2012-10-31 08:54:09 +08:00
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-11-01 10:43:15 +08:00
|
|
|
// Fetch window extents
|
2012-10-31 08:54:09 +08:00
|
|
|
if (!w->extents) {
|
2012-11-19 09:46:07 +08:00
|
|
|
w->extents = win_extents(ps, w);
|
2012-10-31 08:54:09 +08:00
|
|
|
// If w->extents does not exist, the previous add_damage_win()
|
|
|
|
// call when opacity changes has no effect, so redo it here.
|
|
|
|
if (w->opacity != opacity_old)
|
2012-11-19 09:46:07 +08:00
|
|
|
add_damage_win(ps, w);
|
2012-10-31 08:54:09 +08:00
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-10-31 08:54:09 +08:00
|
|
|
// Calculate frame_opacity
|
|
|
|
{
|
|
|
|
double frame_opacity_old = w->frame_opacity;
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.frame_opacity && 1.0 != ps->o.frame_opacity
|
2012-10-31 08:54:09 +08:00
|
|
|
&& win_has_frame(w))
|
2012-11-19 09:46:07 +08:00
|
|
|
w->frame_opacity = get_opacity_percent(w) *
|
|
|
|
ps->o.frame_opacity;
|
2012-10-31 08:54:09 +08:00
|
|
|
else
|
|
|
|
w->frame_opacity = 0.0;
|
2012-10-21 20:44:24 +08:00
|
|
|
|
2012-10-31 08:54:09 +08:00
|
|
|
if (w->to_paint && WINDOW_SOLID == mode_old
|
|
|
|
&& (0.0 == frame_opacity_old) != (0.0 == w->frame_opacity))
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->reg_ignore_expire = true;
|
2012-10-31 08:54:09 +08:00
|
|
|
}
|
2012-10-21 20:44:24 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
w->frame_alpha_pict = get_alpha_pict_d(ps, w->frame_opacity);
|
2012-09-17 12:31:01 +08:00
|
|
|
|
2012-10-31 08:54:09 +08:00
|
|
|
// Calculate shadow opacity
|
|
|
|
if (w->frame_opacity)
|
2012-11-19 09:46:07 +08:00
|
|
|
w->shadow_opacity = ps->o.shadow_opacity * w->frame_opacity;
|
2012-10-31 08:54:09 +08:00
|
|
|
else
|
2012-11-19 09:46:07 +08:00
|
|
|
w->shadow_opacity = ps->o.shadow_opacity * get_opacity_percent(w);
|
2012-09-17 12:31:01 +08:00
|
|
|
|
2012-10-31 08:54:09 +08:00
|
|
|
// Rebuild shadow_pict if necessary
|
|
|
|
if (w->flags & WFLAG_SIZE_CHANGE)
|
2012-11-19 09:46:07 +08:00
|
|
|
free_picture(ps, &w->shadow_pict);
|
2012-09-17 22:15:04 +08:00
|
|
|
|
2012-10-31 08:54:09 +08:00
|
|
|
if (w->shadow && !w->shadow_pict) {
|
2012-11-19 09:46:07 +08:00
|
|
|
w->shadow_pict = shadow_picture(ps, 1, w->widthb, w->heightb);
|
2012-10-31 08:54:09 +08:00
|
|
|
}
|
2012-09-17 22:15:04 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
w->shadow_alpha_pict = get_alpha_pict_d(ps, w->shadow_opacity);
|
2012-09-29 13:15:09 +08:00
|
|
|
}
|
|
|
|
|
2012-10-31 08:54:09 +08:00
|
|
|
if ((to_paint && WINDOW_SOLID == w->mode)
|
|
|
|
!= (w->to_paint && WINDOW_SOLID == mode_old))
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->reg_ignore_expire = true;
|
2012-10-31 08:54:09 +08:00
|
|
|
|
2012-11-09 21:44:02 +08:00
|
|
|
// Add window to damaged area if its painting status changes
|
|
|
|
if (to_paint != w->to_paint)
|
2012-11-19 09:46:07 +08:00
|
|
|
add_damage_win(ps, w);
|
2012-11-09 21:44:02 +08:00
|
|
|
|
2012-10-31 08:54:09 +08:00
|
|
|
if (to_paint) {
|
|
|
|
// Generate ignore region for painting to reduce GPU load
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->reg_ignore_expire || !w->to_paint) {
|
|
|
|
free_region(ps, &w->reg_ignore);
|
2012-10-31 08:54:09 +08:00
|
|
|
|
|
|
|
// If the window is solid, we add the window region to the
|
|
|
|
// ignored region
|
|
|
|
if (WINDOW_SOLID == w->mode) {
|
2012-11-01 19:03:56 +08:00
|
|
|
if (!w->frame_opacity) {
|
|
|
|
if (w->border_size)
|
2012-11-19 09:46:07 +08:00
|
|
|
w->reg_ignore = copy_region(ps, w->border_size);
|
2012-11-01 19:03:56 +08:00
|
|
|
else
|
2012-11-19 09:46:07 +08:00
|
|
|
w->reg_ignore = win_get_region(ps, w);
|
2012-11-01 19:03:56 +08:00
|
|
|
}
|
|
|
|
else {
|
2012-11-19 09:46:07 +08:00
|
|
|
w->reg_ignore = win_get_region_noframe(ps, w);
|
2012-11-01 19:03:56 +08:00
|
|
|
if (w->border_size)
|
2012-11-19 09:46:07 +08:00
|
|
|
XFixesIntersectRegion(ps->dpy, w->reg_ignore, w->reg_ignore,
|
2012-11-01 19:03:56 +08:00
|
|
|
w->border_size);
|
|
|
|
}
|
2012-10-31 08:54:09 +08:00
|
|
|
|
|
|
|
if (last_reg_ignore)
|
2012-11-19 09:46:07 +08:00
|
|
|
XFixesUnionRegion(ps->dpy, w->reg_ignore, w->reg_ignore,
|
2012-10-31 08:54:09 +08:00
|
|
|
last_reg_ignore);
|
|
|
|
}
|
|
|
|
// Otherwise we copy the last region over
|
|
|
|
else if (last_reg_ignore)
|
2012-11-19 09:46:07 +08:00
|
|
|
w->reg_ignore = copy_region(ps, last_reg_ignore);
|
2012-10-21 20:44:24 +08:00
|
|
|
else
|
2012-10-31 08:54:09 +08:00
|
|
|
w->reg_ignore = None;
|
|
|
|
}
|
2012-10-21 20:44:24 +08:00
|
|
|
|
2012-10-31 08:54:09 +08:00
|
|
|
last_reg_ignore = w->reg_ignore;
|
2012-10-21 20:44:24 +08:00
|
|
|
|
2012-11-09 21:44:02 +08:00
|
|
|
if (is_highest && to_paint) {
|
2012-11-19 09:46:07 +08:00
|
|
|
is_highest = false;
|
2012-11-09 21:44:02 +08:00
|
|
|
if (WINDOW_SOLID == w->mode
|
|
|
|
&& (!w->frame_opacity || !win_has_frame(w))
|
2012-11-19 09:46:07 +08:00
|
|
|
&& win_is_fullscreen(ps, w))
|
|
|
|
ps->unredir_possible = true;
|
2012-11-09 21:44:02 +08:00
|
|
|
}
|
|
|
|
|
2012-10-31 08:54:09 +08:00
|
|
|
// Reset flags
|
|
|
|
w->flags = 0;
|
2012-10-21 20:44:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-11-04 19:14:21 +08:00
|
|
|
// Avoid setting w->to_paint if w is to be freed
|
|
|
|
bool destroyed = (w->opacity_tgt == w->opacity && w->destroyed);
|
|
|
|
|
2012-10-31 08:54:09 +08:00
|
|
|
if (to_paint) {
|
|
|
|
w->prev_trans = t;
|
|
|
|
t = w;
|
|
|
|
}
|
|
|
|
else {
|
2012-11-19 09:46:07 +08:00
|
|
|
check_fade_fin(ps, w);
|
2012-10-31 08:54:09 +08:00
|
|
|
}
|
2012-11-04 19:14:21 +08:00
|
|
|
|
|
|
|
if (!destroyed)
|
|
|
|
w->to_paint = to_paint;
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-11-09 21:44:02 +08:00
|
|
|
// If possible, unredirect all windows and stop painting
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.unredir_if_possible && ps->unredir_possible) {
|
|
|
|
redir_stop(ps);
|
2012-11-09 21:44:02 +08:00
|
|
|
}
|
|
|
|
else {
|
2012-11-19 09:46:07 +08:00
|
|
|
redir_start(ps);
|
2012-11-09 21:44:02 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Fetch pictures only if windows are redirected
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->redirected) {
|
2012-11-09 21:44:02 +08:00
|
|
|
for (w = t; w; w = w->prev_trans) {
|
|
|
|
// Fetch the picture and pixmap if needed
|
|
|
|
if (!w->picture) {
|
|
|
|
XRenderPictureAttributes pa;
|
|
|
|
XRenderPictFormat *format;
|
|
|
|
Drawable draw = w->id;
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->has_name_pixmap && !w->pixmap) {
|
|
|
|
set_ignore_next(ps);
|
|
|
|
w->pixmap = XCompositeNameWindowPixmap(ps->dpy, w->id);
|
2012-11-09 21:44:02 +08:00
|
|
|
}
|
|
|
|
if (w->pixmap) draw = w->pixmap;
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
format = XRenderFindVisualFormat(ps->dpy, w->a.visual);
|
2012-11-09 21:44:02 +08:00
|
|
|
pa.subwindow_mode = IncludeInferiors;
|
|
|
|
w->picture = XRenderCreatePicture(
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->dpy, draw, format, CPSubwindowMode, &pa);
|
2012-11-09 21:44:02 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
return t;
|
|
|
|
}
|
|
|
|
|
2012-10-21 20:44:24 +08:00
|
|
|
/**
|
|
|
|
* Paint the shadow of a window.
|
|
|
|
*/
|
|
|
|
static inline void
|
2012-11-19 09:46:07 +08:00
|
|
|
win_paint_shadow(session_t *ps, win *w, Picture tgt_buffer) {
|
2012-10-21 20:44:24 +08:00
|
|
|
XRenderComposite(
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->dpy, PictOpOver, w->shadow_pict, w->shadow_alpha_pict,
|
2012-10-24 10:09:59 +08:00
|
|
|
tgt_buffer, 0, 0, 0, 0,
|
2012-10-21 20:44:24 +08:00
|
|
|
w->a.x + w->shadow_dx, w->a.y + w->shadow_dy,
|
|
|
|
w->shadow_width, w->shadow_height);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Paint a window itself and dim it if asked.
|
|
|
|
*/
|
|
|
|
static inline void
|
2012-11-19 09:46:07 +08:00
|
|
|
win_paint_win(session_t *ps, win *w, Picture tgt_buffer) {
|
2012-10-21 20:44:24 +08:00
|
|
|
int x = w->a.x;
|
|
|
|
int y = w->a.y;
|
|
|
|
int wid = w->widthb;
|
|
|
|
int hei = w->heightb;
|
|
|
|
|
|
|
|
Picture alpha_mask = (OPAQUE == w->opacity ? None: w->alpha_pict);
|
|
|
|
int op = (w->mode == WINDOW_SOLID ? PictOpSrc: PictOpOver);
|
|
|
|
|
|
|
|
if (!w->frame_opacity) {
|
2012-11-19 09:46:07 +08:00
|
|
|
XRenderComposite(ps->dpy, op, w->picture, alpha_mask,
|
2012-10-24 10:09:59 +08:00
|
|
|
tgt_buffer, 0, 0, 0, 0, x, y, wid, hei);
|
2012-10-21 20:44:24 +08:00
|
|
|
}
|
|
|
|
else {
|
2012-11-01 19:03:56 +08:00
|
|
|
int t = w->top_width;
|
|
|
|
int l = w->left_width;
|
|
|
|
int b = w->bottom_width;
|
|
|
|
int r = w->right_width;
|
2012-10-21 20:44:24 +08:00
|
|
|
|
2012-11-01 19:03:56 +08:00
|
|
|
#define COMP_BDR(cx, cy, cwid, chei) \
|
2012-11-19 09:46:07 +08:00
|
|
|
XRenderComposite(ps->dpy, PictOpOver, w->picture, w->frame_alpha_pict, \
|
2012-11-01 19:03:56 +08:00
|
|
|
tgt_buffer, (cx), (cy), 0, 0, x + (cx), y + (cy), (cwid), (chei))
|
2012-10-21 20:44:24 +08:00
|
|
|
|
2012-11-06 11:32:02 +08:00
|
|
|
// The following complicated logic is required because some broken
|
2012-11-01 19:03:56 +08:00
|
|
|
// window managers (I'm talking about you, Openbox!) that makes
|
|
|
|
// top_width + bottom_width > height in some cases.
|
2012-10-21 20:44:24 +08:00
|
|
|
|
2012-11-01 19:03:56 +08:00
|
|
|
// top
|
2012-11-06 11:32:02 +08:00
|
|
|
int phei = min_i(t, hei);
|
|
|
|
if (phei > 0)
|
|
|
|
COMP_BDR(0, 0, wid, phei);
|
2012-11-01 19:03:56 +08:00
|
|
|
|
|
|
|
if (hei > t) {
|
2012-11-06 11:32:02 +08:00
|
|
|
phei = min_i(hei - t, b);
|
2012-11-01 19:03:56 +08:00
|
|
|
|
|
|
|
// bottom
|
2012-11-06 11:32:02 +08:00
|
|
|
if (phei > 0)
|
2012-11-01 19:03:56 +08:00
|
|
|
COMP_BDR(0, hei - phei, wid, phei);
|
|
|
|
|
2012-11-06 11:32:02 +08:00
|
|
|
phei = hei - t - phei;
|
|
|
|
if (phei > 0) {
|
|
|
|
int pwid = min_i(l, wid);
|
|
|
|
// left
|
|
|
|
if (pwid > 0)
|
|
|
|
COMP_BDR(0, t, pwid, phei);
|
|
|
|
|
|
|
|
if (wid > l) {
|
|
|
|
pwid = min_i(wid - l, r);
|
|
|
|
|
|
|
|
// right
|
|
|
|
if (pwid > 0)
|
|
|
|
COMP_BDR(wid - pwid, t, pwid, phei);
|
|
|
|
|
|
|
|
pwid = wid - l - pwid;
|
|
|
|
if (pwid > 0) {
|
|
|
|
// body
|
2012-11-19 09:46:07 +08:00
|
|
|
XRenderComposite(ps->dpy, op, w->picture, alpha_mask,
|
2012-11-06 11:32:02 +08:00
|
|
|
tgt_buffer, l, t, 0, 0, x + l, y + t, pwid, phei);
|
2012-11-01 19:03:56 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-10-21 20:44:24 +08:00
|
|
|
}
|
|
|
|
|
2012-11-01 19:03:56 +08:00
|
|
|
#undef COMP_BDR
|
|
|
|
|
2012-10-21 20:44:24 +08:00
|
|
|
// Dimming the window if needed
|
|
|
|
if (w->dim) {
|
2012-11-19 09:46:07 +08:00
|
|
|
XRenderComposite(ps->dpy, PictOpOver, ps->dim_picture, None,
|
2012-10-24 10:09:59 +08:00
|
|
|
tgt_buffer, 0, 0, 0, 0, x, y, wid, hei);
|
2012-10-21 20:44:24 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-03 10:30:32 +08:00
|
|
|
/**
|
|
|
|
* Rebuild cached <code>screen_reg</code>.
|
|
|
|
*/
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
rebuild_screen_reg(session_t *ps) {
|
|
|
|
if (ps->screen_reg)
|
|
|
|
XFixesDestroyRegion(ps->dpy, ps->screen_reg);
|
|
|
|
ps->screen_reg = get_screen_region(ps);
|
2012-11-03 10:30:32 +08:00
|
|
|
}
|
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
paint_all(session_t *ps, XserverRegion region, win *t) {
|
2012-10-26 11:12:28 +08:00
|
|
|
#ifdef DEBUG_REPAINT
|
|
|
|
static struct timespec last_paint = { 0 };
|
|
|
|
#endif
|
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
win *w;
|
2012-10-21 20:44:24 +08:00
|
|
|
XserverRegion reg_paint = None, reg_tmp = None, reg_tmp2 = None;
|
2012-09-19 20:49:16 +08:00
|
|
|
|
|
|
|
if (!region) {
|
2012-11-19 09:46:07 +08:00
|
|
|
region = get_screen_region(ps);
|
2012-09-19 20:49:16 +08:00
|
|
|
}
|
2012-10-21 20:44:24 +08:00
|
|
|
else {
|
|
|
|
// Remove the damaged area out of screen
|
2012-11-19 09:46:07 +08:00
|
|
|
XFixesIntersectRegion(ps->dpy, region, region, ps->screen_reg);
|
2012-10-21 20:44:24 +08:00
|
|
|
}
|
2012-09-19 20:49:16 +08:00
|
|
|
|
|
|
|
#ifdef MONITOR_REPAINT
|
2012-10-23 13:42:20 +08:00
|
|
|
// Note: MONITOR_REPAINT cannot work with DBE right now.
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->tgt_buffer = ps->tgt_picture;
|
2012-09-19 20:49:16 +08:00
|
|
|
#else
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!ps->tgt_buffer) {
|
2012-10-23 13:42:20 +08:00
|
|
|
// DBE painting mode: Directly paint to a Picture of the back buffer
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.dbe) {
|
|
|
|
ps->tgt_buffer = XRenderCreatePicture(ps->dpy, ps->root_dbe,
|
|
|
|
XRenderFindVisualFormat(ps->dpy, ps->vis),
|
2012-10-23 13:42:20 +08:00
|
|
|
0, 0);
|
|
|
|
}
|
|
|
|
// No-DBE painting mode: Paint to an intermediate Picture then paint
|
|
|
|
// the Picture to root window
|
|
|
|
else {
|
|
|
|
Pixmap root_pixmap = XCreatePixmap(
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->dpy, ps->root, ps->root_width, ps->root_height,
|
|
|
|
ps->depth);
|
2012-09-19 20:49:16 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->tgt_buffer = XRenderCreatePicture(ps->dpy, root_pixmap,
|
|
|
|
XRenderFindVisualFormat(ps->dpy, ps->vis),
|
2012-10-23 13:42:20 +08:00
|
|
|
0, 0);
|
2012-09-19 20:49:16 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
XFreePixmap(ps->dpy, root_pixmap);
|
2012-10-23 13:42:20 +08:00
|
|
|
}
|
2012-09-19 20:49:16 +08:00
|
|
|
}
|
2003-11-24 07:20:42 +08:00
|
|
|
#endif
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
XFixesSetPictureClipRegion(ps->dpy, ps->tgt_picture, 0, 0, region);
|
2012-09-19 20:49:16 +08:00
|
|
|
|
|
|
|
#ifdef MONITOR_REPAINT
|
|
|
|
XRenderComposite(
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->dpy, PictOpSrc, ps->black_picture, None,
|
|
|
|
ps->tgt_picture, 0, 0, 0, 0, 0, 0,
|
|
|
|
ps->root_width, ps->root_height);
|
2012-09-19 20:49:16 +08:00
|
|
|
#endif
|
2012-09-13 13:58:05 +08:00
|
|
|
|
2012-10-21 20:44:24 +08:00
|
|
|
if (t && t->reg_ignore) {
|
|
|
|
// Calculate the region upon which the root window is to be painted
|
|
|
|
// based on the ignore region of the lowest window, if available
|
2012-11-19 09:46:07 +08:00
|
|
|
reg_paint = reg_tmp = XFixesCreateRegion(ps->dpy, NULL, 0);
|
|
|
|
XFixesSubtractRegion(ps->dpy, reg_paint, region, t->reg_ignore);
|
2012-10-21 20:44:24 +08:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
reg_paint = region;
|
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
XFixesSetPictureClipRegion(ps->dpy, ps->tgt_buffer, 0, 0, reg_paint);
|
2012-10-21 20:44:24 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
paint_root(ps, ps->tgt_buffer);
|
2012-09-17 16:04:04 +08:00
|
|
|
|
2012-10-21 20:44:24 +08:00
|
|
|
// Create temporary regions for use during painting
|
|
|
|
if (!reg_tmp)
|
2012-11-19 09:46:07 +08:00
|
|
|
reg_tmp = XFixesCreateRegion(ps->dpy, NULL, 0);
|
|
|
|
reg_tmp2 = XFixesCreateRegion(ps->dpy, NULL, 0);
|
2012-10-21 20:44:24 +08:00
|
|
|
|
|
|
|
for (w = t; w; w = w->prev_trans) {
|
2012-09-17 16:04:04 +08:00
|
|
|
// Painting shadow
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
if (w->shadow) {
|
2012-10-21 20:44:24 +08:00
|
|
|
// Shadow is to be painted based on the ignore region of current
|
|
|
|
// window
|
|
|
|
if (w->reg_ignore) {
|
|
|
|
if (w == t) {
|
|
|
|
// If it's the first cycle and reg_tmp2 is not ready, calculate
|
|
|
|
// the paint region here
|
|
|
|
reg_paint = reg_tmp;
|
2012-11-19 09:46:07 +08:00
|
|
|
XFixesSubtractRegion(ps->dpy, reg_paint, region, w->reg_ignore);
|
2012-10-21 20:44:24 +08:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Otherwise, used the cached region during last cycle
|
|
|
|
reg_paint = reg_tmp2;
|
|
|
|
}
|
2012-11-19 09:46:07 +08:00
|
|
|
XFixesIntersectRegion(ps->dpy, reg_paint, reg_paint, w->extents);
|
2012-10-21 20:44:24 +08:00
|
|
|
}
|
|
|
|
else {
|
2012-10-28 17:02:07 +08:00
|
|
|
reg_paint = reg_tmp;
|
2012-11-19 09:46:07 +08:00
|
|
|
XFixesIntersectRegion(ps->dpy, reg_paint, region, w->extents);
|
2012-10-21 20:44:24 +08:00
|
|
|
}
|
2012-10-28 17:02:07 +08:00
|
|
|
// Clear the shadow here instead of in make_shadow() for saving GPU
|
|
|
|
// power and handling shaped windows
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.clear_shadow && w->border_size)
|
|
|
|
XFixesSubtractRegion(ps->dpy, reg_paint, reg_paint, w->border_size);
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-10-21 20:44:24 +08:00
|
|
|
// Detect if the region is empty before painting
|
2012-11-19 09:46:07 +08:00
|
|
|
if (region == reg_paint || !is_region_empty(ps, reg_paint)) {
|
|
|
|
XFixesSetPictureClipRegion(ps->dpy, ps->tgt_buffer, 0, 0, reg_paint);
|
2011-11-04 17:18:10 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
win_paint_shadow(ps, w, ps->tgt_buffer);
|
2012-10-21 20:44:24 +08:00
|
|
|
}
|
|
|
|
}
|
2011-11-04 17:18:10 +08:00
|
|
|
|
2012-10-21 20:44:24 +08:00
|
|
|
// Calculate the region based on the reg_ignore of the next (higher)
|
|
|
|
// window and the bounding region
|
|
|
|
reg_paint = reg_tmp;
|
|
|
|
if (w->prev_trans && w->prev_trans->reg_ignore) {
|
2012-11-19 09:46:07 +08:00
|
|
|
XFixesSubtractRegion(ps->dpy, reg_paint, region,
|
2012-10-21 20:44:24 +08:00
|
|
|
w->prev_trans->reg_ignore);
|
|
|
|
// Copy the subtracted region to be used for shadow painting in next
|
|
|
|
// cycle
|
2012-11-19 09:46:07 +08:00
|
|
|
XFixesCopyRegion(ps->dpy, reg_tmp2, reg_paint);
|
2012-11-01 10:43:15 +08:00
|
|
|
|
|
|
|
if (w->border_size)
|
2012-11-19 09:46:07 +08:00
|
|
|
XFixesIntersectRegion(ps->dpy, reg_paint, reg_paint, w->border_size);
|
2012-09-17 16:04:04 +08:00
|
|
|
}
|
|
|
|
else {
|
2012-11-01 10:43:15 +08:00
|
|
|
if (w->border_size)
|
2012-11-19 09:46:07 +08:00
|
|
|
XFixesIntersectRegion(ps->dpy, reg_paint, region, w->border_size);
|
2012-11-01 10:43:15 +08:00
|
|
|
else
|
|
|
|
reg_paint = region;
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2011-11-04 17:18:10 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!is_region_empty(ps, reg_paint)) {
|
|
|
|
XFixesSetPictureClipRegion(ps->dpy, ps->tgt_buffer, 0, 0, reg_paint);
|
2012-09-17 16:04:04 +08:00
|
|
|
|
2012-10-21 20:44:24 +08:00
|
|
|
// Painting the window
|
2012-11-19 09:46:07 +08:00
|
|
|
win_paint_win(ps, w, ps->tgt_buffer);
|
2012-10-21 20:44:24 +08:00
|
|
|
}
|
2012-09-19 20:49:16 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
check_fade_fin(ps, w);
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-10-21 20:44:24 +08:00
|
|
|
// Free up all temporary regions
|
2012-11-19 09:46:07 +08:00
|
|
|
XFixesDestroyRegion(ps->dpy, region);
|
|
|
|
XFixesDestroyRegion(ps->dpy, reg_tmp);
|
|
|
|
XFixesDestroyRegion(ps->dpy, reg_tmp2);
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-10-27 21:46:01 +08:00
|
|
|
// Do this as early as possible
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!ps->o.dbe)
|
|
|
|
XFixesSetPictureClipRegion(ps->dpy, ps->tgt_buffer, 0, 0, None);
|
2012-10-27 21:46:01 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (VSYNC_NONE != ps->o.vsync) {
|
2012-11-01 10:43:15 +08:00
|
|
|
// Make sure all previous requests are processed to achieve best
|
|
|
|
// effect
|
2012-11-19 09:46:07 +08:00
|
|
|
XSync(ps->dpy, False);
|
2012-11-01 10:43:15 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Wait for VBlank. We could do it aggressively (send the painting
|
|
|
|
// request and XFlush() on VBlank) or conservatively (send the request
|
|
|
|
// only on VBlank).
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!ps->o.vsync_aggressive)
|
|
|
|
vsync_wait(ps);
|
2012-10-26 11:12:28 +08:00
|
|
|
|
2012-10-23 13:42:20 +08:00
|
|
|
// DBE painting mode, only need to swap the buffer
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.dbe) {
|
2012-10-23 13:42:20 +08:00
|
|
|
XdbeSwapInfo swap_info = {
|
2012-11-19 09:46:07 +08:00
|
|
|
.swap_window = (ps->o.paint_on_overlay ? ps->overlay: ps->root),
|
2012-10-23 13:42:20 +08:00
|
|
|
// Is it safe to use XdbeUndefined?
|
|
|
|
.swap_action = XdbeCopied
|
|
|
|
};
|
2012-11-19 09:46:07 +08:00
|
|
|
XdbeSwapBuffers(ps->dpy, &swap_info, 1);
|
2012-10-23 13:42:20 +08:00
|
|
|
}
|
2012-10-24 10:09:59 +08:00
|
|
|
// No-DBE painting mode
|
2012-11-19 09:46:07 +08:00
|
|
|
else if (ps->tgt_buffer != ps->tgt_picture) {
|
2011-11-04 17:18:10 +08:00
|
|
|
XRenderComposite(
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->dpy, PictOpSrc, ps->tgt_buffer, None,
|
|
|
|
ps->tgt_picture, 0, 0, 0, 0,
|
|
|
|
0, 0, ps->root_width, ps->root_height);
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2012-10-26 11:12:28 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.vsync_aggressive)
|
|
|
|
vsync_wait(ps);
|
2012-11-01 10:43:15 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
XFlush(ps->dpy);
|
2012-10-26 11:12:28 +08:00
|
|
|
|
|
|
|
#ifdef DEBUG_REPAINT
|
2012-11-19 09:46:07 +08:00
|
|
|
print_timestamp(ps);
|
2012-10-26 11:12:28 +08:00
|
|
|
struct timespec now = get_time_timespec();
|
|
|
|
struct timespec diff = { 0 };
|
|
|
|
timespec_subtract(&diff, &now, &last_paint);
|
|
|
|
printf("[ %5ld:%09ld ] ", diff.tv_sec, diff.tv_nsec);
|
|
|
|
last_paint = now;
|
2012-10-30 18:11:30 +08:00
|
|
|
printf("paint:");
|
|
|
|
for (w = t; w; w = w->prev_trans)
|
|
|
|
printf(" %#010lx", w->id);
|
|
|
|
putchar('\n');
|
2012-10-26 11:12:28 +08:00
|
|
|
fflush(stdout);
|
|
|
|
#endif
|
2003-11-09 15:08:23 +08:00
|
|
|
}
|
|
|
|
|
2003-11-20 00:12:15 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
add_damage(session_t *ps, XserverRegion damage) {
|
|
|
|
if (ps->all_damage) {
|
|
|
|
XFixesUnionRegion(ps->dpy, ps->all_damage, ps->all_damage, damage);
|
|
|
|
XFixesDestroyRegion(ps->dpy, damage);
|
2011-11-04 16:41:56 +08:00
|
|
|
} else {
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->all_damage = damage;
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
2003-11-09 15:08:23 +08:00
|
|
|
}
|
|
|
|
|
2003-11-20 00:12:15 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
repair_win(session_t *ps, win *w) {
|
2011-11-04 16:41:56 +08:00
|
|
|
XserverRegion parts;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
|
|
|
if (!w->damaged) {
|
2012-11-19 09:46:07 +08:00
|
|
|
parts = win_extents(ps, w);
|
|
|
|
set_ignore_next(ps);
|
|
|
|
XDamageSubtract(ps->dpy, w->damage, None, None);
|
2011-11-04 14:33:23 +08:00
|
|
|
} else {
|
2012-11-19 09:46:07 +08:00
|
|
|
parts = XFixesCreateRegion(ps->dpy, 0, 0);
|
|
|
|
set_ignore_next(ps);
|
|
|
|
XDamageSubtract(ps->dpy, w->damage, None, parts);
|
|
|
|
XFixesTranslateRegion(ps->dpy, parts,
|
2011-11-04 16:41:56 +08:00
|
|
|
w->a.x + w->a.border_width,
|
|
|
|
w->a.y + w->a.border_width);
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-10-21 20:44:24 +08:00
|
|
|
// Remove the part in the damage area that could be ignored
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!ps->reg_ignore_expire && w->prev_trans && w->prev_trans->reg_ignore)
|
|
|
|
XFixesSubtractRegion(ps->dpy, parts, parts, w->prev_trans->reg_ignore);
|
2012-10-21 20:44:24 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
add_damage(ps, parts);
|
2011-11-04 14:33:23 +08:00
|
|
|
w->damaged = 1;
|
2003-11-09 15:08:23 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
static wintype_t
|
|
|
|
wid_get_prop_wintype(session_t *ps, Window wid) {
|
|
|
|
int i, j;
|
|
|
|
|
|
|
|
set_ignore_next(ps);
|
|
|
|
winprop_t prop = wid_get_prop(ps, wid, ps->atom_win_type, 32L, XA_ATOM, 32);
|
|
|
|
|
|
|
|
for (i = 0; i < prop.nitems; ++i) {
|
2012-09-22 20:49:17 +08:00
|
|
|
for (j = 1; j < NUM_WINTYPES; ++j) {
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->atoms_wintypes[j] == (Atom) ((long *) prop.data)[i]) {
|
|
|
|
free_winprop(&prop);
|
2012-09-22 20:49:17 +08:00
|
|
|
return j;
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
|
|
|
}
|
2012-09-22 20:49:17 +08:00
|
|
|
}
|
2008-02-15 12:38:32 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
free_winprop(&prop);
|
2008-02-15 12:38:32 +08:00
|
|
|
|
2012-09-22 20:49:17 +08:00
|
|
|
return WINTYPE_UNKNOWN;
|
2008-02-15 12:38:32 +08:00
|
|
|
}
|
|
|
|
|
2003-11-20 00:12:15 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
map_win(session_t *ps, Window id, bool override_redirect) {
|
|
|
|
win *w = find_win(ps, id);
|
2003-11-09 15:08:23 +08:00
|
|
|
|
2012-10-27 21:46:01 +08:00
|
|
|
// Don't care about window mapping if it's an InputOnly window
|
|
|
|
if (!w || InputOnly == w->a.class) return;
|
2004-09-10 13:55:19 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
w->focused = false;
|
2011-11-04 14:33:23 +08:00
|
|
|
w->a.map_state = IsViewable;
|
2008-02-15 12:38:32 +08:00
|
|
|
|
2012-09-18 11:28:09 +08:00
|
|
|
// Call XSelectInput() before reading properties so that no property
|
|
|
|
// changes are lost
|
2012-11-19 09:46:07 +08:00
|
|
|
XSelectInput(ps->dpy, id, determine_evmask(ps, id, WIN_EVMODE_FRAME));
|
2012-09-18 11:28:09 +08:00
|
|
|
|
|
|
|
// Notify compton when the shape of a window changes
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->shape_exists) {
|
|
|
|
XShapeSelectInput(ps->dpy, id, ShapeNotifyMask);
|
2012-09-18 11:28:09 +08:00
|
|
|
}
|
2012-09-14 11:51:46 +08:00
|
|
|
|
2012-09-18 11:28:09 +08:00
|
|
|
// Detect client window here instead of in add_win() as the client
|
|
|
|
// window should have been prepared at this point
|
2012-09-20 13:50:27 +08:00
|
|
|
if (!w->client_win) {
|
2012-10-02 21:46:37 +08:00
|
|
|
Window cw = 0;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
// Always recursively look for a window with WM_STATE, as Fluxbox
|
|
|
|
// sets override-redirect flags on all frame windows.
|
2012-11-19 09:46:07 +08:00
|
|
|
cw = find_client_win(ps, w->id);
|
2012-09-20 13:50:27 +08:00
|
|
|
#ifdef DEBUG_CLIENTWIN
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
printf("find_client_win(%#010lx): client %#010lx\n", w->id, cw);
|
2012-09-20 13:50:27 +08:00
|
|
|
#endif
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
// Set a window's client window to itself only if we didn't find a
|
|
|
|
// client window and the window has override-redirect flag
|
|
|
|
if (!cw && w->a.override_redirect) {
|
2012-10-02 21:46:37 +08:00
|
|
|
cw = w->id;
|
|
|
|
#ifdef DEBUG_CLIENTWIN
|
|
|
|
printf("find_client_win(%#010lx): client self (override-redirected)\n", w->id);
|
|
|
|
#endif
|
|
|
|
}
|
2012-09-18 11:28:09 +08:00
|
|
|
if (cw) {
|
2012-11-19 09:46:07 +08:00
|
|
|
mark_client_win(ps, w, cw);
|
2012-09-11 21:33:03 +08:00
|
|
|
}
|
2012-02-27 12:00:12 +08:00
|
|
|
}
|
2012-11-10 11:41:01 +08:00
|
|
|
else {
|
|
|
|
// Re-mark client window here
|
2012-11-19 09:46:07 +08:00
|
|
|
mark_client_win(ps, w, w->client_win);
|
2012-09-20 13:50:27 +08:00
|
|
|
}
|
2011-11-05 01:02:17 +08:00
|
|
|
|
2012-10-21 21:19:00 +08:00
|
|
|
// Workaround for _NET_WM_WINDOW_TYPE for Openbox menus, which is
|
|
|
|
// set on a non-override-redirect window with no WM_STATE either
|
|
|
|
if (!w->client_win && WINTYPE_UNKNOWN == w->window_type)
|
2012-11-19 09:46:07 +08:00
|
|
|
w->window_type = wid_get_prop_wintype(ps, w->id);
|
2012-10-21 21:19:00 +08:00
|
|
|
|
2012-09-22 20:49:17 +08:00
|
|
|
#ifdef DEBUG_WINTYPE
|
|
|
|
printf("map_win(%#010lx): type %s\n",
|
2012-09-25 21:04:10 +08:00
|
|
|
w->id, WINTYPES[w->window_type]);
|
2012-09-22 20:49:17 +08:00
|
|
|
#endif
|
|
|
|
|
2012-10-01 10:34:40 +08:00
|
|
|
// Detect if the window is shaped or has rounded corners
|
2012-11-19 09:46:07 +08:00
|
|
|
win_update_shape_raw(ps, w);
|
2012-10-01 10:34:40 +08:00
|
|
|
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
// Get window name and class if we are tracking them
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.track_wdata) {
|
|
|
|
win_get_name(ps, w);
|
|
|
|
win_get_class(ps, w);
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.track_focus) {
|
2012-11-04 18:11:08 +08:00
|
|
|
// Occasionally compton does not seem able to get a FocusIn event from
|
|
|
|
// a window just mapped. I suspect it's a timing issue again when the
|
|
|
|
// XSelectInput() is called too late. We have to recheck the focused
|
|
|
|
// window here. It makes no sense if we are using EWMH
|
|
|
|
// _NET_ACTIVE_WINDOW.
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!ps->o.use_ewmh_active_win)
|
|
|
|
recheck_focus(ps);
|
2012-11-04 18:11:08 +08:00
|
|
|
|
2012-09-20 13:50:27 +08:00
|
|
|
// Consider a window without client window a WM window and mark it
|
2012-09-26 19:48:36 +08:00
|
|
|
// focused if mark_wmwin_focused is on, or it's over-redirected and
|
|
|
|
// mark_ovredir_focused is on
|
2012-11-19 09:46:07 +08:00
|
|
|
if ((ps->o.mark_wmwin_focused && !w->client_win)
|
|
|
|
|| (ps->o.mark_ovredir_focused && w->id == w->client_win))
|
|
|
|
w->focused = true;
|
2012-09-13 23:12:54 +08:00
|
|
|
}
|
2012-09-12 11:06:16 +08:00
|
|
|
|
2012-11-09 11:35:40 +08:00
|
|
|
// Check for _COMPTON_SHADOW
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.respect_prop_shadow)
|
|
|
|
win_update_attr_shadow_raw(ps, w);
|
2012-11-09 11:35:40 +08:00
|
|
|
|
|
|
|
// Many things above could affect shadow
|
2012-11-19 09:46:07 +08:00
|
|
|
determine_shadow(ps, w);
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
// Fading in
|
2012-11-19 09:46:07 +08:00
|
|
|
calc_opacity(ps, w, true);
|
2012-09-26 21:40:48 +08:00
|
|
|
|
2012-10-01 10:34:40 +08:00
|
|
|
// Set fading state
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.no_fading_openclose) {
|
|
|
|
set_fade_callback(ps, w, finish_map_win, true);
|
2012-09-26 21:40:48 +08:00
|
|
|
// Must be set after we execute the old fade callback, in case we
|
|
|
|
// receive two continuous MapNotify for the same window
|
2012-11-19 09:46:07 +08:00
|
|
|
w->fade = false;
|
2012-09-26 21:40:48 +08:00
|
|
|
}
|
|
|
|
else {
|
2012-11-19 09:46:07 +08:00
|
|
|
set_fade_callback(ps, w, NULL, true);
|
|
|
|
determine_fade(ps, w);
|
2012-09-26 21:40:48 +08:00
|
|
|
}
|
2008-02-15 13:55:17 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
calc_dim(ps, w);
|
2008-02-15 13:55:17 +08:00
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
w->damaged = 1;
|
2004-09-10 13:55:19 +08:00
|
|
|
|
2008-02-15 13:55:17 +08:00
|
|
|
|
2011-11-04 17:18:10 +08:00
|
|
|
/* if any configure events happened while
|
|
|
|
the window was unmapped, then configure
|
|
|
|
the window to its correct place */
|
2011-11-04 16:41:56 +08:00
|
|
|
if (w->need_configure) {
|
2012-11-19 09:46:07 +08:00
|
|
|
configure_win(ps, &w->queue_configure);
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
2003-11-09 15:08:23 +08:00
|
|
|
}
|
|
|
|
|
2012-09-26 21:40:48 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
finish_map_win(session_t *ps, win *w) {
|
|
|
|
if (ps->o.no_fading_openclose)
|
|
|
|
determine_fade(ps, w);
|
2012-09-26 21:40:48 +08:00
|
|
|
}
|
|
|
|
|
2003-11-20 00:12:15 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
finish_unmap_win(session_t *ps, win *w) {
|
2011-11-04 14:33:23 +08:00
|
|
|
w->damaged = 0;
|
2012-10-31 08:54:09 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
update_reg_ignore_expire(ps, w);
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
if (w->extents != None) {
|
2012-02-27 12:00:12 +08:00
|
|
|
/* destroys region */
|
2012-11-19 09:46:07 +08:00
|
|
|
add_damage(ps, w->extents);
|
2011-11-04 14:33:23 +08:00
|
|
|
w->extents = None;
|
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
free_pixmap(ps, &w->pixmap);
|
|
|
|
free_picture(ps, &w->picture);
|
|
|
|
free_region(ps, &w->border_size);
|
|
|
|
free_picture(ps, &w->shadow_pict);
|
2003-11-25 01:11:00 +08:00
|
|
|
}
|
|
|
|
|
2004-07-08 15:07:26 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
unmap_callback(session_t *ps, win *w) {
|
|
|
|
finish_unmap_win(ps, w);
|
2004-07-08 15:07:26 +08:00
|
|
|
}
|
2003-11-25 01:11:00 +08:00
|
|
|
|
2004-07-08 15:07:26 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
unmap_win(session_t *ps, Window id) {
|
|
|
|
win *w = find_win(ps, id);
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-11-09 21:44:02 +08:00
|
|
|
if (!w || IsUnmapped == w->a.map_state) return;
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
w->a.map_state = IsUnmapped;
|
2008-02-15 13:55:17 +08:00
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
// Fading out
|
|
|
|
w->opacity_tgt = 0;
|
2012-11-19 09:46:07 +08:00
|
|
|
set_fade_callback(ps, w, unmap_callback, false);
|
|
|
|
if (ps->o.no_fading_openclose)
|
|
|
|
w->fade = false;
|
2012-09-19 20:49:16 +08:00
|
|
|
|
2012-09-17 16:04:04 +08:00
|
|
|
// don't care about properties anymore
|
2012-11-19 09:46:07 +08:00
|
|
|
win_ev_stop(ps, w);
|
2004-07-08 15:07:26 +08:00
|
|
|
}
|
2003-11-25 01:11:00 +08:00
|
|
|
|
2012-09-13 13:58:05 +08:00
|
|
|
static opacity_t
|
2012-11-19 09:46:07 +08:00
|
|
|
wid_get_opacity_prop(session_t *ps, Window wid, opacity_t def) {
|
|
|
|
opacity_t val = def;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
winprop_t prop = wid_get_prop(ps, wid, ps->atom_opacity, 1L,
|
|
|
|
XA_CARDINAL, 32);
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (prop.nitems)
|
|
|
|
val = *((long *) prop.data);
|
|
|
|
|
|
|
|
free_winprop(&prop);
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
return val;
|
2003-11-25 01:11:00 +08:00
|
|
|
}
|
|
|
|
|
2004-09-10 13:55:19 +08:00
|
|
|
static double
|
2012-11-19 09:46:07 +08:00
|
|
|
get_opacity_percent(win *w) {
|
2012-09-16 23:12:02 +08:00
|
|
|
return ((double) w->opacity) / OPAQUE;
|
2004-09-10 13:55:19 +08:00
|
|
|
}
|
|
|
|
|
2004-07-08 15:07:26 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
determine_mode(session_t *ps, win *w) {
|
2012-10-31 08:54:09 +08:00
|
|
|
winmode mode;
|
2011-11-04 14:33:23 +08:00
|
|
|
XRenderPictFormat *format;
|
|
|
|
|
2012-06-04 00:12:30 +08:00
|
|
|
/* if trans prop == -1 fall back on previous tests */
|
2011-11-04 14:33:23 +08:00
|
|
|
|
|
|
|
if (w->a.class == InputOnly) {
|
|
|
|
format = 0;
|
|
|
|
} else {
|
2012-11-19 09:46:07 +08:00
|
|
|
format = XRenderFindVisualFormat(ps->dpy, w->a.visual);
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
|
|
|
|
2011-11-04 17:18:10 +08:00
|
|
|
if (format && format->type == PictTypeDirect
|
|
|
|
&& format->direct.alphaMask) {
|
2011-11-04 14:33:23 +08:00
|
|
|
mode = WINDOW_ARGB;
|
|
|
|
} else if (w->opacity != OPAQUE) {
|
|
|
|
mode = WINDOW_TRANS;
|
|
|
|
} else {
|
|
|
|
mode = WINDOW_SOLID;
|
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
w->mode = mode;
|
2003-11-09 15:08:23 +08:00
|
|
|
}
|
|
|
|
|
2012-09-11 22:22:58 +08:00
|
|
|
/**
|
|
|
|
* Calculate and set the opacity of a window.
|
|
|
|
*
|
2012-09-26 18:54:35 +08:00
|
|
|
* If window is inactive and inactive_opacity_override is set, the
|
2012-09-11 22:22:58 +08:00
|
|
|
* priority is: (Simulates the old behavior)
|
|
|
|
*
|
2012-09-26 18:54:35 +08:00
|
|
|
* inactive_opacity > _NET_WM_WINDOW_OPACITY (if not opaque)
|
2012-09-11 22:22:58 +08:00
|
|
|
* > window type default opacity
|
|
|
|
*
|
|
|
|
* Otherwise:
|
|
|
|
*
|
|
|
|
* _NET_WM_WINDOW_OPACITY (if not opaque)
|
|
|
|
* > window type default opacity (if not opaque)
|
2012-09-26 18:54:35 +08:00
|
|
|
* > inactive_opacity
|
2012-09-11 22:22:58 +08:00
|
|
|
*
|
|
|
|
* @param dpy X display to use
|
|
|
|
* @param w struct _win object representing the window
|
|
|
|
* @param refetch_prop whether _NET_WM_OPACITY of the window needs to be
|
|
|
|
* refetched
|
|
|
|
*/
|
2012-09-13 13:58:05 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
calc_opacity(session_t *ps, win *w, bool refetch_prop) {
|
2012-09-11 22:22:58 +08:00
|
|
|
opacity_t opacity;
|
|
|
|
|
|
|
|
// Do nothing for unmapped window, calc_opacity() will be called
|
|
|
|
// when it's mapped
|
|
|
|
// I suppose I need not to check for IsUnviewable here?
|
2012-09-13 13:58:05 +08:00
|
|
|
if (IsViewable != w->a.map_state) return;
|
2012-09-11 22:22:58 +08:00
|
|
|
|
|
|
|
// Do not refetch the opacity window attribute unless necessary, this
|
|
|
|
// is probably an expensive operation in some cases
|
2012-09-13 13:58:05 +08:00
|
|
|
if (refetch_prop) {
|
2012-11-19 09:46:07 +08:00
|
|
|
w->opacity_prop = wid_get_opacity_prop(ps, w->id, OPAQUE);
|
|
|
|
if (!ps->o.detect_client_opacity || !w->client_win
|
2012-10-03 21:13:34 +08:00
|
|
|
|| w->id == w->client_win)
|
|
|
|
w->opacity_prop_client = OPAQUE;
|
|
|
|
else
|
2012-11-19 09:46:07 +08:00
|
|
|
w->opacity_prop_client = wid_get_opacity_prop(ps, w->client_win,
|
2012-10-03 21:13:34 +08:00
|
|
|
OPAQUE);
|
2012-09-13 13:58:05 +08:00
|
|
|
}
|
2012-09-11 22:22:58 +08:00
|
|
|
|
2012-10-03 21:13:34 +08:00
|
|
|
if (OPAQUE == (opacity = w->opacity_prop)
|
|
|
|
&& OPAQUE == (opacity = w->opacity_prop_client)) {
|
2012-11-19 09:46:07 +08:00
|
|
|
opacity = ps->o.wintype_opacity[w->window_type] * OPAQUE;
|
2012-09-11 22:22:58 +08:00
|
|
|
}
|
2012-09-13 13:39:43 +08:00
|
|
|
|
2012-09-26 18:54:35 +08:00
|
|
|
// Respect inactive_opacity in some cases
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.inactive_opacity && is_normal_win(w) && false == w->focused
|
|
|
|
&& (OPAQUE == opacity || ps->o.inactive_opacity_override)) {
|
|
|
|
opacity = ps->o.inactive_opacity;
|
2012-09-13 13:58:05 +08:00
|
|
|
}
|
2012-09-11 22:22:58 +08:00
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
w->opacity_tgt = opacity;
|
2012-09-11 22:22:58 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* Determine whether a window is to be dimmed.
|
|
|
|
*/
|
2012-09-13 13:58:05 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
calc_dim(session_t *ps, win *w) {
|
|
|
|
bool dim;
|
2012-09-12 10:52:52 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.inactive_dim && is_normal_win(w) && !(w->focused)) {
|
|
|
|
dim = true;
|
2012-09-13 13:58:05 +08:00
|
|
|
} else {
|
2012-11-19 09:46:07 +08:00
|
|
|
dim = false;
|
2012-09-13 13:58:05 +08:00
|
|
|
}
|
2012-09-12 10:52:52 +08:00
|
|
|
|
|
|
|
if (dim != w->dim) {
|
|
|
|
w->dim = dim;
|
2012-11-19 09:46:07 +08:00
|
|
|
add_damage_win(ps, w);
|
2012-09-12 10:52:52 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-17 22:15:04 +08:00
|
|
|
/**
|
2012-09-19 20:49:16 +08:00
|
|
|
* Determine if a window should fade on opacity change.
|
|
|
|
*/
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
determine_fade(session_t *ps, win *w) {
|
|
|
|
w->fade = ps->o.wintype_fade[w->window_type];
|
2012-09-19 20:49:16 +08:00
|
|
|
}
|
|
|
|
|
2012-11-09 11:35:40 +08:00
|
|
|
/**
|
|
|
|
* Update window-shape.
|
|
|
|
*/
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
win_update_shape_raw(session_t *ps, win *w) {
|
|
|
|
if (ps->shape_exists) {
|
|
|
|
w->bounding_shaped = wid_bounding_shaped(ps, w->id);
|
|
|
|
if (w->bounding_shaped && ps->o.detect_rounded_corners)
|
|
|
|
win_rounded_corners(ps, w);
|
2012-11-09 11:35:40 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-10-28 17:02:07 +08:00
|
|
|
/**
|
|
|
|
* Update window-shape related information.
|
|
|
|
*/
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
win_update_shape(session_t *ps, win *w) {
|
|
|
|
if (ps->shape_exists) {
|
|
|
|
// bool bounding_shaped_old = w->bounding_shaped;
|
2012-10-28 17:02:07 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
win_update_shape_raw(ps, w);
|
2012-10-28 17:02:07 +08:00
|
|
|
|
|
|
|
// Shadow state could be changed
|
2012-11-19 09:46:07 +08:00
|
|
|
determine_shadow(ps, w);
|
2012-10-28 17:02:07 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
// If clear_shadow state on the window possibly changed, destroy the old
|
|
|
|
// shadow_pict
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.clear_shadow && w->bounding_shaped != bounding_shaped_old)
|
|
|
|
free_picture(ps, &w->shadow_pict);
|
2012-10-28 17:02:07 +08:00
|
|
|
*/
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-09 11:35:40 +08:00
|
|
|
/**
|
|
|
|
* Reread _COMPTON_SHADOW property from a window.
|
|
|
|
*
|
|
|
|
* The property must be set on the outermost window, usually the WM frame.
|
|
|
|
*/
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
win_update_attr_shadow_raw(session_t *ps, win *w) {
|
|
|
|
winprop_t prop = wid_get_prop(ps, w->id, ps->atom_compton_shadow, 1,
|
2012-11-09 11:35:40 +08:00
|
|
|
XA_CARDINAL, 32);
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!prop.nitems) {
|
|
|
|
w->attr_shadow = -1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
w->attr_shadow = *((long *) prop.data);
|
2012-11-09 11:35:40 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
free_winprop(&prop);
|
2012-11-09 11:35:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Reread _COMPTON_SHADOW property from a window and update related
|
|
|
|
* things.
|
|
|
|
*/
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
win_update_attr_shadow(session_t *ps, win *w) {
|
2012-11-09 11:35:40 +08:00
|
|
|
long attr_shadow_old = w->attr_shadow;
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
win_update_attr_shadow_raw(ps, w);
|
2012-11-09 11:35:40 +08:00
|
|
|
|
|
|
|
if (w->attr_shadow != attr_shadow_old)
|
2012-11-19 09:46:07 +08:00
|
|
|
determine_shadow(ps, w);
|
2012-11-09 11:35:40 +08:00
|
|
|
}
|
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
/**
|
|
|
|
* Determine if a window should have shadow, and update things depending
|
|
|
|
* on shadow state.
|
2012-09-17 22:15:04 +08:00
|
|
|
*/
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
determine_shadow(session_t *ps, win *w) {
|
|
|
|
bool shadow_old = w->shadow;
|
2012-09-19 20:49:16 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
w->shadow = (ps->o.wintype_shadow[w->window_type]
|
|
|
|
&& !win_match(w, ps->o.shadow_blacklist, &w->cache_sblst)
|
|
|
|
&& !(ps->o.shadow_ignore_shaped && w->bounding_shaped
|
2012-11-09 11:35:40 +08:00
|
|
|
&& !w->rounded_corners)
|
2012-11-19 09:46:07 +08:00
|
|
|
&& !(ps->o.respect_prop_shadow && 0 == w->attr_shadow));
|
2012-09-19 20:49:16 +08:00
|
|
|
|
|
|
|
// Window extents need update on shadow state change
|
|
|
|
if (w->shadow != shadow_old) {
|
|
|
|
// Shadow geometry currently doesn't change on shadow state change
|
2012-11-19 09:46:07 +08:00
|
|
|
// calc_shadow_geometry(ps, w);
|
2012-09-19 20:49:16 +08:00
|
|
|
if (w->extents) {
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
// Mark the old extents as damaged if the shadow is removed
|
|
|
|
if (!w->shadow)
|
2012-11-19 09:46:07 +08:00
|
|
|
add_damage(ps, w->extents);
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
else
|
2012-11-19 09:46:07 +08:00
|
|
|
free_region(ps, &w->extents);
|
|
|
|
w->extents = win_extents(ps, w);
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
// Mark the new extents as damaged if the shadow is added
|
|
|
|
if (w->shadow)
|
2012-11-19 09:46:07 +08:00
|
|
|
add_damage_win(ps, w);
|
2012-09-19 20:49:16 +08:00
|
|
|
}
|
|
|
|
}
|
2012-09-17 22:15:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Update cache data in struct _win that depends on window size.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
calc_win_size(session_t *ps, win *w) {
|
2012-09-17 22:15:04 +08:00
|
|
|
w->widthb = w->a.width + w->a.border_width * 2;
|
|
|
|
w->heightb = w->a.height + w->a.border_width * 2;
|
2012-11-19 09:46:07 +08:00
|
|
|
calc_shadow_geometry(ps, w);
|
2012-09-17 22:15:04 +08:00
|
|
|
w->flags |= WFLAG_SIZE_CHANGE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Calculate and update geometry of the shadow of a window.
|
|
|
|
*/
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
calc_shadow_geometry(session_t *ps, win *w) {
|
|
|
|
w->shadow_dx = ps->o.shadow_offset_x;
|
|
|
|
w->shadow_dy = ps->o.shadow_offset_y;
|
|
|
|
w->shadow_width = w->widthb + ps->gaussian_map->size;
|
|
|
|
w->shadow_height = w->heightb + ps->gaussian_map->size;
|
2012-09-17 22:15:04 +08:00
|
|
|
}
|
|
|
|
|
2012-09-14 11:51:46 +08:00
|
|
|
/**
|
|
|
|
* Mark a window as the client window of another.
|
|
|
|
*
|
|
|
|
* @param dpy display to use
|
|
|
|
* @param w struct _win of the parent window
|
|
|
|
* @param client window ID of the client window
|
|
|
|
*/
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
mark_client_win(session_t *ps, win *w, Window client) {
|
2012-09-14 11:51:46 +08:00
|
|
|
w->client_win = client;
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
XSelectInput(ps->dpy, client, determine_evmask(ps, client, WIN_EVMODE_CLIENT));
|
2012-10-03 21:13:34 +08:00
|
|
|
|
2012-09-14 11:51:46 +08:00
|
|
|
// Get the frame width and monitor further frame width changes on client
|
|
|
|
// window if necessary
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.frame_opacity) {
|
|
|
|
get_frame_extents(ps, w, client);
|
2012-09-14 11:51:46 +08:00
|
|
|
}
|
2012-10-02 21:46:37 +08:00
|
|
|
|
|
|
|
// Detect window type here
|
2012-09-22 20:49:17 +08:00
|
|
|
if (WINTYPE_UNKNOWN == w->window_type)
|
2012-11-19 09:46:07 +08:00
|
|
|
w->window_type = wid_get_prop_wintype(ps, w->client_win);
|
2012-10-02 21:46:37 +08:00
|
|
|
|
|
|
|
// Conform to EWMH standard, if _NET_WM_WINDOW_TYPE is not present, take
|
|
|
|
// override-redirect windows or windows without WM_TRANSIENT_FOR as
|
|
|
|
// _NET_WM_WINDOW_TYPE_NORMAL, otherwise as _NET_WM_WINDOW_TYPE_DIALOG.
|
|
|
|
if (WINTYPE_UNKNOWN == w->window_type) {
|
|
|
|
if (w->a.override_redirect
|
2012-11-19 09:46:07 +08:00
|
|
|
|| !wid_has_attr(ps, client, ps->atom_transient))
|
2012-10-02 21:46:37 +08:00
|
|
|
w->window_type = WINTYPE_NORMAL;
|
|
|
|
else
|
|
|
|
w->window_type = WINTYPE_DIALOG;
|
|
|
|
}
|
2012-09-14 11:51:46 +08:00
|
|
|
}
|
|
|
|
|
2003-11-20 00:12:15 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
add_win(session_t *ps, Window id, Window prev, bool override_redirect) {
|
|
|
|
// Reject overlay window and already added windows
|
|
|
|
if (id == ps->overlay || find_win(ps, id)) {
|
2012-09-09 10:13:56 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-11-04 16:41:56 +08:00
|
|
|
win *new = malloc(sizeof(win));
|
|
|
|
win **p;
|
|
|
|
|
|
|
|
if (!new) return;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
|
|
|
if (prev) {
|
2012-11-19 09:46:07 +08:00
|
|
|
for (p = &ps->list; *p; p = &(*p)->next) {
|
2011-11-04 14:33:23 +08:00
|
|
|
if ((*p)->id == prev && !(*p)->destroyed)
|
|
|
|
break;
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
|
|
|
} else {
|
2012-11-19 09:46:07 +08:00
|
|
|
p = &ps->list;
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
new->id = id;
|
2012-11-19 09:46:07 +08:00
|
|
|
set_ignore_next(ps);
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!XGetWindowAttributes(ps->dpy, id, &new->a)) {
|
2011-11-04 14:33:23 +08:00
|
|
|
free(new);
|
|
|
|
return;
|
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
new->damaged = 0;
|
2012-11-19 09:46:07 +08:00
|
|
|
new->to_paint = false;
|
2011-11-04 14:33:23 +08:00
|
|
|
new->pixmap = None;
|
|
|
|
new->picture = None;
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
if (new->a.class == InputOnly) {
|
|
|
|
new->damage_sequence = 0;
|
|
|
|
new->damage = None;
|
|
|
|
} else {
|
2012-11-19 09:46:07 +08:00
|
|
|
new->damage_sequence = NextRequest(ps->dpy);
|
|
|
|
set_ignore_next(ps);
|
|
|
|
new->damage = XDamageCreate(ps->dpy, id, XDamageReportNonEmpty);
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
new->name = NULL;
|
|
|
|
new->class_instance = NULL;
|
|
|
|
new->class_general = NULL;
|
|
|
|
new->cache_sblst = NULL;
|
|
|
|
new->cache_fblst = NULL;
|
2012-11-19 09:46:07 +08:00
|
|
|
new->bounding_shaped = false;
|
|
|
|
new->rounded_corners = false;
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
|
2011-11-04 16:41:56 +08:00
|
|
|
new->border_size = None;
|
2012-10-21 20:44:24 +08:00
|
|
|
new->reg_ignore = None;
|
2011-11-04 14:33:23 +08:00
|
|
|
new->extents = None;
|
2012-11-19 09:46:07 +08:00
|
|
|
new->shadow = false;
|
2012-09-17 22:15:04 +08:00
|
|
|
new->shadow_opacity = 0.0;
|
|
|
|
new->shadow_pict = None;
|
2012-09-29 13:15:09 +08:00
|
|
|
new->shadow_alpha_pict = None;
|
2011-11-04 14:33:23 +08:00
|
|
|
new->shadow_dx = 0;
|
|
|
|
new->shadow_dy = 0;
|
|
|
|
new->shadow_width = 0;
|
|
|
|
new->shadow_height = 0;
|
2012-09-19 20:49:16 +08:00
|
|
|
new->opacity = 0;
|
|
|
|
new->opacity_tgt = 0;
|
2012-09-11 22:22:58 +08:00
|
|
|
new->opacity_prop = OPAQUE;
|
2012-10-03 21:13:34 +08:00
|
|
|
new->opacity_prop_client = OPAQUE;
|
2012-11-19 09:46:07 +08:00
|
|
|
new->fade = false;
|
2012-09-19 20:49:16 +08:00
|
|
|
new->fade_callback = NULL;
|
2012-09-17 12:31:01 +08:00
|
|
|
new->alpha_pict = None;
|
|
|
|
new->frame_opacity = 1.0;
|
|
|
|
new->frame_alpha_pict = None;
|
2012-11-19 09:46:07 +08:00
|
|
|
new->dim = false;
|
|
|
|
new->focused = false;
|
|
|
|
new->destroyed = false;
|
|
|
|
new->need_configure = false;
|
2012-01-15 19:02:24 +08:00
|
|
|
new->window_type = WINTYPE_UNKNOWN;
|
2012-10-31 08:54:09 +08:00
|
|
|
new->mode = WINDOW_TRANS;
|
2012-11-09 11:35:40 +08:00
|
|
|
new->attr_shadow = -1;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-10-21 20:44:24 +08:00
|
|
|
new->prev_trans = NULL;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2011-11-06 11:33:50 +08:00
|
|
|
new->left_width = 0;
|
|
|
|
new->right_width = 0;
|
2011-11-06 10:39:58 +08:00
|
|
|
new->top_width = 0;
|
2011-11-06 11:33:50 +08:00
|
|
|
new->bottom_width = 0;
|
2011-11-07 05:52:39 +08:00
|
|
|
|
2012-02-01 06:10:30 +08:00
|
|
|
new->client_win = 0;
|
2011-11-07 05:52:39 +08:00
|
|
|
|
2012-09-17 22:15:04 +08:00
|
|
|
new->flags = 0;
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
calc_win_size(ps, new);
|
2012-09-17 22:15:04 +08:00
|
|
|
|
2011-11-07 05:52:39 +08:00
|
|
|
new->next = *p;
|
|
|
|
*p = new;
|
2011-11-06 10:39:58 +08:00
|
|
|
|
2011-11-04 16:41:56 +08:00
|
|
|
if (new->a.map_state == IsViewable) {
|
2012-11-19 09:46:07 +08:00
|
|
|
map_win(ps, id, override_redirect);
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
2003-11-24 07:20:42 +08:00
|
|
|
}
|
|
|
|
|
2012-02-27 12:00:12 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
restack_win(session_t *ps, win *w, Window new_above) {
|
2011-11-04 16:41:56 +08:00
|
|
|
Window old_above;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
update_reg_ignore_expire(ps, w);
|
2012-11-09 21:44:02 +08:00
|
|
|
|
2011-11-04 16:41:56 +08:00
|
|
|
if (w->next) {
|
2011-11-04 14:33:23 +08:00
|
|
|
old_above = w->next->id;
|
2011-11-04 16:41:56 +08:00
|
|
|
} else {
|
2011-11-04 14:33:23 +08:00
|
|
|
old_above = None;
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
if (old_above != new_above) {
|
|
|
|
win **prev;
|
|
|
|
|
|
|
|
/* unhook */
|
2012-11-19 09:46:07 +08:00
|
|
|
for (prev = &ps->list; *prev; prev = &(*prev)->next) {
|
2011-11-04 16:41:56 +08:00
|
|
|
if ((*prev) == w) break;
|
|
|
|
}
|
2011-11-05 20:00:39 +08:00
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
*prev = w->next;
|
|
|
|
|
|
|
|
/* rehook */
|
2012-11-19 09:46:07 +08:00
|
|
|
for (prev = &ps->list; *prev; prev = &(*prev)->next) {
|
2011-11-04 14:33:23 +08:00
|
|
|
if ((*prev)->id == new_above && !(*prev)->destroyed)
|
|
|
|
break;
|
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
w->next = *prev;
|
|
|
|
*prev = w;
|
2012-09-11 21:33:03 +08:00
|
|
|
|
2012-09-12 09:08:15 +08:00
|
|
|
#ifdef DEBUG_RESTACK
|
2012-09-11 21:33:03 +08:00
|
|
|
{
|
|
|
|
const char *desc;
|
2012-11-14 21:34:51 +08:00
|
|
|
char *window_name = NULL;
|
|
|
|
bool to_free;
|
2012-11-19 09:46:07 +08:00
|
|
|
win* c = ps->list;
|
2012-09-13 13:39:43 +08:00
|
|
|
|
2012-09-13 13:58:05 +08:00
|
|
|
printf("restack_win(%#010lx, %#010lx): "
|
|
|
|
"Window stack modified. Current stack:\n", w->id, new_above);
|
|
|
|
|
2012-09-11 21:33:03 +08:00
|
|
|
for (; c; c = c->next) {
|
|
|
|
window_name = "(Failed to get title)";
|
2012-09-13 13:58:05 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
to_free = ev_window_name(ps, c->id, &window_name);
|
2012-09-13 13:58:05 +08:00
|
|
|
|
2012-09-11 21:33:03 +08:00
|
|
|
desc = "";
|
2012-09-13 13:58:05 +08:00
|
|
|
if (c->destroyed) desc = "(D) ";
|
2012-09-11 21:33:03 +08:00
|
|
|
printf("%#010lx \"%s\" %s-> ", c->id, window_name, desc);
|
2012-09-13 13:58:05 +08:00
|
|
|
|
2012-09-11 21:33:03 +08:00
|
|
|
if (to_free) {
|
|
|
|
XFree(window_name);
|
|
|
|
window_name = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fputs("\n", stdout);
|
|
|
|
}
|
|
|
|
#endif
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2003-11-09 15:08:23 +08:00
|
|
|
}
|
|
|
|
|
2003-11-20 00:12:15 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
configure_win(session_t *ps, XConfigureEvent *ce) {
|
|
|
|
if (ce->window == ps->root) {
|
|
|
|
if (ps->tgt_buffer) {
|
|
|
|
XRenderFreePicture(ps->dpy, ps->tgt_buffer);
|
|
|
|
ps->tgt_buffer = None;
|
2012-10-30 18:11:30 +08:00
|
|
|
}
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->root_width = ce->width;
|
|
|
|
ps->root_height = ce->height;
|
2012-10-30 18:11:30 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
rebuild_screen_reg(ps);
|
2012-11-03 10:30:32 +08:00
|
|
|
|
2012-10-30 18:11:30 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
win *w = find_win(ps, ce->window);
|
2011-11-04 16:41:56 +08:00
|
|
|
XserverRegion damage = None;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-10-30 18:11:30 +08:00
|
|
|
if (!w)
|
2011-11-04 14:33:23 +08:00
|
|
|
return;
|
|
|
|
|
|
|
|
if (w->a.map_state == IsUnmapped) {
|
|
|
|
/* save the configure event for when the window maps */
|
2012-11-19 09:46:07 +08:00
|
|
|
w->need_configure = true;
|
2011-11-04 14:33:23 +08:00
|
|
|
w->queue_configure = *ce;
|
2012-11-19 09:46:07 +08:00
|
|
|
restack_win(ps, w, ce->above);
|
2011-11-04 14:33:23 +08:00
|
|
|
} else {
|
2012-09-13 13:58:05 +08:00
|
|
|
if (!(w->need_configure)) {
|
2012-11-19 09:46:07 +08:00
|
|
|
restack_win(ps, w, ce->above);
|
2012-09-13 13:58:05 +08:00
|
|
|
}
|
|
|
|
|
2012-10-31 08:54:09 +08:00
|
|
|
// Windows restack (including window restacks happened when this
|
|
|
|
// window is not mapped) could mess up all reg_ignore
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->reg_ignore_expire = true;
|
2012-10-21 20:44:24 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
w->need_configure = false;
|
2008-02-15 13:55:17 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
damage = XFixesCreateRegion(ps->dpy, 0, 0);
|
2012-10-31 08:54:09 +08:00
|
|
|
if (w->extents != None) {
|
2012-11-19 09:46:07 +08:00
|
|
|
XFixesCopyRegion(ps->dpy, damage, w->extents);
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2008-02-15 13:55:17 +08:00
|
|
|
|
2012-11-01 10:43:15 +08:00
|
|
|
// If window geometry did not change, don't free extents here
|
|
|
|
if (w->a.x != ce->x || w->a.y != ce->y
|
|
|
|
|| w->a.width != ce->width || w->a.height != ce->height) {
|
2012-11-19 09:46:07 +08:00
|
|
|
free_region(ps, &w->extents);
|
|
|
|
free_region(ps, &w->border_size);
|
2012-11-01 10:43:15 +08:00
|
|
|
}
|
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
w->a.x = ce->x;
|
|
|
|
w->a.y = ce->y;
|
2011-11-05 20:00:39 +08:00
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
if (w->a.width != ce->width || w->a.height != ce->height) {
|
2012-11-19 09:46:07 +08:00
|
|
|
free_pixmap(ps, &w->pixmap);
|
|
|
|
free_picture(ps, &w->picture);
|
2004-07-08 15:07:26 +08:00
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-09-17 22:15:04 +08:00
|
|
|
if (w->a.width != ce->width || w->a.height != ce->height
|
|
|
|
|| w->a.border_width != ce->border_width) {
|
|
|
|
w->a.width = ce->width;
|
|
|
|
w->a.height = ce->height;
|
|
|
|
w->a.border_width = ce->border_width;
|
2012-11-19 09:46:07 +08:00
|
|
|
calc_win_size(ps, w);
|
2012-11-01 10:43:15 +08:00
|
|
|
|
|
|
|
// Rounded corner detection is affected by window size
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->shape_exists && ps->o.shadow_ignore_shaped
|
|
|
|
&& ps->o.detect_rounded_corners && w->bounding_shaped)
|
|
|
|
win_update_shape(ps, w);
|
2012-09-17 22:15:04 +08:00
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-11-09 21:44:02 +08:00
|
|
|
if (damage) {
|
2012-11-19 09:46:07 +08:00
|
|
|
XserverRegion extents = win_extents(ps, w);
|
|
|
|
XFixesUnionRegion(ps->dpy, damage, damage, extents);
|
|
|
|
XFixesDestroyRegion(ps->dpy, extents);
|
|
|
|
add_damage(ps, damage);
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
|
|
|
}
|
2008-02-20 14:20:40 +08:00
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
w->a.override_redirect = ce->override_redirect;
|
2003-11-09 15:08:23 +08:00
|
|
|
}
|
|
|
|
|
2003-11-24 07:20:42 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
circulate_win(session_t *ps, XCirculateEvent *ce) {
|
|
|
|
win *w = find_win(ps, ce->window);
|
2011-11-04 16:41:56 +08:00
|
|
|
Window new_above;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2011-11-04 16:41:56 +08:00
|
|
|
if (!w) return;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2011-11-04 16:41:56 +08:00
|
|
|
if (ce->place == PlaceOnTop) {
|
2012-11-19 09:46:07 +08:00
|
|
|
new_above = ps->list->id;
|
2011-11-04 16:41:56 +08:00
|
|
|
} else {
|
2011-11-04 14:33:23 +08:00
|
|
|
new_above = None;
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
restack_win(ps, w, new_above);
|
2003-11-24 07:20:42 +08:00
|
|
|
}
|
|
|
|
|
2003-11-20 00:12:15 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
finish_destroy_win(session_t *ps, Window id) {
|
2011-11-04 16:41:56 +08:00
|
|
|
win **prev, *w;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
for (prev = &ps->list; (w = *prev); prev = &w->next) {
|
2011-11-04 14:33:23 +08:00
|
|
|
if (w->id == id && w->destroyed) {
|
2012-11-19 09:46:07 +08:00
|
|
|
finish_unmap_win(ps, w);
|
2011-11-04 14:33:23 +08:00
|
|
|
*prev = w->next;
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-11-04 18:11:08 +08:00
|
|
|
// Clear active_win if it's pointing to the destroyed window
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->active_win)
|
|
|
|
ps->active_win = NULL;
|
2012-11-04 18:11:08 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
free_win_res(ps, w);
|
2011-11-04 14:33:23 +08:00
|
|
|
|
|
|
|
free(w);
|
|
|
|
break;
|
|
|
|
}
|
2011-11-05 05:18:56 +08:00
|
|
|
}
|
2003-11-09 15:08:23 +08:00
|
|
|
}
|
|
|
|
|
2004-07-08 15:07:26 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
destroy_callback(session_t *ps, win *w) {
|
|
|
|
finish_destroy_win(ps, w->id);
|
2004-07-08 15:07:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
destroy_win(session_t *ps, Window id) {
|
|
|
|
win *w = find_win(ps, id);
|
2008-02-15 13:55:17 +08:00
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
if (w) {
|
2012-11-19 09:46:07 +08:00
|
|
|
w->destroyed = true;
|
2008-02-19 05:44:41 +08:00
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
// Fading out the window
|
|
|
|
w->opacity_tgt = 0;
|
2012-11-19 09:46:07 +08:00
|
|
|
set_fade_callback(ps, w, destroy_callback, false);
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2004-07-08 15:07:26 +08:00
|
|
|
}
|
|
|
|
|
2012-10-24 10:09:59 +08:00
|
|
|
static inline void
|
2012-11-19 09:46:07 +08:00
|
|
|
root_damaged(session_t *ps) {
|
|
|
|
if (ps->root_tile) {
|
|
|
|
XClearArea(ps->dpy, ps->root, 0, 0, 0, 0, true);
|
|
|
|
// if (ps->root_picture != ps->root_tile) {
|
|
|
|
XRenderFreePicture(ps->dpy, ps->root_tile);
|
|
|
|
ps->root_tile = None;
|
2012-10-24 10:09:59 +08:00
|
|
|
/* }
|
|
|
|
if (root_damage) {
|
2012-11-19 09:46:07 +08:00
|
|
|
XserverRegion parts = XFixesCreateRegion(ps->dpy, 0, 0);
|
|
|
|
XDamageSubtract(ps->dpy, root_damage, None, parts);
|
|
|
|
add_damage(ps, parts);
|
2012-10-24 10:09:59 +08:00
|
|
|
} */
|
|
|
|
}
|
|
|
|
// Mark screen damaged if we are painting on overlay
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.paint_on_overlay)
|
|
|
|
add_damage(ps, get_screen_region(ps));
|
2012-10-24 10:09:59 +08:00
|
|
|
}
|
|
|
|
|
2003-11-20 00:12:15 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
damage_win(session_t *ps, XDamageNotifyEvent *de) {
|
2012-10-24 10:09:59 +08:00
|
|
|
/*
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->root == de->drawable) {
|
2012-10-24 10:09:59 +08:00
|
|
|
root_damaged();
|
|
|
|
return;
|
|
|
|
} */
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
win *w = find_win(ps, de->drawable);
|
2011-11-04 16:41:56 +08:00
|
|
|
|
|
|
|
if (!w) return;
|
2004-08-13 16:25:51 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
repair_win(ps, w);
|
2003-11-09 15:08:23 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* Xlib error handler function.
|
|
|
|
*/
|
2003-11-20 00:12:15 +08:00
|
|
|
static int
|
2011-11-04 14:33:23 +08:00
|
|
|
error(Display *dpy, XErrorEvent *ev) {
|
2012-11-19 09:46:07 +08:00
|
|
|
session_t * const ps = ps_g;
|
|
|
|
|
2011-11-04 16:41:56 +08:00
|
|
|
int o;
|
2011-11-05 05:18:56 +08:00
|
|
|
const char *name = "Unknown";
|
2003-11-20 00:12:15 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (should_ignore(ps, ev->serial)) {
|
2003-11-20 00:12:15 +08:00
|
|
|
return 0;
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ev->request_code == ps->composite_opcode
|
2011-11-04 17:18:10 +08:00
|
|
|
&& ev->minor_code == X_CompositeRedirectSubwindows) {
|
2011-11-04 14:33:23 +08:00
|
|
|
fprintf(stderr, "Another composite manager is already running\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2012-11-03 05:51:40 +08:00
|
|
|
#define CASESTRRET2(s) case s: name = #s; break
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
o = ev->error_code - ps->xfixes_error;
|
2011-11-04 14:33:23 +08:00
|
|
|
switch (o) {
|
2012-11-03 05:51:40 +08:00
|
|
|
CASESTRRET2(BadRegion);
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
o = ev->error_code - ps->damage_error;
|
2011-11-04 14:33:23 +08:00
|
|
|
switch (o) {
|
2012-11-03 05:51:40 +08:00
|
|
|
CASESTRRET2(BadDamage);
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
o = ev->error_code - ps->render_error;
|
2011-11-04 14:33:23 +08:00
|
|
|
switch (o) {
|
2012-11-03 05:51:40 +08:00
|
|
|
CASESTRRET2(BadPictFormat);
|
|
|
|
CASESTRRET2(BadPicture);
|
|
|
|
CASESTRRET2(BadPictOp);
|
|
|
|
CASESTRRET2(BadGlyphSet);
|
|
|
|
CASESTRRET2(BadGlyph);
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
|
|
|
|
2012-09-11 21:33:03 +08:00
|
|
|
switch (ev->error_code) {
|
2012-11-03 05:51:40 +08:00
|
|
|
CASESTRRET2(BadAccess);
|
|
|
|
CASESTRRET2(BadAlloc);
|
|
|
|
CASESTRRET2(BadAtom);
|
|
|
|
CASESTRRET2(BadColor);
|
|
|
|
CASESTRRET2(BadCursor);
|
|
|
|
CASESTRRET2(BadDrawable);
|
|
|
|
CASESTRRET2(BadFont);
|
|
|
|
CASESTRRET2(BadGC);
|
|
|
|
CASESTRRET2(BadIDChoice);
|
|
|
|
CASESTRRET2(BadImplementation);
|
|
|
|
CASESTRRET2(BadLength);
|
|
|
|
CASESTRRET2(BadMatch);
|
|
|
|
CASESTRRET2(BadName);
|
|
|
|
CASESTRRET2(BadPixmap);
|
|
|
|
CASESTRRET2(BadRequest);
|
|
|
|
CASESTRRET2(BadValue);
|
|
|
|
CASESTRRET2(BadWindow);
|
|
|
|
}
|
|
|
|
|
|
|
|
#undef CASESTRRET2
|
2012-09-11 21:33:03 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
print_timestamp(ps);
|
2011-11-05 02:30:53 +08:00
|
|
|
printf("error %d (%s) request %d minor %d serial %lu\n",
|
2012-02-27 12:00:12 +08:00
|
|
|
ev->error_code, name, ev->request_code,
|
|
|
|
ev->minor_code, ev->serial);
|
2011-11-04 14:33:23 +08:00
|
|
|
|
|
|
|
return 0;
|
2003-11-09 15:08:23 +08:00
|
|
|
}
|
|
|
|
|
2003-11-20 00:12:15 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
expose_root(session_t *ps, XRectangle *rects, int nrects) {
|
|
|
|
XserverRegion region = XFixesCreateRegion(ps->dpy, rects, nrects);
|
|
|
|
add_damage(ps, region);
|
2003-11-09 15:08:23 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* Get the value of a text property of a window.
|
|
|
|
*/
|
|
|
|
static bool
|
|
|
|
wid_get_text_prop(session_t *ps, Window wid, Atom prop,
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
char ***pstrlst, int *pnstr) {
|
|
|
|
XTextProperty text_prop;
|
2012-09-11 21:33:03 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!(XGetTextProperty(ps->dpy, wid, &text_prop, prop) && text_prop.value))
|
|
|
|
return false;
|
2012-09-13 13:58:05 +08:00
|
|
|
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
if (Success !=
|
2012-11-19 09:46:07 +08:00
|
|
|
XmbTextPropertyToTextList(ps->dpy, &text_prop, pstrlst, pnstr)
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
|| !*pnstr) {
|
|
|
|
*pnstr = 0;
|
|
|
|
if (*pstrlst)
|
|
|
|
XFreeStringList(*pstrlst);
|
2012-11-19 09:46:07 +08:00
|
|
|
return false;
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
}
|
2012-09-13 13:58:05 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
return true;
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
}
|
2012-09-13 13:58:05 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* Get the name of a window from window ID.
|
|
|
|
*/
|
|
|
|
static bool
|
|
|
|
wid_get_name(session_t *ps, Window wid, char **name) {
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
XTextProperty text_prop;
|
|
|
|
char **strlst = NULL;
|
|
|
|
int nstr = 0;
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
// set_ignore_next(ps);
|
|
|
|
if (!(XGetTextProperty(ps->dpy, wid, &text_prop, ps->atom_name_ewmh)
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
&& text_prop.value)) {
|
2012-11-19 09:46:07 +08:00
|
|
|
// set_ignore_next(ps);
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
#ifdef DEBUG_WINDATA
|
|
|
|
printf("wid_get_name(%#010lx): _NET_WM_NAME unset, falling back to WM_NAME.\n", wid);
|
|
|
|
#endif
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!(XGetWMName(ps->dpy, wid, &text_prop) && text_prop.value)) {
|
|
|
|
return false;
|
2012-09-13 13:58:05 +08:00
|
|
|
}
|
2012-09-11 21:33:03 +08:00
|
|
|
}
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
if (Success !=
|
2012-11-19 09:46:07 +08:00
|
|
|
XmbTextPropertyToTextList(ps->dpy, &text_prop, &strlst, &nstr)
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
|| !nstr || !strlst) {
|
|
|
|
if (strlst)
|
|
|
|
XFreeStringList(strlst);
|
2012-11-19 09:46:07 +08:00
|
|
|
return false;
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
}
|
|
|
|
*name = mstrcpy(strlst[0]);
|
|
|
|
|
|
|
|
XFreeStringList(strlst);
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
return true;
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* Retrieve the name of a window and update its <code>win</code>
|
|
|
|
* structure.
|
|
|
|
*/
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
static int
|
2012-11-19 09:46:07 +08:00
|
|
|
win_get_name(session_t *ps, win *w) {
|
|
|
|
bool ret;
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
char *name_old = w->name;
|
|
|
|
|
|
|
|
// Can't do anything if there's no client window
|
|
|
|
if (!w->client_win)
|
2012-11-19 09:46:07 +08:00
|
|
|
return false;
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
|
|
|
|
// Get the name
|
2012-11-19 09:46:07 +08:00
|
|
|
ret = wid_get_name(ps, w->client_win, &w->name);
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
|
|
|
|
// Return -1 if wid_get_name() failed, 0 if name didn't change, 1 if
|
|
|
|
// it changes
|
|
|
|
if (!ret)
|
|
|
|
ret = -1;
|
|
|
|
else if (name_old && !strcmp(w->name, name_old))
|
|
|
|
ret = 0;
|
|
|
|
else
|
|
|
|
ret = 1;
|
|
|
|
|
|
|
|
// Keep the old name if there's no new one
|
|
|
|
if (w->name != name_old)
|
|
|
|
free(name_old);
|
|
|
|
|
|
|
|
#ifdef DEBUG_WINDATA
|
|
|
|
printf("win_get_name(%#010lx): client = %#010lx, name = \"%s\", "
|
|
|
|
"ret = %d\n", w->id, w->client_win, w->name, ret);
|
|
|
|
#endif
|
2012-09-13 13:58:05 +08:00
|
|
|
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
return ret;
|
2012-09-11 21:33:03 +08:00
|
|
|
}
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* Retrieve the <code>WM_CLASS</code> of a window and update its
|
|
|
|
* <code>win</code> structure.
|
|
|
|
*/
|
|
|
|
static bool
|
|
|
|
win_get_class(session_t *ps, win *w) {
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
char **strlst = NULL;
|
|
|
|
int nstr = 0;
|
|
|
|
|
|
|
|
// Can't do anything if there's no client window
|
|
|
|
if (!w->client_win)
|
2012-11-19 09:46:07 +08:00
|
|
|
return false;
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
|
|
|
|
// Free and reset old strings
|
|
|
|
free(w->class_instance);
|
|
|
|
free(w->class_general);
|
|
|
|
w->class_instance = NULL;
|
|
|
|
w->class_general = NULL;
|
|
|
|
|
|
|
|
// Retrieve the property string list
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!wid_get_text_prop(ps, w->client_win, ps->atom_class, &strlst, &nstr))
|
|
|
|
return false;
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
|
|
|
|
// Copy the strings if successful
|
|
|
|
w->class_instance = mstrcpy(strlst[0]);
|
|
|
|
|
|
|
|
if (nstr > 1)
|
|
|
|
w->class_general = mstrcpy(strlst[1]);
|
|
|
|
|
|
|
|
XFreeStringList(strlst);
|
|
|
|
|
|
|
|
#ifdef DEBUG_WINDATA
|
|
|
|
printf("win_get_class(%#010lx): client = %#010lx, "
|
|
|
|
"instance = \"%s\", general = \"%s\"\n",
|
|
|
|
w->id, w->client_win, w->class_instance, w->class_general);
|
2012-09-12 09:08:15 +08:00
|
|
|
#endif
|
2012-09-11 21:33:03 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
return true;
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
}
|
|
|
|
|
2012-09-12 09:08:15 +08:00
|
|
|
#ifdef DEBUG_EVENTS
|
2003-11-24 07:20:42 +08:00
|
|
|
static int
|
2011-11-04 14:33:23 +08:00
|
|
|
ev_serial(XEvent *ev) {
|
2012-09-11 21:33:03 +08:00
|
|
|
if ((ev->type & 0x7f) != KeymapNotify) {
|
2011-11-04 14:33:23 +08:00
|
|
|
return ev->xany.serial;
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
2011-11-04 14:33:23 +08:00
|
|
|
return NextRequest(ev->xany.display);
|
2003-11-24 07:20:42 +08:00
|
|
|
}
|
|
|
|
|
2012-11-03 05:51:40 +08:00
|
|
|
static const char *
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_name(session_t *ps, XEvent *ev) {
|
2011-11-04 17:18:10 +08:00
|
|
|
static char buf[128];
|
2011-11-04 14:33:23 +08:00
|
|
|
switch (ev->type & 0x7f) {
|
2012-11-03 05:51:40 +08:00
|
|
|
CASESTRRET(FocusIn);
|
|
|
|
CASESTRRET(FocusOut);
|
|
|
|
CASESTRRET(CreateNotify);
|
|
|
|
CASESTRRET(ConfigureNotify);
|
|
|
|
CASESTRRET(DestroyNotify);
|
|
|
|
CASESTRRET(MapNotify);
|
|
|
|
CASESTRRET(UnmapNotify);
|
|
|
|
CASESTRRET(ReparentNotify);
|
|
|
|
CASESTRRET(CirculateNotify);
|
|
|
|
CASESTRRET(Expose);
|
|
|
|
CASESTRRET(PropertyNotify);
|
|
|
|
CASESTRRET(ClientMessage);
|
2011-11-04 16:41:56 +08:00
|
|
|
default:
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ev->type == ps->damage_event + XDamageNotify) {
|
2011-11-04 16:41:56 +08:00
|
|
|
return "Damage";
|
|
|
|
}
|
2012-09-13 13:58:05 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->shape_exists && ev->type == ps->shape_event) {
|
2012-09-11 21:33:03 +08:00
|
|
|
return "ShapeNotify";
|
2012-09-13 13:58:05 +08:00
|
|
|
}
|
|
|
|
|
2011-11-04 16:41:56 +08:00
|
|
|
sprintf(buf, "Event %d", ev->type);
|
2012-09-13 13:58:05 +08:00
|
|
|
|
2011-11-04 16:41:56 +08:00
|
|
|
return buf;
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2003-11-24 07:20:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static Window
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_window(session_t *ps, XEvent *ev) {
|
2011-11-04 14:33:23 +08:00
|
|
|
switch (ev->type) {
|
2012-09-11 21:33:03 +08:00
|
|
|
case FocusIn:
|
|
|
|
case FocusOut:
|
|
|
|
return ev->xfocus.window;
|
|
|
|
case CreateNotify:
|
|
|
|
return ev->xcreatewindow.window;
|
|
|
|
case ConfigureNotify:
|
|
|
|
return ev->xconfigure.window;
|
2012-09-19 20:49:16 +08:00
|
|
|
case DestroyNotify:
|
|
|
|
return ev->xdestroywindow.window;
|
2011-11-04 16:41:56 +08:00
|
|
|
case MapNotify:
|
|
|
|
return ev->xmap.window;
|
|
|
|
case UnmapNotify:
|
|
|
|
return ev->xunmap.window;
|
|
|
|
case ReparentNotify:
|
|
|
|
return ev->xreparent.window;
|
|
|
|
case CirculateNotify:
|
|
|
|
return ev->xcirculate.window;
|
2012-09-11 21:33:03 +08:00
|
|
|
case Expose:
|
|
|
|
return ev->xexpose.window;
|
|
|
|
case PropertyNotify:
|
|
|
|
return ev->xproperty.window;
|
2012-09-18 11:28:09 +08:00
|
|
|
case ClientMessage:
|
|
|
|
return ev->xclient.window;
|
2011-11-04 16:41:56 +08:00
|
|
|
default:
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ev->type == ps->damage_event + XDamageNotify) {
|
2011-11-04 17:18:10 +08:00
|
|
|
return ((XDamageNotifyEvent *)ev)->drawable;
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
2012-09-13 13:58:05 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->shape_exists && ev->type == ps->shape_event) {
|
2012-09-11 21:33:03 +08:00
|
|
|
return ((XShapeEvent *) ev)->window;
|
2012-09-13 13:58:05 +08:00
|
|
|
}
|
|
|
|
|
2011-11-04 16:41:56 +08:00
|
|
|
return 0;
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2003-11-24 07:20:42 +08:00
|
|
|
}
|
2012-11-03 05:51:40 +08:00
|
|
|
|
|
|
|
static inline const char *
|
|
|
|
ev_focus_mode_name(XFocusChangeEvent* ev) {
|
|
|
|
switch (ev->mode) {
|
|
|
|
CASESTRRET(NotifyNormal);
|
|
|
|
CASESTRRET(NotifyWhileGrabbed);
|
|
|
|
CASESTRRET(NotifyGrab);
|
|
|
|
CASESTRRET(NotifyUngrab);
|
|
|
|
}
|
|
|
|
|
|
|
|
return "Unknown";
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline const char *
|
|
|
|
ev_focus_detail_name(XFocusChangeEvent* ev) {
|
|
|
|
switch (ev->detail) {
|
|
|
|
CASESTRRET(NotifyAncestor);
|
|
|
|
CASESTRRET(NotifyVirtual);
|
|
|
|
CASESTRRET(NotifyInferior);
|
|
|
|
CASESTRRET(NotifyNonlinear);
|
|
|
|
CASESTRRET(NotifyNonlinearVirtual);
|
|
|
|
CASESTRRET(NotifyPointer);
|
|
|
|
CASESTRRET(NotifyPointerRoot);
|
|
|
|
CASESTRRET(NotifyDetailNone);
|
|
|
|
}
|
|
|
|
|
|
|
|
return "Unknown";
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
ev_focus_report(XFocusChangeEvent* ev) {
|
|
|
|
printf(" { mode: %s, detail: %s }\n", ev_focus_mode_name(ev),
|
|
|
|
ev_focus_detail_name(ev));
|
|
|
|
}
|
|
|
|
|
2007-03-12 20:37:32 +08:00
|
|
|
#endif
|
2003-11-24 07:20:42 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
// === Events ===
|
2012-02-09 17:37:46 +08:00
|
|
|
|
2012-11-03 22:02:07 +08:00
|
|
|
/**
|
|
|
|
* Determine whether we should respond to a <code>FocusIn/Out</code>
|
|
|
|
* event.
|
|
|
|
*/
|
2012-11-03 05:51:40 +08:00
|
|
|
inline static bool
|
|
|
|
ev_focus_accept(XFocusChangeEvent *ev) {
|
2012-11-03 22:02:07 +08:00
|
|
|
return ev->detail == NotifyNonlinear
|
|
|
|
|| ev->detail == NotifyNonlinearVirtual;
|
2012-11-03 05:51:40 +08:00
|
|
|
}
|
|
|
|
|
2012-02-09 17:37:46 +08:00
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_focus_in(session_t *ps, XFocusChangeEvent *ev) {
|
2012-11-03 05:51:40 +08:00
|
|
|
#ifdef DEBUG_EVENTS
|
|
|
|
ev_focus_report(ev);
|
|
|
|
#endif
|
|
|
|
|
2012-11-03 22:02:07 +08:00
|
|
|
if (!ev_focus_accept(ev))
|
|
|
|
return;
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
win *w = find_win(ps, ev->window);
|
2012-09-11 22:22:58 +08:00
|
|
|
|
2012-09-13 22:30:18 +08:00
|
|
|
// To deal with events sent from windows just destroyed
|
2012-09-13 23:28:27 +08:00
|
|
|
if (!w) return;
|
2012-09-13 22:30:18 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
set_focused(ps, w, true);
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_focus_out(session_t *ps, XFocusChangeEvent *ev) {
|
2012-11-03 05:51:40 +08:00
|
|
|
#ifdef DEBUG_EVENTS
|
|
|
|
ev_focus_report(ev);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (!ev_focus_accept(ev))
|
2012-02-09 17:37:46 +08:00
|
|
|
return;
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
win *w = find_win(ps, ev->window);
|
2012-09-11 22:22:58 +08:00
|
|
|
|
2012-09-13 22:30:18 +08:00
|
|
|
// To deal with events sent from windows just destroyed
|
2012-09-13 23:28:27 +08:00
|
|
|
if (!w) return;
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
set_focused(ps, w, false);
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_create_notify(session_t *ps, XCreateWindowEvent *ev) {
|
|
|
|
assert(ev->parent == ps->root);
|
|
|
|
add_win(ps, ev->window, 0, ev->override_redirect);
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_configure_notify(session_t *ps, XConfigureEvent *ev) {
|
2012-09-12 09:08:15 +08:00
|
|
|
#ifdef DEBUG_EVENTS
|
2012-11-03 05:51:40 +08:00
|
|
|
printf(" { send_event: %d, "
|
2012-09-13 13:58:05 +08:00
|
|
|
" above: %#010lx, "
|
|
|
|
" override_redirect: %d }\n",
|
|
|
|
ev->send_event, ev->above, ev->override_redirect);
|
2012-09-11 21:33:03 +08:00
|
|
|
#endif
|
2012-11-19 09:46:07 +08:00
|
|
|
configure_win(ps, ev);
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_destroy_notify(session_t *ps, XDestroyWindowEvent *ev) {
|
|
|
|
destroy_win(ps, ev->window);
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_map_notify(session_t *ps, XMapEvent *ev) {
|
|
|
|
map_win(ps, ev->window, ev->override_redirect);
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_unmap_notify(session_t *ps, XUnmapEvent *ev) {
|
|
|
|
unmap_win(ps, ev->window);
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_reparent_notify(session_t *ps, XReparentEvent *ev) {
|
|
|
|
if (ev->parent == ps->root) {
|
|
|
|
add_win(ps, ev->window, 0, ev->override_redirect);
|
2012-02-09 17:37:46 +08:00
|
|
|
} else {
|
2012-11-19 09:46:07 +08:00
|
|
|
destroy_win(ps, ev->window);
|
2012-09-13 22:30:18 +08:00
|
|
|
// Reset event mask in case something wrong happens
|
2012-11-19 09:46:07 +08:00
|
|
|
XSelectInput(ps->dpy, ev->window,
|
|
|
|
determine_evmask(ps, ev->window, WIN_EVMODE_UNKNOWN));
|
2012-09-14 11:51:46 +08:00
|
|
|
/*
|
|
|
|
// Check if the window is a client window of another
|
2012-11-19 09:46:07 +08:00
|
|
|
win *w_top = find_toplevel2(ps, ev->window);
|
2012-09-14 11:51:46 +08:00
|
|
|
if (w_top && !(w_top->client_win)) {
|
2012-11-19 09:46:07 +08:00
|
|
|
mark_client_win(ps, w_top, ev->window);
|
2012-09-14 11:51:46 +08:00
|
|
|
} */
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_circulate_notify(session_t *ps, XCirculateEvent *ev) {
|
|
|
|
circulate_win(ps, ev);
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_expose(session_t *ps, XExposeEvent *ev) {
|
|
|
|
if (ev->window == ps->root || (ps->overlay && ev->window == ps->overlay)) {
|
2012-02-09 17:37:46 +08:00
|
|
|
int more = ev->count + 1;
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->n_expose == ps->size_expose) {
|
|
|
|
if (ps->expose_rects) {
|
|
|
|
ps->expose_rects = realloc(ps->expose_rects,
|
|
|
|
(ps->size_expose + more) * sizeof(XRectangle));
|
|
|
|
ps->size_expose += more;
|
2012-02-09 17:37:46 +08:00
|
|
|
} else {
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->expose_rects = malloc(more * sizeof(XRectangle));
|
|
|
|
ps->size_expose = more;
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->expose_rects[ps->n_expose].x = ev->x;
|
|
|
|
ps->expose_rects[ps->n_expose].y = ev->y;
|
|
|
|
ps->expose_rects[ps->n_expose].width = ev->width;
|
|
|
|
ps->expose_rects[ps->n_expose].height = ev->height;
|
|
|
|
ps->n_expose++;
|
2012-02-09 17:37:46 +08:00
|
|
|
|
|
|
|
if (ev->count == 0) {
|
2012-11-19 09:46:07 +08:00
|
|
|
expose_root(ps, ps->expose_rects, ps->n_expose);
|
|
|
|
ps->n_expose = 0;
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-04 18:11:08 +08:00
|
|
|
/**
|
|
|
|
* Update current active window based on EWMH _NET_ACTIVE_WIN.
|
|
|
|
*
|
|
|
|
* Does not change anything if we fail to get the attribute or the window
|
|
|
|
* returned could not be found.
|
|
|
|
*/
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
update_ewmh_active_win(session_t *ps) {
|
2012-11-04 18:11:08 +08:00
|
|
|
// Get the attribute firstly
|
2012-11-19 09:46:07 +08:00
|
|
|
winprop_t prop = wid_get_prop(ps, ps->root, ps->atom_ewmh_active_win,
|
2012-11-04 18:11:08 +08:00
|
|
|
1L, XA_WINDOW, 32);
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!prop.nitems) {
|
|
|
|
free_winprop(&prop);
|
2012-11-04 18:11:08 +08:00
|
|
|
return;
|
|
|
|
}
|
2012-11-19 09:46:07 +08:00
|
|
|
|
2012-11-04 18:11:08 +08:00
|
|
|
// Search for the window
|
2012-11-19 09:46:07 +08:00
|
|
|
Window wid = *((long *) prop.data);
|
2012-11-04 18:11:08 +08:00
|
|
|
win *w = NULL;
|
2012-11-19 09:46:07 +08:00
|
|
|
free_winprop(&prop);
|
2012-11-04 18:11:08 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!(w = find_toplevel(ps, wid)))
|
|
|
|
if (!(w = find_win(ps, wid)))
|
|
|
|
w = find_toplevel2(ps, wid);
|
2012-11-04 18:11:08 +08:00
|
|
|
|
|
|
|
// Mark the window focused
|
|
|
|
if (w) {
|
|
|
|
if (!w->focused)
|
2012-11-19 09:46:07 +08:00
|
|
|
set_focused(ps, w, true);
|
|
|
|
if (ps->active_win && w != ps->active_win)
|
|
|
|
set_focused(ps, ps->active_win, false);
|
|
|
|
ps->active_win = w;
|
2012-11-04 18:11:08 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-09 17:37:46 +08:00
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_property_notify(session_t *ps, XPropertyEvent *ev) {
|
|
|
|
if (ps->root == ev->window) {
|
|
|
|
if (ps->o.track_focus && ps->o.use_ewmh_active_win
|
|
|
|
&& ps->atom_ewmh_active_win == ev->atom) {
|
|
|
|
update_ewmh_active_win(ps);
|
2012-11-04 18:11:08 +08:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Destroy the root "image" if the wallpaper probably changed
|
2012-11-19 09:46:07 +08:00
|
|
|
for (int p = 0; background_props_str[p]; p++) {
|
|
|
|
if (ev->atom ==
|
|
|
|
XInternAtom(ps->dpy, background_props_str[p], false)) {
|
|
|
|
root_damaged(ps);
|
2012-11-04 18:11:08 +08:00
|
|
|
break;
|
|
|
|
}
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
}
|
2012-11-04 18:11:08 +08:00
|
|
|
|
2012-10-24 10:09:59 +08:00
|
|
|
// Unconcerned about any other proprties on root window
|
|
|
|
return;
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
|
2012-10-03 21:13:34 +08:00
|
|
|
// If _NET_WM_OPACITY changes
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ev->atom == ps->atom_opacity) {
|
2012-10-03 21:13:34 +08:00
|
|
|
win *w = NULL;
|
2012-11-19 09:46:07 +08:00
|
|
|
if ((w = find_win(ps, ev->window)))
|
|
|
|
w->opacity_prop = wid_get_opacity_prop(ps, w->id, OPAQUE);
|
|
|
|
else if (ps->o.detect_client_opacity
|
|
|
|
&& (w = find_toplevel(ps, ev->window)))
|
|
|
|
w->opacity_prop_client = wid_get_opacity_prop(ps, w->client_win,
|
2012-10-03 21:13:34 +08:00
|
|
|
OPAQUE);
|
2012-02-09 17:37:46 +08:00
|
|
|
if (w) {
|
2012-11-19 09:46:07 +08:00
|
|
|
calc_opacity(ps, w, false);
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
// If frame extents property changes
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.frame_opacity && ev->atom == ps->atom_frame_extents) {
|
|
|
|
win *w = find_toplevel(ps, ev->window);
|
2012-02-09 17:37:46 +08:00
|
|
|
if (w) {
|
2012-11-19 09:46:07 +08:00
|
|
|
get_frame_extents(ps, w, ev->window);
|
2012-09-20 13:50:27 +08:00
|
|
|
// If frame extents change, the window needs repaint
|
2012-11-19 09:46:07 +08:00
|
|
|
add_damage_win(ps, w);
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
}
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
|
|
|
|
// If name changes
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.track_wdata
|
|
|
|
&& (ps->atom_name == ev->atom || ps->atom_name_ewmh == ev->atom)) {
|
|
|
|
win *w = find_toplevel(ps, ev->window);
|
|
|
|
if (w && 1 == win_get_name(ps, w))
|
|
|
|
determine_shadow(ps, w);
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// If class changes
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.track_wdata && ps->atom_class == ev->atom) {
|
|
|
|
win *w = find_toplevel(ps, ev->window);
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
if (w) {
|
2012-11-19 09:46:07 +08:00
|
|
|
win_get_class(ps, w);
|
|
|
|
determine_shadow(ps, w);
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
}
|
|
|
|
}
|
2012-11-09 11:35:40 +08:00
|
|
|
|
|
|
|
// If _COMPTON_SHADOW changes
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.respect_prop_shadow && ps->atom_compton_shadow == ev->atom) {
|
|
|
|
win *w = find_win(ps, ev->window);
|
2012-11-09 11:35:40 +08:00
|
|
|
if (w)
|
2012-11-19 09:46:07 +08:00
|
|
|
win_update_attr_shadow(ps, w);
|
2012-11-09 11:35:40 +08:00
|
|
|
}
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_damage_notify(session_t *ps, XDamageNotifyEvent *ev) {
|
|
|
|
damage_win(ps, ev);
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
|
2012-09-13 13:58:05 +08:00
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_shape_notify(session_t *ps, XShapeEvent *ev) {
|
|
|
|
win *w = find_win(ps, ev->window);
|
2012-10-31 08:54:09 +08:00
|
|
|
if (!w || IsUnmapped == w->a.map_state) return;
|
2012-09-11 21:33:03 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Empty border_size may indicated an
|
|
|
|
* unmapped/destroyed window, in which case
|
|
|
|
* seemingly BadRegion errors would be triggered
|
|
|
|
* if we attempt to rebuild border_size
|
|
|
|
*/
|
|
|
|
if (w->border_size) {
|
|
|
|
// Mark the old border_size as damaged
|
2012-11-19 09:46:07 +08:00
|
|
|
add_damage(ps, w->border_size);
|
2012-09-11 21:33:03 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
w->border_size = border_size(ps, w);
|
2012-09-11 21:33:03 +08:00
|
|
|
|
|
|
|
// Mark the new border_size as damaged
|
2012-11-19 09:46:07 +08:00
|
|
|
add_damage(ps, copy_region(ps, w->border_size));
|
2012-09-11 21:33:03 +08:00
|
|
|
}
|
2012-10-01 10:34:40 +08:00
|
|
|
|
|
|
|
// Redo bounding shape detection and rounded corner detection
|
2012-11-19 09:46:07 +08:00
|
|
|
win_update_shape(ps, w);
|
2012-11-08 19:39:13 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
update_reg_ignore_expire(ps, w);
|
2012-09-11 21:33:03 +08:00
|
|
|
}
|
|
|
|
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
/**
|
|
|
|
* Handle ScreenChangeNotify events from X RandR extension.
|
|
|
|
*/
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_screen_change_notify(session_t *ps, XRRScreenChangeNotifyEvent *ev) {
|
|
|
|
if (!ps->o.refresh_rate) {
|
|
|
|
update_refresh_rate(ps);
|
|
|
|
if (!ps->refresh_rate) {
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
fprintf(stderr, "ev_screen_change_notify(): Refresh rate detection "
|
|
|
|
"failed, software VSync disabled.");
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.vsync = VSYNC_NONE;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-14 21:34:51 +08:00
|
|
|
#if defined(DEBUG_EVENTS) || defined(DEBUG_RESTACK)
|
|
|
|
/**
|
|
|
|
* Get a window's name from window ID.
|
|
|
|
*/
|
|
|
|
static bool
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_window_name(session_t *ps, Window wid, char **name) {
|
2012-11-14 21:34:51 +08:00
|
|
|
bool to_free = false;
|
|
|
|
|
|
|
|
*name = "";
|
|
|
|
if (wid) {
|
|
|
|
*name = "(Failed to get title)";
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->root == wid)
|
2012-11-14 21:34:51 +08:00
|
|
|
*name = "(Root window)";
|
2012-11-19 09:46:07 +08:00
|
|
|
else if (ps->overlay == wid)
|
2012-11-14 21:34:51 +08:00
|
|
|
*name = "(Overlay)";
|
|
|
|
else {
|
2012-11-19 09:46:07 +08:00
|
|
|
win *w = find_win(ps, wid);
|
2012-11-14 21:34:51 +08:00
|
|
|
if (!w)
|
2012-11-19 09:46:07 +08:00
|
|
|
w = find_toplevel(ps, wid);
|
2012-11-14 21:34:51 +08:00
|
|
|
|
|
|
|
if (w && w->name)
|
|
|
|
*name = w->name;
|
|
|
|
else if (!(w && w->client_win
|
2012-11-19 09:46:07 +08:00
|
|
|
&& (to_free = wid_get_name(ps, w->client_win, name))))
|
|
|
|
to_free = wid_get_name(ps, wid, name);
|
2012-11-14 21:34:51 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return to_free;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_handle(session_t *ps, XEvent *ev) {
|
2012-02-09 17:37:46 +08:00
|
|
|
if ((ev->type & 0x7f) != KeymapNotify) {
|
2012-11-19 09:46:07 +08:00
|
|
|
discard_ignore(ps, ev->xany.serial);
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
|
2012-09-12 09:08:15 +08:00
|
|
|
#ifdef DEBUG_EVENTS
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ev->type != ps->damage_event + XDamageNotify) {
|
|
|
|
Window wid = ev_window(ps, ev);
|
2012-11-14 21:34:51 +08:00
|
|
|
char *window_name = NULL;
|
2012-11-19 09:46:07 +08:00
|
|
|
bool to_free = false;
|
2012-11-14 21:34:51 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
to_free = ev_window_name(ps, wid, &window_name);
|
2012-09-13 13:58:05 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
print_timestamp(ps);
|
2012-09-11 21:33:03 +08:00
|
|
|
printf("event %10.10s serial %#010x window %#010lx \"%s\"\n",
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_name(ps, ev), ev_serial(ev), wid, window_name);
|
2012-09-13 13:58:05 +08:00
|
|
|
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
if (to_free) {
|
|
|
|
XFree(window_name);
|
|
|
|
window_name = NULL;
|
|
|
|
}
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
|
2012-02-09 17:37:46 +08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
switch (ev->type) {
|
|
|
|
case FocusIn:
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_focus_in(ps, (XFocusChangeEvent *)ev);
|
2012-02-09 17:37:46 +08:00
|
|
|
break;
|
|
|
|
case FocusOut:
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_focus_out(ps, (XFocusChangeEvent *)ev);
|
2012-02-09 17:37:46 +08:00
|
|
|
break;
|
|
|
|
case CreateNotify:
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_create_notify(ps, (XCreateWindowEvent *)ev);
|
2012-02-09 17:37:46 +08:00
|
|
|
break;
|
|
|
|
case ConfigureNotify:
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_configure_notify(ps, (XConfigureEvent *)ev);
|
2012-02-09 17:37:46 +08:00
|
|
|
break;
|
|
|
|
case DestroyNotify:
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_destroy_notify(ps, (XDestroyWindowEvent *)ev);
|
2012-02-09 17:37:46 +08:00
|
|
|
break;
|
|
|
|
case MapNotify:
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_map_notify(ps, (XMapEvent *)ev);
|
2012-02-09 17:37:46 +08:00
|
|
|
break;
|
|
|
|
case UnmapNotify:
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_unmap_notify(ps, (XUnmapEvent *)ev);
|
2012-02-09 17:37:46 +08:00
|
|
|
break;
|
|
|
|
case ReparentNotify:
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_reparent_notify(ps, (XReparentEvent *)ev);
|
2012-02-09 17:37:46 +08:00
|
|
|
break;
|
|
|
|
case CirculateNotify:
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_circulate_notify(ps, (XCirculateEvent *)ev);
|
2012-02-09 17:37:46 +08:00
|
|
|
break;
|
|
|
|
case Expose:
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_expose(ps, (XExposeEvent *)ev);
|
2012-02-09 17:37:46 +08:00
|
|
|
break;
|
|
|
|
case PropertyNotify:
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_property_notify(ps, (XPropertyEvent *)ev);
|
2012-02-09 17:37:46 +08:00
|
|
|
break;
|
|
|
|
default:
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->shape_exists && ev->type == ps->shape_event) {
|
|
|
|
ev_shape_notify(ps, (XShapeEvent *) ev);
|
2012-09-11 21:33:03 +08:00
|
|
|
break;
|
|
|
|
}
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->randr_exists && ev->type == (ps->randr_event + RRScreenChangeNotify)) {
|
|
|
|
ev_screen_change_notify(ps, (XRRScreenChangeNotifyEvent *) ev);
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
break;
|
|
|
|
}
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ev->type == ps->damage_event + XDamageNotify) {
|
|
|
|
ev_damage_notify(ps, (XDamageNotifyEvent *)ev);
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
// === Main ===
|
2012-02-09 17:37:46 +08:00
|
|
|
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
/**
|
|
|
|
* Print usage text and exit.
|
|
|
|
*/
|
2012-02-27 12:00:12 +08:00
|
|
|
static void
|
2012-09-17 16:04:04 +08:00
|
|
|
usage(void) {
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
fputs(
|
|
|
|
"compton (development version)\n"
|
|
|
|
"usage: compton [options]\n"
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
"Options:\n"
|
|
|
|
"\n"
|
2012-02-27 20:49:50 +08:00
|
|
|
"-d display\n"
|
|
|
|
" Which display should be managed.\n"
|
|
|
|
"-r radius\n"
|
|
|
|
" The blur radius for shadows. (default 12)\n"
|
|
|
|
"-o opacity\n"
|
|
|
|
" The translucency for shadows. (default .75)\n"
|
|
|
|
"-l left-offset\n"
|
|
|
|
" The left offset for shadows. (default -15)\n"
|
|
|
|
"-t top-offset\n"
|
|
|
|
" The top offset for shadows. (default -15)\n"
|
|
|
|
"-I fade-in-step\n"
|
|
|
|
" Opacity change between steps while fading in. (default 0.028)\n"
|
|
|
|
"-O fade-out-step\n"
|
|
|
|
" Opacity change between steps while fading out. (default 0.03)\n"
|
|
|
|
"-D fade-delta-time\n"
|
|
|
|
" The time between steps in a fade in milliseconds. (default 10)\n"
|
|
|
|
"-m opacity\n"
|
|
|
|
" The opacity for menus. (default 1.0)\n"
|
|
|
|
"-c\n"
|
|
|
|
" Enabled client-side shadows on windows.\n"
|
|
|
|
"-C\n"
|
|
|
|
" Avoid drawing shadows on dock/panel windows.\n"
|
|
|
|
"-z\n"
|
2012-03-18 00:29:01 +08:00
|
|
|
" Zero the part of the shadow's mask behind the window (experimental).\n"
|
2012-02-27 20:49:50 +08:00
|
|
|
"-f\n"
|
2012-09-26 21:40:48 +08:00
|
|
|
" Fade windows in/out when opening/closing and when opacity\n"
|
|
|
|
" changes, unless --no-fading-openclose is used.\n"
|
2012-02-27 20:49:50 +08:00
|
|
|
"-F\n"
|
2012-09-26 21:40:48 +08:00
|
|
|
" Equals -f. Deprecated.\n"
|
2012-02-27 20:49:50 +08:00
|
|
|
"-i opacity\n"
|
|
|
|
" Opacity of inactive windows. (0.1 - 1.0)\n"
|
|
|
|
"-e opacity\n"
|
|
|
|
" Opacity of window titlebars and borders. (0.1 - 1.0)\n"
|
|
|
|
"-G\n"
|
|
|
|
" Don't draw shadows on DND windows\n"
|
2012-10-22 21:20:43 +08:00
|
|
|
"-b\n"
|
2012-02-27 20:49:50 +08:00
|
|
|
" Daemonize process.\n"
|
|
|
|
"-S\n"
|
2012-09-11 21:57:50 +08:00
|
|
|
" Enable synchronous operation (for debugging).\n"
|
2012-09-25 10:19:20 +08:00
|
|
|
"--config path\n"
|
|
|
|
" Look for configuration file at the path.\n"
|
2012-09-11 21:57:50 +08:00
|
|
|
"--shadow-red value\n"
|
|
|
|
" Red color value of shadow (0.0 - 1.0, defaults to 0).\n"
|
|
|
|
"--shadow-green value\n"
|
|
|
|
" Green color value of shadow (0.0 - 1.0, defaults to 0).\n"
|
|
|
|
"--shadow-blue value\n"
|
|
|
|
" Blue color value of shadow (0.0 - 1.0, defaults to 0).\n"
|
2012-09-11 22:22:58 +08:00
|
|
|
"--inactive-opacity-override\n"
|
|
|
|
" Inactive opacity set by -i overrides value of _NET_WM_OPACITY.\n"
|
2012-09-12 10:52:52 +08:00
|
|
|
"--inactive-dim value\n"
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
" Dim inactive windows. (0.0 - 1.0, defaults to 0)\n"
|
|
|
|
"--mark-wmwin-focused\n"
|
|
|
|
" Try to detect WM windows and mark them as active.\n"
|
|
|
|
"--shadow-exclude condition\n"
|
|
|
|
" Exclude conditions for shadows.\n"
|
2012-09-26 19:48:36 +08:00
|
|
|
"--mark-ovredir-focused\n"
|
2012-11-03 22:02:07 +08:00
|
|
|
" Mark windows that have no WM frame as active.\n"
|
2012-09-26 21:40:48 +08:00
|
|
|
"--no-fading-openclose\n"
|
|
|
|
" Do not fade on window open/close.\n"
|
2012-10-01 10:34:40 +08:00
|
|
|
"--shadow-ignore-shaped\n"
|
|
|
|
" Do not paint shadows on shaped windows.\n"
|
|
|
|
"--detect-rounded-corners\n"
|
|
|
|
" Try to detect windows with rounded corners and don't consider\n"
|
|
|
|
" them shaped windows.\n"
|
2012-10-03 21:13:34 +08:00
|
|
|
"--detect-client-opacity\n"
|
|
|
|
" Detect _NET_WM_OPACITY on client windows, useful for window\n"
|
|
|
|
" managers not passing _NET_WM_OPACITY of client windows to frame\n"
|
|
|
|
" windows.\n"
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
"\n"
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
"--refresh-rate val\n"
|
|
|
|
" Specify refresh rate of the screen. If not specified or 0, compton\n"
|
|
|
|
" will try detecting this with X RandR extension.\n"
|
|
|
|
"--vsync vsync-method\n"
|
2012-10-26 11:12:28 +08:00
|
|
|
" Set VSync method. There are 2 VSync methods currently available:\n"
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
" none = No VSync\n"
|
|
|
|
" drm = VSync with DRM_IOCTL_WAIT_VBLANK. May only work on some\n"
|
|
|
|
" drivers. Experimental.\n"
|
|
|
|
" opengl = Try to VSync with SGI_swap_control OpenGL extension. Only\n"
|
|
|
|
" work on some drivers. Experimental.\n"
|
|
|
|
" (Note some VSync methods may not be enabled at compile time.)\n"
|
2012-10-13 18:46:59 +08:00
|
|
|
"--alpha-step val\n"
|
|
|
|
" Step for pregenerating alpha pictures. 0.01 - 1.0. Defaults to\n"
|
|
|
|
" 0.03.\n"
|
2012-10-23 13:42:20 +08:00
|
|
|
"--dbe\n"
|
|
|
|
" Enable DBE painting mode, intended to use with VSync to\n"
|
|
|
|
" (hopefully) eliminate tearing.\n"
|
2012-10-24 10:09:59 +08:00
|
|
|
"--paint-on-overlay\n"
|
|
|
|
" Painting on X Composite overlay window.\n"
|
2012-10-26 11:12:28 +08:00
|
|
|
"--sw-opti\n"
|
|
|
|
" Limit compton to repaint at most once every 1 / refresh_rate\n"
|
|
|
|
" second to boost performance. Experimental.\n"
|
2012-11-01 10:43:15 +08:00
|
|
|
"--vsync-aggressive\n"
|
|
|
|
" Attempt to send painting request before VBlank and do XFlush()\n"
|
|
|
|
" during VBlank. This switch may be lifted out at any moment.\n"
|
2012-11-04 18:11:08 +08:00
|
|
|
"--use-ewmh-active-win\n"
|
|
|
|
" Use _NET_WM_ACTIVE_WINDOW on the root window to determine which\n"
|
|
|
|
" window is focused instead of using FocusIn/Out events.\n"
|
2012-11-19 09:46:07 +08:00
|
|
|
"--respect-prop-shadow\n"
|
2012-11-09 11:35:40 +08:00
|
|
|
" Respect _COMPTON_SHADOW. This a prototype-level feature, which\n"
|
|
|
|
" you must not rely on.\n"
|
2012-11-09 21:44:02 +08:00
|
|
|
"--unredir-if-possible\n"
|
|
|
|
" Unredirect all windows if a full-screen opaque window is\n"
|
|
|
|
" detected, to maximize performance for full-screen windows.\n"
|
|
|
|
" Experimental.\n"
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
"\n"
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
"Format of a condition:\n"
|
|
|
|
"\n"
|
|
|
|
" condition = <target>:<type>[<flags>]:<pattern>\n"
|
|
|
|
"\n"
|
|
|
|
" <target> is one of \"n\" (window name), \"i\" (window class\n"
|
|
|
|
" instance), and \"g\" (window general class)\n"
|
|
|
|
"\n"
|
|
|
|
" <type> is one of \"e\" (exact match), \"a\" (match anywhere),\n"
|
|
|
|
" \"s\" (match from start), \"w\" (wildcard), and \"p\" (PCRE\n"
|
|
|
|
" regular expressions, if compiled with the support).\n"
|
|
|
|
"\n"
|
2012-09-22 20:49:17 +08:00
|
|
|
" <flags> could be a series of flags. Currently the only defined\n"
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
" flag is \"i\" (ignore case).\n"
|
|
|
|
"\n"
|
|
|
|
" <pattern> is the actual pattern string.\n"
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
, stderr);
|
2011-11-04 14:33:23 +08:00
|
|
|
|
|
|
|
exit(1);
|
2004-06-27 13:08:33 +08:00
|
|
|
}
|
|
|
|
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
/**
|
|
|
|
* Register a window as symbol, and initialize GLX context if wanted.
|
|
|
|
*/
|
2005-10-07 08:08:02 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
register_cm(session_t *ps, bool want_glxct) {
|
2011-11-04 14:33:23 +08:00
|
|
|
Atom a;
|
|
|
|
char *buf;
|
|
|
|
int len, s;
|
|
|
|
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
#ifdef CONFIG_VSYNC_OPENGL
|
|
|
|
// Create a window with the wanted GLX visual
|
|
|
|
if (want_glxct) {
|
2012-10-10 21:12:46 +08:00
|
|
|
XVisualInfo *pvi = NULL;
|
2012-11-19 09:46:07 +08:00
|
|
|
bool ret = false;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
// Get visual for the window
|
|
|
|
int attribs[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, None };
|
2012-11-19 09:46:07 +08:00
|
|
|
pvi = glXChooseVisual(ps->dpy, ps->scr, attribs);
|
2012-10-10 21:12:46 +08:00
|
|
|
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
if (!pvi) {
|
|
|
|
fprintf(stderr, "register_cm(): Failed to choose visual required "
|
|
|
|
"by fake OpenGL VSync window. OpenGL VSync turned off.\n");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Create the window
|
|
|
|
XSetWindowAttributes swa = {
|
2012-11-19 09:46:07 +08:00
|
|
|
.colormap = XCreateColormap(ps->dpy, ps->root, pvi->visual, AllocNone),
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
.border_pixel = 0,
|
|
|
|
};
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
pvi->screen = ps->scr;
|
|
|
|
ps->reg_win = XCreateWindow(ps->dpy, ps->root, 0, 0, 1, 1, 0, pvi->depth,
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
InputOutput, pvi->visual, CWBorderPixel | CWColormap, &swa);
|
2012-10-10 21:12:46 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!ps->reg_win)
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
fprintf(stderr, "register_cm(): Failed to create window required "
|
|
|
|
"by fake OpenGL VSync. OpenGL VSync turned off.\n");
|
|
|
|
else {
|
|
|
|
// Get GLX context
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->glx_context = glXCreateContext(ps->dpy, pvi, None, GL_TRUE);
|
|
|
|
if (!ps->glx_context) {
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
fprintf(stderr, "register_cm(): Failed to get GLX context. "
|
|
|
|
"OpenGL VSync turned off.\n");
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.vsync = VSYNC_NONE;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Attach GLX context
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!(ret = glXMakeCurrent(ps->dpy, ps->reg_win, ps->glx_context)))
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
fprintf(stderr, "register_cm(): Failed to attach GLX context."
|
|
|
|
" OpenGL VSync turned off.\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-10-10 21:12:46 +08:00
|
|
|
if (pvi)
|
|
|
|
XFree(pvi);
|
|
|
|
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
if (!ret)
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.vsync = VSYNC_NONE;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
}
|
|
|
|
#endif
|
2012-11-19 09:46:07 +08:00
|
|
|
|
|
|
|
if (!ps->reg_win)
|
|
|
|
ps->reg_win = XCreateSimpleWindow(ps->dpy, ps->root, 0, 0, 1, 1, 0,
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
None, None);
|
2006-09-07 01:04:47 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
Xutf8SetWMProperties(ps->dpy, ps->reg_win, "xcompmgr", "xcompmgr",
|
2011-11-04 16:41:56 +08:00
|
|
|
NULL, 0, NULL, NULL, NULL);
|
2011-11-04 14:33:23 +08:00
|
|
|
|
|
|
|
len = strlen(REGISTER_PROP) + 2;
|
2012-11-19 09:46:07 +08:00
|
|
|
s = ps->scr;
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
while (s >= 10) {
|
|
|
|
++len;
|
|
|
|
s /= 10;
|
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
buf = malloc(len);
|
2012-11-19 09:46:07 +08:00
|
|
|
snprintf(buf, len, REGISTER_PROP"%d", ps->scr);
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
a = XInternAtom(ps->dpy, buf, false);
|
2011-11-04 14:33:23 +08:00
|
|
|
free(buf);
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
XSetSelectionOwner(ps->dpy, a, ps->reg_win, 0);
|
2005-10-07 08:08:02 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* Fork program to background and disable all I/O streams.
|
|
|
|
*/
|
2012-02-27 12:00:12 +08:00
|
|
|
static void
|
2012-09-17 16:04:04 +08:00
|
|
|
fork_after(void) {
|
2012-02-27 12:00:12 +08:00
|
|
|
if (getppid() == 1) return;
|
|
|
|
|
|
|
|
int pid = fork();
|
|
|
|
|
|
|
|
if (pid == -1) {
|
|
|
|
fprintf(stderr, "Fork failed\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pid > 0) _exit(0);
|
|
|
|
|
|
|
|
setsid();
|
|
|
|
|
2012-11-04 19:14:21 +08:00
|
|
|
// Mainly to suppress the _FORTIFY_SOURCE warning
|
2012-11-09 11:35:40 +08:00
|
|
|
bool success = freopen("/dev/null", "r", stdin);
|
|
|
|
success = freopen("/dev/null", "w", stdout) && success;
|
|
|
|
if (!success)
|
|
|
|
fprintf(stderr, "fork_after(): freopen() failed.");
|
|
|
|
success = freopen("/dev/null", "w", stderr);
|
|
|
|
if (!success)
|
2012-11-04 19:14:21 +08:00
|
|
|
fprintf(stderr, "fork_after(): freopen() failed.");
|
2012-02-27 12:00:12 +08:00
|
|
|
}
|
|
|
|
|
2012-09-25 10:19:20 +08:00
|
|
|
#ifdef CONFIG_LIBCONFIG
|
|
|
|
/**
|
|
|
|
* Get a file stream of the configuration file to read.
|
|
|
|
*
|
|
|
|
* Follows the XDG specification to search for the configuration file.
|
|
|
|
*/
|
|
|
|
static FILE *
|
|
|
|
open_config_file(char *cpath, char **ppath) {
|
|
|
|
const static char *config_filename = "/compton.conf";
|
|
|
|
const static char *config_filename_legacy = "/.compton.conf";
|
|
|
|
const static char *config_home_suffix = "/.config";
|
|
|
|
const static char *config_system_dir = "/etc/xdg";
|
|
|
|
|
|
|
|
char *dir = NULL, *home = NULL;
|
|
|
|
char *path = cpath;
|
|
|
|
FILE *f = NULL;
|
|
|
|
|
|
|
|
if (path) {
|
|
|
|
f = fopen(path, "r");
|
|
|
|
if (f && ppath)
|
|
|
|
*ppath = path;
|
|
|
|
else
|
|
|
|
free(path);
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check user configuration file in $XDG_CONFIG_HOME firstly
|
|
|
|
if (!((dir = getenv("XDG_CONFIG_HOME")) && strlen(dir))) {
|
|
|
|
if (!((home = getenv("HOME")) && strlen(home)))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
path = mstrjoin3(home, config_home_suffix, config_filename);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
path = mstrjoin(dir, config_filename);
|
|
|
|
|
|
|
|
f = fopen(path, "r");
|
|
|
|
|
|
|
|
if (f && ppath)
|
|
|
|
*ppath = path;
|
|
|
|
else
|
|
|
|
free(path);
|
|
|
|
if (f)
|
|
|
|
return f;
|
|
|
|
|
|
|
|
// Then check user configuration file in $HOME
|
|
|
|
if ((home = getenv("HOME")) && strlen(home)) {
|
|
|
|
path = mstrjoin(home, config_filename_legacy);
|
|
|
|
f = fopen(path, "r");
|
|
|
|
if (f && ppath)
|
|
|
|
*ppath = path;
|
|
|
|
else
|
|
|
|
free(path);
|
|
|
|
if (f)
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check system configuration file in $XDG_CONFIG_DIRS at last
|
|
|
|
if ((dir = getenv("XDG_CONFIG_DIRS")) && strlen(dir)) {
|
|
|
|
char *part = strtok(dir, ":");
|
|
|
|
while (part) {
|
|
|
|
path = mstrjoin(part, config_filename);
|
|
|
|
f = fopen(path, "r");
|
|
|
|
if (f && ppath)
|
|
|
|
*ppath = path;
|
|
|
|
else
|
|
|
|
free(path);
|
|
|
|
if (f)
|
|
|
|
return f;
|
|
|
|
part = strtok(NULL, ":");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
path = mstrjoin(config_system_dir, config_filename);
|
|
|
|
f = fopen(path, "r");
|
|
|
|
if (f && ppath)
|
|
|
|
*ppath = path;
|
|
|
|
else
|
|
|
|
free(path);
|
|
|
|
if (f)
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2012-10-26 11:12:28 +08:00
|
|
|
/**
|
|
|
|
* Parse a VSync option argument.
|
|
|
|
*/
|
|
|
|
static inline void
|
2012-11-19 09:46:07 +08:00
|
|
|
parse_vsync(session_t *ps, const char *optarg) {
|
2012-10-26 11:12:28 +08:00
|
|
|
const static char * const vsync_str[] = {
|
|
|
|
"none", // VSYNC_NONE
|
|
|
|
"drm", // VSYNC_DRM
|
|
|
|
"opengl", // VSYNC_OPENGL
|
|
|
|
};
|
|
|
|
|
|
|
|
vsync_t i;
|
|
|
|
|
|
|
|
for (i = 0; i < (sizeof(vsync_str) / sizeof(vsync_str[0])); ++i)
|
|
|
|
if (!strcasecmp(optarg, vsync_str[i])) {
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.vsync = i;
|
2012-10-26 11:12:28 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if ((sizeof(vsync_str) / sizeof(vsync_str[0])) == i) {
|
|
|
|
fputs("Invalid --vsync argument. Ignored.\n", stderr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-25 10:19:20 +08:00
|
|
|
/**
|
|
|
|
* Parse a configuration file from default location.
|
|
|
|
*/
|
2012-02-09 17:37:46 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
parse_config(session_t *ps, char *cpath, struct options_tmp *pcfgtmp) {
|
2012-09-28 09:10:34 +08:00
|
|
|
char *path = NULL;
|
2012-09-25 10:19:20 +08:00
|
|
|
FILE *f;
|
|
|
|
config_t cfg;
|
|
|
|
int ival = 0;
|
|
|
|
double dval = 0.0;
|
2012-10-26 11:12:28 +08:00
|
|
|
const char *sval = NULL;
|
2012-09-25 10:19:20 +08:00
|
|
|
|
|
|
|
f = open_config_file(cpath, &path);
|
|
|
|
if (!f) {
|
|
|
|
if (cpath)
|
|
|
|
printf("Failed to read the specified configuration file.\n");
|
|
|
|
return;
|
|
|
|
}
|
2012-02-09 17:37:46 +08:00
|
|
|
|
2012-09-25 10:19:20 +08:00
|
|
|
config_init(&cfg);
|
2012-09-28 09:10:34 +08:00
|
|
|
#ifndef CONFIG_LIBCONFIG_LEGACY
|
|
|
|
char *parent = dirname(path);
|
2012-09-25 10:19:20 +08:00
|
|
|
if (parent)
|
|
|
|
config_set_include_dir(&cfg, parent);
|
2012-09-28 09:10:34 +08:00
|
|
|
#endif
|
2012-09-25 10:19:20 +08:00
|
|
|
|
|
|
|
if (CONFIG_FALSE == config_read(&cfg, f)) {
|
|
|
|
printf("Error when reading configuration file \"%s\", line %d: %s\n",
|
|
|
|
path, config_error_line(&cfg), config_error_text(&cfg));
|
|
|
|
config_destroy(&cfg);
|
|
|
|
free(path);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
config_set_auto_convert(&cfg, 1);
|
|
|
|
|
|
|
|
free(path);
|
|
|
|
|
|
|
|
// Get options from the configuration file. We don't do range checking
|
|
|
|
// right now. It will be done later
|
|
|
|
|
2012-09-26 18:54:35 +08:00
|
|
|
// -D (fade_delta)
|
2012-09-28 09:10:34 +08:00
|
|
|
if (lcfg_lookup_int(&cfg, "fade-delta", &ival))
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.fade_delta = ival;
|
2012-09-26 18:54:35 +08:00
|
|
|
// -I (fade_in_step)
|
2012-09-25 10:19:20 +08:00
|
|
|
if (config_lookup_float(&cfg, "fade-in-step", &dval))
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.fade_in_step = normalize_d(dval) * OPAQUE;
|
2012-09-26 18:54:35 +08:00
|
|
|
// -O (fade_out_step)
|
2012-09-25 10:19:20 +08:00
|
|
|
if (config_lookup_float(&cfg, "fade-out-step", &dval))
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.fade_out_step = normalize_d(dval) * OPAQUE;
|
2012-09-26 18:54:35 +08:00
|
|
|
// -r (shadow_radius)
|
2012-11-19 09:46:07 +08:00
|
|
|
lcfg_lookup_int(&cfg, "shadow-radius", &ps->o.shadow_radius);
|
2012-09-26 18:54:35 +08:00
|
|
|
// -o (shadow_opacity)
|
2012-11-19 09:46:07 +08:00
|
|
|
config_lookup_float(&cfg, "shadow-opacity", &ps->o.shadow_opacity);
|
2012-09-26 18:54:35 +08:00
|
|
|
// -l (shadow_offset_x)
|
2012-11-19 09:46:07 +08:00
|
|
|
lcfg_lookup_int(&cfg, "shadow-offset-x", &ps->o.shadow_offset_x);
|
2012-09-26 18:54:35 +08:00
|
|
|
// -t (shadow_offset_y)
|
2012-11-19 09:46:07 +08:00
|
|
|
lcfg_lookup_int(&cfg, "shadow-offset-y", &ps->o.shadow_offset_y);
|
2012-09-26 18:54:35 +08:00
|
|
|
// -i (inactive_opacity)
|
2012-09-25 10:19:20 +08:00
|
|
|
if (config_lookup_float(&cfg, "inactive-opacity", &dval))
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.inactive_opacity = normalize_d(dval) * OPAQUE;
|
2012-09-26 18:54:35 +08:00
|
|
|
// -e (frame_opacity)
|
2012-11-19 09:46:07 +08:00
|
|
|
config_lookup_float(&cfg, "frame-opacity", &ps->o.frame_opacity);
|
2012-09-26 18:54:35 +08:00
|
|
|
// -z (clear_shadow)
|
2012-11-19 09:46:07 +08:00
|
|
|
lcfg_lookup_bool(&cfg, "clear-shadow", &ps->o.clear_shadow);
|
2012-09-26 18:54:35 +08:00
|
|
|
// -c (shadow_enable)
|
|
|
|
if (config_lookup_bool(&cfg, "shadow", &ival) && ival)
|
2012-11-19 09:46:07 +08:00
|
|
|
wintype_arr_enable(ps->o.wintype_shadow);
|
2012-09-26 18:54:35 +08:00
|
|
|
// -C (no_dock_shadow)
|
|
|
|
lcfg_lookup_bool(&cfg, "no-dock-shadow", &pcfgtmp->no_dock_shadow);
|
|
|
|
// -G (no_dnd_shadow)
|
|
|
|
lcfg_lookup_bool(&cfg, "no-dnd-shadow", &pcfgtmp->no_dnd_shadow);
|
|
|
|
// -m (menu_opacity)
|
|
|
|
config_lookup_float(&cfg, "menu-opacity", &pcfgtmp->menu_opacity);
|
|
|
|
// -f (fading_enable)
|
|
|
|
if (config_lookup_bool(&cfg, "fading", &ival) && ival)
|
2012-11-19 09:46:07 +08:00
|
|
|
wintype_arr_enable(ps->o.wintype_fade);
|
2012-09-26 21:40:48 +08:00
|
|
|
// --no-fading-open-close
|
2012-11-19 09:46:07 +08:00
|
|
|
lcfg_lookup_bool(&cfg, "no-fading-openclose", &ps->o.no_fading_openclose);
|
2012-09-25 10:19:20 +08:00
|
|
|
// --shadow-red
|
2012-11-19 09:46:07 +08:00
|
|
|
config_lookup_float(&cfg, "shadow-red", &ps->o.shadow_red);
|
2012-09-25 10:19:20 +08:00
|
|
|
// --shadow-green
|
2012-11-19 09:46:07 +08:00
|
|
|
config_lookup_float(&cfg, "shadow-green", &ps->o.shadow_green);
|
2012-09-25 10:19:20 +08:00
|
|
|
// --shadow-blue
|
2012-11-19 09:46:07 +08:00
|
|
|
config_lookup_float(&cfg, "shadow-blue", &ps->o.shadow_blue);
|
2012-09-25 10:19:20 +08:00
|
|
|
// --inactive-opacity-override
|
2012-09-26 18:54:35 +08:00
|
|
|
lcfg_lookup_bool(&cfg, "inactive-opacity-override",
|
2012-11-19 09:46:07 +08:00
|
|
|
&ps->o.inactive_opacity_override);
|
2012-09-25 10:19:20 +08:00
|
|
|
// --inactive-dim
|
2012-11-19 09:46:07 +08:00
|
|
|
config_lookup_float(&cfg, "inactive-dim", &ps->o.inactive_dim);
|
2012-09-25 10:19:20 +08:00
|
|
|
// --mark-wmwin-focused
|
2012-11-19 09:46:07 +08:00
|
|
|
lcfg_lookup_bool(&cfg, "mark-wmwin-focused", &ps->o.mark_wmwin_focused);
|
2012-09-26 19:48:36 +08:00
|
|
|
// --mark-ovredir-focused
|
|
|
|
lcfg_lookup_bool(&cfg, "mark-ovredir-focused",
|
2012-11-19 09:46:07 +08:00
|
|
|
&ps->o.mark_ovredir_focused);
|
2012-10-01 10:34:40 +08:00
|
|
|
// --shadow-ignore-shaped
|
|
|
|
lcfg_lookup_bool(&cfg, "shadow-ignore-shaped",
|
2012-11-19 09:46:07 +08:00
|
|
|
&ps->o.shadow_ignore_shaped);
|
2012-10-01 10:34:40 +08:00
|
|
|
// --detect-rounded-corners
|
|
|
|
lcfg_lookup_bool(&cfg, "detect-rounded-corners",
|
2012-11-19 09:46:07 +08:00
|
|
|
&ps->o.detect_rounded_corners);
|
2012-10-03 21:13:34 +08:00
|
|
|
// --detect-client-opacity
|
|
|
|
lcfg_lookup_bool(&cfg, "detect-client-opacity",
|
2012-11-19 09:46:07 +08:00
|
|
|
&ps->o.detect_client_opacity);
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
// --refresh-rate
|
2012-11-19 09:46:07 +08:00
|
|
|
lcfg_lookup_int(&cfg, "refresh-rate", &ps->o.refresh_rate);
|
2012-10-26 11:12:28 +08:00
|
|
|
// --vsync
|
|
|
|
if (config_lookup_string(&cfg, "vsync", &sval))
|
2012-11-19 09:46:07 +08:00
|
|
|
parse_vsync(ps, sval);
|
2012-10-13 18:46:59 +08:00
|
|
|
// --alpha-step
|
2012-11-19 09:46:07 +08:00
|
|
|
config_lookup_float(&cfg, "alpha-step", &ps->o.alpha_step);
|
2012-10-27 21:46:01 +08:00
|
|
|
// --dbe
|
2012-11-19 09:46:07 +08:00
|
|
|
lcfg_lookup_bool(&cfg, "dbe", &ps->o.dbe);
|
2012-10-24 10:09:59 +08:00
|
|
|
// --paint-on-overlay
|
2012-11-19 09:46:07 +08:00
|
|
|
lcfg_lookup_bool(&cfg, "paint-on-overlay", &ps->o.paint_on_overlay);
|
2012-10-26 11:12:28 +08:00
|
|
|
// --sw-opti
|
2012-11-19 09:46:07 +08:00
|
|
|
lcfg_lookup_bool(&cfg, "sw-opti", &ps->o.sw_opti);
|
2012-11-04 18:11:08 +08:00
|
|
|
// --use-ewmh-active-win
|
|
|
|
lcfg_lookup_bool(&cfg, "use-ewmh-active-win",
|
2012-11-19 09:46:07 +08:00
|
|
|
&ps->o.use_ewmh_active_win);
|
2012-11-14 21:34:51 +08:00
|
|
|
// --unredir-if-possible
|
|
|
|
lcfg_lookup_bool(&cfg, "unredir-if-possible",
|
2012-11-19 09:46:07 +08:00
|
|
|
&ps->o.unredir_if_possible);
|
2012-09-25 10:19:20 +08:00
|
|
|
// --shadow-exclude
|
|
|
|
{
|
2012-09-25 21:04:10 +08:00
|
|
|
config_setting_t *setting =
|
2012-09-25 10:19:20 +08:00
|
|
|
config_lookup(&cfg, "shadow-exclude");
|
2012-09-25 21:04:10 +08:00
|
|
|
if (setting) {
|
2012-09-25 10:19:20 +08:00
|
|
|
// Parse an array of shadow-exclude
|
2012-09-25 21:04:10 +08:00
|
|
|
if (config_setting_is_array(setting)) {
|
|
|
|
int i = config_setting_length(setting);
|
2012-09-25 10:19:20 +08:00
|
|
|
while (i--) {
|
2012-11-19 09:46:07 +08:00
|
|
|
condlst_add(&ps->o.shadow_blacklist,
|
2012-09-25 21:04:10 +08:00
|
|
|
config_setting_get_string_elem(setting, i));
|
2012-09-25 10:19:20 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// Treat it as a single pattern if it's a string
|
2012-09-25 21:04:10 +08:00
|
|
|
else if (CONFIG_TYPE_STRING == config_setting_type(setting)) {
|
2012-11-19 09:46:07 +08:00
|
|
|
condlst_add(&ps->o.shadow_blacklist,
|
2012-09-25 21:04:10 +08:00
|
|
|
config_setting_get_string(setting));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Wintype settings
|
|
|
|
{
|
2012-11-19 09:46:07 +08:00
|
|
|
wintype_t i;
|
2012-09-25 21:04:10 +08:00
|
|
|
|
|
|
|
for (i = 0; i < NUM_WINTYPES; ++i) {
|
|
|
|
char *str = mstrjoin("wintypes.", WINTYPES[i]);
|
|
|
|
config_setting_t *setting = config_lookup(&cfg, str);
|
|
|
|
free(str);
|
|
|
|
if (setting) {
|
|
|
|
if (config_setting_lookup_bool(setting, "shadow", &ival))
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.wintype_shadow[i] = (bool) ival;
|
2012-09-25 21:04:10 +08:00
|
|
|
if (config_setting_lookup_bool(setting, "fade", &ival))
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.wintype_fade[i] = (bool) ival;
|
2012-09-25 21:04:10 +08:00
|
|
|
config_setting_lookup_float(setting, "opacity",
|
2012-11-19 09:46:07 +08:00
|
|
|
&ps->o.wintype_opacity[i]);
|
2012-09-25 10:19:20 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
config_destroy(&cfg);
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
2012-09-25 10:19:20 +08:00
|
|
|
#endif
|
2012-02-09 17:37:46 +08:00
|
|
|
|
2012-09-25 10:19:20 +08:00
|
|
|
/**
|
|
|
|
* Process arguments and configuration files.
|
|
|
|
*/
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
get_cfg(session_t *ps, int argc, char *const *argv) {
|
2012-09-25 10:19:20 +08:00
|
|
|
const static char *shortopts = "D:I:O:d:r:o:m:l:t:i:e:scnfFCaSzGb";
|
|
|
|
const static struct option longopts[] = {
|
|
|
|
{ "config", required_argument, NULL, 256 },
|
|
|
|
{ "shadow-red", required_argument, NULL, 257 },
|
|
|
|
{ "shadow-green", required_argument, NULL, 258 },
|
|
|
|
{ "shadow-blue", required_argument, NULL, 259 },
|
|
|
|
{ "inactive-opacity-override", no_argument, NULL, 260 },
|
|
|
|
{ "inactive-dim", required_argument, NULL, 261 },
|
|
|
|
{ "mark-wmwin-focused", no_argument, NULL, 262 },
|
|
|
|
{ "shadow-exclude", required_argument, NULL, 263 },
|
2012-09-26 19:48:36 +08:00
|
|
|
{ "mark-ovredir-focused", no_argument, NULL, 264 },
|
2012-09-26 21:40:48 +08:00
|
|
|
{ "no-fading-openclose", no_argument, NULL, 265 },
|
2012-10-01 10:34:40 +08:00
|
|
|
{ "shadow-ignore-shaped", no_argument, NULL, 266 },
|
|
|
|
{ "detect-rounded-corners", no_argument, NULL, 267 },
|
2012-10-03 21:13:34 +08:00
|
|
|
{ "detect-client-opacity", no_argument, NULL, 268 },
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
{ "refresh-rate", required_argument, NULL, 269 },
|
|
|
|
{ "vsync", required_argument, NULL, 270 },
|
2012-10-13 18:46:59 +08:00
|
|
|
{ "alpha-step", required_argument, NULL, 271 },
|
2012-10-23 13:42:20 +08:00
|
|
|
{ "dbe", no_argument, NULL, 272 },
|
2012-10-24 10:09:59 +08:00
|
|
|
{ "paint-on-overlay", no_argument, NULL, 273 },
|
2012-10-26 11:12:28 +08:00
|
|
|
{ "sw-opti", no_argument, NULL, 274 },
|
2012-11-01 10:43:15 +08:00
|
|
|
{ "vsync-aggressive", no_argument, NULL, 275 },
|
2012-11-04 18:11:08 +08:00
|
|
|
{ "use-ewmh-active-win", no_argument, NULL, 276 },
|
2012-11-19 09:46:07 +08:00
|
|
|
{ "respect-prop-shadow", no_argument, NULL, 277 },
|
2012-11-09 21:44:02 +08:00
|
|
|
{ "unredir-if-possible", no_argument, NULL, 278 },
|
2012-09-11 23:11:23 +08:00
|
|
|
// Must terminate with a NULL entry
|
|
|
|
{ NULL, 0, NULL, 0 },
|
2012-09-11 21:57:50 +08:00
|
|
|
};
|
|
|
|
|
2012-09-26 18:54:35 +08:00
|
|
|
struct options_tmp cfgtmp = {
|
2012-11-19 09:46:07 +08:00
|
|
|
.no_dock_shadow = false,
|
|
|
|
.no_dnd_shadow = false,
|
2012-09-26 18:54:35 +08:00
|
|
|
.menu_opacity = 1.0,
|
|
|
|
};
|
2012-11-19 09:46:07 +08:00
|
|
|
bool shadow_enable = false, fading_enable = false;
|
2012-09-25 10:19:20 +08:00
|
|
|
int o, longopt_idx, i;
|
|
|
|
char *config_file = NULL;
|
2012-09-27 22:30:16 +08:00
|
|
|
char *lc_numeric_old = mstrcpy(setlocale(LC_NUMERIC, NULL));
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
for (i = 0; i < NUM_WINTYPES; ++i) {
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.wintype_fade[i] = false;
|
|
|
|
ps->o.wintype_shadow[i] = false;
|
|
|
|
ps->o.wintype_opacity[i] = 1.0;
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
|
|
|
|
2012-09-25 10:19:20 +08:00
|
|
|
// Pre-parse the commandline arguments to check for --config and invalid
|
|
|
|
// switches
|
2012-11-19 09:46:07 +08:00
|
|
|
// Must reset optind to 0 here in case we reread the commandline
|
|
|
|
// arguments
|
|
|
|
optind = 1;
|
2012-09-25 10:19:20 +08:00
|
|
|
while (-1 !=
|
|
|
|
(o = getopt_long(argc, argv, shortopts, longopts, &longopt_idx))) {
|
|
|
|
if (256 == o)
|
|
|
|
config_file = mstrcpy(optarg);
|
|
|
|
else if ('?' == o || ':' == o)
|
|
|
|
usage();
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef CONFIG_LIBCONFIG
|
2012-11-19 09:46:07 +08:00
|
|
|
parse_config(ps, config_file, &cfgtmp);
|
2012-09-25 10:19:20 +08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
// Parse commandline arguments. Range checking will be done later.
|
2012-09-27 22:30:16 +08:00
|
|
|
|
|
|
|
// Enforce LC_NUMERIC locale "C" here to make sure dots are recognized
|
|
|
|
// instead of commas in atof().
|
|
|
|
setlocale(LC_NUMERIC, "C");
|
|
|
|
|
2012-09-25 10:19:20 +08:00
|
|
|
optind = 1;
|
|
|
|
while (-1 !=
|
|
|
|
(o = getopt_long(argc, argv, shortopts, longopts, &longopt_idx))) {
|
2011-11-04 14:33:23 +08:00
|
|
|
switch (o) {
|
2012-09-11 21:57:50 +08:00
|
|
|
// Short options
|
2011-11-04 16:41:56 +08:00
|
|
|
case 'd':
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.display = mstrcpy(optarg);
|
2011-11-04 16:41:56 +08:00
|
|
|
break;
|
|
|
|
case 'D':
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.fade_delta = atoi(optarg);
|
2011-11-04 16:41:56 +08:00
|
|
|
break;
|
|
|
|
case 'I':
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.fade_in_step = normalize_d(atof(optarg)) * OPAQUE;
|
2011-11-04 16:41:56 +08:00
|
|
|
break;
|
|
|
|
case 'O':
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.fade_out_step = normalize_d(atof(optarg)) * OPAQUE;
|
2011-11-04 16:41:56 +08:00
|
|
|
break;
|
2011-11-07 09:29:23 +08:00
|
|
|
case 'c':
|
2012-11-19 09:46:07 +08:00
|
|
|
shadow_enable = true;
|
2011-11-07 09:29:23 +08:00
|
|
|
break;
|
2011-11-04 16:41:56 +08:00
|
|
|
case 'C':
|
2012-11-19 09:46:07 +08:00
|
|
|
cfgtmp.no_dock_shadow = true;
|
2012-09-26 18:54:35 +08:00
|
|
|
break;
|
|
|
|
case 'G':
|
2012-11-19 09:46:07 +08:00
|
|
|
cfgtmp.no_dnd_shadow = true;
|
2011-11-04 16:41:56 +08:00
|
|
|
break;
|
|
|
|
case 'm':
|
2012-09-26 18:54:35 +08:00
|
|
|
cfgtmp.menu_opacity = atof(optarg);
|
2011-11-04 16:41:56 +08:00
|
|
|
break;
|
|
|
|
case 'f':
|
|
|
|
case 'F':
|
2012-11-19 09:46:07 +08:00
|
|
|
fading_enable = true;
|
2011-11-04 16:41:56 +08:00
|
|
|
break;
|
|
|
|
case 'S':
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.synchronize = true;
|
2011-11-04 16:41:56 +08:00
|
|
|
break;
|
|
|
|
case 'r':
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.shadow_radius = atoi(optarg);
|
2011-11-04 16:41:56 +08:00
|
|
|
break;
|
|
|
|
case 'o':
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.shadow_opacity = atof(optarg);
|
2011-11-04 16:41:56 +08:00
|
|
|
break;
|
|
|
|
case 'l':
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.shadow_offset_x = atoi(optarg);
|
2011-11-04 16:41:56 +08:00
|
|
|
break;
|
|
|
|
case 't':
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.shadow_offset_y = atoi(optarg);
|
2011-11-04 16:41:56 +08:00
|
|
|
break;
|
2011-11-05 01:02:17 +08:00
|
|
|
case 'i':
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.inactive_opacity = (normalize_d(atof(optarg)) * OPAQUE);
|
2011-11-05 01:02:17 +08:00
|
|
|
break;
|
2011-11-06 11:33:50 +08:00
|
|
|
case 'e':
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.frame_opacity = atof(optarg);
|
2011-11-06 10:39:58 +08:00
|
|
|
break;
|
2012-02-05 11:46:13 +08:00
|
|
|
case 'z':
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.clear_shadow = true;
|
2012-02-05 11:46:13 +08:00
|
|
|
break;
|
2011-11-04 16:41:56 +08:00
|
|
|
case 'n':
|
|
|
|
case 'a':
|
|
|
|
case 's':
|
2011-11-07 09:29:23 +08:00
|
|
|
fprintf(stderr, "Warning: "
|
|
|
|
"-n, -a, and -s have been removed.\n");
|
2011-11-04 16:41:56 +08:00
|
|
|
break;
|
2012-02-27 01:02:42 +08:00
|
|
|
case 'b':
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.fork_after_register = true;
|
2012-02-27 01:02:42 +08:00
|
|
|
break;
|
2012-09-25 10:19:20 +08:00
|
|
|
// Long options
|
|
|
|
case 256:
|
|
|
|
// --config
|
|
|
|
break;
|
|
|
|
case 257:
|
|
|
|
// --shadow-red
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.shadow_red = atof(optarg);
|
2012-09-25 10:19:20 +08:00
|
|
|
break;
|
|
|
|
case 258:
|
|
|
|
// --shadow-green
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.shadow_green = atof(optarg);
|
2012-09-25 10:19:20 +08:00
|
|
|
break;
|
|
|
|
case 259:
|
|
|
|
// --shadow-blue
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.shadow_blue = atof(optarg);
|
2012-09-25 10:19:20 +08:00
|
|
|
break;
|
|
|
|
case 260:
|
|
|
|
// --inactive-opacity-override
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.inactive_opacity_override = true;
|
2012-09-25 10:19:20 +08:00
|
|
|
break;
|
|
|
|
case 261:
|
|
|
|
// --inactive-dim
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.inactive_dim = atof(optarg);
|
2012-09-25 10:19:20 +08:00
|
|
|
break;
|
|
|
|
case 262:
|
|
|
|
// --mark-wmwin-focused
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.mark_wmwin_focused = true;
|
2012-09-25 10:19:20 +08:00
|
|
|
break;
|
|
|
|
case 263:
|
|
|
|
// --shadow-exclude
|
2012-11-19 09:46:07 +08:00
|
|
|
condlst_add(&ps->o.shadow_blacklist, optarg);
|
2012-09-25 10:19:20 +08:00
|
|
|
break;
|
2012-09-26 19:48:36 +08:00
|
|
|
case 264:
|
|
|
|
// --mark-ovredir-focused
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.mark_ovredir_focused = true;
|
2012-09-26 19:48:36 +08:00
|
|
|
break;
|
2012-09-26 21:40:48 +08:00
|
|
|
case 265:
|
|
|
|
// --no-fading-openclose
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.no_fading_openclose = true;
|
2012-09-25 10:19:20 +08:00
|
|
|
break;
|
2012-10-01 10:34:40 +08:00
|
|
|
case 266:
|
|
|
|
// --shadow-ignore-shaped
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.shadow_ignore_shaped = true;
|
2012-10-01 10:34:40 +08:00
|
|
|
break;
|
|
|
|
case 267:
|
|
|
|
// --detect-rounded-corners
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.detect_rounded_corners = true;
|
2012-10-01 10:34:40 +08:00
|
|
|
break;
|
2012-10-03 21:13:34 +08:00
|
|
|
case 268:
|
|
|
|
// --detect-client-opacity
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.detect_client_opacity = true;
|
2012-10-03 21:13:34 +08:00
|
|
|
break;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
case 269:
|
|
|
|
// --refresh-rate
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.refresh_rate = atoi(optarg);
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
break;
|
|
|
|
case 270:
|
|
|
|
// --vsync
|
2012-11-19 09:46:07 +08:00
|
|
|
parse_vsync(ps, optarg);
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
break;
|
2012-10-13 18:46:59 +08:00
|
|
|
case 271:
|
|
|
|
// --alpha-step
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.alpha_step = atof(optarg);
|
2012-10-13 18:46:59 +08:00
|
|
|
break;
|
2012-10-23 13:42:20 +08:00
|
|
|
case 272:
|
|
|
|
// --dbe
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.dbe = true;
|
2012-10-23 13:42:20 +08:00
|
|
|
break;
|
2012-10-24 10:09:59 +08:00
|
|
|
case 273:
|
|
|
|
// --paint-on-overlay
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.paint_on_overlay = true;
|
2012-10-24 10:09:59 +08:00
|
|
|
break;
|
2012-10-26 11:12:28 +08:00
|
|
|
case 274:
|
|
|
|
// --sw-opti
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.sw_opti = true;
|
2012-10-26 11:12:28 +08:00
|
|
|
break;
|
2012-11-01 10:43:15 +08:00
|
|
|
case 275:
|
|
|
|
// --vsync-aggressive
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.vsync_aggressive = true;
|
2012-11-01 10:43:15 +08:00
|
|
|
break;
|
2012-11-04 18:11:08 +08:00
|
|
|
case 276:
|
|
|
|
// --use-ewmh-active-win
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.use_ewmh_active_win = true;
|
2012-11-04 18:11:08 +08:00
|
|
|
break;
|
2012-11-09 11:35:40 +08:00
|
|
|
case 277:
|
2012-11-19 09:46:07 +08:00
|
|
|
// --respect-prop-shadow
|
|
|
|
ps->o.respect_prop_shadow = true;
|
2012-11-09 11:35:40 +08:00
|
|
|
break;
|
2012-11-09 21:44:02 +08:00
|
|
|
case 278:
|
|
|
|
// --unredir-if-possible
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.unredir_if_possible = true;
|
2012-11-09 21:44:02 +08:00
|
|
|
break;
|
2011-11-04 16:41:56 +08:00
|
|
|
default:
|
2012-02-27 12:00:12 +08:00
|
|
|
usage();
|
2008-02-15 12:38:32 +08:00
|
|
|
}
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2003-11-09 15:08:23 +08:00
|
|
|
|
2012-09-27 22:30:16 +08:00
|
|
|
// Restore LC_NUMERIC
|
|
|
|
setlocale(LC_NUMERIC, lc_numeric_old);
|
|
|
|
free(lc_numeric_old);
|
|
|
|
|
2012-09-25 10:19:20 +08:00
|
|
|
// Range checking and option assignments
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.fade_delta = max_i(ps->o.fade_delta, 1);
|
|
|
|
ps->o.shadow_radius = max_i(ps->o.shadow_radius, 1);
|
|
|
|
ps->o.shadow_red = normalize_d(ps->o.shadow_red);
|
|
|
|
ps->o.shadow_green = normalize_d(ps->o.shadow_green);
|
|
|
|
ps->o.shadow_blue = normalize_d(ps->o.shadow_blue);
|
|
|
|
ps->o.inactive_dim = normalize_d(ps->o.inactive_dim);
|
|
|
|
ps->o.frame_opacity = normalize_d(ps->o.frame_opacity);
|
|
|
|
ps->o.shadow_opacity = normalize_d(ps->o.shadow_opacity);
|
2012-09-26 18:54:35 +08:00
|
|
|
cfgtmp.menu_opacity = normalize_d(cfgtmp.menu_opacity);
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.refresh_rate = normalize_i_range(ps->o.refresh_rate, 0, 300);
|
|
|
|
ps->o.alpha_step = normalize_d_range(ps->o.alpha_step, 0.01, 1.0);
|
|
|
|
if (OPAQUE == ps->o.inactive_opacity) {
|
|
|
|
ps->o.inactive_opacity = 0;
|
2012-09-26 18:54:35 +08:00
|
|
|
}
|
|
|
|
if (shadow_enable)
|
2012-11-19 09:46:07 +08:00
|
|
|
wintype_arr_enable(ps->o.wintype_shadow);
|
|
|
|
ps->o.wintype_shadow[WINTYPE_DESKTOP] = false;
|
2012-09-26 18:54:35 +08:00
|
|
|
if (cfgtmp.no_dock_shadow)
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.wintype_shadow[WINTYPE_DOCK] = false;
|
2012-09-26 18:54:35 +08:00
|
|
|
if (cfgtmp.no_dnd_shadow)
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.wintype_shadow[WINTYPE_DND] = false;
|
2012-09-26 18:54:35 +08:00
|
|
|
if (fading_enable)
|
2012-11-19 09:46:07 +08:00
|
|
|
wintype_arr_enable(ps->o.wintype_fade);
|
2012-09-26 18:54:35 +08:00
|
|
|
if (1.0 != cfgtmp.menu_opacity) {
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.wintype_opacity[WINTYPE_DROPDOWN_MENU] = cfgtmp.menu_opacity;
|
|
|
|
ps->o.wintype_opacity[WINTYPE_POPUP_MENU] = cfgtmp.menu_opacity;
|
2012-02-27 12:00:12 +08:00
|
|
|
}
|
2012-02-27 00:35:17 +08:00
|
|
|
|
2012-09-25 10:19:20 +08:00
|
|
|
// Other variables determined by options
|
|
|
|
|
2012-09-13 11:47:31 +08:00
|
|
|
// Determine whether we need to track focus changes
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.inactive_opacity || ps->o.inactive_dim) {
|
|
|
|
ps->o.track_focus = true;
|
2012-09-13 13:58:05 +08:00
|
|
|
}
|
2012-09-13 11:47:31 +08:00
|
|
|
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
// Determine whether we need to track window name and class
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.shadow_blacklist || ps->o.fade_blacklist)
|
|
|
|
ps->o.track_wdata = true;
|
2012-09-25 10:19:20 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* Fetch all required atoms and save them to a session.
|
|
|
|
*/
|
2012-09-25 10:19:20 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
init_atoms(session_t *ps) {
|
|
|
|
ps->atom_opacity = XInternAtom(ps->dpy, "_NET_WM_WINDOW_OPACITY", False);
|
|
|
|
ps->atom_frame_extents = XInternAtom(ps->dpy, "_NET_FRAME_EXTENTS", False);
|
|
|
|
ps->atom_client = XInternAtom(ps->dpy, "WM_STATE", False);
|
|
|
|
ps->atom_name = XA_WM_NAME;
|
|
|
|
ps->atom_name_ewmh = XInternAtom(ps->dpy, "_NET_WM_NAME", False);
|
|
|
|
ps->atom_class = XA_WM_CLASS;
|
|
|
|
ps->atom_transient = XA_WM_TRANSIENT_FOR;
|
|
|
|
ps->atom_ewmh_active_win = XInternAtom(ps->dpy, "_NET_ACTIVE_WINDOW", False);
|
|
|
|
ps->atom_compton_shadow = XInternAtom(ps->dpy, "_COMPTON_SHADOW", False);
|
|
|
|
|
|
|
|
ps->atom_win_type = XInternAtom(ps->dpy,
|
2012-09-25 10:19:20 +08:00
|
|
|
"_NET_WM_WINDOW_TYPE", False);
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->atoms_wintypes[WINTYPE_UNKNOWN] = 0;
|
|
|
|
ps->atoms_wintypes[WINTYPE_DESKTOP] = XInternAtom(ps->dpy,
|
2012-09-25 10:19:20 +08:00
|
|
|
"_NET_WM_WINDOW_TYPE_DESKTOP", False);
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->atoms_wintypes[WINTYPE_DOCK] = XInternAtom(ps->dpy,
|
2012-09-25 10:19:20 +08:00
|
|
|
"_NET_WM_WINDOW_TYPE_DOCK", False);
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->atoms_wintypes[WINTYPE_TOOLBAR] = XInternAtom(ps->dpy,
|
2012-09-25 10:19:20 +08:00
|
|
|
"_NET_WM_WINDOW_TYPE_TOOLBAR", False);
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->atoms_wintypes[WINTYPE_MENU] = XInternAtom(ps->dpy,
|
2012-09-25 10:19:20 +08:00
|
|
|
"_NET_WM_WINDOW_TYPE_MENU", False);
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->atoms_wintypes[WINTYPE_UTILITY] = XInternAtom(ps->dpy,
|
2012-09-25 10:19:20 +08:00
|
|
|
"_NET_WM_WINDOW_TYPE_UTILITY", False);
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->atoms_wintypes[WINTYPE_SPLASH] = XInternAtom(ps->dpy,
|
2012-09-25 10:19:20 +08:00
|
|
|
"_NET_WM_WINDOW_TYPE_SPLASH", False);
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->atoms_wintypes[WINTYPE_DIALOG] = XInternAtom(ps->dpy,
|
2012-09-25 10:19:20 +08:00
|
|
|
"_NET_WM_WINDOW_TYPE_DIALOG", False);
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->atoms_wintypes[WINTYPE_NORMAL] = XInternAtom(ps->dpy,
|
2012-09-25 10:19:20 +08:00
|
|
|
"_NET_WM_WINDOW_TYPE_NORMAL", False);
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->atoms_wintypes[WINTYPE_DROPDOWN_MENU] = XInternAtom(ps->dpy,
|
2012-09-25 10:19:20 +08:00
|
|
|
"_NET_WM_WINDOW_TYPE_DROPDOWN_MENU", False);
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->atoms_wintypes[WINTYPE_POPUP_MENU] = XInternAtom(ps->dpy,
|
2012-09-25 10:19:20 +08:00
|
|
|
"_NET_WM_WINDOW_TYPE_POPUP_MENU", False);
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->atoms_wintypes[WINTYPE_TOOLTIP] = XInternAtom(ps->dpy,
|
2012-09-25 10:19:20 +08:00
|
|
|
"_NET_WM_WINDOW_TYPE_TOOLTIP", False);
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->atoms_wintypes[WINTYPE_NOTIFY] = XInternAtom(ps->dpy,
|
2012-09-25 10:19:20 +08:00
|
|
|
"_NET_WM_WINDOW_TYPE_NOTIFICATION", False);
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->atoms_wintypes[WINTYPE_COMBO] = XInternAtom(ps->dpy,
|
2012-09-25 10:19:20 +08:00
|
|
|
"_NET_WM_WINDOW_TYPE_COMBO", False);
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->atoms_wintypes[WINTYPE_DND] = XInternAtom(ps->dpy,
|
2012-09-25 10:19:20 +08:00
|
|
|
"_NET_WM_WINDOW_TYPE_DND", False);
|
|
|
|
}
|
|
|
|
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
/**
|
|
|
|
* Update refresh rate info with X Randr extension.
|
|
|
|
*/
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
update_refresh_rate(session_t *ps) {
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
XRRScreenConfiguration* randr_info;
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!(randr_info = XRRGetScreenInfo(ps->dpy, ps->root)))
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
return;
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->refresh_rate = XRRConfigCurrentRate(randr_info);
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
|
|
|
|
XRRFreeScreenConfigInfo(randr_info);
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->refresh_rate)
|
|
|
|
ps->refresh_intv = NS_PER_SEC / ps->refresh_rate;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
else
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->refresh_intv = 0;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2012-10-26 11:12:28 +08:00
|
|
|
* Initialize refresh-rated based software optimization.
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
*
|
2012-11-19 09:46:07 +08:00
|
|
|
* @return true for success, false otherwise
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
*/
|
2012-11-19 09:46:07 +08:00
|
|
|
static bool
|
|
|
|
sw_opti_init(session_t *ps) {
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
// Prepare refresh rate
|
|
|
|
// Check if user provides one
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->refresh_rate = ps->o.refresh_rate;
|
|
|
|
if (ps->refresh_rate)
|
|
|
|
ps->refresh_intv = NS_PER_SEC / ps->refresh_rate;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
|
|
|
|
// Auto-detect refresh rate otherwise
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!ps->refresh_rate && ps->randr_exists) {
|
|
|
|
update_refresh_rate(ps);
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Turn off vsync_sw if we can't get the refresh rate
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!ps->refresh_rate)
|
|
|
|
return false;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
|
|
|
|
// Monitor screen changes only if vsync_sw is enabled and we are using
|
|
|
|
// an auto-detected refresh rate
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->randr_exists && !ps->o.refresh_rate)
|
|
|
|
XRRSelectInput(ps->dpy, ps->root, RRScreenChangeNotify);
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
return true;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the smaller number that is bigger than <code>dividend</code> and is
|
|
|
|
* N times of <code>divisor</code>.
|
|
|
|
*/
|
|
|
|
static inline long
|
|
|
|
lceil_ntimes(long dividend, long divisor) {
|
|
|
|
// It's possible to use the more beautiful expression here:
|
|
|
|
// ret = ((dividend - 1) / divisor + 1) * divisor;
|
|
|
|
// But it does not work well for negative values.
|
|
|
|
long ret = dividend / divisor * divisor;
|
|
|
|
if (ret < dividend)
|
|
|
|
ret += divisor;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2012-10-26 11:12:28 +08:00
|
|
|
* Wait for events until next paint.
|
|
|
|
*
|
|
|
|
* Optionally use refresh-rate based optimization to reduce painting.
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
*
|
2012-10-26 11:12:28 +08:00
|
|
|
* @param fd struct pollfd used for poll()
|
|
|
|
* @param timeout second timeout (fading timeout)
|
|
|
|
* @return > 0 if we get some events, 0 if timeout is reached, < 0 on
|
|
|
|
* problems
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
*/
|
2012-10-26 11:12:28 +08:00
|
|
|
static int
|
2012-11-19 09:46:07 +08:00
|
|
|
evpoll(session_t *ps, int timeout) {
|
|
|
|
struct pollfd ufd = {
|
|
|
|
.fd = ConnectionNumber(ps->dpy),
|
|
|
|
.events = POLLIN
|
|
|
|
};
|
|
|
|
|
2012-10-26 11:12:28 +08:00
|
|
|
// Always wait infinitely if asked so, to minimize CPU usage
|
|
|
|
if (timeout < 0) {
|
2012-11-19 09:46:07 +08:00
|
|
|
int ret = poll(&ufd, 1, timeout);
|
|
|
|
// Reset ps->fade_time so the fading steps during idling are not counted
|
|
|
|
ps->fade_time = get_time_ms();
|
2012-10-26 11:12:28 +08:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Just do a poll() if we are not using optimization
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!ps->o.sw_opti)
|
|
|
|
return poll(&ufd, 1, timeout);
|
2012-10-26 11:12:28 +08:00
|
|
|
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
// Convert the old timeout to struct timespec
|
|
|
|
struct timespec next_paint_tmout = {
|
|
|
|
.tv_sec = timeout / MS_PER_SEC,
|
|
|
|
.tv_nsec = timeout % MS_PER_SEC * (NS_PER_SEC / MS_PER_SEC)
|
|
|
|
};
|
2012-10-26 11:12:28 +08:00
|
|
|
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
// Get the nanosecond offset of the time when the we reach the timeout
|
|
|
|
// I don't think a 32-bit long could overflow here.
|
2012-11-19 09:46:07 +08:00
|
|
|
long target_relative_offset = (next_paint_tmout.tv_nsec + get_time_timespec().tv_nsec - ps->paint_tm_offset) % NS_PER_SEC;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
if (target_relative_offset < 0)
|
|
|
|
target_relative_offset += NS_PER_SEC;
|
|
|
|
|
|
|
|
assert(target_relative_offset >= 0);
|
|
|
|
|
2012-10-26 11:12:28 +08:00
|
|
|
// If the target time is sufficiently close to a refresh time, don't add
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
// an offset, to avoid certain blocking conditions.
|
2012-10-26 11:12:28 +08:00
|
|
|
if ((target_relative_offset % NS_PER_SEC) < SW_OPTI_TOLERANCE)
|
2012-11-19 09:46:07 +08:00
|
|
|
return poll(&ufd, 1, timeout);
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
|
2012-10-26 11:12:28 +08:00
|
|
|
// Add an offset so we wait until the next refresh after timeout
|
2012-11-19 09:46:07 +08:00
|
|
|
next_paint_tmout.tv_nsec += lceil_ntimes(target_relative_offset, ps->refresh_intv) - target_relative_offset;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
if (next_paint_tmout.tv_nsec > NS_PER_SEC) {
|
|
|
|
next_paint_tmout.tv_nsec -= NS_PER_SEC;
|
|
|
|
++next_paint_tmout.tv_sec;
|
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
return ppoll(&ufd, 1, &next_paint_tmout, NULL);
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Initialize DRM VSync.
|
|
|
|
*
|
2012-11-19 09:46:07 +08:00
|
|
|
* @return true for success, false otherwise
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
*/
|
2012-11-19 09:46:07 +08:00
|
|
|
static bool
|
|
|
|
vsync_drm_init(session_t *ps) {
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
#ifdef CONFIG_VSYNC_DRM
|
|
|
|
// Should we always open card0?
|
2012-11-19 09:46:07 +08:00
|
|
|
if ((ps->drm_fd = open("/dev/dri/card0", O_RDWR)) < 0) {
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
fprintf(stderr, "vsync_drm_init(): Failed to open device.\n");
|
2012-11-19 09:46:07 +08:00
|
|
|
return false;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (vsync_drm_wait(ps))
|
|
|
|
return false;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
return true;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
#else
|
|
|
|
fprintf(stderr, "Program not compiled with DRM VSync support.\n");
|
2012-11-19 09:46:07 +08:00
|
|
|
return false;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef CONFIG_VSYNC_DRM
|
|
|
|
/**
|
|
|
|
* Wait for next VSync, DRM method.
|
|
|
|
*
|
|
|
|
* Stolen from: https://github.com/MythTV/mythtv/blob/master/mythtv/libs/libmythtv/vsync.cpp
|
|
|
|
*/
|
|
|
|
static int
|
2012-11-19 09:46:07 +08:00
|
|
|
vsync_drm_wait(session_t *ps) {
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
int ret = -1;
|
|
|
|
drm_wait_vblank_t vbl;
|
|
|
|
|
|
|
|
vbl.request.type = _DRM_VBLANK_RELATIVE,
|
|
|
|
vbl.request.sequence = 1;
|
|
|
|
|
|
|
|
do {
|
2012-11-19 09:46:07 +08:00
|
|
|
ret = ioctl(ps->drm_fd, DRM_IOCTL_WAIT_VBLANK, &vbl);
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
vbl.request.type &= ~_DRM_VBLANK_RELATIVE;
|
|
|
|
} while (ret && errno == EINTR);
|
|
|
|
|
|
|
|
if (ret)
|
|
|
|
fprintf(stderr, "vsync_drm_wait(): VBlank ioctl did not work, "
|
|
|
|
"unimplemented in this drmver?\n");
|
|
|
|
|
|
|
|
return ret;
|
2012-11-19 09:46:07 +08:00
|
|
|
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Initialize OpenGL VSync.
|
|
|
|
*
|
|
|
|
* Stolen from: http://git.tuxfamily.org/?p=ccm/cairocompmgr.git;a=commitdiff;h=efa4ceb97da501e8630ca7f12c99b1dce853c73e
|
|
|
|
* Possible original source: http://www.inb.uni-luebeck.de/~boehme/xvideo_sync.html
|
|
|
|
*
|
2012-11-19 09:46:07 +08:00
|
|
|
* @return true for success, false otherwise
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
*/
|
2012-11-19 09:46:07 +08:00
|
|
|
static bool
|
|
|
|
vsync_opengl_init(session_t *ps) {
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
#ifdef CONFIG_VSYNC_OPENGL
|
|
|
|
// Get video sync functions
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->glx_get_video_sync = (f_GetVideoSync)
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
glXGetProcAddress ((const GLubyte *) "glXGetVideoSyncSGI");
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->glx_wait_video_sync = (f_WaitVideoSync)
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
glXGetProcAddress ((const GLubyte *) "glXWaitVideoSyncSGI");
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!ps->glx_wait_video_sync || !ps->glx_get_video_sync) {
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
fprintf(stderr, "vsync_opengl_init(): "
|
|
|
|
"Failed to get glXWait/GetVideoSyncSGI function.\n");
|
2012-11-19 09:46:07 +08:00
|
|
|
return false;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
}
|
2012-11-19 09:46:07 +08:00
|
|
|
|
|
|
|
return true;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
#else
|
|
|
|
fprintf(stderr, "Program not compiled with OpenGL VSync support.\n");
|
2012-11-19 09:46:07 +08:00
|
|
|
return false;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef CONFIG_VSYNC_OPENGL
|
|
|
|
/**
|
|
|
|
* Wait for next VSync, OpenGL method.
|
|
|
|
*/
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
vsync_opengl_wait(session_t *ps) {
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
unsigned vblank_count;
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->glx_get_video_sync(&vblank_count);
|
|
|
|
ps->glx_wait_video_sync(2, (vblank_count + 1) % 2, &vblank_count);
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
// I see some code calling glXSwapIntervalSGI(1) afterwards, is it required?
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
2012-10-26 11:12:28 +08:00
|
|
|
* Wait for next VSync.
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
*/
|
2012-10-26 11:12:28 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
vsync_wait(session_t *ps) {
|
|
|
|
if (VSYNC_NONE == ps->o.vsync)
|
2012-10-26 11:12:28 +08:00
|
|
|
return;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
|
|
|
|
#ifdef CONFIG_VSYNC_DRM
|
2012-11-19 09:46:07 +08:00
|
|
|
if (VSYNC_DRM == ps->o.vsync) {
|
|
|
|
vsync_drm_wait(ps);
|
2012-10-26 11:12:28 +08:00
|
|
|
return;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef CONFIG_VSYNC_OPENGL
|
2012-11-19 09:46:07 +08:00
|
|
|
if (VSYNC_OPENGL == ps->o.vsync) {
|
|
|
|
vsync_opengl_wait(ps);
|
2012-10-26 11:12:28 +08:00
|
|
|
return;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// This place should not reached!
|
2012-10-10 21:12:46 +08:00
|
|
|
assert(0);
|
|
|
|
|
2012-10-26 11:12:28 +08:00
|
|
|
return;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
}
|
|
|
|
|
2012-10-13 18:46:59 +08:00
|
|
|
/**
|
|
|
|
* Pregenerate alpha pictures.
|
|
|
|
*/
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
init_alpha_picts(session_t *ps) {
|
2012-10-13 18:46:59 +08:00
|
|
|
int i;
|
2012-11-19 09:46:07 +08:00
|
|
|
int num = lround(1.0 / ps->o.alpha_step) + 1;
|
2012-10-13 18:46:59 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->alpha_picts = malloc(sizeof(Picture) * num);
|
2012-10-13 18:46:59 +08:00
|
|
|
|
|
|
|
for (i = 0; i < num; ++i) {
|
2012-11-19 09:46:07 +08:00
|
|
|
double o = i * ps->o.alpha_step;
|
|
|
|
if ((1.0 - o) > ps->o.alpha_step)
|
|
|
|
ps->alpha_picts[i] = solid_picture(ps, false, o, 0, 0, 0);
|
2012-10-13 18:46:59 +08:00
|
|
|
else
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->alpha_picts[i] = None;
|
2012-10-13 18:46:59 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-10-23 13:42:20 +08:00
|
|
|
/**
|
|
|
|
* Initialize double buffer.
|
|
|
|
*/
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
init_dbe(session_t *ps) {
|
|
|
|
if (!(ps->root_dbe = XdbeAllocateBackBufferName(ps->dpy,
|
|
|
|
(ps->o.paint_on_overlay ? ps->overlay: ps->root), XdbeCopied))) {
|
2012-10-23 13:42:20 +08:00
|
|
|
fprintf(stderr, "Failed to create double buffer. Double buffering "
|
|
|
|
"turned off.\n");
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.dbe = false;
|
2012-10-23 13:42:20 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-10-24 10:09:59 +08:00
|
|
|
/**
|
|
|
|
* Initialize X composite overlay window.
|
|
|
|
*/
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
init_overlay(session_t *ps) {
|
|
|
|
ps->overlay = XCompositeGetOverlayWindow(ps->dpy, ps->root);
|
|
|
|
if (ps->overlay) {
|
2012-10-24 10:09:59 +08:00
|
|
|
// Set window region of the overlay window, code stolen from
|
|
|
|
// compiz-0.8.8
|
2012-11-19 09:46:07 +08:00
|
|
|
XserverRegion region = XFixesCreateRegion(ps->dpy, NULL, 0);
|
|
|
|
XFixesSetWindowShapeRegion(ps->dpy, ps->overlay, ShapeBounding, 0, 0, 0);
|
|
|
|
XFixesSetWindowShapeRegion(ps->dpy, ps->overlay, ShapeInput, 0, 0, region);
|
|
|
|
XFixesDestroyRegion(ps->dpy, region);
|
2012-10-24 10:09:59 +08:00
|
|
|
|
2012-10-29 22:00:11 +08:00
|
|
|
// Listen to Expose events on the overlay
|
2012-11-19 09:46:07 +08:00
|
|
|
XSelectInput(ps->dpy, ps->overlay, ExposureMask);
|
2012-10-29 22:00:11 +08:00
|
|
|
|
2012-10-24 10:09:59 +08:00
|
|
|
// Retrieve DamageNotify on root window if we are painting on an
|
|
|
|
// overlay
|
2012-11-19 09:46:07 +08:00
|
|
|
// root_damage = XDamageCreate(ps->dpy, root, XDamageReportNonEmpty);
|
2012-10-24 10:09:59 +08:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
fprintf(stderr, "Cannot get X Composite overlay window. Falling "
|
|
|
|
"back to painting on root window.\n");
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.paint_on_overlay = false;
|
2012-10-24 10:09:59 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-09 21:44:02 +08:00
|
|
|
/**
|
|
|
|
* Redirect all windows.
|
|
|
|
*/
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
redir_start(session_t *ps) {
|
|
|
|
if (!ps->redirected) {
|
2012-11-09 21:44:02 +08:00
|
|
|
#ifdef DEBUG_REDIR
|
|
|
|
printf("redir_start(): Screen redirected.\n");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Map overlay window. Done firstly according to this:
|
|
|
|
// https://bugzilla.gnome.org/show_bug.cgi?id=597014
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->overlay)
|
|
|
|
XMapWindow(ps->dpy, ps->overlay);
|
2012-11-09 21:44:02 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
XCompositeRedirectSubwindows(ps->dpy, ps->root, CompositeRedirectManual);
|
2012-11-09 21:44:02 +08:00
|
|
|
|
|
|
|
// Must call XSync() here
|
2012-11-19 09:46:07 +08:00
|
|
|
XSync(ps->dpy, False);
|
2012-11-09 21:44:02 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->redirected = true;
|
2012-11-09 21:44:02 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Unredirect all windows.
|
|
|
|
*/
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
redir_stop(session_t *ps) {
|
|
|
|
if (ps->redirected) {
|
2012-11-09 21:44:02 +08:00
|
|
|
#ifdef DEBUG_REDIR
|
|
|
|
printf("redir_stop(): Screen unredirected.\n");
|
|
|
|
#endif
|
|
|
|
// Destroy all Pictures as they expire once windows are unredirected
|
|
|
|
// If we don't destroy them here, looks like the resources are just
|
|
|
|
// kept inaccessible somehow
|
2012-11-19 09:46:07 +08:00
|
|
|
for (win *w = ps->list; w; w = w->next) {
|
|
|
|
free_pixmap(ps, &w->pixmap);
|
|
|
|
free_picture(ps, &w->picture);
|
2012-11-09 21:44:02 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
XCompositeUnredirectSubwindows(ps->dpy, ps->root, CompositeRedirectManual);
|
2012-11-09 21:44:02 +08:00
|
|
|
// Unmap overlay window
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->overlay)
|
|
|
|
XUnmapWindow(ps->dpy, ps->overlay);
|
2012-11-09 21:44:02 +08:00
|
|
|
|
|
|
|
// Must call XSync() here
|
2012-11-19 09:46:07 +08:00
|
|
|
XSync(ps->dpy, False);
|
2012-11-09 21:44:02 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->redirected = false;
|
2012-11-09 21:44:02 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* Initialize a session.
|
|
|
|
*
|
|
|
|
* @param ps_old old session, from which the function will take the X
|
|
|
|
* connection, then free it
|
|
|
|
* @param argc number of commandline arguments
|
|
|
|
* @param argv commandline arguments
|
|
|
|
*/
|
|
|
|
static session_t *
|
|
|
|
session_init(session_t *ps_old, int argc, char **argv) {
|
|
|
|
const static session_t s_def = {
|
|
|
|
.dpy = NULL,
|
|
|
|
.scr = 0,
|
|
|
|
.vis = NULL,
|
|
|
|
.depth = 0,
|
|
|
|
.root = None,
|
|
|
|
.root_height = 0,
|
|
|
|
.root_width = 0,
|
|
|
|
// .root_damage = None,
|
|
|
|
.overlay = None,
|
|
|
|
.root_tile = None,
|
|
|
|
.screen_reg = None,
|
|
|
|
.tgt_picture = None,
|
|
|
|
.tgt_buffer = None,
|
|
|
|
.root_dbe = None,
|
|
|
|
.reg_win = None,
|
|
|
|
.o = {
|
|
|
|
.display = NULL,
|
|
|
|
.mark_wmwin_focused = false,
|
|
|
|
.mark_ovredir_focused = false,
|
|
|
|
.fork_after_register = false,
|
|
|
|
.synchronize = false,
|
|
|
|
.detect_rounded_corners = false,
|
|
|
|
.paint_on_overlay = false,
|
|
|
|
.unredir_if_possible = false,
|
|
|
|
|
|
|
|
.refresh_rate = 0,
|
|
|
|
.sw_opti = false,
|
|
|
|
.vsync = VSYNC_NONE,
|
|
|
|
.dbe = false,
|
|
|
|
.vsync_aggressive = false,
|
|
|
|
|
|
|
|
.wintype_shadow = { false },
|
|
|
|
.shadow_red = 0.0,
|
|
|
|
.shadow_green = 0.0,
|
|
|
|
.shadow_blue = 0.0,
|
|
|
|
.shadow_radius = 12,
|
|
|
|
.shadow_offset_x = -15,
|
|
|
|
.shadow_offset_y = -15,
|
|
|
|
.shadow_opacity = .75,
|
|
|
|
.clear_shadow = false,
|
|
|
|
.shadow_blacklist = NULL,
|
|
|
|
.shadow_ignore_shaped = false,
|
|
|
|
.respect_prop_shadow = false,
|
|
|
|
|
|
|
|
.wintype_fade = { false },
|
|
|
|
.fade_in_step = 0.028 * OPAQUE,
|
|
|
|
.fade_out_step = 0.03 * OPAQUE,
|
|
|
|
.fade_delta = 10,
|
|
|
|
.no_fading_openclose = false,
|
|
|
|
.fade_blacklist = NULL,
|
|
|
|
|
|
|
|
.wintype_opacity = { 0.0 },
|
|
|
|
.inactive_opacity = 0,
|
|
|
|
.inactive_opacity_override = false,
|
|
|
|
.frame_opacity = 0.0,
|
|
|
|
.detect_client_opacity = false,
|
|
|
|
.inactive_dim = 0.0,
|
|
|
|
.alpha_step = 0.03,
|
|
|
|
.use_ewmh_active_win = false,
|
|
|
|
|
|
|
|
.track_focus = false,
|
|
|
|
.track_wdata = false,
|
|
|
|
},
|
|
|
|
|
|
|
|
.all_damage = None,
|
|
|
|
.time_start = { 0, 0 },
|
|
|
|
.redirected = false,
|
|
|
|
.unredir_possible = false,
|
|
|
|
.alpha_picts = NULL,
|
|
|
|
.reg_ignore_expire = false,
|
|
|
|
.idling = false,
|
|
|
|
.fade_time = 0,
|
|
|
|
.ignore_head = NULL,
|
|
|
|
.ignore_tail = NULL,
|
|
|
|
.reset = false,
|
|
|
|
|
|
|
|
.expose_rects = NULL,
|
|
|
|
.size_expose = 0,
|
|
|
|
.n_expose = 0,
|
|
|
|
|
|
|
|
.list = NULL,
|
|
|
|
.active_win = NULL,
|
|
|
|
.black_picture = None,
|
|
|
|
.dim_picture = None,
|
|
|
|
.cshadow_picture = None,
|
|
|
|
.gaussian_map = NULL,
|
|
|
|
.cgsize = 0,
|
|
|
|
.shadow_corner = NULL,
|
|
|
|
.shadow_top = NULL,
|
|
|
|
|
|
|
|
.refresh_rate = 0,
|
|
|
|
.refresh_intv = 0UL,
|
|
|
|
.paint_tm_offset = 0L,
|
|
|
|
|
|
|
|
.drm_fd = 0,
|
|
|
|
|
|
|
|
.glx_context = None,
|
|
|
|
.glx_get_video_sync = NULL,
|
|
|
|
.glx_wait_video_sync = NULL,
|
|
|
|
|
|
|
|
.xfixes_event = 0,
|
|
|
|
.xfixes_error = 0,
|
|
|
|
.damage_event = 0,
|
|
|
|
.damage_error = 0,
|
|
|
|
.render_event = 0,
|
|
|
|
.render_error = 0,
|
|
|
|
.composite_event = 0,
|
|
|
|
.composite_error = 0,
|
|
|
|
.composite_opcode = 0,
|
|
|
|
.has_name_pixmap = false,
|
|
|
|
.shape_exists = false,
|
|
|
|
.shape_event = 0,
|
|
|
|
.shape_error = 0,
|
|
|
|
.randr_exists = 0,
|
|
|
|
.randr_event = 0,
|
|
|
|
.randr_error = 0,
|
|
|
|
.glx_exists = false,
|
|
|
|
.glx_event = 0,
|
|
|
|
.glx_error = 0,
|
|
|
|
.dbe_exists = false,
|
|
|
|
|
|
|
|
.atom_opacity = None,
|
|
|
|
.atom_frame_extents = None,
|
|
|
|
.atom_client = None,
|
|
|
|
.atom_name = None,
|
|
|
|
.atom_name_ewmh = None,
|
|
|
|
.atom_class = None,
|
|
|
|
.atom_transient = None,
|
|
|
|
.atom_ewmh_active_win = None,
|
|
|
|
.atom_compton_shadow = None,
|
|
|
|
.atom_win_type = None,
|
|
|
|
.atoms_wintypes = { 0 }
|
|
|
|
};
|
2012-09-25 10:19:20 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
int i;
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
// Allocate a session and copy default values into it
|
|
|
|
session_t *ps = malloc(sizeof(session_t));
|
|
|
|
memcpy(ps, &s_def, sizeof(session_t));
|
|
|
|
ps_g = ps;
|
|
|
|
ps->ignore_tail = &ps->ignore_head;
|
|
|
|
gettimeofday(&ps->time_start, NULL);
|
|
|
|
|
|
|
|
get_cfg(ps, argc, argv);
|
|
|
|
|
|
|
|
// Inherit old Display if possible, primarily for resource leak checking
|
|
|
|
if (ps_old && ps_old->dpy)
|
|
|
|
ps->dpy = ps_old->dpy;
|
|
|
|
|
|
|
|
// Open Display
|
|
|
|
if (!ps->dpy) {
|
|
|
|
ps->dpy = XOpenDisplay(ps->o.display);
|
|
|
|
if (!ps->dpy) {
|
|
|
|
fprintf(stderr, "Can't open display\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2008-02-15 12:38:32 +08:00
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
XSetErrorHandler(error);
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.synchronize) {
|
|
|
|
XSynchronize(ps->dpy, 1);
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->scr = DefaultScreen(ps->dpy);
|
|
|
|
ps->root = RootWindow(ps->dpy, ps->scr);
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->vis = DefaultVisual(ps->dpy, ps->scr);
|
|
|
|
ps->depth = DefaultDepth(ps->dpy, ps->scr);
|
|
|
|
|
|
|
|
if (!XRenderQueryExtension(ps->dpy,
|
|
|
|
&ps->render_event, &ps->render_error)) {
|
2011-11-04 14:33:23 +08:00
|
|
|
fprintf(stderr, "No render extension\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!XQueryExtension(ps->dpy, COMPOSITE_NAME, &ps->composite_opcode,
|
|
|
|
&ps->composite_event, &ps->composite_error)) {
|
2011-11-04 14:33:23 +08:00
|
|
|
fprintf(stderr, "No composite extension\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
{
|
|
|
|
int composite_major = 0, composite_minor = 0;
|
|
|
|
|
|
|
|
XCompositeQueryVersion(ps->dpy, &composite_major, &composite_minor);
|
2003-11-25 01:11:00 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (composite_major > 0 || composite_minor >= 2) {
|
|
|
|
ps->has_name_pixmap = true;
|
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
2004-06-27 12:48:37 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!XDamageQueryExtension(ps->dpy, &ps->damage_event, &ps->damage_error)) {
|
2011-11-04 14:33:23 +08:00
|
|
|
fprintf(stderr, "No damage extension\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!XFixesQueryExtension(ps->dpy, &ps->xfixes_event, &ps->xfixes_error)) {
|
2011-11-04 14:33:23 +08:00
|
|
|
fprintf(stderr, "No XFixes extension\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
// Query X Shape
|
2012-11-19 09:46:07 +08:00
|
|
|
if (XShapeQueryExtension(ps->dpy, &ps->shape_event, &ps->shape_error)) {
|
|
|
|
ps->shape_exists = true;
|
2012-09-13 13:58:05 +08:00
|
|
|
}
|
2012-09-11 21:33:03 +08:00
|
|
|
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
// Query X RandR
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.sw_opti && !ps->o.refresh_rate) {
|
|
|
|
if (XRRQueryExtension(ps->dpy, &ps->randr_event, &ps->randr_error))
|
|
|
|
ps->randr_exists = true;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
else
|
|
|
|
fprintf(stderr, "No XRandR extension, automatic refresh rate "
|
|
|
|
"detection impossible.\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef CONFIG_VSYNC_OPENGL
|
|
|
|
// Query X GLX extension
|
2012-11-19 09:46:07 +08:00
|
|
|
if (VSYNC_OPENGL == ps->o.vsync) {
|
|
|
|
if (glXQueryExtension(ps->dpy, &ps->glx_event, &ps->glx_error))
|
|
|
|
ps->glx_exists = true;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
else {
|
|
|
|
fprintf(stderr, "No GLX extension, OpenGL VSync impossible.\n");
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.vsync = VSYNC_NONE;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2012-10-23 13:42:20 +08:00
|
|
|
// Query X DBE extension
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.dbe) {
|
2012-10-23 13:42:20 +08:00
|
|
|
int dbe_ver_major = 0, dbe_ver_minor = 0;
|
2012-11-19 09:46:07 +08:00
|
|
|
if (XdbeQueryExtension(ps->dpy, &dbe_ver_major, &dbe_ver_minor))
|
2012-10-23 13:42:20 +08:00
|
|
|
if (dbe_ver_major >= 1)
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->dbe_exists = true;
|
2012-10-23 13:42:20 +08:00
|
|
|
else
|
|
|
|
fprintf(stderr, "DBE extension version too low. Double buffering "
|
|
|
|
"impossible.\n");
|
|
|
|
else {
|
|
|
|
fprintf(stderr, "No DBE extension. Double buffering impossible.\n");
|
|
|
|
}
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!ps->dbe_exists)
|
|
|
|
ps->o.dbe = false;
|
2012-10-23 13:42:20 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
register_cm(ps, (VSYNC_OPENGL == ps->o.vsync));
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
|
2012-10-26 11:12:28 +08:00
|
|
|
// Initialize software optimization
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.sw_opti)
|
|
|
|
ps->o.sw_opti = sw_opti_init(ps);
|
2012-10-26 11:12:28 +08:00
|
|
|
|
|
|
|
// Initialize DRM/OpenGL VSync
|
2012-11-19 09:46:07 +08:00
|
|
|
if ((VSYNC_DRM == ps->o.vsync && !vsync_drm_init(ps))
|
|
|
|
|| (VSYNC_OPENGL == ps->o.vsync && !vsync_opengl_init(ps)))
|
|
|
|
ps->o.vsync = VSYNC_NONE;
|
2012-02-27 12:00:12 +08:00
|
|
|
|
2012-10-24 10:09:59 +08:00
|
|
|
// Overlay must be initialized before double buffer
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.paint_on_overlay)
|
|
|
|
init_overlay(ps);
|
2012-10-24 10:09:59 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.dbe)
|
|
|
|
init_dbe(ps);
|
2012-10-23 13:42:20 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.fork_after_register) fork_after();
|
2012-02-27 12:00:12 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
init_atoms(ps);
|
|
|
|
init_alpha_picts(ps);
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->gaussian_map = make_gaussian_map(ps->o.shadow_radius);
|
|
|
|
presum_gaussian(ps, ps->gaussian_map);
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->root_width = DisplayWidth(ps->dpy, ps->scr);
|
|
|
|
ps->root_height = DisplayHeight(ps->dpy, ps->scr);
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
rebuild_screen_reg(ps);
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
{
|
|
|
|
XRenderPictureAttributes pa;
|
|
|
|
pa.subwindow_mode = IncludeInferiors;
|
2012-11-03 10:30:32 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->root_picture = XRenderCreatePicture(ps->dpy, ps->root,
|
|
|
|
XRenderFindVisualFormat(ps->dpy, ps->vis),
|
2012-10-24 10:09:59 +08:00
|
|
|
CPSubwindowMode, &pa);
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.paint_on_overlay) {
|
|
|
|
ps->tgt_picture = XRenderCreatePicture(ps->dpy, ps->overlay,
|
|
|
|
XRenderFindVisualFormat(ps->dpy, ps->vis),
|
|
|
|
CPSubwindowMode, &pa);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
ps->tgt_picture = ps->root_picture;
|
|
|
|
}
|
2012-10-24 10:09:59 +08:00
|
|
|
}
|
2012-02-27 12:00:12 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->black_picture = solid_picture(ps, true, 1, 0, 0, 0);
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-09-11 21:57:50 +08:00
|
|
|
// Generates another Picture for shadows if the color is modified by
|
|
|
|
// user
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!ps->o.shadow_red && !ps->o.shadow_green && !ps->o.shadow_blue) {
|
|
|
|
ps->cshadow_picture = ps->black_picture;
|
2012-09-13 13:58:05 +08:00
|
|
|
} else {
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->cshadow_picture = solid_picture(ps, true, 1,
|
|
|
|
ps->o.shadow_red, ps->o.shadow_green, ps->o.shadow_blue);
|
2012-09-13 13:58:05 +08:00
|
|
|
}
|
2012-09-11 21:57:50 +08:00
|
|
|
|
2012-09-26 18:54:35 +08:00
|
|
|
// Generates a picture for inactive_dim
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.inactive_dim) {
|
|
|
|
ps->dim_picture = solid_picture(ps, true, ps->o.inactive_dim, 0, 0, 0);
|
2012-09-13 13:58:05 +08:00
|
|
|
}
|
2012-09-12 10:52:52 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->all_damage = None;
|
|
|
|
XGrabServer(ps->dpy);
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
redir_start(ps);
|
2011-11-04 17:18:10 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
XSelectInput(ps->dpy, ps->root,
|
2011-11-04 17:18:10 +08:00
|
|
|
SubstructureNotifyMask
|
|
|
|
| ExposureMask
|
|
|
|
| StructureNotifyMask
|
|
|
|
| PropertyChangeMask);
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
{
|
|
|
|
Window root_return, parent_return;
|
|
|
|
Window *children;
|
|
|
|
unsigned int nchildren;
|
|
|
|
|
|
|
|
XQueryTree(ps->dpy, ps->root, &root_return,
|
|
|
|
&parent_return, &children, &nchildren);
|
|
|
|
|
|
|
|
for (i = 0; i < nchildren; i++) {
|
|
|
|
add_win(ps, children[i], i ? children[i-1] : None, false);
|
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
XFree(children);
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
|
|
|
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.track_focus) {
|
|
|
|
recheck_focus(ps);
|
2012-09-13 23:12:54 +08:00
|
|
|
}
|
2012-09-13 21:38:55 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
XUngrabServer(ps->dpy);
|
|
|
|
|
|
|
|
// Free the old session
|
|
|
|
if (ps_old)
|
|
|
|
free(ps_old);
|
|
|
|
|
|
|
|
return ps;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Destroy a session.
|
|
|
|
*
|
|
|
|
* Does not close the X connection or free the <code>session_t</code>
|
|
|
|
* structure, though.
|
|
|
|
*
|
|
|
|
* @param ps session to destroy
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
session_destroy(session_t *ps) {
|
|
|
|
redir_stop(ps);
|
|
|
|
|
|
|
|
// Stop listening to events on root window
|
|
|
|
XSelectInput(ps->dpy, ps->root, 0);
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
// Free window linked list
|
|
|
|
{
|
|
|
|
win *next = NULL;
|
|
|
|
for (win *w = ps->list; w; w = next) {
|
|
|
|
// Must be put here to avoid segfault
|
|
|
|
next = w->next;
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (IsViewable == w->a.map_state && !w->destroyed)
|
|
|
|
win_ev_stop(ps, w);
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
free_win_res(ps, w);
|
|
|
|
free(w);
|
|
|
|
}
|
2012-10-21 20:44:24 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->list = NULL;
|
|
|
|
}
|
2012-11-08 19:39:13 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
// Free alpha_picts
|
|
|
|
{
|
|
|
|
const int max = lround(1.0 / ps->o.alpha_step) + 1;
|
|
|
|
for (int i = 0; i < max; ++i)
|
|
|
|
free_picture(ps, &ps->alpha_picts[i]);
|
|
|
|
free(ps->alpha_picts);
|
|
|
|
ps->alpha_picts = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Free blacklists
|
|
|
|
free_wincondlst(&ps->o.shadow_blacklist);
|
|
|
|
free_wincondlst(&ps->o.fade_blacklist);
|
|
|
|
|
|
|
|
// Free ignore linked list
|
|
|
|
{
|
|
|
|
ignore_t *next = NULL;
|
|
|
|
for (ignore_t *ign = ps->ignore_head; ign; ign = next) {
|
|
|
|
next = ign->next;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
free(ign);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reset head and tail
|
|
|
|
ps->ignore_head = NULL;
|
|
|
|
ps->ignore_tail = &ps->ignore_head;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Free cshadow_picture and black_picture
|
|
|
|
if (ps->cshadow_picture == ps->black_picture)
|
|
|
|
ps->cshadow_picture = None;
|
|
|
|
else
|
|
|
|
free_picture(ps, &ps->cshadow_picture);
|
|
|
|
|
|
|
|
free_picture(ps, &ps->black_picture);
|
|
|
|
|
|
|
|
// Free tgt_{buffer,picture} and root_picture
|
|
|
|
if (ps->tgt_buffer == ps->tgt_picture)
|
|
|
|
ps->tgt_buffer = None;
|
|
|
|
else
|
|
|
|
free_picture(ps, &ps->tgt_buffer);
|
|
|
|
|
|
|
|
if (ps->tgt_picture == ps->root_picture)
|
|
|
|
ps->tgt_picture = None;
|
|
|
|
else
|
|
|
|
free_picture(ps, &ps->tgt_picture);
|
|
|
|
|
|
|
|
free_picture(ps, &ps->root_picture);
|
|
|
|
|
|
|
|
// Free other X resources
|
|
|
|
free_picture(ps, &ps->dim_picture);
|
|
|
|
free_picture(ps, &ps->root_tile);
|
|
|
|
free_region(ps, &ps->screen_reg);
|
|
|
|
free_region(ps, &ps->all_damage);
|
|
|
|
free(ps->expose_rects);
|
|
|
|
free(ps->shadow_corner);
|
|
|
|
free(ps->shadow_top);
|
|
|
|
free(ps->gaussian_map);
|
|
|
|
free(ps->o.display);
|
|
|
|
|
|
|
|
// Free reg_win and glx_context
|
|
|
|
if (ps->reg_win) {
|
|
|
|
XDestroyWindow(ps->dpy, ps->reg_win);
|
|
|
|
ps->reg_win = None;
|
|
|
|
}
|
|
|
|
if (ps->glx_context) {
|
|
|
|
glXDestroyContext(ps->dpy, ps->glx_context);
|
|
|
|
ps->glx_context = None;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Free double buffer
|
|
|
|
if (ps->root_dbe) {
|
|
|
|
XdbeDeallocateBackBufferName(ps->dpy, ps->root_dbe);
|
|
|
|
ps->root_dbe = None;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Close file opened for DRM VSync
|
|
|
|
if (ps->drm_fd) {
|
|
|
|
close(ps->drm_fd);
|
|
|
|
ps->drm_fd = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Release overlay window
|
|
|
|
if (ps->overlay) {
|
|
|
|
XCompositeReleaseOverlayWindow(ps->dpy, ps->overlay);
|
|
|
|
ps->overlay = None;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Flush all events
|
|
|
|
XSync(ps->dpy, True);
|
|
|
|
|
|
|
|
if (ps == ps_g)
|
|
|
|
ps_g = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Do the actual work.
|
|
|
|
*
|
|
|
|
* @param ps current session
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
session_run(session_t *ps) {
|
|
|
|
win *t;
|
|
|
|
|
|
|
|
if (ps->o.sw_opti)
|
|
|
|
ps->paint_tm_offset = get_time_timespec().tv_nsec;
|
|
|
|
|
|
|
|
ps->reg_ignore_expire = true;
|
|
|
|
|
|
|
|
ps->fade_time = get_time_ms();
|
|
|
|
|
|
|
|
t = paint_preprocess(ps, ps->list);
|
|
|
|
|
|
|
|
if (ps->redirected)
|
|
|
|
paint_all(ps, None, t);
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-09-29 22:53:57 +08:00
|
|
|
// Initialize idling
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->idling = false;
|
2012-09-29 22:53:57 +08:00
|
|
|
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
// Main loop
|
2012-11-19 09:46:07 +08:00
|
|
|
while (!ps->reset) {
|
|
|
|
bool ev_received = false;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
while (XEventsQueued(ps->dpy, QueuedAfterReading)
|
|
|
|
|| (evpoll(ps,
|
|
|
|
(ev_received ? 0: (ps->idling ? -1: fade_timeout(ps)))) > 0)) {
|
2012-11-09 21:44:02 +08:00
|
|
|
// Sometimes poll() returns 1 but no events are actually read,
|
|
|
|
// causing XNextEvent() to block, I have no idea what's wrong, so we
|
|
|
|
// check for the number of events here
|
2012-11-19 09:46:07 +08:00
|
|
|
if (XEventsQueued(ps->dpy, QueuedAfterReading)) {
|
|
|
|
XEvent ev;
|
|
|
|
|
|
|
|
XNextEvent(ps->dpy, &ev);
|
|
|
|
ev_handle(ps, &ev);
|
|
|
|
ev_received = true;
|
2012-10-29 22:00:11 +08:00
|
|
|
}
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
}
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-09-29 22:53:57 +08:00
|
|
|
// idling will be turned off during paint_preprocess() if needed
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->idling = true;
|
2012-09-29 22:53:57 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
t = paint_preprocess(ps, ps->list);
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
|
2012-11-09 21:44:02 +08:00
|
|
|
// If the screen is unredirected, free all_damage to stop painting
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!ps->redirected)
|
|
|
|
free_region(ps, &ps->all_damage);
|
2012-11-09 21:44:02 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->all_damage && !is_region_empty(ps, ps->all_damage)) {
|
2011-11-04 16:41:56 +08:00
|
|
|
static int paint;
|
2012-11-19 09:46:07 +08:00
|
|
|
paint_all(ps, ps->all_damage, t);
|
|
|
|
ps->reg_ignore_expire = false;
|
2011-11-04 14:33:23 +08:00
|
|
|
paint++;
|
2012-11-19 09:46:07 +08:00
|
|
|
XSync(ps->dpy, False);
|
|
|
|
ps->all_damage = None;
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
|
|
|
}
|
2003-11-09 15:08:23 +08:00
|
|
|
}
|
2012-11-19 09:46:07 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Turn on the program reset flag.
|
|
|
|
*
|
|
|
|
* This will result in compton resetting itself after next paint.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
reset_enable(int __attribute__((unused)) signum) {
|
|
|
|
session_t * const ps = ps_g;
|
|
|
|
|
|
|
|
ps->reset = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The function that everybody knows.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
main(int argc, char **argv) {
|
|
|
|
// Set locale so window names with special characters are interpreted
|
|
|
|
// correctly
|
|
|
|
setlocale(LC_ALL, "");
|
|
|
|
|
|
|
|
// Set up SIGUSR1 signal handler to reset program
|
|
|
|
{
|
|
|
|
sigset_t block_mask;
|
|
|
|
sigemptyset(&block_mask);
|
|
|
|
const struct sigaction action= {
|
|
|
|
.sa_handler = reset_enable,
|
|
|
|
.sa_mask = block_mask,
|
|
|
|
.sa_flags = 0
|
|
|
|
};
|
|
|
|
sigaction(SIGUSR1, &action, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Main loop
|
|
|
|
session_t *ps_old = ps_g;
|
|
|
|
while (1) {
|
|
|
|
ps_g = session_init(ps_old, argc, argv);
|
|
|
|
session_run(ps_g);
|
|
|
|
ps_old = ps_g;
|
|
|
|
session_destroy(ps_g);
|
|
|
|
}
|
|
|
|
|
|
|
|
free(ps_g);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|