2018-10-04 05:14:51 +08:00
|
|
|
// SPDX-License-Identifier: MIT
|
2003-11-10 11:45:17 +08:00
|
|
|
/*
|
2012-02-27 12:00:12 +08:00
|
|
|
* Compton - a compositor for X11
|
2003-11-10 11:45:17 +08:00
|
|
|
*
|
2012-02-27 12:00:12 +08:00
|
|
|
* Based on `xcompmgr` - Copyright (c) 2003, Keith Packard
|
2003-11-10 11:45:17 +08:00
|
|
|
*
|
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
|
|
|
* Copyright (c) 2011-2013, Christopher Jeffrey
|
2018-10-04 05:24:12 +08:00
|
|
|
* See LICENSE-mit for more information.
|
2003-11-10 11:45:17 +08:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2018-09-07 02:17:26 +08:00
|
|
|
#include <ctype.h>
|
2018-09-09 09:29:45 +08:00
|
|
|
#include <string.h>
|
2018-11-11 05:52:42 +08:00
|
|
|
#include <X11/Xlib.h>
|
|
|
|
#include <X11/Xlibint.h>
|
2018-09-23 06:44:44 +08:00
|
|
|
#include <xcb/randr.h>
|
2018-11-04 06:15:38 +08:00
|
|
|
#include <xcb/present.h>
|
2018-09-23 06:44:44 +08:00
|
|
|
#include <xcb/damage.h>
|
2018-09-24 02:10:46 +08:00
|
|
|
#include <xcb/render.h>
|
|
|
|
#include <xcb/xcb_image.h>
|
2018-09-07 02:17:26 +08:00
|
|
|
|
2018-10-03 03:22:26 +08:00
|
|
|
#include <ev.h>
|
|
|
|
|
2012-02-08 18:31:39 +08:00
|
|
|
#include "compton.h"
|
2018-09-30 06:30:19 +08:00
|
|
|
#ifdef CONFIG_OPENGL
|
|
|
|
#include "opengl.h"
|
|
|
|
#endif
|
2018-09-07 02:17:26 +08:00
|
|
|
#include "win.h"
|
|
|
|
#include "x.h"
|
2018-08-22 19:58:49 +08:00
|
|
|
#include "config.h"
|
2018-11-04 06:15:38 +08:00
|
|
|
#include "diagnostic.h"
|
2018-09-07 02:17:26 +08:00
|
|
|
|
2018-11-11 05:52:42 +08:00
|
|
|
#define auto __auto_type
|
|
|
|
|
2018-11-27 08:32:08 +08:00
|
|
|
/// Get session_t pointer from a pointer to a member of session_t
|
|
|
|
#define session_ptr(ptr, member) ({ \
|
|
|
|
const __typeof__( ((session_t *)0)->member ) *__mptr = (ptr); \
|
|
|
|
(session_t *)((char *)__mptr - offsetof(session_t, member)); \
|
|
|
|
})
|
|
|
|
|
2018-09-23 06:44:44 +08:00
|
|
|
static void
|
2018-09-30 06:30:19 +08:00
|
|
|
finish_destroy_win(session_t *ps, win **_w);
|
2018-09-23 06:44:44 +08:00
|
|
|
|
2018-09-30 06:30:19 +08:00
|
|
|
static void
|
|
|
|
configure_win(session_t *ps, xcb_configure_notify_event_t *ce);
|
2018-09-07 02:17:26 +08:00
|
|
|
|
|
|
|
static void
|
|
|
|
get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass);
|
|
|
|
|
|
|
|
static void
|
|
|
|
update_refresh_rate(session_t *ps);
|
|
|
|
|
|
|
|
static bool
|
|
|
|
swopti_init(session_t *ps);
|
|
|
|
|
|
|
|
static void
|
|
|
|
cxinerama_upd_scrs(session_t *ps);
|
|
|
|
|
|
|
|
static void
|
|
|
|
session_destroy(session_t *ps);
|
|
|
|
|
|
|
|
#ifdef CONFIG_XINERAMA
|
|
|
|
static void
|
|
|
|
cxinerama_upd_scrs(session_t *ps);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static bool
|
|
|
|
vsync_drm_init(session_t *ps);
|
|
|
|
|
|
|
|
#ifdef CONFIG_VSYNC_DRM
|
|
|
|
static int
|
|
|
|
vsync_drm_wait(session_t *ps);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static bool
|
|
|
|
vsync_opengl_init(session_t *ps);
|
|
|
|
|
|
|
|
static bool
|
|
|
|
vsync_opengl_oml_init(session_t *ps);
|
|
|
|
|
|
|
|
static bool
|
|
|
|
vsync_opengl_swc_init(session_t *ps);
|
|
|
|
|
|
|
|
static bool
|
|
|
|
vsync_opengl_mswc_init(session_t *ps);
|
|
|
|
|
|
|
|
#ifdef CONFIG_OPENGL
|
|
|
|
static int
|
|
|
|
vsync_opengl_wait(session_t *ps);
|
|
|
|
|
|
|
|
static int
|
|
|
|
vsync_opengl_oml_wait(session_t *ps);
|
|
|
|
|
|
|
|
static void
|
|
|
|
vsync_opengl_swc_deinit(session_t *ps);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static void
|
|
|
|
vsync_wait(session_t *ps);
|
|
|
|
|
|
|
|
static void
|
|
|
|
redir_start(session_t *ps);
|
|
|
|
|
|
|
|
static void
|
|
|
|
redir_stop(session_t *ps);
|
|
|
|
|
|
|
|
static win *
|
|
|
|
recheck_focus(session_t *ps);
|
|
|
|
|
|
|
|
static bool
|
|
|
|
get_root_tile(session_t *ps);
|
|
|
|
|
|
|
|
static double
|
|
|
|
get_opacity_percent(win *w);
|
|
|
|
|
|
|
|
static void
|
|
|
|
restack_win(session_t *ps, win *w, Window new_above);
|
|
|
|
|
|
|
|
static void
|
|
|
|
update_ewmh_active_win(session_t *ps);
|
|
|
|
|
2018-10-03 03:22:26 +08:00
|
|
|
static void
|
|
|
|
draw_callback(EV_P_ ev_idle *w, int revents);
|
|
|
|
|
2018-11-04 06:38:18 +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,
|
|
|
|
xcb_render_picture_t pict, glx_texture_t *ptex,
|
|
|
|
const region_t *reg_paint, const glx_prog_main_t *pprogram);
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
// === Global constants ===
|
2012-02-27 12:00:12 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/// Name strings for window types.
|
2013-01-24 13:38:03 +08:00
|
|
|
const char * const WINTYPES[NUM_WINTYPES] = {
|
2012-09-25 21:04:10 +08:00
|
|
|
"unknown",
|
|
|
|
"desktop",
|
|
|
|
"dock",
|
|
|
|
"toolbar",
|
|
|
|
"menu",
|
|
|
|
"utility",
|
|
|
|
"splash",
|
|
|
|
"dialog",
|
|
|
|
"normal",
|
|
|
|
"dropdown_menu",
|
|
|
|
"popup_menu",
|
|
|
|
"tooltip",
|
|
|
|
"notify",
|
|
|
|
"combo",
|
|
|
|
"dnd",
|
|
|
|
};
|
|
|
|
|
2013-01-30 13:41:08 +08:00
|
|
|
/// Names of VSync modes.
|
2013-04-21 22:30:22 +08:00
|
|
|
const char * const VSYNC_STRS[NUM_VSYNC + 1] = {
|
2013-03-23 22:06:41 +08:00
|
|
|
"none", // VSYNC_NONE
|
|
|
|
"drm", // VSYNC_DRM
|
|
|
|
"opengl", // VSYNC_OPENGL
|
|
|
|
"opengl-oml", // VSYNC_OPENGL_OML
|
|
|
|
"opengl-swc", // VSYNC_OPENGL_SWC
|
|
|
|
"opengl-mswc", // VSYNC_OPENGL_MSWC
|
2013-04-21 22:30:22 +08:00
|
|
|
NULL
|
2013-01-30 13:41:08 +08:00
|
|
|
};
|
|
|
|
|
2013-03-16 22:54:43 +08:00
|
|
|
/// Names of backends.
|
2013-04-21 22:30:22 +08:00
|
|
|
const char * const BACKEND_STRS[NUM_BKEND + 1] = {
|
2013-03-16 22:54:43 +08:00
|
|
|
"xrender", // BKEND_XRENDER
|
|
|
|
"glx", // BKEND_GLX
|
2013-12-24 07:46:48 +08:00
|
|
|
"xr_glx_hybrid",// BKEND_XR_GLX_HYBRID
|
2013-04-21 22:30:22 +08:00
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
2013-01-30 13:41:08 +08:00
|
|
|
/// Function pointers to init VSync modes.
|
|
|
|
static bool (* const (VSYNC_FUNCS_INIT[NUM_VSYNC]))(session_t *ps) = {
|
2013-03-23 22:06:41 +08:00
|
|
|
[VSYNC_DRM ] = vsync_drm_init,
|
|
|
|
[VSYNC_OPENGL ] = vsync_opengl_init,
|
|
|
|
[VSYNC_OPENGL_OML ] = vsync_opengl_oml_init,
|
|
|
|
[VSYNC_OPENGL_SWC ] = vsync_opengl_swc_init,
|
|
|
|
[VSYNC_OPENGL_MSWC ] = vsync_opengl_mswc_init,
|
2013-01-30 13:41:08 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
/// Function pointers to wait for VSync.
|
|
|
|
static int (* const (VSYNC_FUNCS_WAIT[NUM_VSYNC]))(session_t *ps) = {
|
|
|
|
#ifdef CONFIG_VSYNC_DRM
|
|
|
|
[VSYNC_DRM ] = vsync_drm_wait,
|
|
|
|
#endif
|
2018-08-22 22:12:29 +08:00
|
|
|
#ifdef CONFIG_OPENGL
|
2013-01-30 13:41:08 +08:00
|
|
|
[VSYNC_OPENGL ] = vsync_opengl_wait,
|
|
|
|
[VSYNC_OPENGL_OML ] = vsync_opengl_oml_wait,
|
|
|
|
#endif
|
2013-01-24 13:38:03 +08:00
|
|
|
};
|
|
|
|
|
2013-05-20 18:04:40 +08:00
|
|
|
/// Function pointers to deinitialize VSync.
|
|
|
|
static void (* const (VSYNC_FUNCS_DEINIT[NUM_VSYNC]))(session_t *ps) = {
|
2018-08-22 22:12:29 +08:00
|
|
|
#ifdef CONFIG_OPENGL
|
2013-05-20 18:04:40 +08:00
|
|
|
[VSYNC_OPENGL_SWC ] = vsync_opengl_swc_deinit,
|
2018-12-15 01:21:05 +08:00
|
|
|
[VSYNC_OPENGL_MSWC ] = vsync_opengl_swc_deinit,
|
2013-05-20 18:04:40 +08:00
|
|
|
#endif
|
|
|
|
};
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/// Names of root window properties that could point to a pixmap of
|
|
|
|
/// background.
|
2018-08-22 22:26:08 +08:00
|
|
|
static const char *background_props_str[] = {
|
2012-02-09 06:45:08 +08:00
|
|
|
"_XROOTPMAP_ID",
|
|
|
|
"_XSETROOT_ID",
|
|
|
|
0,
|
|
|
|
};
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
// === Global variables ===
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/// Pointer to current session, as a global variable. Only used by
|
2018-11-27 07:56:55 +08:00
|
|
|
/// xerror(), which could not have a pointer to current session passed in.
|
|
|
|
/// XXX Limit what xerror can access by not having this pointer
|
2012-11-19 09:46:07 +08:00
|
|
|
session_t *ps_g = NULL;
|
2003-11-25 01:11:00 +08:00
|
|
|
|
2018-11-04 06:38:18 +08:00
|
|
|
/**
|
|
|
|
* Free Xinerama screen info.
|
|
|
|
*
|
|
|
|
* XXX consider moving to x.c
|
|
|
|
*/
|
|
|
|
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)
|
|
|
|
pixman_region32_fini(&ps->xinerama_scr_regs[i]);
|
|
|
|
free(ps->xinerama_scr_regs);
|
|
|
|
}
|
|
|
|
cxfree(ps->xinerama_scrs);
|
|
|
|
ps->xinerama_scrs = NULL;
|
|
|
|
ps->xinerama_nscrs = 0;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Destroy all resources in a <code>struct _win</code>.
|
|
|
|
*/
|
|
|
|
static inline void
|
|
|
|
free_win_res(session_t *ps, win *w) {
|
|
|
|
free_win_res_glx(ps, w);
|
|
|
|
free_paint(ps, &w->paint);
|
2018-11-08 22:53:13 +08:00
|
|
|
free_fence(ps, &w->fence);
|
2018-11-04 06:38:18 +08:00
|
|
|
pixman_region32_fini(&w->bounding_shape);
|
|
|
|
free_paint(ps, &w->shadow_paint);
|
|
|
|
// BadDamage may be thrown if the window is destroyed
|
|
|
|
set_ignore_cookie(ps,
|
|
|
|
xcb_damage_destroy(ps->c, w->damage));
|
|
|
|
rc_region_unref(&w->reg_ignore);
|
|
|
|
free(w->name);
|
|
|
|
free(w->class_instance);
|
|
|
|
free(w->class_general);
|
|
|
|
free(w->role);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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) {
|
|
|
|
xcb_free_pixmap(ps->c, ps->root_tile_paint.pixmap);
|
|
|
|
ps->root_tile_paint.pixmap = XCB_NONE;
|
|
|
|
}
|
|
|
|
ps->root_tile_paint.pixmap = None;
|
|
|
|
ps->root_tile_fill = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get current system clock in milliseconds.
|
|
|
|
*/
|
|
|
|
static inline time_ms_t
|
|
|
|
get_time_ms(void) {
|
|
|
|
struct timeval tv;
|
|
|
|
|
|
|
|
gettimeofday(&tv, NULL);
|
|
|
|
|
|
|
|
return tv.tv_sec % SEC_WRAP * 1000 + tv.tv_usec / 1000;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Resize a region.
|
|
|
|
*/
|
|
|
|
static inline void
|
|
|
|
resize_region(session_t *ps, region_t *region, short mod) {
|
|
|
|
if (!mod || !region) return;
|
|
|
|
// Loop through all rectangles
|
|
|
|
int nrects;
|
|
|
|
int nnewrects = 0;
|
|
|
|
pixman_box32_t *rects = pixman_region32_rectangles(region, &nrects);
|
|
|
|
pixman_box32_t *newrects = calloc(nrects, sizeof *newrects);
|
|
|
|
for (int i = 0; i < nrects; i++) {
|
|
|
|
int x1 = max_i(rects[i].x1 - mod, 0);
|
|
|
|
int y1 = max_i(rects[i].y1 - mod, 0);
|
|
|
|
int x2 = min_i(rects[i].x2 + mod, ps->root_width);
|
|
|
|
int y2 = min_i(rects[i].y2 + mod, ps->root_height);
|
|
|
|
int wid = x2 - x1;
|
|
|
|
int hei = y2 - y1;
|
|
|
|
if (wid <= 0 || hei <= 0)
|
|
|
|
continue;
|
|
|
|
newrects[nnewrects] = (pixman_box32_t) {
|
|
|
|
.x1 = x1, .x2 = x2, .y1 = y1, .y2 = y2
|
|
|
|
};
|
|
|
|
++nnewrects;
|
|
|
|
}
|
|
|
|
|
|
|
|
pixman_region32_fini(region);
|
|
|
|
pixman_region32_init_rects(region, newrects, nnewrects);
|
|
|
|
|
|
|
|
free(newrects);
|
|
|
|
}
|
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
static inline void
|
|
|
|
__attribute__((nonnull(1, 2)))
|
|
|
|
set_tgt_clip(session_t *ps, region_t *reg) {
|
|
|
|
switch (ps->o.backend) {
|
|
|
|
case BKEND_XRENDER:
|
|
|
|
case BKEND_XR_GLX_HYBRID:
|
|
|
|
x_set_picture_clip_region(ps, ps->tgt_buffer.pict, 0, 0, reg);
|
|
|
|
break;
|
|
|
|
#ifdef CONFIG_OPENGL
|
|
|
|
case BKEND_GLX:
|
|
|
|
glx_set_clip(ps, reg);
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
default:
|
|
|
|
assert(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-04 06:38:18 +08:00
|
|
|
/**
|
|
|
|
* Get the Xinerama screen a window is on.
|
|
|
|
*
|
|
|
|
* Return an index >= 0, or -1 if not found.
|
|
|
|
*
|
|
|
|
* XXX move to x.c
|
|
|
|
*/
|
|
|
|
static inline void
|
|
|
|
cxinerama_win_upd_scr(session_t *ps, win *w) {
|
|
|
|
#ifdef CONFIG_XINERAMA
|
|
|
|
w->xinerama_scr = -1;
|
|
|
|
|
|
|
|
if (!ps->xinerama_scrs)
|
|
|
|
return;
|
|
|
|
|
|
|
|
xcb_xinerama_screen_info_t *scrs = xcb_xinerama_query_screens_screen_info(ps->xinerama_scrs);
|
|
|
|
int length = xcb_xinerama_query_screens_screen_info_length(ps->xinerama_scrs);
|
|
|
|
for (int i = 0; i < length; i++) {
|
|
|
|
xcb_xinerama_screen_info_t *s = &scrs[i];
|
|
|
|
if (s->x_org <= w->g.x && s->y_org <= w->g.y
|
|
|
|
&& s->x_org + s->width >= w->g.x + w->widthb
|
|
|
|
&& s->y_org + s->height >= w->g.y + w->heightb) {
|
|
|
|
w->xinerama_scr = i;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
// XXX Move to x.c
|
|
|
|
static void
|
|
|
|
cxinerama_upd_scrs(session_t *ps) {
|
|
|
|
#ifdef CONFIG_XINERAMA
|
|
|
|
// XXX Consider deprecating Xinerama, switch to RandR when necessary
|
|
|
|
free_xinerama_info(ps);
|
|
|
|
|
|
|
|
if (!ps->o.xinerama_shadow_crop || !ps->xinerama_exists) return;
|
|
|
|
|
|
|
|
xcb_xinerama_is_active_reply_t *active =
|
|
|
|
xcb_xinerama_is_active_reply(ps->c,
|
|
|
|
xcb_xinerama_is_active(ps->c), NULL);
|
|
|
|
if (!active || !active->state) {
|
|
|
|
free(active);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
free(active);
|
|
|
|
|
|
|
|
ps->xinerama_scrs = xcb_xinerama_query_screens_reply(ps->c,
|
|
|
|
xcb_xinerama_query_screens(ps->c), NULL);
|
|
|
|
if (!ps->xinerama_scrs)
|
|
|
|
return;
|
|
|
|
|
|
|
|
xcb_xinerama_screen_info_t *scrs = xcb_xinerama_query_screens_screen_info(ps->xinerama_scrs);
|
|
|
|
ps->xinerama_nscrs = xcb_xinerama_query_screens_screen_info_length(ps->xinerama_scrs);
|
|
|
|
|
|
|
|
ps->xinerama_scr_regs = allocchk(malloc(sizeof(region_t)
|
|
|
|
* ps->xinerama_nscrs));
|
|
|
|
for (int i = 0; i < ps->xinerama_nscrs; ++i) {
|
|
|
|
const xcb_xinerama_screen_info_t * const s = &scrs[i];
|
|
|
|
pixman_region32_init_rect(&ps->xinerama_scr_regs[i], s->x_org, s->y_org, s->width, s->height);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Find matched window.
|
|
|
|
*
|
|
|
|
* XXX move to win.c
|
|
|
|
*/
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2018-10-03 03:22:26 +08:00
|
|
|
void queue_redraw(session_t *ps) {
|
|
|
|
// If --benchmark is used, redraw is always queued
|
|
|
|
if (!ps->redraw_needed && !ps->o.benchmark)
|
2018-11-27 08:32:08 +08:00
|
|
|
ev_idle_start(ps->loop, &ps->draw_idle);
|
2018-10-03 03:22:26 +08:00
|
|
|
ps->redraw_needed = true;
|
|
|
|
}
|
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
static inline void
|
|
|
|
paint_region(session_t *ps, win *w, int x, int y, int wid, int hei,
|
|
|
|
double opacity, const region_t *reg_paint, xcb_render_picture_t pict) {
|
|
|
|
const int dx = (w ? w->g.x: 0) + x;
|
|
|
|
const int dy = (w ? w->g.y: 0) + y;
|
|
|
|
const bool argb = (w && (win_has_alpha(w) || ps->o.force_win_blend));
|
|
|
|
const bool neg = (w && w->invert_color);
|
|
|
|
|
|
|
|
render(ps, x, y, dx, dy, wid, hei, opacity, argb, neg,
|
|
|
|
pict, (w ? w->paint.ptex: ps->root_tile_paint.ptex),
|
|
|
|
reg_paint, (w ? &ps->o.glx_prog_win: NULL));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get a region of the screen size.
|
|
|
|
*/
|
|
|
|
static inline void
|
|
|
|
get_screen_region(session_t *ps, region_t *res) {
|
|
|
|
pixman_box32_t b = {
|
|
|
|
.x1 = 0, .y1 = 0,
|
|
|
|
.x2 = ps->root_width,
|
|
|
|
.y2 = ps->root_height
|
|
|
|
};
|
|
|
|
pixman_region32_fini(res);
|
|
|
|
pixman_region32_init_rects(res, &b, 1);
|
|
|
|
}
|
|
|
|
|
2018-09-24 02:10:46 +08:00
|
|
|
/**
|
|
|
|
* Check if current backend uses XRender for rendering.
|
|
|
|
*/
|
|
|
|
static inline bool
|
|
|
|
bkend_use_xrender(session_t *ps) {
|
|
|
|
return BKEND_XRENDER == ps->o.backend
|
|
|
|
|| BKEND_XR_GLX_HYBRID == ps->o.backend;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check whether a paint_t contains enough data.
|
|
|
|
*/
|
|
|
|
static inline bool
|
|
|
|
paint_isvalid(session_t *ps, const paint_t *ppaint) {
|
|
|
|
// Don't check for presence of Pixmap here, because older X Composite doesn't
|
|
|
|
// provide it
|
|
|
|
if (!ppaint)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (bkend_use_xrender(ps) && !ppaint->pict)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
#ifdef CONFIG_OPENGL
|
|
|
|
if (BKEND_GLX == ps->o.backend && !glx_tex_binded(ppaint->ptex, None))
|
|
|
|
return false;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
void add_damage(session_t *ps, const region_t *damage) {
|
2018-09-09 09:29:45 +08:00
|
|
|
// Ignore damage when screen isn't redirected
|
|
|
|
if (!ps->redirected)
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
return;
|
2018-09-09 09:29:45 +08:00
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
if (!damage)
|
|
|
|
return;
|
|
|
|
pixman_region32_union(&ps->all_damage, &ps->all_damage, (region_t *)damage);
|
2018-09-09 09:29:45 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
// === Fading ===
|
2012-09-26 15:37:11 +08:00
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
/**
|
|
|
|
* Get the time left before next fading point.
|
|
|
|
*
|
|
|
|
* In milliseconds.
|
|
|
|
*/
|
2018-10-03 03:22:26 +08:00
|
|
|
static double
|
2012-11-19 09:46:07 +08:00
|
|
|
fade_timeout(session_t *ps) {
|
|
|
|
int diff = ps->o.fade_delta - get_time_ms() + ps->fade_time;
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2013-01-11 21:31:02 +08:00
|
|
|
diff = normalize_i_range(diff, 0, ps->o.fade_delta * 2);
|
2004-07-08 15:07:26 +08:00
|
|
|
|
2018-10-03 03:22:26 +08:00
|
|
|
return diff / 1000.0;
|
2004-07-08 15:07:26 +08:00
|
|
|
}
|
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
/**
|
|
|
|
* Run fading on a window.
|
|
|
|
*
|
|
|
|
* @param steps steps of fading
|
|
|
|
*/
|
2012-02-27 12:00:12 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
run_fade(session_t *ps, win *w, unsigned steps) {
|
2012-10-29 22:00:11 +08:00
|
|
|
// If we have reached target opacity, return
|
2012-09-19 20:49:16 +08:00
|
|
|
if (w->opacity == w->opacity_tgt) {
|
|
|
|
return;
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
2004-07-08 15:07:26 +08:00
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
if (!w->fade)
|
|
|
|
w->opacity = w->opacity_tgt;
|
|
|
|
else if (steps) {
|
|
|
|
// Use double below because opacity_t will probably overflow during
|
|
|
|
// calculations
|
|
|
|
if (w->opacity < w->opacity_tgt)
|
|
|
|
w->opacity = normalize_d_range(
|
2012-11-19 09:46:07 +08:00
|
|
|
(double) w->opacity + (double) ps->o.fade_in_step * steps,
|
2012-09-19 20:49:16 +08:00
|
|
|
0.0, w->opacity_tgt);
|
|
|
|
else
|
|
|
|
w->opacity = normalize_d_range(
|
2012-11-19 09:46:07 +08:00
|
|
|
(double) w->opacity - (double) ps->o.fade_out_step * steps,
|
2012-09-19 20:49:16 +08:00
|
|
|
w->opacity_tgt, OPAQUE);
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
2004-07-08 15:07:26 +08:00
|
|
|
|
2012-10-29 22:00:11 +08:00
|
|
|
if (w->opacity != w->opacity_tgt) {
|
2018-10-03 03:22:26 +08:00
|
|
|
ps->fade_running = true;
|
2012-09-29 22:53:57 +08:00
|
|
|
}
|
2004-07-08 15:07:26 +08:00
|
|
|
}
|
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
/**
|
|
|
|
* Set fade callback of a window, and possibly execute the previous
|
|
|
|
* callback.
|
|
|
|
*
|
2018-10-03 03:22:26 +08:00
|
|
|
* If a callback can cause rendering result to change, it should call
|
|
|
|
* `queue_redraw`.
|
|
|
|
*
|
2012-09-19 20:49:16 +08:00
|
|
|
* @param exec_callback whether the previous callback is to be executed
|
|
|
|
*/
|
2018-09-30 06:30:19 +08:00
|
|
|
void set_fade_callback(session_t *ps, win **_w,
|
|
|
|
void (*callback) (session_t *ps, win **w), bool exec_callback) {
|
|
|
|
win *w = *_w;
|
|
|
|
void (*old_callback) (session_t *ps, win **w) = w->fade_callback;
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
w->fade_callback = callback;
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
// Must be the last line as the callback could destroy w!
|
2018-10-03 03:22:26 +08:00
|
|
|
if (exec_callback && old_callback)
|
2018-09-30 06:30:19 +08:00
|
|
|
old_callback(ps, _w);
|
2004-07-08 15:07:26 +08:00
|
|
|
}
|
|
|
|
|
2018-09-30 06:30:19 +08:00
|
|
|
/**
|
|
|
|
* Execute fade callback of a window if fading finished.
|
|
|
|
* XXX should be in win.c
|
|
|
|
*/
|
|
|
|
static inline void
|
|
|
|
check_fade_fin(session_t *ps, win **_w) {
|
|
|
|
win *w = *_w;
|
|
|
|
if (w->fade_callback && w->opacity == w->opacity_tgt) {
|
|
|
|
// Must be the last line as the callback could destroy w!
|
|
|
|
set_fade_callback(ps, _w, NULL, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
// === Shadows ===
|
2012-02-09 06:45:08 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
static double __attribute__((const))
|
2011-11-04 14:33:23 +08:00
|
|
|
gaussian(double r, double x, double y) {
|
2018-12-09 10:04:00 +08:00
|
|
|
// Formula can be found here:
|
|
|
|
// https://en.wikipedia.org/wiki/Gaussian_blur#Mathematics
|
|
|
|
// Except a special case for r == 0 to produce sharp shadows
|
|
|
|
if (r == 0)
|
|
|
|
return 1;
|
|
|
|
return exp(-0.5*(x*x+y*y)/(r*r))/(2*M_PI*r*r);
|
2003-11-10 09:32:01 +08:00
|
|
|
}
|
|
|
|
|
2003-11-20 00:12:15 +08:00
|
|
|
static conv *
|
2012-11-19 09:46:07 +08:00
|
|
|
make_gaussian_map(double r) {
|
2011-11-04 16:41:56 +08:00
|
|
|
conv *c;
|
2018-12-09 10:04:00 +08:00
|
|
|
int size = r*2+1;
|
|
|
|
int center = size/2;
|
2011-11-04 16:41:56 +08:00
|
|
|
double t;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2018-12-09 10:04:00 +08:00
|
|
|
c = malloc(sizeof(conv)+size*size*sizeof(double));
|
2011-11-04 14:33:23 +08:00
|
|
|
c->size = size;
|
|
|
|
t = 0.0;
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2018-12-09 10:04:00 +08:00
|
|
|
/*printf_errf("(): %f", r);*/
|
|
|
|
for (int y = 0; y < size; y++) {
|
|
|
|
for (int x = 0; x < size; x++) {
|
|
|
|
double g = gaussian(r, x-center, y-center);
|
2011-11-04 14:33:23 +08:00
|
|
|
t += g;
|
2018-12-09 10:04:00 +08:00
|
|
|
c->data[y*size+x] = g;
|
|
|
|
/*printf("%f ", c->data[y*size+x]);*/
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2018-12-09 10:04:00 +08:00
|
|
|
/*printf("\n");*/
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
|
|
|
|
2018-12-09 10:04:00 +08:00
|
|
|
for (int y = 0; y < size; y++) {
|
|
|
|
for (int x = 0; x < size; x++) {
|
|
|
|
c->data[y*size+x] /= t;
|
|
|
|
/*printf("%f ", c->data[y*size+x]);*/
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2018-12-09 10:04:00 +08:00
|
|
|
/*printf("\n");*/
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
return c;
|
2003-11-10 09:32:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* A picture will help
|
|
|
|
*
|
2011-11-04 17:01:45 +08:00
|
|
|
* -center 0 width width+center
|
2003-11-10 09:32:01 +08:00
|
|
|
* -center +-----+-------------------+-----+
|
2011-11-04 17:01:45 +08:00
|
|
|
* | | | |
|
|
|
|
* | | | |
|
|
|
|
* 0 +-----+-------------------+-----+
|
|
|
|
* | | | |
|
|
|
|
* | | | |
|
|
|
|
* | | | |
|
2003-11-10 09:32:01 +08:00
|
|
|
* height +-----+-------------------+-----+
|
2011-11-04 17:01:45 +08:00
|
|
|
* | | | |
|
|
|
|
* height+ | | | |
|
2003-11-10 09:32:01 +08:00
|
|
|
* center +-----+-------------------+-----+
|
|
|
|
*/
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2003-11-20 00:12:15 +08:00
|
|
|
static unsigned char
|
2011-11-04 17:18:10 +08:00
|
|
|
sum_gaussian(conv *map, double opacity,
|
|
|
|
int x, int y, int width, int height) {
|
2011-11-04 16:41:56 +08:00
|
|
|
int fx, fy;
|
|
|
|
double *g_data;
|
|
|
|
double *g_line = map->data;
|
|
|
|
int g_size = map->size;
|
|
|
|
int center = g_size / 2;
|
|
|
|
int fx_start, fx_end;
|
|
|
|
int fy_start, fy_end;
|
|
|
|
double v;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Compute set of filter values which are "in range",
|
|
|
|
* that's the set with:
|
|
|
|
* 0 <= x + (fx-center) && x + (fx-center) < width &&
|
|
|
|
* 0 <= y + (fy-center) && y + (fy-center) < height
|
|
|
|
*
|
|
|
|
* 0 <= x + (fx - center) x + fx - center < width
|
|
|
|
* center - x <= fx fx < width + center - x
|
|
|
|
*/
|
|
|
|
|
|
|
|
fx_start = center - x;
|
2011-11-04 16:41:56 +08:00
|
|
|
if (fx_start < 0) fx_start = 0;
|
2011-11-04 14:33:23 +08:00
|
|
|
fx_end = width + center - x;
|
2011-11-04 16:41:56 +08:00
|
|
|
if (fx_end > g_size) fx_end = g_size;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
|
|
|
fy_start = center - y;
|
2011-11-04 16:41:56 +08:00
|
|
|
if (fy_start < 0) fy_start = 0;
|
2011-11-04 14:33:23 +08:00
|
|
|
fy_end = height + center - y;
|
2011-11-04 16:41:56 +08:00
|
|
|
if (fy_end > g_size) fy_end = g_size;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
|
|
|
g_line = g_line + fy_start * g_size + fx_start;
|
|
|
|
|
|
|
|
v = 0;
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
for (fy = fy_start; fy < fy_end; fy++) {
|
|
|
|
g_data = g_line;
|
|
|
|
g_line += g_size;
|
|
|
|
|
2011-11-04 16:41:56 +08:00
|
|
|
for (fx = fx_start; fx < fx_end; fx++) {
|
2011-11-04 14:33:23 +08:00
|
|
|
v += *g_data++;
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
|
|
|
if (v > 1) v = 1;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
|
|
|
return ((unsigned char) (v * opacity * 255.0));
|
2003-11-10 09:32:01 +08:00
|
|
|
}
|
|
|
|
|
2011-11-04 17:18:10 +08:00
|
|
|
/* precompute shadow corners and sides
|
|
|
|
to save time for large windows */
|
2012-02-27 20:49:50 +08:00
|
|
|
|
2004-09-22 06:59:38 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
presum_gaussian(session_t *ps, conv *map) {
|
2012-02-27 20:49:50 +08:00
|
|
|
int center = map->size / 2;
|
2011-11-04 14:33:23 +08:00
|
|
|
int opacity, x, y;
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->cgsize = map->size;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->shadow_corner)
|
|
|
|
free(ps->shadow_corner);
|
|
|
|
if (ps->shadow_top)
|
|
|
|
free(ps->shadow_top);
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->shadow_corner = malloc((ps->cgsize + 1) * (ps->cgsize + 1) * 26);
|
|
|
|
ps->shadow_top = malloc((ps->cgsize + 1) * 26);
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
for (x = 0; x <= ps->cgsize; x++) {
|
|
|
|
ps->shadow_top[25 * (ps->cgsize + 1) + x] =
|
|
|
|
sum_gaussian(map, 1, x - center, center, ps->cgsize * 2, ps->cgsize * 2);
|
2011-11-04 16:41:56 +08:00
|
|
|
|
|
|
|
for (opacity = 0; opacity < 25; opacity++) {
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->shadow_top[opacity * (ps->cgsize + 1) + x] =
|
|
|
|
ps->shadow_top[25 * (ps->cgsize + 1) + x] * opacity / 25;
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
for (y = 0; y <= x; y++) {
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->shadow_corner[25 * (ps->cgsize + 1) * (ps->cgsize + 1) + y * (ps->cgsize + 1) + x]
|
|
|
|
= sum_gaussian(map, 1, x - center, y - center, ps->cgsize * 2, ps->cgsize * 2);
|
|
|
|
ps->shadow_corner[25 * (ps->cgsize + 1) * (ps->cgsize + 1) + x * (ps->cgsize + 1) + y]
|
|
|
|
= ps->shadow_corner[25 * (ps->cgsize + 1) * (ps->cgsize + 1) + y * (ps->cgsize + 1) + x];
|
2011-11-04 16:41:56 +08:00
|
|
|
|
|
|
|
for (opacity = 0; opacity < 25; opacity++) {
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->shadow_corner[opacity * (ps->cgsize + 1) * (ps->cgsize + 1)
|
|
|
|
+ y * (ps->cgsize + 1) + x]
|
|
|
|
= ps->shadow_corner[opacity * (ps->cgsize + 1) * (ps->cgsize + 1)
|
|
|
|
+ x * (ps->cgsize + 1) + y]
|
|
|
|
= ps->shadow_corner[25 * (ps->cgsize + 1) * (ps->cgsize + 1)
|
|
|
|
+ y * (ps->cgsize + 1) + x] * opacity / 25;
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
|
|
|
}
|
2004-09-22 06:59:38 +08:00
|
|
|
}
|
|
|
|
|
2018-09-24 02:10:46 +08:00
|
|
|
static xcb_image_t *
|
2012-11-19 09:46:07 +08:00
|
|
|
make_shadow(session_t *ps, double opacity,
|
|
|
|
int width, int height) {
|
2018-09-24 02:10:46 +08:00
|
|
|
xcb_image_t *ximage;
|
2011-11-04 16:41:56 +08:00
|
|
|
int ylimit, xlimit;
|
2012-11-19 09:46:07 +08:00
|
|
|
int swidth = width + ps->cgsize;
|
|
|
|
int sheight = height + ps->cgsize;
|
|
|
|
int center = ps->cgsize / 2;
|
2011-11-04 16:41:56 +08:00
|
|
|
int x, y;
|
|
|
|
unsigned char d;
|
|
|
|
int x_diff;
|
|
|
|
int opacity_int = (int)(opacity * 25);
|
|
|
|
|
2018-10-03 21:27:48 +08:00
|
|
|
ximage = xcb_image_create_native(ps->c, swidth, sheight, XCB_IMAGE_FORMAT_Z_PIXMAP, 8,
|
2018-09-24 02:10:46 +08:00
|
|
|
0, 0, NULL);
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
if (!ximage) {
|
2018-09-24 02:10:46 +08:00
|
|
|
printf_errf("(): failed to create an X image");
|
2011-11-04 14:33:23 +08:00
|
|
|
return 0;
|
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2018-09-24 02:10:46 +08:00
|
|
|
unsigned char *data = ximage->data;
|
|
|
|
uint32_t sstride = ximage->stride;
|
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
/*
|
|
|
|
* Build the gaussian in sections
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* center (fill the complete data array)
|
|
|
|
*/
|
2011-11-04 17:18:10 +08:00
|
|
|
|
2018-09-24 07:13:08 +08:00
|
|
|
// XXX If the center part of the shadow would be entirely covered by
|
|
|
|
// the body of the window, we shouldn't need to fill the center here.
|
|
|
|
// XXX In general, we want to just fill the part that is not behind
|
|
|
|
// the window, in order to reduce CPU load and make transparent window
|
|
|
|
// look correct
|
|
|
|
if (ps->cgsize > 0) {
|
|
|
|
d = ps->shadow_top[opacity_int * (ps->cgsize + 1) + ps->cgsize];
|
|
|
|
} else {
|
|
|
|
d = sum_gaussian(ps->gaussian_map,
|
|
|
|
opacity, center, center, width, height);
|
|
|
|
}
|
|
|
|
memset(data, d, sheight * swidth);
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
/*
|
|
|
|
* corners
|
|
|
|
*/
|
2011-11-04 17:18:10 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
ylimit = ps->cgsize;
|
2011-11-04 16:41:56 +08:00
|
|
|
if (ylimit > sheight / 2) ylimit = (sheight + 1) / 2;
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
xlimit = ps->cgsize;
|
2011-11-04 16:41:56 +08:00
|
|
|
if (xlimit > swidth / 2) xlimit = (swidth + 1) / 2;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-02-27 12:00:12 +08:00
|
|
|
for (y = 0; y < ylimit; y++) {
|
2011-11-04 14:33:23 +08:00
|
|
|
for (x = 0; x < xlimit; x++) {
|
2012-11-19 09:46:07 +08:00
|
|
|
if (xlimit == ps->cgsize && ylimit == ps->cgsize) {
|
|
|
|
d = ps->shadow_corner[opacity_int * (ps->cgsize + 1) * (ps->cgsize + 1)
|
|
|
|
+ y * (ps->cgsize + 1) + x];
|
2011-11-04 16:41:56 +08:00
|
|
|
} else {
|
2012-11-19 09:46:07 +08:00
|
|
|
d = sum_gaussian(ps->gaussian_map,
|
2011-11-04 17:18:10 +08:00
|
|
|
opacity, x - center, y - center, width, height);
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
2018-09-24 02:10:46 +08:00
|
|
|
data[y * sstride + x] = d;
|
|
|
|
data[(sheight - y - 1) * sstride + x] = d;
|
|
|
|
data[(sheight - y - 1) * sstride + (swidth - x - 1)] = d;
|
|
|
|
data[y * sstride + (swidth - x - 1)] = d;
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2012-02-27 12:00:12 +08:00
|
|
|
}
|
2011-11-04 14:33:23 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* top/bottom
|
|
|
|
*/
|
2011-11-04 17:18:10 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
x_diff = swidth - (ps->cgsize * 2);
|
2011-11-04 14:33:23 +08:00
|
|
|
if (x_diff > 0 && ylimit > 0) {
|
|
|
|
for (y = 0; y < ylimit; y++) {
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ylimit == ps->cgsize) {
|
|
|
|
d = ps->shadow_top[opacity_int * (ps->cgsize + 1) + y];
|
2011-11-04 16:41:56 +08:00
|
|
|
} else {
|
2012-11-19 09:46:07 +08:00
|
|
|
d = sum_gaussian(ps->gaussian_map,
|
2011-11-04 17:18:10 +08:00
|
|
|
opacity, center, y - center, width, height);
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
2018-09-24 02:10:46 +08:00
|
|
|
memset(&data[y * sstride + ps->cgsize], d, x_diff);
|
|
|
|
memset(&data[(sheight - y - 1) * sstride + ps->cgsize], d, x_diff);
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* sides
|
|
|
|
*/
|
|
|
|
|
|
|
|
for (x = 0; x < xlimit; x++) {
|
2012-11-19 09:46:07 +08:00
|
|
|
if (xlimit == ps->cgsize) {
|
|
|
|
d = ps->shadow_top[opacity_int * (ps->cgsize + 1) + x];
|
2011-11-04 16:41:56 +08:00
|
|
|
} else {
|
2012-11-19 09:46:07 +08:00
|
|
|
d = sum_gaussian(ps->gaussian_map,
|
2011-11-04 17:18:10 +08:00
|
|
|
opacity, x - center, center, width, height);
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
2012-11-19 09:46:07 +08:00
|
|
|
for (y = ps->cgsize; y < sheight - ps->cgsize; y++) {
|
2018-09-24 02:10:46 +08:00
|
|
|
data[y * sstride + x] = d;
|
|
|
|
data[y * sstride + (swidth - x - 1)] = d;
|
2003-11-10 09:32:01 +08:00
|
|
|
}
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2003-11-10 09:32:01 +08:00
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
return ximage;
|
2003-11-10 09:32:01 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* Generate shadow <code>Picture</code> for a window.
|
|
|
|
*/
|
2013-03-15 23:16:23 +08:00
|
|
|
static bool
|
|
|
|
win_build_shadow(session_t *ps, win *w, double opacity) {
|
|
|
|
const int width = w->widthb;
|
|
|
|
const int height = w->heightb;
|
2018-10-13 08:17:59 +08:00
|
|
|
//printf_errf("(): building shadow for %s %d %d", w->name, width, height);
|
2013-03-15 23:16:23 +08:00
|
|
|
|
2018-09-24 02:10:46 +08:00
|
|
|
xcb_image_t *shadow_image = NULL;
|
2018-10-01 03:53:52 +08:00
|
|
|
xcb_pixmap_t shadow_pixmap = None, shadow_pixmap_argb = None;
|
2018-09-28 00:14:44 +08:00
|
|
|
xcb_render_picture_t shadow_picture = None, shadow_picture_argb = None;
|
2018-10-03 20:01:18 +08:00
|
|
|
xcb_gcontext_t gc = None;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
shadow_image = make_shadow(ps, opacity, width, height);
|
2018-09-24 02:10:46 +08:00
|
|
|
if (!shadow_image) {
|
|
|
|
printf_errf("(): failed to make shadow");
|
2012-09-29 13:15:09 +08:00
|
|
|
return None;
|
2018-09-24 02:10:46 +08:00
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2018-10-01 03:53:52 +08:00
|
|
|
shadow_pixmap = x_create_pixmap(ps, 8, ps->root, shadow_image->width, shadow_image->height);
|
|
|
|
shadow_pixmap_argb = x_create_pixmap(ps, 32, ps->root, shadow_image->width, shadow_image->height);
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2018-09-24 02:10:46 +08:00
|
|
|
if (!shadow_pixmap || !shadow_pixmap_argb) {
|
|
|
|
printf_errf("(): failed to create shadow pixmaps");
|
2012-09-29 13:15:09 +08:00
|
|
|
goto shadow_picture_err;
|
2018-09-24 02:10:46 +08:00
|
|
|
}
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2018-09-24 02:10:46 +08:00
|
|
|
shadow_picture = x_create_picture_with_standard_and_pixmap(ps,
|
|
|
|
XCB_PICT_STANDARD_A_8, shadow_pixmap, 0, NULL);
|
|
|
|
shadow_picture_argb = x_create_picture_with_standard_and_pixmap(ps,
|
|
|
|
XCB_PICT_STANDARD_ARGB_32, shadow_pixmap_argb, 0, NULL);
|
2012-09-29 13:15:09 +08:00
|
|
|
if (!shadow_picture || !shadow_picture_argb)
|
|
|
|
goto shadow_picture_err;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2018-10-03 21:27:48 +08:00
|
|
|
gc = xcb_generate_id(ps->c);
|
|
|
|
xcb_create_gc(ps->c, gc, shadow_pixmap, 0, NULL);
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_image_put(ps->c, shadow_pixmap, gc, shadow_image, 0, 0, 0);
|
|
|
|
xcb_render_composite(ps->c, XCB_RENDER_PICT_OP_SRC, ps->cshadow_picture, shadow_picture,
|
2012-09-29 13:15:09 +08:00
|
|
|
shadow_picture_argb, 0, 0, 0, 0, 0, 0,
|
|
|
|
shadow_image->width, shadow_image->height);
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2014-08-03 19:40:40 +08:00
|
|
|
assert(!w->shadow_paint.pixmap);
|
2013-03-15 23:16:23 +08:00
|
|
|
w->shadow_paint.pixmap = shadow_pixmap_argb;
|
2014-08-03 19:40:40 +08:00
|
|
|
assert(!w->shadow_paint.pict);
|
2013-03-15 23:16:23 +08:00
|
|
|
w->shadow_paint.pict = shadow_picture_argb;
|
2013-03-18 11:48:28 +08:00
|
|
|
|
2018-11-08 22:53:13 +08:00
|
|
|
// Sync it once and only once
|
|
|
|
xr_sync(ps, w->shadow_paint.pixmap, NULL);
|
|
|
|
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_free_gc(ps->c, gc);
|
2018-09-24 02:10:46 +08:00
|
|
|
xcb_image_destroy(shadow_image);
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_free_pixmap(ps->c, shadow_pixmap);
|
|
|
|
xcb_render_free_picture(ps->c, shadow_picture);
|
2012-09-29 13:15:09 +08:00
|
|
|
|
2014-07-28 12:50:15 +08:00
|
|
|
return true;
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-09-29 13:15:09 +08:00
|
|
|
shadow_picture_err:
|
|
|
|
if (shadow_image)
|
2018-09-24 02:10:46 +08:00
|
|
|
xcb_image_destroy(shadow_image);
|
2012-09-29 13:15:09 +08:00
|
|
|
if (shadow_pixmap)
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_free_pixmap(ps->c, shadow_pixmap);
|
2012-09-29 13:15:09 +08:00
|
|
|
if (shadow_pixmap_argb)
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_free_pixmap(ps->c, shadow_pixmap_argb);
|
2012-09-29 13:15:09 +08:00
|
|
|
if (shadow_picture)
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_render_free_picture(ps->c, shadow_picture);
|
2012-09-29 13:15:09 +08:00
|
|
|
if (shadow_picture_argb)
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_render_free_picture(ps->c, shadow_picture_argb);
|
2012-09-29 13:15:09 +08:00
|
|
|
if (gc)
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_free_gc(ps->c, gc);
|
2013-03-15 23:16:23 +08:00
|
|
|
|
|
|
|
return false;
|
2003-11-10 09:32:01 +08:00
|
|
|
}
|
2003-11-09 15:08:23 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* Generate a 1x1 <code>Picture</code> of a particular color.
|
|
|
|
*/
|
2018-09-28 00:14:44 +08:00
|
|
|
static xcb_render_picture_t
|
2012-11-19 09:46:07 +08:00
|
|
|
solid_picture(session_t *ps, bool argb, double a,
|
2011-11-04 17:18:10 +08:00
|
|
|
double r, double g, double b) {
|
2018-10-01 03:53:52 +08:00
|
|
|
xcb_pixmap_t pixmap;
|
2018-09-28 00:14:44 +08:00
|
|
|
xcb_render_picture_t picture;
|
2018-09-24 02:10:46 +08:00
|
|
|
xcb_render_create_picture_value_list_t pa;
|
2018-09-28 00:14:44 +08:00
|
|
|
xcb_render_color_t col;
|
|
|
|
xcb_rectangle_t rect;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2018-10-01 03:53:52 +08:00
|
|
|
pixmap = x_create_pixmap(ps, argb ? 32 : 8, ps->root, 1, 1);
|
2011-11-04 16:41:56 +08:00
|
|
|
if (!pixmap) return None;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
|
|
|
pa.repeat = True;
|
2018-09-24 02:10:46 +08:00
|
|
|
picture = x_create_picture_with_standard_and_pixmap(ps,
|
|
|
|
argb ? XCB_PICT_STANDARD_ARGB_32 : XCB_PICT_STANDARD_A_8, pixmap,
|
2018-09-28 00:14:44 +08:00
|
|
|
XCB_RENDER_CP_REPEAT, &pa);
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
if (!picture) {
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_free_pixmap(ps->c, pixmap);
|
2011-11-04 14:33:23 +08:00
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
2018-09-28 00:14:44 +08:00
|
|
|
col.alpha = a * 0xffff;
|
|
|
|
col.red = r * 0xffff;
|
|
|
|
col.green = g * 0xffff;
|
|
|
|
col.blue = b * 0xffff;
|
|
|
|
|
|
|
|
rect.x = 0;
|
|
|
|
rect.y = 0;
|
|
|
|
rect.width = 1;
|
|
|
|
rect.height = 1;
|
2011-11-05 05:18:56 +08:00
|
|
|
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_render_fill_rectangles(ps->c, XCB_RENDER_PICT_OP_SRC, picture, col, 1, &rect);
|
|
|
|
xcb_free_pixmap(ps->c, pixmap);
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
return picture;
|
2004-06-27 12:48:37 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
// === Error handling ===
|
2012-02-09 06:45:08 +08:00
|
|
|
|
2012-02-27 12:00:12 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
discard_ignore(session_t *ps, unsigned long sequence) {
|
|
|
|
while (ps->ignore_head) {
|
2018-09-09 09:29:45 +08:00
|
|
|
if (sequence > ps->ignore_head->sequence) {
|
2012-11-19 09:46:07 +08:00
|
|
|
ignore_t *next = ps->ignore_head->next;
|
|
|
|
free(ps->ignore_head);
|
|
|
|
ps->ignore_head = next;
|
|
|
|
if (!ps->ignore_head) {
|
|
|
|
ps->ignore_tail = &ps->ignore_head;
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
|
|
|
} else {
|
2011-11-04 14:33:23 +08:00
|
|
|
break;
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2004-06-27 12:48:37 +08:00
|
|
|
}
|
|
|
|
|
2012-02-27 12:00:12 +08:00
|
|
|
static int
|
2012-11-19 09:46:07 +08:00
|
|
|
should_ignore(session_t *ps, unsigned long sequence) {
|
|
|
|
discard_ignore(ps, sequence);
|
|
|
|
return ps->ignore_head && ps->ignore_head->sequence == sequence;
|
2004-06-27 12:48:37 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
// === Windows ===
|
2012-02-09 06:45:08 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* Determine the event mask for a window.
|
|
|
|
*/
|
2018-09-07 02:17:26 +08:00
|
|
|
long determine_evmask(session_t *ps, Window wid, win_evmode_t mode) {
|
2018-10-04 15:15:38 +08:00
|
|
|
long evmask = 0;
|
2012-12-08 11:10:08 +08:00
|
|
|
win *w = NULL;
|
2012-09-13 22:30:18 +08:00
|
|
|
|
2012-12-08 11:10:08 +08:00
|
|
|
// Check if it's a mapped frame window
|
|
|
|
if (WIN_EVMODE_FRAME == mode
|
2018-11-05 02:54:04 +08:00
|
|
|
|| ((w = find_win(ps, wid)) && w->a.map_state == XCB_MAP_STATE_VIEWABLE)) {
|
2018-10-04 15:15:38 +08:00
|
|
|
evmask |= XCB_EVENT_MASK_PROPERTY_CHANGE;
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.track_focus && !ps->o.use_ewmh_active_win)
|
2018-10-04 15:15:38 +08:00
|
|
|
evmask |= XCB_EVENT_MASK_FOCUS_CHANGE;
|
2012-09-13 22:30:18 +08:00
|
|
|
}
|
2012-09-13 23:12:54 +08:00
|
|
|
|
2012-12-08 11:10:08 +08:00
|
|
|
// Check if it's a mapped client window
|
|
|
|
if (WIN_EVMODE_CLIENT == mode
|
2018-11-05 02:54:04 +08:00
|
|
|
|| ((w = find_toplevel(ps, wid)) && w->a.map_state == XCB_MAP_STATE_VIEWABLE)) {
|
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
|
|
|
if (ps->o.frame_opacity || ps->o.track_wdata || ps->track_atom_lst
|
2012-11-19 09:46:07 +08:00
|
|
|
|| ps->o.detect_client_opacity)
|
2018-10-04 15:15:38 +08:00
|
|
|
evmask |= XCB_EVENT_MASK_PROPERTY_CHANGE;
|
2012-09-13 22:30:18 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return evmask;
|
|
|
|
}
|
|
|
|
|
2012-09-13 21:38:55 +08:00
|
|
|
/**
|
|
|
|
* Find out the WM frame of a client window by querying X.
|
|
|
|
*
|
2012-11-19 09:46:07 +08:00
|
|
|
* @param ps current session
|
2013-01-29 09:57:04 +08:00
|
|
|
* @param wid window ID
|
2012-09-13 21:38:55 +08:00
|
|
|
* @return struct _win object of the found window, NULL if not found
|
|
|
|
*/
|
2018-09-07 02:17:26 +08:00
|
|
|
win *find_toplevel2(session_t *ps, Window wid) {
|
|
|
|
// TODO this should probably be an "update tree", then find_toplevel.
|
|
|
|
// current approach is a bit more "racy"
|
2012-09-13 21:38:55 +08:00
|
|
|
win *w = NULL;
|
|
|
|
|
|
|
|
// We traverse through its ancestors to find out the frame
|
2012-11-19 09:46:07 +08:00
|
|
|
while (wid && wid != ps->root && !(w = find_win(ps, wid))) {
|
2018-10-03 21:06:16 +08:00
|
|
|
xcb_query_tree_reply_t *reply;
|
2012-09-13 21:38:55 +08:00
|
|
|
|
2018-10-03 21:06:16 +08:00
|
|
|
// xcb_query_tree probably fails if you run compton when X is somehow
|
2012-09-13 21:38:55 +08:00
|
|
|
// initializing (like add it in .xinitrc). In this case
|
|
|
|
// just leave it alone.
|
2018-10-03 21:27:48 +08:00
|
|
|
reply = xcb_query_tree_reply(ps->c, xcb_query_tree(ps->c, wid), NULL);
|
2018-10-03 21:06:16 +08:00
|
|
|
if (reply == NULL) {
|
2012-09-13 21:38:55 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2018-10-03 21:06:16 +08:00
|
|
|
wid = reply->parent;
|
2012-09-13 23:12:54 +08:00
|
|
|
|
2018-10-03 21:06:16 +08:00
|
|
|
free(reply);
|
2012-09-13 21:38:55 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return w;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Recheck currently focused window and set its <code>w->focused</code>
|
2012-11-19 09:46:07 +08:00
|
|
|
* to true.
|
2012-09-13 21:38:55 +08:00
|
|
|
*
|
2012-11-19 09:46:07 +08:00
|
|
|
* @param ps current session
|
2012-09-13 21:38:55 +08:00
|
|
|
* @return struct _win of currently focused window, NULL if not found
|
|
|
|
*/
|
2012-09-13 23:12:54 +08:00
|
|
|
static win *
|
2012-11-19 09:46:07 +08:00
|
|
|
recheck_focus(session_t *ps) {
|
2012-11-04 18:11:08 +08:00
|
|
|
// Use EWMH _NET_ACTIVE_WINDOW if enabled
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.use_ewmh_active_win) {
|
|
|
|
update_ewmh_active_win(ps);
|
|
|
|
return ps->active_win;
|
2012-11-04 18:11:08 +08:00
|
|
|
}
|
|
|
|
|
2012-09-13 21:38:55 +08:00
|
|
|
// Determine the currently focused window so we can apply appropriate
|
|
|
|
// opacity on it
|
2018-10-03 20:17:08 +08:00
|
|
|
xcb_window_t wid = XCB_NONE;
|
|
|
|
xcb_get_input_focus_reply_t *reply =
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_get_input_focus_reply(ps->c, xcb_get_input_focus(ps->c), NULL);
|
2012-09-13 21:38:55 +08:00
|
|
|
|
2018-10-03 20:17:08 +08:00
|
|
|
if (reply) {
|
|
|
|
wid = reply->focus;
|
|
|
|
free(reply);
|
|
|
|
}
|
2012-09-13 21:38:55 +08:00
|
|
|
|
2013-09-18 21:50:57 +08:00
|
|
|
win *w = find_win_all(ps, wid);
|
2012-09-13 21:38:55 +08:00
|
|
|
|
2013-10-21 22:17:01 +08:00
|
|
|
#ifdef DEBUG_EVENTS
|
|
|
|
print_timestamp(ps);
|
2018-10-03 20:46:14 +08:00
|
|
|
printf_dbgf("(): %#010" PRIx32 " (%#010lx \"%s\") focused.\n", wid,
|
2013-10-21 22:17:01 +08:00
|
|
|
(w ? w->id: None), (w ? w->name: NULL));
|
|
|
|
#endif
|
|
|
|
|
2013-09-18 21:50:57 +08:00
|
|
|
// And we set the focus state here
|
2012-09-13 21:38:55 +08:00
|
|
|
if (w) {
|
2012-11-28 11:44:00 +08:00
|
|
|
win_set_focused(ps, w, true);
|
2012-09-13 21:38:55 +08:00
|
|
|
return w;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
2012-02-01 06:10:30 +08:00
|
|
|
}
|
|
|
|
|
2013-03-15 23:16:23 +08:00
|
|
|
static bool
|
|
|
|
get_root_tile(session_t *ps) {
|
2012-10-24 10:09:59 +08:00
|
|
|
/*
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.paint_on_overlay) {
|
|
|
|
return ps->root_picture;
|
2012-10-24 10:09:59 +08:00
|
|
|
} */
|
|
|
|
|
2013-03-15 23:16:23 +08:00
|
|
|
assert(!ps->root_tile_paint.pixmap);
|
|
|
|
ps->root_tile_fill = false;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2013-03-15 23:16:23 +08:00
|
|
|
bool fill = false;
|
2018-10-01 03:53:52 +08:00
|
|
|
xcb_pixmap_t pixmap = None;
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-11-04 18:11:08 +08:00
|
|
|
// Get the values of background attributes
|
2013-03-15 23:16:23 +08:00
|
|
|
for (int p = 0; background_props_str[p]; p++) {
|
2012-11-19 09:46:07 +08:00
|
|
|
winprop_t prop = wid_get_prop(ps, ps->root,
|
2013-01-09 20:25:01 +08:00
|
|
|
get_atom(ps, background_props_str[p]),
|
2018-10-03 01:53:28 +08:00
|
|
|
1L, XCB_ATOM_PIXMAP, 32);
|
2012-11-19 09:46:07 +08:00
|
|
|
if (prop.nitems) {
|
2018-11-01 19:12:20 +08:00
|
|
|
pixmap = *prop.p32;
|
2012-11-19 09:46:07 +08:00
|
|
|
fill = false;
|
|
|
|
free_winprop(&prop);
|
2011-11-04 14:33:23 +08:00
|
|
|
break;
|
2012-11-04 18:11:08 +08:00
|
|
|
}
|
2012-11-19 09:46:07 +08:00
|
|
|
free_winprop(&prop);
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2013-05-01 22:08:43 +08:00
|
|
|
// Make sure the pixmap we got is valid
|
|
|
|
if (pixmap && !validate_pixmap(ps, pixmap))
|
|
|
|
pixmap = None;
|
|
|
|
|
2013-03-15 23:16:23 +08:00
|
|
|
// Create a pixmap if there isn't any
|
2011-11-04 14:33:23 +08:00
|
|
|
if (!pixmap) {
|
2018-10-01 03:53:52 +08:00
|
|
|
pixmap = x_create_pixmap(ps, ps->depth, ps->root, 1, 1);
|
2018-09-30 15:31:22 +08:00
|
|
|
if (pixmap == XCB_NONE) {
|
|
|
|
fprintf(stderr, "Failed to create some pixmap\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
2012-11-19 09:46:07 +08:00
|
|
|
fill = true;
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2013-03-15 23:16:23 +08:00
|
|
|
// Create Picture
|
2018-09-24 02:10:46 +08:00
|
|
|
xcb_render_create_picture_value_list_t pa = {
|
|
|
|
.repeat = True,
|
|
|
|
};
|
|
|
|
ps->root_tile_paint.pict = x_create_picture_with_visual_and_pixmap(
|
2018-09-28 00:14:44 +08:00
|
|
|
ps, ps->vis, pixmap, XCB_RENDER_CP_REPEAT, &pa);
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2013-03-15 23:16:23 +08:00
|
|
|
// Fill pixmap if needed
|
2011-11-04 14:33:23 +08:00
|
|
|
if (fill) {
|
2018-09-28 00:14:44 +08:00
|
|
|
xcb_render_color_t col;
|
|
|
|
xcb_rectangle_t rect;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2018-09-28 00:14:44 +08:00
|
|
|
col.red = col.green = col.blue = 0x8080;
|
|
|
|
col.alpha = 0xffff;
|
|
|
|
|
|
|
|
rect.x = rect.y = 0;
|
|
|
|
rect.width = rect.height = 1;
|
|
|
|
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_render_fill_rectangles(ps->c, XCB_RENDER_PICT_OP_SRC, ps->root_tile_paint.pict, col, 1, &rect);
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2013-03-15 23:16:23 +08:00
|
|
|
ps->root_tile_fill = fill;
|
|
|
|
ps->root_tile_paint.pixmap = pixmap;
|
2018-08-22 22:12:29 +08:00
|
|
|
#ifdef CONFIG_OPENGL
|
2013-03-15 23:16:23 +08:00
|
|
|
if (BKEND_GLX == ps->o.backend)
|
2013-03-18 11:48:28 +08:00
|
|
|
return glx_bind_pixmap(ps, &ps->root_tile_paint.ptex, ps->root_tile_paint.pixmap, 0, 0, 0);
|
2013-03-15 23:16:23 +08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
return true;
|
2003-11-10 10:03:26 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* Paint root window content.
|
|
|
|
*/
|
2003-11-20 00:12:15 +08:00
|
|
|
static void
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
paint_root(session_t *ps, const region_t *reg_paint) {
|
2013-03-15 23:16:23 +08:00
|
|
|
if (!ps->root_tile_paint.pixmap)
|
|
|
|
get_root_tile(ps);
|
2011-11-04 14:33:23 +08:00
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
paint_region(ps, NULL, 0, 0, ps->root_width, ps->root_height, 1.0, reg_paint,
|
|
|
|
ps->root_tile_paint.pict);
|
2003-11-09 15:08:23 +08:00
|
|
|
}
|
|
|
|
|
2012-10-21 20:44:24 +08:00
|
|
|
/**
|
2018-09-07 02:17:26 +08:00
|
|
|
* Look for the client window of a particular window.
|
2012-10-21 20:44:24 +08:00
|
|
|
*/
|
2018-10-03 20:59:27 +08:00
|
|
|
xcb_window_t
|
|
|
|
find_client_win(session_t *ps, xcb_window_t w) {
|
2018-09-07 02:17:26 +08:00
|
|
|
if (wid_has_prop(ps, w, ps->atom_client)) {
|
|
|
|
return w;
|
|
|
|
}
|
|
|
|
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_query_tree_reply_t *reply = xcb_query_tree_reply(ps->c,
|
|
|
|
xcb_query_tree(ps->c, w), NULL);
|
2018-10-03 20:59:27 +08:00
|
|
|
if (!reply)
|
2018-09-07 02:17:26 +08:00
|
|
|
return 0;
|
2018-10-03 20:59:27 +08:00
|
|
|
|
|
|
|
xcb_window_t *children = xcb_query_tree_children(reply);
|
|
|
|
int nchildren = xcb_query_tree_children_length(reply);
|
|
|
|
int i;
|
|
|
|
xcb_window_t ret = 0;
|
2018-09-07 02:17:26 +08:00
|
|
|
|
|
|
|
for (i = 0; i < nchildren; ++i) {
|
|
|
|
if ((ret = find_client_win(ps, children[i])))
|
|
|
|
break;
|
|
|
|
}
|
2012-10-21 20:44:24 +08:00
|
|
|
|
2018-10-03 20:59:27 +08:00
|
|
|
free(reply);
|
2012-10-21 20:44:24 +08:00
|
|
|
|
2018-09-07 02:17:26 +08:00
|
|
|
return ret;
|
2012-10-21 20:44:24 +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
|
|
|
win *t = NULL, *next = NULL;
|
2011-11-04 16:41:56 +08:00
|
|
|
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
// Fading step calculation
|
2013-01-11 21:31:02 +08:00
|
|
|
time_ms_t steps = 0L;
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
if (ps->fade_time)
|
|
|
|
steps = (get_time_ms() - ps->fade_time +
|
|
|
|
FADE_DELTA_TOLERANCE*ps->o.fade_delta) /
|
|
|
|
ps->o.fade_delta;
|
2013-01-11 21:31:02 +08:00
|
|
|
// Reset fade_time if unset, or there appears to be a time disorder
|
|
|
|
if (!ps->fade_time || steps < 0L) {
|
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
|
|
|
ps->fade_time = get_time_ms();
|
2013-01-11 21:31:02 +08:00
|
|
|
steps = 0L;
|
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
|
|
|
}
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->fade_time += steps * ps->o.fade_delta;
|
2011-11-04 16:41:56 +08:00
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
// First, let's process fading
|
2013-09-04 22:00:51 +08:00
|
|
|
for (win *w = list; w; w = next) {
|
2012-09-19 20:49:16 +08:00
|
|
|
next = w->next;
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
const winmode_t mode_old = w->mode;
|
|
|
|
const bool was_painted = w->to_paint;
|
|
|
|
const opacity_t opacity_old = w->opacity;
|
2014-04-19 21:52:20 +08:00
|
|
|
// Restore flags from last paint if the window is being faded out
|
2018-11-05 02:54:04 +08:00
|
|
|
if (w->a.map_state == XCB_MAP_STATE_UNMAPPED) {
|
2014-04-19 21:52:20 +08:00
|
|
|
win_set_shadow(ps, w, w->shadow_last);
|
|
|
|
w->fade = w->fade_last;
|
|
|
|
win_set_invert_color(ps, w, w->invert_color_last);
|
|
|
|
win_set_blur_background(ps, w, w->blur_background_last);
|
|
|
|
}
|
|
|
|
|
2012-11-28 11:44:00 +08:00
|
|
|
// Update window opacity target and dim state if asked
|
|
|
|
if (WFLAG_OPCT_CHANGE & w->flags) {
|
2018-09-07 02:17:26 +08:00
|
|
|
win_calc_opacity(ps, w);
|
|
|
|
win_calc_dim(ps, w);
|
2012-11-28 11:44:00 +08:00
|
|
|
}
|
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
// Run fading
|
2012-11-19 09:46:07 +08:00
|
|
|
run_fade(ps, w, steps);
|
2011-11-04 16:41:56 +08:00
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
if (win_has_frame(w))
|
|
|
|
w->frame_opacity = ps->o.frame_opacity;
|
|
|
|
else
|
|
|
|
w->frame_opacity = 1.0;
|
|
|
|
|
|
|
|
// Update window mode
|
|
|
|
win_determine_mode(ps, w);
|
|
|
|
|
|
|
|
// Destroy all reg_ignore above when frame opaque state changes on
|
|
|
|
// SOLID mode
|
|
|
|
if (was_painted && w->mode != mode_old)
|
|
|
|
w->reg_ignore_valid = false;
|
|
|
|
|
|
|
|
// Add window to damaged area if its opacity changes
|
|
|
|
// If was_painted == false, and to_paint is also false, we don't care
|
|
|
|
// If was_painted == false, but to_paint is true, damage will be added in the loop below
|
|
|
|
if (was_painted && w->opacity != opacity_old)
|
|
|
|
add_damage_from_win(ps, w);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Opacity will not change, from now on.
|
|
|
|
rc_region_t *last_reg_ignore = rc_region_new();
|
|
|
|
|
|
|
|
bool unredir_possible = false;
|
|
|
|
// Trace whether it's the highest window to paint
|
|
|
|
bool is_highest = true;
|
|
|
|
bool reg_ignore_valid = true;
|
|
|
|
for (win *w = list; w; w = next) {
|
|
|
|
__label__ skip_window;
|
|
|
|
bool to_paint = true;
|
|
|
|
// w->to_paint remembers whether this window is painted last time
|
|
|
|
const bool was_painted = w->to_paint;
|
|
|
|
|
|
|
|
// In case calling the fade callback function destroys this window
|
|
|
|
next = w->next;
|
|
|
|
|
|
|
|
// Destroy reg_ignore if some window above us invalidated it
|
|
|
|
if (!reg_ignore_valid)
|
|
|
|
rc_region_unref(&w->reg_ignore);
|
|
|
|
|
|
|
|
//printf_errf("(): %d %d %s", w->a.map_state, w->ever_damaged, w->name);
|
2013-09-12 21:23:20 +08:00
|
|
|
|
2012-10-31 08:54:09 +08:00
|
|
|
// Give up if it's not damaged or invisible, or it's unmapped and its
|
2013-09-12 21:23:20 +08:00
|
|
|
// pixmap is gone (for example due to a ConfigureNotify), or when it's
|
|
|
|
// excluded
|
2018-09-09 09:29:45 +08:00
|
|
|
if (!w->ever_damaged
|
2018-09-24 02:10:46 +08:00
|
|
|
|| w->g.x + w->g.width < 1 || w->g.y + w->g.height < 1
|
|
|
|
|| w->g.x >= ps->root_width || w->g.y >= ps->root_height
|
2018-11-05 02:54:04 +08:00
|
|
|
|| ((w->a.map_state == XCB_MAP_STATE_UNMAPPED || w->destroyed) && !w->paint.pixmap)
|
2018-11-10 20:48:36 +08:00
|
|
|
|| (double) w->opacity / OPAQUE * MAX_ALPHA < 1
|
2013-09-12 21:23:20 +08:00
|
|
|
|| w->paint_excluded)
|
2012-11-19 09:46:07 +08:00
|
|
|
to_paint = false;
|
2018-10-13 08:17:59 +08:00
|
|
|
//printf_errf("(): %s %d %d %d", w->name, to_paint, w->opacity, w->paint_excluded);
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2013-09-12 21:23:20 +08:00
|
|
|
// Add window to damaged area if its painting status changes
|
|
|
|
// or opacity changes
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
if (to_paint != was_painted) {
|
|
|
|
w->reg_ignore_valid = false;
|
2018-09-07 02:17:26 +08:00
|
|
|
add_damage_from_win(ps, w);
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
}
|
2013-09-12 21:23:20 +08:00
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
// to_paint will never change afterward
|
|
|
|
if (!to_paint)
|
|
|
|
goto skip_window;
|
|
|
|
|
|
|
|
// Calculate shadow opacity
|
|
|
|
w->shadow_opacity = ps->o.shadow_opacity * get_opacity_percent(w) * ps->o.frame_opacity;
|
|
|
|
|
|
|
|
// Generate ignore region for painting to reduce GPU load
|
|
|
|
if (!w->reg_ignore)
|
|
|
|
w->reg_ignore = rc_region_ref(last_reg_ignore);
|
|
|
|
|
|
|
|
// If the window is solid, we add the window region to the
|
|
|
|
// ignored region
|
|
|
|
// Otherwise last_reg_ignore shouldn't change
|
|
|
|
if (w->mode == WMODE_SOLID && !ps->o.force_win_blend) {
|
|
|
|
region_t *tmp = rc_region_new();
|
|
|
|
if (w->frame_opacity == 1)
|
2018-10-13 08:17:59 +08:00
|
|
|
*tmp = win_get_bounding_shape_global_by_val(w);
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
else {
|
2018-10-22 05:07:48 +08:00
|
|
|
win_get_region_noframe_local(w, tmp);
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
pixman_region32_intersect(tmp, tmp, &w->bounding_shape);
|
2018-10-13 08:17:59 +08:00
|
|
|
pixman_region32_translate(tmp, w->g.x, w->g.y);
|
2012-11-09 21:44:02 +08:00
|
|
|
}
|
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
pixman_region32_union(tmp, tmp, last_reg_ignore);
|
|
|
|
rc_region_unref(&last_reg_ignore);
|
|
|
|
last_reg_ignore = tmp;
|
2012-10-21 20:44:24 +08:00
|
|
|
}
|
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
// (Un)redirect screen
|
|
|
|
// We could definitely unredirect the screen when there's no window to
|
|
|
|
// paint, but this is typically unnecessary, may cause flickering when
|
|
|
|
// fading is enabled, and could create inconsistency when the wallpaper
|
|
|
|
// is not correctly set.
|
|
|
|
if (ps->o.unredir_if_possible && is_highest) {
|
|
|
|
if (win_is_solid(ps, w)
|
|
|
|
&& (w->frame_opacity == 1 || !win_has_frame(w))
|
|
|
|
&& win_is_fullscreen(ps, w)
|
|
|
|
&& !w->unredir_if_possible_excluded)
|
|
|
|
unredir_possible = true;
|
2012-10-31 08:54:09 +08:00
|
|
|
}
|
2012-11-04 19:14:21 +08:00
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
// Reset flags
|
|
|
|
w->flags = 0;
|
|
|
|
w->prev_trans = t;
|
|
|
|
t = w;
|
2018-12-04 23:30:07 +08:00
|
|
|
|
|
|
|
// If the screen is not redirected and the window has redir_ignore set,
|
|
|
|
// this window should not cause the screen to become redirected
|
|
|
|
if (!(ps->o.wintype_option[w->window_type].redir_ignore && !ps->redirected)) {
|
|
|
|
is_highest = false;
|
|
|
|
}
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
|
|
|
|
skip_window:
|
|
|
|
reg_ignore_valid = reg_ignore_valid && w->reg_ignore_valid;
|
|
|
|
w->reg_ignore_valid = true;
|
|
|
|
|
|
|
|
assert(w->destroyed == (w->fade_callback == finish_destroy_win));
|
|
|
|
check_fade_fin(ps, &w);
|
|
|
|
|
|
|
|
// Avoid setting w->to_paint if w is freed
|
2018-09-30 06:30:19 +08:00
|
|
|
if (w) {
|
2012-11-04 19:14:21 +08:00
|
|
|
w->to_paint = to_paint;
|
2014-04-19 21:52:20 +08:00
|
|
|
|
|
|
|
if (w->to_paint) {
|
|
|
|
// Save flags
|
|
|
|
w->shadow_last = w->shadow;
|
|
|
|
w->fade_last = w->fade;
|
|
|
|
w->invert_color_last = w->invert_color;
|
|
|
|
w->blur_background_last = w->blur_background;
|
|
|
|
}
|
|
|
|
}
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
rc_region_unref(&last_reg_ignore);
|
2013-09-04 22:00:51 +08:00
|
|
|
|
2012-11-09 21:44:02 +08:00
|
|
|
// If possible, unredirect all windows and stop painting
|
2013-07-26 12:52:16 +08:00
|
|
|
if (UNSET != ps->o.redirected_force)
|
|
|
|
unredir_possible = !ps->o.redirected_force;
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
else if (ps->o.unredir_if_possible && is_highest && !ps->redirected)
|
|
|
|
// If there's no window to paint, and the screen isn't redirected,
|
|
|
|
// don't redirect it.
|
2013-09-12 21:23:20 +08:00
|
|
|
unredir_possible = true;
|
2013-09-04 22:00:51 +08:00
|
|
|
if (unredir_possible) {
|
|
|
|
if (ps->redirected) {
|
|
|
|
if (!ps->o.unredir_if_possible_delay || ps->tmout_unredir_hit)
|
|
|
|
redir_stop(ps);
|
2018-11-27 08:32:08 +08:00
|
|
|
else if (!ev_is_active(&ps->unredir_timer)) {
|
|
|
|
ev_timer_set(&ps->unredir_timer,
|
2018-10-03 03:22:26 +08:00
|
|
|
ps->o.unredir_if_possible_delay / 1000.0, 0);
|
2018-11-27 08:32:08 +08:00
|
|
|
ev_timer_start(ps->loop, &ps->unredir_timer);
|
2013-09-04 22:00:51 +08:00
|
|
|
}
|
|
|
|
}
|
2018-12-04 23:30:07 +08:00
|
|
|
} else {
|
2018-11-27 08:32:08 +08:00
|
|
|
ev_timer_stop(ps->loop, &ps->unredir_timer);
|
2012-11-19 09:46:07 +08:00
|
|
|
redir_start(ps);
|
2013-09-04 22:00:51 +08:00
|
|
|
}
|
2012-11-09 21:44:02 +08:00
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
return t;
|
|
|
|
}
|
|
|
|
|
2012-10-21 20:44:24 +08:00
|
|
|
/**
|
|
|
|
* Paint the shadow of a window.
|
|
|
|
*/
|
|
|
|
static inline void
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
win_paint_shadow(session_t *ps, win *w, region_t *reg_paint) {
|
2014-07-28 12:50:15 +08:00
|
|
|
// Bind shadow pixmap to GLX texture if needed
|
|
|
|
paint_bind_tex(ps, &w->shadow_paint, 0, 0, 32, false);
|
|
|
|
|
2013-03-15 23:16:23 +08:00
|
|
|
if (!paint_isvalid(ps, &w->shadow_paint)) {
|
2018-09-24 02:10:46 +08:00
|
|
|
printf_errf("(%#010lx): Missing shadow data.", w->id);
|
2013-03-15 23:16:23 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-09-24 02:10:46 +08:00
|
|
|
render(ps, 0, 0, w->g.x + w->shadow_dx, w->g.y + w->shadow_dy,
|
2013-03-15 23:16:23 +08:00
|
|
|
w->shadow_width, w->shadow_height, w->shadow_opacity, true, false,
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
w->shadow_paint.pict, w->shadow_paint.ptex, reg_paint, NULL);
|
2012-10-21 20:44:24 +08:00
|
|
|
}
|
|
|
|
|
2013-05-20 18:04:40 +08:00
|
|
|
/**
|
|
|
|
* @brief Blur an area on a buffer.
|
|
|
|
*
|
|
|
|
* @param ps current session
|
|
|
|
* @param tgt_buffer a buffer as both source and destination
|
|
|
|
* @param x x pos
|
|
|
|
* @param y y pos
|
|
|
|
* @param wid width
|
|
|
|
* @param hei height
|
|
|
|
* @param blur_kerns blur kernels, ending with a NULL, guaranteed to have at
|
|
|
|
* least one kernel
|
|
|
|
* @param reg_clip a clipping region to be applied on intermediate buffers
|
|
|
|
*
|
|
|
|
* @return true if successful, false otherwise
|
|
|
|
*/
|
|
|
|
static bool
|
2018-09-28 00:14:44 +08:00
|
|
|
xr_blur_dst(session_t *ps, xcb_render_picture_t tgt_buffer,
|
|
|
|
int x, int y, int wid, int hei, xcb_render_fixed_t **blur_kerns,
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
const region_t *reg_clip) {
|
2013-05-20 18:04:40 +08:00
|
|
|
assert(blur_kerns[0]);
|
|
|
|
|
|
|
|
// Directly copying from tgt_buffer to it does not work, so we create a
|
|
|
|
// Picture in the middle.
|
2018-09-28 00:14:44 +08:00
|
|
|
xcb_render_picture_t tmp_picture = x_create_picture(ps, wid, hei, NULL, 0, NULL);
|
2013-05-20 18:04:40 +08:00
|
|
|
|
|
|
|
if (!tmp_picture) {
|
|
|
|
printf_errf("(): Failed to build intermediate Picture.");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (reg_clip && tmp_picture)
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
x_set_picture_clip_region(ps, tmp_picture, 0, 0, reg_clip);
|
2013-05-20 18:04:40 +08:00
|
|
|
|
2018-09-28 00:14:44 +08:00
|
|
|
xcb_render_picture_t src_pict = tgt_buffer, dst_pict = tmp_picture;
|
2013-05-20 18:04:40 +08:00
|
|
|
for (int i = 0; blur_kerns[i]; ++i) {
|
|
|
|
assert(i < MAX_BLUR_PASS - 1);
|
2018-09-28 00:14:44 +08:00
|
|
|
xcb_render_fixed_t *convolution_blur = blur_kerns[i];
|
|
|
|
int kwid = XFIXED_TO_DOUBLE(convolution_blur[0]),
|
|
|
|
khei = XFIXED_TO_DOUBLE(convolution_blur[1]);
|
2013-05-20 18:04:40 +08:00
|
|
|
bool rd_from_tgt = (tgt_buffer == src_pict);
|
|
|
|
|
|
|
|
// Copy from source picture to destination. The filter must
|
|
|
|
// be applied on source picture, to get the nearby pixels outside the
|
|
|
|
// window.
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_render_set_picture_filter(ps->c, src_pict, strlen(XRFILTER_CONVOLUTION), XRFILTER_CONVOLUTION,
|
2018-09-28 00:14:44 +08:00
|
|
|
kwid * khei + 2, convolution_blur);
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_render_composite(ps->c, XCB_RENDER_PICT_OP_SRC, src_pict, None, dst_pict,
|
2013-05-20 18:04:40 +08:00
|
|
|
(rd_from_tgt ? x: 0), (rd_from_tgt ? y: 0), 0, 0,
|
|
|
|
(rd_from_tgt ? 0: x), (rd_from_tgt ? 0: y), wid, hei);
|
|
|
|
xrfilter_reset(ps, src_pict);
|
|
|
|
|
|
|
|
{
|
2018-11-27 07:56:36 +08:00
|
|
|
xcb_render_picture_t tmp = src_pict;
|
2013-05-20 18:04:40 +08:00
|
|
|
src_pict = dst_pict;
|
|
|
|
dst_pict = tmp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (src_pict != tgt_buffer)
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_render_composite(ps->c, XCB_RENDER_PICT_OP_SRC, src_pict, None, tgt_buffer,
|
2013-05-20 18:04:40 +08:00
|
|
|
0, 0, 0, 0, x, y, wid, hei);
|
|
|
|
|
|
|
|
free_picture(ps, &tmp_picture);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-09-07 18:58:09 +08:00
|
|
|
/*
|
|
|
|
* WORK-IN-PROGRESS!
|
|
|
|
static void
|
|
|
|
xr_take_screenshot(session_t *ps) {
|
|
|
|
XImage *img = XGetImage(ps->dpy, get_tgt_window(ps), 0, 0,
|
|
|
|
ps->root_width, ps->root_height, AllPlanes, XYPixmap);
|
|
|
|
if (!img) {
|
|
|
|
printf_errf("(): Failed to get XImage.");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
assert(0 == img->xoffset);
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
2012-12-14 20:32:46 +08:00
|
|
|
/**
|
|
|
|
* Blur the background of a window.
|
|
|
|
*/
|
|
|
|
static inline void
|
2018-09-28 00:14:44 +08:00
|
|
|
win_blur_background(session_t *ps, win *w, xcb_render_picture_t tgt_buffer,
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
const region_t *reg_paint) {
|
2018-09-24 02:10:46 +08:00
|
|
|
const int x = w->g.x;
|
|
|
|
const int y = w->g.y;
|
2013-01-12 22:21:35 +08:00
|
|
|
const int wid = w->widthb;
|
|
|
|
const int hei = w->heightb;
|
2012-12-14 20:32:46 +08:00
|
|
|
|
2013-03-20 17:29:45 +08:00
|
|
|
double factor_center = 1.0;
|
2012-12-15 20:07:45 +08:00
|
|
|
// Adjust blur strength according to window opacity, to make it appear
|
|
|
|
// better during fading
|
|
|
|
if (!ps->o.blur_background_fixed) {
|
|
|
|
double pct = 1.0 - get_opacity_percent(w) * (1.0 - 1.0 / 9.0);
|
2013-03-20 17:29:45 +08:00
|
|
|
factor_center = pct * 8.0 / (1.1 - pct);
|
2012-12-15 20:07:45 +08:00
|
|
|
}
|
|
|
|
|
2013-03-20 17:29:45 +08:00
|
|
|
switch (ps->o.backend) {
|
|
|
|
case BKEND_XRENDER:
|
2013-12-24 07:46:48 +08:00
|
|
|
case BKEND_XR_GLX_HYBRID:
|
2013-03-20 17:29:45 +08:00
|
|
|
{
|
2013-05-20 18:04:40 +08:00
|
|
|
// Normalize blur kernels
|
|
|
|
for (int i = 0; i < MAX_BLUR_PASS; ++i) {
|
2018-09-28 00:14:44 +08:00
|
|
|
xcb_render_fixed_t *kern_src = ps->o.blur_kerns[i];
|
|
|
|
xcb_render_fixed_t *kern_dst = ps->blur_kerns_cache[i];
|
2013-05-20 18:04:40 +08:00
|
|
|
assert(i < MAX_BLUR_PASS);
|
|
|
|
if (!kern_src) {
|
|
|
|
assert(!kern_dst);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(!kern_dst
|
|
|
|
|| (kern_src[0] == kern_dst[0] && kern_src[1] == kern_dst[1]));
|
|
|
|
|
|
|
|
// Skip for fixed factor_center if the cache exists already
|
|
|
|
if (ps->o.blur_background_fixed && kern_dst) continue;
|
|
|
|
|
2018-09-28 00:14:44 +08:00
|
|
|
int kwid = XFIXED_TO_DOUBLE(kern_src[0]),
|
|
|
|
khei = XFIXED_TO_DOUBLE(kern_src[1]);
|
2013-03-20 17:29:45 +08:00
|
|
|
|
2013-05-20 18:04:40 +08:00
|
|
|
// Allocate cache space if needed
|
|
|
|
if (!kern_dst) {
|
2018-09-28 00:14:44 +08:00
|
|
|
kern_dst = malloc((kwid * khei + 2) * sizeof(xcb_render_fixed_t));
|
2013-05-20 18:04:40 +08:00
|
|
|
if (!kern_dst) {
|
|
|
|
printf_errf("(): Failed to allocate memory for blur kernel.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
ps->blur_kerns_cache[i] = kern_dst;
|
|
|
|
}
|
2013-03-20 17:29:45 +08:00
|
|
|
|
2013-05-20 18:04:40 +08:00
|
|
|
// Modify the factor of the center pixel
|
|
|
|
kern_src[2 + (khei / 2) * kwid + kwid / 2] =
|
2018-09-28 00:14:44 +08:00
|
|
|
DOUBLE_TO_XFIXED(factor_center);
|
2013-04-25 22:23:35 +08:00
|
|
|
|
2013-05-20 18:04:40 +08:00
|
|
|
// Copy over
|
2018-09-28 00:14:44 +08:00
|
|
|
memcpy(kern_dst, kern_src, (kwid * khei + 2) * sizeof(xcb_render_fixed_t));
|
2013-05-20 18:04:40 +08:00
|
|
|
normalize_conv_kern(kwid, khei, kern_dst + 2);
|
|
|
|
}
|
2013-03-20 17:29:45 +08:00
|
|
|
|
|
|
|
// Minimize the region we try to blur, if the window itself is not
|
|
|
|
// opaque, only the frame is.
|
2018-10-13 08:17:59 +08:00
|
|
|
region_t reg_blur = win_get_bounding_shape_global_by_val(w);
|
2014-05-16 15:18:17 +08:00
|
|
|
if (win_is_solid(ps, w)) {
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
region_t reg_noframe;
|
|
|
|
pixman_region32_init(®_noframe);
|
2018-10-22 05:07:48 +08:00
|
|
|
win_get_region_noframe_local(w, ®_noframe);
|
2018-10-13 08:17:59 +08:00
|
|
|
pixman_region32_translate(®_noframe, w->g.x, w->g.y);
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
pixman_region32_subtract(®_blur, ®_blur, ®_noframe);
|
|
|
|
pixman_region32_fini(®_noframe);
|
2013-03-20 17:29:45 +08:00
|
|
|
}
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
// Translate global coordinates to local ones
|
|
|
|
pixman_region32_translate(®_blur, -x, -y);
|
2013-05-20 18:04:40 +08:00
|
|
|
xr_blur_dst(ps, tgt_buffer, x, y, wid, hei, ps->blur_kerns_cache,
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
®_blur);
|
|
|
|
pixman_region32_clear(®_blur);
|
2013-03-20 17:29:45 +08:00
|
|
|
}
|
|
|
|
break;
|
2018-08-22 22:12:29 +08:00
|
|
|
#ifdef CONFIG_OPENGL
|
2013-03-20 17:29:45 +08:00
|
|
|
case BKEND_GLX:
|
2013-05-20 18:04:40 +08:00
|
|
|
// TODO: Handle frame opacity
|
2014-07-28 12:50:15 +08:00
|
|
|
glx_blur_dst(ps, x, y, wid, hei, ps->psglx->z - 0.5, factor_center,
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
reg_paint, &w->glx_blur_cache);
|
2013-03-20 17:29:45 +08:00
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
default:
|
|
|
|
assert(0);
|
|
|
|
}
|
2012-12-14 20:32:46 +08:00
|
|
|
}
|
|
|
|
|
2018-11-04 06:38:18 +08:00
|
|
|
static void
|
2018-09-30 05:47:12 +08:00
|
|
|
render(session_t *ps, int x, int y, int dx, int dy, int wid, int hei,
|
|
|
|
double opacity, bool argb, bool neg,
|
|
|
|
xcb_render_picture_t pict, glx_texture_t *ptex,
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
const region_t *reg_paint, const glx_prog_main_t *pprogram)
|
2018-09-30 05:47:12 +08:00
|
|
|
{
|
2013-03-15 23:16:23 +08:00
|
|
|
switch (ps->o.backend) {
|
|
|
|
case BKEND_XRENDER:
|
2013-12-24 07:46:48 +08:00
|
|
|
case BKEND_XR_GLX_HYBRID:
|
2013-03-15 23:16:23 +08:00
|
|
|
{
|
2018-11-10 20:48:36 +08:00
|
|
|
int alpha_step = opacity * MAX_ALPHA;
|
2018-10-21 03:08:43 +08:00
|
|
|
xcb_render_picture_t alpha_pict = ps->alpha_picts[alpha_step];
|
|
|
|
if (alpha_step != 0) {
|
2018-09-28 00:14:44 +08:00
|
|
|
int op = ((!argb && !alpha_pict) ? XCB_RENDER_PICT_OP_SRC: XCB_RENDER_PICT_OP_OVER);
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_render_composite(ps->c, op, pict, alpha_pict,
|
2013-12-10 22:06:02 +08:00
|
|
|
ps->tgt_buffer.pict, x, y, 0, 0, dx, dy, wid, hei);
|
2013-03-15 23:16:23 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2018-08-22 22:12:29 +08:00
|
|
|
#ifdef CONFIG_OPENGL
|
2013-03-15 23:16:23 +08:00
|
|
|
case BKEND_GLX:
|
|
|
|
glx_render(ps, ptex, x, y, dx, dy, wid, hei,
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
ps->psglx->z, opacity, argb, neg, reg_paint, pprogram);
|
2014-07-28 12:50:15 +08:00
|
|
|
ps->psglx->z += 1;
|
2013-03-15 23:16:23 +08:00
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
default:
|
|
|
|
assert(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-10-21 20:44:24 +08:00
|
|
|
/**
|
|
|
|
* Paint a window itself and dim it if asked.
|
|
|
|
*/
|
|
|
|
static inline void
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
paint_one(session_t *ps, win *w, const region_t *reg_paint) {
|
2013-05-12 18:21:16 +08:00
|
|
|
glx_mark(ps, w->id, true);
|
|
|
|
|
2013-03-17 12:14:00 +08:00
|
|
|
// Fetch Pixmap
|
|
|
|
if (!w->paint.pixmap && ps->has_name_pixmap) {
|
2018-10-03 21:27:48 +08:00
|
|
|
w->paint.pixmap = xcb_generate_id(ps->c);
|
2018-09-29 17:18:09 +08:00
|
|
|
set_ignore_cookie(ps,
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_composite_name_window_pixmap(ps->c, w->id, w->paint.pixmap));
|
2018-11-08 22:53:13 +08:00
|
|
|
if (w->paint.pixmap)
|
|
|
|
free_fence(ps, &w->fence);
|
2013-03-17 12:14:00 +08:00
|
|
|
}
|
2014-03-17 23:25:34 +08:00
|
|
|
|
|
|
|
Drawable draw = w->paint.pixmap;
|
|
|
|
if (!draw)
|
|
|
|
draw = w->id;
|
|
|
|
|
2013-03-17 12:14:00 +08:00
|
|
|
// XRender: Build picture
|
2013-12-10 22:06:02 +08:00
|
|
|
if (bkend_use_xrender(ps) && !w->paint.pict) {
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
xcb_render_create_picture_value_list_t pa = {
|
|
|
|
.subwindowmode = IncludeInferiors,
|
|
|
|
};
|
2013-03-17 12:14:00 +08:00
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
w->paint.pict = x_create_picture_with_pictfmt_and_pixmap(ps, w->pictfmt,
|
|
|
|
draw, XCB_RENDER_CP_SUBWINDOW_MODE, &pa);
|
2013-03-17 12:14:00 +08:00
|
|
|
}
|
2014-03-17 23:25:34 +08:00
|
|
|
|
2018-11-08 22:53:13 +08:00
|
|
|
if (IsViewable == w->a.map_state)
|
|
|
|
xr_sync(ps, draw, &w->fence);
|
|
|
|
|
2013-03-17 12:14:00 +08:00
|
|
|
// GLX: Build texture
|
2013-03-18 11:48:28 +08:00
|
|
|
// Let glx_bind_pixmap() determine pixmap size, because if the user
|
|
|
|
// is resizing windows, the width and height we get may not be up-to-date,
|
|
|
|
// causing the jittering issue M4he reported in #7.
|
2013-04-05 21:05:19 +08:00
|
|
|
if (!paint_bind_tex(ps, &w->paint, 0, 0, 0,
|
|
|
|
(!ps->o.glx_no_rebind_pixmap && w->pixmap_damaged))) {
|
2013-03-17 12:14:00 +08:00
|
|
|
printf_errf("(%#010lx): Failed to bind texture. Expect troubles.", w->id);
|
|
|
|
}
|
|
|
|
w->pixmap_damaged = false;
|
|
|
|
|
2013-03-15 23:16:23 +08:00
|
|
|
if (!paint_isvalid(ps, &w->paint)) {
|
|
|
|
printf_errf("(%#010lx): Missing painting data. This is a bad sign.", w->id);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-09-24 02:10:46 +08:00
|
|
|
const int x = w->g.x;
|
|
|
|
const int y = w->g.y;
|
2013-03-15 23:16:23 +08:00
|
|
|
const int wid = w->widthb;
|
|
|
|
const int hei = w->heightb;
|
2012-10-21 20:44:24 +08:00
|
|
|
|
2018-09-28 00:14:44 +08:00
|
|
|
xcb_render_picture_t pict = w->paint.pict;
|
2013-01-12 22:21:35 +08:00
|
|
|
|
|
|
|
// Invert window color, if required
|
2013-12-10 22:06:02 +08:00
|
|
|
if (bkend_use_xrender(ps) && w->invert_color) {
|
2018-09-28 00:14:44 +08:00
|
|
|
xcb_render_picture_t newpict = x_create_picture(ps, wid, hei, w->pictfmt, 0, NULL);
|
2013-01-12 22:21:35 +08:00
|
|
|
if (newpict) {
|
2013-01-29 09:57:04 +08:00
|
|
|
// Apply clipping region to save some CPU
|
|
|
|
if (reg_paint) {
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
region_t reg;
|
|
|
|
pixman_region32_init(®);
|
|
|
|
pixman_region32_copy(®, (region_t *)reg_paint);
|
|
|
|
pixman_region32_translate(®, -x, -y);
|
|
|
|
// FIXME XFixesSetPictureClipRegion(ps->dpy, newpict, 0, 0, reg);
|
|
|
|
pixman_region32_fini(®);
|
2013-01-29 09:57:04 +08:00
|
|
|
}
|
|
|
|
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_render_composite(ps->c, XCB_RENDER_PICT_OP_SRC, pict, None,
|
2013-01-12 22:21:35 +08:00
|
|
|
newpict, 0, 0, 0, 0, 0, 0, wid, hei);
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_render_composite(ps->c, XCB_RENDER_PICT_OP_DIFFERENCE, ps->white_picture, None,
|
2013-01-12 22:21:35 +08:00
|
|
|
newpict, 0, 0, 0, 0, 0, 0, wid, hei);
|
|
|
|
// We use an extra PictOpInReverse operation to get correct pixel
|
|
|
|
// alpha. There could be a better solution.
|
2018-09-30 02:07:39 +08:00
|
|
|
if (win_has_alpha(w))
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_render_composite(ps->c, XCB_RENDER_PICT_OP_IN_REVERSE, pict, None,
|
2013-01-12 22:21:35 +08:00
|
|
|
newpict, 0, 0, 0, 0, 0, 0, wid, hei);
|
|
|
|
pict = newpict;
|
|
|
|
}
|
|
|
|
}
|
2012-10-21 20:44:24 +08:00
|
|
|
|
2013-12-10 22:06:02 +08:00
|
|
|
const double dopacity = get_opacity_percent(w);
|
2013-03-15 23:16:23 +08:00
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
if (w->frame_opacity == 1) {
|
|
|
|
paint_region(ps, w, 0, 0, wid, hei, dopacity, reg_paint, pict);
|
|
|
|
} else {
|
2013-01-09 20:25:01 +08:00
|
|
|
// Painting parameters
|
2018-10-22 05:07:48 +08:00
|
|
|
const margin_t extents = win_calc_frame_extents(w);
|
2015-09-06 21:40:51 +08:00
|
|
|
const int t = extents.top;
|
|
|
|
const int l = extents.left;
|
|
|
|
const int b = extents.bottom;
|
|
|
|
const int r = extents.right;
|
2012-10-21 20:44:24 +08:00
|
|
|
|
2012-11-01 19:03:56 +08:00
|
|
|
#define COMP_BDR(cx, cy, cwid, chei) \
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
paint_region(ps, w, (cx), (cy), (cwid), (chei), w->frame_opacity * dopacity, \
|
|
|
|
reg_paint, pict)
|
2012-10-21 20:44:24 +08:00
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
// Sanitize the margins, in case some broken WM makes
|
2012-11-01 19:03:56 +08:00
|
|
|
// top_width + bottom_width > height in some cases.
|
2012-10-21 20:44:24 +08:00
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
do {
|
|
|
|
// top
|
|
|
|
int body_height = hei;
|
|
|
|
// ctop = checked top
|
|
|
|
int ctop = min_i(body_height, t); // Make sure top margin is smaller than height
|
|
|
|
if (ctop > 0)
|
|
|
|
COMP_BDR(0, 0, wid, ctop);
|
2012-11-01 19:03:56 +08:00
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
body_height -= ctop;
|
|
|
|
if (body_height <= 0)
|
|
|
|
break;
|
2012-11-01 19:03:56 +08:00
|
|
|
|
|
|
|
// bottom
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
// cbot = checked bottom
|
|
|
|
int cbot = min_i(body_height, b); // Make sure bottom margin is not too large
|
|
|
|
if (cbot > 0)
|
|
|
|
COMP_BDR(0, hei-cbot, wid, cbot);
|
|
|
|
|
|
|
|
body_height -= cbot; // Height of window exclude the margin
|
|
|
|
if (body_height <= 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
// left
|
|
|
|
int body_width = wid;
|
|
|
|
int cleft = min_i(body_width, l);
|
|
|
|
if (cleft > 0)
|
|
|
|
COMP_BDR(0, ctop, cleft, body_height);
|
|
|
|
|
|
|
|
body_width -= cleft;
|
|
|
|
if (body_width <= 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
// right
|
|
|
|
int cright = min_i(body_width, r);
|
|
|
|
if (cright > 0)
|
|
|
|
COMP_BDR(wid - cright, ctop, cright, body_height);
|
|
|
|
|
|
|
|
body_width -= cright;
|
|
|
|
if (body_width <= 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
// body
|
|
|
|
paint_region(ps, w, cleft, ctop, body_width, body_height, dopacity, reg_paint, pict);
|
|
|
|
} while (0);
|
2012-10-21 20:44:24 +08:00
|
|
|
}
|
|
|
|
|
2012-11-01 19:03:56 +08:00
|
|
|
#undef COMP_BDR
|
|
|
|
|
2013-03-15 23:16:23 +08:00
|
|
|
if (pict != w->paint.pict)
|
2013-01-12 22:21:35 +08:00
|
|
|
free_picture(ps, &pict);
|
|
|
|
|
2012-10-21 20:44:24 +08:00
|
|
|
// Dimming the window if needed
|
2013-03-25 11:36:39 +08:00
|
|
|
if (w->dim) {
|
|
|
|
double dim_opacity = ps->o.inactive_dim;
|
|
|
|
if (!ps->o.inactive_dim_fixed)
|
|
|
|
dim_opacity *= get_opacity_percent(w);
|
|
|
|
|
|
|
|
switch (ps->o.backend) {
|
|
|
|
case BKEND_XRENDER:
|
2013-12-24 07:46:48 +08:00
|
|
|
case BKEND_XR_GLX_HYBRID:
|
2013-03-25 11:36:39 +08:00
|
|
|
{
|
|
|
|
unsigned short cval = 0xffff * dim_opacity;
|
|
|
|
|
|
|
|
// Premultiply color
|
2018-09-28 00:14:44 +08:00
|
|
|
xcb_render_color_t color = {
|
2013-03-25 11:36:39 +08:00
|
|
|
.red = 0, .green = 0, .blue = 0, .alpha = cval,
|
|
|
|
};
|
|
|
|
|
2018-09-28 00:14:44 +08:00
|
|
|
xcb_rectangle_t rect = {
|
2013-03-25 11:36:39 +08:00
|
|
|
.x = x,
|
|
|
|
.y = y,
|
|
|
|
.width = wid,
|
|
|
|
.height = hei,
|
|
|
|
};
|
|
|
|
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_render_fill_rectangles(ps->c, XCB_RENDER_PICT_OP_OVER, ps->tgt_buffer.pict,
|
2018-09-28 00:14:44 +08:00
|
|
|
color, 1, &rect);
|
2013-03-25 11:36:39 +08:00
|
|
|
}
|
|
|
|
break;
|
2018-08-22 22:12:29 +08:00
|
|
|
#ifdef CONFIG_OPENGL
|
2013-03-25 11:36:39 +08:00
|
|
|
case BKEND_GLX:
|
2014-07-28 12:50:15 +08:00
|
|
|
glx_dim_dst(ps, x, y, wid, hei, ps->psglx->z - 0.7, dim_opacity,
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
reg_paint);
|
2013-03-25 11:36:39 +08:00
|
|
|
break;
|
|
|
|
#endif
|
2018-05-17 19:50:22 +08:00
|
|
|
default:
|
|
|
|
assert(false);
|
2013-03-25 11:36:39 +08:00
|
|
|
}
|
2012-10-21 20:44:24 +08:00
|
|
|
}
|
2013-05-12 18:21:16 +08:00
|
|
|
|
|
|
|
glx_mark(ps, w->id, false);
|
2012-10-21 20:44:24 +08:00
|
|
|
}
|
|
|
|
|
2012-11-03 10:30:32 +08:00
|
|
|
/**
|
|
|
|
* Rebuild cached <code>screen_reg</code>.
|
|
|
|
*/
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
rebuild_screen_reg(session_t *ps) {
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
get_screen_region(ps, &ps->screen_reg);
|
2012-11-03 10:30:32 +08:00
|
|
|
}
|
|
|
|
|
2013-06-09 17:06:35 +08:00
|
|
|
/**
|
|
|
|
* Rebuild <code>shadow_exclude_reg</code>.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
rebuild_shadow_exclude_reg(session_t *ps) {
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
bool ret = parse_geometry(ps, ps->o.shadow_exclude_reg_str,
|
|
|
|
&ps->shadow_exclude_reg);
|
|
|
|
if (!ret)
|
|
|
|
exit(1);
|
2018-09-09 09:29:45 +08:00
|
|
|
}
|
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
/// paint all windows
|
|
|
|
/// region = ??
|
|
|
|
/// region_real = the damage region
|
2012-09-19 20:49:16 +08:00
|
|
|
static void
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
paint_all(session_t *ps, region_t *region, const region_t *region_real, win * const t) {
|
2013-04-27 17:34:42 +08:00
|
|
|
if (!region_real)
|
|
|
|
region_real = region;
|
|
|
|
|
2012-10-26 11:12:28 +08:00
|
|
|
#ifdef DEBUG_REPAINT
|
|
|
|
static struct timespec last_paint = { 0 };
|
|
|
|
#endif
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
|
|
|
|
if (!region)
|
|
|
|
region_real = region = &ps->screen_reg;
|
|
|
|
else
|
|
|
|
// Remove the damaged area out of screen
|
|
|
|
pixman_region32_intersect(region, region, &ps->screen_reg);
|
2012-09-19 20:49:16 +08:00
|
|
|
|
2018-08-22 22:12:29 +08:00
|
|
|
#ifdef CONFIG_OPENGL
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
if (bkend_use_glx(ps))
|
|
|
|
glx_paint_pre(ps, region);
|
2013-03-15 23:16:23 +08:00
|
|
|
#endif
|
|
|
|
|
2013-12-10 22:06:02 +08:00
|
|
|
if (!paint_isvalid(ps, &ps->tgt_buffer)) {
|
2018-10-22 02:25:13 +08:00
|
|
|
if (!ps->tgt_buffer.pixmap) {
|
|
|
|
free_paint(ps, &ps->tgt_buffer);
|
|
|
|
ps->tgt_buffer.pixmap = x_create_pixmap(ps, ps->depth, ps->root, ps->root_width, ps->root_height);
|
|
|
|
if (ps->tgt_buffer.pixmap == XCB_NONE) {
|
|
|
|
fprintf(stderr, "Failed to allocate a screen-sized pixmap\n");
|
|
|
|
exit(1);
|
2013-12-10 22:06:02 +08:00
|
|
|
}
|
2012-10-23 13:42:20 +08:00
|
|
|
}
|
2018-10-22 02:25:13 +08:00
|
|
|
|
|
|
|
if (BKEND_GLX != ps->o.backend)
|
|
|
|
ps->tgt_buffer.pict = x_create_picture_with_visual_and_pixmap(
|
|
|
|
ps, ps->vis, ps->tgt_buffer.pixmap, 0, 0);
|
2012-09-19 20:49:16 +08:00
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
if (BKEND_XRENDER == ps->o.backend) {
|
2018-11-10 19:55:52 +08:00
|
|
|
x_set_picture_clip_region(ps, ps->tgt_picture, 0, 0, region_real);
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
}
|
2012-09-19 20:49:16 +08:00
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
region_t reg_tmp, *reg_paint;
|
|
|
|
pixman_region32_init(®_tmp);
|
|
|
|
if (t) {
|
2012-10-21 20:44:24 +08:00
|
|
|
// Calculate the region upon which the root window is to be painted
|
|
|
|
// based on the ignore region of the lowest window, if available
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
pixman_region32_subtract(®_tmp, region, t->reg_ignore);
|
|
|
|
reg_paint = ®_tmp;
|
2018-09-24 02:10:46 +08:00
|
|
|
} else {
|
2012-10-21 20:44:24 +08:00
|
|
|
reg_paint = region;
|
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
set_tgt_clip(ps, reg_paint);
|
2013-03-15 23:16:23 +08:00
|
|
|
paint_root(ps, reg_paint);
|
2012-09-17 16:04:04 +08:00
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
// Windows are sorted from bottom to top
|
|
|
|
// Each window has a reg_ignore, which is the region obscured by all the windows
|
|
|
|
// on top of that window. This is used to reduce the number of pixels painted.
|
|
|
|
//
|
|
|
|
// Whether this is beneficial is to be determined XXX
|
2013-09-04 22:00:51 +08:00
|
|
|
for (win *w = t; w; w = w->prev_trans) {
|
2018-10-13 08:17:59 +08:00
|
|
|
region_t bshape = win_get_bounding_shape_global_by_val(w);
|
2012-09-17 16:04:04 +08:00
|
|
|
// Painting shadow
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
if (w->shadow) {
|
2013-09-12 21:23:20 +08:00
|
|
|
// Lazy shadow building
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
if (!w->shadow_paint.pixmap)
|
2018-09-24 02:10:46 +08:00
|
|
|
if (!win_build_shadow(ps, w, 1))
|
|
|
|
printf_errf("(): build shadow failed");
|
2013-09-12 21:23:20 +08:00
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
// Shadow doesn't need to be painted underneath the body of the window
|
|
|
|
// Because no one can see it
|
|
|
|
pixman_region32_subtract(®_tmp, region, w->reg_ignore);
|
2013-03-17 12:14:00 +08:00
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
// Mask out the region we don't want shadow on
|
|
|
|
if (pixman_region32_not_empty(&ps->shadow_exclude_reg))
|
|
|
|
pixman_region32_subtract(®_tmp, ®_tmp, &ps->shadow_exclude_reg);
|
2013-06-09 17:06:35 +08:00
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
// Might be worth while to crop the region to shadow border
|
|
|
|
pixman_region32_intersect_rect(®_tmp, ®_tmp,
|
|
|
|
w->g.x + w->shadow_dx, w->g.y + w->shadow_dy,
|
|
|
|
w->shadow_width, w->shadow_height);
|
2013-03-17 12:14:00 +08:00
|
|
|
|
2018-11-10 03:56:05 +08:00
|
|
|
// Mask out the body of the window from the shadow if needed
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
// Doing it here instead of in make_shadow() for saving GPU
|
|
|
|
// power and handling shaped windows (XXX unconfirmed)
|
2018-12-04 21:44:16 +08:00
|
|
|
if (!ps->o.wintype_option[w->window_type].full_shadow)
|
2018-11-10 03:56:05 +08:00
|
|
|
pixman_region32_subtract(®_tmp, ®_tmp, &bshape);
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2013-08-22 21:15:04 +08:00
|
|
|
#ifdef CONFIG_XINERAMA
|
2018-10-22 22:38:45 +08:00
|
|
|
if (ps->o.xinerama_shadow_crop && w->xinerama_scr >= 0 &&
|
|
|
|
w->xinerama_scr < ps->xinerama_nscrs)
|
|
|
|
// There can be a window where number of screens is updated,
|
|
|
|
// but the screen number attached to the windows have not.
|
|
|
|
//
|
|
|
|
// Window screen number will be updated eventually, so here we
|
|
|
|
// just check to make sure we don't access out of bounds.
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
pixman_region32_intersect(®_tmp, ®_tmp,
|
|
|
|
&ps->xinerama_scr_regs[w->xinerama_scr]);
|
2013-08-22 21:15:04 +08:00
|
|
|
#endif
|
|
|
|
|
2012-10-21 20:44:24 +08:00
|
|
|
// Detect if the region is empty before painting
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
if (pixman_region32_not_empty(®_tmp)) {
|
|
|
|
set_tgt_clip(ps, ®_tmp);
|
|
|
|
win_paint_shadow(ps, w, ®_tmp);
|
2012-10-21 20:44:24 +08:00
|
|
|
}
|
|
|
|
}
|
2011-11-04 17:18:10 +08:00
|
|
|
|
2012-10-21 20:44:24 +08:00
|
|
|
// Calculate the region based on the reg_ignore of the next (higher)
|
|
|
|
// window and the bounding region
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
// XXX XXX
|
|
|
|
pixman_region32_subtract(®_tmp, region, w->reg_ignore);
|
2018-10-13 08:17:59 +08:00
|
|
|
pixman_region32_intersect(®_tmp, ®_tmp, &bshape);
|
|
|
|
pixman_region32_fini(&bshape);
|
2011-11-04 17:18:10 +08:00
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
if (pixman_region32_not_empty(®_tmp)) {
|
|
|
|
set_tgt_clip(ps, ®_tmp);
|
2013-04-05 21:05:19 +08:00
|
|
|
// Blur window background
|
2014-05-16 15:18:17 +08:00
|
|
|
if (w->blur_background && (!win_is_solid(ps, w)
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
|| (ps->o.blur_background_frame && w->frame_opacity != 1)))
|
|
|
|
win_blur_background(ps, w, ps->tgt_buffer.pict, ®_tmp);
|
2012-09-17 16:04:04 +08:00
|
|
|
|
2013-04-05 21:05:19 +08:00
|
|
|
// Painting the window
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
paint_one(ps, w, ®_tmp);
|
2012-10-21 20:44:24 +08:00
|
|
|
}
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-10-21 20:44:24 +08:00
|
|
|
// Free up all temporary regions
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
pixman_region32_fini(®_tmp);
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-10-27 21:46:01 +08:00
|
|
|
// Do this as early as possible
|
2018-10-22 02:25:13 +08:00
|
|
|
set_tgt_clip(ps, &ps->screen_reg);
|
2012-10-27 21:46:01 +08:00
|
|
|
|
2013-01-30 13:41:08 +08:00
|
|
|
if (ps->o.vsync) {
|
2012-11-01 10:43:15 +08:00
|
|
|
// Make sure all previous requests are processed to achieve best
|
|
|
|
// effect
|
2018-10-03 21:27:48 +08:00
|
|
|
x_sync(ps->c);
|
2018-08-22 22:12:29 +08:00
|
|
|
#ifdef CONFIG_OPENGL
|
2014-07-28 12:50:15 +08:00
|
|
|
if (glx_has_context(ps)) {
|
2013-12-26 20:43:06 +08:00
|
|
|
if (ps->o.vsync_use_glfinish)
|
|
|
|
glFinish();
|
|
|
|
else
|
|
|
|
glFlush();
|
2013-01-30 13:41:08 +08:00
|
|
|
glXWaitX();
|
|
|
|
}
|
|
|
|
#endif
|
2012-11-01 10:43:15 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Wait for VBlank. We could do it aggressively (send the painting
|
|
|
|
// request and XFlush() on VBlank) or conservatively (send the request
|
|
|
|
// only on VBlank).
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!ps->o.vsync_aggressive)
|
|
|
|
vsync_wait(ps);
|
2012-10-26 11:12:28 +08:00
|
|
|
|
2013-03-15 23:16:23 +08:00
|
|
|
switch (ps->o.backend) {
|
|
|
|
case BKEND_XRENDER:
|
2018-10-22 06:56:53 +08:00
|
|
|
if (ps->o.monitor_repaint) {
|
|
|
|
// Copy the screen content to a new picture, and highlight the paint
|
|
|
|
// region. This is not very efficient, but since it's for debug only,
|
|
|
|
// we don't really care
|
|
|
|
|
|
|
|
// First, we clear tgt_buffer.pict's clip region, since we want to copy
|
|
|
|
// everything
|
|
|
|
x_set_picture_clip_region(ps, ps->tgt_buffer.pict, 0, 0, &ps->screen_reg);
|
|
|
|
|
|
|
|
// Then we create a new picture, and copy content to it
|
|
|
|
xcb_render_pictforminfo_t *pictfmt = x_get_pictform_for_visual(ps, ps->vis);
|
|
|
|
xcb_render_picture_t new_pict = x_create_picture(
|
|
|
|
ps, ps->root_width, ps->root_height, pictfmt, 0, NULL);
|
|
|
|
xcb_render_composite(ps->c, XCB_RENDER_PICT_OP_SRC, ps->tgt_buffer.pict,
|
|
|
|
None, new_pict, 0, 0, 0, 0, 0, 0, ps->root_width, ps->root_height);
|
|
|
|
|
|
|
|
// Next, we set the region of paint and highlight it
|
|
|
|
x_set_picture_clip_region(ps, new_pict, 0, 0, region_real);
|
|
|
|
xcb_render_composite(ps->c, XCB_RENDER_PICT_OP_OVER, ps->white_picture,
|
2018-11-10 20:48:36 +08:00
|
|
|
ps->alpha_picts[MAX_ALPHA / 2],
|
2018-10-22 06:56:53 +08:00
|
|
|
new_pict, 0, 0, 0, 0, 0, 0,
|
|
|
|
ps->root_width, ps->root_height);
|
|
|
|
|
|
|
|
// Finally, clear clip region and put the whole thing on screen
|
|
|
|
x_set_picture_clip_region(ps, new_pict, 0, 0, &ps->screen_reg);
|
|
|
|
xcb_render_composite(
|
|
|
|
ps->c, XCB_RENDER_PICT_OP_SRC, new_pict, None,
|
|
|
|
ps->tgt_picture, 0, 0, 0, 0,
|
|
|
|
0, 0, ps->root_width, ps->root_height);
|
|
|
|
xcb_render_free_picture(ps->c, new_pict);
|
|
|
|
} else
|
2018-09-28 00:14:44 +08:00
|
|
|
xcb_render_composite(
|
2018-10-03 21:27:48 +08:00
|
|
|
ps->c, XCB_RENDER_PICT_OP_SRC, ps->tgt_buffer.pict, None,
|
2013-03-15 23:16:23 +08:00
|
|
|
ps->tgt_picture, 0, 0, 0, 0,
|
|
|
|
0, 0, ps->root_width, ps->root_height);
|
|
|
|
break;
|
2018-08-22 22:12:29 +08:00
|
|
|
#ifdef CONFIG_OPENGL
|
2013-12-24 07:46:48 +08:00
|
|
|
case BKEND_XR_GLX_HYBRID:
|
2018-10-03 21:27:48 +08:00
|
|
|
x_sync(ps->c);
|
2013-12-26 20:43:06 +08:00
|
|
|
if (ps->o.vsync_use_glfinish)
|
|
|
|
glFinish();
|
|
|
|
else
|
|
|
|
glFlush();
|
2013-12-10 22:06:02 +08:00
|
|
|
glXWaitX();
|
2014-03-17 23:25:34 +08:00
|
|
|
assert(ps->tgt_buffer.pixmap);
|
2018-11-08 22:53:13 +08:00
|
|
|
xr_sync(ps, ps->tgt_buffer.pixmap, &ps->tgt_buffer_fence);
|
2018-09-30 05:47:12 +08:00
|
|
|
paint_bind_tex(ps, &ps->tgt_buffer,
|
2013-12-10 22:06:02 +08:00
|
|
|
ps->root_width, ps->root_height, ps->depth,
|
|
|
|
!ps->o.glx_no_rebind_pixmap);
|
2018-11-08 22:53:13 +08:00
|
|
|
// See #163
|
|
|
|
xr_sync(ps, ps->tgt_buffer.pixmap, &ps->tgt_buffer_fence);
|
2014-01-19 08:04:14 +08:00
|
|
|
if (ps->o.vsync_use_glfinish)
|
|
|
|
glFinish();
|
|
|
|
else
|
|
|
|
glFlush();
|
|
|
|
glXWaitX();
|
2013-12-10 22:06:02 +08:00
|
|
|
glx_render(ps, ps->tgt_buffer.ptex, 0, 0, 0, 0,
|
2014-05-16 15:18:17 +08:00
|
|
|
ps->root_width, ps->root_height, 0, 1.0, false, false,
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
region_real, NULL);
|
2018-08-14 17:51:01 +08:00
|
|
|
// falls through
|
2013-03-15 23:16:23 +08:00
|
|
|
case BKEND_GLX:
|
2018-09-30 02:24:33 +08:00
|
|
|
glXSwapBuffers(ps->dpy, get_tgt_window(ps));
|
2013-03-15 23:16:23 +08:00
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
default:
|
|
|
|
assert(0);
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2013-05-12 18:21:16 +08:00
|
|
|
glx_mark_frame(ps);
|
2012-10-26 11:12:28 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.vsync_aggressive)
|
|
|
|
vsync_wait(ps);
|
2012-11-01 10:43:15 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
XFlush(ps->dpy);
|
2012-10-26 11:12:28 +08:00
|
|
|
|
2018-08-22 22:12:29 +08:00
|
|
|
#ifdef CONFIG_OPENGL
|
2014-07-28 12:50:15 +08:00
|
|
|
if (glx_has_context(ps)) {
|
2013-01-30 13:41:08 +08:00
|
|
|
glFlush();
|
|
|
|
glXWaitX();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2012-10-26 11:12:28 +08:00
|
|
|
#ifdef DEBUG_REPAINT
|
2012-11-19 09:46:07 +08:00
|
|
|
print_timestamp(ps);
|
2012-10-26 11:12:28 +08:00
|
|
|
struct timespec now = get_time_timespec();
|
|
|
|
struct timespec diff = { 0 };
|
|
|
|
timespec_subtract(&diff, &now, &last_paint);
|
|
|
|
printf("[ %5ld:%09ld ] ", diff.tv_sec, diff.tv_nsec);
|
|
|
|
last_paint = now;
|
2012-10-30 18:11:30 +08:00
|
|
|
printf("paint:");
|
2013-09-04 22:00:51 +08:00
|
|
|
for (win *w = t; w; w = w->prev_trans)
|
2012-10-30 18:11:30 +08:00
|
|
|
printf(" %#010lx", w->id);
|
|
|
|
putchar('\n');
|
2012-10-26 11:12:28 +08:00
|
|
|
fflush(stdout);
|
|
|
|
#endif
|
2013-03-15 23:16:23 +08:00
|
|
|
|
|
|
|
// Check if fading is finished on all painted windows
|
|
|
|
{
|
|
|
|
win *pprev = NULL;
|
2013-09-04 22:00:51 +08:00
|
|
|
for (win *w = t; w; w = pprev) {
|
2013-03-15 23:16:23 +08:00
|
|
|
pprev = w->prev_trans;
|
2018-09-30 06:30:19 +08:00
|
|
|
check_fade_fin(ps, &w);
|
2013-03-15 23:16:23 +08:00
|
|
|
}
|
|
|
|
}
|
2003-11-09 15:08:23 +08:00
|
|
|
}
|
|
|
|
|
2003-11-20 00:12:15 +08:00
|
|
|
static void
|
2018-09-23 02:43:35 +08:00
|
|
|
repair_win(session_t *ps, win *w) {
|
2018-11-05 02:54:04 +08:00
|
|
|
if (w->a.map_state != XCB_MAP_STATE_VIEWABLE)
|
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
|
|
|
return;
|
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
region_t parts;
|
|
|
|
pixman_region32_init(&parts);
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2018-09-09 09:29:45 +08:00
|
|
|
if (!w->ever_damaged) {
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
win_extents(w, &parts);
|
2018-09-29 17:18:09 +08:00
|
|
|
set_ignore_cookie(ps,
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_damage_subtract(ps->c, w->damage, XCB_NONE, XCB_NONE));
|
2011-11-04 14:33:23 +08:00
|
|
|
} else {
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_xfixes_region_t tmp = xcb_generate_id(ps->c);
|
|
|
|
xcb_xfixes_create_region(ps->c, tmp, 0, NULL);
|
2018-09-29 17:18:09 +08:00
|
|
|
set_ignore_cookie(ps,
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_damage_subtract(ps->c, w->damage, XCB_NONE, tmp));
|
|
|
|
xcb_xfixes_translate_region(ps->c, tmp,
|
2018-09-24 02:10:46 +08:00
|
|
|
w->g.x + w->g.border_width,
|
|
|
|
w->g.y + w->g.border_width);
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
x_fetch_region(ps, tmp, &parts);
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_xfixes_destroy_region(ps->c, tmp);
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2018-09-09 09:29:45 +08:00
|
|
|
w->ever_damaged = true;
|
2013-09-04 22:00:51 +08:00
|
|
|
w->pixmap_damaged = true;
|
|
|
|
|
|
|
|
// Why care about damage when screen is unredirected?
|
|
|
|
// We will force full-screen repaint on redirection.
|
2015-05-13 04:14:39 +08:00
|
|
|
if (!ps->redirected) {
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
pixman_region32_fini(&parts);
|
2015-05-13 04:14:39 +08:00
|
|
|
return;
|
|
|
|
}
|
2013-09-04 22:00:51 +08:00
|
|
|
|
2012-10-21 20:44:24 +08:00
|
|
|
// Remove the part in the damage area that could be ignored
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
if (w->reg_ignore && win_is_region_ignore_valid(ps, w))
|
|
|
|
pixman_region32_subtract(&parts, &parts, w->reg_ignore);
|
2012-10-21 20:44:24 +08:00
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
add_damage(ps, &parts);
|
|
|
|
pixman_region32_fini(&parts);
|
2003-11-09 15:08:23 +08:00
|
|
|
}
|
|
|
|
|
2018-09-30 06:30:19 +08:00
|
|
|
static void
|
|
|
|
finish_map_win(session_t *ps, win **_w) {
|
|
|
|
win *w = *_w;
|
|
|
|
w->in_openclose = false;
|
|
|
|
if (ps->o.no_fading_openclose) {
|
|
|
|
win_determine_fade(ps, w);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-07 02:17:26 +08:00
|
|
|
void
|
2012-11-21 09:15:49 +08:00
|
|
|
map_win(session_t *ps, Window id) {
|
2013-09-12 21:23:20 +08:00
|
|
|
// Unmap overlay window if it got mapped but we are currently not
|
|
|
|
// in redirected state.
|
|
|
|
if (ps->overlay && id == ps->overlay && !ps->redirected) {
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_unmap_window(ps->c, ps->overlay);
|
2013-09-12 21:23:20 +08:00
|
|
|
XFlush(ps->dpy);
|
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
win *w = find_win(ps, id);
|
2003-11-09 15:08:23 +08:00
|
|
|
|
2014-01-21 22:13:06 +08:00
|
|
|
#ifdef DEBUG_EVENTS
|
|
|
|
printf_dbgf("(%#010lx \"%s\"): %p\n", id, (w ? w->name: NULL), w);
|
|
|
|
#endif
|
|
|
|
|
2012-10-27 21:46:01 +08:00
|
|
|
// Don't care about window mapping if it's an InputOnly window
|
2012-12-07 22:38:10 +08:00
|
|
|
// Try avoiding mapping a window twice
|
2018-09-24 02:10:46 +08:00
|
|
|
if (!w || InputOnly == w->a._class
|
2018-11-05 02:54:04 +08:00
|
|
|
|| w->a.map_state == XCB_MAP_STATE_VIEWABLE)
|
2012-12-07 22:38:10 +08:00
|
|
|
return;
|
|
|
|
|
2013-09-18 21:50:57 +08:00
|
|
|
assert(!win_is_focused_real(ps, w));
|
2004-09-10 13:55:19 +08:00
|
|
|
|
2018-11-05 02:54:04 +08:00
|
|
|
w->a.map_state = XCB_MAP_STATE_VIEWABLE;
|
2012-12-07 22:38:10 +08:00
|
|
|
|
2013-08-22 21:15:04 +08:00
|
|
|
cxinerama_win_upd_scr(ps, w);
|
|
|
|
|
2018-10-03 20:34:24 +08:00
|
|
|
// Set window event mask before reading properties so that no property
|
2012-09-18 11:28:09 +08:00
|
|
|
// changes are lost
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_change_window_attributes(ps->c, id, XCB_CW_EVENT_MASK,
|
2018-10-03 20:34:24 +08:00
|
|
|
(const uint32_t[]) { determine_evmask(ps, id, WIN_EVMODE_FRAME) });
|
2012-09-18 11:28:09 +08:00
|
|
|
|
|
|
|
// Notify compton when the shape of a window changes
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->shape_exists) {
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_shape_select_input(ps->c, id, 1);
|
2012-09-18 11:28:09 +08:00
|
|
|
}
|
2012-09-14 11:51:46 +08:00
|
|
|
|
2012-12-05 12:43:34 +08:00
|
|
|
// Make sure the XSelectInput() requests are sent
|
2014-03-17 23:25:34 +08:00
|
|
|
XFlush(ps->dpy);
|
2012-12-05 12:43:34 +08:00
|
|
|
|
2013-03-15 23:16:23 +08:00
|
|
|
// Update window mode here to check for ARGB windows
|
2013-03-10 18:45:54 +08:00
|
|
|
win_determine_mode(ps, w);
|
|
|
|
|
2012-09-18 11:28:09 +08:00
|
|
|
// Detect client window here instead of in add_win() as the client
|
|
|
|
// window should have been prepared at this point
|
2012-09-20 13:50:27 +08:00
|
|
|
if (!w->client_win) {
|
2012-12-07 22:38:10 +08:00
|
|
|
win_recheck_client(ps, w);
|
2012-02-27 12:00:12 +08:00
|
|
|
}
|
2012-11-10 11:41:01 +08:00
|
|
|
else {
|
|
|
|
// Re-mark client window here
|
2012-12-07 22:38:10 +08:00
|
|
|
win_mark_client(ps, w, w->client_win);
|
2012-09-20 13:50:27 +08:00
|
|
|
}
|
2011-11-05 01:02:17 +08:00
|
|
|
|
2012-12-05 12:43:34 +08:00
|
|
|
assert(w->client_win);
|
2012-10-21 21:19:00 +08:00
|
|
|
|
2012-09-22 20:49:17 +08:00
|
|
|
#ifdef DEBUG_WINTYPE
|
2012-12-05 12:43:34 +08:00
|
|
|
printf_dbgf("(%#010lx): type %s\n", w->id, WINTYPES[w->window_type]);
|
2012-09-22 20:49:17 +08:00
|
|
|
#endif
|
|
|
|
|
2013-09-18 21:50:57 +08:00
|
|
|
// FocusIn/Out may be ignored when the window is unmapped, so we must
|
|
|
|
// recheck focus here
|
|
|
|
if (ps->o.track_focus)
|
2012-11-28 11:44:00 +08:00
|
|
|
recheck_focus(ps);
|
2012-09-12 11:06:16 +08:00
|
|
|
|
2012-11-28 11:44:00 +08:00
|
|
|
// Update window focus state
|
|
|
|
win_update_focused(ps, w);
|
|
|
|
|
|
|
|
// Update opacity and dim state
|
|
|
|
win_update_opacity_prop(ps, w);
|
|
|
|
w->flags |= WFLAG_OPCT_CHANGE;
|
|
|
|
|
2012-11-09 11:35:40 +08:00
|
|
|
// Check for _COMPTON_SHADOW
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.respect_prop_shadow)
|
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(ps, w);
|
2012-11-09 11:35:40 +08:00
|
|
|
|
|
|
|
// Many things above could affect shadow
|
2013-01-12 22:21:35 +08:00
|
|
|
win_determine_shadow(ps, w);
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
|
2012-10-01 10:34:40 +08:00
|
|
|
// Set fading state
|
2013-05-20 18:04:40 +08:00
|
|
|
w->in_openclose = true;
|
2018-09-30 06:30:19 +08:00
|
|
|
set_fade_callback(ps, &w, finish_map_win, true);
|
2013-01-13 13:44:05 +08:00
|
|
|
win_determine_fade(ps, w);
|
2008-02-15 13:55:17 +08:00
|
|
|
|
2013-03-23 22:06:41 +08:00
|
|
|
win_determine_blur_background(ps, w);
|
|
|
|
|
2018-09-09 09:29:45 +08:00
|
|
|
w->ever_damaged = false;
|
2004-09-10 13:55:19 +08:00
|
|
|
|
2011-11-04 17:18:10 +08:00
|
|
|
/* if any configure events happened while
|
|
|
|
the window was unmapped, then configure
|
|
|
|
the window to its correct place */
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
if (w->need_configure)
|
2012-11-19 09:46:07 +08:00
|
|
|
configure_win(ps, &w->queue_configure);
|
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
|
|
|
|
2018-11-02 05:05:52 +08:00
|
|
|
// We stopped listening on ShapeNotify events
|
|
|
|
// when the window is unmapped (XXX we shouldn't),
|
|
|
|
// so the shape of the window might have changed,
|
|
|
|
// update. (Issue #35)
|
|
|
|
win_update_bounding_shape(ps, w);
|
|
|
|
|
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
|
|
|
#ifdef CONFIG_DBUS
|
|
|
|
// Send D-Bus signal
|
|
|
|
if (ps->o.dbus) {
|
|
|
|
cdbus_ev_win_mapped(ps, w);
|
|
|
|
}
|
|
|
|
#endif
|
2003-11-09 15:08:23 +08:00
|
|
|
}
|
|
|
|
|
2012-09-26 21:40:48 +08:00
|
|
|
static void
|
2018-09-30 06:30:19 +08:00
|
|
|
finish_unmap_win(session_t *ps, win **_w) {
|
|
|
|
win *w = *_w;
|
2018-09-09 09:29:45 +08:00
|
|
|
w->ever_damaged = false;
|
2013-01-13 13:44:05 +08:00
|
|
|
w->in_openclose = false;
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
w->reg_ignore_valid = false;
|
2013-01-13 13:44:05 +08:00
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
/* damage region */
|
|
|
|
add_damage_from_win(ps, w);
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2018-11-04 06:38:18 +08:00
|
|
|
free_paint(ps, &w->paint);
|
2013-03-15 23:16:23 +08:00
|
|
|
free_paint(ps, &w->shadow_paint);
|
2003-11-25 01:11:00 +08:00
|
|
|
}
|
|
|
|
|
2004-07-08 15:07:26 +08:00
|
|
|
static void
|
2018-09-30 06:30:19 +08:00
|
|
|
unmap_win(session_t *ps, win **_w) {
|
|
|
|
win *w = *_w;
|
2018-11-05 02:54:04 +08:00
|
|
|
if (!w || w->a.map_state == XCB_MAP_STATE_UNMAPPED) return;
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2016-07-15 03:32:45 +08:00
|
|
|
if (w->destroyed) return;
|
|
|
|
|
2018-11-08 22:53:13 +08:00
|
|
|
// One last synchronization
|
|
|
|
if (w->paint.pixmap)
|
|
|
|
xr_sync(ps, w->paint.pixmap, &w->fence);
|
|
|
|
free_fence(ps, &w->fence);
|
|
|
|
|
2012-12-05 18:12:21 +08:00
|
|
|
// Set focus out
|
|
|
|
win_set_focused(ps, w, false);
|
|
|
|
|
2018-11-05 02:54:04 +08:00
|
|
|
w->a.map_state = XCB_MAP_STATE_UNMAPPED;
|
2012-12-07 22:38:10 +08:00
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
// Fading out
|
2012-11-28 11:44:00 +08:00
|
|
|
w->flags |= WFLAG_OPCT_CHANGE;
|
2018-09-30 06:30:19 +08:00
|
|
|
set_fade_callback(ps, _w, finish_unmap_win, false);
|
2013-05-20 18:04:40 +08:00
|
|
|
w->in_openclose = true;
|
2013-01-29 09:57:04 +08:00
|
|
|
win_determine_fade(ps, w);
|
|
|
|
|
|
|
|
// Validate pixmap if we have to do fading
|
|
|
|
if (w->fade)
|
|
|
|
win_validate_pixmap(ps, w);
|
2012-09-19 20:49:16 +08:00
|
|
|
|
2012-09-17 16:04:04 +08:00
|
|
|
// don't care about properties anymore
|
2012-11-19 09:46:07 +08:00
|
|
|
win_ev_stop(ps, w);
|
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
|
|
|
|
|
|
|
#ifdef CONFIG_DBUS
|
|
|
|
// Send D-Bus signal
|
|
|
|
if (ps->o.dbus) {
|
|
|
|
cdbus_ev_win_unmapped(ps, w);
|
|
|
|
}
|
|
|
|
#endif
|
2004-07-08 15:07:26 +08:00
|
|
|
}
|
2003-11-25 01:11:00 +08:00
|
|
|
|
2018-09-07 02:17:26 +08:00
|
|
|
static void
|
|
|
|
restack_win(session_t *ps, win *w, Window new_above) {
|
|
|
|
Window old_above;
|
2003-11-25 01:11:00 +08:00
|
|
|
|
2018-09-07 02:17:26 +08:00
|
|
|
if (w->next) {
|
|
|
|
old_above = w->next->id;
|
2011-11-04 14:33:23 +08:00
|
|
|
} else {
|
2018-09-07 02:17:26 +08:00
|
|
|
old_above = None;
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2018-09-07 02:17:26 +08:00
|
|
|
if (old_above != new_above) {
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
w->reg_ignore_valid = false;
|
|
|
|
rc_region_unref(&w->reg_ignore);
|
|
|
|
if (w->next) {
|
|
|
|
w->next->reg_ignore_valid = false;
|
|
|
|
rc_region_unref(&w->next->reg_ignore);
|
|
|
|
}
|
|
|
|
|
2018-09-07 02:17:26 +08:00
|
|
|
win **prev = NULL, **prev_old = NULL;
|
2012-09-11 22:22:58 +08:00
|
|
|
|
2018-09-07 02:17:26 +08:00
|
|
|
// unhook
|
|
|
|
for (prev = &ps->list; *prev; prev = &(*prev)->next) {
|
|
|
|
if ((*prev) == w) break;
|
2018-08-12 01:54:51 +08:00
|
|
|
}
|
2018-08-12 02:17:04 +08:00
|
|
|
|
2018-09-07 02:17:26 +08:00
|
|
|
prev_old = prev;
|
2012-09-11 22:22:58 +08:00
|
|
|
|
2018-09-07 02:17:26 +08:00
|
|
|
bool found = false;
|
2012-09-11 22:22:58 +08:00
|
|
|
|
2018-09-07 02:17:26 +08:00
|
|
|
// rehook
|
|
|
|
for (prev = &ps->list; *prev; prev = &(*prev)->next) {
|
|
|
|
if ((*prev)->id == new_above && !(*prev)->destroyed) {
|
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2012-09-12 10:52:52 +08:00
|
|
|
|
2018-09-07 02:17:26 +08:00
|
|
|
if (new_above && !found) {
|
|
|
|
printf_errf("(%#010lx, %#010lx): "
|
|
|
|
"Failed to found new above window.", w->id, new_above);
|
|
|
|
return;
|
|
|
|
}
|
2012-11-28 11:44:00 +08:00
|
|
|
|
2018-09-07 02:17:26 +08:00
|
|
|
*prev_old = w->next;
|
2012-09-12 10:52:52 +08:00
|
|
|
|
2018-09-07 02:17:26 +08:00
|
|
|
w->next = *prev;
|
|
|
|
*prev = w;
|
2012-09-12 10:52:52 +08:00
|
|
|
|
2018-10-30 01:13:23 +08:00
|
|
|
// add damage for this window
|
|
|
|
add_damage_from_win(ps, w);
|
|
|
|
|
2018-09-07 02:17:26 +08:00
|
|
|
#ifdef DEBUG_RESTACK
|
|
|
|
{
|
|
|
|
const char *desc;
|
|
|
|
char *window_name = NULL;
|
|
|
|
bool to_free;
|
|
|
|
win* c = ps->list;
|
2012-09-19 20:49:16 +08:00
|
|
|
|
2018-09-07 02:17:26 +08:00
|
|
|
printf_dbgf("(%#010lx, %#010lx): "
|
|
|
|
"Window stack modified. Current stack:\n", w->id, new_above);
|
2012-11-09 11:35:40 +08:00
|
|
|
|
2018-09-07 02:17:26 +08:00
|
|
|
for (; c; c = c->next) {
|
|
|
|
window_name = "(Failed to get title)";
|
2012-10-28 17:02:07 +08:00
|
|
|
|
2018-09-07 02:17:26 +08:00
|
|
|
to_free = ev_window_name(ps, c->id, &window_name);
|
2012-10-28 17:02:07 +08:00
|
|
|
|
2018-09-07 02:17:26 +08:00
|
|
|
desc = "";
|
|
|
|
if (c->destroyed) desc = "(D) ";
|
|
|
|
printf("%#010lx \"%s\" %s", c->id, window_name, desc);
|
|
|
|
if (c->next)
|
|
|
|
printf("-> ");
|
2012-10-28 17:02:07 +08:00
|
|
|
|
2018-09-07 02:17:26 +08:00
|
|
|
if (to_free) {
|
|
|
|
cxfree(window_name);
|
|
|
|
window_name = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fputs("\n", stdout);
|
|
|
|
}
|
|
|
|
#endif
|
2012-10-28 17:02:07 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-07 02:17:26 +08:00
|
|
|
static bool
|
|
|
|
init_filters(session_t *ps);
|
2012-11-09 11:35:40 +08:00
|
|
|
|
|
|
|
static void
|
2018-09-23 06:44:44 +08:00
|
|
|
configure_win(session_t *ps, xcb_configure_notify_event_t *ce) {
|
2018-09-07 02:17:26 +08:00
|
|
|
// On root window changes
|
|
|
|
if (ce->window == ps->root) {
|
|
|
|
free_paint(ps, &ps->tgt_buffer);
|
2012-11-09 11:35:40 +08:00
|
|
|
|
2018-09-07 02:17:26 +08:00
|
|
|
ps->root_width = ce->width;
|
|
|
|
ps->root_height = ce->height;
|
2012-11-09 11:35:40 +08:00
|
|
|
|
2018-09-07 02:17:26 +08:00
|
|
|
rebuild_screen_reg(ps);
|
|
|
|
rebuild_shadow_exclude_reg(ps);
|
|
|
|
free_all_damage_last(ps);
|
2014-04-19 21:52:20 +08:00
|
|
|
|
2018-09-07 02:17:26 +08:00
|
|
|
// Re-redirect screen if required
|
|
|
|
if (ps->o.reredir_on_root_change && ps->redirected) {
|
|
|
|
redir_stop(ps);
|
|
|
|
redir_start(ps);
|
|
|
|
}
|
2014-04-19 21:52:20 +08:00
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
// Invalidate reg_ignore from the top
|
|
|
|
rc_region_unref(&ps->list->reg_ignore);
|
|
|
|
ps->list->reg_ignore_valid = false;
|
|
|
|
|
2018-09-07 02:17:26 +08:00
|
|
|
#ifdef CONFIG_OPENGL
|
|
|
|
// Reinitialize GLX on root change
|
|
|
|
if (ps->o.glx_reinit_on_root_change && ps->psglx) {
|
|
|
|
if (!glx_reinit(ps, bkend_use_glx(ps)))
|
|
|
|
printf_errf("(): Failed to reinitialize GLX, troubles ahead.");
|
|
|
|
if (BKEND_GLX == ps->o.backend && !init_filters(ps))
|
|
|
|
printf_errf("(): Failed to initialize filters.");
|
|
|
|
}
|
2014-04-19 21:52:20 +08:00
|
|
|
|
2018-09-07 02:17:26 +08:00
|
|
|
// GLX root change callback
|
|
|
|
if (BKEND_GLX == ps->o.backend)
|
|
|
|
glx_on_root_change(ps);
|
|
|
|
#endif
|
2014-04-19 21:52:20 +08:00
|
|
|
|
2018-09-07 02:17:26 +08:00
|
|
|
force_repaint(ps);
|
2012-09-17 22:15:04 +08:00
|
|
|
|
2018-09-07 02:17:26 +08:00
|
|
|
return;
|
|
|
|
}
|
2013-01-12 22:21:35 +08:00
|
|
|
|
2018-09-07 02:17:26 +08:00
|
|
|
// Other window changes
|
|
|
|
win *w = find_win(ps, ce->window);
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
region_t damage;
|
|
|
|
pixman_region32_init(&damage);
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-10-30 18:11:30 +08:00
|
|
|
if (!w)
|
2011-11-04 14:33:23 +08:00
|
|
|
return;
|
|
|
|
|
2018-11-02 05:05:52 +08:00
|
|
|
if (w->a.map_state == XCB_MAP_STATE_UNMAPPED) {
|
2011-11-04 14:33:23 +08:00
|
|
|
/* save the configure event for when the window maps */
|
2012-11-19 09:46:07 +08:00
|
|
|
w->need_configure = true;
|
2011-11-04 14:33:23 +08:00
|
|
|
w->queue_configure = *ce;
|
2018-09-23 06:44:44 +08:00
|
|
|
restack_win(ps, w, ce->above_sibling);
|
2011-11-04 14:33:23 +08:00
|
|
|
} else {
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
if (!w->need_configure)
|
2018-09-23 06:44:44 +08:00
|
|
|
restack_win(ps, w, ce->above_sibling);
|
2012-09-13 13:58:05 +08:00
|
|
|
|
2013-06-19 19:36:48 +08:00
|
|
|
bool factor_change = false;
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
w->need_configure = false;
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
win_extents(w, &damage);
|
2008-02-15 13:55:17 +08:00
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
// If window geometry change, free old extents
|
2018-09-24 02:10:46 +08:00
|
|
|
if (w->g.x != ce->x || w->g.y != ce->y
|
|
|
|
|| w->g.width != ce->width || w->g.height != ce->height
|
2018-10-13 08:17:59 +08:00
|
|
|
|| w->g.border_width != ce->border_width)
|
2013-06-19 19:36:48 +08:00
|
|
|
factor_change = true;
|
2012-11-01 10:43:15 +08:00
|
|
|
|
2018-09-24 02:10:46 +08:00
|
|
|
w->g.x = ce->x;
|
|
|
|
w->g.y = ce->y;
|
2011-11-05 20:00:39 +08:00
|
|
|
|
2018-09-24 02:10:46 +08:00
|
|
|
if (w->g.width != ce->width || w->g.height != ce->height
|
|
|
|
|| w->g.border_width != ce->border_width) {
|
|
|
|
w->g.width = ce->width;
|
|
|
|
w->g.height = ce->height;
|
|
|
|
w->g.border_width = ce->border_width;
|
2012-11-19 09:46:07 +08:00
|
|
|
calc_win_size(ps, w);
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
win_update_bounding_shape(ps, w);
|
2012-09-17 22:15:04 +08:00
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
region_t new_extents;
|
|
|
|
pixman_region32_init(&new_extents);
|
|
|
|
win_extents(w, &new_extents);
|
|
|
|
pixman_region32_union(&damage, &damage, &new_extents);
|
|
|
|
pixman_region32_fini(&new_extents);
|
2013-06-19 19:36:48 +08:00
|
|
|
|
2013-08-22 21:15:04 +08:00
|
|
|
if (factor_change) {
|
2018-10-17 00:16:18 +08:00
|
|
|
win_on_factor_change(ps, w);
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
add_damage(ps, &damage);
|
2013-08-22 21:15:04 +08:00
|
|
|
cxinerama_win_upd_scr(ps, w);
|
|
|
|
}
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2008-02-20 14:20:40 +08:00
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
pixman_region32_fini(&damage);
|
|
|
|
|
2013-01-29 09:57:04 +08:00
|
|
|
// override_redirect flag cannot be changed after window creation, as far
|
|
|
|
// as I know, so there's no point to re-match windows here.
|
2011-11-04 14:33:23 +08:00
|
|
|
w->a.override_redirect = ce->override_redirect;
|
2003-11-09 15:08:23 +08:00
|
|
|
}
|
|
|
|
|
2003-11-24 07:20:42 +08:00
|
|
|
static void
|
2018-09-23 06:44:44 +08:00
|
|
|
circulate_win(session_t *ps, xcb_circulate_notify_event_t *ce) {
|
2012-11-19 09:46:07 +08:00
|
|
|
win *w = find_win(ps, ce->window);
|
2011-11-04 16:41:56 +08:00
|
|
|
Window new_above;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2011-11-04 16:41:56 +08:00
|
|
|
if (!w) return;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2011-11-04 16:41:56 +08:00
|
|
|
if (ce->place == PlaceOnTop) {
|
2012-11-19 09:46:07 +08:00
|
|
|
new_above = ps->list->id;
|
2011-11-04 16:41:56 +08:00
|
|
|
} else {
|
2011-11-04 14:33:23 +08:00
|
|
|
new_above = None;
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
restack_win(ps, w, new_above);
|
2003-11-24 07:20:42 +08:00
|
|
|
}
|
|
|
|
|
2003-11-20 00:12:15 +08:00
|
|
|
static void
|
2018-09-30 06:30:19 +08:00
|
|
|
finish_destroy_win(session_t *ps, win **_w) {
|
|
|
|
win *w = *_w;
|
2016-07-15 04:43:20 +08:00
|
|
|
assert(w->destroyed);
|
|
|
|
win **prev = NULL, *i = NULL;
|
2014-01-21 22:13:06 +08:00
|
|
|
|
|
|
|
#ifdef DEBUG_EVENTS
|
2016-07-15 04:43:20 +08:00
|
|
|
printf_dbgf("(%#010lx): Starting...\n", w->id);
|
2014-01-21 22:13:06 +08:00
|
|
|
#endif
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2016-07-15 04:43:20 +08:00
|
|
|
for (prev = &ps->list; (i = *prev); prev = &i->next) {
|
|
|
|
if (w == i) {
|
2014-01-21 22:13:06 +08:00
|
|
|
#ifdef DEBUG_EVENTS
|
2016-07-15 04:43:20 +08:00
|
|
|
printf_dbgf("(%#010lx \"%s\"): %p\n", w->id, w->name, w);
|
2014-01-21 22:13:06 +08:00
|
|
|
#endif
|
|
|
|
|
2018-09-30 06:30:19 +08:00
|
|
|
finish_unmap_win(ps, _w);
|
2011-11-04 14:33:23 +08:00
|
|
|
*prev = w->next;
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2012-11-04 18:11:08 +08:00
|
|
|
// Clear active_win if it's pointing to the destroyed window
|
2012-11-27 00:02:18 +08:00
|
|
|
if (w == ps->active_win)
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->active_win = NULL;
|
2012-11-04 18:11:08 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
free_win_res(ps, w);
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2014-01-21 22:13:06 +08:00
|
|
|
// Drop w from all prev_trans to avoid accessing freed memory in
|
|
|
|
// repair_win()
|
|
|
|
for (win *w2 = ps->list; w2; w2 = w2->next)
|
|
|
|
if (w == w2->prev_trans)
|
|
|
|
w2->prev_trans = NULL;
|
|
|
|
|
2011-11-04 14:33:23 +08:00
|
|
|
free(w);
|
2018-09-30 06:30:19 +08:00
|
|
|
*_w = NULL;
|
2011-11-04 14:33:23 +08:00
|
|
|
break;
|
|
|
|
}
|
2011-11-05 05:18:56 +08:00
|
|
|
}
|
2003-11-09 15:08:23 +08:00
|
|
|
}
|
|
|
|
|
2004-07-08 15:07:26 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
destroy_win(session_t *ps, Window id) {
|
|
|
|
win *w = find_win(ps, id);
|
2008-02-15 13:55:17 +08:00
|
|
|
|
2014-01-21 22:13:06 +08:00
|
|
|
#ifdef DEBUG_EVENTS
|
|
|
|
printf_dbgf("(%#010lx \"%s\"): %p\n", id, (w ? w->name: NULL), w);
|
|
|
|
#endif
|
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
if (w) {
|
2018-09-30 06:30:19 +08:00
|
|
|
unmap_win(ps, &w);
|
2013-01-29 09:57:04 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
w->destroyed = true;
|
2008-02-19 05:44:41 +08:00
|
|
|
|
2014-05-16 15:18:17 +08:00
|
|
|
if (ps->o.no_fading_destroyed_argb)
|
|
|
|
win_determine_fade(ps, w);
|
|
|
|
|
2013-01-29 09:57:04 +08:00
|
|
|
// Set fading callback
|
2018-09-30 06:30:19 +08:00
|
|
|
set_fade_callback(ps, &w, finish_destroy_win, false);
|
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
|
|
|
|
|
|
|
#ifdef CONFIG_DBUS
|
|
|
|
// Send D-Bus signal
|
|
|
|
if (ps->o.dbus) {
|
|
|
|
cdbus_ev_win_destroyed(ps, w);
|
|
|
|
}
|
|
|
|
#endif
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2004-07-08 15:07:26 +08:00
|
|
|
}
|
|
|
|
|
2012-10-24 10:09:59 +08:00
|
|
|
static inline void
|
2012-11-19 09:46:07 +08:00
|
|
|
root_damaged(session_t *ps) {
|
2013-03-15 23:16:23 +08:00
|
|
|
if (ps->root_tile_paint.pixmap) {
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_clear_area(ps->c, true, ps->root, 0, 0, 0, 0);
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
free_root_tile(ps);
|
2012-10-24 10:09:59 +08:00
|
|
|
}
|
2013-01-24 13:38:03 +08:00
|
|
|
|
|
|
|
// Mark screen damaged
|
|
|
|
force_repaint(ps);
|
2012-10-24 10:09:59 +08:00
|
|
|
}
|
|
|
|
|
2018-09-29 17:11:43 +08:00
|
|
|
/**
|
|
|
|
* Xlib error handler function.
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
xerror(Display __attribute__((unused)) *dpy, XErrorEvent *ev) {
|
2018-09-30 21:37:21 +08:00
|
|
|
if (!should_ignore(ps_g, ev->serial))
|
|
|
|
x_print_error(ev->serial, ev->request_code, ev->minor_code, ev->error_code);
|
2011-11-04 14:33:23 +08:00
|
|
|
return 0;
|
2003-11-09 15:08:23 +08:00
|
|
|
}
|
|
|
|
|
2018-09-29 17:11:43 +08:00
|
|
|
/**
|
|
|
|
* XCB error handler function.
|
|
|
|
*/
|
2018-09-30 15:31:22 +08:00
|
|
|
void
|
2018-09-29 17:11:43 +08:00
|
|
|
ev_xcb_error(session_t __attribute__((unused)) *ps, xcb_generic_error_t *err) {
|
2018-09-30 21:37:21 +08:00
|
|
|
if (!should_ignore(ps, err->sequence))
|
|
|
|
x_print_error(err->sequence, err->major_code, err->minor_code, err->error_code);
|
2018-09-29 17:11:43 +08:00
|
|
|
}
|
|
|
|
|
2003-11-20 00:12:15 +08:00
|
|
|
static void
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
expose_root(session_t *ps, const rect_t *rects, int nrects) {
|
2014-03-11 07:22:23 +08:00
|
|
|
free_all_damage_last(ps);
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
region_t region;
|
|
|
|
pixman_region32_init_rects(®ion, rects, nrects);
|
|
|
|
add_damage(ps, ®ion);
|
2003-11-09 15:08:23 +08:00
|
|
|
}
|
2013-01-24 13:38:03 +08:00
|
|
|
/**
|
|
|
|
* Force a full-screen repaint.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
force_repaint(session_t *ps) {
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
assert(pixman_region32_not_empty(&ps->screen_reg));
|
2018-10-03 03:22:26 +08:00
|
|
|
queue_redraw(ps);
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
add_damage(ps, &ps->screen_reg);
|
2013-01-24 13:38:03 +08:00
|
|
|
}
|
|
|
|
|
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
|
|
|
#ifdef CONFIG_DBUS
|
|
|
|
/** @name DBus hooks
|
|
|
|
*/
|
|
|
|
///@{
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set w->shadow_force of a window.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
win_set_shadow_force(session_t *ps, win *w, switch_t val) {
|
|
|
|
if (val != w->shadow_force) {
|
|
|
|
w->shadow_force = val;
|
|
|
|
win_determine_shadow(ps, w);
|
2018-10-03 03:22:26 +08:00
|
|
|
queue_redraw(ps);
|
2013-05-20 18:04:40 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set w->fade_force of a window.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
win_set_fade_force(session_t *ps, win *w, switch_t val) {
|
|
|
|
if (val != w->fade_force) {
|
|
|
|
w->fade_force = val;
|
|
|
|
win_determine_fade(ps, w);
|
2018-10-03 03:22:26 +08:00
|
|
|
queue_redraw(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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set w->focused_force of a window.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
win_set_focused_force(session_t *ps, win *w, switch_t val) {
|
|
|
|
if (val != w->focused_force) {
|
|
|
|
w->focused_force = val;
|
|
|
|
win_update_focused(ps, w);
|
2018-10-03 03:22:26 +08:00
|
|
|
queue_redraw(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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set w->invert_color_force of a window.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
win_set_invert_color_force(session_t *ps, win *w, switch_t val) {
|
|
|
|
if (val != w->invert_color_force) {
|
|
|
|
w->invert_color_force = val;
|
|
|
|
win_determine_invert_color(ps, w);
|
2018-10-03 03:22:26 +08:00
|
|
|
queue_redraw(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
|
|
|
}
|
|
|
|
}
|
2013-03-10 18:45:54 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Enable focus tracking.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
opts_init_track_focus(session_t *ps) {
|
|
|
|
// Already tracking focus
|
|
|
|
if (ps->o.track_focus)
|
|
|
|
return;
|
|
|
|
|
|
|
|
ps->o.track_focus = true;
|
|
|
|
|
|
|
|
if (!ps->o.use_ewmh_active_win) {
|
|
|
|
// Start listening to FocusChange events
|
|
|
|
for (win *w = ps->list; w; w = w->next)
|
2018-11-05 02:54:04 +08:00
|
|
|
if (w->a.map_state == XCB_MAP_STATE_VIEWABLE)
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_change_window_attributes(ps->c, w->id, XCB_CW_EVENT_MASK,
|
2018-10-03 20:34:24 +08:00
|
|
|
(const uint32_t[]) { determine_evmask(ps, w->id, WIN_EVMODE_FRAME) });
|
2013-03-10 18:45:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Recheck focus
|
|
|
|
recheck_focus(ps);
|
|
|
|
}
|
2013-05-20 18:04:40 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Set no_fading_openclose option.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
opts_set_no_fading_openclose(session_t *ps, bool newval) {
|
|
|
|
if (newval != ps->o.no_fading_openclose) {
|
|
|
|
ps->o.no_fading_openclose = newval;
|
|
|
|
for (win *w = ps->list; w; w = w->next)
|
|
|
|
win_determine_fade(ps, w);
|
2018-10-03 03:22:26 +08:00
|
|
|
queue_redraw(ps);
|
2013-05-20 18:04:40 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
//!@}
|
|
|
|
#endif
|
|
|
|
|
2018-09-24 02:10:46 +08:00
|
|
|
static inline int __attribute__((unused))
|
|
|
|
ev_serial(xcb_generic_event_t *ev) {
|
|
|
|
return ev->full_sequence;
|
2003-11-24 07:20:42 +08:00
|
|
|
}
|
|
|
|
|
2018-09-24 02:10:46 +08:00
|
|
|
static inline const char * __attribute__((unused))
|
2018-09-23 06:44:44 +08:00
|
|
|
ev_name(session_t *ps, xcb_generic_event_t *ev) {
|
2011-11-04 17:18:10 +08:00
|
|
|
static char buf[128];
|
2018-09-23 06:44:44 +08:00
|
|
|
switch (ev->response_type & 0x7f) {
|
2012-11-03 05:51:40 +08:00
|
|
|
CASESTRRET(FocusIn);
|
|
|
|
CASESTRRET(FocusOut);
|
|
|
|
CASESTRRET(CreateNotify);
|
|
|
|
CASESTRRET(ConfigureNotify);
|
|
|
|
CASESTRRET(DestroyNotify);
|
|
|
|
CASESTRRET(MapNotify);
|
|
|
|
CASESTRRET(UnmapNotify);
|
|
|
|
CASESTRRET(ReparentNotify);
|
|
|
|
CASESTRRET(CirculateNotify);
|
|
|
|
CASESTRRET(Expose);
|
|
|
|
CASESTRRET(PropertyNotify);
|
|
|
|
CASESTRRET(ClientMessage);
|
2014-03-17 23:25:34 +08:00
|
|
|
}
|
2012-09-13 13:58:05 +08:00
|
|
|
|
2018-09-27 23:29:51 +08:00
|
|
|
if (ps->damage_event + XCB_DAMAGE_NOTIFY == ev->response_type)
|
2014-03-17 23:25:34 +08:00
|
|
|
return "Damage";
|
2012-09-13 13:58:05 +08:00
|
|
|
|
2018-09-23 06:44:44 +08:00
|
|
|
if (ps->shape_exists && ev->response_type == ps->shape_event)
|
2014-03-17 23:25:34 +08:00
|
|
|
return "ShapeNotify";
|
2012-09-13 13:58:05 +08:00
|
|
|
|
2018-11-08 22:53:13 +08:00
|
|
|
if (ps->xsync_exists) {
|
|
|
|
int o = ev->response_type - ps->xsync_event;
|
|
|
|
switch (o) {
|
|
|
|
CASESTRRET(XSyncCounterNotify);
|
|
|
|
CASESTRRET(XSyncAlarmNotify);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-23 06:44:44 +08:00
|
|
|
sprintf(buf, "Event %d", ev->response_type);
|
2014-03-17 23:25:34 +08:00
|
|
|
|
|
|
|
return buf;
|
2003-11-24 07:20:42 +08:00
|
|
|
}
|
|
|
|
|
2018-09-24 02:10:46 +08:00
|
|
|
static inline Window __attribute__((unused))
|
2018-09-23 06:44:44 +08:00
|
|
|
ev_window(session_t *ps, xcb_generic_event_t *ev) {
|
|
|
|
switch (ev->response_type) {
|
2012-09-11 21:33:03 +08:00
|
|
|
case FocusIn:
|
|
|
|
case FocusOut:
|
2018-09-23 06:44:44 +08:00
|
|
|
return ((xcb_focus_in_event_t *)ev)->event;
|
2012-09-11 21:33:03 +08:00
|
|
|
case CreateNotify:
|
2018-09-23 06:44:44 +08:00
|
|
|
return ((xcb_create_notify_event_t *)ev)->window;
|
2012-09-11 21:33:03 +08:00
|
|
|
case ConfigureNotify:
|
2018-09-23 06:44:44 +08:00
|
|
|
return ((xcb_configure_notify_event_t *)ev)->window;
|
2012-09-19 20:49:16 +08:00
|
|
|
case DestroyNotify:
|
2018-09-23 06:44:44 +08:00
|
|
|
return ((xcb_destroy_notify_event_t *)ev)->window;
|
2011-11-04 16:41:56 +08:00
|
|
|
case MapNotify:
|
2018-09-23 06:44:44 +08:00
|
|
|
return ((xcb_map_notify_event_t *)ev)->window;
|
2011-11-04 16:41:56 +08:00
|
|
|
case UnmapNotify:
|
2018-09-23 06:44:44 +08:00
|
|
|
return ((xcb_unmap_notify_event_t *)ev)->window;
|
2011-11-04 16:41:56 +08:00
|
|
|
case ReparentNotify:
|
2018-09-23 06:44:44 +08:00
|
|
|
return ((xcb_reparent_notify_event_t *)ev)->window;
|
2011-11-04 16:41:56 +08:00
|
|
|
case CirculateNotify:
|
2018-09-23 06:44:44 +08:00
|
|
|
return ((xcb_circulate_notify_event_t *)ev)->window;
|
2012-09-11 21:33:03 +08:00
|
|
|
case Expose:
|
2018-09-23 06:44:44 +08:00
|
|
|
return ((xcb_expose_event_t *)ev)->window;
|
2012-09-11 21:33:03 +08:00
|
|
|
case PropertyNotify:
|
2018-09-23 06:44:44 +08:00
|
|
|
return ((xcb_property_notify_event_t *)ev)->window;
|
2012-09-18 11:28:09 +08:00
|
|
|
case ClientMessage:
|
2018-09-23 06:44:44 +08:00
|
|
|
return ((xcb_client_message_event_t *)ev)->window;
|
2011-11-04 16:41:56 +08:00
|
|
|
default:
|
2018-09-27 23:29:51 +08:00
|
|
|
if (ps->damage_event + XCB_DAMAGE_NOTIFY == ev->response_type) {
|
2018-09-23 06:44:44 +08:00
|
|
|
return ((xcb_damage_notify_event_t *)ev)->drawable;
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
2012-09-13 13:58:05 +08:00
|
|
|
|
2018-09-23 06:44:44 +08:00
|
|
|
if (ps->shape_exists && ev->response_type == ps->shape_event) {
|
|
|
|
return ((xcb_shape_notify_event_t *) ev)->affected_window;
|
2012-09-13 13:58:05 +08:00
|
|
|
}
|
|
|
|
|
2011-11-04 16:41:56 +08:00
|
|
|
return 0;
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2003-11-24 07:20:42 +08:00
|
|
|
}
|
2012-11-03 05:51:40 +08:00
|
|
|
|
|
|
|
static inline const char *
|
2018-09-24 02:10:46 +08:00
|
|
|
ev_focus_mode_name(xcb_focus_in_event_t* ev) {
|
2012-11-03 05:51:40 +08:00
|
|
|
switch (ev->mode) {
|
|
|
|
CASESTRRET(NotifyNormal);
|
|
|
|
CASESTRRET(NotifyWhileGrabbed);
|
|
|
|
CASESTRRET(NotifyGrab);
|
|
|
|
CASESTRRET(NotifyUngrab);
|
|
|
|
}
|
|
|
|
|
|
|
|
return "Unknown";
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline const char *
|
2018-09-24 02:10:46 +08:00
|
|
|
ev_focus_detail_name(xcb_focus_in_event_t* ev) {
|
2012-11-03 05:51:40 +08:00
|
|
|
switch (ev->detail) {
|
|
|
|
CASESTRRET(NotifyAncestor);
|
|
|
|
CASESTRRET(NotifyVirtual);
|
|
|
|
CASESTRRET(NotifyInferior);
|
|
|
|
CASESTRRET(NotifyNonlinear);
|
|
|
|
CASESTRRET(NotifyNonlinearVirtual);
|
|
|
|
CASESTRRET(NotifyPointer);
|
|
|
|
CASESTRRET(NotifyPointerRoot);
|
|
|
|
CASESTRRET(NotifyDetailNone);
|
|
|
|
}
|
|
|
|
|
|
|
|
return "Unknown";
|
|
|
|
}
|
|
|
|
|
2018-09-24 02:10:46 +08:00
|
|
|
static inline void __attribute__((unused))
|
|
|
|
ev_focus_report(xcb_focus_in_event_t *ev) {
|
2012-11-03 05:51:40 +08:00
|
|
|
printf(" { mode: %s, detail: %s }\n", ev_focus_mode_name(ev),
|
|
|
|
ev_focus_detail_name(ev));
|
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
// === Events ===
|
2012-02-09 17:37:46 +08:00
|
|
|
|
2012-11-03 22:02:07 +08:00
|
|
|
/**
|
|
|
|
* Determine whether we should respond to a <code>FocusIn/Out</code>
|
|
|
|
* event.
|
|
|
|
*/
|
2014-04-19 19:41:26 +08:00
|
|
|
/*
|
2012-11-03 05:51:40 +08:00
|
|
|
inline static bool
|
|
|
|
ev_focus_accept(XFocusChangeEvent *ev) {
|
2013-09-18 21:50:57 +08:00
|
|
|
return NotifyNormal == ev->mode || NotifyUngrab == ev->mode;
|
2012-11-03 05:51:40 +08:00
|
|
|
}
|
2014-04-19 19:41:26 +08:00
|
|
|
*/
|
2012-11-03 05:51:40 +08:00
|
|
|
|
2013-09-18 21:50:57 +08:00
|
|
|
static inline void
|
2018-09-23 06:44:44 +08:00
|
|
|
ev_focus_in(session_t *ps, xcb_focus_in_event_t *ev) {
|
2012-11-03 05:51:40 +08:00
|
|
|
#ifdef DEBUG_EVENTS
|
|
|
|
ev_focus_report(ev);
|
|
|
|
#endif
|
|
|
|
|
2013-10-21 22:17:01 +08:00
|
|
|
recheck_focus(ps);
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
inline static void
|
2018-09-23 06:44:44 +08:00
|
|
|
ev_focus_out(session_t *ps, xcb_focus_out_event_t *ev) {
|
2012-11-03 05:51:40 +08:00
|
|
|
#ifdef DEBUG_EVENTS
|
|
|
|
ev_focus_report(ev);
|
|
|
|
#endif
|
|
|
|
|
2013-10-21 22:17:01 +08:00
|
|
|
recheck_focus(ps);
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
inline static void
|
2018-09-23 06:44:44 +08:00
|
|
|
ev_create_notify(session_t *ps, xcb_create_notify_event_t *ev) {
|
2012-11-19 09:46:07 +08:00
|
|
|
assert(ev->parent == ps->root);
|
2012-11-21 09:15:49 +08:00
|
|
|
add_win(ps, ev->window, 0);
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
inline static void
|
2018-09-23 06:44:44 +08:00
|
|
|
ev_configure_notify(session_t *ps, xcb_configure_notify_event_t *ev) {
|
2012-09-12 09:08:15 +08:00
|
|
|
#ifdef DEBUG_EVENTS
|
2012-11-03 05:51:40 +08:00
|
|
|
printf(" { send_event: %d, "
|
2018-09-24 02:10:46 +08:00
|
|
|
" above: %#010x, "
|
2012-09-13 13:58:05 +08:00
|
|
|
" override_redirect: %d }\n",
|
2018-09-24 02:10:46 +08:00
|
|
|
ev->event, ev->above_sibling, ev->override_redirect);
|
2012-09-11 21:33:03 +08:00
|
|
|
#endif
|
2012-11-19 09:46:07 +08:00
|
|
|
configure_win(ps, ev);
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
inline static void
|
2018-09-23 06:44:44 +08:00
|
|
|
ev_destroy_notify(session_t *ps, xcb_destroy_notify_event_t *ev) {
|
2012-11-19 09:46:07 +08:00
|
|
|
destroy_win(ps, ev->window);
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
inline static void
|
2018-09-23 06:44:44 +08:00
|
|
|
ev_map_notify(session_t *ps, xcb_map_notify_event_t *ev) {
|
2012-11-21 09:15:49 +08:00
|
|
|
map_win(ps, ev->window);
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
inline static void
|
2018-09-23 06:44:44 +08:00
|
|
|
ev_unmap_notify(session_t *ps, xcb_unmap_notify_event_t *ev) {
|
2013-01-29 09:57:04 +08:00
|
|
|
win *w = find_win(ps, ev->window);
|
|
|
|
|
|
|
|
if (w)
|
2018-09-30 06:30:19 +08:00
|
|
|
unmap_win(ps, &w);
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
inline static void
|
2018-09-23 06:44:44 +08:00
|
|
|
ev_reparent_notify(session_t *ps, xcb_reparent_notify_event_t *ev) {
|
2013-03-03 21:53:08 +08:00
|
|
|
#ifdef DEBUG_EVENTS
|
2018-09-24 02:10:46 +08:00
|
|
|
printf_dbg(" { new_parent: %#010x, override_redirect: %d }\n",
|
2013-03-03 21:53:08 +08:00
|
|
|
ev->parent, ev->override_redirect);
|
|
|
|
#endif
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ev->parent == ps->root) {
|
2012-11-21 09:15:49 +08:00
|
|
|
add_win(ps, ev->window, 0);
|
2012-02-09 17:37:46 +08:00
|
|
|
} else {
|
2012-11-19 09:46:07 +08:00
|
|
|
destroy_win(ps, ev->window);
|
2012-12-07 22:38:10 +08:00
|
|
|
|
2012-09-13 22:30:18 +08:00
|
|
|
// Reset event mask in case something wrong happens
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_change_window_attributes(ps->c, ev->window, XCB_CW_EVENT_MASK,
|
2018-10-03 20:34:24 +08:00
|
|
|
(const uint32_t[]) { determine_evmask(ps, ev->window, WIN_EVMODE_UNKNOWN) });
|
2012-12-07 22:38:10 +08:00
|
|
|
|
|
|
|
// Check if the window is an undetected client window
|
|
|
|
// Firstly, check if it's a known client window
|
|
|
|
if (!find_toplevel(ps, ev->window)) {
|
|
|
|
// If not, look for its frame window
|
|
|
|
win *w_top = find_toplevel2(ps, ev->parent);
|
2012-12-08 11:10:08 +08:00
|
|
|
// If found, and the client window has not been determined, or its
|
|
|
|
// frame may not have a correct client, continue
|
|
|
|
if (w_top && (!w_top->client_win
|
|
|
|
|| w_top->client_win == w_top->id)) {
|
2012-12-07 22:38:10 +08:00
|
|
|
// If it has WM_STATE, mark it the client window
|
|
|
|
if (wid_has_prop(ps, ev->window, ps->atom_client)) {
|
|
|
|
w_top->wmwin = false;
|
|
|
|
win_unmark_client(ps, w_top);
|
|
|
|
win_mark_client(ps, w_top, ev->window);
|
|
|
|
}
|
|
|
|
// Otherwise, watch for WM_STATE on it
|
|
|
|
else {
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_change_window_attributes(ps->c, ev->window, XCB_CW_EVENT_MASK, (const uint32_t[]) {
|
2018-10-04 15:15:38 +08:00
|
|
|
determine_evmask(ps, ev->window, WIN_EVMODE_UNKNOWN) | XCB_EVENT_MASK_PROPERTY_CHANGE });
|
2012-12-07 22:38:10 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
inline static void
|
2018-09-23 06:44:44 +08:00
|
|
|
ev_circulate_notify(session_t *ps, xcb_circulate_notify_event_t *ev) {
|
2012-11-19 09:46:07 +08:00
|
|
|
circulate_win(ps, ev);
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
inline static void
|
2018-09-23 06:44:44 +08:00
|
|
|
ev_expose(session_t *ps, xcb_expose_event_t *ev) {
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ev->window == ps->root || (ps->overlay && ev->window == ps->overlay)) {
|
2012-02-09 17:37:46 +08:00
|
|
|
int more = ev->count + 1;
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->n_expose == ps->size_expose) {
|
|
|
|
if (ps->expose_rects) {
|
|
|
|
ps->expose_rects = realloc(ps->expose_rects,
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
(ps->size_expose + more) * sizeof(rect_t));
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->size_expose += more;
|
2012-02-09 17:37:46 +08:00
|
|
|
} else {
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
ps->expose_rects = malloc(more * sizeof(rect_t));
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->size_expose = more;
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
ps->expose_rects[ps->n_expose].x1 = ev->x;
|
|
|
|
ps->expose_rects[ps->n_expose].y1 = ev->y;
|
|
|
|
ps->expose_rects[ps->n_expose].x2 = ev->x + ev->width;
|
|
|
|
ps->expose_rects[ps->n_expose].y2 = ev->y + ev->height;
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->n_expose++;
|
2012-02-09 17:37:46 +08:00
|
|
|
|
|
|
|
if (ev->count == 0) {
|
2012-11-19 09:46:07 +08:00
|
|
|
expose_root(ps, ps->expose_rects, ps->n_expose);
|
|
|
|
ps->n_expose = 0;
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-04 18:11:08 +08:00
|
|
|
/**
|
|
|
|
* Update current active window based on EWMH _NET_ACTIVE_WIN.
|
|
|
|
*
|
|
|
|
* Does not change anything if we fail to get the attribute or the window
|
|
|
|
* returned could not be found.
|
|
|
|
*/
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
update_ewmh_active_win(session_t *ps) {
|
2012-11-04 18:11:08 +08:00
|
|
|
// Search for the window
|
2013-09-18 21:50:57 +08:00
|
|
|
Window wid = wid_get_prop_window(ps, ps->root, ps->atom_ewmh_active_win);
|
|
|
|
win *w = find_win_all(ps, wid);
|
2012-11-04 18:11:08 +08:00
|
|
|
|
2013-09-18 21:50:57 +08:00
|
|
|
// Mark the window focused. No need to unfocus the previous one.
|
|
|
|
if (w) win_set_focused(ps, w, true);
|
2012-11-04 18:11:08 +08:00
|
|
|
}
|
|
|
|
|
2012-02-09 17:37:46 +08:00
|
|
|
inline static void
|
2018-09-23 06:44:44 +08:00
|
|
|
ev_property_notify(session_t *ps, xcb_property_notify_event_t *ev) {
|
2013-03-01 12:41:16 +08:00
|
|
|
#ifdef DEBUG_EVENTS
|
|
|
|
{
|
|
|
|
// Print out changed atom
|
2018-10-03 20:54:03 +08:00
|
|
|
xcb_get_atom_name_reply_t *reply =
|
|
|
|
xcb_get_atom_name_reply(ps->c, xcb_get_atom_name(ps->c, ev->atom), NULL);
|
|
|
|
const char *name = "?";
|
|
|
|
int name_len = 1;
|
|
|
|
if (reply) {
|
|
|
|
name = xcb_get_atom_name_name(reply);
|
|
|
|
name_len = xcb_get_atom_name_name_length(reply);
|
|
|
|
}
|
|
|
|
|
|
|
|
printf_dbg(" { atom = %.*s }\n", name_len, name);
|
|
|
|
free(reply);
|
2013-03-01 12:41:16 +08:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->root == ev->window) {
|
|
|
|
if (ps->o.track_focus && ps->o.use_ewmh_active_win
|
|
|
|
&& ps->atom_ewmh_active_win == ev->atom) {
|
|
|
|
update_ewmh_active_win(ps);
|
2012-11-04 18:11:08 +08:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Destroy the root "image" if the wallpaper probably changed
|
2012-11-19 09:46:07 +08:00
|
|
|
for (int p = 0; background_props_str[p]; p++) {
|
2013-01-09 20:25:01 +08:00
|
|
|
if (ev->atom == get_atom(ps, background_props_str[p])) {
|
2012-11-19 09:46:07 +08:00
|
|
|
root_damaged(ps);
|
2012-11-04 18:11:08 +08:00
|
|
|
break;
|
|
|
|
}
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
}
|
2012-11-04 18:11:08 +08:00
|
|
|
|
2012-10-24 10:09:59 +08:00
|
|
|
// Unconcerned about any other proprties on root window
|
|
|
|
return;
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
|
2012-12-07 22:38:10 +08:00
|
|
|
// If WM_STATE changes
|
|
|
|
if (ev->atom == ps->atom_client) {
|
|
|
|
// Check whether it could be a client window
|
|
|
|
if (!find_toplevel(ps, ev->window)) {
|
|
|
|
// Reset event mask anyway
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_change_window_attributes(ps->c, ev->window, XCB_CW_EVENT_MASK, (const uint32_t[]) {
|
2018-10-03 20:34:24 +08:00
|
|
|
determine_evmask(ps, ev->window, WIN_EVMODE_UNKNOWN) });
|
2012-12-07 22:38:10 +08:00
|
|
|
|
|
|
|
win *w_top = find_toplevel2(ps, ev->window);
|
2012-12-10 10:31:24 +08:00
|
|
|
// Initialize client_win as early as possible
|
|
|
|
if (w_top && (!w_top->client_win || w_top->client_win == w_top->id)
|
2012-12-07 22:38:10 +08:00
|
|
|
&& wid_has_prop(ps, ev->window, ps->atom_client)) {
|
|
|
|
w_top->wmwin = false;
|
|
|
|
win_unmark_client(ps, w_top);
|
|
|
|
win_mark_client(ps, w_top, ev->window);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-15 11:07:49 +08:00
|
|
|
// If _NET_WM_WINDOW_TYPE changes... God knows why this would happen, but
|
|
|
|
// there are always some stupid applications. (#144)
|
|
|
|
if (ev->atom == ps->atom_win_type) {
|
|
|
|
win *w = NULL;
|
|
|
|
if ((w = find_toplevel(ps, ev->window)))
|
|
|
|
win_upd_wintype(ps, w);
|
|
|
|
}
|
|
|
|
|
2012-10-03 21:13:34 +08:00
|
|
|
// If _NET_WM_OPACITY changes
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ev->atom == ps->atom_opacity) {
|
2018-08-12 01:22:49 +08:00
|
|
|
win *w = find_win(ps, ev->window) ?: find_toplevel(ps, ev->window);
|
2012-02-09 17:37:46 +08:00
|
|
|
if (w) {
|
2018-08-12 01:22:49 +08:00
|
|
|
win_update_opacity_prop(ps, w);
|
2012-11-28 11:44:00 +08:00
|
|
|
w->flags |= WFLAG_OPCT_CHANGE;
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
// If frame extents property changes
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.frame_opacity && ev->atom == ps->atom_frame_extents) {
|
|
|
|
win *w = find_toplevel(ps, ev->window);
|
2012-02-09 17:37:46 +08:00
|
|
|
if (w) {
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
win_update_frame_extents(ps, w, ev->window);
|
2012-09-20 13:50:27 +08:00
|
|
|
// If frame extents change, the window needs repaint
|
2018-09-07 02:17:26 +08:00
|
|
|
add_damage_from_win(ps, w);
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
}
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
|
|
|
|
// If name changes
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.track_wdata
|
|
|
|
&& (ps->atom_name == ev->atom || ps->atom_name_ewmh == ev->atom)) {
|
|
|
|
win *w = find_toplevel(ps, ev->window);
|
2012-11-28 11:44:00 +08:00
|
|
|
if (w && 1 == win_get_name(ps, w)) {
|
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(ps, w);
|
2012-11-28 11:44:00 +08:00
|
|
|
}
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// If class changes
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.track_wdata && ps->atom_class == ev->atom) {
|
|
|
|
win *w = find_toplevel(ps, ev->window);
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
if (w) {
|
2012-11-19 09:46:07 +08:00
|
|
|
win_get_class(ps, w);
|
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(ps, w);
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
}
|
|
|
|
}
|
2012-11-09 11:35:40 +08:00
|
|
|
|
2012-12-05 18:12:21 +08:00
|
|
|
// If role changes
|
|
|
|
if (ps->o.track_wdata && ps->atom_role == ev->atom) {
|
|
|
|
win *w = find_toplevel(ps, ev->window);
|
|
|
|
if (w && 1 == win_get_role(ps, w)) {
|
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(ps, w);
|
2012-12-05 18:12:21 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-09 11:35:40 +08:00
|
|
|
// If _COMPTON_SHADOW changes
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.respect_prop_shadow && ps->atom_compton_shadow == ev->atom) {
|
|
|
|
win *w = find_win(ps, ev->window);
|
2012-11-09 11:35:40 +08:00
|
|
|
if (w)
|
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(ps, w);
|
2012-11-09 11:35:40 +08:00
|
|
|
}
|
2012-12-12 12:01:51 +08:00
|
|
|
|
|
|
|
// If a leader property changes
|
|
|
|
if ((ps->o.detect_transient && ps->atom_transient == ev->atom)
|
|
|
|
|| (ps->o.detect_client_leader && ps->atom_client_leader == ev->atom)) {
|
|
|
|
win *w = find_toplevel(ps, ev->window);
|
|
|
|
if (w) {
|
|
|
|
win_update_leader(ps, w);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
// Check for other atoms we are tracking
|
|
|
|
for (latom_t *platom = ps->track_atom_lst; platom; platom = platom->next) {
|
|
|
|
if (platom->atom == ev->atom) {
|
|
|
|
win *w = find_win(ps, ev->window);
|
|
|
|
if (!w)
|
|
|
|
w = find_toplevel(ps, ev->window);
|
|
|
|
if (w)
|
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(ps, w);
|
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
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
inline static void
|
2018-09-23 06:44:44 +08:00
|
|
|
ev_damage_notify(session_t *ps, xcb_damage_notify_event_t *de) {
|
2018-09-09 09:29:45 +08:00
|
|
|
/*
|
|
|
|
if (ps->root == de->drawable) {
|
|
|
|
root_damaged();
|
|
|
|
return;
|
|
|
|
} */
|
|
|
|
|
|
|
|
win *w = find_win(ps, de->drawable);
|
|
|
|
|
|
|
|
if (!w) return;
|
|
|
|
|
2018-09-23 02:43:35 +08:00
|
|
|
repair_win(ps, w);
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
|
2012-09-13 13:58:05 +08:00
|
|
|
inline static void
|
2018-09-23 06:44:44 +08:00
|
|
|
ev_shape_notify(session_t *ps, xcb_shape_notify_event_t *ev) {
|
|
|
|
win *w = find_win(ps, ev->affected_window);
|
2018-11-05 02:54:04 +08:00
|
|
|
if (!w || w->a.map_state == XCB_MAP_STATE_UNMAPPED) return;
|
2012-09-11 21:33:03 +08:00
|
|
|
|
|
|
|
/*
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
* Empty bounding_shape may indicated an
|
2012-09-11 21:33:03 +08:00
|
|
|
* unmapped/destroyed window, in which case
|
|
|
|
* seemingly BadRegion errors would be triggered
|
|
|
|
* if we attempt to rebuild border_size
|
|
|
|
*/
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
// Mark the old border_size as damaged
|
2018-10-13 08:17:59 +08:00
|
|
|
region_t tmp = win_get_bounding_shape_global_by_val(w);
|
|
|
|
add_damage(ps, &tmp);
|
|
|
|
pixman_region32_fini(&tmp);
|
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
win_update_bounding_shape(ps, w);
|
2018-10-13 08:17:59 +08:00
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
// Mark the new border_size as damaged
|
2018-10-13 08:17:59 +08:00
|
|
|
tmp = win_get_bounding_shape_global_by_val(w);
|
|
|
|
add_damage(ps, &tmp);
|
|
|
|
pixman_region32_fini(&tmp);
|
|
|
|
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
w->reg_ignore_valid = false;
|
2012-09-11 21:33:03 +08:00
|
|
|
}
|
|
|
|
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
/**
|
|
|
|
* Handle ScreenChangeNotify events from X RandR extension.
|
|
|
|
*/
|
|
|
|
static void
|
2012-11-21 09:15:49 +08:00
|
|
|
ev_screen_change_notify(session_t *ps,
|
2018-09-23 06:44:44 +08:00
|
|
|
xcb_randr_screen_change_notify_event_t __attribute__((unused)) *ev) {
|
2013-08-28 21:47:16 +08:00
|
|
|
if (ps->o.xinerama_shadow_crop)
|
|
|
|
cxinerama_upd_scrs(ps);
|
|
|
|
|
|
|
|
if (ps->o.sw_opti && !ps->o.refresh_rate) {
|
2012-11-19 09:46:07 +08:00
|
|
|
update_refresh_rate(ps);
|
|
|
|
if (!ps->refresh_rate) {
|
2018-11-27 00:53:57 +08:00
|
|
|
fprintf(stderr, "ev_screen_change_notify(): Refresh rate detection failed."
|
|
|
|
"swopti will be temporarily disabled");
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-24 18:42:16 +08:00
|
|
|
inline static void
|
|
|
|
ev_selection_clear(session_t *ps,
|
2018-09-23 06:44:44 +08:00
|
|
|
xcb_selection_clear_event_t __attribute__((unused)) *ev) {
|
2015-10-24 18:42:16 +08:00
|
|
|
// The only selection we own is the _NET_WM_CM_Sn selection.
|
|
|
|
// If we lose that one, we should exit.
|
|
|
|
fprintf(stderr, "Another composite manager started and "
|
|
|
|
"took the _NET_WM_CM_Sn selection.\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2012-11-14 21:34:51 +08:00
|
|
|
/**
|
|
|
|
* Get a window's name from window ID.
|
|
|
|
*/
|
2018-09-24 02:10:46 +08:00
|
|
|
static inline void __attribute__((unused))
|
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
|
|
|
*name = "";
|
|
|
|
if (wid) {
|
|
|
|
*name = "(Failed to get title)";
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->root == wid)
|
2012-11-14 21:34:51 +08:00
|
|
|
*name = "(Root window)";
|
2012-11-19 09:46:07 +08:00
|
|
|
else if (ps->overlay == wid)
|
2012-11-14 21:34:51 +08:00
|
|
|
*name = "(Overlay)";
|
|
|
|
else {
|
2012-11-19 09:46:07 +08:00
|
|
|
win *w = find_win(ps, wid);
|
2012-11-14 21:34:51 +08:00
|
|
|
if (!w)
|
2012-11-19 09:46:07 +08:00
|
|
|
w = find_toplevel(ps, wid);
|
2012-11-14 21:34:51 +08:00
|
|
|
|
2018-09-09 09:29:45 +08:00
|
|
|
if (w)
|
|
|
|
win_get_name(ps, w);
|
2012-11-14 21:34:51 +08:00
|
|
|
if (w && w->name)
|
|
|
|
*name = w->name;
|
2018-09-09 09:29:45 +08:00
|
|
|
else
|
|
|
|
*name = "unknown";
|
2012-11-14 21:34:51 +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
|
|
|
static void
|
2018-09-23 06:44:44 +08:00
|
|
|
ev_handle(session_t *ps, xcb_generic_event_t *ev) {
|
|
|
|
if ((ev->response_type & 0x7f) != KeymapNotify) {
|
|
|
|
discard_ignore(ps, ev->full_sequence);
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
|
2012-09-12 09:08:15 +08:00
|
|
|
#ifdef DEBUG_EVENTS
|
2018-10-03 04:24:34 +08:00
|
|
|
if (ev->response_type != ps->damage_event + XCB_DAMAGE_NOTIFY) {
|
2012-11-19 09:46:07 +08:00
|
|
|
Window wid = ev_window(ps, ev);
|
2012-11-14 21:34:51 +08:00
|
|
|
char *window_name = NULL;
|
2018-09-09 09:29:45 +08:00
|
|
|
ev_window_name(ps, wid, &window_name);
|
2012-09-13 13:58:05 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
print_timestamp(ps);
|
2018-09-09 09:29:45 +08:00
|
|
|
printf_errf(" event %10.10s serial %#010x window %#010lx \"%s\"\n",
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_name(ps, ev), ev_serial(ev), wid, window_name);
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2018-11-11 05:52:42 +08:00
|
|
|
// Check if a custom XEvent constructor was registered in xlib for this event
|
|
|
|
// type, and call it discarding the constructed XEvent if any. XESetWireToEvent
|
|
|
|
// might be used by libraries to intercept messages from the X server e.g. the
|
|
|
|
// OpenGL lib waiting for DRI2 events.
|
|
|
|
|
|
|
|
// XXX This exists to workaround compton issue #33, #34, #47
|
|
|
|
// For even more details, see:
|
|
|
|
// https://bugs.freedesktop.org/show_bug.cgi?id=35945
|
|
|
|
// https://lists.freedesktop.org/archives/xcb/2011-November/007337.html
|
|
|
|
auto proc = XESetWireToEvent(ps->dpy, ev->response_type, 0);
|
|
|
|
if (proc) {
|
|
|
|
XESetWireToEvent(ps->dpy, ev->response_type, proc);
|
|
|
|
XEvent dummy;
|
|
|
|
|
|
|
|
// Stop Xlib from complaining about lost sequence numbers.
|
|
|
|
// proc might also just be Xlib internal event processing functions, and
|
|
|
|
// because they probably won't see all X replies, they will complain about
|
|
|
|
// missing sequence numbers.
|
|
|
|
ev->sequence = LastKnownRequestProcessed(ps->dpy);
|
|
|
|
proc(ps->dpy, &dummy, (xEvent *)ev);
|
|
|
|
}
|
|
|
|
|
2018-10-03 03:22:26 +08:00
|
|
|
// XXX redraw needs to be more fine grained
|
|
|
|
queue_redraw(ps);
|
|
|
|
|
2018-09-23 06:44:44 +08:00
|
|
|
switch (ev->response_type) {
|
2012-02-09 17:37:46 +08:00
|
|
|
case FocusIn:
|
2018-09-23 06:44:44 +08:00
|
|
|
ev_focus_in(ps, (xcb_focus_in_event_t *)ev);
|
2012-02-09 17:37:46 +08:00
|
|
|
break;
|
|
|
|
case FocusOut:
|
2018-09-23 06:44:44 +08:00
|
|
|
ev_focus_out(ps, (xcb_focus_out_event_t *)ev);
|
2012-02-09 17:37:46 +08:00
|
|
|
break;
|
|
|
|
case CreateNotify:
|
2018-09-23 06:44:44 +08:00
|
|
|
ev_create_notify(ps, (xcb_create_notify_event_t *)ev);
|
2012-02-09 17:37:46 +08:00
|
|
|
break;
|
|
|
|
case ConfigureNotify:
|
2018-09-23 06:44:44 +08:00
|
|
|
ev_configure_notify(ps, (xcb_configure_notify_event_t *)ev);
|
2012-02-09 17:37:46 +08:00
|
|
|
break;
|
|
|
|
case DestroyNotify:
|
2018-09-23 06:44:44 +08:00
|
|
|
ev_destroy_notify(ps, (xcb_destroy_notify_event_t *)ev);
|
2012-02-09 17:37:46 +08:00
|
|
|
break;
|
|
|
|
case MapNotify:
|
2018-09-23 06:44:44 +08:00
|
|
|
ev_map_notify(ps, (xcb_map_notify_event_t *)ev);
|
2012-02-09 17:37:46 +08:00
|
|
|
break;
|
|
|
|
case UnmapNotify:
|
2018-09-23 06:44:44 +08:00
|
|
|
ev_unmap_notify(ps, (xcb_unmap_notify_event_t *)ev);
|
2012-02-09 17:37:46 +08:00
|
|
|
break;
|
|
|
|
case ReparentNotify:
|
2018-09-23 06:44:44 +08:00
|
|
|
ev_reparent_notify(ps, (xcb_reparent_notify_event_t *)ev);
|
2012-02-09 17:37:46 +08:00
|
|
|
break;
|
|
|
|
case CirculateNotify:
|
2018-09-23 06:44:44 +08:00
|
|
|
ev_circulate_notify(ps, (xcb_circulate_notify_event_t *)ev);
|
2012-02-09 17:37:46 +08:00
|
|
|
break;
|
|
|
|
case Expose:
|
2018-09-23 06:44:44 +08:00
|
|
|
ev_expose(ps, (xcb_expose_event_t *)ev);
|
2012-02-09 17:37:46 +08:00
|
|
|
break;
|
|
|
|
case PropertyNotify:
|
2018-09-23 06:44:44 +08:00
|
|
|
ev_property_notify(ps, (xcb_property_notify_event_t *)ev);
|
2012-02-09 17:37:46 +08:00
|
|
|
break;
|
2015-10-24 18:42:16 +08:00
|
|
|
case SelectionClear:
|
2018-09-23 06:44:44 +08:00
|
|
|
ev_selection_clear(ps, (xcb_selection_clear_event_t *)ev);
|
2015-10-24 18:42:16 +08:00
|
|
|
break;
|
2018-09-29 17:11:43 +08:00
|
|
|
case 0:
|
|
|
|
ev_xcb_error(ps, (xcb_generic_error_t *)ev);
|
|
|
|
break;
|
2012-02-09 17:37:46 +08:00
|
|
|
default:
|
2018-09-23 06:44:44 +08:00
|
|
|
if (ps->shape_exists && ev->response_type == ps->shape_event) {
|
|
|
|
ev_shape_notify(ps, (xcb_shape_notify_event_t *) ev);
|
2012-09-11 21:33:03 +08:00
|
|
|
break;
|
|
|
|
}
|
2018-09-27 23:38:24 +08:00
|
|
|
if (ps->randr_exists && ev->response_type == (ps->randr_event + XCB_RANDR_SCREEN_CHANGE_NOTIFY)) {
|
2018-09-23 06:44:44 +08:00
|
|
|
ev_screen_change_notify(ps, (xcb_randr_screen_change_notify_event_t *) ev);
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
break;
|
|
|
|
}
|
2018-09-27 23:29:51 +08:00
|
|
|
if (ps->damage_event + XCB_DAMAGE_NOTIFY == ev->response_type) {
|
2018-09-23 06:44:44 +08:00
|
|
|
ev_damage_notify(ps, (xcb_damage_notify_event_t *) ev);
|
2013-09-04 22:00:51 +08:00
|
|
|
break;
|
2012-02-09 17:37:46 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
// === Main ===
|
2012-02-09 17:37:46 +08:00
|
|
|
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
/**
|
|
|
|
* Print usage text and exit.
|
|
|
|
*/
|
2012-02-27 12:00:12 +08:00
|
|
|
static void
|
2013-05-12 18:21:16 +08:00
|
|
|
usage(int ret) {
|
2013-01-29 09:57:04 +08:00
|
|
|
#define WARNING_DISABLED " (DISABLED AT COMPILE TIME)"
|
|
|
|
#define WARNING
|
2018-08-22 22:26:08 +08:00
|
|
|
static const char *usage_text =
|
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
|
|
|
"compton (" COMPTON_VERSION ")\n"
|
2018-09-10 19:01:07 +08:00
|
|
|
"This is the maintenance fork of compton, please report\n"
|
|
|
|
"bugs to https://github.com/yshui/compton\n\n"
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
"usage: compton [options]\n"
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
"Options:\n"
|
|
|
|
"\n"
|
2012-02-27 20:49:50 +08:00
|
|
|
"-d display\n"
|
|
|
|
" Which display should be managed.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-02-27 20:49:50 +08:00
|
|
|
"-r radius\n"
|
|
|
|
" The blur radius for shadows. (default 12)\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-02-27 20:49:50 +08:00
|
|
|
"-o opacity\n"
|
|
|
|
" The translucency for shadows. (default .75)\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-02-27 20:49:50 +08:00
|
|
|
"-l left-offset\n"
|
|
|
|
" The left offset for shadows. (default -15)\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-02-27 20:49:50 +08:00
|
|
|
"-t top-offset\n"
|
|
|
|
" The top offset for shadows. (default -15)\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-02-27 20:49:50 +08:00
|
|
|
"-I fade-in-step\n"
|
|
|
|
" Opacity change between steps while fading in. (default 0.028)\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-02-27 20:49:50 +08:00
|
|
|
"-O fade-out-step\n"
|
|
|
|
" Opacity change between steps while fading out. (default 0.03)\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-02-27 20:49:50 +08:00
|
|
|
"-D fade-delta-time\n"
|
|
|
|
" The time between steps in a fade in milliseconds. (default 10)\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-02-27 20:49:50 +08:00
|
|
|
"-m opacity\n"
|
|
|
|
" The opacity for menus. (default 1.0)\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-02-27 20:49:50 +08:00
|
|
|
"-c\n"
|
|
|
|
" Enabled client-side shadows on windows.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-02-27 20:49:50 +08:00
|
|
|
"-C\n"
|
|
|
|
" Avoid drawing shadows on dock/panel windows.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-02-27 20:49:50 +08:00
|
|
|
"-z\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
" Zero the part of the shadow's mask behind the window.\n"
|
|
|
|
"\n"
|
2012-02-27 20:49:50 +08:00
|
|
|
"-f\n"
|
2012-09-26 21:40:48 +08:00
|
|
|
" Fade windows in/out when opening/closing and when opacity\n"
|
|
|
|
" changes, unless --no-fading-openclose is used.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-02-27 20:49:50 +08:00
|
|
|
"-F\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
" Equals to -f. Deprecated.\n"
|
|
|
|
"\n"
|
2012-02-27 20:49:50 +08:00
|
|
|
"-i opacity\n"
|
|
|
|
" Opacity of inactive windows. (0.1 - 1.0)\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-02-27 20:49:50 +08:00
|
|
|
"-e opacity\n"
|
|
|
|
" Opacity of window titlebars and borders. (0.1 - 1.0)\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-02-27 20:49:50 +08:00
|
|
|
"-G\n"
|
|
|
|
" Don't draw shadows on DND windows\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-10-22 21:20:43 +08:00
|
|
|
"-b\n"
|
2012-02-27 20:49:50 +08:00
|
|
|
" Daemonize process.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-02-27 20:49:50 +08:00
|
|
|
"-S\n"
|
2012-09-11 21:57:50 +08:00
|
|
|
" Enable synchronous operation (for debugging).\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2014-04-19 19:41:26 +08:00
|
|
|
"--show-all-xerrors\n"
|
|
|
|
" Show all X errors (for debugging).\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2015-01-11 16:22:08 +08:00
|
|
|
#undef WARNING
|
|
|
|
#ifndef CONFIG_LIBCONFIG
|
|
|
|
#define WARNING WARNING_DISABLED
|
|
|
|
#else
|
|
|
|
#define WARNING
|
|
|
|
#endif
|
2012-09-25 10:19:20 +08:00
|
|
|
"--config path\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
" Look for configuration file at the path. Use /dev/null to avoid\n"
|
2015-01-11 16:22:08 +08:00
|
|
|
" loading configuration file." WARNING "\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2013-11-09 21:38:31 +08:00
|
|
|
"--write-pid-path path\n"
|
|
|
|
" Write process ID to a file.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-09-11 21:57:50 +08:00
|
|
|
"--shadow-red value\n"
|
|
|
|
" Red color value of shadow (0.0 - 1.0, defaults to 0).\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-09-11 21:57:50 +08:00
|
|
|
"--shadow-green value\n"
|
|
|
|
" Green color value of shadow (0.0 - 1.0, defaults to 0).\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-09-11 21:57:50 +08:00
|
|
|
"--shadow-blue value\n"
|
|
|
|
" Blue color value of shadow (0.0 - 1.0, defaults to 0).\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-09-11 22:22:58 +08:00
|
|
|
"--inactive-opacity-override\n"
|
|
|
|
" Inactive opacity set by -i overrides value of _NET_WM_OPACITY.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-09-12 10:52:52 +08:00
|
|
|
"--inactive-dim value\n"
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
" Dim inactive windows. (0.0 - 1.0, defaults to 0)\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2013-03-30 11:46:32 +08:00
|
|
|
"--active-opacity opacity\n"
|
|
|
|
" Default opacity for active windows. (0.0 - 1.0)\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
"--mark-wmwin-focused\n"
|
|
|
|
" Try to detect WM windows and mark them as active.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
"--shadow-exclude condition\n"
|
|
|
|
" Exclude conditions for shadows.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2013-04-21 22:30:22 +08:00
|
|
|
"--fade-exclude condition\n"
|
|
|
|
" Exclude conditions for fading.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-09-26 19:48:36 +08:00
|
|
|
"--mark-ovredir-focused\n"
|
2012-11-03 22:02:07 +08:00
|
|
|
" Mark windows that have no WM frame as active.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-09-26 21:40:48 +08:00
|
|
|
"--no-fading-openclose\n"
|
|
|
|
" Do not fade on window open/close.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2014-05-16 15:18:17 +08:00
|
|
|
"--no-fading-destroyed-argb\n"
|
|
|
|
" Do not fade destroyed ARGB windows with WM frame. Workaround of bugs\n"
|
|
|
|
" in Openbox, Fluxbox, etc.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-10-01 10:34:40 +08:00
|
|
|
"--shadow-ignore-shaped\n"
|
2014-04-21 22:45:27 +08:00
|
|
|
" Do not paint shadows on shaped windows. (Deprecated, use\n"
|
|
|
|
" --shadow-exclude \'bounding_shaped\' or\n"
|
|
|
|
" --shadow-exclude \'bounding_shaped && !rounded_corners\' instead.)\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-10-01 10:34:40 +08:00
|
|
|
"--detect-rounded-corners\n"
|
|
|
|
" Try to detect windows with rounded corners and don't consider\n"
|
2014-04-21 22:45:27 +08:00
|
|
|
" them shaped windows. Affects --shadow-ignore-shaped,\n"
|
|
|
|
" --unredir-if-possible, and possibly others. You need to turn this\n"
|
|
|
|
" on manually if you want to match against rounded_corners in\n"
|
|
|
|
" conditions.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-10-03 21:13:34 +08:00
|
|
|
"--detect-client-opacity\n"
|
|
|
|
" Detect _NET_WM_OPACITY on client windows, useful for window\n"
|
|
|
|
" managers not passing _NET_WM_OPACITY of client windows to frame\n"
|
|
|
|
" windows.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
"--refresh-rate val\n"
|
|
|
|
" Specify refresh rate of the screen. If not specified or 0, compton\n"
|
|
|
|
" will try detecting this with X RandR extension.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
"--vsync vsync-method\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
" Set VSync method. There are (up to) 5 VSync methods currently\n"
|
|
|
|
" available:\n"
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
" none = No VSync\n"
|
2013-01-29 09:57:04 +08:00
|
|
|
#undef WARNING
|
|
|
|
#ifndef CONFIG_VSYNC_DRM
|
|
|
|
#define WARNING WARNING_DISABLED
|
|
|
|
#else
|
|
|
|
#define WARNING
|
|
|
|
#endif
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
" drm = VSync with DRM_IOCTL_WAIT_VBLANK. May only work on some\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
" (DRI-based) drivers." WARNING "\n"
|
2013-01-29 09:57:04 +08:00
|
|
|
#undef WARNING
|
2018-08-22 22:12:29 +08:00
|
|
|
#ifndef CONFIG_OPENGL
|
2013-01-29 09:57:04 +08:00
|
|
|
#define WARNING WARNING_DISABLED
|
|
|
|
#else
|
|
|
|
#define WARNING
|
2013-01-29 00:08:34 +08:00
|
|
|
#endif
|
2013-04-25 09:27:14 +08:00
|
|
|
" opengl = Try to VSync with SGI_video_sync OpenGL extension. Only\n"
|
2013-03-15 23:16:23 +08:00
|
|
|
" work on some drivers." WARNING"\n"
|
2013-01-31 22:53:44 +08:00
|
|
|
" opengl-oml = Try to VSync with OML_sync_control OpenGL extension.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
" Only work on some drivers." WARNING"\n"
|
2018-12-15 01:21:05 +08:00
|
|
|
" opengl-swc = Enable driver-level VSync. Works only with GLX backend." WARNING "\n"
|
|
|
|
" opengl-mswc = Deprecated, use opengl-swc instead." WARNING "\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2013-07-30 22:24:11 +08:00
|
|
|
"--vsync-aggressive\n"
|
|
|
|
" Attempt to send painting request before VBlank and do XFlush()\n"
|
|
|
|
" during VBlank. This switch may be lifted out at any moment.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-10-24 10:09:59 +08:00
|
|
|
"--paint-on-overlay\n"
|
|
|
|
" Painting on X Composite overlay window.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-10-26 11:12:28 +08:00
|
|
|
"--sw-opti\n"
|
|
|
|
" Limit compton to repaint at most once every 1 / refresh_rate\n"
|
2013-07-30 22:24:11 +08:00
|
|
|
" second to boost performance.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-11-04 18:11:08 +08:00
|
|
|
"--use-ewmh-active-win\n"
|
|
|
|
" Use _NET_WM_ACTIVE_WINDOW on the root window to determine which\n"
|
|
|
|
" window is focused instead of using FocusIn/Out events.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-11-19 09:46:07 +08:00
|
|
|
"--respect-prop-shadow\n"
|
2012-11-09 11:35:40 +08:00
|
|
|
" Respect _COMPTON_SHADOW. This a prototype-level feature, which\n"
|
|
|
|
" you must not rely on.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-11-09 21:44:02 +08:00
|
|
|
"--unredir-if-possible\n"
|
|
|
|
" Unredirect all windows if a full-screen opaque window is\n"
|
|
|
|
" detected, to maximize performance for full-screen windows.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2013-09-04 22:00:51 +08:00
|
|
|
"--unredir-if-possible-delay ms\n"
|
|
|
|
" Delay before unredirecting the window, in milliseconds.\n"
|
|
|
|
" Defaults to 0.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2013-09-04 22:00:51 +08:00
|
|
|
"--unredir-if-possible-exclude condition\n"
|
|
|
|
" Conditions of windows that shouldn't be considered full-screen\n"
|
|
|
|
" for unredirecting screen.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-11-28 11:44:00 +08:00
|
|
|
"--focus-exclude condition\n"
|
|
|
|
" Specify a list of conditions of windows that should always be\n"
|
|
|
|
" considered focused.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-12-05 12:43:34 +08:00
|
|
|
"--inactive-dim-fixed\n"
|
|
|
|
" Use fixed inactive dim value.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-12-12 12:01:51 +08:00
|
|
|
"--detect-transient\n"
|
|
|
|
" Use WM_TRANSIENT_FOR to group windows, and consider windows in\n"
|
|
|
|
" the same group focused at the same time.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-12-12 12:01:51 +08:00
|
|
|
"--detect-client-leader\n"
|
|
|
|
" Use WM_CLIENT_LEADER to group windows, and consider windows in\n"
|
|
|
|
" the same group focused at the same time. WM_TRANSIENT_FOR has\n"
|
|
|
|
" higher priority if --detect-transient is enabled, too.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-12-14 20:32:46 +08:00
|
|
|
"--blur-background\n"
|
|
|
|
" Blur background of semi-transparent / ARGB windows. Bad in\n"
|
|
|
|
" performance. The switch name may change without prior\n"
|
|
|
|
" notifications.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-12-14 20:32:46 +08:00
|
|
|
"--blur-background-frame\n"
|
|
|
|
" Blur background of windows when the window frame is not opaque.\n"
|
|
|
|
" Implies --blur-background. Bad in performance. The switch name\n"
|
|
|
|
" may change.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2012-12-15 20:07:45 +08:00
|
|
|
"--blur-background-fixed\n"
|
|
|
|
" Use fixed blur strength instead of adjusting according to window\n"
|
|
|
|
" opacity.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2013-04-25 22:23:35 +08:00
|
|
|
"--blur-kern matrix\n"
|
|
|
|
" Specify the blur convolution kernel, with the following format:\n"
|
|
|
|
" WIDTH,HEIGHT,ELE1,ELE2,ELE3,ELE4,ELE5...\n"
|
|
|
|
" The element in the center must not be included, it will be forever\n"
|
|
|
|
" 1.0 or changing based on opacity, depending on whether you have\n"
|
|
|
|
" --blur-background-fixed.\n"
|
2014-08-06 07:32:18 +08:00
|
|
|
" A 7x7 Gaussian blur kernel looks like:\n"
|
2013-04-25 22:23:35 +08:00
|
|
|
" --blur-kern '7,7,0.000003,0.000102,0.000849,0.001723,0.000849,0.000102,0.000003,0.000102,0.003494,0.029143,0.059106,0.029143,0.003494,0.000102,0.000849,0.029143,0.243117,0.493069,0.243117,0.029143,0.000849,0.001723,0.059106,0.493069,0.493069,0.059106,0.001723,0.000849,0.029143,0.243117,0.493069,0.243117,0.029143,0.000849,0.000102,0.003494,0.029143,0.059106,0.029143,0.003494,0.000102,0.000003,0.000102,0.000849,0.001723,0.000849,0.000102,0.000003'\n"
|
2013-05-20 18:04:40 +08:00
|
|
|
" Up to 4 blur kernels may be specified, separated with semicolon, for\n"
|
|
|
|
" multi-pass blur.\n"
|
2013-04-29 22:42:46 +08:00
|
|
|
" May also be one the predefined kernels: 3x3box (default), 5x5box,\n"
|
|
|
|
" 7x7box, 3x3gaussian, 5x5gaussian, 7x7gaussian, 9x9gaussian,\n"
|
|
|
|
" 11x11gaussian.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2013-03-25 11:36:39 +08:00
|
|
|
"--blur-background-exclude condition\n"
|
|
|
|
" Exclude conditions for background blur.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2013-04-27 11:43:11 +08:00
|
|
|
"--resize-damage integer\n"
|
|
|
|
" Resize damaged region by a specific number of pixels. A positive\n"
|
|
|
|
" value enlarges it while a negative one shrinks it. Useful for\n"
|
|
|
|
" fixing the line corruption issues of blur. May or may not\n"
|
|
|
|
" work with --glx-no-stencil. Shrinking doesn't function correctly.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2013-01-12 22:21:35 +08:00
|
|
|
"--invert-color-include condition\n"
|
|
|
|
" Specify a list of conditions of windows that should be painted with\n"
|
|
|
|
" inverted color. Resource-hogging, and is not well tested.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2013-05-21 09:18:41 +08:00
|
|
|
"--opacity-rule opacity:condition\n"
|
|
|
|
" Specify a list of opacity rules, in the format \"PERCENT:PATTERN\",\n"
|
|
|
|
" like \'50:name *= \"Firefox\"'. compton-trans is recommended over\n"
|
|
|
|
" this. Note we do not distinguish 100% and unset, and we don't make\n"
|
|
|
|
" any guarantee about possible conflicts with other programs that set\n"
|
|
|
|
" _NET_WM_WINDOW_OPACITY on frame or client windows.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2013-06-09 17:06:35 +08:00
|
|
|
"--shadow-exclude-reg geometry\n"
|
|
|
|
" Specify a X geometry that describes the region in which shadow\n"
|
|
|
|
" should not be painted in, such as a dock window region.\n"
|
|
|
|
" Use --shadow-exclude-reg \'x10+0-0\', for example, if the 10 pixels\n"
|
|
|
|
" on the bottom of the screen should not have shadows painted on.\n"
|
2013-08-22 21:15:04 +08:00
|
|
|
#undef WARNING
|
|
|
|
#ifndef CONFIG_XINERAMA
|
|
|
|
#define WARNING WARNING_DISABLED
|
|
|
|
#else
|
|
|
|
#define WARNING
|
|
|
|
#endif
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2013-08-22 21:15:04 +08:00
|
|
|
"--xinerama-shadow-crop\n"
|
|
|
|
" Crop shadow of a window fully on a particular Xinerama screen to the\n"
|
|
|
|
" screen." WARNING "\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2015-01-11 16:22:08 +08:00
|
|
|
#undef WARNING
|
2018-08-22 22:12:29 +08:00
|
|
|
#ifndef CONFIG_OPENGL
|
2015-01-11 16:22:08 +08:00
|
|
|
#define WARNING "(GLX BACKENDS DISABLED AT COMPILE TIME)"
|
|
|
|
#else
|
|
|
|
#define WARNING
|
|
|
|
#endif
|
2013-03-16 22:54:43 +08:00
|
|
|
"--backend backend\n"
|
2013-12-10 22:06:02 +08:00
|
|
|
" Choose backend. Possible choices are xrender, glx, and\n"
|
2013-12-24 07:46:48 +08:00
|
|
|
" xr_glx_hybrid" WARNING ".\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2013-03-17 12:14:00 +08:00
|
|
|
"--glx-no-stencil\n"
|
2013-03-19 20:58:55 +08:00
|
|
|
" GLX backend: Avoid using stencil buffer. Might cause issues\n"
|
2013-04-06 20:21:38 +08:00
|
|
|
" when rendering transparent content. My tests show a 15% performance\n"
|
|
|
|
" boost.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2013-04-05 21:05:19 +08:00
|
|
|
"--glx-no-rebind-pixmap\n"
|
|
|
|
" GLX backend: Avoid rebinding pixmap on window damage. Probably\n"
|
|
|
|
" could improve performance on rapid window content changes, but is\n"
|
2014-07-28 16:54:02 +08:00
|
|
|
" known to break things on some drivers (LLVMpipe, xf86-video-intel,\n"
|
|
|
|
" etc.).\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2013-04-26 14:01:20 +08:00
|
|
|
"--glx-swap-method undefined/copy/exchange/3/4/5/6/buffer-age\n"
|
2013-04-21 22:30:22 +08:00
|
|
|
" GLX backend: GLX buffer swap method we assume. Could be\n"
|
2013-04-26 14:01:20 +08:00
|
|
|
" undefined (0), copy (1), exchange (2), 3-6, or buffer-age (-1).\n"
|
|
|
|
" \"undefined\" is the slowest and the safest, and the default value.\n"
|
|
|
|
" 1 is fastest, but may fail on some drivers, 2-6 are gradually slower\n"
|
|
|
|
" but safer (6 is still faster than 0). -1 means auto-detect using\n"
|
2018-10-01 04:05:32 +08:00
|
|
|
" GLX_EXT_buffer_age, supported by some drivers. \n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2013-05-08 22:44:36 +08:00
|
|
|
"--glx-use-gpushader4\n"
|
|
|
|
" GLX backend: Use GL_EXT_gpu_shader4 for some optimization on blur\n"
|
|
|
|
" GLSL code. My tests on GTX 670 show no noticeable effect.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2018-11-08 22:53:13 +08:00
|
|
|
"--xrender-sync\n"
|
|
|
|
" Attempt to synchronize client applications' draw calls with XSync(),\n"
|
|
|
|
" used on GLX backend to ensure up-to-date window content is painted.\n"
|
|
|
|
#undef WARNING
|
|
|
|
#define WARNING
|
|
|
|
"\n"
|
|
|
|
"--xrender-sync-fence\n"
|
|
|
|
" Additionally use X Sync fence to sync clients' draw calls. Needed\n"
|
|
|
|
" on nvidia-drivers with GLX backend for some users." WARNING "\n"
|
|
|
|
"\n"
|
2014-05-16 15:18:17 +08:00
|
|
|
"--force-win-blend\n"
|
|
|
|
" Force all windows to be painted with blending. Useful if you have a\n"
|
|
|
|
" --glx-fshader-win that could turn opaque pixels transparent.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2015-01-11 16:22:08 +08:00
|
|
|
#undef WARNING
|
|
|
|
#ifndef CONFIG_DBUS
|
|
|
|
#define WARNING WARNING_DISABLED
|
|
|
|
#else
|
|
|
|
#define WARNING
|
|
|
|
#endif
|
2013-01-24 13:38:03 +08:00
|
|
|
"--dbus\n"
|
|
|
|
" Enable remote control via D-Bus. See the D-BUS API section in the\n"
|
2013-03-19 20:58:55 +08:00
|
|
|
" man page for more details." WARNING "\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2013-03-19 20:58:55 +08:00
|
|
|
"--benchmark cycles\n"
|
|
|
|
" Benchmark mode. Repeatedly paint until reaching the specified cycles.\n"
|
2014-11-24 22:03:07 +08:00
|
|
|
"\n"
|
2013-03-19 20:58:55 +08:00
|
|
|
"--benchmark-wid window-id\n"
|
|
|
|
" Specify window ID to repaint in benchmark mode. If omitted or is 0,\n"
|
|
|
|
" the whole screen is repainted.\n"
|
2018-10-22 06:56:53 +08:00
|
|
|
"--monitor-repaint\n"
|
|
|
|
" Highlight the updated area of the screen. For debugging the xrender\n"
|
|
|
|
" backend only.\n"
|
2013-03-19 20:58:55 +08:00
|
|
|
;
|
2013-05-12 18:21:16 +08:00
|
|
|
FILE *f = (ret ? stderr: stdout);
|
|
|
|
fputs(usage_text, f);
|
2018-11-08 22:53:13 +08:00
|
|
|
#undef WARNING
|
2013-01-29 09:57:04 +08:00
|
|
|
#undef WARNING_DISABLED
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2013-05-12 18:21:16 +08:00
|
|
|
exit(ret);
|
2004-06-27 13:08:33 +08:00
|
|
|
}
|
|
|
|
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
/**
|
|
|
|
* Register a window as symbol, and initialize GLX context if wanted.
|
|
|
|
*/
|
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
|
|
|
assert(!ps->reg_win);
|
|
|
|
|
2013-03-01 12:41:16 +08:00
|
|
|
ps->reg_win = XCreateSimpleWindow(ps->dpy, ps->root, 0, 0, 1, 1, 0,
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
None, None);
|
2006-09-07 01:04:47 +08:00
|
|
|
|
2013-01-30 13:41:08 +08:00
|
|
|
if (!ps->reg_win) {
|
|
|
|
printf_errf("(): Failed to create window.");
|
|
|
|
return false;
|
|
|
|
}
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2013-01-31 22:53:44 +08:00
|
|
|
// Unredirect the window if it's redirected, just in case
|
|
|
|
if (ps->redirected)
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_composite_unredirect_window(ps->c, ps->reg_win, XCB_COMPOSITE_REDIRECT_MANUAL);
|
2013-01-31 22:53:44 +08:00
|
|
|
|
2013-11-10 10:13:18 +08:00
|
|
|
{
|
|
|
|
XClassHint *h = XAllocClassHint();
|
|
|
|
if (h) {
|
|
|
|
h->res_name = "compton";
|
|
|
|
h->res_class = "xcompmgr";
|
|
|
|
}
|
|
|
|
Xutf8SetWMProperties(ps->dpy, ps->reg_win, "xcompmgr", "xcompmgr",
|
|
|
|
NULL, 0, NULL, NULL, h);
|
|
|
|
cxfree(h);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set _NET_WM_PID
|
|
|
|
{
|
2018-10-03 20:13:59 +08:00
|
|
|
uint32_t pid = getpid();
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_change_property(ps->c, XCB_PROP_MODE_REPLACE, ps->reg_win,
|
2018-10-03 20:13:59 +08:00
|
|
|
get_atom(ps, "_NET_WM_PID"), XCB_ATOM_CARDINAL, 32, 1, &pid);
|
2013-11-10 10:13:18 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Set COMPTON_VERSION
|
|
|
|
if (!wid_set_text_prop(ps, ps->reg_win, get_atom(ps, "COMPTON_VERSION"), COMPTON_VERSION)) {
|
|
|
|
printf_errf("(): Failed to set COMPTON_VERSION.");
|
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2014-07-13 09:34:38 +08:00
|
|
|
// Acquire X Selection _NET_WM_CM_S?
|
|
|
|
if (!ps->o.no_x_selection) {
|
2013-01-30 13:41:08 +08:00
|
|
|
unsigned len = strlen(REGISTER_PROP) + 2;
|
|
|
|
int s = ps->scr;
|
2015-10-24 18:32:55 +08:00
|
|
|
Atom atom;
|
2013-01-30 13:41:08 +08:00
|
|
|
|
|
|
|
while (s >= 10) {
|
|
|
|
++len;
|
|
|
|
s /= 10;
|
|
|
|
}
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2013-01-30 13:41:08 +08:00
|
|
|
char *buf = malloc(len);
|
|
|
|
snprintf(buf, len, REGISTER_PROP "%d", ps->scr);
|
|
|
|
buf[len - 1] = '\0';
|
2015-10-24 18:32:55 +08:00
|
|
|
atom = get_atom(ps, buf);
|
2018-10-03 20:20:33 +08:00
|
|
|
free(buf);
|
|
|
|
|
|
|
|
xcb_get_selection_owner_reply_t *reply =
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_get_selection_owner_reply(ps->c,
|
|
|
|
xcb_get_selection_owner(ps->c, atom), NULL);
|
2015-10-24 18:32:55 +08:00
|
|
|
|
2018-10-03 20:20:33 +08:00
|
|
|
if (reply && reply->owner != XCB_NONE) {
|
|
|
|
free(reply);
|
2015-10-24 18:32:55 +08:00
|
|
|
fprintf(stderr, "Another composite manager is already running\n");
|
|
|
|
return false;
|
|
|
|
}
|
2018-10-03 20:20:33 +08:00
|
|
|
free(reply);
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_set_selection_owner(ps->c, ps->reg_win, atom, 0);
|
2013-01-30 13:41:08 +08:00
|
|
|
}
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2013-01-30 13:41:08 +08:00
|
|
|
return true;
|
2005-10-07 08:08:02 +08:00
|
|
|
}
|
|
|
|
|
2013-01-11 21:31:02 +08:00
|
|
|
/**
|
|
|
|
* Reopen streams for logging.
|
|
|
|
*/
|
|
|
|
static bool
|
|
|
|
ostream_reopen(session_t *ps, const char *path) {
|
|
|
|
if (!path)
|
|
|
|
path = ps->o.logpath;
|
|
|
|
if (!path)
|
|
|
|
path = "/dev/null";
|
|
|
|
|
|
|
|
bool success = freopen(path, "a", stdout);
|
|
|
|
success = freopen(path, "a", stderr) && success;
|
|
|
|
if (!success)
|
|
|
|
printf_errfq(1, "(%s): freopen() failed.", path);
|
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* Fork program to background and disable all I/O streams.
|
|
|
|
*/
|
2013-11-09 21:38:31 +08:00
|
|
|
static inline bool
|
2013-01-11 21:31:02 +08:00
|
|
|
fork_after(session_t *ps) {
|
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 (getppid() == 1)
|
|
|
|
return true;
|
2012-02-27 12:00:12 +08:00
|
|
|
|
2018-08-22 22:12:29 +08:00
|
|
|
#ifdef CONFIG_OPENGL
|
2013-03-15 23:16:23 +08:00
|
|
|
// GLX context must be released and reattached on fork
|
2014-07-28 12:50:15 +08:00
|
|
|
if (glx_has_context(ps) && !glXMakeCurrent(ps->dpy, None, NULL)) {
|
2013-03-15 23:16:23 +08:00
|
|
|
printf_errf("(): Failed to detach GLx context.");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2012-02-27 12:00:12 +08:00
|
|
|
int pid = fork();
|
|
|
|
|
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 (-1 == pid) {
|
|
|
|
printf_errf("(): fork() failed.");
|
|
|
|
return false;
|
2012-02-27 12:00:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (pid > 0) _exit(0);
|
|
|
|
|
|
|
|
setsid();
|
|
|
|
|
2018-08-22 22:12:29 +08:00
|
|
|
#ifdef CONFIG_OPENGL
|
2014-07-28 12:50:15 +08:00
|
|
|
if (glx_has_context(ps)
|
|
|
|
&& !glXMakeCurrent(ps->dpy, get_tgt_window(ps), ps->psglx->context)) {
|
2013-03-15 23:16:23 +08:00
|
|
|
printf_errf("(): Failed to make GLX context current.");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2012-11-04 19:14:21 +08:00
|
|
|
// Mainly to suppress the _FORTIFY_SOURCE warning
|
2012-11-09 11:35:40 +08:00
|
|
|
bool success = freopen("/dev/null", "r", stdin);
|
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 (!success) {
|
|
|
|
printf_errf("(): freopen() failed.");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-01-11 21:31:02 +08:00
|
|
|
return success;
|
2012-02-27 12:00:12 +08:00
|
|
|
}
|
|
|
|
|
2013-11-09 21:38:31 +08:00
|
|
|
/**
|
|
|
|
* Write PID to a file.
|
|
|
|
*/
|
|
|
|
static inline bool
|
|
|
|
write_pid(session_t *ps) {
|
|
|
|
if (!ps->o.write_pid_path)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
FILE *f = fopen(ps->o.write_pid_path, "w");
|
|
|
|
if (unlikely(!f)) {
|
|
|
|
printf_errf("(): Failed to write PID to \"%s\".", ps->o.write_pid_path);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
fprintf(f, "%ld\n", (long) getpid());
|
|
|
|
fclose(f);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-09-25 10:19:20 +08:00
|
|
|
/**
|
|
|
|
* Process arguments and configuration files.
|
|
|
|
*/
|
|
|
|
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) {
|
2018-08-22 22:26:08 +08:00
|
|
|
static const char *shortopts = "D:I:O:d:r:o:m:l:t:i:e:hscnfFCaSzGb";
|
|
|
|
static const struct option longopts[] = {
|
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
|
|
|
{ "help", no_argument, NULL, 'h' },
|
2012-09-25 10:19:20 +08:00
|
|
|
{ "config", required_argument, NULL, 256 },
|
2013-08-26 22:00:53 +08:00
|
|
|
{ "shadow-radius", required_argument, NULL, 'r' },
|
|
|
|
{ "shadow-opacity", required_argument, NULL, 'o' },
|
|
|
|
{ "shadow-offset-x", required_argument, NULL, 'l' },
|
|
|
|
{ "shadow-offset-y", required_argument, NULL, 't' },
|
|
|
|
{ "fade-in-step", required_argument, NULL, 'I' },
|
|
|
|
{ "fade-out-step", required_argument, NULL, 'O' },
|
2014-06-15 11:51:59 +08:00
|
|
|
{ "fade-delta", required_argument, NULL, 'D' },
|
2013-08-26 22:00:53 +08:00
|
|
|
{ "menu-opacity", required_argument, NULL, 'm' },
|
|
|
|
{ "shadow", no_argument, NULL, 'c' },
|
|
|
|
{ "no-dock-shadow", no_argument, NULL, 'C' },
|
|
|
|
{ "clear-shadow", no_argument, NULL, 'z' },
|
|
|
|
{ "fading", no_argument, NULL, 'f' },
|
|
|
|
{ "inactive-opacity", required_argument, NULL, 'i' },
|
|
|
|
{ "frame-opacity", required_argument, NULL, 'e' },
|
2014-06-15 11:51:59 +08:00
|
|
|
{ "daemon", no_argument, NULL, 'b' },
|
2013-08-26 22:00:53 +08:00
|
|
|
{ "no-dnd-shadow", no_argument, NULL, 'G' },
|
2012-09-25 10:19:20 +08:00
|
|
|
{ "shadow-red", required_argument, NULL, 257 },
|
|
|
|
{ "shadow-green", required_argument, NULL, 258 },
|
|
|
|
{ "shadow-blue", required_argument, NULL, 259 },
|
|
|
|
{ "inactive-opacity-override", no_argument, NULL, 260 },
|
|
|
|
{ "inactive-dim", required_argument, NULL, 261 },
|
|
|
|
{ "mark-wmwin-focused", no_argument, NULL, 262 },
|
|
|
|
{ "shadow-exclude", required_argument, NULL, 263 },
|
2012-09-26 19:48:36 +08:00
|
|
|
{ "mark-ovredir-focused", no_argument, NULL, 264 },
|
2012-09-26 21:40:48 +08:00
|
|
|
{ "no-fading-openclose", no_argument, NULL, 265 },
|
2012-10-01 10:34:40 +08:00
|
|
|
{ "shadow-ignore-shaped", no_argument, NULL, 266 },
|
|
|
|
{ "detect-rounded-corners", no_argument, NULL, 267 },
|
2012-10-03 21:13:34 +08:00
|
|
|
{ "detect-client-opacity", no_argument, NULL, 268 },
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
{ "refresh-rate", required_argument, NULL, 269 },
|
|
|
|
{ "vsync", required_argument, NULL, 270 },
|
2012-10-13 18:46:59 +08:00
|
|
|
{ "alpha-step", required_argument, NULL, 271 },
|
2012-10-23 13:42:20 +08:00
|
|
|
{ "dbe", no_argument, NULL, 272 },
|
2012-10-24 10:09:59 +08:00
|
|
|
{ "paint-on-overlay", no_argument, NULL, 273 },
|
2012-10-26 11:12:28 +08:00
|
|
|
{ "sw-opti", no_argument, NULL, 274 },
|
2012-11-01 10:43:15 +08:00
|
|
|
{ "vsync-aggressive", no_argument, NULL, 275 },
|
2012-11-04 18:11:08 +08:00
|
|
|
{ "use-ewmh-active-win", no_argument, NULL, 276 },
|
2012-11-19 09:46:07 +08:00
|
|
|
{ "respect-prop-shadow", no_argument, NULL, 277 },
|
2012-11-09 21:44:02 +08:00
|
|
|
{ "unredir-if-possible", no_argument, NULL, 278 },
|
2012-11-28 11:44:00 +08:00
|
|
|
{ "focus-exclude", required_argument, NULL, 279 },
|
2012-12-05 12:43:34 +08:00
|
|
|
{ "inactive-dim-fixed", no_argument, NULL, 280 },
|
2012-12-12 12:01:51 +08:00
|
|
|
{ "detect-transient", no_argument, NULL, 281 },
|
|
|
|
{ "detect-client-leader", no_argument, NULL, 282 },
|
2012-12-14 20:32:46 +08:00
|
|
|
{ "blur-background", no_argument, NULL, 283 },
|
|
|
|
{ "blur-background-frame", no_argument, NULL, 284 },
|
2012-12-15 20:07:45 +08:00
|
|
|
{ "blur-background-fixed", no_argument, NULL, 285 },
|
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
|
|
|
{ "dbus", no_argument, NULL, 286 },
|
2013-01-11 21:31:02 +08:00
|
|
|
{ "logpath", required_argument, NULL, 287 },
|
2013-01-12 22:21:35 +08:00
|
|
|
{ "invert-color-include", required_argument, NULL, 288 },
|
2013-03-15 23:16:23 +08:00
|
|
|
{ "opengl", no_argument, NULL, 289 },
|
2013-03-16 22:54:43 +08:00
|
|
|
{ "backend", required_argument, NULL, 290 },
|
2013-03-17 12:14:00 +08:00
|
|
|
{ "glx-no-stencil", no_argument, NULL, 291 },
|
2013-03-19 20:58:55 +08:00
|
|
|
{ "glx-copy-from-front", no_argument, NULL, 292 },
|
|
|
|
{ "benchmark", required_argument, NULL, 293 },
|
|
|
|
{ "benchmark-wid", required_argument, NULL, 294 },
|
2013-03-21 13:05:56 +08:00
|
|
|
{ "glx-use-copysubbuffermesa", no_argument, NULL, 295 },
|
2013-03-23 22:06:41 +08:00
|
|
|
{ "blur-background-exclude", required_argument, NULL, 296 },
|
2013-03-30 11:46:32 +08:00
|
|
|
{ "active-opacity", required_argument, NULL, 297 },
|
2013-04-05 21:05:19 +08:00
|
|
|
{ "glx-no-rebind-pixmap", no_argument, NULL, 298 },
|
2013-04-21 22:30:22 +08:00
|
|
|
{ "glx-swap-method", required_argument, NULL, 299 },
|
|
|
|
{ "fade-exclude", required_argument, NULL, 300 },
|
2013-04-25 22:23:35 +08:00
|
|
|
{ "blur-kern", required_argument, NULL, 301 },
|
2013-04-27 11:43:11 +08:00
|
|
|
{ "resize-damage", required_argument, NULL, 302 },
|
2013-05-08 22:44:36 +08:00
|
|
|
{ "glx-use-gpushader4", no_argument, NULL, 303 },
|
2013-05-21 09:18:41 +08:00
|
|
|
{ "opacity-rule", required_argument, NULL, 304 },
|
2013-06-09 17:06:35 +08:00
|
|
|
{ "shadow-exclude-reg", required_argument, NULL, 305 },
|
2013-06-19 19:36:48 +08:00
|
|
|
{ "paint-exclude", required_argument, NULL, 306 },
|
2013-08-22 21:15:04 +08:00
|
|
|
{ "xinerama-shadow-crop", no_argument, NULL, 307 },
|
2013-09-04 22:00:51 +08:00
|
|
|
{ "unredir-if-possible-exclude", required_argument, NULL, 308 },
|
|
|
|
{ "unredir-if-possible-delay", required_argument, NULL, 309 },
|
2013-11-09 21:38:31 +08:00
|
|
|
{ "write-pid-path", required_argument, NULL, 310 },
|
2013-12-26 20:43:06 +08:00
|
|
|
{ "vsync-use-glfinish", no_argument, NULL, 311 },
|
2014-03-17 23:25:34 +08:00
|
|
|
{ "xrender-sync", no_argument, NULL, 312 },
|
|
|
|
{ "xrender-sync-fence", no_argument, NULL, 313 },
|
2014-04-19 19:41:26 +08:00
|
|
|
{ "show-all-xerrors", no_argument, NULL, 314 },
|
2014-05-16 15:18:17 +08:00
|
|
|
{ "no-fading-destroyed-argb", no_argument, NULL, 315 },
|
|
|
|
{ "force-win-blend", no_argument, NULL, 316 },
|
|
|
|
{ "glx-fshader-win", required_argument, NULL, 317 },
|
2014-07-13 09:34:38 +08:00
|
|
|
{ "version", no_argument, NULL, 318 },
|
|
|
|
{ "no-x-selection", no_argument, NULL, 319 },
|
2014-09-07 16:05:14 +08:00
|
|
|
{ "no-name-pixmap", no_argument, NULL, 320 },
|
2014-07-28 12:50:15 +08:00
|
|
|
{ "reredir-on-root-change", no_argument, NULL, 731 },
|
|
|
|
{ "glx-reinit-on-root-change", no_argument, NULL, 732 },
|
2018-10-22 06:56:53 +08:00
|
|
|
{ "monitor-repaint", no_argument, NULL, 800 },
|
2018-11-04 06:15:38 +08:00
|
|
|
{ "diagnostics", no_argument, NULL, 801 },
|
2012-09-11 23:11:23 +08:00
|
|
|
// Must terminate with a NULL entry
|
|
|
|
{ NULL, 0, NULL, 0 },
|
2012-09-11 21:57:50 +08:00
|
|
|
};
|
|
|
|
|
2018-12-04 21:44:16 +08:00
|
|
|
int o = 0, longopt_idx = -1;
|
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
|
|
|
|
|
|
|
if (first_pass) {
|
|
|
|
// Pre-parse the commandline arguments to check for --config and invalid
|
|
|
|
// switches
|
|
|
|
// Must reset optind to 0 here in case we reread the commandline
|
|
|
|
// arguments
|
|
|
|
optind = 1;
|
|
|
|
while (-1 !=
|
|
|
|
(o = getopt_long(argc, argv, shortopts, longopts, &longopt_idx))) {
|
|
|
|
if (256 == o)
|
|
|
|
ps->o.config_file = mstrcpy(optarg);
|
|
|
|
else if ('d' == o)
|
|
|
|
ps->o.display = mstrcpy(optarg);
|
2014-02-27 22:08:30 +08:00
|
|
|
else if ('S' == o)
|
|
|
|
ps->o.synchronize = true;
|
2014-04-19 19:41:26 +08:00
|
|
|
else if (314 == o)
|
|
|
|
ps->o.show_all_xerrors = true;
|
2014-07-13 09:34:38 +08:00
|
|
|
else if (318 == o) {
|
|
|
|
printf("%s\n", COMPTON_VERSION);
|
|
|
|
exit(0);
|
|
|
|
}
|
2014-09-07 16:05:14 +08:00
|
|
|
else if (320 == o)
|
|
|
|
ps->o.no_name_pixmap = true;
|
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
|
|
|
else if ('?' == o || ':' == o)
|
2013-05-12 18:21:16 +08:00
|
|
|
usage(1);
|
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
|
|
|
}
|
|
|
|
|
2013-03-01 12:41:16 +08:00
|
|
|
// Check for abundant positional arguments
|
|
|
|
if (optind < argc)
|
|
|
|
printf_errfq(1, "(): compton doesn't accept positional arguments.");
|
|
|
|
|
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
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
bool shadow_enable = false, fading_enable = false;
|
2012-09-27 22:30:16 +08:00
|
|
|
char *lc_numeric_old = mstrcpy(setlocale(LC_NUMERIC, NULL));
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
|
2018-12-04 21:44:16 +08:00
|
|
|
win_option_mask_t winopt_mask[NUM_WINTYPES] = {{0}};
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2013-09-14 10:04:38 +08:00
|
|
|
// Enforce LC_NUMERIC locale "C" here to make sure dots are recognized
|
|
|
|
// instead of commas in atof().
|
|
|
|
setlocale(LC_NUMERIC, "C");
|
|
|
|
|
2018-12-04 21:44:16 +08:00
|
|
|
parse_config(ps, &shadow_enable, &fading_enable, winopt_mask);
|
2012-09-25 10:19:20 +08:00
|
|
|
|
|
|
|
// Parse commandline arguments. Range checking will be done later.
|
2012-09-27 22:30:16 +08:00
|
|
|
|
2018-10-24 05:12:42 +08:00
|
|
|
const char *deprecation_message = "has been removed. If you encounter problems "
|
|
|
|
"without this feature, please feel free to open a bug report.";
|
2012-09-25 10:19:20 +08:00
|
|
|
optind = 1;
|
|
|
|
while (-1 !=
|
|
|
|
(o = getopt_long(argc, argv, shortopts, longopts, &longopt_idx))) {
|
2013-09-04 22:00:51 +08:00
|
|
|
long val = 0;
|
2011-11-04 14:33:23 +08:00
|
|
|
switch (o) {
|
2013-04-05 21:05:19 +08:00
|
|
|
#define P_CASEBOOL(idx, option) case idx: ps->o.option = true; break
|
2013-09-04 22:00:51 +08:00
|
|
|
#define P_CASELONG(idx, option) \
|
|
|
|
case idx: \
|
|
|
|
if (!parse_long(optarg, &val)) exit(1); \
|
|
|
|
ps->o.option = val; \
|
|
|
|
break
|
|
|
|
|
2012-09-11 21:57:50 +08:00
|
|
|
// Short options
|
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
|
|
|
case 'h':
|
2013-05-12 18:21:16 +08:00
|
|
|
usage(0);
|
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
|
|
|
break;
|
2011-11-04 16:41:56 +08:00
|
|
|
case 'd':
|
2014-02-27 22:08:30 +08:00
|
|
|
case 'S':
|
2014-04-19 19:41:26 +08:00
|
|
|
case 314:
|
2014-07-13 09:34:38 +08:00
|
|
|
case 318:
|
2014-09-07 16:05:14 +08:00
|
|
|
case 320:
|
2011-11-04 16:41:56 +08:00
|
|
|
break;
|
2013-09-04 22:00:51 +08:00
|
|
|
P_CASELONG('D', fade_delta);
|
2011-11-04 16:41:56 +08:00
|
|
|
case 'I':
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.fade_in_step = normalize_d(atof(optarg)) * OPAQUE;
|
2011-11-04 16:41:56 +08:00
|
|
|
break;
|
|
|
|
case 'O':
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.fade_out_step = normalize_d(atof(optarg)) * OPAQUE;
|
2011-11-04 16:41:56 +08:00
|
|
|
break;
|
2011-11-07 09:29:23 +08:00
|
|
|
case 'c':
|
2012-11-19 09:46:07 +08:00
|
|
|
shadow_enable = true;
|
2011-11-07 09:29:23 +08:00
|
|
|
break;
|
2011-11-04 16:41:56 +08:00
|
|
|
case 'C':
|
2018-12-04 21:44:16 +08:00
|
|
|
winopt_mask[WINTYPE_DOCK].shadow = true;
|
|
|
|
ps->o.wintype_option[WINTYPE_DOCK].shadow = true;
|
2012-09-26 18:54:35 +08:00
|
|
|
break;
|
|
|
|
case 'G':
|
2018-12-04 21:44:16 +08:00
|
|
|
winopt_mask[WINTYPE_DND].shadow = true;
|
|
|
|
ps->o.wintype_option[WINTYPE_DND].shadow = true;
|
2011-11-04 16:41:56 +08:00
|
|
|
break;
|
2018-12-04 21:44:16 +08:00
|
|
|
case 'm':;
|
|
|
|
double tmp;
|
|
|
|
tmp = normalize_d(atof(optarg));
|
|
|
|
winopt_mask[WINTYPE_DROPDOWN_MENU].opacity = true;
|
|
|
|
winopt_mask[WINTYPE_POPUP_MENU].opacity = true;
|
|
|
|
ps->o.wintype_option[WINTYPE_POPUP_MENU].opacity = tmp;
|
|
|
|
ps->o.wintype_option[WINTYPE_DROPDOWN_MENU].opacity = tmp;
|
2011-11-04 16:41:56 +08:00
|
|
|
break;
|
|
|
|
case 'f':
|
|
|
|
case 'F':
|
2012-11-19 09:46:07 +08:00
|
|
|
fading_enable = true;
|
2011-11-04 16:41:56 +08:00
|
|
|
break;
|
2013-09-04 22:00:51 +08:00
|
|
|
P_CASELONG('r', shadow_radius);
|
2011-11-04 16:41:56 +08:00
|
|
|
case 'o':
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.shadow_opacity = atof(optarg);
|
2011-11-04 16:41:56 +08:00
|
|
|
break;
|
2013-09-04 22:00:51 +08:00
|
|
|
P_CASELONG('l', shadow_offset_x);
|
|
|
|
P_CASELONG('t', shadow_offset_y);
|
2011-11-05 01:02:17 +08:00
|
|
|
case 'i':
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.inactive_opacity = (normalize_d(atof(optarg)) * OPAQUE);
|
2011-11-05 01:02:17 +08:00
|
|
|
break;
|
2011-11-06 11:33:50 +08:00
|
|
|
case 'e':
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.frame_opacity = atof(optarg);
|
2011-11-06 10:39:58 +08:00
|
|
|
break;
|
2018-09-24 06:52:55 +08:00
|
|
|
case 'z':
|
2018-11-10 05:03:53 +08:00
|
|
|
printf_errf("(): clear-shadow is removed, shadows are automatically cleared now.\n"
|
|
|
|
"If you want to prevent shadow from been cleared under certain types of windows,\n"
|
|
|
|
"you can use the \"full-shadow\" per window type option.");
|
2018-09-24 06:52:55 +08:00
|
|
|
break;
|
2011-11-04 16:41:56 +08:00
|
|
|
case 'n':
|
|
|
|
case 'a':
|
|
|
|
case 's':
|
2013-01-11 21:31:02 +08:00
|
|
|
printf_errfq(1, "(): -n, -a, and -s have been removed.");
|
2011-11-04 16:41:56 +08:00
|
|
|
break;
|
2013-04-05 21:05:19 +08:00
|
|
|
P_CASEBOOL('b', fork_after_register);
|
2012-09-25 10:19:20 +08:00
|
|
|
// Long options
|
|
|
|
case 256:
|
|
|
|
// --config
|
|
|
|
break;
|
|
|
|
case 257:
|
|
|
|
// --shadow-red
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.shadow_red = atof(optarg);
|
2012-09-25 10:19:20 +08:00
|
|
|
break;
|
|
|
|
case 258:
|
|
|
|
// --shadow-green
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.shadow_green = atof(optarg);
|
2012-09-25 10:19:20 +08:00
|
|
|
break;
|
|
|
|
case 259:
|
|
|
|
// --shadow-blue
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.shadow_blue = atof(optarg);
|
2012-09-25 10:19:20 +08:00
|
|
|
break;
|
2013-04-05 21:05:19 +08:00
|
|
|
P_CASEBOOL(260, inactive_opacity_override);
|
2012-09-25 10:19:20 +08:00
|
|
|
case 261:
|
|
|
|
// --inactive-dim
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.inactive_dim = atof(optarg);
|
2012-09-25 10:19:20 +08:00
|
|
|
break;
|
2013-04-05 21:05:19 +08:00
|
|
|
P_CASEBOOL(262, mark_wmwin_focused);
|
2012-09-25 10:19:20 +08:00
|
|
|
case 263:
|
|
|
|
// --shadow-exclude
|
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(ps, &ps->o.shadow_blacklist, optarg);
|
2012-09-25 10:19:20 +08:00
|
|
|
break;
|
2013-04-05 21:05:19 +08:00
|
|
|
P_CASEBOOL(264, mark_ovredir_focused);
|
|
|
|
P_CASEBOOL(265, no_fading_openclose);
|
|
|
|
P_CASEBOOL(266, shadow_ignore_shaped);
|
|
|
|
P_CASEBOOL(267, detect_rounded_corners);
|
|
|
|
P_CASEBOOL(268, detect_client_opacity);
|
2013-09-04 22:00:51 +08:00
|
|
|
P_CASELONG(269, refresh_rate);
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
case 270:
|
|
|
|
// --vsync
|
2013-01-31 22:53:44 +08:00
|
|
|
if (!parse_vsync(ps, optarg))
|
|
|
|
exit(1);
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
break;
|
2012-10-13 18:46:59 +08:00
|
|
|
case 271:
|
|
|
|
// --alpha-step
|
2018-11-10 20:48:36 +08:00
|
|
|
printf_errf("(): --alpha-step has been removed, compton now tries to make use"
|
|
|
|
" of all alpha values");
|
2012-10-13 18:46:59 +08:00
|
|
|
break;
|
2018-10-22 02:25:13 +08:00
|
|
|
case 272:
|
|
|
|
printf_errf("(): use of --dbe is deprecated");
|
|
|
|
break;
|
2018-11-03 22:04:18 +08:00
|
|
|
case 273:
|
2018-11-10 20:48:36 +08:00
|
|
|
printf_errf("(): --paint-on-overlay has been removed, and is enabled when "
|
|
|
|
"possible");
|
2018-11-03 22:04:18 +08:00
|
|
|
break;
|
2013-04-05 21:05:19 +08:00
|
|
|
P_CASEBOOL(274, sw_opti);
|
|
|
|
P_CASEBOOL(275, vsync_aggressive);
|
|
|
|
P_CASEBOOL(276, use_ewmh_active_win);
|
|
|
|
P_CASEBOOL(277, respect_prop_shadow);
|
|
|
|
P_CASEBOOL(278, unredir_if_possible);
|
2012-11-28 11:44:00 +08:00
|
|
|
case 279:
|
|
|
|
// --focus-exclude
|
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(ps, &ps->o.focus_blacklist, optarg);
|
2012-11-28 11:44:00 +08:00
|
|
|
break;
|
2013-04-05 21:05:19 +08:00
|
|
|
P_CASEBOOL(280, inactive_dim_fixed);
|
|
|
|
P_CASEBOOL(281, detect_transient);
|
|
|
|
P_CASEBOOL(282, detect_client_leader);
|
|
|
|
P_CASEBOOL(283, blur_background);
|
|
|
|
P_CASEBOOL(284, blur_background_frame);
|
|
|
|
P_CASEBOOL(285, blur_background_fixed);
|
|
|
|
P_CASEBOOL(286, dbus);
|
2013-01-11 21:31:02 +08:00
|
|
|
case 287:
|
|
|
|
// --logpath
|
|
|
|
ps->o.logpath = mstrcpy(optarg);
|
|
|
|
break;
|
2013-01-12 22:21:35 +08:00
|
|
|
case 288:
|
|
|
|
// --invert-color-include
|
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(ps, &ps->o.invert_color_list, optarg);
|
2013-01-12 22:21:35 +08:00
|
|
|
break;
|
2013-03-15 23:16:23 +08:00
|
|
|
case 289:
|
|
|
|
// --opengl
|
|
|
|
ps->o.backend = BKEND_GLX;
|
|
|
|
break;
|
2013-03-16 22:54:43 +08:00
|
|
|
case 290:
|
|
|
|
// --backend
|
|
|
|
if (!parse_backend(ps, optarg))
|
|
|
|
exit(1);
|
|
|
|
break;
|
2013-04-05 21:05:19 +08:00
|
|
|
P_CASEBOOL(291, glx_no_stencil);
|
2018-10-01 04:05:32 +08:00
|
|
|
case 292:
|
2018-10-24 05:12:42 +08:00
|
|
|
printf_errf("(): --glx-copy-from-front %s", deprecation_message);
|
2018-10-01 04:05:32 +08:00
|
|
|
break;
|
2013-09-04 22:00:51 +08:00
|
|
|
P_CASELONG(293, benchmark);
|
2013-03-19 20:58:55 +08:00
|
|
|
case 294:
|
|
|
|
// --benchmark-wid
|
|
|
|
ps->o.benchmark_wid = strtol(optarg, NULL, 0);
|
|
|
|
break;
|
2018-10-01 04:05:32 +08:00
|
|
|
case 295:
|
2018-10-24 05:12:42 +08:00
|
|
|
printf_errf("(): --glx-use-copysubbuffermesa %s", deprecation_message);
|
2018-10-01 04:05:32 +08:00
|
|
|
break;
|
2013-03-23 22:06:41 +08:00
|
|
|
case 296:
|
|
|
|
// --blur-background-exclude
|
|
|
|
condlst_add(ps, &ps->o.blur_background_blacklist, optarg);
|
|
|
|
break;
|
2013-03-30 11:46:32 +08:00
|
|
|
case 297:
|
|
|
|
// --active-opacity
|
|
|
|
ps->o.active_opacity = (normalize_d(atof(optarg)) * OPAQUE);
|
|
|
|
break;
|
2013-04-05 21:05:19 +08:00
|
|
|
P_CASEBOOL(298, glx_no_rebind_pixmap);
|
2013-04-21 22:30:22 +08:00
|
|
|
case 299:
|
|
|
|
// --glx-swap-method
|
|
|
|
if (!parse_glx_swap_method(ps, optarg))
|
|
|
|
exit(1);
|
|
|
|
break;
|
|
|
|
case 300:
|
|
|
|
// --fade-exclude
|
|
|
|
condlst_add(ps, &ps->o.fade_blacklist, optarg);
|
|
|
|
break;
|
2013-04-25 22:23:35 +08:00
|
|
|
case 301:
|
|
|
|
// --blur-kern
|
2013-05-20 18:04:40 +08:00
|
|
|
if (!parse_conv_kern_lst(ps, optarg, ps->o.blur_kerns, MAX_BLUR_PASS))
|
2013-04-25 22:23:35 +08:00
|
|
|
exit(1);
|
2013-05-20 18:04:40 +08:00
|
|
|
break;
|
2013-09-04 22:00:51 +08:00
|
|
|
P_CASELONG(302, resize_damage);
|
2013-05-08 22:44:36 +08:00
|
|
|
P_CASEBOOL(303, glx_use_gpushader4);
|
2013-05-21 09:18:41 +08:00
|
|
|
case 304:
|
|
|
|
// --opacity-rule
|
|
|
|
if (!parse_rule_opacity(ps, optarg))
|
|
|
|
exit(1);
|
|
|
|
break;
|
2013-06-09 17:06:35 +08:00
|
|
|
case 305:
|
|
|
|
// --shadow-exclude-reg
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
ps->o.shadow_exclude_reg_str = strdup(optarg);
|
|
|
|
printf_err("--shadow-exclude-reg is deprecated.\n"
|
|
|
|
"You are likely better off using --shadow-exclude anyway");
|
2013-06-09 17:06:35 +08:00
|
|
|
break;
|
2013-06-19 19:36:48 +08:00
|
|
|
case 306:
|
|
|
|
// --paint-exclude
|
|
|
|
condlst_add(ps, &ps->o.paint_blacklist, optarg);
|
|
|
|
break;
|
2013-08-22 21:15:04 +08:00
|
|
|
P_CASEBOOL(307, xinerama_shadow_crop);
|
2013-09-04 22:00:51 +08:00
|
|
|
case 308:
|
|
|
|
// --unredir-if-possible-exclude
|
|
|
|
condlst_add(ps, &ps->o.unredir_if_possible_blacklist, optarg);
|
|
|
|
break;
|
|
|
|
P_CASELONG(309, unredir_if_possible_delay);
|
2013-11-09 21:38:31 +08:00
|
|
|
case 310:
|
|
|
|
// --write-pid-path
|
|
|
|
ps->o.write_pid_path = mstrcpy(optarg);
|
|
|
|
break;
|
2013-12-26 20:43:06 +08:00
|
|
|
P_CASEBOOL(311, vsync_use_glfinish);
|
2018-11-08 22:53:13 +08:00
|
|
|
P_CASEBOOL(312, xrender_sync);
|
|
|
|
P_CASEBOOL(313, xrender_sync_fence);
|
2014-05-16 15:18:17 +08:00
|
|
|
P_CASEBOOL(315, no_fading_destroyed_argb);
|
|
|
|
P_CASEBOOL(316, force_win_blend);
|
|
|
|
case 317:
|
|
|
|
ps->o.glx_fshader_win_str = mstrcpy(optarg);
|
2018-11-12 03:38:29 +08:00
|
|
|
printf_errf("(): --glx-fshader-win is being deprecated, and might be\n"
|
|
|
|
" removed in the future. If you really need this feature, please report\n"
|
|
|
|
"an issue to let us know\n");
|
2014-05-16 15:18:17 +08:00
|
|
|
break;
|
2014-07-13 09:34:38 +08:00
|
|
|
P_CASEBOOL(319, no_x_selection);
|
2014-07-28 12:50:15 +08:00
|
|
|
P_CASEBOOL(731, reredir_on_root_change);
|
|
|
|
P_CASEBOOL(732, glx_reinit_on_root_change);
|
2018-10-22 06:56:53 +08:00
|
|
|
P_CASEBOOL(800, monitor_repaint);
|
2018-11-04 06:15:38 +08:00
|
|
|
case 801:
|
|
|
|
ps->o.print_diagnostics = true;
|
|
|
|
break;
|
2011-11-04 16:41:56 +08:00
|
|
|
default:
|
2013-05-12 18:21:16 +08:00
|
|
|
usage(1);
|
2013-01-11 21:31:02 +08:00
|
|
|
break;
|
2013-04-05 21:05:19 +08:00
|
|
|
#undef P_CASEBOOL
|
2008-02-15 12:38:32 +08:00
|
|
|
}
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2003-11-09 15:08:23 +08:00
|
|
|
|
2012-09-27 22:30:16 +08:00
|
|
|
// Restore LC_NUMERIC
|
|
|
|
setlocale(LC_NUMERIC, lc_numeric_old);
|
|
|
|
free(lc_numeric_old);
|
|
|
|
|
2018-10-22 06:56:53 +08:00
|
|
|
if (ps->o.monitor_repaint && ps->o.backend != BKEND_XRENDER)
|
|
|
|
printf_errf("(): --monitor-repaint has no effect when backend is not xrender");
|
|
|
|
|
2012-09-25 10:19:20 +08:00
|
|
|
// Range checking and option assignments
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.fade_delta = max_i(ps->o.fade_delta, 1);
|
2018-12-09 10:04:00 +08:00
|
|
|
ps->o.shadow_radius = max_i(ps->o.shadow_radius, 0);
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.shadow_red = normalize_d(ps->o.shadow_red);
|
|
|
|
ps->o.shadow_green = normalize_d(ps->o.shadow_green);
|
|
|
|
ps->o.shadow_blue = normalize_d(ps->o.shadow_blue);
|
|
|
|
ps->o.inactive_dim = normalize_d(ps->o.inactive_dim);
|
|
|
|
ps->o.frame_opacity = normalize_d(ps->o.frame_opacity);
|
|
|
|
ps->o.shadow_opacity = normalize_d(ps->o.shadow_opacity);
|
|
|
|
ps->o.refresh_rate = normalize_i_range(ps->o.refresh_rate, 0, 300);
|
2018-11-10 03:56:05 +08:00
|
|
|
|
2018-12-04 21:44:16 +08:00
|
|
|
// Apply default wintype options that are dependent on global options
|
|
|
|
for (int i = 0; i < NUM_WINTYPES; i++) {
|
|
|
|
auto wo = &ps->o.wintype_option[i];
|
|
|
|
auto mask = &winopt_mask[i];
|
|
|
|
if (!mask->shadow) {
|
|
|
|
wo->shadow = shadow_enable;
|
|
|
|
mask->shadow = true;
|
|
|
|
}
|
|
|
|
if (!mask->fade) {
|
|
|
|
wo->fade = fading_enable;
|
|
|
|
mask->fade = true;
|
|
|
|
}
|
2012-02-27 12:00:12 +08:00
|
|
|
}
|
2012-02-27 00:35:17 +08:00
|
|
|
|
2012-12-14 20:32:46 +08:00
|
|
|
// --blur-background-frame implies --blur-background
|
|
|
|
if (ps->o.blur_background_frame)
|
|
|
|
ps->o.blur_background = true;
|
|
|
|
|
2018-11-08 22:53:13 +08:00
|
|
|
if (ps->o.xrender_sync_fence)
|
|
|
|
ps->o.xrender_sync = true;
|
|
|
|
|
2012-09-25 10:19:20 +08:00
|
|
|
// Other variables determined by options
|
|
|
|
|
2012-09-13 11:47:31 +08:00
|
|
|
// Determine whether we need to track focus changes
|
2018-08-12 02:48:37 +08:00
|
|
|
if (ps->o.inactive_opacity != ps->o.active_opacity ||
|
|
|
|
ps->o.inactive_dim) {
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->o.track_focus = true;
|
2012-09-13 13:58:05 +08:00
|
|
|
}
|
2012-09-13 11:47:31 +08:00
|
|
|
|
2012-12-12 12:01:51 +08:00
|
|
|
// Determine whether we track window grouping
|
|
|
|
if (ps->o.detect_transient || ps->o.detect_client_leader) {
|
|
|
|
ps->o.track_leader = true;
|
|
|
|
}
|
|
|
|
|
2013-04-25 22:23:35 +08:00
|
|
|
// Fill default blur kernel
|
2013-05-20 18:04:40 +08:00
|
|
|
if (ps->o.blur_background && !ps->o.blur_kerns[0]) {
|
2013-04-25 22:23:35 +08:00
|
|
|
// Convolution filter parameter (box blur)
|
|
|
|
// gaussian or binomial filters are definitely superior, yet looks
|
|
|
|
// like they aren't supported as of xorg-server-1.13.0
|
2018-09-28 00:14:44 +08:00
|
|
|
static const xcb_render_fixed_t convolution_blur[] = {
|
|
|
|
// Must convert to XFixed with DOUBLE_TO_XFIXED()
|
2013-04-25 22:23:35 +08:00
|
|
|
// Matrix size
|
2018-09-28 00:14:44 +08:00
|
|
|
DOUBLE_TO_XFIXED(3), DOUBLE_TO_XFIXED(3),
|
2013-04-25 22:23:35 +08:00
|
|
|
// Matrix
|
2018-09-28 00:14:44 +08:00
|
|
|
DOUBLE_TO_XFIXED(1), DOUBLE_TO_XFIXED(1), DOUBLE_TO_XFIXED(1),
|
|
|
|
DOUBLE_TO_XFIXED(1), DOUBLE_TO_XFIXED(1), DOUBLE_TO_XFIXED(1),
|
|
|
|
DOUBLE_TO_XFIXED(1), DOUBLE_TO_XFIXED(1), DOUBLE_TO_XFIXED(1),
|
2013-04-25 22:23:35 +08:00
|
|
|
};
|
2013-05-20 18:04:40 +08:00
|
|
|
ps->o.blur_kerns[0] = malloc(sizeof(convolution_blur));
|
|
|
|
if (!ps->o.blur_kerns[0]) {
|
2013-04-25 22:23:35 +08:00
|
|
|
printf_errf("(): Failed to allocate memory for convolution kernel.");
|
|
|
|
exit(1);
|
|
|
|
}
|
2013-05-20 18:04:40 +08:00
|
|
|
memcpy(ps->o.blur_kerns[0], &convolution_blur, sizeof(convolution_blur));
|
2013-04-25 22:23:35 +08:00
|
|
|
}
|
2013-06-09 17:06:35 +08:00
|
|
|
|
|
|
|
rebuild_shadow_exclude_reg(ps);
|
2013-07-30 22:24:11 +08:00
|
|
|
|
|
|
|
if (ps->o.resize_damage < 0)
|
|
|
|
printf_errf("(): Negative --resize-damage does not work correctly.");
|
2012-09-25 10:19:20 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* Fetch all required atoms and save them to a session.
|
|
|
|
*/
|
2012-09-25 10:19:20 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
init_atoms(session_t *ps) {
|
2013-01-09 20:25:01 +08:00
|
|
|
ps->atom_opacity = get_atom(ps, "_NET_WM_WINDOW_OPACITY");
|
|
|
|
ps->atom_frame_extents = get_atom(ps, "_NET_FRAME_EXTENTS");
|
|
|
|
ps->atom_client = get_atom(ps, "WM_STATE");
|
2018-10-03 01:53:28 +08:00
|
|
|
ps->atom_name = XCB_ATOM_WM_NAME;
|
2013-01-09 20:25:01 +08:00
|
|
|
ps->atom_name_ewmh = get_atom(ps, "_NET_WM_NAME");
|
2018-10-03 01:53:28 +08:00
|
|
|
ps->atom_class = XCB_ATOM_WM_CLASS;
|
2013-01-09 20:25:01 +08:00
|
|
|
ps->atom_role = get_atom(ps, "WM_WINDOW_ROLE");
|
2018-10-03 01:53:28 +08:00
|
|
|
ps->atom_transient = XCB_ATOM_WM_TRANSIENT_FOR;
|
2013-01-09 20:25:01 +08:00
|
|
|
ps->atom_client_leader = get_atom(ps, "WM_CLIENT_LEADER");
|
|
|
|
ps->atom_ewmh_active_win = get_atom(ps, "_NET_ACTIVE_WINDOW");
|
|
|
|
ps->atom_compton_shadow = get_atom(ps, "_COMPTON_SHADOW");
|
2012-11-19 09:46:07 +08:00
|
|
|
|
2013-01-09 20:25:01 +08:00
|
|
|
ps->atom_win_type = get_atom(ps, "_NET_WM_WINDOW_TYPE");
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->atoms_wintypes[WINTYPE_UNKNOWN] = 0;
|
2013-01-09 20:25:01 +08:00
|
|
|
ps->atoms_wintypes[WINTYPE_DESKTOP] = get_atom(ps,
|
|
|
|
"_NET_WM_WINDOW_TYPE_DESKTOP");
|
|
|
|
ps->atoms_wintypes[WINTYPE_DOCK] = get_atom(ps,
|
|
|
|
"_NET_WM_WINDOW_TYPE_DOCK");
|
|
|
|
ps->atoms_wintypes[WINTYPE_TOOLBAR] = get_atom(ps,
|
|
|
|
"_NET_WM_WINDOW_TYPE_TOOLBAR");
|
|
|
|
ps->atoms_wintypes[WINTYPE_MENU] = get_atom(ps,
|
|
|
|
"_NET_WM_WINDOW_TYPE_MENU");
|
|
|
|
ps->atoms_wintypes[WINTYPE_UTILITY] = get_atom(ps,
|
|
|
|
"_NET_WM_WINDOW_TYPE_UTILITY");
|
|
|
|
ps->atoms_wintypes[WINTYPE_SPLASH] = get_atom(ps,
|
|
|
|
"_NET_WM_WINDOW_TYPE_SPLASH");
|
|
|
|
ps->atoms_wintypes[WINTYPE_DIALOG] = get_atom(ps,
|
|
|
|
"_NET_WM_WINDOW_TYPE_DIALOG");
|
|
|
|
ps->atoms_wintypes[WINTYPE_NORMAL] = get_atom(ps,
|
|
|
|
"_NET_WM_WINDOW_TYPE_NORMAL");
|
|
|
|
ps->atoms_wintypes[WINTYPE_DROPDOWN_MENU] = get_atom(ps,
|
|
|
|
"_NET_WM_WINDOW_TYPE_DROPDOWN_MENU");
|
|
|
|
ps->atoms_wintypes[WINTYPE_POPUP_MENU] = get_atom(ps,
|
|
|
|
"_NET_WM_WINDOW_TYPE_POPUP_MENU");
|
|
|
|
ps->atoms_wintypes[WINTYPE_TOOLTIP] = get_atom(ps,
|
|
|
|
"_NET_WM_WINDOW_TYPE_TOOLTIP");
|
|
|
|
ps->atoms_wintypes[WINTYPE_NOTIFY] = get_atom(ps,
|
|
|
|
"_NET_WM_WINDOW_TYPE_NOTIFICATION");
|
|
|
|
ps->atoms_wintypes[WINTYPE_COMBO] = get_atom(ps,
|
|
|
|
"_NET_WM_WINDOW_TYPE_COMBO");
|
|
|
|
ps->atoms_wintypes[WINTYPE_DND] = get_atom(ps,
|
|
|
|
"_NET_WM_WINDOW_TYPE_DND");
|
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
|
|
|
/**
|
|
|
|
* Update refresh rate info with X Randr extension.
|
|
|
|
*/
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
update_refresh_rate(session_t *ps) {
|
2018-09-27 23:38:24 +08:00
|
|
|
xcb_randr_get_screen_info_reply_t *randr_info =
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_randr_get_screen_info_reply(ps->c,
|
|
|
|
xcb_randr_get_screen_info(ps->c, ps->root), NULL);
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
|
2018-09-27 23:38:24 +08:00
|
|
|
if (!randr_info)
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
return;
|
2018-09-27 23:38:24 +08:00
|
|
|
ps->refresh_rate = randr_info->rate;
|
|
|
|
free(randr_info);
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->refresh_rate)
|
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
|
|
|
ps->refresh_intv = US_PER_SEC / ps->refresh_rate;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
else
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->refresh_intv = 0;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2012-10-26 11:12:28 +08:00
|
|
|
* Initialize refresh-rated based software optimization.
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
*
|
2012-11-19 09:46:07 +08:00
|
|
|
* @return true for success, false otherwise
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
*/
|
2012-11-19 09:46:07 +08:00
|
|
|
static bool
|
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
|
|
|
// Prepare refresh rate
|
|
|
|
// Check if user provides one
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->refresh_rate = ps->o.refresh_rate;
|
|
|
|
if (ps->refresh_rate)
|
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
|
|
|
ps->refresh_intv = US_PER_SEC / ps->refresh_rate;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
|
|
|
|
// Auto-detect refresh rate otherwise
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!ps->refresh_rate && ps->randr_exists) {
|
|
|
|
update_refresh_rate(ps);
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Turn off vsync_sw if we can't get the refresh rate
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!ps->refresh_rate)
|
|
|
|
return false;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
return true;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
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
|
|
|
* Modify a struct timeval timeout value to render at a fixed pace.
|
2012-10-26 11:12:28 +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
|
|
|
* @param ps current session
|
|
|
|
* @param[in,out] ptv pointer to the timeout
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
*/
|
2018-10-03 03:22:26 +08:00
|
|
|
static double
|
|
|
|
swopti_handle_timeout(session_t *ps) {
|
2018-11-27 00:53:57 +08:00
|
|
|
if (!ps->refresh_intv)
|
|
|
|
return 0;
|
|
|
|
|
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
|
|
|
// Get the microsecond offset of the time when the we reach the timeout
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
// I don't think a 32-bit long could overflow here.
|
2018-10-03 03:22:26 +08:00
|
|
|
long offset = (get_time_timeval().tv_usec - ps->paint_tm_offset) % ps->refresh_intv;
|
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 (offset < 0)
|
|
|
|
offset += ps->refresh_intv;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
|
2012-10-26 11:12:28 +08:00
|
|
|
// If the target time is sufficiently close to a refresh time, don't add
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
// an offset, to avoid certain blocking conditions.
|
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 (offset < SWOPTI_TOLERANCE
|
|
|
|
|| offset > ps->refresh_intv - SWOPTI_TOLERANCE)
|
2018-10-03 03:22:26 +08:00
|
|
|
return 0;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
|
2012-10-26 11:12:28 +08:00
|
|
|
// Add an offset so we wait until the next refresh after timeout
|
2018-10-03 03:22:26 +08:00
|
|
|
return (ps->refresh_intv - offset) / 1e6;
|
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
|
|
|
}
|
|
|
|
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
/**
|
|
|
|
* Initialize DRM VSync.
|
|
|
|
*
|
2012-11-19 09:46:07 +08:00
|
|
|
* @return true for success, false otherwise
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
*/
|
2012-11-19 09:46:07 +08:00
|
|
|
static bool
|
|
|
|
vsync_drm_init(session_t *ps) {
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
#ifdef CONFIG_VSYNC_DRM
|
|
|
|
// Should we always open card0?
|
2013-01-31 22:53:44 +08:00
|
|
|
if (ps->drm_fd < 0 && (ps->drm_fd = open("/dev/dri/card0", O_RDWR)) < 0) {
|
2013-01-30 13:41:08 +08:00
|
|
|
printf_errf("(): Failed to open device.");
|
2012-11-19 09:46:07 +08:00
|
|
|
return false;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (vsync_drm_wait(ps))
|
|
|
|
return false;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
return true;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
#else
|
2013-01-30 13:41:08 +08:00
|
|
|
printf_errf("(): Program not compiled with DRM VSync support.");
|
2012-11-19 09:46:07 +08:00
|
|
|
return false;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef CONFIG_VSYNC_DRM
|
|
|
|
/**
|
|
|
|
* Wait for next VSync, DRM method.
|
|
|
|
*
|
|
|
|
* Stolen from: https://github.com/MythTV/mythtv/blob/master/mythtv/libs/libmythtv/vsync.cpp
|
|
|
|
*/
|
|
|
|
static int
|
2012-11-19 09:46:07 +08:00
|
|
|
vsync_drm_wait(session_t *ps) {
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
int ret = -1;
|
|
|
|
drm_wait_vblank_t vbl;
|
|
|
|
|
|
|
|
vbl.request.type = _DRM_VBLANK_RELATIVE,
|
|
|
|
vbl.request.sequence = 1;
|
|
|
|
|
|
|
|
do {
|
2012-11-19 09:46:07 +08:00
|
|
|
ret = ioctl(ps->drm_fd, DRM_IOCTL_WAIT_VBLANK, &vbl);
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
vbl.request.type &= ~_DRM_VBLANK_RELATIVE;
|
|
|
|
} while (ret && errno == EINTR);
|
|
|
|
|
|
|
|
if (ret)
|
|
|
|
fprintf(stderr, "vsync_drm_wait(): VBlank ioctl did not work, "
|
|
|
|
"unimplemented in this drmver?\n");
|
|
|
|
|
|
|
|
return ret;
|
2012-11-19 09:46:07 +08:00
|
|
|
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Initialize OpenGL VSync.
|
|
|
|
*
|
|
|
|
* Stolen from: http://git.tuxfamily.org/?p=ccm/cairocompmgr.git;a=commitdiff;h=efa4ceb97da501e8630ca7f12c99b1dce853c73e
|
|
|
|
* Possible original source: http://www.inb.uni-luebeck.de/~boehme/xvideo_sync.html
|
|
|
|
*
|
2012-11-19 09:46:07 +08:00
|
|
|
* @return true for success, false otherwise
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
*/
|
2012-11-19 09:46:07 +08:00
|
|
|
static bool
|
|
|
|
vsync_opengl_init(session_t *ps) {
|
2018-08-22 22:12:29 +08:00
|
|
|
#ifdef CONFIG_OPENGL
|
2013-01-31 22:53:44 +08:00
|
|
|
if (!ensure_glx_context(ps))
|
|
|
|
return false;
|
|
|
|
|
2018-12-09 02:15:19 +08:00
|
|
|
if (!glx_hasglxext(ps, "GLX_SGI_video_sync")) {
|
|
|
|
printf_errf("(): Your driver doesn't support SGI_video_sync, giving up.");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
// Get video sync functions
|
2014-07-28 12:50:15 +08:00
|
|
|
if (!ps->psglx->glXGetVideoSyncSGI)
|
|
|
|
ps->psglx->glXGetVideoSyncSGI = (f_GetVideoSync)
|
2013-03-01 12:41:16 +08:00
|
|
|
glXGetProcAddress((const GLubyte *) "glXGetVideoSyncSGI");
|
2014-07-28 12:50:15 +08:00
|
|
|
if (!ps->psglx->glXWaitVideoSyncSGI)
|
|
|
|
ps->psglx->glXWaitVideoSyncSGI = (f_WaitVideoSync)
|
2013-03-01 12:41:16 +08:00
|
|
|
glXGetProcAddress((const GLubyte *) "glXWaitVideoSyncSGI");
|
2014-07-28 12:50:15 +08:00
|
|
|
if (!ps->psglx->glXWaitVideoSyncSGI || !ps->psglx->glXGetVideoSyncSGI) {
|
2013-01-30 13:41:08 +08:00
|
|
|
printf_errf("(): Failed to get glXWait/GetVideoSyncSGI function.");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
#else
|
2013-01-31 22:53:44 +08:00
|
|
|
printf_errf("(): Program not compiled with OpenGL VSync support.");
|
2013-01-30 13:41:08 +08:00
|
|
|
return false;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool
|
|
|
|
vsync_opengl_oml_init(session_t *ps) {
|
2018-08-22 22:12:29 +08:00
|
|
|
#ifdef CONFIG_OPENGL
|
2013-01-31 22:53:44 +08:00
|
|
|
if (!ensure_glx_context(ps))
|
|
|
|
return false;
|
|
|
|
|
2018-12-09 02:15:19 +08:00
|
|
|
if (!glx_hasglxext(ps, "GLX_OML_sync_control")) {
|
|
|
|
printf_errf("(): Your driver doesn't support OML_sync_control, giving up.");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-01-30 13:41:08 +08:00
|
|
|
// Get video sync functions
|
2014-07-28 12:50:15 +08:00
|
|
|
if (!ps->psglx->glXGetSyncValuesOML)
|
|
|
|
ps->psglx->glXGetSyncValuesOML = (f_GetSyncValuesOML)
|
2013-01-31 22:53:44 +08:00
|
|
|
glXGetProcAddress ((const GLubyte *) "glXGetSyncValuesOML");
|
2014-07-28 12:50:15 +08:00
|
|
|
if (!ps->psglx->glXWaitForMscOML)
|
|
|
|
ps->psglx->glXWaitForMscOML = (f_WaitForMscOML)
|
2013-01-31 22:53:44 +08:00
|
|
|
glXGetProcAddress ((const GLubyte *) "glXWaitForMscOML");
|
2014-07-28 12:50:15 +08:00
|
|
|
if (!ps->psglx->glXGetSyncValuesOML || !ps->psglx->glXWaitForMscOML) {
|
2013-01-30 13:41:08 +08:00
|
|
|
printf_errf("(): Failed to get OML_sync_control functions.");
|
2012-11-19 09:46:07 +08:00
|
|
|
return false;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
}
|
2012-11-19 09:46:07 +08:00
|
|
|
|
|
|
|
return true;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
#else
|
2013-01-31 22:53:44 +08:00
|
|
|
printf_errf("(): Program not compiled with OpenGL VSync support.");
|
2012-11-19 09:46:07 +08:00
|
|
|
return false;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2013-03-15 23:16:23 +08:00
|
|
|
static bool
|
2018-12-15 01:21:05 +08:00
|
|
|
vsync_opengl_swc_swap_interval(session_t *ps, unsigned int interval) {
|
2013-03-15 23:16:23 +08:00
|
|
|
if (!ensure_glx_context(ps))
|
|
|
|
return false;
|
|
|
|
|
2018-12-15 01:21:05 +08:00
|
|
|
if (!ps->psglx->glXSwapIntervalProc && !ps->psglx->glXSwapIntervalMESAProc) {
|
|
|
|
if (glx_hasglxext(ps, "GLX_MESA_swap_control")) {
|
|
|
|
ps->psglx->glXSwapIntervalMESAProc = (f_SwapIntervalMESA)
|
|
|
|
glXGetProcAddress ((const GLubyte *) "glXSwapIntervalMESA");
|
|
|
|
} else if (glx_hasglxext(ps, "GLX_SGI_swap_control")) {
|
|
|
|
ps->psglx->glXSwapIntervalProc = (f_SwapIntervalSGI)
|
|
|
|
glXGetProcAddress ((const GLubyte *) "glXSwapIntervalSGI");
|
|
|
|
} else {
|
|
|
|
printf_errf("(): Your driver doesn't support SGI_swap_control nor MESA_swap_control, giving up.");
|
|
|
|
return false;
|
|
|
|
}
|
2013-03-15 23:16:23 +08:00
|
|
|
}
|
|
|
|
|
2018-12-15 01:21:05 +08:00
|
|
|
if (ps->psglx->glXSwapIntervalMESAProc)
|
|
|
|
ps->psglx->glXSwapIntervalMESAProc(interval);
|
|
|
|
else if (ps->psglx->glXSwapIntervalProc)
|
|
|
|
ps->psglx->glXSwapIntervalProc(interval);
|
|
|
|
else
|
2013-03-15 23:16:23 +08:00
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-03-23 22:06:41 +08:00
|
|
|
static bool
|
2018-12-15 01:21:05 +08:00
|
|
|
vsync_opengl_swc_init(session_t *ps) {
|
2018-08-22 22:12:29 +08:00
|
|
|
#ifdef CONFIG_OPENGL
|
2013-12-10 22:06:02 +08:00
|
|
|
if (!bkend_use_glx(ps)) {
|
2018-12-15 01:21:05 +08:00
|
|
|
printf_errf("(): I'm afraid OpenGL swap control wouldn't help if you are "
|
2013-03-23 22:06:41 +08:00
|
|
|
"not using GLX backend. You could try, nonetheless.");
|
|
|
|
}
|
|
|
|
|
2018-12-15 01:21:05 +08:00
|
|
|
if (!vsync_opengl_swc_swap_interval(ps, 1)) {
|
|
|
|
printf_errf("(): Failed to load a swap control extension.");
|
2013-03-23 22:06:41 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
#else
|
|
|
|
printf_errf("(): Program not compiled with OpenGL VSync support.");
|
|
|
|
return false;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2018-12-15 01:21:05 +08:00
|
|
|
static bool
|
|
|
|
vsync_opengl_mswc_init(session_t *ps) {
|
|
|
|
printf_errf("(): opengl-mswc is deprecated, please use opengl-swc instead.");
|
|
|
|
return vsync_opengl_swc_init(ps);
|
|
|
|
}
|
|
|
|
|
2018-08-22 22:12:29 +08:00
|
|
|
#ifdef CONFIG_OPENGL
|
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
|
|
|
/**
|
|
|
|
* Wait for next VSync, OpenGL method.
|
|
|
|
*/
|
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
|
|
|
unsigned vblank_count = 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
|
|
|
|
2014-07-28 12:50:15 +08:00
|
|
|
ps->psglx->glXGetVideoSyncSGI(&vblank_count);
|
|
|
|
ps->psglx->glXWaitVideoSyncSGI(2, (vblank_count + 1) % 2, &vblank_count);
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
// I see some code calling glXSwapIntervalSGI(1) afterwards, is it required?
|
2013-01-30 13:41:08 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Wait for next VSync, OpenGL OML method.
|
|
|
|
*
|
|
|
|
* https://mail.gnome.org/archives/clutter-list/2012-November/msg00031.html
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
vsync_opengl_oml_wait(session_t *ps) {
|
|
|
|
int64_t ust = 0, msc = 0, sbc = 0;
|
|
|
|
|
2014-07-28 12:50:15 +08:00
|
|
|
ps->psglx->glXGetSyncValuesOML(ps->dpy, ps->reg_win, &ust, &msc, &sbc);
|
|
|
|
ps->psglx->glXWaitForMscOML(ps->dpy, ps->reg_win, 0, 2, (msc + 1) % 2,
|
2013-01-30 13:41:08 +08:00
|
|
|
&ust, &msc, &sbc);
|
|
|
|
|
|
|
|
return 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
|
|
|
}
|
2013-05-20 18:04:40 +08:00
|
|
|
|
|
|
|
static void
|
|
|
|
vsync_opengl_swc_deinit(session_t *ps) {
|
2018-12-15 01:21:05 +08:00
|
|
|
vsync_opengl_swc_swap_interval(ps, 0);
|
2013-05-20 18:04:40 +08:00
|
|
|
}
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
#endif
|
|
|
|
|
2013-01-31 22:53:44 +08:00
|
|
|
/**
|
|
|
|
* Initialize current VSync method.
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
vsync_init(session_t *ps) {
|
2018-12-15 01:22:45 +08:00
|
|
|
// Mesa turns on swap control by default, undo that
|
|
|
|
vsync_opengl_swc_swap_interval(ps, 0);
|
|
|
|
|
2013-01-31 22:53:44 +08:00
|
|
|
if (ps->o.vsync && VSYNC_FUNCS_INIT[ps->o.vsync]
|
|
|
|
&& !VSYNC_FUNCS_INIT[ps->o.vsync](ps)) {
|
|
|
|
ps->o.vsync = VSYNC_NONE;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
/**
|
2012-10-26 11:12:28 +08:00
|
|
|
* Wait for next VSync.
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
*/
|
2012-10-26 11:12:28 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
vsync_wait(session_t *ps) {
|
2013-01-30 13:41:08 +08:00
|
|
|
if (!ps->o.vsync)
|
2012-10-26 11:12:28 +08:00
|
|
|
return;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
|
2013-01-30 13:41:08 +08:00
|
|
|
if (VSYNC_FUNCS_WAIT[ps->o.vsync])
|
|
|
|
VSYNC_FUNCS_WAIT[ps->o.vsync](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-05-20 18:04:40 +08:00
|
|
|
/**
|
|
|
|
* Deinitialize current VSync method.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
vsync_deinit(session_t *ps) {
|
|
|
|
if (ps->o.vsync && VSYNC_FUNCS_DEINIT[ps->o.vsync])
|
|
|
|
VSYNC_FUNCS_DEINIT[ps->o.vsync](ps);
|
|
|
|
}
|
|
|
|
|
2012-10-13 18:46:59 +08:00
|
|
|
/**
|
|
|
|
* Pregenerate alpha pictures.
|
|
|
|
*/
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
init_alpha_picts(session_t *ps) {
|
2018-11-10 20:48:36 +08:00
|
|
|
ps->alpha_picts = malloc(sizeof(xcb_render_picture_t) * (MAX_ALPHA+1));
|
2012-10-13 18:46:59 +08:00
|
|
|
|
2018-11-10 20:48:36 +08:00
|
|
|
for (int i = 0; i <= MAX_ALPHA; ++i) {
|
|
|
|
double o = (double) i / MAX_ALPHA;
|
|
|
|
ps->alpha_picts[i] = solid_picture(ps, false, o, 0, 0, 0);
|
|
|
|
assert(ps->alpha_picts[i] != None);
|
2012-10-13 18:46:59 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-10-24 10:09:59 +08:00
|
|
|
/**
|
|
|
|
* Initialize X composite overlay window.
|
|
|
|
*/
|
2014-07-28 12:50:15 +08:00
|
|
|
static bool
|
2012-11-19 09:46:07 +08:00
|
|
|
init_overlay(session_t *ps) {
|
2018-09-29 00:44:51 +08:00
|
|
|
xcb_composite_get_overlay_window_reply_t *reply =
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_composite_get_overlay_window_reply(ps->c,
|
|
|
|
xcb_composite_get_overlay_window(ps->c, ps->root), NULL);
|
2018-09-29 00:44:51 +08:00
|
|
|
if (reply) {
|
|
|
|
ps->overlay = reply->overlay_win;
|
|
|
|
free(reply);
|
|
|
|
} else {
|
|
|
|
ps->overlay = XCB_NONE;
|
|
|
|
}
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->overlay) {
|
2012-10-24 10:09:59 +08:00
|
|
|
// Set window region of the overlay window, code stolen from
|
|
|
|
// compiz-0.8.8
|
2018-09-30 22:39:14 +08:00
|
|
|
xcb_generic_error_t *e;
|
2018-10-03 21:27:48 +08:00
|
|
|
e = XCB_SYNCED_VOID(xcb_shape_mask, ps->c, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING,
|
2018-09-30 22:39:14 +08:00
|
|
|
ps->overlay, 0, 0, 0);
|
|
|
|
if (e) {
|
|
|
|
printf_errf("(): failed to set the bounding shape of overlay, giving up.");
|
|
|
|
exit(1);
|
|
|
|
}
|
2018-10-03 21:27:48 +08:00
|
|
|
e = XCB_SYNCED_VOID(xcb_shape_rectangles, ps->c, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT,
|
2018-09-30 22:39:14 +08:00
|
|
|
XCB_CLIP_ORDERING_UNSORTED, ps->overlay, 0, 0, 0, NULL);
|
|
|
|
if (e) {
|
|
|
|
printf_errf("(): failed to set the input shape of overlay, giving up.");
|
|
|
|
exit(1);
|
|
|
|
}
|
2012-10-24 10:09:59 +08:00
|
|
|
|
2012-10-29 22:00:11 +08:00
|
|
|
// Listen to Expose events on the overlay
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_change_window_attributes(ps->c, ps->overlay, XCB_CW_EVENT_MASK,
|
2018-10-03 20:34:24 +08:00
|
|
|
(const uint32_t[]) { XCB_EVENT_MASK_EXPOSURE });
|
2012-10-29 22:00:11 +08:00
|
|
|
|
2012-10-24 10:09:59 +08:00
|
|
|
// Retrieve DamageNotify on root window if we are painting on an
|
|
|
|
// overlay
|
2012-11-19 09:46:07 +08:00
|
|
|
// root_damage = XDamageCreate(ps->dpy, root, XDamageReportNonEmpty);
|
2013-09-12 21:23:20 +08:00
|
|
|
|
|
|
|
// Unmap overlay, firstly. But this typically does not work because
|
|
|
|
// the window isn't created yet.
|
2018-10-03 19:51:00 +08:00
|
|
|
// xcb_unmap_window(c, ps->overlay);
|
2013-09-12 21:23:20 +08:00
|
|
|
// XFlush(ps->dpy);
|
2012-10-24 10:09:59 +08:00
|
|
|
}
|
2018-11-03 22:04:18 +08:00
|
|
|
else
|
2012-10-24 10:09:59 +08:00
|
|
|
fprintf(stderr, "Cannot get X Composite overlay window. Falling "
|
|
|
|
"back to painting on root window.\n");
|
2014-07-28 12:50:15 +08:00
|
|
|
#ifdef DEBUG_REDIR
|
|
|
|
printf_dbgf("(): overlay = %#010lx\n", ps->overlay);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return ps->overlay;
|
2012-10-24 10:09:59 +08:00
|
|
|
}
|
|
|
|
|
2012-12-14 20:32:46 +08:00
|
|
|
/**
|
2013-03-15 23:16:23 +08:00
|
|
|
* Query needed X Render / OpenGL filters to check for their existence.
|
2012-12-14 20:32:46 +08:00
|
|
|
*/
|
2013-03-15 23:16:23 +08:00
|
|
|
static bool
|
2012-12-14 20:32:46 +08:00
|
|
|
init_filters(session_t *ps) {
|
2013-03-15 23:16:23 +08:00
|
|
|
// Blur filter
|
2012-12-14 20:32:46 +08:00
|
|
|
if (ps->o.blur_background || ps->o.blur_background_frame) {
|
2013-03-15 23:16:23 +08:00
|
|
|
switch (ps->o.backend) {
|
|
|
|
case BKEND_XRENDER:
|
2013-12-24 07:46:48 +08:00
|
|
|
case BKEND_XR_GLX_HYBRID:
|
2013-03-15 23:16:23 +08:00
|
|
|
{
|
|
|
|
// Query filters
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_render_query_filters_reply_t *pf = xcb_render_query_filters_reply(ps->c,
|
|
|
|
xcb_render_query_filters(ps->c, get_tgt_window(ps)), NULL);
|
2013-03-15 23:16:23 +08:00
|
|
|
if (pf) {
|
2018-09-28 00:14:44 +08:00
|
|
|
xcb_str_iterator_t iter = xcb_render_query_filters_filters_iterator(pf);
|
|
|
|
for (; iter.rem; xcb_str_next(&iter)) {
|
2013-03-15 23:16:23 +08:00
|
|
|
// Convolution filter
|
2018-09-28 16:45:16 +08:00
|
|
|
if (strlen(XRFILTER_CONVOLUTION) == xcb_str_name_length(iter.data)
|
|
|
|
&& !memcmp(XRFILTER_CONVOLUTION, xcb_str_name(iter.data), strlen(XRFILTER_CONVOLUTION)))
|
2013-03-15 23:16:23 +08:00
|
|
|
ps->xrfilter_convolution_exists = true;
|
|
|
|
}
|
2018-09-28 00:14:44 +08:00
|
|
|
free(pf);
|
2013-03-15 23:16:23 +08:00
|
|
|
}
|
2012-12-14 20:32:46 +08:00
|
|
|
|
2013-03-15 23:16:23 +08:00
|
|
|
// Turn features off if any required filter is not present
|
|
|
|
if (!ps->xrfilter_convolution_exists) {
|
|
|
|
printf_errf("(): X Render convolution filter unsupported by your X server. Background blur is not possible.");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2018-08-22 22:12:29 +08:00
|
|
|
#ifdef CONFIG_OPENGL
|
2013-03-15 23:16:23 +08:00
|
|
|
case BKEND_GLX:
|
2018-08-14 17:51:01 +08:00
|
|
|
return glx_init_blur(ps);
|
2013-03-16 22:54:43 +08:00
|
|
|
#endif
|
2018-05-17 19:50:22 +08:00
|
|
|
default:
|
|
|
|
assert(false);
|
2012-12-14 20:32:46 +08:00
|
|
|
}
|
|
|
|
}
|
2013-03-15 23:16:23 +08:00
|
|
|
|
|
|
|
return true;
|
2012-12-14 20:32:46 +08:00
|
|
|
}
|
|
|
|
|
2012-11-09 21:44:02 +08:00
|
|
|
/**
|
|
|
|
* Redirect all windows.
|
|
|
|
*/
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
redir_start(session_t *ps) {
|
|
|
|
if (!ps->redirected) {
|
2012-11-09 21:44:02 +08:00
|
|
|
#ifdef DEBUG_REDIR
|
2013-09-04 22:00:51 +08:00
|
|
|
print_timestamp(ps);
|
|
|
|
printf_dbgf("(): Screen redirected.\n");
|
2012-11-09 21:44:02 +08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
// Map overlay window. Done firstly according to this:
|
|
|
|
// https://bugzilla.gnome.org/show_bug.cgi?id=597014
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->overlay)
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_map_window(ps->c, ps->overlay);
|
2012-11-09 21:44:02 +08:00
|
|
|
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_composite_redirect_subwindows(ps->c, ps->root, XCB_COMPOSITE_REDIRECT_MANUAL);
|
2012-11-09 21:44:02 +08:00
|
|
|
|
2013-03-01 12:41:16 +08:00
|
|
|
/*
|
|
|
|
// Unredirect GL context window as this may have an effect on VSync:
|
2013-01-30 13:41:08 +08:00
|
|
|
// < http://dri.freedesktop.org/wiki/CompositeSwap >
|
2018-09-29 16:41:14 +08:00
|
|
|
xcb_composite_unredirect_window(c, ps->reg_win, XCB_COMPOSITE_REDIRECT_MANUAL);
|
2013-03-01 12:41:16 +08:00
|
|
|
if (ps->o.paint_on_overlay && ps->overlay) {
|
2018-09-29 00:41:24 +08:00
|
|
|
xcb_composite_unredirect_window(c, ps->overlay,
|
2018-09-29 16:41:14 +08:00
|
|
|
XCB_COMPOSITE_REDIRECT_MANUAL);
|
2013-03-01 12:41:16 +08:00
|
|
|
} */
|
2013-01-30 13:41:08 +08:00
|
|
|
|
2012-11-09 21:44:02 +08:00
|
|
|
// Must call XSync() here
|
2018-10-03 21:27:48 +08:00
|
|
|
x_sync(ps->c);
|
2012-11-09 21:44:02 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->redirected = true;
|
2013-09-04 22:00:51 +08:00
|
|
|
|
|
|
|
// Repaint the whole screen
|
|
|
|
force_repaint(ps);
|
2012-11-09 21:44:02 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Unredirect all windows.
|
|
|
|
*/
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
redir_stop(session_t *ps) {
|
|
|
|
if (ps->redirected) {
|
2012-11-09 21:44:02 +08:00
|
|
|
#ifdef DEBUG_REDIR
|
2013-09-04 22:00:51 +08:00
|
|
|
print_timestamp(ps);
|
|
|
|
printf_dbgf("(): Screen unredirected.\n");
|
2012-11-09 21:44:02 +08:00
|
|
|
#endif
|
|
|
|
// Destroy all Pictures as they expire once windows are unredirected
|
|
|
|
// If we don't destroy them here, looks like the resources are just
|
|
|
|
// kept inaccessible somehow
|
2018-11-08 22:53:13 +08:00
|
|
|
for (win *w = ps->list; w; w = w->next) {
|
2018-11-04 06:38:18 +08:00
|
|
|
free_paint(ps, &w->paint);
|
2018-11-08 22:53:13 +08:00
|
|
|
free_fence(ps, &w->fence);
|
|
|
|
}
|
2012-11-09 21:44:02 +08:00
|
|
|
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_composite_unredirect_subwindows(ps->c, ps->root, XCB_COMPOSITE_REDIRECT_MANUAL);
|
2012-11-09 21:44:02 +08:00
|
|
|
// Unmap overlay window
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->overlay)
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_unmap_window(ps->c, ps->overlay);
|
2012-11-09 21:44:02 +08:00
|
|
|
|
|
|
|
// Must call XSync() here
|
2018-10-03 21:27:48 +08:00
|
|
|
x_sync(ps->c);
|
2012-11-09 21:44:02 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->redirected = false;
|
2012-11-09 21:44:02 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-03 03:22:26 +08:00
|
|
|
// Handle queued events before we go to sleep
|
|
|
|
static void
|
|
|
|
handle_queued_x_events(EV_P_ ev_prepare *w, int revents) {
|
2018-11-27 08:32:08 +08:00
|
|
|
session_t *ps = session_ptr(w, event_check);
|
2018-10-03 03:22:26 +08:00
|
|
|
xcb_generic_event_t *ev;
|
2018-10-03 21:27:48 +08:00
|
|
|
while ((ev = xcb_poll_for_queued_event(ps->c))) {
|
2018-10-03 03:22:26 +08:00
|
|
|
ev_handle(ps, ev);
|
|
|
|
free(ev);
|
|
|
|
};
|
|
|
|
XFlush(ps->dpy);
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_flush(ps->c);
|
2018-10-04 15:36:48 +08:00
|
|
|
|
|
|
|
int err = xcb_connection_has_error(ps->c);
|
|
|
|
if (err) {
|
|
|
|
printf_errfq(1, "(): X11 server connection broke (error %d)", err);
|
|
|
|
}
|
2018-10-03 03:22:26 +08:00
|
|
|
}
|
|
|
|
|
2013-09-04 22:00:51 +08:00
|
|
|
/**
|
|
|
|
* Unredirection timeout callback.
|
|
|
|
*/
|
2018-10-03 03:22:26 +08:00
|
|
|
static void
|
|
|
|
tmout_unredir_callback(EV_P_ ev_timer *w, int revents) {
|
2018-11-27 08:32:08 +08:00
|
|
|
session_t *ps = session_ptr(w, unredir_timer);
|
|
|
|
ps->tmout_unredir_hit = true;
|
|
|
|
queue_redraw(ps);
|
2013-09-04 22:00:51 +08:00
|
|
|
}
|
|
|
|
|
2018-10-03 03:22:26 +08:00
|
|
|
static void
|
|
|
|
fade_timer_callback(EV_P_ ev_timer *w, int revents) {
|
2018-11-27 08:32:08 +08:00
|
|
|
session_t *ps = session_ptr(w, fade_timer);
|
|
|
|
queue_redraw(ps);
|
2018-10-03 03:22:26 +08:00
|
|
|
}
|
2013-01-11 21:31:02 +08:00
|
|
|
|
2018-10-03 03:22:26 +08:00
|
|
|
static void
|
|
|
|
_draw_callback(EV_P_ session_t *ps, int revents) {
|
|
|
|
if (ps->o.benchmark) {
|
|
|
|
if (ps->o.benchmark_wid) {
|
|
|
|
win *wi = find_win(ps, ps->o.benchmark_wid);
|
|
|
|
if (!wi) {
|
|
|
|
printf_errf("(): Couldn't find specified benchmark window.");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
add_damage_from_win(ps, wi);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
force_repaint(ps);
|
|
|
|
}
|
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
|
|
|
}
|
|
|
|
|
2018-10-03 03:22:26 +08:00
|
|
|
ps->fade_running = false;
|
|
|
|
win *t = paint_preprocess(ps, ps->list);
|
|
|
|
ps->tmout_unredir_hit = false;
|
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
|
|
|
|
2018-10-03 03:22:26 +08:00
|
|
|
// Start/stop fade timer depends on whether window are fading
|
2018-11-27 08:32:08 +08:00
|
|
|
if (!ps->fade_running && ev_is_active(&ps->fade_timer))
|
|
|
|
ev_timer_stop(ps->loop, &ps->fade_timer);
|
|
|
|
else if (ps->fade_running && !ev_is_active(&ps->fade_timer)) {
|
|
|
|
ev_timer_set(&ps->fade_timer, fade_timeout(ps), 0);
|
|
|
|
ev_timer_start(ps->loop, &ps->fade_timer);
|
2018-10-03 03:22:26 +08:00
|
|
|
}
|
2013-01-11 21:31:02 +08:00
|
|
|
|
2018-10-03 03:22:26 +08:00
|
|
|
// If the screen is unredirected, free all_damage to stop painting
|
|
|
|
if (!ps->redirected || ps->o.stoppaint_force == ON)
|
|
|
|
pixman_region32_clear(&ps->all_damage);
|
2013-01-11 21:31:02 +08:00
|
|
|
|
2018-10-03 03:22:26 +08:00
|
|
|
if (pixman_region32_not_empty(&ps->all_damage)) {
|
|
|
|
region_t all_damage_orig, *region_real = NULL;
|
|
|
|
pixman_region32_init(&all_damage_orig);
|
2013-01-11 21:31:02 +08:00
|
|
|
|
2018-10-03 03:22:26 +08:00
|
|
|
// keep a copy of non-resized all_damage for region_real
|
|
|
|
if (ps->o.resize_damage > 0) {
|
|
|
|
copy_region(&all_damage_orig, &ps->all_damage);
|
|
|
|
resize_region(ps, &ps->all_damage, ps->o.resize_damage);
|
|
|
|
region_real = &all_damage_orig;
|
2013-01-11 21:31:02 +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
|
|
|
|
2018-10-03 03:22:26 +08:00
|
|
|
static int paint = 0;
|
|
|
|
paint_all(ps, &ps->all_damage, region_real, t);
|
2013-01-11 21:31:02 +08:00
|
|
|
|
2018-10-03 03:22:26 +08:00
|
|
|
pixman_region32_clear(&ps->all_damage);
|
|
|
|
pixman_region32_fini(&all_damage_orig);
|
|
|
|
|
|
|
|
paint++;
|
|
|
|
if (ps->o.benchmark && paint >= ps->o.benchmark)
|
|
|
|
exit(0);
|
2013-01-11 21:31:02 +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
|
|
|
|
2018-10-03 03:22:26 +08:00
|
|
|
if (!ps->fade_running)
|
|
|
|
ps->fade_time = 0L;
|
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
|
|
|
|
2018-10-03 03:22:26 +08:00
|
|
|
ps->redraw_needed = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
draw_callback(EV_P_ ev_idle *w, int revents) {
|
|
|
|
// This function is not used if we are using --swopti
|
2018-11-27 08:32:08 +08:00
|
|
|
session_t *ps = session_ptr(w, draw_idle);
|
2018-10-03 03:22:26 +08:00
|
|
|
|
2018-11-27 08:32:08 +08:00
|
|
|
_draw_callback(EV_A_ ps, revents);
|
2018-10-03 03:22:26 +08:00
|
|
|
|
|
|
|
// Don't do painting non-stop unless we are in benchmark mode
|
2018-11-27 08:32:08 +08:00
|
|
|
if (!ps->o.benchmark)
|
|
|
|
ev_idle_stop(ps->loop, &ps->draw_idle);
|
2018-10-03 03:22:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
delayed_draw_timer_callback(EV_P_ ev_timer *w, int revents) {
|
2018-11-27 08:32:08 +08:00
|
|
|
session_t *ps = session_ptr(w, delayed_draw_timer);
|
|
|
|
_draw_callback(EV_A_ ps, revents);
|
2018-10-03 03:22:26 +08:00
|
|
|
|
|
|
|
// We might have stopped the ev_idle in delayed_draw_callback,
|
|
|
|
// so we restart it if we are in benchmark mode
|
2018-11-27 08:32:08 +08:00
|
|
|
if (ps->o.benchmark)
|
|
|
|
ev_idle_start(EV_A_ &ps->draw_idle);
|
2018-10-03 03:22:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
delayed_draw_callback(EV_P_ ev_idle *w, int revents) {
|
|
|
|
// This function is only used if we are using --swopti
|
2018-11-27 08:32:08 +08:00
|
|
|
session_t *ps = session_ptr(w, draw_idle);
|
|
|
|
if (ev_is_active(&ps->delayed_draw_timer))
|
2018-10-03 03:22:26 +08:00
|
|
|
return;
|
|
|
|
|
2018-11-27 08:32:08 +08:00
|
|
|
double delay = swopti_handle_timeout(ps);
|
2018-10-03 03:22:26 +08:00
|
|
|
if (delay < 1e-6)
|
2018-11-27 08:32:08 +08:00
|
|
|
return _draw_callback(EV_A_ ps, revents);
|
2018-10-03 03:22:26 +08:00
|
|
|
|
|
|
|
// This is a little bit hacky. When we get to this point in code, we need
|
2018-11-27 08:32:08 +08:00
|
|
|
// to update the screen , but we will only be updating after a delay, So
|
2018-10-03 03:22:26 +08:00
|
|
|
// we want to stop the ev_idle, so this callback doesn't get call repeatedly
|
|
|
|
// during the delay, we also want queue_redraw to not restart the ev_idle.
|
2018-11-27 08:32:08 +08:00
|
|
|
// So we stop ev_idle and leave ps->redraw_needed to be true. (effectively,
|
|
|
|
// ps->redraw_needed means if redraw is needed or if draw is in progress).
|
2018-10-03 03:22:26 +08:00
|
|
|
//
|
|
|
|
// We do this anyway even if we are in benchmark mode. That means we will
|
|
|
|
// have to restart draw_idle after the draw actually happened when we are in
|
|
|
|
// benchmark mode.
|
2018-11-27 08:32:08 +08:00
|
|
|
ev_idle_stop(ps->loop, &ps->draw_idle);
|
2018-10-03 03:22:26 +08:00
|
|
|
|
2018-11-27 08:32:08 +08:00
|
|
|
ev_timer_set(&ps->delayed_draw_timer, delay, 0);
|
|
|
|
ev_timer_start(ps->loop, &ps->delayed_draw_timer);
|
2018-10-03 03:22:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
x_event_callback(EV_P_ ev_io *w, int revents) {
|
|
|
|
session_t *ps = (session_t *)w;
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_generic_event_t *ev = xcb_poll_for_event(ps->c);
|
2018-10-03 03:22:26 +08:00
|
|
|
if (ev) {
|
|
|
|
ev_handle(ps, ev);
|
|
|
|
free(ev);
|
|
|
|
}
|
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
|
|
|
}
|
|
|
|
|
2018-11-27 07:56:55 +08:00
|
|
|
/**
|
|
|
|
* Turn on the program reset flag.
|
|
|
|
*
|
|
|
|
* This will result in compton resetting itself after next paint.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
reset_enable(EV_P_ ev_signal *w, int revents) {
|
2018-11-27 08:32:08 +08:00
|
|
|
session_t *ps = session_ptr(w, usr1_signal);
|
2018-11-27 07:56:55 +08:00
|
|
|
ev_break(ps->loop, EVBREAK_ALL);
|
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* Initialize a session.
|
|
|
|
*
|
|
|
|
* @param ps_old old session, from which the function will take the X
|
|
|
|
* connection, then free it
|
|
|
|
* @param argc number of commandline arguments
|
|
|
|
* @param argv commandline arguments
|
|
|
|
*/
|
|
|
|
static session_t *
|
|
|
|
session_init(session_t *ps_old, int argc, char **argv) {
|
2018-08-22 22:26:08 +08:00
|
|
|
static const session_t s_def = {
|
2012-11-19 09:46:07 +08:00
|
|
|
.dpy = NULL,
|
|
|
|
.scr = 0,
|
2018-10-03 21:27:48 +08:00
|
|
|
.c = NULL,
|
2018-09-24 02:10:46 +08:00
|
|
|
.vis = 0,
|
2012-11-19 09:46:07 +08:00
|
|
|
.depth = 0,
|
|
|
|
.root = None,
|
|
|
|
.root_height = 0,
|
|
|
|
.root_width = 0,
|
|
|
|
// .root_damage = None,
|
|
|
|
.overlay = None,
|
2013-03-15 23:16:23 +08:00
|
|
|
.root_tile_fill = false,
|
|
|
|
.root_tile_paint = PAINT_INIT,
|
2012-11-19 09:46:07 +08:00
|
|
|
.tgt_picture = None,
|
2013-12-10 22:06:02 +08:00
|
|
|
.tgt_buffer = PAINT_INIT,
|
2012-11-19 09:46:07 +08:00
|
|
|
.reg_win = None,
|
|
|
|
.o = {
|
2013-03-15 23:16:23 +08:00
|
|
|
.config_file = NULL,
|
2012-11-19 09:46:07 +08:00
|
|
|
.display = NULL,
|
2013-03-15 23:16:23 +08:00
|
|
|
.backend = BKEND_XRENDER,
|
2013-03-17 12:14:00 +08:00
|
|
|
.glx_no_stencil = false,
|
2018-08-22 22:12:29 +08:00
|
|
|
#ifdef CONFIG_OPENGL
|
2014-05-16 15:18:17 +08:00
|
|
|
.glx_prog_win = GLX_PROG_MAIN_INIT,
|
|
|
|
#endif
|
2012-11-19 09:46:07 +08:00
|
|
|
.mark_wmwin_focused = false,
|
|
|
|
.mark_ovredir_focused = false,
|
|
|
|
.fork_after_register = false,
|
|
|
|
.synchronize = false,
|
|
|
|
.detect_rounded_corners = false,
|
2013-04-27 11:43:11 +08:00
|
|
|
.resize_damage = 0,
|
2012-11-19 09:46:07 +08:00
|
|
|
.unredir_if_possible = false,
|
2013-09-04 22:00:51 +08:00
|
|
|
.unredir_if_possible_blacklist = NULL,
|
|
|
|
.unredir_if_possible_delay = 0,
|
2013-07-26 12:52:16 +08:00
|
|
|
.redirected_force = UNSET,
|
2013-07-30 22:24:11 +08:00
|
|
|
.stoppaint_force = UNSET,
|
2013-01-11 21:31:02 +08:00
|
|
|
.dbus = false,
|
2013-03-19 20:58:55 +08:00
|
|
|
.benchmark = 0,
|
|
|
|
.benchmark_wid = None,
|
2013-01-11 21:31:02 +08:00
|
|
|
.logpath = NULL,
|
2012-11-19 09:46:07 +08:00
|
|
|
|
|
|
|
.refresh_rate = 0,
|
|
|
|
.sw_opti = false,
|
|
|
|
.vsync = VSYNC_NONE,
|
|
|
|
.vsync_aggressive = false,
|
|
|
|
|
|
|
|
.shadow_red = 0.0,
|
|
|
|
.shadow_green = 0.0,
|
|
|
|
.shadow_blue = 0.0,
|
|
|
|
.shadow_radius = 12,
|
|
|
|
.shadow_offset_x = -15,
|
|
|
|
.shadow_offset_y = -15,
|
|
|
|
.shadow_opacity = .75,
|
|
|
|
.shadow_blacklist = NULL,
|
|
|
|
.shadow_ignore_shaped = false,
|
|
|
|
.respect_prop_shadow = false,
|
2013-08-22 21:15:04 +08:00
|
|
|
.xinerama_shadow_crop = false,
|
2012-11-19 09:46:07 +08:00
|
|
|
|
|
|
|
.fade_in_step = 0.028 * OPAQUE,
|
|
|
|
.fade_out_step = 0.03 * OPAQUE,
|
|
|
|
.fade_delta = 10,
|
|
|
|
.no_fading_openclose = false,
|
2014-05-16 15:18:17 +08:00
|
|
|
.no_fading_destroyed_argb = false,
|
2012-11-19 09:46:07 +08:00
|
|
|
.fade_blacklist = NULL,
|
|
|
|
|
2018-08-12 02:48:37 +08:00
|
|
|
.inactive_opacity = OPAQUE,
|
2012-11-19 09:46:07 +08:00
|
|
|
.inactive_opacity_override = false,
|
2018-08-12 02:48:37 +08:00
|
|
|
.active_opacity = OPAQUE,
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
.frame_opacity = 1.0,
|
2012-11-19 09:46:07 +08:00
|
|
|
.detect_client_opacity = false,
|
2013-01-12 22:21:35 +08:00
|
|
|
|
2012-12-14 20:32:46 +08:00
|
|
|
.blur_background = false,
|
|
|
|
.blur_background_frame = false,
|
2012-12-15 20:07:45 +08:00
|
|
|
.blur_background_fixed = false,
|
2013-03-23 22:06:41 +08:00
|
|
|
.blur_background_blacklist = NULL,
|
2013-05-20 18:04:40 +08:00
|
|
|
.blur_kerns = { NULL },
|
2013-01-12 22:21:35 +08:00
|
|
|
.inactive_dim = 0.0,
|
|
|
|
.inactive_dim_fixed = false,
|
|
|
|
.invert_color_list = NULL,
|
2013-05-21 09:18:41 +08:00
|
|
|
.opacity_rules = NULL,
|
2012-12-10 10:31:24 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
.use_ewmh_active_win = false,
|
2012-11-28 11:44:00 +08:00
|
|
|
.focus_blacklist = NULL,
|
2012-12-12 12:01:51 +08:00
|
|
|
.detect_transient = false,
|
|
|
|
.detect_client_leader = false,
|
2012-11-19 09:46:07 +08:00
|
|
|
|
|
|
|
.track_focus = false,
|
|
|
|
.track_wdata = false,
|
2012-12-12 12:01:51 +08:00
|
|
|
.track_leader = false,
|
2012-11-19 09:46:07 +08:00
|
|
|
},
|
|
|
|
|
|
|
|
.time_start = { 0, 0 },
|
|
|
|
.redirected = false,
|
|
|
|
.alpha_picts = NULL,
|
2018-10-03 03:22:26 +08:00
|
|
|
.fade_running = false,
|
2013-01-11 21:31:02 +08:00
|
|
|
.fade_time = 0L,
|
2012-11-19 09:46:07 +08:00
|
|
|
.ignore_head = NULL,
|
|
|
|
.ignore_tail = NULL,
|
2018-10-03 03:22:26 +08:00
|
|
|
.quit = false,
|
2012-11-19 09:46:07 +08:00
|
|
|
|
|
|
|
.expose_rects = NULL,
|
|
|
|
.size_expose = 0,
|
|
|
|
.n_expose = 0,
|
|
|
|
|
|
|
|
.list = NULL,
|
|
|
|
.active_win = NULL,
|
2012-12-12 12:01:51 +08:00
|
|
|
.active_leader = None,
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
.black_picture = None,
|
|
|
|
.cshadow_picture = None,
|
2013-01-12 22:21:35 +08:00
|
|
|
.white_picture = None,
|
2012-11-19 09:46:07 +08:00
|
|
|
.gaussian_map = NULL,
|
|
|
|
.cgsize = 0,
|
|
|
|
.shadow_corner = NULL,
|
|
|
|
.shadow_top = NULL,
|
|
|
|
|
|
|
|
.refresh_rate = 0,
|
|
|
|
.refresh_intv = 0UL,
|
|
|
|
.paint_tm_offset = 0L,
|
|
|
|
|
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
|
|
|
#ifdef CONFIG_VSYNC_DRM
|
2013-01-31 22:53:44 +08:00
|
|
|
.drm_fd = -1,
|
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
|
|
|
#endif
|
2012-11-19 09:46:07 +08:00
|
|
|
|
|
|
|
.xfixes_event = 0,
|
|
|
|
.xfixes_error = 0,
|
|
|
|
.damage_event = 0,
|
|
|
|
.damage_error = 0,
|
|
|
|
.render_event = 0,
|
|
|
|
.render_error = 0,
|
|
|
|
.composite_event = 0,
|
|
|
|
.composite_error = 0,
|
|
|
|
.composite_opcode = 0,
|
|
|
|
.has_name_pixmap = false,
|
|
|
|
.shape_exists = false,
|
|
|
|
.shape_event = 0,
|
|
|
|
.shape_error = 0,
|
|
|
|
.randr_exists = 0,
|
|
|
|
.randr_event = 0,
|
|
|
|
.randr_error = 0,
|
2018-08-22 22:12:29 +08:00
|
|
|
#ifdef CONFIG_OPENGL
|
2012-11-19 09:46:07 +08:00
|
|
|
.glx_exists = false,
|
|
|
|
.glx_event = 0,
|
|
|
|
.glx_error = 0,
|
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
|
|
|
#endif
|
2012-12-14 20:32:46 +08:00
|
|
|
.xrfilter_convolution_exists = false,
|
2012-11-19 09:46:07 +08:00
|
|
|
|
|
|
|
.atom_opacity = None,
|
|
|
|
.atom_frame_extents = None,
|
|
|
|
.atom_client = None,
|
|
|
|
.atom_name = None,
|
|
|
|
.atom_name_ewmh = None,
|
|
|
|
.atom_class = None,
|
2012-12-05 18:12:21 +08:00
|
|
|
.atom_role = None,
|
2012-11-19 09:46:07 +08:00
|
|
|
.atom_transient = None,
|
|
|
|
.atom_ewmh_active_win = None,
|
|
|
|
.atom_compton_shadow = None,
|
|
|
|
.atom_win_type = None,
|
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
|
|
|
.atoms_wintypes = { 0 },
|
|
|
|
.track_atom_lst = NULL,
|
|
|
|
|
|
|
|
#ifdef CONFIG_DBUS
|
|
|
|
.dbus_conn = NULL,
|
|
|
|
.dbus_service = NULL,
|
|
|
|
#endif
|
2012-11-19 09:46:07 +08:00
|
|
|
};
|
2012-09-25 10:19:20 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
// Allocate a session and copy default values into it
|
|
|
|
session_t *ps = malloc(sizeof(session_t));
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
*ps = s_def;
|
2018-10-03 03:22:26 +08:00
|
|
|
ps->loop = EV_DEFAULT;
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
pixman_region32_init(&ps->screen_reg);
|
|
|
|
pixman_region32_init(&ps->all_damage);
|
|
|
|
for (int i = 0; i < CGLX_MAX_BUFFER_AGE; i ++)
|
|
|
|
pixman_region32_init(&ps->all_damage_last[i]);
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
ps_g = ps;
|
|
|
|
ps->ignore_tail = &ps->ignore_head;
|
|
|
|
gettimeofday(&ps->time_start, NULL);
|
|
|
|
|
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
|
|
|
// First pass
|
|
|
|
get_cfg(ps, argc, argv, true);
|
2012-11-19 09:46:07 +08:00
|
|
|
|
|
|
|
// Inherit old Display if possible, primarily for resource leak checking
|
|
|
|
if (ps_old && ps_old->dpy)
|
|
|
|
ps->dpy = ps_old->dpy;
|
|
|
|
|
|
|
|
// Open Display
|
|
|
|
if (!ps->dpy) {
|
|
|
|
ps->dpy = XOpenDisplay(ps->o.display);
|
|
|
|
if (!ps->dpy) {
|
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
|
|
|
printf_errfq(1, "(): Can't open display.");
|
2012-11-19 09:46:07 +08:00
|
|
|
}
|
2018-09-23 02:43:35 +08:00
|
|
|
XSetEventQueueOwner(ps->dpy, XCBOwnsEventQueue);
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
2018-10-03 21:27:48 +08:00
|
|
|
ps->c = XGetXCBConnection(ps->dpy);
|
2018-09-27 23:29:51 +08:00
|
|
|
const xcb_query_extension_reply_t *ext_info;
|
2008-02-15 12:38:32 +08:00
|
|
|
|
2014-03-17 23:25:34 +08:00
|
|
|
XSetErrorHandler(xerror);
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.synchronize) {
|
|
|
|
XSynchronize(ps->dpy, 1);
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->scr = DefaultScreen(ps->dpy);
|
|
|
|
ps->root = RootWindow(ps->dpy, ps->scr);
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2018-09-24 02:10:46 +08:00
|
|
|
ps->vis = XVisualIDFromVisual(DefaultVisual(ps->dpy, ps->scr));
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->depth = DefaultDepth(ps->dpy, ps->scr);
|
|
|
|
|
2013-06-09 17:06:35 +08:00
|
|
|
// Start listening to events on root earlier to catch all possible
|
|
|
|
// root geometry changes
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_change_window_attributes(ps->c, ps->root, XCB_CW_EVENT_MASK, (const uint32_t[]) {
|
2018-10-03 20:34:24 +08:00
|
|
|
XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY
|
|
|
|
| XCB_EVENT_MASK_EXPOSURE
|
|
|
|
| XCB_EVENT_MASK_STRUCTURE_NOTIFY
|
|
|
|
| XCB_EVENT_MASK_PROPERTY_CHANGE });
|
2013-09-12 21:23:20 +08:00
|
|
|
XFlush(ps->dpy);
|
2013-06-09 17:06:35 +08:00
|
|
|
|
|
|
|
ps->root_width = DisplayWidth(ps->dpy, ps->scr);
|
|
|
|
ps->root_height = DisplayHeight(ps->dpy, ps->scr);
|
|
|
|
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_prefetch_extension_data(ps->c, &xcb_render_id);
|
|
|
|
xcb_prefetch_extension_data(ps->c, &xcb_composite_id);
|
|
|
|
xcb_prefetch_extension_data(ps->c, &xcb_damage_id);
|
|
|
|
xcb_prefetch_extension_data(ps->c, &xcb_shape_id);
|
|
|
|
xcb_prefetch_extension_data(ps->c, &xcb_xfixes_id);
|
|
|
|
xcb_prefetch_extension_data(ps->c, &xcb_randr_id);
|
|
|
|
xcb_prefetch_extension_data(ps->c, &xcb_xinerama_id);
|
2018-11-04 06:15:38 +08:00
|
|
|
xcb_prefetch_extension_data(ps->c, &xcb_present_id);
|
2018-09-27 23:29:51 +08:00
|
|
|
|
2018-10-03 21:27:48 +08:00
|
|
|
ext_info = xcb_get_extension_data(ps->c, &xcb_render_id);
|
2018-09-28 00:14:44 +08:00
|
|
|
if (!ext_info || !ext_info->present) {
|
2011-11-04 14:33:23 +08:00
|
|
|
fprintf(stderr, "No render extension\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
2018-09-28 00:14:44 +08:00
|
|
|
ps->render_event = ext_info->first_event;
|
|
|
|
ps->render_error = ext_info->first_error;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2018-10-03 21:27:48 +08:00
|
|
|
ext_info = xcb_get_extension_data(ps->c, &xcb_composite_id);
|
2018-09-29 01:13:53 +08:00
|
|
|
if (!ext_info || !ext_info->present) {
|
2011-11-04 14:33:23 +08:00
|
|
|
fprintf(stderr, "No composite extension\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
2018-09-29 01:13:53 +08:00
|
|
|
ps->composite_opcode = ext_info->major_opcode;
|
|
|
|
ps->composite_event = ext_info->first_event;
|
|
|
|
ps->composite_error = ext_info->first_error;
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
{
|
2018-09-29 01:13:53 +08:00
|
|
|
xcb_composite_query_version_reply_t *reply =
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_composite_query_version_reply(ps->c,
|
|
|
|
xcb_composite_query_version(ps->c, XCB_COMPOSITE_MAJOR_VERSION, XCB_COMPOSITE_MINOR_VERSION),
|
2018-09-29 01:13:53 +08:00
|
|
|
NULL);
|
2003-11-25 01:11:00 +08:00
|
|
|
|
2014-09-07 16:05:14 +08:00
|
|
|
if (!ps->o.no_name_pixmap
|
2018-09-29 01:13:53 +08:00
|
|
|
&& reply && (reply->major_version > 0 || reply->minor_version >= 2)) {
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->has_name_pixmap = true;
|
|
|
|
}
|
2018-09-29 01:13:53 +08:00
|
|
|
free(reply);
|
2011-11-04 16:41:56 +08:00
|
|
|
}
|
2004-06-27 12:48:37 +08:00
|
|
|
|
2018-10-03 21:27:48 +08:00
|
|
|
ext_info = xcb_get_extension_data(ps->c, &xcb_damage_id);
|
2018-09-27 23:29:51 +08:00
|
|
|
if (!ext_info || !ext_info->present) {
|
2011-11-04 14:33:23 +08:00
|
|
|
fprintf(stderr, "No damage extension\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
2018-09-27 23:29:51 +08:00
|
|
|
ps->damage_event = ext_info->first_event;
|
|
|
|
ps->damage_error = ext_info->first_error;
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_discard_reply(ps->c,
|
|
|
|
xcb_damage_query_version(ps->c, XCB_DAMAGE_MAJOR_VERSION, XCB_DAMAGE_MINOR_VERSION).sequence);
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2018-10-03 21:27:48 +08:00
|
|
|
ext_info = xcb_get_extension_data(ps->c, &xcb_xfixes_id);
|
2018-09-29 00:31:00 +08:00
|
|
|
if (!ext_info || !ext_info->present) {
|
2011-11-04 14:33:23 +08:00
|
|
|
fprintf(stderr, "No XFixes extension\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
2018-09-29 00:31:00 +08:00
|
|
|
ps->xfixes_event = ext_info->first_event;
|
|
|
|
ps->xfixes_error = ext_info->first_error;
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_discard_reply(ps->c,
|
|
|
|
xcb_xfixes_query_version(ps->c, XCB_XFIXES_MAJOR_VERSION, XCB_XFIXES_MINOR_VERSION).sequence);
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2013-11-09 21:38:31 +08:00
|
|
|
// Build a safe representation of display name
|
|
|
|
{
|
|
|
|
char *display_repr = DisplayString(ps->dpy);
|
|
|
|
if (!display_repr)
|
|
|
|
display_repr = "unknown";
|
|
|
|
display_repr = mstrcpy(display_repr);
|
|
|
|
|
|
|
|
// Convert all special characters in display_repr name to underscore
|
|
|
|
{
|
|
|
|
char *pdisp = display_repr;
|
|
|
|
|
|
|
|
while (*pdisp) {
|
|
|
|
if (!isalnum(*pdisp))
|
|
|
|
*pdisp = '_';
|
|
|
|
++pdisp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ps->o.display_repr = display_repr;
|
|
|
|
}
|
|
|
|
|
2013-06-09 17:06:35 +08:00
|
|
|
// Second pass
|
|
|
|
get_cfg(ps, argc, argv, false);
|
|
|
|
|
2014-03-17 23:25:34 +08:00
|
|
|
// Query X Shape
|
2018-10-03 21:27:48 +08:00
|
|
|
ext_info = xcb_get_extension_data(ps->c, &xcb_shape_id);
|
2018-09-29 17:29:51 +08:00
|
|
|
if (ext_info && ext_info->present) {
|
|
|
|
ps->shape_event = ext_info->first_event;
|
|
|
|
ps->shape_error = ext_info->first_error;
|
2014-03-17 23:25:34 +08:00
|
|
|
ps->shape_exists = true;
|
|
|
|
}
|
|
|
|
|
2018-11-04 06:15:38 +08:00
|
|
|
ext_info = xcb_get_extension_data(ps->c, &xcb_randr_id);
|
|
|
|
if (ext_info && ext_info->present) {
|
|
|
|
ps->randr_exists = true;
|
|
|
|
ps->randr_event = ext_info->first_event;
|
|
|
|
ps->randr_error = ext_info->first_error;
|
|
|
|
}
|
|
|
|
|
|
|
|
ext_info = xcb_get_extension_data(ps->c, &xcb_present_id);
|
|
|
|
if (ext_info && ext_info->present) {
|
|
|
|
ps->present_exists = true;
|
|
|
|
}
|
|
|
|
|
2018-11-08 22:53:13 +08:00
|
|
|
// Query X Sync
|
|
|
|
if (XSyncQueryExtension(ps->dpy, &ps->xsync_event, &ps->xsync_error)) {
|
|
|
|
// TODO: Fencing may require version >= 3.0?
|
|
|
|
int major_version_return = 0, minor_version_return = 0;
|
|
|
|
if (XSyncInitialize(ps->dpy, &major_version_return, &minor_version_return))
|
|
|
|
ps->xsync_exists = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!ps->xsync_exists && ps->o.xrender_sync_fence) {
|
|
|
|
printf_errf("(): X Sync extension not found. No X Sync fence sync is "
|
|
|
|
"possible.");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
// Query X RandR
|
2013-08-28 21:47:16 +08:00
|
|
|
if ((ps->o.sw_opti && !ps->o.refresh_rate) || ps->o.xinerama_shadow_crop) {
|
2018-11-04 06:15:38 +08:00
|
|
|
if (!ps->randr_exists) {
|
2013-08-28 21:47:16 +08:00
|
|
|
printf_errf("(): No XRandR extension, automatic screen change "
|
2013-01-30 13:41:08 +08:00
|
|
|
"detection impossible.");
|
2018-11-04 06:15:38 +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
|
|
|
}
|
|
|
|
|
2013-08-22 21:15:04 +08:00
|
|
|
// Query X Xinerama extension
|
|
|
|
if (ps->o.xinerama_shadow_crop) {
|
|
|
|
#ifdef CONFIG_XINERAMA
|
2018-10-03 21:27:48 +08:00
|
|
|
ext_info = xcb_get_extension_data(ps->c, &xcb_xinerama_id);
|
2018-09-29 17:46:29 +08:00
|
|
|
ps->xinerama_exists = ext_info && ext_info->present;
|
2013-08-22 21:15:04 +08:00
|
|
|
#else
|
|
|
|
printf_errf("(): Xinerama support not compiled in.");
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2013-03-15 23:16:23 +08:00
|
|
|
rebuild_screen_reg(ps);
|
|
|
|
|
2013-03-12 09:43:14 +08:00
|
|
|
// Overlay must be initialized before double buffer, and before creation
|
|
|
|
// of OpenGL context.
|
2018-11-03 22:04:18 +08:00
|
|
|
init_overlay(ps);
|
2013-03-12 09:43:14 +08:00
|
|
|
|
2018-11-04 06:15:38 +08:00
|
|
|
if (ps->o.print_diagnostics) {
|
|
|
|
print_diagnostics(ps);
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
2013-03-15 23:16:23 +08:00
|
|
|
// Initialize OpenGL as early as possible
|
2013-12-10 22:06:02 +08:00
|
|
|
if (bkend_use_glx(ps)) {
|
2018-08-22 22:12:29 +08:00
|
|
|
#ifdef CONFIG_OPENGL
|
2013-03-15 23:16:23 +08:00
|
|
|
if (!glx_init(ps, true))
|
|
|
|
exit(1);
|
|
|
|
#else
|
2013-03-16 22:54:43 +08:00
|
|
|
printf_errfq(1, "(): GLX backend support not compiled in.");
|
2013-03-15 23:16:23 +08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2014-05-16 15:18:17 +08:00
|
|
|
// Initialize window GL shader
|
|
|
|
if (BKEND_GLX == ps->o.backend && ps->o.glx_fshader_win_str) {
|
2018-08-22 22:12:29 +08:00
|
|
|
#ifdef CONFIG_OPENGL
|
2014-05-16 15:18:17 +08:00
|
|
|
if (!glx_load_prog_main(ps, NULL, ps->o.glx_fshader_win_str, &ps->o.glx_prog_win))
|
|
|
|
exit(1);
|
|
|
|
#else
|
|
|
|
printf_errf("(): GLSL supported not compiled in, can't load shader.");
|
|
|
|
exit(1);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2012-10-26 11:12:28 +08:00
|
|
|
// Initialize software optimization
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.sw_opti)
|
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
|
|
|
ps->o.sw_opti = swopti_init(ps);
|
2012-10-26 11:12:28 +08:00
|
|
|
|
2013-08-28 21:47:16 +08:00
|
|
|
// Monitor screen changes if vsync_sw is enabled and we are using
|
|
|
|
// an auto-detected refresh rate, or when Xinerama features are enabled
|
|
|
|
if (ps->randr_exists && ((ps->o.sw_opti && !ps->o.refresh_rate)
|
|
|
|
|| ps->o.xinerama_shadow_crop))
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_randr_select_input(ps->c, ps->root, XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE);
|
2013-08-28 21:47:16 +08:00
|
|
|
|
2013-01-30 13:41:08 +08:00
|
|
|
// Initialize VSync
|
2013-01-31 22:53:44 +08:00
|
|
|
if (!vsync_init(ps))
|
2013-01-30 13:41:08 +08:00
|
|
|
exit(1);
|
2012-02-27 12:00:12 +08:00
|
|
|
|
2013-08-22 21:15:04 +08:00
|
|
|
cxinerama_upd_scrs(ps);
|
|
|
|
|
2013-01-31 22:53:44 +08:00
|
|
|
// Create registration window
|
2013-03-01 12:41:16 +08:00
|
|
|
if (!ps->reg_win && !register_cm(ps))
|
2013-01-31 22:53:44 +08:00
|
|
|
exit(1);
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
init_atoms(ps);
|
|
|
|
init_alpha_picts(ps);
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->gaussian_map = make_gaussian_map(ps->o.shadow_radius);
|
|
|
|
presum_gaussian(ps, ps->gaussian_map);
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
{
|
2018-09-24 02:10:46 +08:00
|
|
|
xcb_render_create_picture_value_list_t pa = {
|
|
|
|
.subwindowmode = IncludeInferiors,
|
|
|
|
};
|
2012-11-03 10:30:32 +08:00
|
|
|
|
2018-09-24 02:10:46 +08:00
|
|
|
ps->root_picture = x_create_picture_with_visual_and_pixmap(ps,
|
2018-09-28 00:14:44 +08:00
|
|
|
ps->vis, ps->root, XCB_RENDER_CP_SUBWINDOW_MODE, &pa);
|
2018-11-03 22:04:18 +08:00
|
|
|
if (ps->overlay != XCB_NONE) {
|
2018-09-24 02:10:46 +08:00
|
|
|
ps->tgt_picture = x_create_picture_with_visual_and_pixmap(ps,
|
2018-09-28 00:14:44 +08:00
|
|
|
ps->vis, ps->overlay, XCB_RENDER_CP_SUBWINDOW_MODE, &pa);
|
2018-09-24 02:10:46 +08:00
|
|
|
} else
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->tgt_picture = ps->root_picture;
|
2012-10-24 10:09:59 +08:00
|
|
|
}
|
2012-02-27 12:00:12 +08:00
|
|
|
|
2013-03-16 22:54:43 +08:00
|
|
|
// Initialize filters, must be preceded by OpenGL context creation
|
2013-03-15 23:16:23 +08:00
|
|
|
if (!init_filters(ps))
|
|
|
|
exit(1);
|
2012-12-14 20:32:46 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->black_picture = solid_picture(ps, true, 1, 0, 0, 0);
|
2013-01-12 22:21:35 +08:00
|
|
|
ps->white_picture = solid_picture(ps, true, 1, 1, 1, 1);
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-09-11 21:57:50 +08:00
|
|
|
// Generates another Picture for shadows if the color is modified by
|
|
|
|
// user
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!ps->o.shadow_red && !ps->o.shadow_green && !ps->o.shadow_blue) {
|
|
|
|
ps->cshadow_picture = ps->black_picture;
|
2012-09-13 13:58:05 +08:00
|
|
|
} else {
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->cshadow_picture = solid_picture(ps, true, 1,
|
|
|
|
ps->o.shadow_red, ps->o.shadow_green, ps->o.shadow_blue);
|
2012-09-13 13:58:05 +08:00
|
|
|
}
|
2012-09-11 21:57:50 +08:00
|
|
|
|
2018-10-03 03:22:26 +08:00
|
|
|
ev_io_init(&ps->xiow, x_event_callback, ConnectionNumber(ps->dpy), EV_READ);
|
|
|
|
ev_io_start(ps->loop, &ps->xiow);
|
2018-11-27 08:32:08 +08:00
|
|
|
ev_init(&ps->unredir_timer, tmout_unredir_callback);
|
2018-10-03 03:22:26 +08:00
|
|
|
if (ps->o.sw_opti)
|
2018-11-27 08:32:08 +08:00
|
|
|
ev_idle_init(&ps->draw_idle, delayed_draw_callback);
|
2018-10-03 03:22:26 +08:00
|
|
|
else
|
2018-11-27 08:32:08 +08:00
|
|
|
ev_idle_init(&ps->draw_idle, draw_callback);
|
2018-10-03 03:22:26 +08:00
|
|
|
|
2018-11-27 08:32:08 +08:00
|
|
|
ev_init(&ps->fade_timer, fade_timer_callback);
|
|
|
|
ev_init(&ps->delayed_draw_timer, delayed_draw_timer_callback);
|
2018-10-03 03:22:26 +08:00
|
|
|
|
2018-11-27 07:56:55 +08:00
|
|
|
// Set up SIGUSR1 signal handler to reset program
|
2018-11-27 08:32:08 +08:00
|
|
|
ev_signal_init(&ps->usr1_signal, reset_enable, SIGUSR1);
|
|
|
|
ev_signal_start(ps->loop, &ps->usr1_signal);
|
2018-11-27 07:56:55 +08:00
|
|
|
|
2018-11-27 07:21:33 +08:00
|
|
|
// xcb can read multiple events from the socket when a request with reply is
|
|
|
|
// made.
|
2018-10-03 03:22:26 +08:00
|
|
|
//
|
|
|
|
// Use an ev_prepare to make sure we cannot accidentally forget to handle them
|
|
|
|
// before we go to sleep.
|
|
|
|
//
|
|
|
|
// If we don't drain the queue before goes to sleep (i.e. blocking on socket
|
|
|
|
// input), we will be sleeping with events available in queue. Which might
|
|
|
|
// cause us to block indefinitely because arrival of new events could be
|
|
|
|
// dependent on processing of existing events (e.g. if we don't process damage
|
2018-11-27 07:21:33 +08:00
|
|
|
// event and do damage subtract, new damage event won't be generated).
|
|
|
|
//
|
|
|
|
// So we make use of a ev_prepare handle, which is called right before libev
|
|
|
|
// goes into sleep, to handle all the queued X events.
|
2018-11-27 08:32:08 +08:00
|
|
|
ev_prepare_init(&ps->event_check, handle_queued_x_events);
|
2018-10-03 03:22:26 +08:00
|
|
|
// Make sure nothing can cause xcb to read from the X socket after events are
|
|
|
|
// handled and before we going to sleep.
|
2018-11-27 08:32:08 +08:00
|
|
|
ev_set_priority(&ps->event_check, EV_MINPRI);
|
|
|
|
ev_prepare_start(ps->loop, &ps->event_check);
|
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
|
|
|
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_grab_server(ps->c);
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
{
|
2018-10-03 21:06:16 +08:00
|
|
|
xcb_window_t *children;
|
|
|
|
int nchildren;
|
2012-11-19 09:46:07 +08:00
|
|
|
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_query_tree_reply_t *reply = xcb_query_tree_reply(ps->c,
|
|
|
|
xcb_query_tree(ps->c, ps->root), NULL);
|
2012-11-19 09:46:07 +08:00
|
|
|
|
2018-10-03 21:06:16 +08:00
|
|
|
if (reply) {
|
|
|
|
children = xcb_query_tree_children(reply);
|
|
|
|
nchildren = xcb_query_tree_children_length(reply);
|
|
|
|
} else {
|
|
|
|
children = NULL;
|
|
|
|
nchildren = 0;
|
2012-11-19 09:46:07 +08:00
|
|
|
}
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2018-10-03 21:06:16 +08:00
|
|
|
for (int i = 0; i < nchildren; i++) {
|
|
|
|
add_win(ps, children[i], i ? children[i-1] : XCB_NONE);
|
|
|
|
}
|
|
|
|
|
|
|
|
free(reply);
|
2011-11-04 14:33:23 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps->o.track_focus) {
|
|
|
|
recheck_focus(ps);
|
2012-09-13 23:12:54 +08:00
|
|
|
}
|
2012-09-13 21:38:55 +08:00
|
|
|
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_ungrab_server(ps->c);
|
2018-10-03 19:52:52 +08:00
|
|
|
// ALWAYS flush after xcb_ungrab_server()!
|
2014-10-06 11:36:47 +08:00
|
|
|
XFlush(ps->dpy);
|
2012-11-19 09:46:07 +08:00
|
|
|
|
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
|
|
|
// Initialize DBus
|
|
|
|
if (ps->o.dbus) {
|
|
|
|
#ifdef CONFIG_DBUS
|
|
|
|
cdbus_init(ps);
|
|
|
|
if (!ps->dbus_conn) {
|
|
|
|
cdbus_destroy(ps);
|
|
|
|
ps->o.dbus = false;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
printf_errfq(1, "(): DBus support not compiled in!");
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
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
|
|
|
// Fork to background, if asked
|
|
|
|
if (ps->o.fork_after_register) {
|
2013-01-11 21:31:02 +08:00
|
|
|
if (!fork_after(ps)) {
|
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
|
|
|
session_destroy(ps);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-26 21:28:48 +08:00
|
|
|
// Redirect output stream
|
|
|
|
if (ps->o.fork_after_register || ps->o.logpath)
|
|
|
|
ostream_reopen(ps, NULL);
|
|
|
|
|
2013-11-09 21:38:31 +08:00
|
|
|
write_pid(ps);
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
// Free the old session
|
|
|
|
if (ps_old)
|
|
|
|
free(ps_old);
|
|
|
|
|
|
|
|
return ps;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Destroy a session.
|
|
|
|
*
|
|
|
|
* Does not close the X connection or free the <code>session_t</code>
|
|
|
|
* structure, though.
|
|
|
|
*
|
|
|
|
* @param ps session to destroy
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
session_destroy(session_t *ps) {
|
|
|
|
redir_stop(ps);
|
|
|
|
|
|
|
|
// Stop listening to events on root window
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_change_window_attributes(ps->c, ps->root, XCB_CW_EVENT_MASK,
|
2018-10-03 20:34:24 +08:00
|
|
|
(const uint32_t[]) { 0 });
|
2011-11-04 14:33:23 +08:00
|
|
|
|
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
|
|
|
#ifdef CONFIG_DBUS
|
|
|
|
// Kill DBus connection
|
|
|
|
if (ps->o.dbus)
|
|
|
|
cdbus_destroy(ps);
|
|
|
|
|
|
|
|
free(ps->dbus_service);
|
|
|
|
#endif
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
// Free window linked list
|
|
|
|
{
|
|
|
|
win *next = NULL;
|
|
|
|
for (win *w = ps->list; w; w = next) {
|
|
|
|
// Must be put here to avoid segfault
|
|
|
|
next = w->next;
|
2011-11-04 16:41:56 +08:00
|
|
|
|
2018-11-05 02:54:04 +08:00
|
|
|
if (w->a.map_state == XCB_MAP_STATE_VIEWABLE && !w->destroyed)
|
2012-11-19 09:46:07 +08:00
|
|
|
win_ev_stop(ps, w);
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
free_win_res(ps, w);
|
|
|
|
free(w);
|
|
|
|
}
|
2012-10-21 20:44:24 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->list = NULL;
|
|
|
|
}
|
2012-11-08 19:39:13 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
// Free alpha_picts
|
|
|
|
{
|
2018-11-10 20:48:36 +08:00
|
|
|
for (int i = 0; i <= MAX_ALPHA; ++i)
|
2012-11-19 09:46:07 +08:00
|
|
|
free_picture(ps, &ps->alpha_picts[i]);
|
|
|
|
free(ps->alpha_picts);
|
|
|
|
ps->alpha_picts = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Free blacklists
|
|
|
|
free_wincondlst(&ps->o.shadow_blacklist);
|
|
|
|
free_wincondlst(&ps->o.fade_blacklist);
|
2013-01-12 22:21:35 +08:00
|
|
|
free_wincondlst(&ps->o.focus_blacklist);
|
|
|
|
free_wincondlst(&ps->o.invert_color_list);
|
2013-04-25 22:23:35 +08:00
|
|
|
free_wincondlst(&ps->o.blur_background_blacklist);
|
2013-05-21 09:18:41 +08:00
|
|
|
free_wincondlst(&ps->o.opacity_rules);
|
2013-06-19 19:36:48 +08:00
|
|
|
free_wincondlst(&ps->o.paint_blacklist);
|
2013-09-04 22:00:51 +08:00
|
|
|
free_wincondlst(&ps->o.unredir_if_possible_blacklist);
|
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
|
|
|
|
|
|
|
// Free tracked atom list
|
|
|
|
{
|
|
|
|
latom_t *next = NULL;
|
|
|
|
for (latom_t *this = ps->track_atom_lst; this; this = next) {
|
|
|
|
next = this->next;
|
|
|
|
free(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
ps->track_atom_lst = NULL;
|
|
|
|
}
|
2012-11-19 09:46:07 +08:00
|
|
|
|
|
|
|
// Free ignore linked list
|
|
|
|
{
|
|
|
|
ignore_t *next = NULL;
|
|
|
|
for (ignore_t *ign = ps->ignore_head; ign; ign = next) {
|
|
|
|
next = ign->next;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
free(ign);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reset head and tail
|
|
|
|
ps->ignore_head = NULL;
|
|
|
|
ps->ignore_tail = &ps->ignore_head;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Free cshadow_picture and black_picture
|
|
|
|
if (ps->cshadow_picture == ps->black_picture)
|
|
|
|
ps->cshadow_picture = None;
|
|
|
|
else
|
|
|
|
free_picture(ps, &ps->cshadow_picture);
|
|
|
|
|
|
|
|
free_picture(ps, &ps->black_picture);
|
2013-01-12 22:21:35 +08:00
|
|
|
free_picture(ps, &ps->white_picture);
|
2012-11-19 09:46:07 +08:00
|
|
|
|
|
|
|
// Free tgt_{buffer,picture} and root_picture
|
2013-12-10 22:06:02 +08:00
|
|
|
if (ps->tgt_buffer.pict == ps->tgt_picture)
|
|
|
|
ps->tgt_buffer.pict = None;
|
2012-11-19 09:46:07 +08:00
|
|
|
|
|
|
|
if (ps->tgt_picture == ps->root_picture)
|
|
|
|
ps->tgt_picture = None;
|
|
|
|
else
|
|
|
|
free_picture(ps, &ps->tgt_picture);
|
2018-11-08 22:53:13 +08:00
|
|
|
free_fence(ps, &ps->tgt_buffer_fence);
|
2012-11-19 09:46:07 +08:00
|
|
|
|
|
|
|
free_picture(ps, &ps->root_picture);
|
2013-12-10 22:06:02 +08:00
|
|
|
free_paint(ps, &ps->tgt_buffer);
|
2012-11-19 09:46:07 +08:00
|
|
|
|
|
|
|
// Free other X resources
|
2013-03-15 23:16:23 +08:00
|
|
|
free_root_tile(ps);
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
pixman_region32_fini(&ps->screen_reg);
|
|
|
|
pixman_region32_fini(&ps->all_damage);
|
2013-04-26 14:01:20 +08:00
|
|
|
for (int i = 0; i < CGLX_MAX_BUFFER_AGE; ++i)
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
pixman_region32_fini(&ps->all_damage_last[i]);
|
2012-11-19 09:46:07 +08:00
|
|
|
free(ps->expose_rects);
|
|
|
|
free(ps->shadow_corner);
|
|
|
|
free(ps->shadow_top);
|
|
|
|
free(ps->gaussian_map);
|
2013-11-09 21:38:31 +08:00
|
|
|
|
|
|
|
free(ps->o.config_file);
|
|
|
|
free(ps->o.write_pid_path);
|
2012-11-19 09:46:07 +08:00
|
|
|
free(ps->o.display);
|
2013-11-09 21:38:31 +08:00
|
|
|
free(ps->o.display_repr);
|
2013-01-11 21:31:02 +08:00
|
|
|
free(ps->o.logpath);
|
2013-05-20 18:04:40 +08:00
|
|
|
for (int i = 0; i < MAX_BLUR_PASS; ++i) {
|
|
|
|
free(ps->o.blur_kerns[i]);
|
|
|
|
free(ps->blur_kerns_cache[i]);
|
|
|
|
}
|
2014-05-16 15:18:17 +08:00
|
|
|
free(ps->o.glx_fshader_win_str);
|
2013-08-22 21:15:04 +08:00
|
|
|
free_xinerama_info(ps);
|
2018-09-24 02:10:46 +08:00
|
|
|
free(ps->pictfmts);
|
2012-11-19 09:46:07 +08:00
|
|
|
|
2018-08-22 22:12:29 +08:00
|
|
|
#ifdef CONFIG_OPENGL
|
2013-03-15 23:16:23 +08:00
|
|
|
glx_destroy(ps);
|
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
|
|
|
#endif
|
2012-11-19 09:46:07 +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
|
|
|
#ifdef CONFIG_VSYNC_DRM
|
2012-11-19 09:46:07 +08:00
|
|
|
// Close file opened for DRM VSync
|
2013-01-31 22:53:44 +08:00
|
|
|
if (ps->drm_fd >= 0) {
|
2012-11-19 09:46:07 +08:00
|
|
|
close(ps->drm_fd);
|
2013-01-31 22:53:44 +08:00
|
|
|
ps->drm_fd = -1;
|
2012-11-19 09:46:07 +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
|
|
|
#endif
|
2012-11-19 09:46:07 +08:00
|
|
|
|
|
|
|
// Release overlay window
|
|
|
|
if (ps->overlay) {
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_composite_release_overlay_window(ps->c, ps->overlay);
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->overlay = None;
|
|
|
|
}
|
|
|
|
|
2013-03-15 23:16:23 +08:00
|
|
|
// Free reg_win
|
|
|
|
if (ps->reg_win) {
|
2018-10-03 21:27:48 +08:00
|
|
|
xcb_destroy_window(ps->c, ps->reg_win);
|
2013-03-15 23:16:23 +08:00
|
|
|
ps->reg_win = None;
|
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
// Flush all events
|
2018-10-03 21:27:48 +08:00
|
|
|
x_sync(ps->c);
|
2018-10-03 03:22:26 +08:00
|
|
|
ev_io_stop(ps->loop, &ps->xiow);
|
2012-11-19 09:46:07 +08:00
|
|
|
|
2014-08-03 19:40:40 +08:00
|
|
|
#ifdef DEBUG_XRC
|
|
|
|
// Report about resource leakage
|
|
|
|
xrc_report_xid();
|
|
|
|
#endif
|
|
|
|
|
2018-11-27 08:32:08 +08:00
|
|
|
// Stop libev event handlers
|
|
|
|
ev_timer_stop(ps->loop, &ps->unredir_timer);
|
|
|
|
ev_timer_stop(ps->loop, &ps->fade_timer);
|
|
|
|
ev_idle_stop(ps->loop, &ps->draw_idle);
|
|
|
|
ev_prepare_stop(ps->loop, &ps->event_check);
|
|
|
|
ev_signal_stop(ps->loop, &ps->usr1_signal);
|
2018-11-27 07:56:55 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (ps == ps_g)
|
|
|
|
ps_g = NULL;
|
|
|
|
}
|
|
|
|
|
2014-09-07 18:58:09 +08:00
|
|
|
/*
|
|
|
|
static inline void
|
|
|
|
dump_img(session_t *ps) {
|
|
|
|
int len = 0;
|
|
|
|
unsigned char *d = glx_take_screenshot(ps, &len);
|
|
|
|
write_binary_data("/tmp/dump.raw", d, len);
|
|
|
|
free(d);
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* Do the actual work.
|
|
|
|
*
|
|
|
|
* @param ps current session
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
session_run(session_t *ps) {
|
|
|
|
win *t;
|
|
|
|
|
|
|
|
if (ps->o.sw_opti)
|
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
|
|
|
ps->paint_tm_offset = get_time_timeval().tv_usec;
|
2012-11-19 09:46:07 +08:00
|
|
|
|
|
|
|
t = paint_preprocess(ps, ps->list);
|
|
|
|
|
|
|
|
if (ps->redirected)
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
paint_all(ps, NULL, NULL, t);
|
2011-11-04 14:33:23 +08:00
|
|
|
|
2018-11-27 08:32:08 +08:00
|
|
|
// In benchmark mode, we want draw_idle handler to always be active
|
2018-10-03 03:22:26 +08:00
|
|
|
if (ps->o.benchmark)
|
2018-11-27 08:32:08 +08:00
|
|
|
ev_idle_start(ps->loop, &ps->draw_idle);
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
|
2018-10-03 03:22:26 +08:00
|
|
|
ev_run(ps->loop, 0);
|
2003-11-09 15:08:23 +08:00
|
|
|
}
|
2012-11-19 09:46:07 +08:00
|
|
|
|
2018-11-27 07:21:53 +08:00
|
|
|
static void
|
|
|
|
sigint_handler(int __attribute__((unused)) signum) {
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* The function that everybody knows.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
main(int argc, char **argv) {
|
|
|
|
// Set locale so window names with special characters are interpreted
|
|
|
|
// correctly
|
|
|
|
setlocale(LC_ALL, "");
|
|
|
|
|
2018-11-27 07:21:53 +08:00
|
|
|
sigset_t sigmask;
|
|
|
|
sigemptyset(&sigmask);
|
|
|
|
const struct sigaction int_action = {
|
|
|
|
.sa_handler = sigint_handler,
|
|
|
|
.sa_mask = sigmask,
|
|
|
|
.sa_flags = 0
|
|
|
|
};
|
|
|
|
sigaction(SIGINT, &int_action, NULL);
|
2012-11-19 09:46:07 +08:00
|
|
|
|
|
|
|
// Main loop
|
|
|
|
session_t *ps_old = ps_g;
|
2018-10-03 03:22:26 +08:00
|
|
|
bool quit = false;
|
|
|
|
while (!quit) {
|
2012-11-19 09:46:07 +08:00
|
|
|
ps_g = session_init(ps_old, argc, argv);
|
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 (!ps_g) {
|
2013-03-15 23:16:23 +08:00
|
|
|
printf_errf("(): Failed to create new session.");
|
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 1;
|
|
|
|
}
|
2012-11-19 09:46:07 +08:00
|
|
|
session_run(ps_g);
|
|
|
|
ps_old = ps_g;
|
2018-10-03 03:22:26 +08:00
|
|
|
quit = ps_g->quit;
|
2012-11-19 09:46:07 +08:00
|
|
|
session_destroy(ps_g);
|
|
|
|
}
|
|
|
|
|
|
|
|
free(ps_g);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2018-08-12 01:22:49 +08:00
|
|
|
|
|
|
|
// vim: set et sw=2 :
|