2012-02-27 12:00:12 +08:00
|
|
|
/**
|
|
|
|
* compton.h
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Throw everything in here.
|
|
|
|
|
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
|
|
|
|
|
|
|
// === Includes ===
|
|
|
|
|
Feature #80: D-Bus support
- Add D-Bus support. Currently 7 methods are available: "reset" (same as
SIGUSR1), "list_win" (list the windows compton manages), "win_get"
(get a property of the window), "win_set" (set a property of the
window), "find_win" (find window based on client window / focus),
"opts_get" (get the value of a compton option), and "opts_set" (set
the value of a compton option), together with 4 signals: "win_added",
"win_destroyed", "win_mapped", "win_unmapped".
- D-Bus support depends on libdbus.
- As there are many items and my time is tight, no much tests are done.
Bugs to be expected.
- Create a new header file `common.h` that contains shared content.
- Fix some bugs in timeout handling.
- Update file headers in all source files.
- Re-enable --unredir-if-possible on multi-screen set-ups, as the user
could turn if off manually anyway.
- Check if the window is mapped in `repair_win()`.
- Add ps->track_atom_lst and its handlers, to prepare for the new
condition format.
- Known issue 1: "win_get", "win_set", "opts_get", "opts_set" support a
very limited number of targets only. New ones will be added gradually.
- Known issue 2: Accidental drop of D-Bus connection is not handled.
- Known issue 3: Introspection does not reveal all available methods,
because some methods have unpredictable prototypes. Still hesitating
about what to do...
- Known issue 4: Error handling is not finished yet. Compton does not
always reply with the correct error message (but it does print out the
correct error message, usually).
2013-01-19 20:20:27 +08:00
|
|
|
#include "common.h"
|
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-08 18:31:39 +08:00
|
|
|
#include <math.h>
|
2013-01-11 21:31:02 +08:00
|
|
|
#include <sys/select.h>
|
|
|
|
#include <limits.h>
|
2012-02-08 18:31:39 +08:00
|
|
|
#include <unistd.h>
|
|
|
|
#include <getopt.h>
|
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
|
|
|
#include <locale.h>
|
2012-11-19 09:46:07 +08:00
|
|
|
#include <signal.h>
|
2012-09-25 10:19:20 +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
|
|
|
#ifdef CONFIG_VSYNC_DRM
|
|
|
|
#include <fcntl.h>
|
|
|
|
// We references some definitions in drm.h, which could also be found in
|
|
|
|
// /usr/src/linux/include/drm/drm.h, but that path is probably even less
|
|
|
|
// reliable than libdrm
|
2013-03-01 12:41:16 +08:00
|
|
|
#include <drm.h>
|
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
|
|
|
#include <sys/ioctl.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#endif
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
// == Functions ==
|
2012-02-27 12:00:12 +08:00
|
|
|
|
2012-09-11 21:57:50 +08:00
|
|
|
// inline functions must be made static to compile correctly under clang:
|
|
|
|
// http://clang.llvm.org/compatibility.html#inline
|
|
|
|
|
2012-09-16 23:12:02 +08:00
|
|
|
// Helper functions
|
|
|
|
|
2012-09-17 16:04:04 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
discard_ignore(session_t *ps, unsigned long sequence);
|
2012-09-17 16:04:04 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
set_ignore(session_t *ps, unsigned long sequence);
|
|
|
|
|
Improvement #74: Use libevent for main loop
- Use libevent for main loop. I will explain the reasons in #56 later.
The preferred libevent version is 2.x, yet 1.4.x should work as well.
- As a result, compton now should build fine on *BSD. Thanks to
DachiChang for the FreeBSD build issue report.
- Another consequence is we now use microsecond-level timing all the
way. Nanosecond-level code will be dropped soon. Start using long
instead of unsigned long to represent time in milliseconds, as both
can't hold the full epoch time in ms, anyway, and a signed type
requires less care in subtraction. Wrap the epoch time in ms to 15
days.
- Fix broken NO_VSYNC_DRM and NO_VSYNC_OPENGL compile-time options.
- Use git revision number for versioning in Makefile, and other small
improvements.
- Reorganize struct _win. Drop unused w->damaged_sequence. w->damaged is
turned to bool.
- Add type and format to winprop_t, as preparation for the new condition
format.
- Add w->shadow_force and w->focus_force, to prepare for D-Bus support.
- Rename wid_get_prop() to wid_get_prop_adv() with more options. Add
wrapper function wid_get_prop().
- Add some extra helper functions, for D-Bus support later.
- Make some functions return a bool value to indicate if it's
successful.
- Modify add_win(), use a static const structure to initialize the new
struct _win.
- Add some helper macros, like printf_err(f)(q). Make some errors fatal.
- Rename some types, constants, and functions. Code clean-up.
- Check for time disorder in paint_preprocess() when calculating fading
steps.
- Rename evpoll() to swopti_handle_timeout(), and partially rewrite it.
- Make -h / --help legal.
- Known issue: compton segfaults on FreeBSD with nvidia-drivers, unless
NO_VSYNC_OPENGL is used. Will look into it later. Thamls to DachiChang
for reporting.
2013-01-08 08:50:58 +08:00
|
|
|
/**
|
|
|
|
* Ignore X errors caused by next X request.
|
|
|
|
*/
|
2012-11-19 09:46:07 +08:00
|
|
|
static inline void
|
|
|
|
set_ignore_next(session_t *ps) {
|
|
|
|
set_ignore(ps, NextRequest(ps->dpy));
|
|
|
|
}
|
2012-09-17 16:04:04 +08:00
|
|
|
|
|
|
|
static int
|
2012-11-19 09:46:07 +08:00
|
|
|
should_ignore(session_t *ps, unsigned long sequence);
|
2012-09-17 16:04:04 +08:00
|
|
|
|
2012-12-14 20:32:46 +08:00
|
|
|
/**
|
|
|
|
* Reset filter on a <code>Picture</code>.
|
|
|
|
*/
|
|
|
|
static inline void
|
|
|
|
xrfilter_reset(session_t *ps, Picture p) {
|
|
|
|
XRenderSetPictureFilter(ps->dpy, p, "Nearest", NULL, 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
|
|
|
/**
|
|
|
|
* Subtract two unsigned long values.
|
|
|
|
*
|
|
|
|
* Truncate to 0 if the result is negative.
|
|
|
|
*/
|
2012-11-19 09:46:07 +08:00
|
|
|
static inline unsigned long __attribute__((const))
|
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
|
|
|
sub_unslong(unsigned long a, unsigned long b) {
|
|
|
|
return (a > b) ? a - b : 0;
|
|
|
|
}
|
|
|
|
|
2012-09-25 21:04:10 +08:00
|
|
|
/**
|
2012-11-19 09:46:07 +08:00
|
|
|
* Set a <code>bool</code> array of all wintypes to true.
|
2012-09-25 21:04:10 +08:00
|
|
|
*/
|
2012-12-10 10:31:24 +08:00
|
|
|
static inline void
|
2012-11-19 09:46:07 +08:00
|
|
|
wintype_arr_enable(bool arr[]) {
|
|
|
|
wintype_t i;
|
2012-09-25 21:04:10 +08:00
|
|
|
|
|
|
|
for (i = 0; i < NUM_WINTYPES; ++i) {
|
2012-11-19 09:46:07 +08:00
|
|
|
arr[i] = true;
|
2012-09-25 21:04:10 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-12-10 10:31:24 +08:00
|
|
|
/**
|
|
|
|
* Set a <code>switch_t</code> array of all unset wintypes to true.
|
|
|
|
*/
|
|
|
|
static inline void
|
|
|
|
wintype_arr_enable_unset(switch_t arr[]) {
|
|
|
|
wintype_t i;
|
|
|
|
|
|
|
|
for (i = 0; i < NUM_WINTYPES; ++i)
|
|
|
|
if (UNSET == arr[i])
|
|
|
|
arr[i] = ON;
|
|
|
|
}
|
|
|
|
|
2012-09-11 22:22:58 +08:00
|
|
|
/**
|
|
|
|
* Check if a window ID exists in an array of window IDs.
|
|
|
|
*
|
|
|
|
* @param arr the array of window IDs
|
|
|
|
* @param count amount of elements in the array
|
|
|
|
* @param wid window ID to search for
|
|
|
|
*/
|
2012-11-19 09:46:07 +08:00
|
|
|
static inline bool
|
2012-09-13 13:58:05 +08:00
|
|
|
array_wid_exists(const Window *arr, int count, Window wid) {
|
2012-09-11 22:22:58 +08:00
|
|
|
while (count--) {
|
2012-09-13 13:58:05 +08:00
|
|
|
if (arr[count] == wid) {
|
2012-11-19 09:46:07 +08:00
|
|
|
return true;
|
2012-09-13 13:58:05 +08:00
|
|
|
}
|
2012-09-11 22:22:58 +08:00
|
|
|
}
|
2012-09-13 13:39:43 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
return false;
|
2012-09-11 22:22:58 +08:00
|
|
|
}
|
2012-09-16 23:12:02 +08:00
|
|
|
|
2013-06-09 17:06:35 +08:00
|
|
|
/**
|
|
|
|
* Convert a geometry_t value to XRectangle.
|
|
|
|
*/
|
|
|
|
static inline XRectangle
|
|
|
|
geom_to_rect(session_t *ps, const geometry_t *src, const XRectangle *def) {
|
|
|
|
XRectangle rect_def = { .x = 0, .y = 0,
|
|
|
|
.width = ps->root_width, .height = ps->root_height };
|
|
|
|
if (!def) def = &rect_def;
|
|
|
|
|
|
|
|
XRectangle rect = { .x = src->x, .y = src->y,
|
|
|
|
.width = src->wid, .height = src->hei };
|
|
|
|
if (src->wid < 0) rect.width = def->width;
|
|
|
|
if (src->hei < 0) rect.height = def->height;
|
|
|
|
if (-1 == src->x) rect.x = def->x;
|
|
|
|
else if (src->x < 0) rect.x = ps->root_width + rect.x + 2 - rect.width;
|
|
|
|
if (-1 == src->y) rect.y = def->y;
|
|
|
|
else if (src->y < 0) rect.y = ps->root_height + rect.y + 2 - rect.height;
|
|
|
|
return rect;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert a XRectangle to a XServerRegion.
|
|
|
|
*/
|
|
|
|
static inline XserverRegion
|
|
|
|
rect_to_reg(session_t *ps, const XRectangle *src) {
|
|
|
|
if (!src) return None;
|
|
|
|
XRectangle bound = { .x = 0, .y = 0,
|
|
|
|
.width = ps->root_width, .height = ps->root_height };
|
|
|
|
XRectangle res = { };
|
|
|
|
rect_crop(&res, src, &bound);
|
|
|
|
if (res.width && res.height)
|
|
|
|
return XFixesCreateRegion(ps->dpy, &res, 1);
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
2012-09-16 23:12:02 +08:00
|
|
|
/**
|
|
|
|
* Destroy a <code>Picture</code>.
|
|
|
|
*/
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
free_picture(session_t *ps, Picture *p) {
|
2012-09-16 23:12:02 +08:00
|
|
|
if (*p) {
|
2012-11-19 09:46:07 +08:00
|
|
|
XRenderFreePicture(ps->dpy, *p);
|
2012-09-16 23:12:02 +08:00
|
|
|
*p = None;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Destroy a <code>Pixmap</code>.
|
|
|
|
*/
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
free_pixmap(session_t *ps, Pixmap *p) {
|
2012-09-16 23:12:02 +08:00
|
|
|
if (*p) {
|
2012-11-19 09:46:07 +08:00
|
|
|
XFreePixmap(ps->dpy, *p);
|
2012-09-16 23:12:02 +08:00
|
|
|
*p = None;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Destroy a <code>Damage</code>.
|
|
|
|
*/
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
free_damage(session_t *ps, Damage *p) {
|
2012-09-16 23:12:02 +08:00
|
|
|
if (*p) {
|
2012-09-17 16:04:04 +08:00
|
|
|
// BadDamage will be thrown if the window is destroyed
|
2012-11-19 09:46:07 +08:00
|
|
|
set_ignore_next(ps);
|
|
|
|
XDamageDestroy(ps->dpy, *p);
|
2012-09-16 23:12:02 +08:00
|
|
|
*p = None;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
Feature #16: Advanced window matching
- Add advanced window matching system, capable of matching against
arbitrary window properties as well as a series of internal
properties, with 4 additional operators (>, <, >=, <=) useful for
integer targets, and support of logical operators. The old matching
system is removed, but compatibility with the format is retained.
- As the new matching system is pretty complicated, and I have no past
experience in writing a parser, it's pretty possible that bugs are
present. It also has inferior performance, but I hope it doesn't
matter on modern CPUs.
- It's possible to disable matching system at compile time with NO_C2=1
now.
- Add ps->o.config_file to track which config file we have actually
read. Queryable via D-Bus.
- Parse -d in first pass in get_cfg() as c2 needs to query X to get
atoms during condition parsing.
- Fix a bug in wid_get_prop_adv() that 0 == rformat is not handled
correctly.
- Fix incompatibility with FreeBSD sed in dbus-examples/cdbus-driver.sh
.
- Add recipe to generate .clang_complete in Makefile, used by Vim
clang_complete plugin.
- Add DEBUG_C2 for debugging condition string parsing. DEBUG_WINMATCH is
still used for match debugging.
- Rename win_on_wdata_change() to win_on_factor_change().
- Extra malloc() failure checks. Add const to matching cache members in
session_t. Code clean-up. Documentation update.
2013-01-28 21:39:38 +08:00
|
|
|
* Destroy a condition list.
|
2012-11-19 09:46:07 +08:00
|
|
|
*/
|
Feature #16: Advanced window matching
- Add advanced window matching system, capable of matching against
arbitrary window properties as well as a series of internal
properties, with 4 additional operators (>, <, >=, <=) useful for
integer targets, and support of logical operators. The old matching
system is removed, but compatibility with the format is retained.
- As the new matching system is pretty complicated, and I have no past
experience in writing a parser, it's pretty possible that bugs are
present. It also has inferior performance, but I hope it doesn't
matter on modern CPUs.
- It's possible to disable matching system at compile time with NO_C2=1
now.
- Add ps->o.config_file to track which config file we have actually
read. Queryable via D-Bus.
- Parse -d in first pass in get_cfg() as c2 needs to query X to get
atoms during condition parsing.
- Fix a bug in wid_get_prop_adv() that 0 == rformat is not handled
correctly.
- Fix incompatibility with FreeBSD sed in dbus-examples/cdbus-driver.sh
.
- Add recipe to generate .clang_complete in Makefile, used by Vim
clang_complete plugin.
- Add DEBUG_C2 for debugging condition string parsing. DEBUG_WINMATCH is
still used for match debugging.
- Rename win_on_wdata_change() to win_on_factor_change().
- Extra malloc() failure checks. Add const to matching cache members in
session_t. Code clean-up. Documentation update.
2013-01-28 21:39:38 +08:00
|
|
|
static inline void
|
|
|
|
free_wincondlst(c2_lptr_t **pcondlst) {
|
2013-05-09 21:47:09 +08:00
|
|
|
#ifdef CONFIG_C2
|
Feature #16: Advanced window matching
- Add advanced window matching system, capable of matching against
arbitrary window properties as well as a series of internal
properties, with 4 additional operators (>, <, >=, <=) useful for
integer targets, and support of logical operators. The old matching
system is removed, but compatibility with the format is retained.
- As the new matching system is pretty complicated, and I have no past
experience in writing a parser, it's pretty possible that bugs are
present. It also has inferior performance, but I hope it doesn't
matter on modern CPUs.
- It's possible to disable matching system at compile time with NO_C2=1
now.
- Add ps->o.config_file to track which config file we have actually
read. Queryable via D-Bus.
- Parse -d in first pass in get_cfg() as c2 needs to query X to get
atoms during condition parsing.
- Fix a bug in wid_get_prop_adv() that 0 == rformat is not handled
correctly.
- Fix incompatibility with FreeBSD sed in dbus-examples/cdbus-driver.sh
.
- Add recipe to generate .clang_complete in Makefile, used by Vim
clang_complete plugin.
- Add DEBUG_C2 for debugging condition string parsing. DEBUG_WINMATCH is
still used for match debugging.
- Rename win_on_wdata_change() to win_on_factor_change().
- Extra malloc() failure checks. Add const to matching cache members in
session_t. Code clean-up. Documentation update.
2013-01-28 21:39:38 +08:00
|
|
|
while ((*pcondlst = c2_free_lptr(*pcondlst)))
|
|
|
|
continue;
|
|
|
|
#endif
|
2013-05-09 21:47:09 +08:00
|
|
|
}
|
2012-11-19 09:46:07 +08:00
|
|
|
|
2013-08-22 21:15:04 +08:00
|
|
|
/**
|
|
|
|
* Free Xinerama screen info.
|
|
|
|
*/
|
|
|
|
static inline void
|
|
|
|
free_xinerama_info(session_t *ps) {
|
|
|
|
#ifdef CONFIG_XINERAMA
|
|
|
|
if (ps->xinerama_scr_regs) {
|
|
|
|
for (int i = 0; i < ps->xinerama_nscrs; ++i)
|
|
|
|
free_region(ps, &ps->xinerama_scr_regs[i]);
|
|
|
|
free(ps->xinerama_scr_regs);
|
|
|
|
}
|
|
|
|
cxfree(ps->xinerama_scrs);
|
|
|
|
ps->xinerama_scrs = NULL;
|
|
|
|
ps->xinerama_nscrs = 0;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2013-03-15 23:16:23 +08:00
|
|
|
/**
|
|
|
|
* Check whether a paint_t contains enough data.
|
|
|
|
*/
|
|
|
|
static inline bool
|
|
|
|
paint_isvalid(session_t *ps, const paint_t *ppaint) {
|
2013-03-18 11:48:28 +08:00
|
|
|
// Don't check for presence of Pixmap here, because older X Composite doesn't
|
|
|
|
// provide it
|
|
|
|
if (!ppaint)
|
2013-03-15 23:16:23 +08:00
|
|
|
return false;
|
|
|
|
|
2013-12-10 22:06:02 +08:00
|
|
|
if (bkend_use_xrender(ps) && !ppaint->pict)
|
2013-03-15 23:16:23 +08:00
|
|
|
return false;
|
|
|
|
|
|
|
|
#ifdef CONFIG_VSYNC_OPENGL
|
2013-03-17 12:14:00 +08:00
|
|
|
if (BKEND_GLX == ps->o.backend && !glx_tex_binded(ppaint->ptex, None))
|
2013-03-15 23:16:23 +08:00
|
|
|
return false;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2013-12-10 22:06:02 +08:00
|
|
|
|
2013-03-15 23:16:23 +08:00
|
|
|
/**
|
2013-03-16 22:54:43 +08:00
|
|
|
* Bind texture in paint_t if we are using GLX backend.
|
2013-03-15 23:16:23 +08:00
|
|
|
*/
|
|
|
|
static inline bool
|
2013-12-10 22:06:02 +08:00
|
|
|
paint_bind_tex_real(session_t *ps, paint_t *ppaint,
|
2013-03-18 11:48:28 +08:00
|
|
|
unsigned wid, unsigned hei, unsigned depth, bool force) {
|
2013-03-15 23:16:23 +08:00
|
|
|
#ifdef CONFIG_VSYNC_OPENGL
|
2013-12-10 22:06:02 +08:00
|
|
|
if (!ppaint->pixmap)
|
|
|
|
return false;
|
2013-03-18 11:48:28 +08:00
|
|
|
|
2013-12-10 22:06:02 +08:00
|
|
|
if (force || !glx_tex_binded(ppaint->ptex, ppaint->pixmap))
|
|
|
|
return glx_bind_pixmap(ps, &ppaint->ptex, ppaint->pixmap, wid, hei, depth);
|
2013-03-15 23:16:23 +08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-12-10 22:06:02 +08:00
|
|
|
static inline bool
|
|
|
|
paint_bind_tex(session_t *ps, paint_t *ppaint,
|
|
|
|
unsigned wid, unsigned hei, unsigned depth, bool force) {
|
|
|
|
if (BKEND_GLX == ps->o.backend)
|
|
|
|
return paint_bind_tex_real(ps, ppaint, wid, hei, depth, force);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-04-06 20:21:38 +08:00
|
|
|
/**
|
|
|
|
* Free data in a reg_data_t.
|
|
|
|
*/
|
|
|
|
static inline void
|
|
|
|
free_reg_data(reg_data_t *pregd) {
|
|
|
|
cxfree(pregd->rects);
|
|
|
|
pregd->rects = NULL;
|
|
|
|
pregd->nrects = 0;
|
|
|
|
}
|
|
|
|
|
2013-03-15 23:16:23 +08:00
|
|
|
/**
|
|
|
|
* Free paint_t.
|
|
|
|
*/
|
|
|
|
static inline void
|
|
|
|
free_paint(session_t *ps, paint_t *ppaint) {
|
|
|
|
free_texture(ps, &ppaint->ptex);
|
|
|
|
free_picture(ps, &ppaint->pict);
|
|
|
|
free_pixmap(ps, &ppaint->pixmap);
|
|
|
|
}
|
|
|
|
|
2014-03-17 23:25:34 +08:00
|
|
|
/**
|
|
|
|
* Free w->paint.
|
|
|
|
*/
|
|
|
|
static inline void
|
|
|
|
free_wpaint(session_t *ps, win *w) {
|
|
|
|
free_paint(ps, &w->paint);
|
|
|
|
free_fence(ps, &w->fence);
|
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* Destroy all resources in a <code>struct _win</code>.
|
|
|
|
*/
|
2013-03-15 23:16:23 +08:00
|
|
|
static inline void
|
2012-11-19 09:46:07 +08:00
|
|
|
free_win_res(session_t *ps, win *w) {
|
|
|
|
free_region(ps, &w->extents);
|
2013-03-15 23:16:23 +08:00
|
|
|
free_paint(ps, &w->paint);
|
2012-11-19 09:46:07 +08:00
|
|
|
free_region(ps, &w->border_size);
|
2013-03-15 23:16:23 +08:00
|
|
|
free_paint(ps, &w->shadow_paint);
|
2012-11-19 09:46:07 +08:00
|
|
|
free_damage(ps, &w->damage);
|
|
|
|
free_region(ps, &w->reg_ignore);
|
|
|
|
free(w->name);
|
|
|
|
free(w->class_instance);
|
|
|
|
free(w->class_general);
|
2012-12-07 22:38:10 +08:00
|
|
|
free(w->role);
|
2013-05-20 18:04:40 +08:00
|
|
|
#ifdef CONFIG_VSYNC_OPENGL_GLSL
|
|
|
|
free_glx_bc(ps, &w->glx_blur_cache);
|
|
|
|
#endif
|
2012-11-19 09:46:07 +08:00
|
|
|
}
|
|
|
|
|
2013-03-15 23:16:23 +08:00
|
|
|
/**
|
|
|
|
* Free root tile related things.
|
|
|
|
*/
|
|
|
|
static inline void
|
|
|
|
free_root_tile(session_t *ps) {
|
|
|
|
free_picture(ps, &ps->root_tile_paint.pict);
|
|
|
|
free_texture(ps, &ps->root_tile_paint.ptex);
|
|
|
|
if (ps->root_tile_fill)
|
|
|
|
free_pixmap(ps, &ps->root_tile_paint.pixmap);
|
|
|
|
ps->root_tile_paint.pixmap = None;
|
|
|
|
ps->root_tile_fill = false;
|
|
|
|
}
|
|
|
|
|
2012-10-29 22:00:11 +08:00
|
|
|
/**
|
|
|
|
* Get current system clock in milliseconds.
|
|
|
|
*/
|
Improvement #74: Use libevent for main loop
- Use libevent for main loop. I will explain the reasons in #56 later.
The preferred libevent version is 2.x, yet 1.4.x should work as well.
- As a result, compton now should build fine on *BSD. Thanks to
DachiChang for the FreeBSD build issue report.
- Another consequence is we now use microsecond-level timing all the
way. Nanosecond-level code will be dropped soon. Start using long
instead of unsigned long to represent time in milliseconds, as both
can't hold the full epoch time in ms, anyway, and a signed type
requires less care in subtraction. Wrap the epoch time in ms to 15
days.
- Fix broken NO_VSYNC_DRM and NO_VSYNC_OPENGL compile-time options.
- Use git revision number for versioning in Makefile, and other small
improvements.
- Reorganize struct _win. Drop unused w->damaged_sequence. w->damaged is
turned to bool.
- Add type and format to winprop_t, as preparation for the new condition
format.
- Add w->shadow_force and w->focus_force, to prepare for D-Bus support.
- Rename wid_get_prop() to wid_get_prop_adv() with more options. Add
wrapper function wid_get_prop().
- Add some extra helper functions, for D-Bus support later.
- Make some functions return a bool value to indicate if it's
successful.
- Modify add_win(), use a static const structure to initialize the new
struct _win.
- Add some helper macros, like printf_err(f)(q). Make some errors fatal.
- Rename some types, constants, and functions. Code clean-up.
- Check for time disorder in paint_preprocess() when calculating fading
steps.
- Rename evpoll() to swopti_handle_timeout(), and partially rewrite it.
- Make -h / --help legal.
- Known issue: compton segfaults on FreeBSD with nvidia-drivers, unless
NO_VSYNC_OPENGL is used. Will look into it later. Thamls to DachiChang
for reporting.
2013-01-08 08:50:58 +08:00
|
|
|
static inline time_ms_t
|
2012-10-29 22:00:11 +08:00
|
|
|
get_time_ms(void) {
|
|
|
|
struct timeval tv;
|
|
|
|
|
|
|
|
gettimeofday(&tv, NULL);
|
|
|
|
|
Improvement #74: Use libevent for main loop
- Use libevent for main loop. I will explain the reasons in #56 later.
The preferred libevent version is 2.x, yet 1.4.x should work as well.
- As a result, compton now should build fine on *BSD. Thanks to
DachiChang for the FreeBSD build issue report.
- Another consequence is we now use microsecond-level timing all the
way. Nanosecond-level code will be dropped soon. Start using long
instead of unsigned long to represent time in milliseconds, as both
can't hold the full epoch time in ms, anyway, and a signed type
requires less care in subtraction. Wrap the epoch time in ms to 15
days.
- Fix broken NO_VSYNC_DRM and NO_VSYNC_OPENGL compile-time options.
- Use git revision number for versioning in Makefile, and other small
improvements.
- Reorganize struct _win. Drop unused w->damaged_sequence. w->damaged is
turned to bool.
- Add type and format to winprop_t, as preparation for the new condition
format.
- Add w->shadow_force and w->focus_force, to prepare for D-Bus support.
- Rename wid_get_prop() to wid_get_prop_adv() with more options. Add
wrapper function wid_get_prop().
- Add some extra helper functions, for D-Bus support later.
- Make some functions return a bool value to indicate if it's
successful.
- Modify add_win(), use a static const structure to initialize the new
struct _win.
- Add some helper macros, like printf_err(f)(q). Make some errors fatal.
- Rename some types, constants, and functions. Code clean-up.
- Check for time disorder in paint_preprocess() when calculating fading
steps.
- Rename evpoll() to swopti_handle_timeout(), and partially rewrite it.
- Make -h / --help legal.
- Known issue: compton segfaults on FreeBSD with nvidia-drivers, unless
NO_VSYNC_OPENGL is used. Will look into it later. Thamls to DachiChang
for reporting.
2013-01-08 08:50:58 +08:00
|
|
|
return tv.tv_sec % SEC_WRAP * 1000 + tv.tv_usec / 1000;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert time from milliseconds to struct timeval.
|
|
|
|
*/
|
|
|
|
static inline struct timeval
|
|
|
|
ms_to_tv(int timeout) {
|
|
|
|
return (struct timeval) {
|
|
|
|
.tv_sec = timeout / MS_PER_SEC,
|
|
|
|
.tv_usec = timeout % MS_PER_SEC * (US_PER_SEC / MS_PER_SEC)
|
|
|
|
};
|
2012-10-29 22:00:11 +08:00
|
|
|
}
|
2012-02-08 18:31:39 +08:00
|
|
|
|
2013-09-04 22:00:51 +08:00
|
|
|
/**
|
|
|
|
* Whether an event is DamageNotify.
|
|
|
|
*/
|
|
|
|
static inline bool
|
|
|
|
isdamagenotify(session_t *ps, const XEvent *ev) {
|
|
|
|
return ps->damage_event + XDamageNotify == ev->type;
|
|
|
|
}
|
|
|
|
|
2013-01-30 13:41:08 +08:00
|
|
|
/**
|
|
|
|
* Create a XTextProperty of a single string.
|
|
|
|
*/
|
|
|
|
static inline XTextProperty *
|
|
|
|
make_text_prop(session_t *ps, char *str) {
|
2013-11-10 10:13:18 +08:00
|
|
|
XTextProperty *pprop = cmalloc(1, XTextProperty);
|
2013-01-30 13:41:08 +08:00
|
|
|
|
|
|
|
if (XmbTextListToTextProperty(ps->dpy, &str, 1, XStringStyle, pprop)) {
|
2013-04-05 21:05:19 +08:00
|
|
|
cxfree(pprop->value);
|
2013-01-30 13:41:08 +08:00
|
|
|
free(pprop);
|
|
|
|
pprop = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return pprop;
|
|
|
|
}
|
|
|
|
|
2013-11-10 10:13:18 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Set a single-string text property on a window.
|
|
|
|
*/
|
|
|
|
static inline bool
|
|
|
|
wid_set_text_prop(session_t *ps, Window wid, Atom prop_atom, char *str) {
|
|
|
|
XTextProperty *pprop = make_text_prop(ps, str);
|
|
|
|
if (!pprop) {
|
|
|
|
printf_errf("(\"%s\"): Failed to make text property.", str);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
XSetTextProperty(ps->dpy, wid, pprop, prop_atom);
|
|
|
|
cxfree(pprop->value);
|
|
|
|
cxfree(pprop);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
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-02-08 18:31:39 +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);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
/**
|
|
|
|
* Execute fade callback of a window if fading finished.
|
|
|
|
*/
|
|
|
|
static inline void
|
2012-11-19 09:46:07 +08:00
|
|
|
check_fade_fin(session_t *ps, win *w) {
|
2012-10-29 22:00:11 +08:00
|
|
|
if (w->fade_callback && w->opacity == w->opacity_tgt) {
|
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-11-19 09:46:07 +08:00
|
|
|
set_fade_callback(ps, w, NULL, true);
|
2012-09-19 20:49:16 +08:00
|
|
|
}
|
|
|
|
}
|
2012-02-08 18:31:39 +08:00
|
|
|
|
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);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static double
|
|
|
|
gaussian(double r, double x, double y);
|
|
|
|
|
|
|
|
static conv *
|
2012-11-19 09:46:07 +08:00
|
|
|
make_gaussian_map(double r);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static unsigned char
|
|
|
|
sum_gaussian(conv *map, double opacity,
|
|
|
|
int x, int y, int width, int height);
|
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
presum_gaussian(session_t *ps, conv *map);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static XImage *
|
2012-11-19 09:46:07 +08:00
|
|
|
make_shadow(session_t *ps, double opacity, int width, int height);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
2013-03-15 23:16:23 +08:00
|
|
|
static bool
|
|
|
|
win_build_shadow(session_t *ps, win *w, double opacity);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
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,
|
2012-02-08 18:31:39 +08:00
|
|
|
double r, double g, double b);
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* Stop listening for events on a particular window.
|
|
|
|
*/
|
|
|
|
static inline void
|
|
|
|
win_ev_stop(session_t *ps, win *w) {
|
|
|
|
// Will get BadWindow if the window is destroyed
|
|
|
|
set_ignore_next(ps);
|
|
|
|
XSelectInput(ps->dpy, w->id, 0);
|
|
|
|
|
|
|
|
if (w->client_win) {
|
|
|
|
set_ignore_next(ps);
|
|
|
|
XSelectInput(ps->dpy, w->client_win, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ps->shape_exists) {
|
|
|
|
set_ignore_next(ps);
|
|
|
|
XShapeSelectInput(ps->dpy, w->id, 0);
|
2012-11-04 18:11:08 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-10-01 10:34:40 +08:00
|
|
|
/**
|
|
|
|
* Get the children of a window.
|
|
|
|
*
|
2013-01-29 09:57:04 +08:00
|
|
|
* @param ps current session
|
2012-10-01 10:34:40 +08:00
|
|
|
* @param w window to check
|
|
|
|
* @param children [out] an array of child window IDs
|
|
|
|
* @param nchildren [out] number of children
|
|
|
|
* @return 1 if successful, 0 otherwise
|
|
|
|
*/
|
2012-11-19 09:46:07 +08:00
|
|
|
static inline bool
|
|
|
|
wid_get_children(session_t *ps, Window w,
|
2012-10-01 10:34:40 +08:00
|
|
|
Window **children, unsigned *nchildren) {
|
|
|
|
Window troot, tparent;
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!XQueryTree(ps->dpy, w, &troot, &tparent, children, nchildren)) {
|
2012-10-01 10:34:40 +08:00
|
|
|
*nchildren = 0;
|
2012-11-19 09:46:07 +08:00
|
|
|
return false;
|
2012-10-01 10:34:40 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
return true;
|
2012-10-01 10:34:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if a window is bounding-shaped.
|
|
|
|
*/
|
2012-11-19 09:46:07 +08:00
|
|
|
static inline bool
|
|
|
|
wid_bounding_shaped(const session_t *ps, Window wid) {
|
|
|
|
if (ps->shape_exists) {
|
|
|
|
Bool bounding_shaped = False, clip_shaped = False;
|
2012-10-01 10:34:40 +08:00
|
|
|
int x_bounding, y_bounding, x_clip, y_clip;
|
|
|
|
unsigned int w_bounding, h_bounding, w_clip, h_clip;
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
XShapeQueryExtents(ps->dpy, wid, &bounding_shaped,
|
2012-10-01 10:34:40 +08:00
|
|
|
&x_bounding, &y_bounding, &w_bounding, &h_bounding,
|
|
|
|
&clip_shaped, &x_clip, &y_clip, &w_clip, &h_clip);
|
|
|
|
return bounding_shaped;
|
|
|
|
}
|
2012-11-19 09:46:07 +08:00
|
|
|
|
|
|
|
return false;
|
2012-10-01 10:34:40 +08:00
|
|
|
}
|
|
|
|
|
2012-11-10 11:41:01 +08:00
|
|
|
/**
|
2012-11-19 09:46:07 +08:00
|
|
|
* Determine if a window change affects <code>reg_ignore</code> and set
|
|
|
|
* <code>reg_ignore_expire</code> accordingly.
|
2012-11-10 11:41:01 +08:00
|
|
|
*/
|
2012-10-31 08:54:09 +08:00
|
|
|
static inline void
|
2012-11-19 09:46:07 +08:00
|
|
|
update_reg_ignore_expire(session_t *ps, const win *w) {
|
Improvement #74: Use libevent for main loop
- Use libevent for main loop. I will explain the reasons in #56 later.
The preferred libevent version is 2.x, yet 1.4.x should work as well.
- As a result, compton now should build fine on *BSD. Thanks to
DachiChang for the FreeBSD build issue report.
- Another consequence is we now use microsecond-level timing all the
way. Nanosecond-level code will be dropped soon. Start using long
instead of unsigned long to represent time in milliseconds, as both
can't hold the full epoch time in ms, anyway, and a signed type
requires less care in subtraction. Wrap the epoch time in ms to 15
days.
- Fix broken NO_VSYNC_DRM and NO_VSYNC_OPENGL compile-time options.
- Use git revision number for versioning in Makefile, and other small
improvements.
- Reorganize struct _win. Drop unused w->damaged_sequence. w->damaged is
turned to bool.
- Add type and format to winprop_t, as preparation for the new condition
format.
- Add w->shadow_force and w->focus_force, to prepare for D-Bus support.
- Rename wid_get_prop() to wid_get_prop_adv() with more options. Add
wrapper function wid_get_prop().
- Add some extra helper functions, for D-Bus support later.
- Make some functions return a bool value to indicate if it's
successful.
- Modify add_win(), use a static const structure to initialize the new
struct _win.
- Add some helper macros, like printf_err(f)(q). Make some errors fatal.
- Rename some types, constants, and functions. Code clean-up.
- Check for time disorder in paint_preprocess() when calculating fading
steps.
- Rename evpoll() to swopti_handle_timeout(), and partially rewrite it.
- Make -h / --help legal.
- Known issue: compton segfaults on FreeBSD with nvidia-drivers, unless
NO_VSYNC_OPENGL is used. Will look into it later. Thamls to DachiChang
for reporting.
2013-01-08 08:50:58 +08:00
|
|
|
if (w->to_paint && WMODE_SOLID == w->mode)
|
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
|
|
|
/**
|
|
|
|
* Check whether a window has WM frames.
|
|
|
|
*/
|
2012-11-19 09:46:07 +08:00
|
|
|
static inline bool __attribute__((const))
|
2012-10-31 08:54:09 +08:00
|
|
|
win_has_frame(const win *w) {
|
2013-01-09 20:25:01 +08:00
|
|
|
return w->a.border_width
|
|
|
|
|| w->top_width || w->left_width || w->right_width || w->bottom_width;
|
|
|
|
}
|
|
|
|
|
2013-05-21 09:18:41 +08:00
|
|
|
static inline void
|
2013-10-01 23:20:22 +08:00
|
|
|
wid_set_opacity_prop(session_t *ps, Window wid, opacity_t val) {
|
|
|
|
const unsigned long v = val;
|
2013-05-21 09:18:41 +08:00
|
|
|
XChangeProperty(ps->dpy, wid, ps->atom_opacity, XA_CARDINAL, 32,
|
2013-10-01 23:20:22 +08:00
|
|
|
PropModeReplace, (unsigned char *) &v, 1);
|
2013-05-21 09:18:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
wid_rm_opacity_prop(session_t *ps, Window wid) {
|
|
|
|
XDeleteProperty(ps->dpy, wid, ps->atom_opacity);
|
|
|
|
}
|
|
|
|
|
2013-01-09 20:25:01 +08:00
|
|
|
/**
|
|
|
|
* Dump an drawable's info.
|
|
|
|
*/
|
|
|
|
static inline void
|
|
|
|
dump_drawable(session_t *ps, Drawable drawable) {
|
|
|
|
Window rroot = None;
|
|
|
|
int x = 0, y = 0;
|
|
|
|
unsigned width = 0, height = 0, border = 0, depth = 0;
|
|
|
|
if (XGetGeometry(ps->dpy, drawable, &rroot, &x, &y, &width, &height,
|
|
|
|
&border, &depth)) {
|
|
|
|
printf_dbgf("(%#010lx): x = %u, y = %u, wid = %u, hei = %d, b = %u, d = %u\n", drawable, x, y, width, height, border, depth);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
printf_dbgf("(%#010lx): Failed\n", drawable);
|
|
|
|
}
|
2012-10-31 08:54:09 +08:00
|
|
|
}
|
|
|
|
|
2012-10-01 10:34:40 +08:00
|
|
|
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
|
|
|
|
2013-05-01 22:08:43 +08:00
|
|
|
/**
|
|
|
|
* Validate a pixmap.
|
|
|
|
*
|
|
|
|
* Detect whether the pixmap is valid with XGetGeometry. Well, maybe there
|
|
|
|
* are better ways.
|
|
|
|
*/
|
|
|
|
static inline bool
|
|
|
|
validate_pixmap(session_t *ps, Pixmap pxmap) {
|
|
|
|
if (!pxmap) return false;
|
|
|
|
|
|
|
|
Window rroot = None;
|
|
|
|
int rx = 0, ry = 0;
|
|
|
|
unsigned rwid = 0, rhei = 0, rborder = 0, rdepth = 0;
|
|
|
|
return XGetGeometry(ps->dpy, pxmap, &rroot, &rx, &ry,
|
|
|
|
&rwid, &rhei, &rborder, &rdepth) && rwid && rhei;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Validate pixmap of a window, and destroy pixmap and picture if invalid.
|
|
|
|
*/
|
|
|
|
static inline void
|
|
|
|
win_validate_pixmap(session_t *ps, win *w) {
|
|
|
|
// Destroy pixmap and picture, if invalid
|
|
|
|
if (!validate_pixmap(ps, w->paint.pixmap))
|
|
|
|
free_paint(ps, &w->paint);
|
|
|
|
}
|
2013-01-29 09:57:04 +08:00
|
|
|
|
Feature #16: Advanced window matching
- Add advanced window matching system, capable of matching against
arbitrary window properties as well as a series of internal
properties, with 4 additional operators (>, <, >=, <=) useful for
integer targets, and support of logical operators. The old matching
system is removed, but compatibility with the format is retained.
- As the new matching system is pretty complicated, and I have no past
experience in writing a parser, it's pretty possible that bugs are
present. It also has inferior performance, but I hope it doesn't
matter on modern CPUs.
- It's possible to disable matching system at compile time with NO_C2=1
now.
- Add ps->o.config_file to track which config file we have actually
read. Queryable via D-Bus.
- Parse -d in first pass in get_cfg() as c2 needs to query X to get
atoms during condition parsing.
- Fix a bug in wid_get_prop_adv() that 0 == rformat is not handled
correctly.
- Fix incompatibility with FreeBSD sed in dbus-examples/cdbus-driver.sh
.
- Add recipe to generate .clang_complete in Makefile, used by Vim
clang_complete plugin.
- Add DEBUG_C2 for debugging condition string parsing. DEBUG_WINMATCH is
still used for match debugging.
- Rename win_on_wdata_change() to win_on_factor_change().
- Extra malloc() failure checks. Add const to matching cache members in
session_t. Code clean-up. Documentation update.
2013-01-28 21:39:38 +08:00
|
|
|
/**
|
|
|
|
* Wrapper of c2_match().
|
|
|
|
*/
|
|
|
|
static inline bool
|
|
|
|
win_match(session_t *ps, win *w, c2_lptr_t *condlst, const c2_lptr_t **cache) {
|
|
|
|
#ifdef CONFIG_C2
|
|
|
|
return c2_match(ps, w, condlst, cache);
|
|
|
|
#else
|
|
|
|
return false;
|
|
|
|
#endif
|
|
|
|
}
|
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
|
|
|
static bool
|
Feature #16: Advanced window matching
- Add advanced window matching system, capable of matching against
arbitrary window properties as well as a series of internal
properties, with 4 additional operators (>, <, >=, <=) useful for
integer targets, and support of logical operators. The old matching
system is removed, but compatibility with the format is retained.
- As the new matching system is pretty complicated, and I have no past
experience in writing a parser, it's pretty possible that bugs are
present. It also has inferior performance, but I hope it doesn't
matter on modern CPUs.
- It's possible to disable matching system at compile time with NO_C2=1
now.
- Add ps->o.config_file to track which config file we have actually
read. Queryable via D-Bus.
- Parse -d in first pass in get_cfg() as c2 needs to query X to get
atoms during condition parsing.
- Fix a bug in wid_get_prop_adv() that 0 == rformat is not handled
correctly.
- Fix incompatibility with FreeBSD sed in dbus-examples/cdbus-driver.sh
.
- Add recipe to generate .clang_complete in Makefile, used by Vim
clang_complete plugin.
- Add DEBUG_C2 for debugging condition string parsing. DEBUG_WINMATCH is
still used for match debugging.
- Rename win_on_wdata_change() to win_on_factor_change().
- Extra malloc() failure checks. Add const to matching cache members in
session_t. Code clean-up. Documentation update.
2013-01-28 21:39:38 +08:00
|
|
|
condlst_add(session_t *ps, c2_lptr_t **pcondlst, const char *pattern);
|
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 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 23:24:37 +08:00
|
|
|
|
2012-12-12 12:01:51 +08:00
|
|
|
/**
|
|
|
|
* Clear leader cache of all windows.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
clear_cache_win_leaders(session_t *ps) {
|
|
|
|
for (win *w = ps->list; w; w = w->next)
|
|
|
|
w->cache_leader = None;
|
|
|
|
}
|
2012-02-08 18:31:39 +08:00
|
|
|
|
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 23:12:54 +08:00
|
|
|
|
2013-09-18 21:50:57 +08:00
|
|
|
/**
|
|
|
|
* Find matched window.
|
|
|
|
*/
|
|
|
|
static inline win *
|
|
|
|
find_win_all(session_t *ps, const Window wid) {
|
|
|
|
if (!wid || PointerRoot == wid || wid == ps->root || wid == ps->overlay)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
win *w = find_win(ps, wid);
|
|
|
|
if (!w) w = find_toplevel(ps, wid);
|
|
|
|
if (!w) w = find_toplevel2(ps, wid);
|
|
|
|
return w;
|
|
|
|
}
|
|
|
|
|
2012-12-12 12:01:51 +08:00
|
|
|
static Window
|
|
|
|
win_get_leader_raw(session_t *ps, win *w, int recursions);
|
|
|
|
|
2012-12-12 12:34:56 +08:00
|
|
|
/**
|
|
|
|
* Get the leader of a window.
|
|
|
|
*
|
|
|
|
* This function updates w->cache_leader if necessary.
|
|
|
|
*/
|
|
|
|
static inline Window
|
|
|
|
win_get_leader(session_t *ps, win *w) {
|
|
|
|
return win_get_leader_raw(ps, w, 0);
|
|
|
|
}
|
|
|
|
|
2012-12-12 12:01:51 +08:00
|
|
|
/**
|
|
|
|
* Return whether a window group is really focused.
|
|
|
|
*
|
|
|
|
* @param leader leader window ID
|
|
|
|
* @return true if the window group is focused, false otherwise
|
|
|
|
*/
|
|
|
|
static inline bool
|
|
|
|
group_is_focused(session_t *ps, Window leader) {
|
|
|
|
if (!leader)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
for (win *w = ps->list; w; w = w->next) {
|
|
|
|
if (win_get_leader(ps, w) == leader && !w->destroyed
|
2013-09-18 21:50:57 +08:00
|
|
|
&& win_is_focused_real(ps, w))
|
2012-12-12 12:01:51 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-09-13 23:12:54 +08:00
|
|
|
static win *
|
2012-11-19 09:46:07 +08:00
|
|
|
recheck_focus(session_t *ps);
|
2012-09-13 23:12:54 +08:00
|
|
|
|
2013-03-15 23:16:23 +08:00
|
|
|
static bool
|
|
|
|
get_root_tile(session_t *ps);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static void
|
2013-03-15 23:16:23 +08:00
|
|
|
paint_root(session_t *ps, XserverRegion reg_paint);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
2012-12-15 20:07:45 +08:00
|
|
|
static XserverRegion
|
|
|
|
win_get_region(session_t *ps, win *w, bool use_offset);
|
|
|
|
|
|
|
|
static XserverRegion
|
|
|
|
win_get_region_noframe(session_t *ps, win *w, bool use_offset);
|
|
|
|
|
2012-02-08 18:31:39 +08:00
|
|
|
static XserverRegion
|
2012-11-19 09:46:07 +08:00
|
|
|
win_extents(session_t *ps, win *w);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static XserverRegion
|
2012-12-15 20:07:45 +08:00
|
|
|
border_size(session_t *ps, win *w, bool use_offset);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
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);
|
2012-09-13 21:38:55 +08:00
|
|
|
|
2012-02-08 18:31:39 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
get_frame_extents(session_t *ps, win *w, Window client);
|
2012-02-08 18:31:39 +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-09-19 20:49:16 +08:00
|
|
|
|
2013-03-15 23:16:23 +08:00
|
|
|
static void
|
|
|
|
render(session_t *ps, int x, int y, int dx, int dy, int wid, int hei,
|
|
|
|
double opacity, bool argb, bool neg,
|
2013-04-06 20:21:38 +08:00
|
|
|
Picture pict, glx_texture_t *ptex,
|
|
|
|
XserverRegion reg_paint, const reg_data_t *pcache_reg);
|
2013-03-15 23:16:23 +08:00
|
|
|
|
|
|
|
static inline void
|
2013-04-06 20:21:38 +08:00
|
|
|
win_render(session_t *ps, win *w, int x, int y, int wid, int hei, double opacity, XserverRegion reg_paint, const reg_data_t *pcache_reg, Picture pict) {
|
2013-03-15 23:16:23 +08:00
|
|
|
const int dx = (w ? w->a.x: 0) + x;
|
|
|
|
const int dy = (w ? w->a.y: 0) + y;
|
|
|
|
const bool argb = (w && w->mode == WMODE_ARGB);
|
|
|
|
const bool neg = (w && w->invert_color);
|
|
|
|
|
|
|
|
render(ps, x, y, dx, dy, wid, hei, opacity, argb, neg,
|
2013-04-06 20:21:38 +08:00
|
|
|
pict, (w ? w->paint.ptex: ps->root_tile_paint.ptex), reg_paint, pcache_reg);
|
2013-03-15 23:16:23 +08:00
|
|
|
}
|
|
|
|
|
2013-03-16 22:54:43 +08:00
|
|
|
static inline void
|
2013-04-06 20:21:38 +08:00
|
|
|
set_tgt_clip(session_t *ps, XserverRegion reg, const reg_data_t *pcache_reg) {
|
2013-03-16 22:54:43 +08:00
|
|
|
switch (ps->o.backend) {
|
|
|
|
case BKEND_XRENDER:
|
2014-01-03 02:33:57 +08:00
|
|
|
case BKEND_XR_GLX_HYBRID:
|
2013-12-10 22:06:02 +08:00
|
|
|
XFixesSetPictureClipRegion(ps->dpy, ps->tgt_buffer.pict, 0, 0, reg);
|
2013-03-16 22:54:43 +08:00
|
|
|
break;
|
|
|
|
#ifdef CONFIG_VSYNC_OPENGL
|
|
|
|
case BKEND_GLX:
|
2013-04-06 20:21:38 +08:00
|
|
|
glx_set_clip(ps, reg, pcache_reg);
|
2013-03-16 22:54:43 +08:00
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-20 18:04:40 +08:00
|
|
|
static bool
|
|
|
|
xr_blur_dst(session_t *ps, Picture tgt_buffer,
|
|
|
|
int x, int y, int wid, int hei, XFixed **blur_kerns,
|
|
|
|
XserverRegion reg_clip);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Normalize a convolution kernel.
|
|
|
|
*/
|
|
|
|
static inline void
|
|
|
|
normalize_conv_kern(int wid, int hei, XFixed *kern) {
|
|
|
|
double sum = 0.0;
|
|
|
|
for (int i = 0; i < wid * hei; ++i)
|
|
|
|
sum += XFixedToDouble(kern[i]);
|
|
|
|
double factor = 1.0 / sum;
|
|
|
|
for (int i = 0; i < wid * hei; ++i)
|
|
|
|
kern[i] = XDoubleToFixed(XFixedToDouble(kern[i]) * factor);
|
|
|
|
}
|
|
|
|
|
2012-02-08 18:31:39 +08:00
|
|
|
static void
|
2013-04-27 17:34:42 +08:00
|
|
|
paint_all(session_t *ps, XserverRegion region, XserverRegion region_real, win *t);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
add_damage(session_t *ps, XserverRegion damage);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
repair_win(session_t *ps, win *w);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
static wintype_t
|
|
|
|
wid_get_prop_wintype(session_t *ps, Window w);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-21 09:15:49 +08:00
|
|
|
map_win(session_t *ps, Window id);
|
2012-02-08 18:31:39 +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);
|
2012-09-26 21:40:48 +08:00
|
|
|
|
2012-02-08 18:31:39 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
finish_unmap_win(session_t *ps, win *w);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
unmap_callback(session_t *ps, win *w);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static void
|
2013-01-29 09:57:04 +08:00
|
|
|
unmap_win(session_t *ps, win *w);
|
2012-02-08 18:31:39 +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);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
2012-11-28 11:44:00 +08:00
|
|
|
/**
|
|
|
|
* Reread opacity property of a window.
|
|
|
|
*/
|
|
|
|
static inline void
|
|
|
|
win_update_opacity_prop(session_t *ps, win *w) {
|
|
|
|
w->opacity_prop = wid_get_opacity_prop(ps, w->id, OPAQUE);
|
|
|
|
if (!ps->o.detect_client_opacity || !w->client_win
|
|
|
|
|| w->id == w->client_win)
|
|
|
|
w->opacity_prop_client = OPAQUE;
|
|
|
|
else
|
|
|
|
w->opacity_prop_client = wid_get_opacity_prop(ps, w->client_win,
|
|
|
|
OPAQUE);
|
|
|
|
}
|
|
|
|
|
2012-02-08 18:31:39 +08:00
|
|
|
static double
|
2012-11-19 09:46:07 +08:00
|
|
|
get_opacity_percent(win *w);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static void
|
2013-01-12 22:21:35 +08:00
|
|
|
win_determine_mode(session_t *ps, win *w);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
2012-09-13 13:58:05 +08:00
|
|
|
static void
|
2012-11-28 11:44:00 +08:00
|
|
|
calc_opacity(session_t *ps, win *w);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
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);
|
2012-09-12 10:52:52 +08:00
|
|
|
|
2012-12-12 12:01:51 +08:00
|
|
|
static Window
|
|
|
|
wid_get_prop_window(session_t *ps, Window wid, Atom aprop);
|
|
|
|
|
|
|
|
static void
|
|
|
|
win_update_leader(session_t *ps, win *w);
|
|
|
|
|
|
|
|
static void
|
|
|
|
win_set_leader(session_t *ps, win *w, Window leader);
|
|
|
|
|
2012-12-12 12:34:56 +08:00
|
|
|
static void
|
|
|
|
win_update_focused(session_t *ps, win *w);
|
2012-11-28 11:44:00 +08:00
|
|
|
|
2012-12-12 12:01:51 +08:00
|
|
|
/**
|
|
|
|
* Run win_update_focused() on all windows with the same leader window.
|
|
|
|
*
|
|
|
|
* @param leader leader window ID
|
|
|
|
*/
|
|
|
|
static inline void
|
|
|
|
group_update_focused(session_t *ps, Window leader) {
|
|
|
|
if (!leader)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (win *w = ps->list; w; w = w->next) {
|
|
|
|
if (win_get_leader(ps, w) == leader && !w->destroyed)
|
|
|
|
win_update_focused(ps, w);
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-09-20 13:50:27 +08:00
|
|
|
static inline void
|
2012-12-12 12:34:56 +08:00
|
|
|
win_set_focused(session_t *ps, win *w, bool focused);
|
2012-09-20 13:50:27 +08:00
|
|
|
|
2013-09-18 21:50:57 +08:00
|
|
|
static void
|
|
|
|
win_on_focus_change(session_t *ps, win *w);
|
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
static void
|
2013-01-12 22:21:35 +08:00
|
|
|
win_determine_fade(session_t *ps, win *w);
|
2012-09-19 20:49:16 +08:00
|
|
|
|
2012-11-09 11:35:40 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
win_update_shape_raw(session_t *ps, win *w);
|
2012-11-09 11:35:40 +08:00
|
|
|
|
2012-10-28 17:02:07 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
win_update_shape(session_t *ps, win *w);
|
2012-10-28 17:02:07 +08:00
|
|
|
|
2012-11-09 11:35:40 +08:00
|
|
|
static void
|
Improvement #74: Use libevent for main loop
- Use libevent for main loop. I will explain the reasons in #56 later.
The preferred libevent version is 2.x, yet 1.4.x should work as well.
- As a result, compton now should build fine on *BSD. Thanks to
DachiChang for the FreeBSD build issue report.
- Another consequence is we now use microsecond-level timing all the
way. Nanosecond-level code will be dropped soon. Start using long
instead of unsigned long to represent time in milliseconds, as both
can't hold the full epoch time in ms, anyway, and a signed type
requires less care in subtraction. Wrap the epoch time in ms to 15
days.
- Fix broken NO_VSYNC_DRM and NO_VSYNC_OPENGL compile-time options.
- Use git revision number for versioning in Makefile, and other small
improvements.
- Reorganize struct _win. Drop unused w->damaged_sequence. w->damaged is
turned to bool.
- Add type and format to winprop_t, as preparation for the new condition
format.
- Add w->shadow_force and w->focus_force, to prepare for D-Bus support.
- Rename wid_get_prop() to wid_get_prop_adv() with more options. Add
wrapper function wid_get_prop().
- Add some extra helper functions, for D-Bus support later.
- Make some functions return a bool value to indicate if it's
successful.
- Modify add_win(), use a static const structure to initialize the new
struct _win.
- Add some helper macros, like printf_err(f)(q). Make some errors fatal.
- Rename some types, constants, and functions. Code clean-up.
- Check for time disorder in paint_preprocess() when calculating fading
steps.
- Rename evpoll() to swopti_handle_timeout(), and partially rewrite it.
- Make -h / --help legal.
- Known issue: compton segfaults on FreeBSD with nvidia-drivers, unless
NO_VSYNC_OPENGL is used. Will look into it later. Thamls to DachiChang
for reporting.
2013-01-08 08:50:58 +08:00
|
|
|
win_update_prop_shadow_raw(session_t *ps, win *w);
|
2012-11-09 11:35:40 +08:00
|
|
|
|
|
|
|
static void
|
Improvement #74: Use libevent for main loop
- Use libevent for main loop. I will explain the reasons in #56 later.
The preferred libevent version is 2.x, yet 1.4.x should work as well.
- As a result, compton now should build fine on *BSD. Thanks to
DachiChang for the FreeBSD build issue report.
- Another consequence is we now use microsecond-level timing all the
way. Nanosecond-level code will be dropped soon. Start using long
instead of unsigned long to represent time in milliseconds, as both
can't hold the full epoch time in ms, anyway, and a signed type
requires less care in subtraction. Wrap the epoch time in ms to 15
days.
- Fix broken NO_VSYNC_DRM and NO_VSYNC_OPENGL compile-time options.
- Use git revision number for versioning in Makefile, and other small
improvements.
- Reorganize struct _win. Drop unused w->damaged_sequence. w->damaged is
turned to bool.
- Add type and format to winprop_t, as preparation for the new condition
format.
- Add w->shadow_force and w->focus_force, to prepare for D-Bus support.
- Rename wid_get_prop() to wid_get_prop_adv() with more options. Add
wrapper function wid_get_prop().
- Add some extra helper functions, for D-Bus support later.
- Make some functions return a bool value to indicate if it's
successful.
- Modify add_win(), use a static const structure to initialize the new
struct _win.
- Add some helper macros, like printf_err(f)(q). Make some errors fatal.
- Rename some types, constants, and functions. Code clean-up.
- Check for time disorder in paint_preprocess() when calculating fading
steps.
- Rename evpoll() to swopti_handle_timeout(), and partially rewrite it.
- Make -h / --help legal.
- Known issue: compton segfaults on FreeBSD with nvidia-drivers, unless
NO_VSYNC_OPENGL is used. Will look into it later. Thamls to DachiChang
for reporting.
2013-01-08 08:50:58 +08:00
|
|
|
win_update_prop_shadow(session_t *ps, win *w);
|
2012-11-09 11:35:40 +08:00
|
|
|
|
2014-04-19 21:52:20 +08:00
|
|
|
static void
|
|
|
|
win_set_shadow(session_t *ps, win *w, bool shadow_new);
|
|
|
|
|
2012-09-17 22:15:04 +08:00
|
|
|
static void
|
2013-01-12 22:21:35 +08:00
|
|
|
win_determine_shadow(session_t *ps, win *w);
|
|
|
|
|
2014-04-19 21:52:20 +08:00
|
|
|
static void
|
|
|
|
win_set_invert_color(session_t *ps, win *w, bool invert_color_new);
|
|
|
|
|
2013-03-23 22:06:41 +08:00
|
|
|
static void
|
|
|
|
win_determine_invert_color(session_t *ps, win *w);
|
|
|
|
|
2014-04-19 21:52:20 +08:00
|
|
|
static void
|
|
|
|
win_set_blur_background(session_t *ps, win *w, bool blur_background_new);
|
|
|
|
|
2013-03-23 22:06:41 +08:00
|
|
|
static void
|
|
|
|
win_determine_blur_background(session_t *ps, win *w);
|
|
|
|
|
2013-01-12 22:21:35 +08:00
|
|
|
static void
|
|
|
|
win_on_wtype_change(session_t *ps, win *w);
|
|
|
|
|
|
|
|
static void
|
Feature #16: Advanced window matching
- Add advanced window matching system, capable of matching against
arbitrary window properties as well as a series of internal
properties, with 4 additional operators (>, <, >=, <=) useful for
integer targets, and support of logical operators. The old matching
system is removed, but compatibility with the format is retained.
- As the new matching system is pretty complicated, and I have no past
experience in writing a parser, it's pretty possible that bugs are
present. It also has inferior performance, but I hope it doesn't
matter on modern CPUs.
- It's possible to disable matching system at compile time with NO_C2=1
now.
- Add ps->o.config_file to track which config file we have actually
read. Queryable via D-Bus.
- Parse -d in first pass in get_cfg() as c2 needs to query X to get
atoms during condition parsing.
- Fix a bug in wid_get_prop_adv() that 0 == rformat is not handled
correctly.
- Fix incompatibility with FreeBSD sed in dbus-examples/cdbus-driver.sh
.
- Add recipe to generate .clang_complete in Makefile, used by Vim
clang_complete plugin.
- Add DEBUG_C2 for debugging condition string parsing. DEBUG_WINMATCH is
still used for match debugging.
- Rename win_on_wdata_change() to win_on_factor_change().
- Extra malloc() failure checks. Add const to matching cache members in
session_t. Code clean-up. Documentation update.
2013-01-28 21:39:38 +08:00
|
|
|
win_on_factor_change(session_t *ps, win *w);
|
2013-01-12 22:21:35 +08:00
|
|
|
|
|
|
|
static void
|
|
|
|
win_upd_run(session_t *ps, win *w, win_upd_t *pupd);
|
2012-09-17 22:15:04 +08:00
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
calc_shadow_geometry(session_t *ps, win *w);
|
2012-09-17 22:15:04 +08:00
|
|
|
|
2013-09-15 11:07:49 +08:00
|
|
|
static void
|
|
|
|
win_upd_wintype(session_t *ps, win *w);
|
|
|
|
|
2012-09-14 11:51:46 +08:00
|
|
|
static void
|
2012-12-07 22:38:10 +08:00
|
|
|
win_mark_client(session_t *ps, win *w, Window client);
|
|
|
|
|
|
|
|
static void
|
|
|
|
win_unmark_client(session_t *ps, win *w);
|
|
|
|
|
|
|
|
static void
|
|
|
|
win_recheck_client(session_t *ps, win *w);
|
2012-09-14 11:51:46 +08:00
|
|
|
|
Improvement #74: Use libevent for main loop
- Use libevent for main loop. I will explain the reasons in #56 later.
The preferred libevent version is 2.x, yet 1.4.x should work as well.
- As a result, compton now should build fine on *BSD. Thanks to
DachiChang for the FreeBSD build issue report.
- Another consequence is we now use microsecond-level timing all the
way. Nanosecond-level code will be dropped soon. Start using long
instead of unsigned long to represent time in milliseconds, as both
can't hold the full epoch time in ms, anyway, and a signed type
requires less care in subtraction. Wrap the epoch time in ms to 15
days.
- Fix broken NO_VSYNC_DRM and NO_VSYNC_OPENGL compile-time options.
- Use git revision number for versioning in Makefile, and other small
improvements.
- Reorganize struct _win. Drop unused w->damaged_sequence. w->damaged is
turned to bool.
- Add type and format to winprop_t, as preparation for the new condition
format.
- Add w->shadow_force and w->focus_force, to prepare for D-Bus support.
- Rename wid_get_prop() to wid_get_prop_adv() with more options. Add
wrapper function wid_get_prop().
- Add some extra helper functions, for D-Bus support later.
- Make some functions return a bool value to indicate if it's
successful.
- Modify add_win(), use a static const structure to initialize the new
struct _win.
- Add some helper macros, like printf_err(f)(q). Make some errors fatal.
- Rename some types, constants, and functions. Code clean-up.
- Check for time disorder in paint_preprocess() when calculating fading
steps.
- Rename evpoll() to swopti_handle_timeout(), and partially rewrite it.
- Make -h / --help legal.
- Known issue: compton segfaults on FreeBSD with nvidia-drivers, unless
NO_VSYNC_OPENGL is used. Will look into it later. Thamls to DachiChang
for reporting.
2013-01-08 08:50:58 +08:00
|
|
|
static bool
|
2012-11-21 09:15:49 +08:00
|
|
|
add_win(session_t *ps, Window id, Window prev);
|
2012-02-08 18:31:39 +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);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
configure_win(session_t *ps, XConfigureEvent *ce);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
circulate_win(session_t *ps, XCirculateEvent *ce);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
finish_destroy_win(session_t *ps, Window id);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
destroy_callback(session_t *ps, win *w);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
destroy_win(session_t *ps, Window id);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
damage_win(session_t *ps, XDamageNotifyEvent *de);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static int
|
2014-03-17 23:25:34 +08:00
|
|
|
xerror(Display *dpy, XErrorEvent *ev);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
expose_root(session_t *ps, XRectangle *rects, int nrects);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
2012-12-07 22:38:10 +08:00
|
|
|
static Window
|
|
|
|
wid_get_prop_window(session_t *ps, Window wid, Atom aprop);
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
static bool
|
|
|
|
wid_get_name(session_t *ps, Window w, 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
|
|
|
|
2012-12-05 18:12:21 +08:00
|
|
|
static bool
|
|
|
|
wid_get_role(session_t *ps, Window w, char **role);
|
|
|
|
|
2012-09-13 13:58:05 +08:00
|
|
|
static int
|
2012-12-05 18:12:21 +08:00
|
|
|
win_get_prop_str(session_t *ps, win *w, char **tgt,
|
|
|
|
bool (*func_wid_get_prop_str)(session_t *ps, Window wid, char **tgt));
|
|
|
|
|
|
|
|
static inline int
|
|
|
|
win_get_name(session_t *ps, win *w) {
|
|
|
|
int ret = win_get_prop_str(ps, w, &w->name, wid_get_name);
|
|
|
|
|
|
|
|
#ifdef DEBUG_WINDATA
|
|
|
|
printf_dbgf("(%#010lx): client = %#010lx, name = \"%s\", "
|
|
|
|
"ret = %d\n", w->id, w->client_win, w->name, ret);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int
|
|
|
|
win_get_role(session_t *ps, win *w) {
|
|
|
|
int ret = win_get_prop_str(ps, w, &w->role, wid_get_role);
|
|
|
|
|
|
|
|
#ifdef DEBUG_WINDATA
|
|
|
|
printf_dbgf("(%#010lx): client = %#010lx, role = \"%s\", "
|
|
|
|
"ret = %d\n", w->id, w->client_win, w->role, ret);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return 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
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
static bool
|
|
|
|
win_get_class(session_t *ps, win *w);
|
2012-09-12 09:08:15 +08:00
|
|
|
|
|
|
|
#ifdef DEBUG_EVENTS
|
2012-02-08 18:31:39 +08:00
|
|
|
static int
|
|
|
|
ev_serial(XEvent *ev);
|
|
|
|
|
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);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static Window
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_window(session_t *ps, XEvent *ev);
|
2012-02-08 18:31:39 +08:00
|
|
|
#endif
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
static void __attribute__ ((noreturn))
|
2013-05-12 18:21:16 +08:00
|
|
|
usage(int ret);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
2013-01-30 13:41:08 +08:00
|
|
|
static bool
|
2013-03-01 12:41:16 +08:00
|
|
|
register_cm(session_t *ps);
|
2013-01-31 22:53:44 +08:00
|
|
|
|
2012-02-08 18:31:39 +08:00
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_focus_in(session_t *ps, XFocusChangeEvent *ev);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_focus_out(session_t *ps, XFocusChangeEvent *ev);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_create_notify(session_t *ps, XCreateWindowEvent *ev);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_configure_notify(session_t *ps, XConfigureEvent *ev);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_destroy_notify(session_t *ps, XDestroyWindowEvent *ev);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_map_notify(session_t *ps, XMapEvent *ev);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_unmap_notify(session_t *ps, XUnmapEvent *ev);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_reparent_notify(session_t *ps, XReparentEvent *ev);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_circulate_notify(session_t *ps, XCirculateEvent *ev);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_expose(session_t *ps, XExposeEvent *ev);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
2012-11-04 18:11:08 +08:00
|
|
|
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
|
|
|
|
2012-02-08 18:31:39 +08:00
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_property_notify(session_t *ps, XPropertyEvent *ev);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_damage_notify(session_t *ps, XDamageNotifyEvent *ev);
|
2012-02-08 18:31:39 +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);
|
2012-09-13 13:58:05 +08:00
|
|
|
|
2012-09-11 21:33:03 +08:00
|
|
|
/**
|
|
|
|
* Get a region of the screen size.
|
|
|
|
*/
|
2012-09-13 13:58:05 +08:00
|
|
|
inline static XserverRegion
|
2012-11-19 09:46:07 +08:00
|
|
|
get_screen_region(session_t *ps) {
|
2012-09-11 21:33:03 +08:00
|
|
|
XRectangle r;
|
|
|
|
|
|
|
|
r.x = 0;
|
|
|
|
r.y = 0;
|
2012-11-19 09:46:07 +08:00
|
|
|
r.width = ps->root_width;
|
|
|
|
r.height = ps->root_height;
|
|
|
|
return XFixesCreateRegion(ps->dpy, &r, 1);
|
2012-09-11 21:33:03 +08:00
|
|
|
}
|
|
|
|
|
2012-10-21 20:44:24 +08:00
|
|
|
/**
|
2013-04-27 11:43:11 +08:00
|
|
|
* Resize a region.
|
2012-10-21 20:44:24 +08:00
|
|
|
*/
|
|
|
|
static inline void
|
2013-04-27 11:43:11 +08:00
|
|
|
resize_region(session_t *ps, XserverRegion region, short mod) {
|
|
|
|
if (!mod || !region) return;
|
|
|
|
|
|
|
|
int nrects = 0, nnewrects = 0;
|
|
|
|
XRectangle *newrects = NULL;
|
2012-11-19 09:46:07 +08:00
|
|
|
XRectangle *rects = XFixesFetchRegion(ps->dpy, region, &nrects);
|
2013-04-27 11:43:11 +08:00
|
|
|
if (!rects || !nrects)
|
|
|
|
goto resize_region_end;
|
|
|
|
|
|
|
|
// Allocate memory for new rectangle list, because I don't know if it's
|
|
|
|
// safe to write in the memory Xlib allocates
|
|
|
|
newrects = calloc(nrects, sizeof(XRectangle));
|
|
|
|
if (!newrects) {
|
|
|
|
printf_errf("(): Failed to allocate memory.");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Loop through all rectangles
|
|
|
|
for (int i = 0; i < nrects; ++i) {
|
|
|
|
int x1 = max_i(rects[i].x - mod, 0);
|
|
|
|
int y1 = max_i(rects[i].y - mod, 0);
|
|
|
|
int x2 = min_i(rects[i].x + rects[i].width + mod, ps->root_width);
|
|
|
|
int y2 = min_i(rects[i].y + rects[i].height + mod, ps->root_height);
|
|
|
|
int wid = x2 - x1;
|
|
|
|
int hei = y2 - y1;
|
|
|
|
if (wid <= 0 || hei <= 0)
|
|
|
|
continue;
|
|
|
|
newrects[nnewrects].x = x1;
|
|
|
|
newrects[nnewrects].y = y1;
|
|
|
|
newrects[nnewrects].width = wid;
|
|
|
|
newrects[nnewrects].height = hei;
|
|
|
|
++nnewrects;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set region
|
|
|
|
XFixesSetRegion(ps->dpy, region, newrects, nnewrects);
|
2012-10-21 20:44:24 +08:00
|
|
|
|
2013-04-27 11:43:11 +08:00
|
|
|
resize_region_end:
|
|
|
|
cxfree(rects);
|
|
|
|
free(newrects);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Dump a region.
|
|
|
|
*/
|
|
|
|
static inline void
|
|
|
|
dump_region(const session_t *ps, XserverRegion region) {
|
|
|
|
int nrects = 0;
|
|
|
|
XRectangle *rects = NULL;
|
|
|
|
if (!rects && region)
|
|
|
|
rects = XFixesFetchRegion(ps->dpy, region, &nrects);
|
|
|
|
|
|
|
|
printf_dbgf("(%#010lx): %d rects\n", region, nrects);
|
|
|
|
if (!rects) return;
|
|
|
|
for (int i = 0; i < nrects; ++i)
|
2012-10-21 20:44:24 +08:00
|
|
|
printf("Rect #%d: %8d, %8d, %8d, %8d\n", i, rects[i].x, rects[i].y,
|
|
|
|
rects[i].width, rects[i].height);
|
2013-04-27 11:43:11 +08:00
|
|
|
putchar('\n');
|
|
|
|
fflush(stdout);
|
2012-10-21 20:44:24 +08:00
|
|
|
|
2013-04-05 21:05:19 +08:00
|
|
|
cxfree(rects);
|
2012-10-21 20:44:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if a region is empty.
|
|
|
|
*
|
|
|
|
* Keith Packard said this is slow:
|
|
|
|
* http://lists.freedesktop.org/archives/xorg/2007-November/030467.html
|
2012-11-19 09:46:07 +08:00
|
|
|
*
|
|
|
|
* @param ps current session
|
|
|
|
* @param region region to check for
|
2013-04-05 21:05:19 +08:00
|
|
|
* @param pcache_rects a place to cache the dumped rectangles
|
|
|
|
* @param ncache_nrects a place to cache the number of dumped rectangles
|
2012-10-21 20:44:24 +08:00
|
|
|
*/
|
2012-11-19 09:46:07 +08:00
|
|
|
static inline bool
|
2013-04-05 21:05:19 +08:00
|
|
|
is_region_empty(const session_t *ps, XserverRegion region,
|
2013-04-06 20:21:38 +08:00
|
|
|
reg_data_t *pcache_reg) {
|
2012-10-21 20:44:24 +08:00
|
|
|
int nrects = 0;
|
2012-11-19 09:46:07 +08:00
|
|
|
XRectangle *rects = XFixesFetchRegion(ps->dpy, region, &nrects);
|
2012-10-21 20:44:24 +08:00
|
|
|
|
2013-04-06 20:21:38 +08:00
|
|
|
if (pcache_reg) {
|
|
|
|
pcache_reg->rects = rects;
|
|
|
|
pcache_reg->nrects = nrects;
|
|
|
|
}
|
2013-04-05 21:05:19 +08:00
|
|
|
else
|
|
|
|
cxfree(rects);
|
|
|
|
|
2012-10-21 20:44:24 +08:00
|
|
|
return !nrects;
|
|
|
|
}
|
|
|
|
|
2012-09-12 10:52:52 +08:00
|
|
|
/**
|
|
|
|
* Add a window to damaged area.
|
|
|
|
*
|
2012-11-19 09:46:07 +08:00
|
|
|
* @param ps current session
|
2012-09-12 10:52:52 +08:00
|
|
|
* @param w struct _win element representing the window
|
|
|
|
*/
|
2012-09-13 13:58:05 +08:00
|
|
|
static inline void
|
2012-11-19 09:46:07 +08:00
|
|
|
add_damage_win(session_t *ps, win *w) {
|
2012-09-13 13:58:05 +08:00
|
|
|
if (w->extents) {
|
2012-11-19 09:46:07 +08:00
|
|
|
add_damage(ps, copy_region(ps, w->extents));
|
2012-09-13 13:58:05 +08:00
|
|
|
}
|
2012-09-12 10:52:52 +08:00
|
|
|
}
|
|
|
|
|
2012-11-14 21:34:51 +08:00
|
|
|
#if defined(DEBUG_EVENTS) || defined(DEBUG_RESTACK)
|
|
|
|
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
|
|
|
#endif
|
|
|
|
|
2012-02-08 18:31:39 +08:00
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_handle(session_t *ps, XEvent *ev);
|
2012-02-27 12:00:12 +08:00
|
|
|
|
Improvement #74: Use libevent for main loop
- Use libevent for main loop. I will explain the reasons in #56 later.
The preferred libevent version is 2.x, yet 1.4.x should work as well.
- As a result, compton now should build fine on *BSD. Thanks to
DachiChang for the FreeBSD build issue report.
- Another consequence is we now use microsecond-level timing all the
way. Nanosecond-level code will be dropped soon. Start using long
instead of unsigned long to represent time in milliseconds, as both
can't hold the full epoch time in ms, anyway, and a signed type
requires less care in subtraction. Wrap the epoch time in ms to 15
days.
- Fix broken NO_VSYNC_DRM and NO_VSYNC_OPENGL compile-time options.
- Use git revision number for versioning in Makefile, and other small
improvements.
- Reorganize struct _win. Drop unused w->damaged_sequence. w->damaged is
turned to bool.
- Add type and format to winprop_t, as preparation for the new condition
format.
- Add w->shadow_force and w->focus_force, to prepare for D-Bus support.
- Rename wid_get_prop() to wid_get_prop_adv() with more options. Add
wrapper function wid_get_prop().
- Add some extra helper functions, for D-Bus support later.
- Make some functions return a bool value to indicate if it's
successful.
- Modify add_win(), use a static const structure to initialize the new
struct _win.
- Add some helper macros, like printf_err(f)(q). Make some errors fatal.
- Rename some types, constants, and functions. Code clean-up.
- Check for time disorder in paint_preprocess() when calculating fading
steps.
- Rename evpoll() to swopti_handle_timeout(), and partially rewrite it.
- Make -h / --help legal.
- Known issue: compton segfaults on FreeBSD with nvidia-drivers, unless
NO_VSYNC_OPENGL is used. Will look into it later. Thamls to DachiChang
for reporting.
2013-01-08 08:50:58 +08:00
|
|
|
static bool
|
2013-01-11 21:31:02 +08:00
|
|
|
fork_after(session_t *ps);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
2012-09-25 10:19:20 +08:00
|
|
|
#ifdef CONFIG_LIBCONFIG
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* Wrapper of libconfig's <code>config_lookup_int</code>.
|
|
|
|
*
|
|
|
|
* To convert <code>int</code> value <code>config_lookup_bool</code>
|
|
|
|
* returns to <code>bool</code>.
|
|
|
|
*/
|
2012-09-28 09:10:34 +08:00
|
|
|
static inline void
|
2012-11-19 09:46:07 +08:00
|
|
|
lcfg_lookup_bool(const config_t *config, const char *path,
|
|
|
|
bool *value) {
|
2012-09-26 18:54:35 +08:00
|
|
|
int ival;
|
|
|
|
|
|
|
|
if (config_lookup_bool(config, path, &ival))
|
|
|
|
*value = ival;
|
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* Wrapper of libconfig's <code>config_lookup_int</code>.
|
|
|
|
*
|
|
|
|
* To deal with the different value types <code>config_lookup_int</code>
|
|
|
|
* returns in libconfig-1.3 and libconfig-1.4.
|
|
|
|
*/
|
2012-09-28 09:10:34 +08:00
|
|
|
static inline int
|
|
|
|
lcfg_lookup_int(const config_t *config, const char *path, int *value) {
|
|
|
|
#ifndef CONFIG_LIBCONFIG_LEGACY
|
|
|
|
return config_lookup_int(config, path, value);
|
|
|
|
#else
|
|
|
|
long lval;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if ((ret = config_lookup_int(config, path, &lval)))
|
|
|
|
*value = lval;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2012-09-25 10:19:20 +08:00
|
|
|
static FILE *
|
|
|
|
open_config_file(char *cpath, char **path);
|
|
|
|
|
2012-11-28 11:44:00 +08:00
|
|
|
static void
|
Feature #16: Advanced window matching
- Add advanced window matching system, capable of matching against
arbitrary window properties as well as a series of internal
properties, with 4 additional operators (>, <, >=, <=) useful for
integer targets, and support of logical operators. The old matching
system is removed, but compatibility with the format is retained.
- As the new matching system is pretty complicated, and I have no past
experience in writing a parser, it's pretty possible that bugs are
present. It also has inferior performance, but I hope it doesn't
matter on modern CPUs.
- It's possible to disable matching system at compile time with NO_C2=1
now.
- Add ps->o.config_file to track which config file we have actually
read. Queryable via D-Bus.
- Parse -d in first pass in get_cfg() as c2 needs to query X to get
atoms during condition parsing.
- Fix a bug in wid_get_prop_adv() that 0 == rformat is not handled
correctly.
- Fix incompatibility with FreeBSD sed in dbus-examples/cdbus-driver.sh
.
- Add recipe to generate .clang_complete in Makefile, used by Vim
clang_complete plugin.
- Add DEBUG_C2 for debugging condition string parsing. DEBUG_WINMATCH is
still used for match debugging.
- Rename win_on_wdata_change() to win_on_factor_change().
- Extra malloc() failure checks. Add const to matching cache members in
session_t. Code clean-up. Documentation update.
2013-01-28 21:39:38 +08:00
|
|
|
parse_cfg_condlst(session_t *ps, const config_t *pcfg, c2_lptr_t **pcondlst,
|
2012-11-28 11:44:00 +08:00
|
|
|
const char *name);
|
|
|
|
|
2012-09-25 10:19:20 +08:00
|
|
|
static void
|
Feature #16: Advanced window matching
- Add advanced window matching system, capable of matching against
arbitrary window properties as well as a series of internal
properties, with 4 additional operators (>, <, >=, <=) useful for
integer targets, and support of logical operators. The old matching
system is removed, but compatibility with the format is retained.
- As the new matching system is pretty complicated, and I have no past
experience in writing a parser, it's pretty possible that bugs are
present. It also has inferior performance, but I hope it doesn't
matter on modern CPUs.
- It's possible to disable matching system at compile time with NO_C2=1
now.
- Add ps->o.config_file to track which config file we have actually
read. Queryable via D-Bus.
- Parse -d in first pass in get_cfg() as c2 needs to query X to get
atoms during condition parsing.
- Fix a bug in wid_get_prop_adv() that 0 == rformat is not handled
correctly.
- Fix incompatibility with FreeBSD sed in dbus-examples/cdbus-driver.sh
.
- Add recipe to generate .clang_complete in Makefile, used by Vim
clang_complete plugin.
- Add DEBUG_C2 for debugging condition string parsing. DEBUG_WINMATCH is
still used for match debugging.
- Rename win_on_wdata_change() to win_on_factor_change().
- Extra malloc() failure checks. Add const to matching cache members in
session_t. Code clean-up. Documentation update.
2013-01-28 21:39:38 +08:00
|
|
|
parse_config(session_t *ps, struct options_tmp *pcfgtmp);
|
2012-09-25 10:19:20 +08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
static void
|
Feature #16: Advanced window matching
- Add advanced window matching system, capable of matching against
arbitrary window properties as well as a series of internal
properties, with 4 additional operators (>, <, >=, <=) useful for
integer targets, and support of logical operators. The old matching
system is removed, but compatibility with the format is retained.
- As the new matching system is pretty complicated, and I have no past
experience in writing a parser, it's pretty possible that bugs are
present. It also has inferior performance, but I hope it doesn't
matter on modern CPUs.
- It's possible to disable matching system at compile time with NO_C2=1
now.
- Add ps->o.config_file to track which config file we have actually
read. Queryable via D-Bus.
- Parse -d in first pass in get_cfg() as c2 needs to query X to get
atoms during condition parsing.
- Fix a bug in wid_get_prop_adv() that 0 == rformat is not handled
correctly.
- Fix incompatibility with FreeBSD sed in dbus-examples/cdbus-driver.sh
.
- Add recipe to generate .clang_complete in Makefile, used by Vim
clang_complete plugin.
- Add DEBUG_C2 for debugging condition string parsing. DEBUG_WINMATCH is
still used for match debugging.
- Rename win_on_wdata_change() to win_on_factor_change().
- Extra malloc() failure checks. Add const to matching cache members in
session_t. Code clean-up. Documentation update.
2013-01-28 21:39:38 +08:00
|
|
|
get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass);
|
2012-09-25 10:19:20 +08:00
|
|
|
|
2012-02-08 18:31:39 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
init_atoms(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
|
|
|
|
|
|
|
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
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
static bool
|
Improvement #74: Use libevent for main loop
- Use libevent for main loop. I will explain the reasons in #56 later.
The preferred libevent version is 2.x, yet 1.4.x should work as well.
- As a result, compton now should build fine on *BSD. Thanks to
DachiChang for the FreeBSD build issue report.
- Another consequence is we now use microsecond-level timing all the
way. Nanosecond-level code will be dropped soon. Start using long
instead of unsigned long to represent time in milliseconds, as both
can't hold the full epoch time in ms, anyway, and a signed type
requires less care in subtraction. Wrap the epoch time in ms to 15
days.
- Fix broken NO_VSYNC_DRM and NO_VSYNC_OPENGL compile-time options.
- Use git revision number for versioning in Makefile, and other small
improvements.
- Reorganize struct _win. Drop unused w->damaged_sequence. w->damaged is
turned to bool.
- Add type and format to winprop_t, as preparation for the new condition
format.
- Add w->shadow_force and w->focus_force, to prepare for D-Bus support.
- Rename wid_get_prop() to wid_get_prop_adv() with more options. Add
wrapper function wid_get_prop().
- Add some extra helper functions, for D-Bus support later.
- Make some functions return a bool value to indicate if it's
successful.
- Modify add_win(), use a static const structure to initialize the new
struct _win.
- Add some helper macros, like printf_err(f)(q). Make some errors fatal.
- Rename some types, constants, and functions. Code clean-up.
- Check for time disorder in paint_preprocess() when calculating fading
steps.
- Rename evpoll() to swopti_handle_timeout(), and partially rewrite it.
- Make -h / --help legal.
- Known issue: compton segfaults on FreeBSD with nvidia-drivers, unless
NO_VSYNC_OPENGL is used. Will look into it later. Thamls to DachiChang
for reporting.
2013-01-08 08:50:58 +08:00
|
|
|
swopti_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
|
|
|
|
Improvement #74: Use libevent for main loop
- Use libevent for main loop. I will explain the reasons in #56 later.
The preferred libevent version is 2.x, yet 1.4.x should work as well.
- As a result, compton now should build fine on *BSD. Thanks to
DachiChang for the FreeBSD build issue report.
- Another consequence is we now use microsecond-level timing all the
way. Nanosecond-level code will be dropped soon. Start using long
instead of unsigned long to represent time in milliseconds, as both
can't hold the full epoch time in ms, anyway, and a signed type
requires less care in subtraction. Wrap the epoch time in ms to 15
days.
- Fix broken NO_VSYNC_DRM and NO_VSYNC_OPENGL compile-time options.
- Use git revision number for versioning in Makefile, and other small
improvements.
- Reorganize struct _win. Drop unused w->damaged_sequence. w->damaged is
turned to bool.
- Add type and format to winprop_t, as preparation for the new condition
format.
- Add w->shadow_force and w->focus_force, to prepare for D-Bus support.
- Rename wid_get_prop() to wid_get_prop_adv() with more options. Add
wrapper function wid_get_prop().
- Add some extra helper functions, for D-Bus support later.
- Make some functions return a bool value to indicate if it's
successful.
- Modify add_win(), use a static const structure to initialize the new
struct _win.
- Add some helper macros, like printf_err(f)(q). Make some errors fatal.
- Rename some types, constants, and functions. Code clean-up.
- Check for time disorder in paint_preprocess() when calculating fading
steps.
- Rename evpoll() to swopti_handle_timeout(), and partially rewrite it.
- Make -h / --help legal.
- Known issue: compton segfaults on FreeBSD with nvidia-drivers, unless
NO_VSYNC_OPENGL is used. Will look into it later. Thamls to DachiChang
for reporting.
2013-01-08 08:50:58 +08:00
|
|
|
static void
|
|
|
|
swopti_handle_timeout(session_t *ps, struct timeval *ptv);
|
|
|
|
|
2013-03-01 12:41:16 +08:00
|
|
|
#ifdef CONFIG_VSYNC_OPENGL
|
|
|
|
/**
|
|
|
|
* Ensure we have a GLX context.
|
|
|
|
*/
|
|
|
|
static inline bool
|
|
|
|
ensure_glx_context(session_t *ps) {
|
|
|
|
// Create GLX context
|
|
|
|
if (!ps->glx_context)
|
2013-03-15 23:16:23 +08:00
|
|
|
glx_init(ps, false);
|
2013-03-01 12:41:16 +08:00
|
|
|
|
|
|
|
return ps->glx_context;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
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
|
|
|
|
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
|
|
|
#endif
|
|
|
|
|
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
|
|
|
|
2013-01-30 13:41:08 +08:00
|
|
|
static bool
|
|
|
|
vsync_opengl_oml_init(session_t *ps);
|
|
|
|
|
2013-03-15 23:16:23 +08:00
|
|
|
static bool
|
|
|
|
vsync_opengl_swc_init(session_t *ps);
|
|
|
|
|
2013-03-23 22:06:41 +08:00
|
|
|
static bool
|
|
|
|
vsync_opengl_mswc_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
|
2013-01-30 13:41:08 +08:00
|
|
|
static int
|
2012-11-19 09:46:07 +08:00
|
|
|
vsync_opengl_wait(session_t *ps);
|
2013-01-30 13:41:08 +08:00
|
|
|
|
|
|
|
static int
|
|
|
|
vsync_opengl_oml_wait(session_t *ps);
|
2013-05-20 18:04:40 +08:00
|
|
|
|
|
|
|
static void
|
|
|
|
vsync_opengl_swc_deinit(session_t *ps);
|
|
|
|
|
|
|
|
static void
|
|
|
|
vsync_opengl_mswc_deinit(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
|
|
|
#endif
|
|
|
|
|
2012-10-26 11:12:28 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
vsync_wait(session_t *ps);
|
|
|
|
|
|
|
|
static void
|
|
|
|
init_alpha_picts(session_t *ps);
|
2012-10-13 18:46:59 +08:00
|
|
|
|
2013-01-30 13:41:08 +08:00
|
|
|
static bool
|
2012-11-19 09:46:07 +08:00
|
|
|
init_dbe(session_t *ps);
|
2012-10-24 10:09:59 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
init_overlay(session_t *ps);
|
|
|
|
|
|
|
|
static void
|
|
|
|
redir_start(session_t *ps);
|
|
|
|
|
|
|
|
static void
|
|
|
|
redir_stop(session_t *ps);
|
|
|
|
|
Feature #80: D-Bus support
- Add D-Bus support. Currently 7 methods are available: "reset" (same as
SIGUSR1), "list_win" (list the windows compton manages), "win_get"
(get a property of the window), "win_set" (set a property of the
window), "find_win" (find window based on client window / focus),
"opts_get" (get the value of a compton option), and "opts_set" (set
the value of a compton option), together with 4 signals: "win_added",
"win_destroyed", "win_mapped", "win_unmapped".
- D-Bus support depends on libdbus.
- As there are many items and my time is tight, no much tests are done.
Bugs to be expected.
- Create a new header file `common.h` that contains shared content.
- Fix some bugs in timeout handling.
- Update file headers in all source files.
- Re-enable --unredir-if-possible on multi-screen set-ups, as the user
could turn if off manually anyway.
- Check if the window is mapped in `repair_win()`.
- Add ps->track_atom_lst and its handlers, to prepare for the new
condition format.
- Known issue 1: "win_get", "win_set", "opts_get", "opts_set" support a
very limited number of targets only. New ones will be added gradually.
- Known issue 2: Accidental drop of D-Bus connection is not handled.
- Known issue 3: Introspection does not reveal all available methods,
because some methods have unpredictable prototypes. Still hesitating
about what to do...
- Known issue 4: Error handling is not finished yet. Compton does not
always reply with the correct error message (but it does print out the
correct error message, usually).
2013-01-19 20:20:27 +08:00
|
|
|
static inline time_ms_t
|
|
|
|
timeout_get_newrun(const timeout_t *ptmout) {
|
2013-01-29 09:57:04 +08:00
|
|
|
return ptmout->firstrun + (max_l((ptmout->lastrun + (time_ms_t) (ptmout->interval * TIMEOUT_RUN_TOLERANCE) - ptmout->firstrun) / ptmout->interval, (ptmout->lastrun + (time_ms_t) (ptmout->interval * (1 - TIMEOUT_RUN_TOLERANCE)) - ptmout->firstrun) / ptmout->interval) + 1) * ptmout->interval;
|
Feature #80: D-Bus support
- Add D-Bus support. Currently 7 methods are available: "reset" (same as
SIGUSR1), "list_win" (list the windows compton manages), "win_get"
(get a property of the window), "win_set" (set a property of the
window), "find_win" (find window based on client window / focus),
"opts_get" (get the value of a compton option), and "opts_set" (set
the value of a compton option), together with 4 signals: "win_added",
"win_destroyed", "win_mapped", "win_unmapped".
- D-Bus support depends on libdbus.
- As there are many items and my time is tight, no much tests are done.
Bugs to be expected.
- Create a new header file `common.h` that contains shared content.
- Fix some bugs in timeout handling.
- Update file headers in all source files.
- Re-enable --unredir-if-possible on multi-screen set-ups, as the user
could turn if off manually anyway.
- Check if the window is mapped in `repair_win()`.
- Add ps->track_atom_lst and its handlers, to prepare for the new
condition format.
- Known issue 1: "win_get", "win_set", "opts_get", "opts_set" support a
very limited number of targets only. New ones will be added gradually.
- Known issue 2: Accidental drop of D-Bus connection is not handled.
- Known issue 3: Introspection does not reveal all available methods,
because some methods have unpredictable prototypes. Still hesitating
about what to do...
- Known issue 4: Error handling is not finished yet. Compton does not
always reply with the correct error message (but it does print out the
correct error message, usually).
2013-01-19 20:20:27 +08:00
|
|
|
}
|
|
|
|
|
2013-01-11 21:31:02 +08:00
|
|
|
static time_ms_t
|
|
|
|
timeout_get_poll_time(session_t *ps);
|
|
|
|
|
|
|
|
static void
|
|
|
|
timeout_clear(session_t *ps);
|
|
|
|
|
2013-09-04 22:00:51 +08:00
|
|
|
static bool
|
|
|
|
tmout_unredir_callback(session_t *ps, timeout_t *tmout);
|
|
|
|
|
Improvement #74: Use libevent for main loop
- Use libevent for main loop. I will explain the reasons in #56 later.
The preferred libevent version is 2.x, yet 1.4.x should work as well.
- As a result, compton now should build fine on *BSD. Thanks to
DachiChang for the FreeBSD build issue report.
- Another consequence is we now use microsecond-level timing all the
way. Nanosecond-level code will be dropped soon. Start using long
instead of unsigned long to represent time in milliseconds, as both
can't hold the full epoch time in ms, anyway, and a signed type
requires less care in subtraction. Wrap the epoch time in ms to 15
days.
- Fix broken NO_VSYNC_DRM and NO_VSYNC_OPENGL compile-time options.
- Use git revision number for versioning in Makefile, and other small
improvements.
- Reorganize struct _win. Drop unused w->damaged_sequence. w->damaged is
turned to bool.
- Add type and format to winprop_t, as preparation for the new condition
format.
- Add w->shadow_force and w->focus_force, to prepare for D-Bus support.
- Rename wid_get_prop() to wid_get_prop_adv() with more options. Add
wrapper function wid_get_prop().
- Add some extra helper functions, for D-Bus support later.
- Make some functions return a bool value to indicate if it's
successful.
- Modify add_win(), use a static const structure to initialize the new
struct _win.
- Add some helper macros, like printf_err(f)(q). Make some errors fatal.
- Rename some types, constants, and functions. Code clean-up.
- Check for time disorder in paint_preprocess() when calculating fading
steps.
- Rename evpoll() to swopti_handle_timeout(), and partially rewrite it.
- Make -h / --help legal.
- Known issue: compton segfaults on FreeBSD with nvidia-drivers, unless
NO_VSYNC_OPENGL is used. Will look into it later. Thamls to DachiChang
for reporting.
2013-01-08 08:50:58 +08:00
|
|
|
static bool
|
|
|
|
mainloop(session_t *ps);
|
|
|
|
|
2013-08-22 21:15:04 +08:00
|
|
|
#ifdef CONFIG_XINERAMA
|
|
|
|
static void
|
|
|
|
cxinerama_upd_scrs(session_t *ps);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the Xinerama screen a window is on.
|
|
|
|
*
|
|
|
|
* Return an index >= 0, or -1 if not found.
|
|
|
|
*/
|
|
|
|
static inline void
|
|
|
|
cxinerama_win_upd_scr(session_t *ps, win *w) {
|
|
|
|
#ifdef CONFIG_XINERAMA
|
|
|
|
w->xinerama_scr = -1;
|
|
|
|
for (XineramaScreenInfo *s = ps->xinerama_scrs;
|
|
|
|
s < ps->xinerama_scrs + ps->xinerama_nscrs; ++s)
|
|
|
|
if (s->x_org <= w->a.x && s->y_org <= w->a.y
|
|
|
|
&& s->x_org + s->width >= w->a.x + w->widthb
|
|
|
|
&& s->y_org + s->height >= w->a.y + w->heightb) {
|
|
|
|
w->xinerama_scr = s - ps->xinerama_scrs;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2013-08-28 21:47:16 +08:00
|
|
|
static void
|
|
|
|
cxinerama_upd_scrs(session_t *ps);
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
static session_t *
|
|
|
|
session_init(session_t *ps_old, int argc, char **argv);
|
2012-10-24 10:09:59 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
session_destroy(session_t *ps);
|
2012-11-09 21:44:02 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
session_run(session_t *ps);
|
2012-11-09 21:44:02 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
reset_enable(int __attribute__((unused)) signum);
|